GH-200 quick-recall
GH-200 flashcards
Flip through 9 cards — one per GH-200 topic — and self-test the key exam facts. Free, no account needed. These exams reward fast recognition, which is exactly what flashcards train.
1 / 9
Every GH-200 flashcard, by exam domain
94 key facts across 5 domains — the full deck below, so you can scan it even without the interactive cards.
Author and manage workflows
24% of the exam- 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).
- 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.
Consume and troubleshoot workflows
19% of the exam- 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.
- 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.
Author and maintain actions
18% of the exam- 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.
- 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.
Manage GitHub Actions for the enterprise
24% of the exam- 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.
- 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.
Secure and optimize automation
15% of the exam- 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).
Keep studying GH-200
GH-200 flashcards: your questions
Source
Exam structure, domain weights and scoring on this page come from the official GH-200 exam guide.