From 641ed02e816850643019409686a60120c2000698 Mon Sep 17 00:00:00 2001 From: Vanessa Yuen <6842965+vanessayuenn@users.noreply.github.com> Date: Mon, 11 Jan 2021 18:30:57 +0100 Subject: [PATCH] Actions Guides sublanding page (#16740) Co-authored-by: Emily Gould <4822039+emilyistoofunky@users.noreply.github.com> Co-authored-by: Cynthia Rich --- .../actions/creating-actions/about-actions.md | 1 + .../creating-a-composite-run-steps-action.md | 1 + .../creating-a-docker-container-action.md | 1 + .../creating-a-javascript-action.md | 1 + .../dockerfile-support-for-github-actions.md | 15 +-- .../metadata-syntax-for-github-actions.md | 17 +-- ...ublishing-actions-in-github-marketplace.md | 1 + .../setting-exit-codes-for-actions.md | 1 + .../guides/about-continuous-integration.md | 1 + .../about-packaging-with-github-actions.md | 1 + .../guides/about-service-containers.md | 1 + .../building-and-testing-java-with-ant.md | 1 + .../building-and-testing-java-with-gradle.md | 1 + .../building-and-testing-java-with-maven.md | 1 + .../guides/building-and-testing-nodejs.md | 1 + .../guides/building-and-testing-powershell.md | 1 + .../guides/building-and-testing-python.md | 1 + .../guides/building-and-testing-ruby.md | 1 + ...hing-dependencies-to-speed-up-workflows.md | 1 + .../creating-postgresql-service-containers.md | 1 + .../creating-redis-service-containers.md | 1 + content/actions/guides/index.md | 79 +++++------- .../guides/publishing-docker-images.md | 1 + .../publishing-java-packages-with-gradle.md | 1 + .../publishing-java-packages-with-maven.md | 1 + .../guides/publishing-nodejs-packages.md | 1 + ...us-integration-using-workflow-templates.md | 1 + .../storing-workflow-data-as-artifacts.md | 1 + .../about-self-hosted-runners.md | 1 + .../adding-self-hosted-runners.md | 1 + ...-hosted-runner-application-as-a-service.md | 5 +- ...ess-to-self-hosted-runners-using-groups.md | 1 + ...and-troubleshooting-self-hosted-runners.md | 11 +- .../removing-self-hosted-runners.md | 1 + ...a-proxy-server-with-self-hosted-runners.md | 1 + .../using-labels-with-self-hosted-runners.md | 1 + ...using-self-hosted-runners-in-a-workflow.md | 1 + .../essential-features-of-github-actions.md | 1 + .../finding-and-customizing-actions.md | 7 +- .../introduction-to-github-actions.md | 1 + .../managing-complex-workflows.md | 1 + ...-from-azure-pipelines-to-github-actions.md | 4 +- ...grating-from-circleci-to-github-actions.md | 1 + ...ting-from-gitlab-cicd-to-github-actions.md | 1 + ...igrating-from-jenkins-to-github-actions.md | 7 +- ...rating-from-travis-ci-to-github-actions.md | 1 + .../security-hardening-for-github-actions.md | 1 + ...haring-workflows-with-your-organization.md | 1 + data/learning-tracks/actions.yml | 56 +++++++++ data/ui.yml | 12 ++ javascripts/index.js | 2 + javascripts/show-more.js | 38 ++++++ layouts/product-sublanding.html | 119 ++++++++++++++++++ lib/frontmatter.js | 8 ++ lib/get-link-data.js | 36 ++++++ lib/page.js | 16 +++ middleware/featured-links.js | 31 +---- stylesheets/gradient.scss | 79 ++++++++++++ stylesheets/gradients.scss | 83 ------------ stylesheets/index.scss | 3 +- stylesheets/product-sublanding.scss | 5 + .../fixtures/article-with-learning-tracks.md | 10 ++ tests/helpers/links-checker.js | 6 +- tests/unit/page.js | 49 ++++++++ 64 files changed, 542 insertions(+), 196 deletions(-) create mode 100644 data/learning-tracks/actions.yml create mode 100644 javascripts/show-more.js create mode 100644 layouts/product-sublanding.html create mode 100644 lib/get-link-data.js create mode 100644 stylesheets/gradient.scss delete mode 100644 stylesheets/gradients.scss create mode 100644 stylesheets/product-sublanding.scss create mode 100644 tests/fixtures/article-with-learning-tracks.md diff --git a/content/actions/creating-actions/about-actions.md b/content/actions/creating-actions/about-actions.md index ae9f98de99..740b23b443 100644 --- a/content/actions/creating-actions/about-actions.md +++ b/content/actions/creating-actions/about-actions.md @@ -10,6 +10,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'overview' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/creating-actions/creating-a-composite-run-steps-action.md b/content/actions/creating-actions/creating-a-composite-run-steps-action.md index 34312304fd..dc74071275 100644 --- a/content/actions/creating-actions/creating-a-composite-run-steps-action.md +++ b/content/actions/creating-actions/creating-a-composite-run-steps-action.md @@ -5,6 +5,7 @@ product: '{% data reusables.gated-features.actions %}' versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/creating-actions/creating-a-docker-container-action.md b/content/actions/creating-actions/creating-a-docker-container-action.md index ba06a3a938..9d3e36e46f 100644 --- a/content/actions/creating-actions/creating-a-docker-container-action.md +++ b/content/actions/creating-actions/creating-a-docker-container-action.md @@ -10,6 +10,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/creating-actions/creating-a-javascript-action.md b/content/actions/creating-actions/creating-a-javascript-action.md index f479922f56..28771f2944 100644 --- a/content/actions/creating-actions/creating-a-javascript-action.md +++ b/content/actions/creating-actions/creating-a-javascript-action.md @@ -10,6 +10,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/creating-actions/dockerfile-support-for-github-actions.md b/content/actions/creating-actions/dockerfile-support-for-github-actions.md index 58809b0f22..68f93976d7 100644 --- a/content/actions/creating-actions/dockerfile-support-for-github-actions.md +++ b/content/actions/creating-actions/dockerfile-support-for-github-actions.md @@ -8,6 +8,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'reference' --- {% data reusables.actions.enterprise-beta %} @@ -52,7 +53,7 @@ ENTRYPOINT ["echo $GITHUB_SHA"] ``` If you want variable substitution, then either use the _shell_ form or execute a shell directly. For example, using the following _exec_ format, you can execute a shell to print the value stored in the `GITHUB_SHA` environment variable. - + ``` ENTRYPOINT ["sh", "-c", "echo $GITHUB_SHA"] ```` @@ -60,32 +61,32 @@ ENTRYPOINT ["sh", "-c", "echo $GITHUB_SHA"] To supply `args` defined in the action's metadata file to a Docker container that uses the _exec_ form in the `ENTRYPOINT`, we recommend creating a shell script called `entrypoint.sh` that you call from the `ENTRYPOINT` instruction: ##### Example *Dockerfile* -``` +``` # Container image that runs your code FROM debian:9.5-slim # Copies your code file from your action repository to the filesystem path `/` of the container COPY entrypoint.sh /entrypoint.sh -# Executes `entrypoint.sh` when the Docker container starts up +# Executes `entrypoint.sh` when the Docker container starts up ENTRYPOINT ["/entrypoint.sh"] ``` ##### Example *entrypoint.sh* file -Using the example Dockerfile above, {% data variables.product.product_name %} will send the `args` configured in the action's metadata file as arguments to `entrypoint.sh`. Add the `#!/bin/sh` [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) at the top of the `entrypoint.sh` file to explicitly use the system's [POSIX](https://en.wikipedia.org/wiki/POSIX)-compliant shell. +Using the example Dockerfile above, {% data variables.product.product_name %} will send the `args` configured in the action's metadata file as arguments to `entrypoint.sh`. Add the `#!/bin/sh` [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) at the top of the `entrypoint.sh` file to explicitly use the system's [POSIX](https://en.wikipedia.org/wiki/POSIX)-compliant shell. ``` sh #!/bin/sh -# `$*` expands the `args` supplied in an `array` individually +# `$*` expands the `args` supplied in an `array` individually # or splits `args` in a string separated by whitespace. sh -c "echo $*" ``` -Your code must be executable. Make sure the `entrypoint.sh` file has `execute` permissions before using it in a workflow. You can modify the permission from your terminal using this command: +Your code must be executable. Make sure the `entrypoint.sh` file has `execute` permissions before using it in a workflow. You can modify the permission from your terminal using this command: ``` sh - chmod +x entrypoint.sh + chmod +x entrypoint.sh ``` When an `ENTRYPOINT` shell script is not executable, you'll receive an error similar to this: diff --git a/content/actions/creating-actions/metadata-syntax-for-github-actions.md b/content/actions/creating-actions/metadata-syntax-for-github-actions.md index d0c4b338f7..4dfb33bcf8 100644 --- a/content/actions/creating-actions/metadata-syntax-for-github-actions.md +++ b/content/actions/creating-actions/metadata-syntax-for-github-actions.md @@ -11,6 +11,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'reference' --- {% data reusables.actions.enterprise-beta %} @@ -104,12 +105,12 @@ outputs: {% raw %} ```yaml outputs: - random-number: + random-number: description: "Random number" value: ${{ steps.random-number-generator.outputs.random-id }} runs: using: "composite" - steps: + steps: - id: random-number-generator run: echo "::set-output name=random-id::$(echo $RANDOM)" shell: bash @@ -159,7 +160,7 @@ runs: #### `pre-if` **Optional** Allows you to define conditions for the `pre:` action execution. The `pre:` action will only run if the conditions in `pre-if` are met. If not set, then `pre-if` defaults to `always()`. -Note that the `step` context is unavailable, as no steps have run yet. +Note that the `step` context is unavailable, as no steps have run yet. In this example, `cleanup.js` only runs on Linux-based runners: @@ -214,7 +215,7 @@ For example, this `cleanup.js` will only run on Linux-based runners: ```yaml runs: using: "composite" - steps: + steps: - run: ${{ github.action_path }}/test/script.sh shell: bash ``` @@ -225,7 +226,7 @@ Alternatively, you can use `$GITHUB_ACTION_PATH`: ```yaml runs: using: "composite" - steps: + steps: - run: $GITHUB_ACTION_PATH/script.sh shell: bash ``` @@ -254,12 +255,12 @@ For more information, see "[`github context`](/actions/reference/context-and-exp ### `runs` for Docker actions -**Required** Configures the image used for the Docker action. +**Required** Configures the image used for the Docker action. #### Example using a Dockerfile in your repository ```yaml -runs: +runs: using: 'docker' image: 'Dockerfile' ``` @@ -267,7 +268,7 @@ runs: #### Example using public Docker registry container ```yaml -runs: +runs: using: 'docker' image: 'docker://debian:stretch-slim' ``` diff --git a/content/actions/creating-actions/publishing-actions-in-github-marketplace.md b/content/actions/creating-actions/publishing-actions-in-github-marketplace.md index fb35e6e2e1..b69b89065b 100644 --- a/content/actions/creating-actions/publishing-actions-in-github-marketplace.md +++ b/content/actions/creating-actions/publishing-actions-in-github-marketplace.md @@ -8,6 +8,7 @@ redirect_from: - /actions/building-actions/publishing-actions-in-github-marketplace versions: free-pro-team: '*' +type: 'how_to' --- You must accept the terms of service to publish actions in {% data variables.product.prodname_marketplace %}. diff --git a/content/actions/creating-actions/setting-exit-codes-for-actions.md b/content/actions/creating-actions/setting-exit-codes-for-actions.md index 057c8cd2dc..1e550d3bbc 100644 --- a/content/actions/creating-actions/setting-exit-codes-for-actions.md +++ b/content/actions/creating-actions/setting-exit-codes-for-actions.md @@ -8,6 +8,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'how_to' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/about-continuous-integration.md b/content/actions/guides/about-continuous-integration.md index e95c24d84b..84cf895266 100644 --- a/content/actions/guides/about-continuous-integration.md +++ b/content/actions/guides/about-continuous-integration.md @@ -10,6 +10,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'overview' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/about-packaging-with-github-actions.md b/content/actions/guides/about-packaging-with-github-actions.md index aba20c17f6..5269a8a331 100644 --- a/content/actions/guides/about-packaging-with-github-actions.md +++ b/content/actions/guides/about-packaging-with-github-actions.md @@ -8,6 +8,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'overview' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/about-service-containers.md b/content/actions/guides/about-service-containers.md index 5575c35355..a91914c527 100644 --- a/content/actions/guides/about-service-containers.md +++ b/content/actions/guides/about-service-containers.md @@ -8,6 +8,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'overview' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/building-and-testing-java-with-ant.md b/content/actions/guides/building-and-testing-java-with-ant.md index 7fed692812..96019ea729 100644 --- a/content/actions/guides/building-and-testing-java-with-ant.md +++ b/content/actions/guides/building-and-testing-java-with-ant.md @@ -7,6 +7,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/building-and-testing-java-with-gradle.md b/content/actions/guides/building-and-testing-java-with-gradle.md index 9a7b45671e..67e760c925 100644 --- a/content/actions/guides/building-and-testing-java-with-gradle.md +++ b/content/actions/guides/building-and-testing-java-with-gradle.md @@ -7,6 +7,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/building-and-testing-java-with-maven.md b/content/actions/guides/building-and-testing-java-with-maven.md index e652606ea2..fbc8f90151 100644 --- a/content/actions/guides/building-and-testing-java-with-maven.md +++ b/content/actions/guides/building-and-testing-java-with-maven.md @@ -7,6 +7,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/building-and-testing-nodejs.md b/content/actions/guides/building-and-testing-nodejs.md index 7cf7d0667e..245a2c519b 100644 --- a/content/actions/guides/building-and-testing-nodejs.md +++ b/content/actions/guides/building-and-testing-nodejs.md @@ -8,6 +8,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/building-and-testing-powershell.md b/content/actions/guides/building-and-testing-powershell.md index faca1bcdc2..90a68f7977 100644 --- a/content/actions/guides/building-and-testing-powershell.md +++ b/content/actions/guides/building-and-testing-powershell.md @@ -7,6 +7,7 @@ versions: enterprise-server: '>=2.22' authors: - potatoqualitee +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/building-and-testing-python.md b/content/actions/guides/building-and-testing-python.md index ee9fe22a68..86db5490be 100644 --- a/content/actions/guides/building-and-testing-python.md +++ b/content/actions/guides/building-and-testing-python.md @@ -7,6 +7,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/building-and-testing-ruby.md b/content/actions/guides/building-and-testing-ruby.md index c3c091109e..ad30a1c5e5 100644 --- a/content/actions/guides/building-and-testing-ruby.md +++ b/content/actions/guides/building-and-testing-ruby.md @@ -5,6 +5,7 @@ product: '{% data reusables.gated-features.actions %}' versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/caching-dependencies-to-speed-up-workflows.md b/content/actions/guides/caching-dependencies-to-speed-up-workflows.md index 497bcad57e..d450d7ae52 100644 --- a/content/actions/guides/caching-dependencies-to-speed-up-workflows.md +++ b/content/actions/guides/caching-dependencies-to-speed-up-workflows.md @@ -9,6 +9,7 @@ redirect_from: - /actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows versions: free-pro-team: '*' +type: 'tutorial' --- ### About caching workflow dependencies diff --git a/content/actions/guides/creating-postgresql-service-containers.md b/content/actions/guides/creating-postgresql-service-containers.md index c333d93b5c..e3967ef172 100644 --- a/content/actions/guides/creating-postgresql-service-containers.md +++ b/content/actions/guides/creating-postgresql-service-containers.md @@ -9,6 +9,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/creating-redis-service-containers.md b/content/actions/guides/creating-redis-service-containers.md index 62cbca2bc9..4b7c9918c4 100644 --- a/content/actions/guides/creating-redis-service-containers.md +++ b/content/actions/guides/creating-redis-service-containers.md @@ -9,6 +9,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/index.md b/content/actions/guides/index.md index 0ccacf47e7..7a92a7c43e 100644 --- a/content/actions/guides/index.md +++ b/content/actions/guides/index.md @@ -17,54 +17,33 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +learningTracks: + - getting_started + - continuous_integration + - continuous_deployment + - hosting_your_own_runners + - create_actions +layout: product-sublanding --- - -{% data reusables.actions.enterprise-beta %} -{% data reusables.actions.enterprise-github-hosted-runners %} - -### Creating custom continuous integration workflows - -You can use {% data variables.product.prodname_actions %} to create custom continuous integration (CI) workflows that build and test projects written in different programming languages. - -{% link_in_list /about-continuous-integration %} -{% link_in_list /setting-up-continuous-integration-using-workflow-templates %} -{% link_in_list /building-and-testing-nodejs %} -{% link_in_list /building-and-testing-powershell %} -{% link_in_list /building-and-testing-python %} -{% link_in_list /building-and-testing-ruby %} -{% link_in_list /building-and-testing-java-with-maven %} -{% link_in_list /building-and-testing-java-with-gradle %} -{% link_in_list /building-and-testing-java-with-ant %} - -### Creating custom continuous deployment workflows - -You can use {% data variables.product.prodname_actions %} to create custom continuous deployment (CD) workflows that deploy projects to a number of cloud partner ecosystems. - - {% link_in_list /deploying-to-amazon-elastic-container-service %} - {% link_in_list /deploying-to-azure-app-service %} - {% link_in_list /deploying-to-google-kubernetes-engine %} - -### Publishing software packages - -You can automate publishing software packages as part your continuous delivery (CD) workflow. Packages can be published to any package host and to {% data reusables.gated-features.packages %}. - -{% link_in_list /about-packaging-with-github-actions %} -{% link_in_list /publishing-nodejs-packages %} -{% link_in_list /publishing-java-packages-with-maven %} -{% link_in_list /publishing-java-packages-with-gradle %} -{% link_in_list /publishing-docker-images %} - -### Caching and storing workflow data - -Cache dependencies and store artifacts to make your workflow runs more efficient. - -{% link_in_list /storing-workflow-data-as-artifacts %} -{% link_in_list /caching-dependencies-to-speed-up-workflows %} - -### Using service containers in a workflow - -Connect services to your workflow using service containers. - -{% link_in_list /about-service-containers %} -{% link_in_list /creating-redis-service-containers %} -{% link_in_list /creating-postgresql-service-containers %} + + + + + + + + + + + + + + + + + + + + + + diff --git a/content/actions/guides/publishing-docker-images.md b/content/actions/guides/publishing-docker-images.md index dab057d611..b0f2ca729f 100644 --- a/content/actions/guides/publishing-docker-images.md +++ b/content/actions/guides/publishing-docker-images.md @@ -7,6 +7,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/publishing-java-packages-with-gradle.md b/content/actions/guides/publishing-java-packages-with-gradle.md index 4cfbe26bc3..7eca03c8c0 100644 --- a/content/actions/guides/publishing-java-packages-with-gradle.md +++ b/content/actions/guides/publishing-java-packages-with-gradle.md @@ -7,6 +7,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/publishing-java-packages-with-maven.md b/content/actions/guides/publishing-java-packages-with-maven.md index e601a53a16..0b2c6c89be 100644 --- a/content/actions/guides/publishing-java-packages-with-maven.md +++ b/content/actions/guides/publishing-java-packages-with-maven.md @@ -7,6 +7,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/publishing-nodejs-packages.md b/content/actions/guides/publishing-nodejs-packages.md index a1ca797261..ce467dd525 100644 --- a/content/actions/guides/publishing-nodejs-packages.md +++ b/content/actions/guides/publishing-nodejs-packages.md @@ -8,6 +8,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/setting-up-continuous-integration-using-workflow-templates.md b/content/actions/guides/setting-up-continuous-integration-using-workflow-templates.md index a10ab35eaf..7e0a7bc29e 100644 --- a/content/actions/guides/setting-up-continuous-integration-using-workflow-templates.md +++ b/content/actions/guides/setting-up-continuous-integration-using-workflow-templates.md @@ -11,6 +11,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/storing-workflow-data-as-artifacts.md b/content/actions/guides/storing-workflow-data-as-artifacts.md index cf0932f879..fe6aac29ed 100644 --- a/content/actions/guides/storing-workflow-data-as-artifacts.md +++ b/content/actions/guides/storing-workflow-data-as-artifacts.md @@ -11,6 +11,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/hosting-your-own-runners/about-self-hosted-runners.md b/content/actions/hosting-your-own-runners/about-self-hosted-runners.md index 2cce28ae15..9b55022371 100644 --- a/content/actions/hosting-your-own-runners/about-self-hosted-runners.md +++ b/content/actions/hosting-your-own-runners/about-self-hosted-runners.md @@ -7,6 +7,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'overview' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/hosting-your-own-runners/adding-self-hosted-runners.md b/content/actions/hosting-your-own-runners/adding-self-hosted-runners.md index 1693f59185..b97b319e37 100644 --- a/content/actions/hosting-your-own-runners/adding-self-hosted-runners.md +++ b/content/actions/hosting-your-own-runners/adding-self-hosted-runners.md @@ -7,6 +7,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/hosting-your-own-runners/configuring-the-self-hosted-runner-application-as-a-service.md b/content/actions/hosting-your-own-runners/configuring-the-self-hosted-runner-application-as-a-service.md index 2106948b11..e74b6cdeab 100644 --- a/content/actions/hosting-your-own-runners/configuring-the-self-hosted-runner-application-as-a-service.md +++ b/content/actions/hosting-your-own-runners/configuring-the-self-hosted-runner-application-as-a-service.md @@ -6,6 +6,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' defaultPlatform: linux --- @@ -162,7 +163,7 @@ Stop-Service "{{ service_win_name }}" ### Customizing the self-hosted runner service -If you don't want to use the above default `systemd` service configuration, you can create a customized service or use whichever service mechanism you prefer. Consider using the `serviced` template at `actions-runner/bin/actions.runner.service.template` as a reference. If you use a customized service, the self-hosted runner service must always be invoked using the `runsvc.sh` entry point. +If you don't want to use the above default `systemd` service configuration, you can create a customized service or use whichever service mechanism you prefer. Consider using the `serviced` template at `actions-runner/bin/actions.runner.service.template` as a reference. If you use a customized service, the self-hosted runner service must always be invoked using the `runsvc.sh` entry point. {% endlinux %} @@ -170,6 +171,6 @@ If you don't want to use the above default `systemd` service configuration, you ### Customizing the self-hosted runner service -If you don't want to use the above default launchd service configuration, you can create a customized service or use whichever service mechanism you prefer. Consider using the `plist` template at `actions-runner/bin/actions.runner.plist.template` as a reference. If you use a customized service, the self-hosted runner service must always be invoked using the `runsvc.sh` entry point. +If you don't want to use the above default launchd service configuration, you can create a customized service or use whichever service mechanism you prefer. Consider using the `plist` template at `actions-runner/bin/actions.runner.plist.template` as a reference. If you use a customized service, the self-hosted runner service must always be invoked using the `runsvc.sh` entry point. {% endmac %} diff --git a/content/actions/hosting-your-own-runners/managing-access-to-self-hosted-runners-using-groups.md b/content/actions/hosting-your-own-runners/managing-access-to-self-hosted-runners-using-groups.md index cff123387c..583e24c0b2 100644 --- a/content/actions/hosting-your-own-runners/managing-access-to-self-hosted-runners-using-groups.md +++ b/content/actions/hosting-your-own-runners/managing-access-to-self-hosted-runners-using-groups.md @@ -6,6 +6,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/hosting-your-own-runners/monitoring-and-troubleshooting-self-hosted-runners.md b/content/actions/hosting-your-own-runners/monitoring-and-troubleshooting-self-hosted-runners.md index e29d2fe178..36a11e07c2 100644 --- a/content/actions/hosting-your-own-runners/monitoring-and-troubleshooting-self-hosted-runners.md +++ b/content/actions/hosting-your-own-runners/monitoring-and-troubleshooting-self-hosted-runners.md @@ -8,6 +8,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' defaultPlatform: linux --- @@ -33,13 +34,13 @@ defaultPlatform: linux ### Reviewing the self-hosted runner application log files -You can monitor the status of the self-hosted runner application and its activities. Log files are kept in the `_diag` directory, and a new one is generated each time the application is started. The filename begins with *Runner_*, and is followed by a UTC timestamp of when the application was started. +You can monitor the status of the self-hosted runner application and its activities. Log files are kept in the `_diag` directory, and a new one is generated each time the application is started. The filename begins with *Runner_*, and is followed by a UTC timestamp of when the application was started. For detailed logs on workflow job executions, see the next section describing the *Worker_* files. ### Reviewing a job's log file -The self-hosted runner application creates a detailed log file for each job that it processes. These files are stored in the `_diag` directory, and the filename begins with *Worker_*. +The self-hosted runner application creates a detailed log file for each job that it processes. These files are stored in the `_diag` directory, and the filename begins with *Worker_*. {% linux %} @@ -70,7 +71,7 @@ Feb 11 16:06:54 runner01 runsvc.sh[962]: 2020-02-11 16:06:54Z: Running job: test Feb 11 16:07:10 runner01 runsvc.sh[962]: 2020-02-11 16:07:10Z: Job testAction completed with result: Succeeded ``` -To view the systemd configuration, you can locate the service file here: `/etc/systemd/system/actions.runner.-..service`. +To view the systemd configuration, you can locate the service file here: `/etc/systemd/system/actions.runner.-..service`. If you want to customize the self-hosted runner application service, do not directly modify this file. Follow the instructions described in "[Configuring the self-hosted runner application as a service](/actions/hosting-your-own-runners/configuring-the-self-hosted-runner-application-as-a-service#customizing-the-self-hosted-runner-service)." {% endlinux %} @@ -98,7 +99,7 @@ Started: The resulting output includes the process ID and the name of the application’s launchd service. -To view the launchd configuration, you can locate the service file here: `/Users/exampleUsername/Library/LaunchAgents/actions.runner...service`. +To view the launchd configuration, you can locate the service file here: `/Users/exampleUsername/Library/LaunchAgents/actions.runner...service`. If you want to customize the self-hosted runner application service, do not directly modify this file. Follow the instructions described in "[Configuring the self-hosted runner application as a service](/actions/hosting-your-own-runners/configuring-the-self-hosted-runner-application-as-a-service#customizing-the-self-hosted-runner-service-1)." {% endmac %} @@ -161,7 +162,7 @@ In addition, you can find more information in the _SelfUpdate_ log files located #### Checking that Docker is installed -If your jobs require containers, then the self-hosted runner must be Linux-based and needs to have Docker installed. Check that your self-hosted runner has Docker installed and that the service is running. +If your jobs require containers, then the self-hosted runner must be Linux-based and needs to have Docker installed. Check that your self-hosted runner has Docker installed and that the service is running. You can use `systemctl` to check the service status: diff --git a/content/actions/hosting-your-own-runners/removing-self-hosted-runners.md b/content/actions/hosting-your-own-runners/removing-self-hosted-runners.md index 20b8926c30..cd29dcd43b 100644 --- a/content/actions/hosting-your-own-runners/removing-self-hosted-runners.md +++ b/content/actions/hosting-your-own-runners/removing-self-hosted-runners.md @@ -7,6 +7,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners.md b/content/actions/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners.md index df6458092e..2dc3f1fc96 100644 --- a/content/actions/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners.md +++ b/content/actions/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners.md @@ -6,6 +6,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/hosting-your-own-runners/using-labels-with-self-hosted-runners.md b/content/actions/hosting-your-own-runners/using-labels-with-self-hosted-runners.md index ba23713fbb..87ce2bbde1 100644 --- a/content/actions/hosting-your-own-runners/using-labels-with-self-hosted-runners.md +++ b/content/actions/hosting-your-own-runners/using-labels-with-self-hosted-runners.md @@ -4,6 +4,7 @@ intro: You can use labels to organize your self-hosted runners based on their ch versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/hosting-your-own-runners/using-self-hosted-runners-in-a-workflow.md b/content/actions/hosting-your-own-runners/using-self-hosted-runners-in-a-workflow.md index 06a4e41dfd..895402a42c 100644 --- a/content/actions/hosting-your-own-runners/using-self-hosted-runners-in-a-workflow.md +++ b/content/actions/hosting-your-own-runners/using-self-hosted-runners-in-a-workflow.md @@ -7,6 +7,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/learn-github-actions/essential-features-of-github-actions.md b/content/actions/learn-github-actions/essential-features-of-github-actions.md index 1c580cd36a..d6dec9f2ef 100644 --- a/content/actions/learn-github-actions/essential-features-of-github-actions.md +++ b/content/actions/learn-github-actions/essential-features-of-github-actions.md @@ -5,6 +5,7 @@ intro: '{% data variables.product.prodname_actions %} are designed to help you b versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'overview' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/learn-github-actions/finding-and-customizing-actions.md b/content/actions/learn-github-actions/finding-and-customizing-actions.md index d8789d48fa..97dfcb35b8 100644 --- a/content/actions/learn-github-actions/finding-and-customizing-actions.md +++ b/content/actions/learn-github-actions/finding-and-customizing-actions.md @@ -10,6 +10,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'how_to' --- {% data reusables.actions.enterprise-beta %} @@ -39,7 +40,7 @@ You can search and browse actions directly in your repository's workflow editor. ### Adding an action to your workflow -An action's listing page includes the action's version and the workflow syntax required to use the action. To keep your workflow stable even when updates are made to an action, you can reference the version of the action to use by specifying the Git or Docker tag number in your workflow file. +An action's listing page includes the action's version and the workflow syntax required to use the action. To keep your workflow stable even when updates are made to an action, you can reference the version of the action to use by specifying the Git or Docker tag number in your workflow file. 1. Navigate to the action you want to use in your workflow. 1. Under "Installation", click {% octicon "clippy" aria-label="The edit icon" %} to copy the workflow syntax. @@ -90,9 +91,9 @@ For more information, see "[Using release management for actions](/actions/creat ### Using inputs and outputs with an action -An action often accepts or requires inputs and generates outputs that you can use. For example, an action might require you to specify a path to a file, the name of a label, or other data it will use as part of the action processing. +An action often accepts or requires inputs and generates outputs that you can use. For example, an action might require you to specify a path to a file, the name of a label, or other data it will use as part of the action processing. -To see the inputs and outputs of an action, check the `action.yml` or `action.yaml` in the root directory of the repository. +To see the inputs and outputs of an action, check the `action.yml` or `action.yaml` in the root directory of the repository. In this example `action.yml`, the `inputs` keyword defines a required input called `file-path`, and includes a default value that will be used if none is specified. The `outputs` keyword defines an output called `results-file`, which tells you where to locate the results. diff --git a/content/actions/learn-github-actions/introduction-to-github-actions.md b/content/actions/learn-github-actions/introduction-to-github-actions.md index 455cac19cf..c84f11c6b4 100644 --- a/content/actions/learn-github-actions/introduction-to-github-actions.md +++ b/content/actions/learn-github-actions/introduction-to-github-actions.md @@ -9,6 +9,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'overview' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/learn-github-actions/managing-complex-workflows.md b/content/actions/learn-github-actions/managing-complex-workflows.md index 318d912061..17e8e3fc37 100644 --- a/content/actions/learn-github-actions/managing-complex-workflows.md +++ b/content/actions/learn-github-actions/managing-complex-workflows.md @@ -5,6 +5,7 @@ intro: 'This guide shows you how to use the advanced features of {% data variabl versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'how_to' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/learn-github-actions/migrating-from-azure-pipelines-to-github-actions.md b/content/actions/learn-github-actions/migrating-from-azure-pipelines-to-github-actions.md index 15963c3d2e..d80d7fb120 100644 --- a/content/actions/learn-github-actions/migrating-from-azure-pipelines-to-github-actions.md +++ b/content/actions/learn-github-actions/migrating-from-azure-pipelines-to-github-actions.md @@ -6,6 +6,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} @@ -104,7 +105,7 @@ In Azure Pipelines, scripts can be configured to error if any output is sent to In Azure Pipelines, the default shell for scripts on Windows platforms is the Command shell (_cmd.exe_). In {% data variables.product.prodname_actions %}, the default shell for scripts on Windows platforms is PowerShell. PowerShell has several differences in built-in commands, variable expansion, and flow control. -If you're running a simple command, you might be able to run a Command shell script in PowerShell without any changes. But in most cases, you will either need to update your script with PowerShell syntax or instruct {% data variables.product.prodname_actions %} to run the script with the Command shell instead of PowerShell. You can do this by specifying `shell` as `cmd`. +If you're running a simple command, you might be able to run a Command shell script in PowerShell without any changes. But in most cases, you will either need to update your script with PowerShell syntax or instruct {% data variables.product.prodname_actions %} to run the script with the Command shell instead of PowerShell. You can do this by specifying `shell` as `cmd`. Below is an example of the syntax for each system: @@ -324,4 +325,3 @@ jobs: You can find actions that you can use in your workflow in [{% data variables.product.prodname_marketplace %}](https://github.com/marketplace?type=actions), or you can create your own actions. For more information, see "[Creating actions](/actions/creating-actions)." - diff --git a/content/actions/learn-github-actions/migrating-from-circleci-to-github-actions.md b/content/actions/learn-github-actions/migrating-from-circleci-to-github-actions.md index 497f6175fc..8dae1c3e25 100644 --- a/content/actions/learn-github-actions/migrating-from-circleci-to-github-actions.md +++ b/content/actions/learn-github-actions/migrating-from-circleci-to-github-actions.md @@ -6,6 +6,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/learn-github-actions/migrating-from-gitlab-cicd-to-github-actions.md b/content/actions/learn-github-actions/migrating-from-gitlab-cicd-to-github-actions.md index 80d2f12511..4fa6ce3d64 100644 --- a/content/actions/learn-github-actions/migrating-from-gitlab-cicd-to-github-actions.md +++ b/content/actions/learn-github-actions/migrating-from-gitlab-cicd-to-github-actions.md @@ -4,6 +4,7 @@ intro: '{% data variables.product.prodname_actions %} and GitLab CI/CD share sev versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/learn-github-actions/migrating-from-jenkins-to-github-actions.md b/content/actions/learn-github-actions/migrating-from-jenkins-to-github-actions.md index 799d4c020f..0bcf0df3de 100644 --- a/content/actions/learn-github-actions/migrating-from-jenkins-to-github-actions.md +++ b/content/actions/learn-github-actions/migrating-from-jenkins-to-github-actions.md @@ -6,6 +6,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} @@ -81,7 +82,7 @@ Jenkins can run the `stages` and `steps` in parallel, while {% data variables.pr #### Build matrix -Both {% data variables.product.prodname_actions %} and Jenkins let you use a build matrix to define various system combinations. +Both {% data variables.product.prodname_actions %} and Jenkins let you use a build matrix to define various system combinations. | Jenkins | {% data variables.product.prodname_actions %} | | ------------- | ------------- | @@ -166,7 +167,7 @@ Jenkins Pipeline maven-build: env: MAVEN_PATH: '/usr/local/maven' - + ``` @@ -209,7 +210,7 @@ Jenkins Pipeline needs: job1 job3: needs: [job1, job2] - + ``` diff --git a/content/actions/learn-github-actions/migrating-from-travis-ci-to-github-actions.md b/content/actions/learn-github-actions/migrating-from-travis-ci-to-github-actions.md index 3c720b7eb0..4eb55be554 100644 --- a/content/actions/learn-github-actions/migrating-from-travis-ci-to-github-actions.md +++ b/content/actions/learn-github-actions/migrating-from-travis-ci-to-github-actions.md @@ -6,6 +6,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- ### Introduction diff --git a/content/actions/learn-github-actions/security-hardening-for-github-actions.md b/content/actions/learn-github-actions/security-hardening-for-github-actions.md index 112a68f67c..deb87de4f2 100644 --- a/content/actions/learn-github-actions/security-hardening-for-github-actions.md +++ b/content/actions/learn-github-actions/security-hardening-for-github-actions.md @@ -8,6 +8,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'overview' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/learn-github-actions/sharing-workflows-with-your-organization.md b/content/actions/learn-github-actions/sharing-workflows-with-your-organization.md index 9dd9b99567..264a15171f 100644 --- a/content/actions/learn-github-actions/sharing-workflows-with-your-organization.md +++ b/content/actions/learn-github-actions/sharing-workflows-with-your-organization.md @@ -7,6 +7,7 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'how_to' --- {% data reusables.actions.enterprise-beta %} diff --git a/data/learning-tracks/actions.yml b/data/learning-tracks/actions.yml new file mode 100644 index 0000000000..ee75a5d27e --- /dev/null +++ b/data/learning-tracks/actions.yml @@ -0,0 +1,56 @@ +getting_started: + title: 'Get started with {% data variables.product.prodname_actions %}' + description: 'Discover the possibilities of {% data variables.product.prodname_actions %} by creating your first workflow.' + guides: + - /actions/learn-github-actions/introduction-to-github-actions + - /actions/learn-github-actions/finding-and-customizing-actions + - /actions/learn-github-actions/essential-features-of-github-actions + - /actions/learn-github-actions/managing-complex-workflows + - /actions/learn-github-actions/security-hardening-for-github-actions +continuous_integration: + title: 'Build and test code' + description: 'You can create custom continuous integration (CI) workflows right in your repository.' + guides: + - /actions/guides/about-continuous-integration + - /actions/guides/setting-up-continuous-integration-using-workflow-templates + - /actions/guides/about-service-containers + - /actions/guides/building-and-testing-nodejs + - /actions/guides/building-and-testing-powershell + - /actions/guides/building-and-testing-python + - /actions/guides/building-and-testing-ruby + - /actions/guides/building-and-testing-java-with-maven + - /actions/guides/building-and-testing-java-with-gradle + - /actions/guides/building-and-testing-java-with-ant +continuous_deployment: + title: 'Automate your deployments' + description: 'Learn how to automate release publishing for your project with a custom continuous deployment (CD) workflow in {% data variables.product.prodname_actions %}.' + guides: + - /actions/guides/about-packaging-with-github-actions + - /actions/guides/publishing-nodejs-packages + - /actions/guides/publishing-java-packages-with-maven + - /actions/guides/publishing-java-packages-with-gradle + - /actions/guides/publishing-docker-images +hosting_your_own_runners: + title: 'Host your own runners' + description: 'You can create self-hosted runners to run workflows in a highly customizable environment.' + guides: + - /actions/hosting-your-own-runners/about-self-hosted-runners + - /actions/hosting-your-own-runners/adding-self-hosted-runners + - /actions/hosting-your-own-runners/configuring-the-self-hosted-runner-application-as-a-service + - /actions/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners + - /actions/hosting-your-own-runners/using-labels-with-self-hosted-runners + - /actions/hosting-your-own-runners/using-self-hosted-runners-in-a-workflow + - /actions/hosting-your-own-runners/managing-access-to-self-hosted-runners-using-groups + - /actions/hosting-your-own-runners/monitoring-and-troubleshooting-self-hosted-runners +create_actions: + title: 'Create an action' + description: 'Do you have an idea for a new action? Have you built something custom for your project? Learn how to build shareable actions and publish them to GitHub Marketplace.' + guides: + - /actions/creating-actions/about-actions + - /actions/creating-actions/creating-a-docker-container-action + - /actions/creating-actions/creating-a-javascript-action + - /actions/creating-actions/creating-a-composite-run-steps-action + - /actions/creating-actions/metadata-syntax-for-github-actions + - /actions/creating-actions/dockerfile-support-for-github-actions + - /actions/creating-actions/setting-exit-codes-for-actions + - /actions/creating-actions/publishing-actions-in-github-marketplace diff --git a/data/ui.yml b/data/ui.yml index 72318099aa..18d2e37e7b 100644 --- a/data/ui.yml +++ b/data/ui.yml @@ -142,3 +142,15 @@ product_landing: quick_start: Quickstart reference_guides: Reference guides overview: Overview +product_sublanding: + start: Start + start_path: Start path + learning_paths: Learning paths + learning_paths_desc: Learning paths are a collection of guides that help you master a particular subject. + more_guides: more guides + guideTypes: + overview: Overview + quick_start: Quickstart + tutorial: Tutorial + how_to: How-to guide + reference: Reference diff --git a/javascripts/index.js b/javascripts/index.js index 034701bdfd..75c6989301 100644 --- a/javascripts/index.js +++ b/javascripts/index.js @@ -17,6 +17,7 @@ import initializeEvents from './events' import filterCards from './filter-cards' import allArticles from './all-articles' import devToc from './dev-toc' +import showMore from './show-more' document.addEventListener('DOMContentLoaded', async () => { displayPlatformSpecificContent() @@ -32,6 +33,7 @@ document.addEventListener('DOMContentLoaded', async () => { filterCards() allArticles() devToc() + showMore() await fillCsrf() // this must complete before any POST calls initializeEvents() // requires fillCsrf to complete experiment() // requires fillCsrf to complete diff --git a/javascripts/show-more.js b/javascripts/show-more.js new file mode 100644 index 0000000000..00a23bba81 --- /dev/null +++ b/javascripts/show-more.js @@ -0,0 +1,38 @@ +/* + * This utility makes it easy to implement a list of items, some of which are hidden initially + * until user clicks "show more". + * + * Example: + * + *
+ *
item
+ *
hidden item
+ *
hidden item
+ * + *
+*/ + +export default function showMore () { + const buttons = document.querySelectorAll('.js-show-more-button') + + for (const btn of buttons) { + btn.addEventListener('click', evt => { + const container = evt.currentTarget.closest('.js-show-more-container') + if (!container) return + const hiddenLinks = container.querySelectorAll('.js-show-more-item.d-none') + // get number of items to show more of, if not set, show all remaining items + const showMoreNum = evt.currentTarget.dataset.jsShowMoreItems || hiddenLinks.length + let count = 0 + for (const link of hiddenLinks) { + if (count++ >= showMoreNum) { + break + } + link.classList.remove('d-none') + } + // Remove the button if all items have been shown + if (container.querySelectorAll('.js-show-more-item.d-none').length === 0) { + evt.currentTarget.parentElement.removeChild(evt.currentTarget) + } + }) + } +} diff --git a/layouts/product-sublanding.html b/layouts/product-sublanding.html new file mode 100644 index 0000000000..92b67c4429 --- /dev/null +++ b/layouts/product-sublanding.html @@ -0,0 +1,119 @@ + +{% assign guideTypes = site.data.ui.product_sublanding.guideTypes %} + + + {% include head %} + + + {% include sidebar %} + +
+ {% include header %} + +
+
+
+
+ {% include breadcrumbs %} +

{{ page.shortTitle }}

+
{{ page.intro }}
+
+
+ + +
+ {% assign featuredTrack = page.learningTracks[0] %} + +
+
+
+ +
+

{% data ui.product_sublanding.learning_paths %}

+
{% data ui.product_sublanding.learning_paths_desc %}
+ + +
+ {% for track in page.learningTracks offset:1 %} +
+
+
+
+
+ {% octicon "star-fill" height="20" class="v-align-middle m-2"%} +
+
+

+ {{ track.title }} +

+

{{ track.description }}

+
+
+ + {% data ui.product_sublanding.start %} + {% octicon "arrow-right" height="20" %} + +
+ + {% if track.guides.size > 4 %} + +
+ {{ track.guides.size | minus: 4 }} {% data ui.product_sublanding.more_guides %} +
+ {% endif %} +
+
+ {% endfor %} +
+
+
+
+ +
+
+ +
+
+ +
+ {% include small-footer %} +
+
+ + diff --git a/lib/frontmatter.js b/lib/frontmatter.js index c22059679b..405c49325f 100644 --- a/lib/frontmatter.js +++ b/lib/frontmatter.js @@ -6,6 +6,7 @@ const semverRange = { message: 'Must be a valid SemVer range' } const versionIds = Object.keys(require('./all-versions')) +const guideTypes = ['overview', 'quick_start', 'tutorial', 'how_to', 'reference'] const schema = { properties: { @@ -89,6 +90,13 @@ const schema = { } } }, + type: { + type: 'string', + enum: guideTypes + }, + learningTracks: { + type: 'array' + }, // Used in `product-landing.html` beta_product: { type: 'boolean' diff --git a/lib/get-link-data.js b/lib/get-link-data.js new file mode 100644 index 0000000000..56ab03a699 --- /dev/null +++ b/lib/get-link-data.js @@ -0,0 +1,36 @@ +const findPageInVersion = require('../lib/find-page-in-version') +const { getVersionedPathWithLanguage } = require('../lib/path-utils') + +// rawLinks is an array of paths: [ '/foo' ] +// we need to convert it to an array of localized objects: [ { href: '/en/foo', title: 'Foo', intro: 'Description here' } ] +module.exports = async (rawLinks, context, additionalProperties = []) => { + if (!rawLinks) return + + const links = [] + + for (const link of rawLinks) { + const href = link.href + ? getVersionedPathWithLanguage(link.href, context.currentVersion, context.currentLanguage) + : getVersionedPathWithLanguage(link, context.currentVersion, context.currentLanguage) + + const linkedPage = findPageInVersion(href, context.pages, context.redirects, context.currentLanguage, context.currentVersion) + if (!linkedPage) continue + + const opts = { textOnly: true, encodeEntities: true } + + const props = {} + for (const propName of additionalProperties) { + props[propName] = linkedPage[propName] + } + + links.push({ + href, + title: await linkedPage.renderTitle(context, opts), + intro: await linkedPage.renderProp('intro', context, opts), + page: linkedPage, + ...props + }) + } + + return links +} diff --git a/lib/page.js b/lib/page.js index 08016bea84..92651112f8 100644 --- a/lib/page.js +++ b/lib/page.js @@ -21,6 +21,7 @@ const frontmatter = require('./frontmatter') const products = require('./all-products') const slash = require('slash') const statsd = require('./statsd') +const getLinkData = require('./get-link-data') class Page { static init (opts) { @@ -79,6 +80,7 @@ class Page { this.rawShortTitle = this.shortTitle this.rawProduct = this.product this.rawPermissions = this.permissions + this.rawLearningTracks = this.learningTracks // a page should only be available in versions that its parent product is available in const versionsParentProductIsNotAvailableIn = getApplicableVersions(this.versions, this.fullPath) @@ -194,6 +196,20 @@ class Page { this.permissions = await renderContent(this.rawPermissions, context) } + if (this.learningTracks) { + const learningTracks = [] + for await (const trackName of this.rawLearningTracks) { + const track = context.site.data['learning-tracks'][context.currentProduct][trackName] + if (!track) continue + learningTracks.push({ + title: await renderContent(track.title, context, { textOnly: true, encodeEntities: true }), + description: await renderContent(track.description, context, { textOnly: true, encodeEntities: true }), + guides: await getLinkData(track.guides, context, ['type']) + }) + } + this.learningTracks = learningTracks + } + const $ = cheerio.load(html) // set a flag so layout knows whether to render a mac/windows/linux switcher element diff --git a/middleware/featured-links.js b/middleware/featured-links.js index eeaba4fa34..0430d06af5 100644 --- a/middleware/featured-links.js +++ b/middleware/featured-links.js @@ -1,5 +1,4 @@ -const findPageInVersion = require('../lib/find-page-in-version') -const { getVersionedPathWithLanguage } = require('../lib/path-utils') +const getLinkData = require('../lib/get-link-data') // this middleware adds properties to the context object module.exports = async (req, res, next) => { @@ -16,31 +15,3 @@ module.exports = async (req, res, next) => { return next() } - -// rawLinks is an array of paths: [ '/foo' ] -// we need to convert it to an array of localized objects: [ { href: '/en/foo', title: 'Foo', intro: 'Description here' } ] -async function getLinkData (rawLinks, context) { - if (!rawLinks) return - - const links = [] - - for (const link of rawLinks) { - const href = link.href - ? getVersionedPathWithLanguage(link.href, context.currentVersion, context.currentLanguage) - : getVersionedPathWithLanguage(link, context.currentVersion, context.currentLanguage) - - const linkedPage = findPageInVersion(href, context.pages, context.redirects, context.currentLanguage, context.currentVersion) - if (!linkedPage) continue - - const opts = { textOnly: true, encodeEntities: true } - - links.push({ - href, - title: await linkedPage.renderTitle(context, opts), - intro: await linkedPage.renderProp('intro', context, opts), - page: linkedPage - }) - } - - return links -} diff --git a/stylesheets/gradient.scss b/stylesheets/gradient.scss new file mode 100644 index 0000000000..0f6b9d1f23 --- /dev/null +++ b/stylesheets/gradient.scss @@ -0,0 +1,79 @@ +$gradients: ( + "-purple-pink": linear-gradient(135deg, $purple-400 0%, $pink-500 100%), + "-aquamarine-mauve": linear-gradient(130deg, #3bf0e4 -6.8%, #bca1f7 70%), + "-purple-coral": linear-gradient(87.54deg, #9867f0 -6.8%, #ed4e50 84.14%), + "-purple-coral-dark": linear-gradient(92deg, #bca1f7 15%, #e577b4 45%, #ff7170 85%), + "-coral-yellow": linear-gradient(267.91deg, #ffe57f 9.35%, #ff7170 96.48%), + "-coral-yellow-dark": linear-gradient(-70deg, #ff7170 0%, #ffe57f 100%), + "-dark-mint": linear-gradient(90deg, #05aa82, #1c8df0), + "-mint-blue": linear-gradient(271.72deg, #a2facf 7.09%, #64acff 96.61%), + "-mint-blue-dark": linear-gradient(-70deg, #a2facf 0%, #64acff 100%), + "-turq-purple-dark": linear-gradient(-70deg, #3bf0e4 0%, #bca1f7 100%), + "-blue-green": linear-gradient(-70deg, #2188ff 0%, #01a49e 100%), + "-red-orange": linear-gradient(-70deg, #ed4e50 0%, #f06f00 100%), + "-blue-purple": linear-gradient(-70deg, #2188ff 0%, #804eda 100%), + "-pink-blue": linear-gradient(-70deg, #db469f 0%, #2188ff 100%), + "-pink-blue-dark": linear-gradient(-70deg, #e577b4 0%, #64acff 100%) +) !default; + +@mixin bg-gradient($parent, $gradient) { + #{$parent} { + background: $gradient; + } +} + +@mixin text-gradient($parent, $gradient) { + #{$parent} { + background-image: $gradient; + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + color: transparent; + } +} + +$border-width: 2px; +@mixin border-gradient($parent, $gradient) { + #{$parent} { + position: relative; + background-clip: padding-box; + &:before { + content: ""; + position: absolute; + background: white; + border-radius: inherit; + z-index: 1; + left: 0; + right: 0; + top: 0; + bottom: 0; + } + &:after { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + background: $gradient; + content: ""; + z-index: 0; + border-radius: inherit; + margin: -$border-width; + } + & > span { + z-index: 2; + } + } +} + +@each $gradient, $value in $gradients { + @include bg-gradient(".bg-gradient-#{$gradient}", $value); +} + +@each $gradient, $value in $gradients { + @include text-gradient(".text-gradient-#{$gradient}", $value); +} + +@each $gradient, $value in $gradients { + @include border-gradient(".border-gradient-#{$gradient}", $value); +} \ No newline at end of file diff --git a/stylesheets/gradients.scss b/stylesheets/gradients.scss deleted file mode 100644 index d49462f1e0..0000000000 --- a/stylesheets/gradients.scss +++ /dev/null @@ -1,83 +0,0 @@ -// Dark Text Gradients - -.text-gradient { - -webkit-background-clip: text !important; - background-clip: text !important; - -webkit-text-fill-color: transparent; - -webkit-box-decoration-break: clone; - - &-aquamarine-mauve { - @extend .text-gradient; - background: -webkit-linear-gradient(130deg, #3bf0e4 -6.8%, #bca1f7 70%); - } - &-dark-mint { - @extend .text-gradient; - background: -webkit-linear-gradient(90deg, #05aa82, #1c8df0); - } - &-mint-blue-dark { - @extend .text-gradient; - background: -webkit-linear-gradient(-70deg, #a2facf 0%, #64acff 100%); - } - &-coral-yellow-dark { - @extend .text-gradient; - background: -webkit-linear-gradient(-70deg, #ff7170 0%, #ffe57f 100%); - } - &-purple-coral-dark { - @extend .text-gradient; - background: -webkit-linear-gradient(92deg, #bca1f7 15%, #e577b4 45%, #ff7170 85%); - } - &-turq-purple-dark { - @extend .text-gradient; - background: -webkit-linear-gradient(-70deg, #3bf0e4 0%, #bca1f7 100%); - } - &-pink-blue-dark { - @extend .text-gradient; - background: -webkit-linear-gradient(-70deg, #e577b4 0%, #64acff 100%); - } - - // Light Text Gradients - &-blue-green { - @extend .text-gradient; - background: -webkit-linear-gradient(-70deg, #2188ff 0%, #01a49e 100%); - } - &-red-orange { - @extend .text-gradient; - background: -webkit-linear-gradient(-70deg, #ed4e50 0%, #f06f00 100%); - } - &-purple-coral { - @extend .text-gradient; - background: -webkit-linear-gradient(-70deg, #9867f0 0%, #ed4e50 100%); - } - &-blue-purple { - @extend .text-gradient; - background: -webkit-linear-gradient(-70deg, #2188ff 0%, #804eda 100%); - } - &-pink-blue { - @extend .text-gradient; - background: -webkit-linear-gradient(-70deg, #db469f 0%, #2188ff 100%); - } -} - -.bg-gradient { - &-red-orange { - background: linear-gradient(-70deg, #ed4e50 0%, #f06f00 100%); - } - &-aquamarine-mauve { - background: linear-gradient(130deg, #3bf0e4 -6.8%, #bca1f7 70%); - } - &-purple-coral { - background: linear-gradient(87.54deg, #9867f0 -6.8%, #ed4e50 84.14%); - } - &-coral-yellow { - background: linear-gradient(267.91deg, #ffe57f 9.35%, #ff7170 96.48%); - } - &-dark-mint { - background: linear-gradient(90deg, #05aa82, #1c8df0); - } - &-mint-blue { - background: linear-gradient(271.72deg, #a2facf 7.09%, #64acff 96.61%); - } - &-blue-purple { - background: linear-gradient(90.91deg, #027bfd -24.67%, #9f51fb 53.55%); - } -} diff --git a/stylesheets/index.scss b/stylesheets/index.scss index 21702f86c3..8b868c3487 100644 --- a/stylesheets/index.scss +++ b/stylesheets/index.scss @@ -56,5 +56,6 @@ $marketing-font-path: "/dist/fonts/"; @import "shadows.scss"; @import "product-landing.scss"; @import "dev-toc.scss"; +@import "gradient.scss"; +@import "product-sublanding.scss"; @import "release-notes.scss"; -@import "gradients.scss"; \ No newline at end of file diff --git a/stylesheets/product-sublanding.scss b/stylesheets/product-sublanding.scss new file mode 100644 index 0000000000..48b80e6051 --- /dev/null +++ b/stylesheets/product-sublanding.scss @@ -0,0 +1,5 @@ +.feature-track { + li { + width: 280px; + } +} \ No newline at end of file diff --git a/tests/fixtures/article-with-learning-tracks.md b/tests/fixtures/article-with-learning-tracks.md new file mode 100644 index 0000000000..b9a7c9045d --- /dev/null +++ b/tests/fixtures/article-with-learning-tracks.md @@ -0,0 +1,10 @@ +--- +title: Article with learning tracks +versions: + free-pro-team: '*' +learningTracks: + - track_1 + - track_2 + - non_existing_track +layout: product-sublanding +--- diff --git a/tests/helpers/links-checker.js b/tests/helpers/links-checker.js index 843d5e5884..536f800ffb 100644 --- a/tests/helpers/links-checker.js +++ b/tests/helpers/links-checker.js @@ -3,7 +3,7 @@ const { union, uniq } = require('lodash') const fs = require('fs') const path = require('path') -const { getVersionStringFromPath } = require('../../lib/path-utils') +const { getVersionStringFromPath, getProductStringFromPath } = require('../../lib/path-utils') const patterns = require('../../lib/patterns') const { deprecated } = require('../../lib/enterprise-server-releases') const findPageInVersion = require('../../lib/find-page-in-version') @@ -234,9 +234,11 @@ async function buildPathContext (initialContext, page, permalink) { // If we find this causes problems for link checking, we can call `contextualize` on // every page. For now, this cherry-picking approach is intended to improve performance so // we don't have to build the expensive `pages`, `redirects`, etc. data on every page we check. + const path = permalink.href const pathContext = { page, currentVersion: permalink.pageVersion, + currentProduct: getProductStringFromPath(path), relativePath: permalink.relativePath, currentPath: permalink.href } @@ -246,7 +248,7 @@ async function buildPathContext (initialContext, page, permalink) { // Create a new req object using the combined context const req = { - path: permalink.href, + path, context: combinedContext, language: 'en', query: {} diff --git a/tests/unit/page.js b/tests/unit/page.js index ce7dd03c76..6ead028b45 100644 --- a/tests/unit/page.js +++ b/tests/unit/page.js @@ -5,6 +5,10 @@ const prerenderedObjects = require('../../lib/graphql/static/prerendered-objects const allVersions = require('../../lib/all-versions') const enterpriseServerReleases = require('../../lib/enterprise-server-releases') const nonEnterpriseDefaultVersion = require('../../lib/non-enterprise-default-version') + +const getLinkData = require('../../lib/get-link-data') +jest.mock('../../lib/get-link-data') + // get the `free-pro-team` segment of `free-pro-team@latest` const nonEnterpriseDefaultPlan = nonEnterpriseDefaultVersion.split('@')[0] @@ -291,6 +295,51 @@ describe('Page class', () => { }) }) + describe('learning tracks', () => { + let page + + beforeEach(async () => { + page = await Page.init({ + relativePath: 'article-with-learning-tracks.md', + basePath: path.join(__dirname, '../fixtures'), + languageCode: 'en' + }) + }) + + it('includes learning tracks specified in frontmatter', async () => { + expect(page.learningTracks).toStrictEqual(['track_1', 'track_2', 'non_existing_track']) + }) + + it('renders learning tracks that have been defined', async () => { + const guides = ['/path/guide1', '/path/guide2'] + const context = { + currentLanguage: 'en', + currentProduct: 'snowbird', + site: { + data: { + 'learning-tracks': { + snowbird: { + track_1: { + title: 'title', + description: 'description', + guides + }, + track_2: { + title: 'title', + description: 'description', + guides + } + } + } + } + } + } + await page.render(context) + expect(getLinkData).toHaveBeenCalledWith(guides, context, ['type']) + expect(page.learningTracks).toHaveLength(2) + }) + }) + describe('Page.parseFrontmatter()', () => { it('throws an error on bad input', () => { const markdown = null