diff --git a/content/actions/creating-actions/about-actions.md b/content/actions/creating-actions/about-actions.md index 5f7e2bd249ea..4c9b2e16eaa9 100644 --- a/content/actions/creating-actions/about-actions.md +++ b/content/actions/creating-actions/about-actions.md @@ -11,6 +11,9 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'overview' +topics: + - 'Action development' + - 'Fundamentals' --- {% 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 dc74071275c7..efd8430a3c2e 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 @@ -6,6 +6,8 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'Action development' --- {% data reusables.actions.enterprise-beta %} @@ -32,7 +34,7 @@ Before you begin, you'll create a {% data variables.product.product_name %} repo ``` 2. In the `hello-world-composite-run-steps-action` repository, create a new file called `goodbye.sh`, and add the following example code: - + ```bash echo "Goodbye" ``` @@ -65,12 +67,12 @@ Before you begin, you'll create a {% data variables.product.product_name %} repo required: true default: 'World' outputs: - random-number: + random-number: description: "Random number" value: ${{ steps.random-number-generator.outputs.random-id }} runs: using: "composite" - steps: + steps: - run: echo Hello ${{ inputs.who-to-greet }}. shell: bash - id: random-number-generator @@ -82,7 +84,7 @@ Before you begin, you'll create a {% data variables.product.product_name %} repo {% endraw %} This file defines the `who-to-greet` input, maps the random generated number to the `random-number` output variable, and runs the `goodbye.sh` script. It also tells the runner how to execute the composite run steps action. - For more information about managing outputs, see "[`outputs` for a composite run steps](/actions/creating-actions/metadata-syntax-for-github-actions#outputs-for-composite-run-steps-actions)". + For more information about managing outputs, see "[`outputs` for a composite run steps](/actions/creating-actions/metadata-syntax-for-github-actions#outputs-for-composite-run-steps-actions)". For more information about how to use `github.action_path`, see "[`github context`](/actions/reference/context-and-expression-syntax-for-github-actions#github-context)". @@ -122,7 +124,7 @@ jobs: uses: actions/hello-world-composite-run-steps-action@v1 with: who-to-greet: 'Mona the Octocat' - - run: echo random-number ${{ steps.foo.outputs.random-number }} + - run: echo random-number ${{ steps.foo.outputs.random-number }} shell: bash ``` {% endraw %} 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 b906f5358e03..33fa426b4b90 100644 --- a/content/actions/creating-actions/creating-a-docker-container-action.md +++ b/content/actions/creating-actions/creating-a-docker-container-action.md @@ -11,6 +11,9 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'Action development' + - 'Docker' --- {% data reusables.actions.enterprise-beta %} @@ -93,7 +96,7 @@ This metadata defines one `who-to-greet` input and one `time` output parameter. You can choose any base Docker image and, therefore, any language for your action. The following shell script example uses the `who-to-greet` input variable to print "Hello [who-to-greet]" in the log file. -Next, the script gets the current time and sets it as an output variable that actions running later in a job can use. In order for {% data variables.product.prodname_dotcom %} to recognize output variables, you must use a workflow command in a specific syntax: `echo "::set-output name=::"`. For more information, see "[Workflow commands for {% data variables.product.prodname_actions %}](/actions/reference/workflow-commands-for-github-actions#setting-an-output-parameter)." +Next, the script gets the current time and sets it as an output variable that actions running later in a job can use. In order for {% data variables.product.prodname_dotcom %} to recognize output variables, you must use a workflow command in a specific syntax: `echo "::set-output name=::"`. For more information, see "[Workflow commands for {% data variables.product.prodname_actions %}](/actions/reference/workflow-commands-for-github-actions#setting-an-output-parameter)." 1. Create a new `entrypoint.sh` file in the `hello-world-docker-action` directory. @@ -102,7 +105,7 @@ Next, the script gets the current time and sets it as an output variable that ac **entrypoint.sh** ```shell{:copy} #!/bin/sh -l - + echo "Hello $1" time=$(date) echo "::set-output name=time::$time" diff --git a/content/actions/creating-actions/creating-a-javascript-action.md b/content/actions/creating-actions/creating-a-javascript-action.md index 28771f294410..0068ed60a501 100644 --- a/content/actions/creating-actions/creating-a-javascript-action.md +++ b/content/actions/creating-actions/creating-a-javascript-action.md @@ -11,6 +11,9 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'Action development' + - 'JavaScript' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/about-continuous-integration.md b/content/actions/guides/about-continuous-integration.md index 84cf895266d6..c85d6cd06bca 100644 --- a/content/actions/guides/about-continuous-integration.md +++ b/content/actions/guides/about-continuous-integration.md @@ -11,11 +11,14 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'overview' +topics: + - 'CI' + - 'CD' --- {% data reusables.actions.enterprise-beta %} {% data reusables.actions.enterprise-github-hosted-runners %} - + ### About continuous integration Continuous integration (CI) is a software practice that requires frequently committing code to a shared repository. Committing code more often detects errors sooner and reduces the amount of code a developer needs to debug when finding the source of an error. Frequent code updates also make it easier to merge changes from different members of a software development team. This is great for developers, who can spend more time writing code and less time debugging errors or resolving merge conflicts. diff --git a/content/actions/guides/about-packaging-with-github-actions.md b/content/actions/guides/about-packaging-with-github-actions.md index 5269a8a331e3..77fbd944bd90 100644 --- a/content/actions/guides/about-packaging-with-github-actions.md +++ b/content/actions/guides/about-packaging-with-github-actions.md @@ -9,6 +9,8 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'overview' +topics: + - 'Packaging' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/about-service-containers.md b/content/actions/guides/about-service-containers.md index ceaed1b507e1..5c5172fd926e 100644 --- a/content/actions/guides/about-service-containers.md +++ b/content/actions/guides/about-service-containers.md @@ -9,6 +9,9 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'overview' +topics: + - 'Containers' + - 'Docker' --- {% 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 3f062ffb2894..4fa691d5783e 100644 --- a/content/actions/guides/building-and-testing-java-with-ant.md +++ b/content/actions/guides/building-and-testing-java-with-ant.md @@ -8,6 +8,10 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'CI' + - 'Java' + - 'Ant' --- {% 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 316fa2b6c725..b1349bbb213a 100644 --- a/content/actions/guides/building-and-testing-java-with-gradle.md +++ b/content/actions/guides/building-and-testing-java-with-gradle.md @@ -8,6 +8,10 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'CI' + - 'Java' + - 'Gradle' --- {% 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 205a4116de8b..84c68b6dae92 100644 --- a/content/actions/guides/building-and-testing-java-with-maven.md +++ b/content/actions/guides/building-and-testing-java-with-maven.md @@ -8,6 +8,10 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'CI' + - 'Java' + - 'Maven' --- {% 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 98d94691100e..bd06e9851c75 100644 --- a/content/actions/guides/building-and-testing-nodejs.md +++ b/content/actions/guides/building-and-testing-nodejs.md @@ -9,6 +9,10 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'CI' + - 'Node' + - 'JavaScript' --- {% 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 90a68f797738..73db57f053b6 100644 --- a/content/actions/guides/building-and-testing-powershell.md +++ b/content/actions/guides/building-and-testing-powershell.md @@ -8,6 +8,9 @@ versions: authors: - potatoqualitee type: 'tutorial' +topics: + - 'CI' + - 'Powershell' --- {% 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 8ae02ab51240..5ee9c6b4b6f4 100644 --- a/content/actions/guides/building-and-testing-python.md +++ b/content/actions/guides/building-and-testing-python.md @@ -8,6 +8,9 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'CI' + - 'Python' --- {% 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 ad30a1c5e570..e2862acd6740 100644 --- a/content/actions/guides/building-and-testing-ruby.md +++ b/content/actions/guides/building-and-testing-ruby.md @@ -6,6 +6,9 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'CI' + - 'Ruby' --- {% data reusables.actions.enterprise-beta %} @@ -83,7 +86,7 @@ Alternatively, you can check a `.ruby-version` file into the root of your repos ### Testing with multiple versions of Ruby -You can add a matrix strategy to run your workflow with more than one version of Ruby. For example, you can test your code against the latest patch releases of versions 2.7, 2.6, and 2.5. The 'x' is a wildcard character that matches the latest patch release available for a version. +You can add a matrix strategy to run your workflow with more than one version of Ruby. For example, you can test your code against the latest patch releases of versions 2.7, 2.6, and 2.5. The 'x' is a wildcard character that matches the latest patch release available for a version. {% raw %} ```yaml @@ -316,4 +319,3 @@ jobs: GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}" ``` {% endraw %} - 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 9954a6229d6a..571e3ef82003 100644 --- a/content/actions/guides/caching-dependencies-to-speed-up-workflows.md +++ b/content/actions/guides/caching-dependencies-to-speed-up-workflows.md @@ -10,6 +10,8 @@ redirect_from: versions: free-pro-team: '*' type: 'tutorial' +topics: + - 'Workflows' --- ### 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 76a41c11a9b1..61e3ee912456 100644 --- a/content/actions/guides/creating-postgresql-service-containers.md +++ b/content/actions/guides/creating-postgresql-service-containers.md @@ -10,6 +10,9 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'Containers' + - 'Docker' --- {% 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 ae29fc7e074a..de5c6772109a 100644 --- a/content/actions/guides/creating-redis-service-containers.md +++ b/content/actions/guides/creating-redis-service-containers.md @@ -10,6 +10,9 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'Containers' + - 'Docker' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/deploying-to-amazon-elastic-container-service.md b/content/actions/guides/deploying-to-amazon-elastic-container-service.md index 023472a4cbed..2e981496c6b0 100644 --- a/content/actions/guides/deploying-to-amazon-elastic-container-service.md +++ b/content/actions/guides/deploying-to-amazon-elastic-container-service.md @@ -6,6 +6,10 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'CD' + - 'Containers' + - 'Amazon ECS' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/deploying-to-azure-app-service.md b/content/actions/guides/deploying-to-azure-app-service.md index ef83e1b85a08..391bcdd288cb 100644 --- a/content/actions/guides/deploying-to-azure-app-service.md +++ b/content/actions/guides/deploying-to-azure-app-service.md @@ -6,6 +6,10 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'CD' + - 'Containers' + - 'Azure App Service' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/deploying-to-google-kubernetes-engine.md b/content/actions/guides/deploying-to-google-kubernetes-engine.md index 325e0eedad56..8728dde11f2e 100644 --- a/content/actions/guides/deploying-to-google-kubernetes-engine.md +++ b/content/actions/guides/deploying-to-google-kubernetes-engine.md @@ -6,6 +6,10 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'CD' + - 'Containers' + - 'Google Kubernetes Engine' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/index.md b/content/actions/guides/index.md index eb563c17ff70..bb3ae78614ba 100644 --- a/content/actions/guides/index.md +++ b/content/actions/guides/index.md @@ -25,6 +25,43 @@ learningTracks: - hosting_your_own_runners - create_actions layout: product-sublanding +includeGuides: + - /actions/quickstart + - /actions/learn-github-actions/introduction-to-github-actions + - /actions/creating-actions/creating-a-docker-container-action + - /actions/guides/setting-up-continuous-integration-using-workflow-templates + - /actions/guides/building-and-testing-python + - /actions/guides/building-and-testing-nodejs + - /actions/guides/about-packaging-with-github-actions + - /actions/guides/publishing-docker-images + - /actions/guides/caching-dependencies-to-speed-up-workflows + - /actions/guides/about-continuous-integration + - /actions/guides/building-and-testing-powershell + - /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 + - /actions/guides/publishing-nodejs-packages + - /actions/guides/publishing-java-packages-with-maven + - /actions/guides/publishing-java-packages-with-gradle + - /actions/guides/storing-workflow-data-as-artifacts + - /actions/guides/about-service-containers + - /actions/guides/creating-redis-service-containers + - /actions/guides/creating-postgresql-service-containers + - /actions/guides/deploying-to-amazon-elastic-container-service + - /actions/guides/deploying-to-azure-app-service + - /actions/guides/deploying-to-google-kubernetes-engine + - /actions/learn-github-actions/essential-features-of-github-actions + - /actions/learn-github-actions/security-hardening-for-github-actions + - /actions/creating-actions/about-actions + - /actions/creating-actions/creating-a-javascript-action + - /actions/creating-actions/creating-a-composite-run-steps-action + - /actions/learn-github-actions/migrating-from-azure-pipelines-to-github-actions + - /actions/learn-github-actions/migrating-from-circleci-to-github-actions + - /actions/learn-github-actions/migrating-from-gitlab-cicd-to-github-actions + - /actions/learn-github-actions/migrating-from-jenkins-to-github-actions + - /actions/learn-github-actions/migrating-from-travis-ci-to-github-actions + --- diff --git a/content/actions/guides/publishing-docker-images.md b/content/actions/guides/publishing-docker-images.md index 7d372f4a1e7f..815b28215cdd 100644 --- a/content/actions/guides/publishing-docker-images.md +++ b/content/actions/guides/publishing-docker-images.md @@ -8,6 +8,10 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'Packaging' + - 'Publishing' + - 'Docker' --- {% 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 351685c7cde5..407d44644767 100644 --- a/content/actions/guides/publishing-java-packages-with-gradle.md +++ b/content/actions/guides/publishing-java-packages-with-gradle.md @@ -8,6 +8,11 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'Packaging' + - 'Publishing' + - 'Java' + - 'Gradle' --- {% data reusables.actions.enterprise-beta %} @@ -148,7 +153,7 @@ jobs: {% data reusables.github-actions.gradle-workflow-steps %} 1. Runs the `gradle publish` command to publish to {% data variables.product.prodname_registry %}. The `GITHUB_TOKEN` environment variable will be set with the content of the `GITHUB_TOKEN` secret. - + For more information about using secrets in your workflow, see "[Creating and using encrypted secrets](/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets)." ### Publishing packages to the Maven Central Repository and {% data variables.product.prodname_registry %} diff --git a/content/actions/guides/publishing-java-packages-with-maven.md b/content/actions/guides/publishing-java-packages-with-maven.md index e615b185ff37..48a533fbf2ef 100644 --- a/content/actions/guides/publishing-java-packages-with-maven.md +++ b/content/actions/guides/publishing-java-packages-with-maven.md @@ -8,6 +8,11 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'Packaging' + - 'Publishing' + - 'Java' + - 'Maven' --- {% data reusables.actions.enterprise-beta %} @@ -155,7 +160,7 @@ This workflow performs the following steps: 1. Checks out a copy of project's repository. 1. Sets up the Java JDK, and also automatically configures the Maven _settings.xml_ file to add authentication for the `github` Maven repository to use the `GITHUB_TOKEN` environment variable. 1. {% data reusables.github-actions.publish-to-packages-workflow-step %} - + For more information about using secrets in your workflow, see "[Creating and using encrypted secrets](/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets)." ### Publishing packages to the Maven Central Repository and {% data variables.product.prodname_registry %} diff --git a/content/actions/guides/publishing-nodejs-packages.md b/content/actions/guides/publishing-nodejs-packages.md index 726e1f9bd2c1..711f52f3a8ac 100644 --- a/content/actions/guides/publishing-nodejs-packages.md +++ b/content/actions/guides/publishing-nodejs-packages.md @@ -9,6 +9,11 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'Packaging' + - 'Publishing' + - 'Node' + - 'JavaScript' --- {% data reusables.actions.enterprise-beta %} @@ -167,7 +172,7 @@ jobs: node-version: '12.x' registry-url: 'https://registry.npmjs.org' # Defaults to the user or organization that owns the workflow file - scope: '@octocat' + scope: '@octocat' - run: yarn - run: yarn publish env: 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 7e0a7bc29e0a..fd3a776b0963 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 @@ -12,6 +12,9 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'Workflows' + - 'CI' --- {% 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 a382ebc76b65..898bf40efe83 100644 --- a/content/actions/guides/storing-workflow-data-as-artifacts.md +++ b/content/actions/guides/storing-workflow-data-as-artifacts.md @@ -12,6 +12,8 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'Workflows' --- {% data reusables.actions.enterprise-beta %} @@ -19,7 +21,7 @@ type: 'tutorial' ### About workflow artifacts -Artifacts allow you to persist data after a job has completed, and share that data with another job in the same workflow. An artifact is a file or collection of files produced during a workflow run. For example, you can use artifacts to save your build and test output after a workflow run has ended. +Artifacts allow you to persist data after a job has completed, and share that data with another job in the same workflow. An artifact is a file or collection of files produced during a workflow run. For example, you can use artifacts to save your build and test output after a workflow run has ended. {% data reusables.github-actions.artifact-log-retention-statement %} The retention period for a pull request restarts each time someone pushes a new commit to the pull request. @@ -128,7 +130,7 @@ The `retention-days` value cannot exceed the retention limit set by the reposito ### Downloading or deleting artifacts -During a workflow run, you can use the [`download-artifact`](https://github.com/actions/download-artifact)action to download artifacts that were previously uploaded in the same workflow run. +During a workflow run, you can use the [`download-artifact`](https://github.com/actions/download-artifact)action to download artifacts that were previously uploaded in the same workflow run. After a workflow run has been completed, you can download or delete artifacts on {% data variables.product.prodname_dotcom %} or using the REST API. For more information, see "[Downloading workflow artifacts](/actions/managing-workflow-runs/downloading-workflow-artifacts)," "[Removing workflow artifacts](/actions/managing-workflow-runs/removing-workflow-artifacts)," and the "[Artifacts REST API](/rest/reference/actions#artifacts)." 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 d6dec9f2ef31..4e1c1907ef24 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 @@ -6,6 +6,8 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'overview' +topics: + - 'Fundamentals' --- {% data reusables.actions.enterprise-beta %} @@ -43,7 +45,7 @@ jobs: - run: npm install -g bats ``` -For example, to run a script as an action, you can store the script in your repository and supply the path and shell type. +For example, to run a script as an action, you can store the script in your repository and supply the path and shell type. ```yaml jobs: 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 c3d0c6b44491..bf6ef136cae0 100644 --- a/content/actions/learn-github-actions/finding-and-customizing-actions.md +++ b/content/actions/learn-github-actions/finding-and-customizing-actions.md @@ -11,6 +11,8 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'how_to' +topics: + - 'Fundamentals' --- {% data reusables.actions.enterprise-beta %} 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 3d56d7db0c59..495818104efa 100644 --- a/content/actions/learn-github-actions/introduction-to-github-actions.md +++ b/content/actions/learn-github-actions/introduction-to-github-actions.md @@ -10,6 +10,8 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'overview' +topics: + - 'Fundamentals' --- {% data reusables.actions.enterprise-beta %} @@ -39,7 +41,7 @@ An event is a specific activity that triggers a workflow. For example, activity #### Jobs -A job is a set of steps that execute on the same runner. By default, a workflow with multiple jobs will run those jobs in parallel. You can also configure a workflow to run jobs sequentially. For example, a workflow can have two sequential jobs that build and test code, where the test job is dependent on the status of the build job. If the build job fails, the test job will not run. +A job is a set of steps that execute on the same runner. By default, a workflow with multiple jobs will run those jobs in parallel. You can also configure a workflow to run jobs sequentially. For example, a workflow can have two sequential jobs that build and test code, where the test job is dependent on the status of the build job. If the build job fails, the test job will not run. #### Steps @@ -180,7 +182,7 @@ To help you understand how YAML syntax is used to create a workflow file, this s ``` - The run keyword tells the job to execute a command on the runner. In this case, you are using npm to install the bats software testing package. + The run keyword tells the job to execute a command on the runner. In this case, you are using npm to install the bats software testing package. diff --git a/content/actions/learn-github-actions/managing-complex-workflows.md b/content/actions/learn-github-actions/managing-complex-workflows.md index 17e8e3fc370a..17dc573c37c1 100644 --- a/content/actions/learn-github-actions/managing-complex-workflows.md +++ b/content/actions/learn-github-actions/managing-complex-workflows.md @@ -6,6 +6,8 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'how_to' +topics: + - 'Workflows' --- {% 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 42d8fe4c79f9..b7ac0eaf559e 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 @@ -7,6 +7,11 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'Azure Pipelines' + - 'Migration' + - 'CI' + - 'CD' --- {% data reusables.actions.enterprise-beta %} 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 58502218ca40..6e1684ec0d25 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 @@ -7,6 +7,11 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'CircleCI' + - 'Migration' + - 'CI' + - 'CD' --- {% 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 2af0aafcfc85..e146bc69884e 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 @@ -5,6 +5,11 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'GitLab' + - 'Migration' + - 'CI' + - 'CD' --- {% 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 0a036cc76fc2..bbcc743aacbd 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 @@ -7,6 +7,11 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'Jenkins' + - 'Migration' + - 'CI' + - 'CD' --- {% data reusables.actions.enterprise-beta %} 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 194bf4110729..9daceeafc0c2 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 @@ -7,6 +7,11 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'tutorial' +topics: + - 'Travis CI' + - 'Migration' + - 'CI' + - 'CD' --- ### 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 56b4aab9ca4f..5a55d39d1d98 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 @@ -9,6 +9,8 @@ versions: free-pro-team: '*' enterprise-server: '>=2.22' type: 'overview' +topics: + - 'Security' --- {% data reusables.actions.enterprise-beta %} @@ -22,7 +24,7 @@ This guide explains how to configure security hardening for certain {% data vari Sensitive values should never be stored as plaintext in workflow files, but rather as secrets. [Secrets](/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets) can be configured at the organization{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@3.0" %}, repository, or environment{% else %} or repository{% endif %} level, and allow you to store sensitive information in {% data variables.product.product_name %}. -Secrets use [Libsodium sealed boxes](https://libsodium.gitbook.io/doc/public-key_cryptography/sealed_boxes), so that they are encrypted before reaching {% data variables.product.product_name %}. This occurs when the secret is submitted [using the UI](/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets-for-a-repository) or through the [REST API](/rest/reference/actions#secrets). This client-side encryption helps the minimize risks related to accidental logging (for example, exception logs and request logs, among others) within {% data variables.product.product_name %}'s infrastructure. Once the secret is uploaded, {% data variables.product.product_name %} is then able to decrypt it so that it can be injected into the workflow runtime. +Secrets use [Libsodium sealed boxes](https://libsodium.gitbook.io/doc/public-key_cryptography/sealed_boxes), so that they are encrypted before reaching {% data variables.product.product_name %}. This occurs when the secret is submitted [using the UI](/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets-for-a-repository) or through the [REST API](/rest/reference/actions#secrets). This client-side encryption helps the minimize risks related to accidental logging (for example, exception logs and request logs, among others) within {% data variables.product.product_name %}'s infrastructure. Once the secret is uploaded, {% data variables.product.product_name %} is then able to decrypt it so that it can be injected into the workflow runtime. To help prevent accidental disclosure, {% data variables.product.product_name %} uses a mechanism that attempts to redact any secrets that appear in run logs. This redaction looks for exact matches of any configured secrets, as well as common encodings of the values, such as Base64. However, because there are multiple ways a secret value can be transformed, this redaction is not guaranteed. As a result, there are certain proactive steps and good practices you should follow to help ensure secrets are redacted, and to limit other risks associated with secrets: @@ -56,7 +58,7 @@ This means that a compromise of a single action within a workflow can be very si {% if currentVersion ver_lt "enterprise-server@3.1" %} {% warning %} - + **Warning:** The short version of the commit SHA is insecure and should never be used for specifying an action's Git reference. Because of how repository networks work, any user can fork the repository and push a crafted commit to it that collides with the short SHA. This causes subsequent clones at that SHA to fail because it becomes an ambiguous commit. As a result, any workflows that use the shortened SHA will immediately fail. {% endwarning %} @@ -104,7 +106,7 @@ As a result, self-hosted runners should almost [never be used for public reposit When a self-hosted runner is defined at the organization or enterprise level, {% data variables.product.product_name %} can schedule workflows from multiple repositories onto the same runner. Consequently, a security compromise of these environments can result in a wide impact. To help reduce the scope of a compromise, you can create boundaries by organizing your self-hosted runners into separate groups. For more information, see "[Managing access to self-hosted runners using groups](/actions/hosting-your-own-runners/managing-access-to-self-hosted-runners-using-groups)." You should also consider the environment of the self-hosted runner machines: -- What sensitive information resides on the machine configured as a self-hosted runner? For example, private SSH keys, API access tokens, among others. +- What sensitive information resides on the machine configured as a self-hosted runner? For example, private SSH keys, API access tokens, among others. - Does the machine have network access to sensitive services? For example, Azure or AWS metadata services. The amount of sensitive information in this environment should be kept to a minimum, and you should always be mindful that any user capable of invoking workflows has access to this environment. Some customers might attempt to partially mitigate these risks by implementing systems that automatically destroy the self-hosted runner after each job execution. However, this approach might not be as effective as intended, as there is no way to guarantee that a self-hosted runner only runs one job. @@ -116,7 +118,7 @@ You can use the audit log to monitor administrative tasks in an organization. Th For example, you can use the audit log to track the `action:org.update_actions_secret` event, which tracks changes to organization secrets: ![Audit log entries](/assets/images/help/repository/audit-log-entries.png) -The following tables describe the {% data variables.product.prodname_actions %} events that you can find in the audit log. For more information on using the audit log, see +The following tables describe the {% data variables.product.prodname_actions %} events that you can find in the audit log. For more information on using the audit log, see "[Reviewing the audit log for your organization](/github/setting-up-and-managing-organizations-and-teams/reviewing-the-audit-log-for-your-organization#searching-the-audit-log)." #### Events for secret management @@ -134,14 +136,14 @@ The following tables describe the {% data variables.product.prodname_actions %} |------------------|------------------- | `action:org.register_self_hosted_runner` | Triggered when an organization owner [registers a new self-hosted runner](/actions/hosting-your-own-runners/adding-self-hosted-runners#adding-a-self-hosted-runner-to-an-organization). | `action:org.remove_self_hosted_runner` | Triggered when an organization owner [removes a self-hosted runner](/actions/hosting-your-own-runners/removing-self-hosted-runners#removing-a-runner-from-an-organization). -| `action:repo.register_self_hosted_runner` | Triggered when a repository admin [registers a new self-hosted runner](/actions/hosting-your-own-runners/adding-self-hosted-runners#adding-a-self-hosted-runner-to-a-repository). -| `action:repo.remove_self_hosted_runner` | Triggered when a repository admin [removes a self-hosted runner](/actions/hosting-your-own-runners/removing-self-hosted-runners#removing-a-runner-from-a-repository). +| `action:repo.register_self_hosted_runner` | Triggered when a repository admin [registers a new self-hosted runner](/actions/hosting-your-own-runners/adding-self-hosted-runners#adding-a-self-hosted-runner-to-a-repository). +| `action:repo.remove_self_hosted_runner` | Triggered when a repository admin [removes a self-hosted runner](/actions/hosting-your-own-runners/removing-self-hosted-runners#removing-a-runner-from-a-repository). #### Events for self-hosted runner groups | Action | Description |------------------|------------------- -| `action:org.runner_group_created` | Triggered when an organization admin [creates a self-hosted runner group](/actions/hosting-your-own-runners/managing-access-to-self-hosted-runners-using-groups#creating-a-self-hosted-runner-group-for-an-organization). -| `action:org.runner_group_removed` | Triggered when an organization admin removes a self-hosted runner group. -| `action:org.runner_group_renamed` | Triggered when an organization admin renames a self-hosted runner group. -| `action:org.runner_group_runners_added` | Triggered when an organization admin [adds a self-hosted runner to a group](/actions/hosting-your-own-runners/managing-access-to-self-hosted-runners-using-groups#moving-a-self-hosted-runner-to-a-group). -| `action:org.runner_group_runners_removed` | Triggered when an organization admin removes a self-hosted runner from a group. +| `action:org.runner_group_created` | Triggered when an organization admin [creates a self-hosted runner group](/actions/hosting-your-own-runners/managing-access-to-self-hosted-runners-using-groups#creating-a-self-hosted-runner-group-for-an-organization). +| `action:org.runner_group_removed` | Triggered when an organization admin removes a self-hosted runner group. +| `action:org.runner_group_renamed` | Triggered when an organization admin renames a self-hosted runner group. +| `action:org.runner_group_runners_added` | Triggered when an organization admin [adds a self-hosted runner to a group](/actions/hosting-your-own-runners/managing-access-to-self-hosted-runners-using-groups#moving-a-self-hosted-runner-to-a-group). +| `action:org.runner_group_runners_removed` | Triggered when an organization admin removes a self-hosted runner from a group. diff --git a/content/actions/quickstart.md b/content/actions/quickstart.md index 4b9613add092..9602d5bf9adc 100644 --- a/content/actions/quickstart.md +++ b/content/actions/quickstart.md @@ -7,6 +7,9 @@ redirect_from: versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'quick_start' +topics: + - 'Fundamentals' --- {% data reusables.actions.enterprise-beta %} diff --git a/data/ui.yml b/data/ui.yml index 1f5e96a35020..f66f2ced6f6a 100644 --- a/data/ui.yml +++ b/data/ui.yml @@ -153,6 +153,7 @@ product_sublanding: no_result: Sorry, there is no guide that match your filter. filters: type: Type + topic: Topic all: All guide_types: overview: Overview diff --git a/includes/article-cards.html b/includes/article-cards.html index 72b21648acba..bb64bb9152a2 100644 --- a/includes/article-cards.html +++ b/includes/article-cards.html @@ -1,32 +1,39 @@ -{% assign currentCategory = siteTree[currentLanguage][currentVersion].products[currentProduct].categories[breadcrumbs.category.href] %} - {% assign maxArticles = 9 %}

{% data ui.product_sublanding.all_guides %}

-
- - + +
+ + +
+
+ + +
- {% for article in currentCategory.articles %} - + {% for article in page.includeGuides %} {% assign card_display_class = "" %} {% if forloop.index > maxArticles %} {% assign card_display_class = "d-none" %} {% endif %} {% capture link_card %} - {% link_as_article_card {{ article[1].href }} %} + {% link_as_article_card {{ article.href }} %} {% endcapture %} {{ link_card | replace: "", card_display_class }} diff --git a/includes/liquid-tags/link-as-article-card.html b/includes/liquid-tags/link-as-article-card.html index 555cf1e0e2d1..a6d7960c4f8f 100644 --- a/includes/liquid-tags/link-as-article-card.html +++ b/includes/liquid-tags/link-as-article-card.html @@ -1,7 +1,14 @@ -
- + \ No newline at end of file diff --git a/javascripts/filter-cards.js b/javascripts/filter-cards.js index 52280a293307..b62c210556dd 100644 --- a/javascripts/filter-cards.js +++ b/javascripts/filter-cards.js @@ -6,30 +6,39 @@ function matchCardBySearch (card, searchString) { function matchCardByAttribute (card, attribute, value) { if (attribute in card.dataset) { - return card.dataset[attribute] === value + const allValues = card.dataset[attribute].split(',') + return allValues.some(key => key === value) } return false } export default function cardsFilter () { const inputFilter = document.querySelector('.js-filter-card-filter') - const dropdownFilter = document.querySelector('.js-filter-card-filter-dropdown') + const dropdownFilters = document.querySelectorAll('.js-filter-card-filter-dropdown') const cards = Array.from(document.querySelectorAll('.js-filter-card')) const showMoreButton = document.querySelector('.js-filter-card-show-more') const noResults = document.querySelector('.js-filter-card-no-results') // if jsFilterCardMax not set, assume no limit (well, at 99) const maxCards = showMoreButton ? parseInt(showMoreButton.dataset.jsFilterCardMax || 99) : null + const noFilter = () => { + showMoreButton.classList.remove('d-none') + for (let index = 0; index < cards.length; index++) { + const card = cards[index] + // Hide all but the first n number of cards + if (index > maxCards - 1) { + card.classList.add('d-none') + } else { + card.classList.remove('d-none') + } + } + } + const filterEventHandler = (evt) => { const { currentTarget } = evt const value = currentTarget.value - // Show or hide the "Show more" button if there is a value - if (value) { - showMoreButton.classList.add('d-none') - } else { - showMoreButton.classList.remove('d-none') - } + showMoreButton.classList.add('d-none') // Track whether or not we had at least one match let hasMatches = false @@ -37,29 +46,34 @@ export default function cardsFilter () { for (let index = 0; index < cards.length; index++) { const card = cards[index] - // Filter was emptied - if (!value) { - // Make sure we don't show the "No results" blurb - hasMatches = true - - // Hide all but the first n number of cards - if (index > maxCards - 1) { - card.classList.add('d-none') - } else { - card.classList.remove('d-none') - } - - continue - } - let cardMatches = false if (currentTarget.tagName === 'INPUT') { + // Filter was emptied + if (!value) { + noFilter() + // return hasMatches = true, so we don't show the "No results" blurb + hasMatches = true + continue + } cardMatches = matchCardBySearch(card, value) } if (currentTarget.tagName === 'SELECT' && currentTarget.name) { - cardMatches = matchCardByAttribute(card, currentTarget.name, value) + const matches = [] + // check all the other dropdowns + dropdownFilters.forEach(({ name, value }) => { + if (!name || !value) return + matches.push(matchCardByAttribute(card, name, value)) + }) + // if none of the filters is selected + if (matches.length === 0) { + noFilter() + // return hasMatches = true, so we don't show the "No results" blurb + hasMatches = true + continue + } + cardMatches = matches.every(value => value) } if (cardMatches) { @@ -89,8 +103,8 @@ export default function cardsFilter () { }) } - if (dropdownFilter) { - dropdownFilter.addEventListener('change', filterEventHandler) + if (dropdownFilters) { + dropdownFilters.forEach(filter => filter.addEventListener('change', filterEventHandler)) } if (showMoreButton) { diff --git a/layouts/product-sublanding.html b/layouts/product-sublanding.html index 6f27e1511559..5a50f9029ff3 100644 --- a/layouts/product-sublanding.html +++ b/layouts/product-sublanding.html @@ -102,9 +102,11 @@
{{ guide.title }}
-
- {% include 'article-cards' %} -
+ {% if page.includeGuides %} +
+ {% include 'article-cards' %} +
+ {% endif %}
{% include small-footer %} diff --git a/lib/frontmatter.js b/lib/frontmatter.js index 405c49325faf..946bcf9ebf1c 100644 --- a/lib/frontmatter.js +++ b/lib/frontmatter.js @@ -94,6 +94,12 @@ const schema = { type: 'string', enum: guideTypes }, + topics: { + type: 'array' + }, + includeGuides: { + type: 'array' + }, learningTracks: { type: 'array' }, diff --git a/lib/liquid-tags/link-as-article-card.js b/lib/liquid-tags/link-as-article-card.js index 060e3989ee66..12a95a9dc015 100644 --- a/lib/liquid-tags/link-as-article-card.js +++ b/lib/liquid-tags/link-as-article-card.js @@ -4,7 +4,12 @@ const Link = require('./link') module.exports = class LinkAsArticleCard extends Link { async renderPageProps (page, ctx, props) { const renderedProps = await super.renderPageProps(page, ctx, props) - const { type } = page - return { ...renderedProps, type } + const { type: typeKey, topics = [] } = page + const typeVal = typeKey ? ctx.site.data.ui.product_sublanding.guide_types[typeKey] : null + return { + ...renderedProps, + type: { key: typeKey, value: typeVal }, + topics + } } } diff --git a/lib/page.js b/lib/page.js index ec29665bf2c6..d60ef0a24c34 100644 --- a/lib/page.js +++ b/lib/page.js @@ -23,6 +23,7 @@ const slash = require('slash') const statsd = require('./statsd') const fmfromf = require('./read-frontmatter') const getLinkData = require('./get-link-data') +const union = require('lodash/union') class Page { static async init (opts) { @@ -72,6 +73,7 @@ class Page { this.rawProduct = this.product this.rawPermissions = this.permissions this.rawLearningTracks = this.learningTracks + this.rawIncludeGuides = this.includeGuides // a page should only be available in versions that its parent product is available in const versionsParentProductIsNotAvailableIn = getApplicableVersions(this.versions, this.fullPath) @@ -217,6 +219,21 @@ class Page { this.learningTracks = learningTracks } + if (this.rawIncludeGuides) { + this.allTopics = [] + this.includeGuides = await getLinkData(this.rawIncludeGuides, context) + this.includeGuides.map((guide) => { + const { page } = guide + guide.type = page.type + if (page.topics) { + this.allTopics = union(this.allTopics, page.topics) + guide.topics = page.topics + } + delete guide.page + return guide + }) + } + const $ = cheerio.load(html) // set a flag so layout knows whether to render a mac/windows/linux switcher element diff --git a/tests/fixtures/article-with-includeGuides.md b/tests/fixtures/article-with-includeGuides.md new file mode 100644 index 000000000000..4277de1cfbfb --- /dev/null +++ b/tests/fixtures/article-with-includeGuides.md @@ -0,0 +1,10 @@ +--- +title: Article with includeGuides +versions: + free-pro-team: '*' +includeGuides: + - /path/guide1 + - /path/guide2 + - /path/guide3 +layout: product-sublanding +--- diff --git a/tests/unit/liquid-helpers.js b/tests/unit/liquid-helpers.js index 49509ce72bd4..77001971b1be 100644 --- a/tests/unit/liquid-helpers.js +++ b/tests/unit/liquid-helpers.js @@ -96,15 +96,13 @@ describe('liquid helper tags', () => { test('link_as_article_card', async () => { const template = '{% link_as_article_card /contributing-and-collaborating-using-github-desktop %}' - const expected = `
- + const expected = `` +

Use GitHub Desktop to manage your projects, create meaningful commits, and track the project's history in an app instead of on the command line.

` const output = await liquid.parseAndRender(template, context) - expect(output).toBe(expected) + expect(output.includes(expected)).toBe(true) }) describe('indented_data_reference tag', () => { diff --git a/tests/unit/page.js b/tests/unit/page.js index d86452f6ad05..e8e18bd12a34 100644 --- a/tests/unit/page.js +++ b/tests/unit/page.js @@ -340,6 +340,45 @@ describe('Page class', () => { }) }) + describe('includeGuides', () => { + let page + + beforeEach(async () => { + page = await Page.init({ + relativePath: 'article-with-includeGuides.md', + basePath: path.join(__dirname, '../fixtures'), + languageCode: 'en' + }) + }) + + it('includes guide paths specified in frontmatter', async () => { + expect(page.includeGuides).toStrictEqual(['/path/guide1', '/path/guide2', '/path/guide3']) + }) + + it('renders guides and topics', async () => { + getLinkData.mockImplementation(() => { + return [{ + page: { topics: ['Spring', 'Summer'] } + }, { + page: { topics: ['Summer', 'Fall'] } + }, { + page: { topics: ['Fall', 'Winter'] } + }] + }) + const guides = ['/path/guide1', '/path/guide2', '/path/guide3'] + const context = { + currentLanguage: 'en' + } + await page.render(context) + expect(getLinkData).toHaveBeenCalledWith(guides, context) + expect(page.includeGuides).toHaveLength(3) + expect(page.allTopics).toHaveLength(4) + expect(page.allTopics).toEqual( + expect.arrayContaining(['Spring', 'Summer', 'Fall', 'Winter']) + ) + }) + }) + describe('Page.parseFrontmatter()', () => { it('throws an error on bad input', () => { const markdown = null