Exam tips & caveats

Everything you want in your head the night before: the numbers that turn up in answer options, the places where the study guide, the Learn modules and the live documentation disagree, the mistakes candidates make most often, and a lookup table from typical scenario wording to the answer the exam expects.

Page
Final review
Exam
GH-200
Skills measured
January 2026
Sections
8

Key numbers and limits

NumberWhat it is
100 min · 700Exam time · passing score (out of 1,000); retake after 24 hours
2 yearsValidity of the certification
6 h · 5 daysMaximum job time on GitHub-hosted · self-hosted runners
360 minDefault timeout-minutes for a job
35 daysMaximum life of a workflow run, waiting and approvals included
24 hQueue limit for self-hosted jobs; maximum life of GITHUB_TOKEN
256Jobs a matrix can generate per run
25 · 65,535workflow_dispatch inputs · input payload characters
10 · 50Reusable workflow nesting levels · unique reusable workflows per workflow file
3Levels of workflow_run chaining; also tags per push that still create an event
5 min · 60 daysShortest schedule interval · inactivity before public-repo schedules are disabled
10 GB · 7 daysDefault cache storage per repository · eviction of caches not accessed
90 daysDefault artifact and log retention (public 1–90, private and internal up to 400)
30 days · 50Re-run window · re-runs per run
6 · 43,200 min · 30 daysRequired reviewers per environment · maximum wait timer · approval wait before the job fails
100 · 1,000 · 100Secrets per repository · organisation · environment (48 KB each)
500 · 1,000 · 100Variables per repository · organisation · environment (48 KB each, 256 KB per run)
1 MB · 50 MBOne job output · all outputs in a run
1 MiB · 20Job summary per step · step summaries shown per job
14 days · 1 dayOffline time before a self-hosted · ephemeral runner is removed
30 days · 1 hourRunner update window before it stops getting jobs · registration token lifetime
20 · 40 · 60 · 500Concurrent standard-runner jobs on Free · Pro · Team · Enterprise (macOS: 5, 5, 5, 50)
1,000/hREST API requests per repository with GITHUB_TOKEN (15,000 on Enterprise Cloud)
500 KBMaximum workflow file size

Renames and retired syntax

The full table is on the Foundations page. The five that cost the most marks:

  • Starter workflows = workflow templates.
  • ::set-output and ::save-state → $GITHUB_OUTPUT and $GITHUB_STATE; ::set-env and ::add-path → $GITHUB_ENV and $GITHUB_PATH.
  • upload-artifact@v3 → @v7 (and download-artifact@v8); v4 and later are immutable per name.
  • runs.using: node16 / node20 → node24.
  • Organisation "required workflows" → a ruleset with Require workflows to pass before merging.

Where the study guide, Learn and the docs disagree

When the official sources disagree, these notes follow the live documentation. Here is every discrepancy found while writing them, checked on 5 November 2026, so neither version throws you.

Source saysThe documentation and product sayWhat to remember
Study guide: "starter workflows""Workflow templates", still stored in actions/starter-workflowsSame feature, two names
Study guide: YAML anchors, aliases and merge <<Docs describe only & anchors and * aliases (supported since September 2025); community reports say << is still rejectedExpand merged mappings when reading; do not rely on << in a workflow
Study guide: "immutable actions rollout on hosted runners" and "immutable actions enforcement"Immutable actions were removed from GitHub's roadmap on 11 December 2025. What shipped: immutable releases (October 2025), the SHA pinning policy (August 2025) and workflow lockfiles (GA 28 October 2026)"Make the version unchangeable" = full SHA, lockfile or immutable release
Study guide: "Ubuntu 20.04 deprecation, Windows Server 2025 migration for windows-latest"Both finished in 2025. The live change is ubuntu-latest moving to Ubuntu 26.04 (19 October – 19 November 2026)The lesson is the same: -latest labels move; pin when you need reproducibility
Study guide: "required reviewers for unverified actions"No single setting does thisAllowed-actions policy (verified creators plus patterns) and CODEOWNERS review of workflow changes
Study guide: retention policies "(logs, artifacts, workflow runs)" via RESTOne artifact-and-log-retention setting per enterprise, organisation and repository; runs, logs and artifacts can also be deleted individuallyLower levels can only shorten the retention
Study guide: "Microsoft associate, expert and specialty certifications expire annually"The GH-200 certification page: GitHub certifications are valid for two years; GitHub is moving to Microsoft's recertification process and extends certifications expiring before then by six monthsTwo years for GH-200
Study guide: "Get trained" links only the learning path's part 1Part 2 holds the custom actions, GitHub Packages and enterprise modulesDo both parts
Learn, Create a custom GitHub action: runs.using: "node16"node24; Node 16 and Node 20 are gone from the runnersAny answer with node16 or node20 is outdated
Learn samples: actions/checkout@v4, setup-node@v4, actions/cache@v4Current majors are checkout@v7, setup-node@v7, cache@v6, upload-artifact@v7, download-artifact@v8Old majors still appear in questions; recognise them
Older material: pull_request_target runs the PR base branch's workflow; checkout of the PR head "just works"Since 8 December 2025 it always runs the default branch's workflow; checkout@v7 refuses fork PR code there without allow-unsafe-pr-checkoutThe safe answer never runs PR code with secrets
Older material: reusable workflows nest 4 deep, 20 per file; 10 dispatch inputs10 levels and 50 workflows (November 2025); 25 inputs (December 2025)Use the new numbers
Certification page: practice assessment"Not currently available"Use the exam sandbox and hands-on practice

