SaveMyCert
Log in
5 of 5 free questions left today·for 30 a day
GH-200 last-day review

GH-200 cheat sheet — every exam topic on one page

94 key facts across 5 exam domains — every topic on the GH-200 blueprint, with the exam pattern behind each. A condensed cheat sheet, distilled from the full GH-200 revision notes. Skim it the week of your exam.

Updated

Author and manage workflows

24% of the exam

GitHub Actions Triggers, Events, Caching, Artifacts and Outputs (GH-200)

  • schedule, workflow_dispatch, repository_dispatch and workflow_run only use workflow files on the default branch; a dispatch can then target any ref.
  • Cron is UTC unless a timezone key is set, runs can be delayed, and public repositories disable schedules after 60 days without activity.
  • Setting types on pull_request replaces the defaults (opened, synchronize, reopened); branch and path filters must both match, and paths-ignore skips only when every file is ignored.
  • Fork pull requests on pull_request get a read-only token and no secrets; pull_request_target and workflow_run run with base-repository privileges, so never run fork code in them. Scope the token with permissions: — once any scope is listed, the rest become none.
  • Most events caused by the GITHUB_TOKEN (tags, releases, issues, pushes outside a pull request) start no new runs, except workflow_dispatch and repository_dispatch; pull_request runs it causes wait for approval. Use a GitHub App token or PAT for follow-on runs.
  • workflow_call inputs are boolean, number or string only; required secrets must be passed or inherited (same org or enterprise); caller env never propagates.
  • Outputs travel step (GITHUB_OUTPUT) → job outputs → needs; reusable workflows add on.workflow_call.outputs, and callers read needs.<calling-job>.outputs.
  • Cache dependencies (key, newest prefix match via restore-keys, immutable, 7-day eviction); use artifacts for files a run produces, with unique names per run in v4.
  • Set retention with the artifact-and-log-retention endpoints at org or repo level; DELETE runs/{id}/logs removes logs but keeps the run.
  • GITHUB_STEP_SUMMARY is per step; badges are addressed by workflow file name; environment secrets reach only jobs with environment: after protection rules pass.
  • A workflow_run run checks out the default branch by default; to ship the commit the triggering run tested, check out github.event.workflow_run.head_sha (head_branch's tip may have moved).
How the exam tests this

Expect scenario questions built on short YAML snippets: a workflow that never ran, a value that arrives empty, an upload that fails, or a security review of a trigger. You are asked to predict which event starts a run, to spot the missing piece in an output or secret chain, or to choose the trigger, filter, token, API call or environment setting that meets every stated constraint. Wrong options are usually real Actions features used in the wrong place — a near-twin trigger, GITHUB_ENV where an output is needed, a repository secret where an environment secret is required — and some items ask you to select two answers.

GitHub Actions Workflow Structure: Jobs, Conditions, Matrices and Contexts (GH-200)

  • An if without a status function implies success(); use always() or !cancelled() plus needs.<job>.result to run after an upstream failure or skip, and remember && binds tighter than ||.
  • A leading ! in an if must be inside ${{ }} (or quoted), because YAML reads an unquoted ! as a tag.
  • Jobs run in parallel unless needs orders them; a failed or skipped needed job skips its dependents, and the needs context holds direct dependencies only.
  • A job skipped by its if reports Success to a required check, but a workflow skipped by a path or branch filter or a commit-message skip leaves the check Pending; skip the job, not the workflow.
  • Workflow commands (::warning file=,line=::, ::group::, ::add-mask::, ::stop-commands::) are lines printed to stdout; a GITHUB_ENV value reaches later steps only.
  • The most specific env definition wins; default GITHUB_* and RUNNER_* variables are in the shell, not in the env context — use the github and runner context properties in expressions.
  • Service containers run on Linux runners; container jobs reach them by label, runner jobs via localhost and mapped ports; --health-cmd options make the runner wait for readiness.
  • exclude removes partial matches first, include then adds keys or new combinations without overwriting originals; fail-fast cancels the matrix, continue-on-error tolerates one variant, max-parallel caps concurrency; matrix jobs that share an output name overwrite each other, so give each one a unique output name.
  • -latest labels move (windows-latest is Windows Server 2025; ubuntu-latest moves from 24.04 to 26.04 in a gradual rollout from 19 October 2026; ubuntu-20.04 is retired); pin a version label to control upgrades and test runner.os instead of the label.
  • jobs.<id>.if sees only github, needs, vars and inputs; secrets are never allowed in if, so map them into env and test env in step conditions.
  • ${{ }} is substituted into scripts before they run, so pass untrusted input through env or action inputs; encoded, derived and structured secret values are not redacted, and only a full commit SHA (or an immutable release) fixes the action code that runs.
How the exam tests this

Expect scenario items, often with a short YAML snippet, that ask what a workflow does or which change fixes it under a stated constraint. Dependency and condition items ask which jobs run or are skipped after a failure, and which if expression reacts to exactly one job's outcome without firing on cancellation or on an earlier failure. Context items test where each context is allowed (secrets in conditions, matrix or runner in job-level keys), env precedence, and outcome versus conclusion. Matrix items ask which include or exclude entry produces exactly the required jobs, how fail-fast, continue-on-error and max-parallel combine or differ from concurrency, and how to pass outputs from several matrix jobs. Required-check items contrast a job skipped by if with a workflow skipped by a filter. Service-container items hinge on host name, port mapping and health checks. Security items test script injection through ${{ }}, which values redaction misses, which uses: references can change, and what the SHA-pinning policy accepts. Distractors are usually real Actions features applied in the wrong place, so check each option against where it is evaluated and what it actually controls.

Consume and troubleshoot workflows

19% of the exam

Troubleshoot GitHub Actions Workflow Runs: Logs, Matrix Re-runs and Artifacts (GH-200)

  • A run starts only when the event, its activity type and every filter match; branches plus paths must both pass, and branches-only push filters ignore tags.
  • pull_request defaults to opened, synchronize and reopened; merging a pull request is a push to the base branch.
  • A workflow skipped by a filter or [skip ci] creates no run, so its required check stays Pending; a job skipped by if reports Success.
  • pull_request runs build refs/pull/N/merge, a merge of the head into the current base, not the branch tip.
  • The default Linux shell is bash -e without pipefail; shell: bash adds pipefail. Log search covers expanded steps only.
  • ACTIONS_STEP_DEBUG adds step debug lines, ACTIONS_RUNNER_DEBUG adds runner diagnostic logs; a secret beats a variable of the same name.
  • A re-run is a new attempt of the same run on the same commit and ref, with the initial actor's privileges; a fix needs a new run.
  • Matrix: cross product, then exclude (partial match), then include; fail-fast cancels the rest, so cancelled variants are unknown.
  • Re-run failed jobs retries every failed job plus dependents; re-run one variant by its job ID to retry only that job and its dependents.
  • Log and artifact downloads are 302 redirects valid for one minute; artifacts are found and deleted by ID, and zipped artifacts lose file modes.
  • download-artifact reads another run only when github-token is set (run-id alone is ignored); with GITHUB_TOKEN, an explicit permissions block must also grant actions: read.
How the exam tests this

Expect scenario items that show a short YAML snippet or describe a run page and ask what happened or what to do next: which pushes, pull request events and merges start a run, why a required check is pending, which commit a pull request run built, why a step passed although a command failed, and which debug setting produces the missing output. Re-run items contrast re-run all jobs, failed jobs and one job by ID, and what a re-run keeps (commit, ref, actor), often with a constraint such as no commits, no repository-wide settings, or retrying one matrix variant but not another. Matrix and anchor items ask you to expand the configuration and count or name the resulting jobs. API and CLI items test exact endpoints: run vs attempt vs job logs, artifacts by run, by name and by ID, the one-minute redirect, gh run view --log-failed or gh run download -n, and what download-artifact needs (run-id, github-token, actions: read) to fetch another run's artifact.

GitHub Actions Workflow Templates, Reusable Workflows and Composite Actions (GH-200)

  • Template = a one-time copy; reusable workflow = central jobs called by a job; composite action = central steps run inside a job.
  • A workflow created from a template is independent: customise it in its own repository, and later template edits never reach it.
  • Organization templates live in workflow-templates/ of the .github repository as <name>.yml plus <name>.properties.json (name and description required).
  • filePatterns decides where a template is suggested; $default-branch is replaced with the default branch's name once, at creation, so the copy keeps that literal name after a rename and the placeholder means nothing in an ordinary workflow file.
  • A public .github repository serves all repositories, internal serves internal and private, private serves private only; people also need Read access to a non-public one.
  • Call reusable workflows with jobs.<id>.uses: owner/repo/.github/workflows/file@ref, or $/.github/workflows/file (recommended) or ./.github/workflows/file for the caller's own commit; no expressions in uses.
  • Pin to a full commit SHA for immutability; a tag beats a branch of the same name.
  • Calling jobs allow only name, uses, with, secrets, strategy, needs, if, concurrency and permissions; environments go on the called job.
  • Private reusable workflows need the holding repository's Actions access setting; chains allow ten levels, no loops, and permissions that only go down.
  • Disabling stops a workflow on every branch and keeps the file; deleting the file only affects the branch that drops it; re-enable auto-disabled scheduled workflows explicitly.
How the exam tests this

Expect scenario items that state a requirement and ask which sharing mechanism fits: a central fix every repository picks up without edits, shared steps that must run inside an existing job's workspace, or a shared job on a different runner with per-step logs. Template items test that a created workflow is an independent copy, where organization templates and their .properties.json metadata live, filePatterns versus trigger filters, when $default-branch is substituted and what a created copy holds after a branch rename, and which repositories see templates from a public, internal or private .github repository. Reusable workflow items show a short YAML calling job and ask which uses value or ref is valid, which keys must be removed, how to fan out with a matrix, where an environment belongs, and why a call to a private or nested workflow fails. Disable-versus-delete items add constraints such as keeping the file, changing no branch or scripting many repositories.

Author and maintain actions

18% of the exam

Create Custom GitHub Actions: JavaScript, Docker and Composite Actions (GH-200)

  • JavaScript actions run on every runner OS and start fastest; Docker actions, docker:// steps and job containers are Linux-only; composite actions package steps (or existing scripts) and can call other actions.
  • action.yml or action.yaml must contain name, description and runs; required: true on an input is not enforced, so validate in code.
  • An action can read the job token through github.token even when the workflow passes nothing, so token inputs default to ${{ github.token }} and callers override them only for wider access.
  • The runner never runs npm install for an action: commit node_modules or an ncc bundle and point main at it, with using: node24.
  • Composite actions need shell on every run step, an explicit value for each output and the inputs context instead of INPUT_ variables; their steps start in the caller's workspace, so shipped files are reached through github.action_path.
  • In Docker actions, args override CMD, entrypoint overrides ENTRYPOINT, docker:// pulls a prebuilt image, and exec form does not expand $VARIABLES.
  • Action Dockerfiles must not use USER or WORKDIR, the workspace is mounted over /github/workspace, and entrypoint.sh must be executable in Git.
  • post runs at job end with post-if defaulting to always(); status functions in pre-if/post-if read the job's status; pre is not supported for local actions; saveState/getState pass private values between scripts.
  • setOutput, exportVariable, addPath and saveState write environment files; setFailed sets the exit code without stopping the code.
  • Hosted runners use an immutable version where one exists and fall back to Git; only a full commit SHA (or an immutable version) guarantees unchanged code.
How the exam tests this

Expect scenario items about building or fixing a custom action: which action type fits a set of constraints (runner operating systems, start-up time, independence from the runner image, one step inside an existing job), and what to change when an action fails. Many show a short action.yml, Dockerfile or uses: snippet and ask which runs block, reference or metadata change is valid, or which arguments a container receives. Others test toolkit behaviour inside JavaScript actions (outputs, PATH, state, failing a step), pre/post timing, composite inputs, outputs and file paths (github.action_path), token input defaults, post-if job-status conditions, Dockerfile rules, and how immutable actions changed version resolution, self-hosted firewall hosts and pinning guarantees. Constraints such as no caller steps, no Dockerfile change or a value that must stay private decide between near-identical options.

Share, Publish and Version GitHub Actions (GH-200)

  • Any workflow can use an action in a public repository with owner/repo@ref; Marketplace only adds discovery.
  • Private and internal actions are shared through Settings > Actions > General > Access on the action's repository — not people's permissions, caller tokens or allow lists.
  • Private actions admit only private callers, internal actions admit private or internal callers, and public repositories can use neither.
  • To reach several organizations while staying inside the enterprise, use an internal repository with the enterprise Access option.
  • ./ paths need a checkout; $/ uses the running commit without one; subfolder actions use owner/repo/path@ref with the ref last.
  • Marketplace needs a public repository with one root metadata file and a unique name that matches no other action, other account, category or GitHub feature.
  • Publish to Marketplace by publishing a release with the Marketplace option; the owner must accept the Developer Agreement, 2FA is required, and there is no review.
  • Delist by clearing the Marketplace option on every published release; a transfer keeps uses: working through a redirect but drops the verified badge for an unverified owner.
  • Release vX.Y.Z from a validated release branch, then move vX; breaking changes get a new major and the old major tag stays put.
  • Immutable releases lock tags and assets for future releases: draft, attach assets, publish — and keep moving major tags as plain tags without releases.
  • Automating the major tag move needs contents: write on the GITHUB_TOKEN and a forced push (git push --force origin v1), because the tag already exists on the remote.
How the exam tests this

Expect scenario items that state who must run an action and who may see its code, then ask which distribution model, Access option or repository visibility fits — including why a public, internal or other-organization caller is refused, and what a user-owned versus organization-owned repository can offer. Reference items show a short YAML step and ask which uses: value works for a root, subfolder or same-repository action, with constraints such as running the triggering commit or adding no step. Marketplace items test eligibility, which name values are rejected, why the publish checkbox is disabled, how listing and delisting work through releases, and what a repository transfer keeps or loses. Versioning items describe a fix or a breaking change and ask how to release it and which tags to move, what a workflow that moves the major tag needs (token permission and push type), how to serve two major versions, which consumer reference meets a stability or update requirement, how immutable releases change asset uploads and major tags, and how to package JavaScript or Docker releases so they run for consumers.

Manage GitHub Actions for the enterprise

24% of the exam

Govern GitHub Actions in the Enterprise: Policies, Templates, Secrets and Variables (GH-200)

  • Each policy level can only narrow the level above; organizations cannot loosen an enterprise policy, and repositories cannot override their organization.
  • Enablement decides where workflows run at all; the allowed-actions policy decides which actions they use; token permissions decide what they may change.
  • Owner-only allowed actions also block GitHub's own actions; the select option with "Allow actions created by GitHub" admits the actions and github organizations.
  • Allow/block lists exist only under the select option: OWNER/REPO@ref for actions, OWNER/REPO/PATH/FILE@ref for reusable workflows, * as a wildcard, ! to block. Local ./ actions are never restricted.
  • SHA pinning applies to actions; reusable workflows may keep tags. A declared permissions key sets every unlisted scope to none.
  • Ruleset-required workflows run on pull_request, pull_request_target and merge_group, ignore branch and path filters, and need a source repository whose visibility and Access setting suit the targets.
  • The lowest scope wins per name (environment > repository > organization); environment secrets reach only jobs that name the environment after its protection rules pass.
  • Secrets are written via REST as libsodium-encrypted values with the scope's key_id; variables use POST to create and PATCH to update, and an unset variable is an empty string.
  • Actions receive secrets only through inputs or env passed by the calling workflow; composite actions cannot read the secrets context.
How the exam tests this

Expect scenario items that describe an enterprise or organization requirement — who may run workflows, which publishers are acceptable, a compromised action, a moved tag — and ask which enablement, allowed-actions, pattern or pinning setting meets it, often with YAML showing which references comply. Token and fork items describe a failing release job, a 403 when opening a pull request, or contractors working from forks, and ask which setting or permissions key resolves it. Distribution items contrast workflow templates, Access sharing for private and internal repositories and ruleset-required workflows, including visibility rules, ignored filters and why a required workflow never starts. Secret and variable items show values at several scopes and ask which one a job receives, why a value is empty (plan, access policy, the 100-secret window, a missing environment key, naming rules) or where a credential should live, and REST or GitHub CLI items ask for the request or command that creates, updates or shares a value under constraints such as one rotation point or not resending the value.

Manage GitHub Actions Runners at Scale: Self-Hosted, Larger Runners and Runner Groups (GH-200)

  • runs-on as an array needs a runner with every label; labels are case-insensitive and choose among runners, they never restrict access.
  • runs-on with group plus labels requires the runner to be in that group and carry every label.
  • A job with no matching runner stays queued and fails after 24 hours; an assigned job not picked up within 60 seconds is re-queued.
  • Ephemeral runners (--ephemeral or JIT) take one job; autoscale with ARC runner scale sets or workflow_job queued/completed webhooks, never with the job-completed script.
  • --disableupdate obliges you to apply every runner release within 30 days; runners offline more than 14 days (ephemeral: 1 day) are removed.
  • Runner groups are the access boundary: repository access, public repositories off by default, enterprise groups need an org owner's grant, workflow access admits only jobs directly defined in listed workflows.
  • Self-hosted runners need only outbound HTTPS 443 to GitHub's domains; proxy variables go in the runner's .env, lowercase wins on Linux and macOS, and a restart is required.
  • With an IP allow list, add self-hosted egress IPs or use larger runners with static IP ranges; GET /meta ranges are not a supported allowlist, and macOS larger runners get neither static IPs nor Azure private networking.
  • Set up job > Runner Image shows the exact image and its Included Software; setup-* actions pin tool versions from the tool cache.
  • Install extra software with sudo apt-get update then install -y, a job container, or a custom image built with the snapshot keyword.
How the exam tests this

Questions on this topic are usually scenarios with one deciding constraint: a job that must reach exactly one kind of machine, runners that must be reserved for certain repositories or workflows, a firewall or IP allow list that must stay in place, a requirement for clean machines or no servers to maintain, or a tool version that must not drift. Options are concrete artefacts such as runs-on values, config.sh flags, .env lines, service commands, runner group settings and setup-action inputs, and the wrong ones are real features used in the wrong place: labels where a group is needed, repository access where workflow access is needed, usage metrics where performance metrics are needed, the job-completed hook where an ephemeral runner is needed, or static IP ranges where private networking is needed. Expect troubleshooting items that start from a symptom (Offline, waiting for a runner, permission denied on the Docker socket, a build broken by an image update) and ask for the cause or the evidence to collect.

Secure and optimize automation

15% of the exam

Secure and Optimize GitHub Actions: Permissions, OIDC, Pinning, Attestations and Caching (GH-200)

  • Required reviewers let the deployer approve their own run unless Prevent self-review is on, and admins can bypass the rules unless that option is cleared.
  • ${{ }} is pasted into script text before it runs, so untrusted values belong in env: and are read as "$VAR" or process.env, never as ${{ env.VAR }}.
  • Branch names, titles, bodies, comments, commit messages, author names or emails, and artifacts uploaded by fork runs are attacker-controlled, even when a privileged workflow_run reads them.
  • GITHUB_TOKEN is created per job, works on one repository, is attributed to github-actions[bot] and expires when the job ends.
  • Listing any permission sets the rest to none, and a job-level permissions block replaces the workflow-level one.
  • For automation across repositories that must outlive any employee, mint a narrowed GitHub App token instead of using a PAT.
  • OIDC needs id-token: write; adding environment: changes the sub claim to repo:ORG/REPO:environment:NAME, and pull_request jobs present repo:ORG/REPO:pull_request.
  • Pin third-party actions to a full 40-character SHA from the action's own repository, check that its action.yml pins its own nested actions, and let Dependabot's github-actions ecosystem propose updates.
  • Allowed-actions policy: set allowed_actions to selected, then GitHub-owned, verified creators and patterns, with ! entries to block.
  • Attestations prove where and how an artifact was built, not that it is safe; verify with --repo or --signer-workflow to trust a specific source.
  • Offline attestation checks need two files carried in: the bundle from gh attestation download (--bundle) and the root from gh attestation trusted-root (--custom-trusted-root).
How the exam tests this

Questions on this topic are scenarios built around one deciding constraint: no long-lived cloud keys stored in GitHub, the least access that still works, a second person approving every deployment, no human approval in GitHub, a credential that must outlive any employee, provenance that must come from one repository or one build workflow, a run on main that must never be cancelled, or a deployment network that cannot reach GitHub. Options are concrete artefacts such as permissions blocks, run: lines, OIDC subject strings, allow-list patterns, REST calls, gh attestation verify flags, cache keys and concurrency blocks, and the wrong ones are real features used in the wrong place: masking where injection must be stopped, ${{ env.X }} where "$X" is needed, a release tag where a SHA is needed, a wait timer where approval is needed, --owner where --repo is needed, or a workflow-level block where a job-level one decides. Expect troubleshooting items that start from a symptom (403 or not found on checkout, 401 after the job ended, an OIDC subject mismatch, a cache miss on every run, a pinned action that still ran changed code) and ask for the cause or the fix.

Facts fresh? Prove it.
Drill GH-200 practice questions with an explanation on every option.
Practice now

Where these GH-200 facts came from

GH-200 cheat sheet: your questions

Every key takeaway from all 9 GH-200 revision lessons — 94 facts — pulled onto one page and grouped by exam domain, with the exam pattern behind each topic. It is a compression of the notes, not a separate set of content, so it can never contradict them.

Source

Exam structure, domain weights and scoring on this page come from the official GH-200 exam guide.