{"id":16123575,"url":"https://github.com/austenstone/github-actions-best-practices","last_synced_at":"2025-08-24T08:19:41.944Z","repository":{"id":106376339,"uuid":"466897453","full_name":"austenstone/github-actions-best-practices","owner":"austenstone","description":"GitHub Actions best practices.","archived":false,"fork":false,"pushed_at":"2024-05-29T15:03:19.000Z","size":13,"stargazers_count":4,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-16T20:01:45.729Z","etag":null,"topics":["actions"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/austenstone.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["austenstone"]}},"created_at":"2022-03-07T00:58:10.000Z","updated_at":"2024-05-29T15:03:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"6acd7c72-60f6-417c-8254-b7bfad992c59","html_url":"https://github.com/austenstone/github-actions-best-practices","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/austenstone%2Fgithub-actions-best-practices","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/austenstone%2Fgithub-actions-best-practices/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/austenstone%2Fgithub-actions-best-practices/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/austenstone%2Fgithub-actions-best-practices/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/austenstone","download_url":"https://codeload.github.com/austenstone/github-actions-best-practices/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244222392,"owners_count":20418505,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actions"],"created_at":"2024-10-09T21:17:29.014Z","updated_at":"2025-03-18T12:31:25.281Z","avatar_url":"https://github.com/austenstone.png","language":null,"funding_links":["https://github.com/sponsors/austenstone"],"categories":[],"sub_categories":[],"readme":"# The GitHub Actions Well-Architected Framework\n\n## Introduction\n\nThe GitHub Actions Well-Architected Framework is a design framework that can improve the quality of a workload by helping it to:\n\n* Be resilient, available, and recoverable.\n* Be as secure as you need it to be.\n* Deliver a sufficient return on investment.\n* Support responsible development and operations.\n* Accomplish its purpose within acceptable timeframes.\n* The framework is founded on the five pillars of architectural excellence, which are mapped to those goals. They are: Reliability, Security, Cost Optimization, Operational Excellence, and Performance Efficiency.\n\nEach pillar provides recommended practices, risk considerations, and tradeoffs. The design decisions must be balanced across all pillars, given the business requirements. The technical and actionable guidance is broad enough for all workloads and applies to a specific scenario. This guidance is centered on GitHub Actions.\n\nWorkload architecture isn't the same as its implementation. The Well-Architected Framework can set you up for success through architectural design, but the implementation choices depend on the business requirements and constraints of your organization.\n\n## Pillars\n\nThe pillars dive into the five key areas of the Well-Architected Framework.\n\n### 1. Reliability\n\n\n\n### 2. Security\n\n#### [Security hardening for GitHub Actions](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions)\n\n### 3. Cost Optimization\n\n#### Jobs round up to the nearest minute\n\nWhen you run a job GitHub Actions spins up a new VM for the job to run on. The job is billed by the minute, and any fraction of a minute is rounded up to the nearest minute. For example, a job that runs for 61 seconds is billed for two minutes.\n\n#### [Caching dependencies to speed up workflows](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows)\n\nCaching dependencies can significantly reduce the time it takes to run a workflow. For example, if you're building a Node.js project, you can cache the `node_modules` directory to avoid reinstalling dependencies every time you run a workflow.\n\n#### [Set timeouts for workflows](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes)\n\nYou can set a timeout for each [job](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes) or [step](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepstimeout-minutes) in a workflow to prevent it from running for longer than it should. If the timeout is reached, the job or step is cancelled.\n\n#### [Concurrency](https://docs.github.com/en/actions/using-jobs/using-concurrency)\n\nUse concurrency to ensure that only a single job or workflow using the same concurrency group can run at a time.\n\n```yml\nconcurrency:\n  group: ${{ github.ref }}\n```\n\nYou can also cancel a previous run when a new run is triggered.\n\n```yml\n  cancel-in-progress: true\n```\n\n#### Disable Actions\n\nYou can always disable actions for a specific [repository](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#managing-github-actions-permissions-for-your-repository) or [workflow](https://docs.github.com/en/actions/using-workflows/disabling-and-enabling-a-workflow) if you're not using them. You can always re-enable them later.\n\n### 4. Deployment\n\n#### [Environments](https://docs.github.com/en/actions/using-jobs/using-environments-for-jobs)\n\nEnvironments allow you to specify a job as a deployment job. This allows you to better track deployments and enforce environment protection rules.\n\n##### [Environment protection rules](https://docs.github.com/en/enterprise-cloud@latest/actions/deployment/targeting-different-environments/using-environments-for-deployment#deployment-protection-rules)\n\n\n### 4. Operational Excellence\n\n### 5. Performance Efficiency\n\n#### Conditional on changed files\n\nSometimes you want to condition the jobs/steps that run based on what files changed in a push or pull request.\n\n##### [Path filtering](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onpushpull_requestpull_request_targetpathspaths-ignore)\n\nYou can use `on.\u003cpush|pull_request|pull_request_target\u003e.\u003cpaths|paths-ignore\u003e` to trigger a workflow based on the files changed in a push or pull request.\n\n##### [tj-actions/changed-files](https://github.com/tj-actions/changed-files) and [dorny/paths-filter](https://github.com/dorny/paths-filter)\n\nThese actions allows you to conditionally run jobs or steps based on the files changed in a pull request.\n\n### 6. Authoring\n\nUse [VSCode](https://code.visualstudio.com/).\n\n#### [GitHub Actions](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-github-actions)\n\nThe GitHub Actions extension lets you manage your workflows, view the workflow run history, and helps with authoring workflows. It provides syntax highlighting, integrated documentation, validation, code completion, and more.\n\n#### [GitHub CLI](https://cli.github.com/)\n\nThe GitHub CLI is preinstalled on all GitHub-hosted runners. It's a great utility both during actions runtime and even for local development.\n\n#### Running locally\n\nWhile there isn't really a way to run GitHub Actions locally, there are a few ways to test your workflows locally.\n\n##### Make your local machine as a [self-hosted runner](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/adding-self-hosted-runners)\n\nYou can use your local machine as a self-hosted runner to test your workflows locally. You do need to specify the `runs-on` label as the one you set your machine to. You still need to trigger the workflow through GitHub.\n\n##### [Act](https://github.com/nektos/act)\n\nAct is a command-line tool that allows you to run your GitHub Actions locally.\n\n### 6. Scale and Reusability\n\nYou should call workflows from other workflows to avoid duplication. Practice innersourcing to promote best practices and reuse well designed and tested workflows.\n\n- Easier to maintain\n- Create workflows more quickly\n- Avoid duplication. DRY(don't repeat yourself).\n- Build consistently across multiple, dozens, or even hundreds of repositories\n- Require specific workflows for specific deployments\n- Promotes best practices\n- Abstract away complexity\n\n#### Reusable workflows \u0026 Composite Actions\n\n[Reusable Workflows](https://docs.github.com/en/actions/learn-github-actions/reusing-workflows) and [Composite Actions](https://docs.github.com/en/actions/creating-actions/creating-a-composite-run-steps-action) can help you reuse logic across multiple workflows.\n\n| Feature | [Reusable workflows](https://docs.github.com/en/actions/learn-github-actions/reusing-workflows) | [Composite Actions](https://docs.github.com/en/actions/creating-actions/creating-a-composite-run-steps-action) |\n|---------|--------------------|-------------------|\n| Definition | Reusable jobs | Reusable steps |\n| Nesting Depth | 3 layers | 10 layers |\n| Use of Secrets | Can use secrets from the caller workflow | Must be passed in as inputs |\n| Can specify the `runs on` label | Yes | No |\n| Can add additional steps to job | No | Yes |\n| call | `uses: \u003cowner\u003e\u003crepo\u003e/.github/workflows/\u003cworkflow\u003e.yml@\u003cref\u003e` | `uses: \u003cowner\u003e/\u003crepo\u003e\u003c?/path\u003e@\u003cref\u003e` |\n| can be used in matrix strategy | Yes | Yes |\n\n#### [Repository rulesets](https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-organization-settings/managing-rulesets-for-repositories-in-your-organization)\n\nUsing the new version of branch protection rules, repository rulesets, you can actually [require workflows to pass before merging](https://docs.github.com/en/enterprise-cloud@latest/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets#require-workflows-to-pass-before-merging) a pull request for all(or some) of the repositories in your organization.\n\n#### Keeping reusable workflows and actions up to date\n\nIt's important that you can cleanly update your workflows across all repositories that use them but how do we know that something won't break?\n\n##### Versioning\n\n\u003e [!WARNING]\n\u003e Pinning to a branch such as `@main` is not a best practice because it can introduce breaking changes. It's recommended to pin to a specific version or use a version range.\n\nBy versioning your actions and reusable workflows you can ensure that you can update them in a controlled manner. This allows you to test the changes in a single repository before rolling them out to all repositories that use them.\n\n###### [Dependabot](https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/about-dependabot-version-updates)\n\nDependabot supports GitHub Actions as a package manager. It can automatically create pull requests to update your workflows when new versions of actions are released. By introducing changes through PRs you can ensure that the changes are reviewed before merging and don't cause any issues.\n\n#### [Starter workflows](https://docs.github.com/en/actions/using-workflows/creating-starter-workflows-for-your-organization)\n\n\u003e [!NOTE]  \n\u003e Starter workflows require a public .github repository, they are not available for private repositories.\n\nStarter workflows are a great way to provide pre-written workflows to your users.\n\n#### [Repository templates](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-template-repository)\n\nRepository templates allow you to create a repository that can be used as a template for new repositories. This template can include workflows, actions, and other files that you want to be included in new repositories.\n\n#### [Sharing secrets and variables within an organization](https://docs.github.com/en/actions/using-workflows/sharing-workflows-secrets-and-runners-with-your-organization#sharing-secrets-and-variables-within-an-organization)\n\n## Conclusion\n\nSummarize the key points of the framework and its benefits.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faustenstone%2Fgithub-actions-best-practices","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faustenstone%2Fgithub-actions-best-practices","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faustenstone%2Fgithub-actions-best-practices/lists"}