Commonly mistaken topics

Each one reads as a failed run and the run that fixed it.

Jobs with needs
Trap

A job with needs: build runs once build has finished.

Correct

It runs only if build succeeded; otherwise it is skipped, and the skip propagates. To run anyway, add if: always() (or !cancelled()) and check needs.build.result.

Conditions and the implicit success()
Trap

if: github.ref == 'refs/heads/main' on a notification step runs on main even after a failure.

Correct

Without a status function, success() && is added, so it is skipped after a failure. Use if: failure() && … or always() && ….

Boolean dispatch inputs
Trap

if: github.event.inputs.dry-run is false when the box is unticked.

Correct

github.event.inputs holds strings, and 'false' is truthy. Use inputs.dry-run, which keeps the boolean type.

GITHUB_ENV in the same step
Trap

After echo "X=1" >> "$GITHUB_ENV", $X is set in the same run script and in the next job.

Correct

It is set for the following steps of the same job only. Use a shell variable within the step, and a job output to cross jobs.

Secrets on fork pull requests
Trap

A pull_request run from a fork can read repository secrets if the workflow references them.

Correct

Fork PR runs get no secrets and a read-only GITHUB_TOKEN. pull_request_target has secrets but runs the default branch's code — never check out and run the PR there.

Workflows triggering workflows
Trap

A tag pushed with GITHUB_TOKEN starts the on: push: tags release workflow.

Correct

Events created with GITHUB_TOKEN start no new runs, except workflow_dispatch and repository_dispatch. Use a GitHub App token, or dispatch the workflow.

Cache versus artifact
Trap

Use actions/cache to hand the build output from the build job to the deploy job.

Correct

Use an artifact: it belongs to the run and is guaranteed to be there. Caches are for dependencies, can be evicted at any time, and are scoped by branch.

Composite actions and secrets
Trap

A composite action can read ${{ secrets.NPM_TOKEN }} directly.

Correct

Composite actions have no secrets context. Declare an input and have the workflow pass the secret into it.

What a reusable workflow inherits
Trap

The called workflow sees the caller's env values and secrets automatically.

Correct

Neither. env is never propagated — use inputs — and secrets must be mapped or passed with secrets: inherit. The github context, by contrast, is the caller's.

Docker actions on any runner
Trap

A Docker container action works on windows-latest and macos-latest because Docker runs there.

Correct

Docker container actions, service containers and job containers need a Linux runner. Write a JavaScript action for cross-platform use.

Reaching a service container
Trap

A job running in container: node:24 reaches its Postgres service at localhost:5432.

Correct

In a container job, use the service label as the hostname (postgres:5432). localhost plus a ports mapping is for jobs that run directly on the runner.

Environment secrets
Trap

Environment secrets are available to every job in the workflow, like repository secrets.

Correct

Only a job that names the environment gets them, and only once its protection rules pass — they are read when that job starts.

Granting one permission
Trap

Adding permissions: pull-requests: write keeps the token's other default scopes.

Correct

Once any scope is listed, every unlisted scope becomes none. List everything the job needs — typically contents: read as well.

Version tags are fixed
Trap

uses: vendor/action@v1.4.2 always runs the same code.

Correct

Tags can be moved or recreated. Only a full commit SHA is fixed — or a commit recorded in a workflow lockfile, or a tag protected by an immutable release.

Scheduled runs
Trap

A schedule runs on every branch that contains the workflow, at the runner's local time.

Correct

Schedules run on the latest commit of the default branch, in UTC unless the entry sets a timezone, and may be delayed under load.

Re-running a workflow
Trap

Re-running picks up the latest commit and runs with the permissions of whoever clicked re-run.

Correct

A re-run uses the same commit and ref, and the privileges of the actor who triggered the original run.

continue-on-error and step results
Trap

After a failed step with continue-on-error: true, steps.x.conclusion == 'failure'.

Correct

outcome is failure; conclusion is success. Test outcome to react to the real result.

OIDC needs a stored credential
Trap

OIDC to Azure still needs the client secret stored as a repository secret.

Correct

No secret at all: a federated credential trusts GitHub's token. The job needs id-token: write, and the IDs can live in variables.

Stopping a workflow
Trap

Delete the workflow file to pause a noisy schedule for a week.

Correct

Disable it: the file and history stay, and enabling it again is one click. Deleting is a commit, and other branches with the file can still trigger it.

Decision trees

