{"dataset":{"id":"00000000-0000-0000-0000-000000000031","slug":"github-actions-best-practices","name":"GitHub Actions best practices","description":"Source-linked guidance on GitHub Actions: workflow triggers and schedules, runner selection, dependency caching, secrets and environments, and security hardening. Scoped to GitHub Actions; not a general CI/CD corpus.","visibility":"public","version":1,"documentCount":5,"publisher":"Koskamo editorial","license":"Original summaries; linked sources retain their own terms.","reviewedAt":"2026-10-04T00:00:00.000Z","readOnly":true,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"},"total":5,"documents":[{"title":"Security hardening: script injection and third-party actions","sourceUrl":"https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions","text":"Against script injection, prefer a JavaScript action that receives the context value as an argument instead of an inline script; when an inline script must handle untrusted input, assign the expression to an intermediate environment variable — for example env: TITLE: ${{ github.event.pull_request.title }} — so the value never participates in script generation, and double-quote shell variables to avoid word splitting. Treat pull_request_target and workflow_run as privileged triggers that can carry repository write access and referenced secrets: avoid pull_request_target unless needed, prefer workflow_run for privilege separation, and never check out untrusted pull request code under these triggers. Audit and rotate registered secrets periodically, and gate environment secrets behind required reviewers. For third-party actions, pin to a full-length commit SHA — currently the only way to consume an action as an immutable release — verifying the SHA is from the action's repository, not a fork; use tags only for trusted creators, since tags can be moved or deleted. Audit the action's source code, restrict GITHUB_TOKEN permissions, add .github/workflows to CODEOWNERS so changes require designated review, and use OpenID Connect for short-lived cloud access tokens. Scope: GitHub Actions. Reviewed October 4, 2026.","id":"github-actions-best-practices:Security hardening: script injection and third-party actions","version":1,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"},{"title":"Secrets at repository, environment, and organization level","sourceUrl":"https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions","text":"Create secrets at the repository, environment, or organization level; in organization repositories this requires admin access. Organization secrets carry an access policy — all repositories, private repositories only (the default), or a selected list of repositories. With the exception of GITHUB_TOKEN, secrets are not passed to the runner when a workflow is triggered from a forked repository; they are also not automatically passed to reusable workflows and are unavailable to workflows triggered by Dependabot events. Reference secrets through the secrets context, for example ${{ secrets.SuperSecret }}, as an action input or environment variable; an unset secret evaluates to an empty string. Secrets cannot be referenced directly in if: conditionals — set them as job-level environment variables and reference those instead. Mask any sensitive value that is not a GitHub secret with ::add-mask::VALUE so it is redacted from logs, avoid passing secrets on the command line where ps or security audit events can expose them, and quote shell variables that hold secrets. Where a cloud provider supports OpenID Connect, configure OIDC authentication instead of storing long-lived credentials as secrets. Scope: GitHub Actions. Reviewed October 4, 2026.","id":"github-actions-best-practices:Secrets at repository, environment, and organization level","version":1,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"},{"title":"Dependency caching with actions/cache","sourceUrl":"https://docs.github.com/en/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/caching-dependencies-to-speed-up-workflows","text":"actions/cache (actions/cache@v4) restores a cache by exact key match, then partial key matches, then restore-keys checked sequentially for partial matches; on a partial match the most recent cache is restored. An exact match is a cache hit; on a miss the action saves a new cache under the provided key and paths only if the job completes successfully. Existing caches cannot be modified — change contents by creating a new cache with a new key. The required key can combine variables, context values, static strings, and functions up to a maximum of 512 characters; the required path accepts a single path or several on separate lines, and restore-keys lists fallback keys one per line in the order they are tried. GitHub removes entries that have not been accessed in over 7 days. Total cache size defaults to 10 GB per repository, a limit enterprise owners, organization owners, or repository administrators can increase; once reached, eviction deletes caches in order of last access date, oldest first. Rate limits allow 200 cache uploads and 1,500 downloads per minute per repository. Scope: GitHub Actions. Reviewed October 4, 2026.","id":"github-actions-best-practices:Dependency caching with actions/cache","version":1,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"},{"title":"Choosing runners with runs-on","sourceUrl":"https://docs.github.com/en/actions/how-tos/writing-workflows/choosing-where-your-workflow-runs/choosing-the-runner-for-a-job","text":"Use jobs.<job_id>.runs-on to define the machine a job runs on: a GitHub-hosted runner, a larger runner, or a self-hosted runner. Runners are targeted by labels, group membership, or both, and runs-on accepts a single string, a variable, an array of strings and variables, or a key:value pair using the group or labels keys. An array requires a runner matching every value — runs-on: [self-hosted, linux, x64, gpu] picks a self-hosted machine carrying all three labels — while jobs.<job_id>.strategy fans a job out across multiple machines. Quote expressions such as \"${{ inputs.chosen-os }}\"; simple strings like self-hosted need no quotes. On GitHub-hosted runners each job runs in a fresh instance of the runner image. Standard labels include ubuntu-latest (also ubuntu-24.04, ubuntu-22.04, and ubuntu-26.04), windows-latest (windows-2025, windows-2022), and macos-latest (macos-14, macos-15, macos-26). Standard GitHub-hosted runners are free and unlimited for public repositories; private repositories draw on the account's free minutes allotment and are then billed per minute. Scope: GitHub Actions. Reviewed October 4, 2026.","id":"github-actions-best-practices:Choosing runners with runs-on","version":1,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"},{"title":"Workflow triggers and scheduled runs","sourceUrl":"https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows","text":"Workflow triggers are the events that cause a workflow to run: activity on GitHub, a scheduled time, or an external event, and not all webhook events trigger workflows. Many events have multiple activity types, and the types keyword limits runs to specific ones. The schedule event uses five-field POSIX cron syntax; runs are in UTC by default, accept an IANA timezone string, occur at most once every 5 minutes, and always target the latest commit of the default branch. Schedules can be delayed under high load — including the start of every hour — and in public repositories scheduled workflows are disabled after 60 days without repository activity; non-standard shortcuts like @daily or @weekly are unsupported. Workflows do not run on pull_request activity while a merge conflict exists. For mergeable pull requests, GITHUB_REF points at the merge branch, so actions/checkout tests the merged result; check out github.event.pull_request.head.sha to test only head commits. Pull requests created or updated with GITHUB_TOKEN require write-access approval for opened, synchronize, or reopened runs; other GITHUB_TOKEN-triggered events, except workflow_dispatch and repository_dispatch, create no runs at all. Scope: GitHub Actions. Reviewed October 4, 2026.","id":"github-actions-best-practices:Workflow triggers and scheduled runs","version":1,"createdAt":"2026-10-04T00:00:00.000Z","updatedAt":"2026-10-04T00:00:00.000Z"}]}