flowchart TD
  Q["Share automation across repositories"] --> A{"Should later changes<br/>reach every user?"}
  A -->|"no — a starting point"| T["Workflow template"]
  A -->|"yes"| B{"Whole jobs, with their own<br/>runners, environments, secrets?"}
  B -->|"yes"| R["Reusable workflow<br/>on: workflow_call"]
  B -->|"no — steps inside a job"| C["Composite action"]
Template, reusable workflow or composite action.
flowchart TD
  Q["The workflow must authenticate to…"] --> A{"This repository on GitHub?"}
  A -->|"yes"| GT["GITHUB_TOKEN<br/>with minimal permissions"]
  A -->|"no"| B{"A cloud provider?"}
  B -->|"yes"| OIDC["OIDC federation<br/>id-token: write, no stored key"]
  B -->|"no"| C{"Other repositories, or must<br/>trigger other workflows?"}
  C -->|"yes"| APP["GitHub App installation token"]
  C -->|"no — a third-party service"| SEC["Environment secret<br/>scoped to the deploying job"]
Which credential a workflow should use.

Scenario → answer lookup

The scenario says…Reach for
"Run only when files under docs/ change"on: push: paths: ['docs/**']
"Let operators start a deploy and pick the target"workflow_dispatch with a choice or environment input
"An external system should start the workflow"repository_dispatch with an event_type
"Run the same tests on three OSes and two runtimes"strategy.matrix; fail-fast: false to see every result
"Tests need a real database"services: with a health check
"Avoid repeating the same env block in one file"A YAML anchor and alias
"Pass a version from one job to the next"$GITHUB_OUTPUT → job outputs → needs.<job>.outputs
"Show test results on the run page"$GITHUB_STEP_SUMMARY
"A new push should cancel the PR's running build"concurrency with cancel-in-progress: true
"Deployments must run one at a time, none dropped"concurrency with queue: max
"Production needs a human approval"Environment with required reviewers
"Why was this step skipped?"Re-run with debug logging; read the ##[debug] condition trace
"Retry only the flaky Windows leg"Re-run that matrix job
"Every team's pipeline must follow one central definition"Reusable workflow, plus a ruleset requiring it
"Bundle three setup steps used in many jobs"Composite action
"Share a private action with the rest of the organisation"The action repository's Actions Access setting
"Only allow GitHub and verified-creator actions"Allowed-actions policy at organisation or enterprise level
"Stop one compromised action everywhere, now"A !owner/repo@* blocklist pattern
"Jobs fail behind the organisation's IP allow list"Larger runners with static IPs, or self-hosted runners
"Keep production runners for the deploy workflow only"Runner group restricted to selected workflows
"Clean machine for every job on our own infrastructure"Ephemeral self-hosted runners, autoscaled with ARC
"Which Python versions are preinstalled?"The image README in actions/runner-images, linked from Set up job
"Rotate a secret from a script"Fetch the public key, encrypt, PUT …/actions/secrets/{name} — or gh secret set
"Issue titles end up in a run: script"Pass them through env: and quote them
"Deploy to the cloud without long-lived keys"OIDC: id-token: write and a federated credential
"Prove a binary came from our pipeline"actions/attest, then gh attestation verify before deploy
"Make sure the action code never changes under us"Full-SHA pins (enforced by policy) or a workflow lockfile
"Artifacts are filling the storage quota"Shorter retention-days and a lower retention policy via the API

Exam-day caveats

Read the YAML before the question

Many items are a workflow followed by "what happens?". Read on:, permissions and every needs and if before you read the answer options — the trap is usually a filter that does not match, a skipped dependency or a missing scope.

Watch for the old syntax in the options

::set-output, @v3 artifact actions, node16 and ubuntu-20.04 make an option wrong today, however tidy it looks.

Prefer the enforceable answer

When two options both "work", the exam tends to prefer the one that is enforced by the platform — a policy, a protection rule, a permission, a pin — over one that relies on people remembering to do the right thing.

Pre-exam checklist

  • I can name the event, filters and branch behind any on: block, including schedule, workflow_dispatch and pull_request_target.
  • I can expand a matrix with include and exclude, and an anchored file, in my head.
  • I know which contexts are available in a job if, runs-on and a step if.
  • I can move a value step → step, job → job and reusable workflow → caller.
  • I can tell a cache from an artifact, and know their scope, retention and limits.
  • I can write action.yml for JavaScript, Docker and composite actions, and know where each runs.
  • I know the Marketplace publishing requirements and why consumers pin to SHAs.
  • I can set allowed-actions, SHA pinning, fork PR and token-permission policies, and know they only tighten downwards.
  • I can register a self-hosted runner, put it in a group and target it with labels.
  • I know secret and variable scopes, precedence and limits, and how the API encrypts secrets.
  • I can spot script injection and fix it with env:, and explain why pull_request_target is dangerous.
  • I can configure OIDC to a cloud provider and read a subject claim.
  • I can attest an artifact and verify it before deployment.
  • I have tried the exam sandbox.