GH-200 practice questions

20 free GH-200 practice questions with answers and explanations, covering workflow authoring, triggers, custom actions, runners, and securing GitHub Actions across an enterprise.

Study the full GH-200 course, free to start.

GH-200 exam at a glance

Skills measured from January 2026

Official GH-200 study guide on Microsoft Learn

20 free GH-200 practice questions

Automate your workflow with GitHub Actions, Part 1 of 2

Question 1. Which `on:` form restricts a workflow to pushes and pull requests on main only?

  1. An event-configuration map, listing branches under each event
  2. A single event, on: push
  3. An array, on: [push, pull_request]
  4. A schedule with a cron expression matching the branch
Show answer

Answer: A, An event-configuration map, listing branches under each event. A single event or an array triggers on all activity with no filtering. Restricting to particular branches, tags or files requires the event-configuration map form, where each event carries its own filters.

Question 2. A deploy job must run only when the preceding build job reported that something actually changed. How is that wired?

  1. Read `steps.build.outputs.changed` in the deploy job
  2. Use `needs: [build]` with `if: needs.build.outputs.changed == 'true'`
  3. Set an environment variable with GITHUB_ENV in the build job and read it in deploy
  4. Cache the flag in the build job and restore it in deploy
Show answer

Answer: B, Use `needs: [build]` with `if: needs.build.outputs.changed == 'true'`. Job outputs cross job boundaries through the `needs` context. The `steps` context is scoped to one job, and GITHUB_ENV only affects later steps within the same job, since jobs run on separate runners. Caches are for re-derivable data, not control flow.

Question 3. A team spends the first hour of every release day running the same lint, test and package steps by hand, and a step is occasionally missed. Beyond saving time, what is the strongest argument for automating the sequence?

  1. It removes the need for code review, since automation checks the code
  2. The same steps run the same way every time, so a missed step stops being possible
  3. It guarantees the build is faster than running the steps locally
  4. It transfers responsibility for failures from the team to GitHub
Show answer

Answer: B, The same steps run the same way every time, so a missed step stops being possible. The consistency argument is the one that holds. Automation runs an identical sequence on every trigger, which removes the human variability that lets a step be skipped under pressure. Speed is a common side effect but not the point, and review and responsibility do not move anywhere.

Question 4. A value is needed by several workflows across an organisation, is not sensitive, and changes occasionally. What is the appropriate home for it?

  1. An organisation variable, read through the vars context
  2. A hard-coded value in each workflow, updated when it changes
  3. An organisation secret, read through the secrets context
  4. A step-level env entry in every workflow that needs it
Show answer

Answer: A, An organisation variable, read through the vars context. Variables exist for non-sensitive configuration and can be set at organisation, repository or environment level, then read through the `vars` context. Using a secret would work but hides the value from logs unnecessarily and makes it harder to audit; hard-coding creates the update problem you already have.

Question 5. A workflow run appears in the Actions tab at 03:00 with no corresponding commit. You need to establish what started it, and you only have API access. What tells you?

  1. The run object's event property, alongside its commit SHA, actor and timestamp
  2. The name of the first job in the run
  3. The runner image the run was allocated
  4. The repository's branch protection settings
Show answer

Answer: A, The run object's event property, alongside its commit SHA, actor and timestamp. Workflow run objects returned by the REST API carry an `event` property naming the trigger, plus the commit SHA, actor and timestamp for tracing. In the interface the same information sits at the top of the run summary, and inside a workflow `github.event_name` exposes it.

Question 6. An end-to-end test job should upload browser screenshots when it fails, but the upload step never runs on red builds. What is missing?

  1. A needs: reference to the failing job
  2. retention-days set on the upload action
  3. The artifact name must be unique per run
  4. A condition such as if: always() or if: failure() on the upload step
Show answer

Answer: D, A condition such as if: always() or if: failure() on the upload step. A failing step stops the steps that follow, so an unconditional upload runs only when everything already passed, which is exactly when the diagnostics are least useful. `if: always()` runs it regardless, and `if: failure()` restricts it to red runs.

Question 7. A job occasionally hangs and consumes minutes until the platform's own limit terminates it. What is the appropriate fix in the workflow?

  1. continue-on-error: true, so a hung job does not fail the run
  2. concurrency, so only one instance of the job can run
  3. fail-fast: false, so the rest of the matrix continues
  4. timeout-minutes on the job, set to a value comfortably above its normal duration
Show answer

Answer: D, timeout-minutes on the job, set to a value comfortably above its normal duration. `timeout-minutes` sets your own ceiling rather than waiting for the platform's, so a hung job is cut short in minutes instead of hours. The others address different problems: overlapping runs, matrix behaviour, and how a failure is reported.

Question 8. A reviewer asks what continue-on-error: true on a single step actually changes, given that the step still fails. What is the accurate answer?

  1. Both the job and the run are still failed, and the setting only suppresses the annotation
  2. The job is failed but the run is reported as successful
  3. The step is marked failed, the remaining steps in the job still run, and neither the job nor the run is failed by it
  4. The step is skipped silently and nothing is recorded against it
Show answer

Answer: C, The step is marked failed, the remaining steps in the job still run, and neither the job nor the run is failed by it. Exit codes normally propagate: a non-zero exit fails the step, stops the rest of the job, fails the job, and skips anything declaring needs: on it. continue-on-error breaks that chain wherever you put it, on a step so the job carries on, or on a job so the run can still be reported as successful. The failure stays visible, it just stops being fatal.

Question 9. An organisation shortens its default artifact retention to reclaim storage, but usage does not fall. Why?

  1. Storage is measured before compression, so the change is invisible
  2. Retention changes apply only to new artifacts and log files, not to objects that already exist
  3. Retention settings take 90 days to take effect
  4. Retention can only be set at enterprise level, so a repository change is ignored
Show answer

Answer: B, Retention changes apply only to new artifacts and log files, not to objects that already exist. A retention change is forward-looking: existing artifacts keep their original period and must be deleted explicitly, manually from the run or through the Artifacts REST API. That is why an immediate saving does not appear.

Question 10. A GitHub Script automation has grown to eighty lines and is duplicated in three repositories. What should happen?

  1. Convert it into a Docker container action for isolation
  2. Split it across three shorter GitHub Script steps
  3. Move it into a JavaScript action, which gives metadata, versioning and publication
  4. Keep it inline but add comments so it is easier to read
Show answer

Answer: C, Move it into a JavaScript action, which gives metadata, versioning and publication. GitHub Script suits short, repository-specific chores. Long-lived logic shared across repositories belongs in a JavaScript action, where it can be versioned, published and consumed by all three rather than copied.

Automate your workflow with GitHub Actions, Part 2 of 2

Question 11. An organisation publishes an internal library as a package and wants only its own repositories to consume it. What determines who can install it?

  1. The package's visibility, which for a private package restricts access to those with permission on it
  2. The licence file in the source repository
  3. Whether the workflow that published it used GITHUB_TOKEN or a personal access token
  4. The retention period configured for the package
Show answer

Answer: A, The package's visibility, which for a private package restricts access to those with permission on it. Visibility is the control. A public package can be installed by anyone, while a private one is limited to accounts granted access. The token used to publish affects whether the publish succeeds, not who may consume the result afterwards.

Question 12. A nightly workflow is failing every night while a fix is developed. The team wants the noise to stop without losing the file or its history. What should they do?

  1. Disable the workflow, and re-enable it once fixed
  2. Delete the workflow file and restore it from git later
  3. Set continue-on-error: true on every job
  4. Add an if: false condition to each job
Show answer

Answer: A, Disable the workflow, and re-enable it once fixed. Disabling stops runs while leaving the file and run history intact and is reversible, which is precisely the stated requirement. Deleting loses the file from the branch, and masking failures with `continue-on-error` or `if: false` leaves a workflow that reports success while doing nothing.

Question 13. A composite action's step writes to $GITHUB_OUTPUT but the workflow fails with an error about the step. What is the most likely omission?

  1. The step needs continue-on-error: true to write outputs
  2. Composite actions cannot write to GITHUB_OUTPUT and must use GITHUB_ENV
  3. The run step does not declare shell:, which composite actions require
  4. The action.yml is missing a runs: image: key
Show answer

Answer: C, The run step does not declare shell:, which composite actions require. Every `run` step inside a composite action must declare its shell, unlike a workflow step which inherits job defaults. It is the most common first-time composite action error. Composite actions can and do use `GITHUB_OUTPUT`.

Question 14. You need an action that runs on Linux, macOS and Windows runners and starts as quickly as possible. Which type fits?

  1. A Docker container action, because the image guarantees consistency
  2. A composite action, because it is the only type that is cross-platform
  3. A JavaScript action, because it runs directly on the runner and is not tied to Linux
  4. Any type, since all three behave identically across operating systems
Show answer

Answer: C, A JavaScript action, because it runs directly on the runner and is not tied to Linux. Container actions are restricted to Linux runners and pay the cost of pulling or building an image, so cross-platform plus fast startup points to JavaScript. A composite action is cross-platform too, but it bundles steps rather than carrying its own logic.

Question 15. An action catches every exception and logs it with console.log so users are not alarmed by stack traces. A later job then consumes an output that was never produced. What is the root cause?

  1. The action is not failing properly: swallowing the error lets the step report success, so nothing stops the workflow and the later job runs on nothing
  2. The later job is missing a needs: entry
  3. console.log output is not captured in the run log
  4. The output should have been written to GITHUB_ENV rather than to GITHUB_OUTPUT
Show answer

Answer: A, The action is not failing properly: swallowing the error lets the step report success, so nothing stops the workflow and the later job runs on nothing. Wrap the logic in try and catch and call core.setFailed with a message that says what went wrong. That marks the step failed, which stops the workflow, and leaves a readable reason in the log. Hiding the stack trace is a reasonable thing to want. Hiding the failure is not.

Question 16. Which mitigation most directly removes the persistence that makes a compromised self-hosted runner dangerous over time?

  1. Using ephemeral runners that reset after each job
  2. Increasing the runner's disk encryption
  3. Adding the runner to a larger runner group
  4. Switching the runner's operating system to Windows
Show answer

Answer: A, Using ephemeral runners that reset after each job. Self-hosted runners do not reset between jobs, so a compromise persists across subsequent runs. Ephemeral runners restore the clean-instance-per-job property that GitHub-hosted runners have, which neutralises the most damaging follow-on attacks.

Question 17. An organisation wants to guarantee that a third-party action cannot be swapped for malicious code after review. What achieves this?

  1. Pinning to the major version tag and enabling Dependabot
  2. Forking the action and referencing the fork's default branch
  3. Requiring the action to carry a Verified creator badge
  4. Pinning to the full commit SHA, and enforcing SHA pinning through the allowed actions policy
Show answer

Answer: D, Pinning to the full commit SHA, and enforcing SHA pinning through the allowed actions policy. A tag can be moved to different code, so only a full commit SHA is immutable, and organisation policy can require SHA pinning and fail workflows that use floating tags. The Verified badge indicates a verified creator but does not prevent a tag being moved, and a fork's default branch is just as movable.

Question 18. Which of these is a genuine abuse risk that an Actions use policy is designed to reduce?

  1. Runners being shared between unrelated organisations by default
  2. A workflow triggered by an outside contributor running a malicious third-party action with access to repository secrets
  3. Artefacts being retained longer than the repository setting allows
  4. Workflow logs being publicly readable on private repositories
Show answer

Answer: B, A workflow triggered by an outside contributor running a malicious third-party action with access to repository secrets. The core risk is untrusted code executing inside a trusted context with access to secrets and a token. That is why policies restrict which actions may run and why triggers that expose secrets to outside contributions are treated carefully.

Question 19. An organisation plans to remove version 1 of a widely used reusable workflow. What should happen first?

  1. Delete the tag, so consumers are forced to migrate promptly
  2. Notify consumers in advance and publish a migration guide before removing the version
  3. Make the repository private, so no new consumers can adopt it
  4. Nothing, since consumers pinned to v1 are unaffected by its removal
Show answer

Answer: B, Notify consumers in advance and publish a migration guide before removing the version. Removing a referenced version breaks the pipelines of teams who had no warning, and pinning does not protect them because the pin points at something that no longer exists. Announce, provide a migration path, then remove.

Question 20. An enterprise policy permits only actions the enterprise itself created. One organisation beneath it wants to allow a single Marketplace action for its own repositories. What can that organisation do?

  1. Add the action to an organisation allowlist, which takes precedence over the enterprise setting
  2. Nothing locally: an inherited policy can be narrowed further but never widened, so the change has to be made a level up
  3. Fork the action into the enterprise, which is blocked because a fork inherits the original's policy
  4. Grant the requesting team the repository admin role, which bypasses the policy
Show answer

Answer: B, Nothing locally: an inherited policy can be narrowed further but never widened, so the change has to be made a level up. Action usage policies are set at enterprise level and inherited downwards. Every level below may be more restrictive than the one above it and never more permissive, which is why a request of this kind escalates rather than being settled in the organisation's own settings.

A 4-week GH-200 study plan

Frequently asked questions

How hard is GH-200?

It rewards people who write workflows regularly. Many questions show YAML and ask what it does or what's wrong with it, so reading workflow files fluently matters as much as knowing the features.

How long should I study for GH-200?

If you already use GitHub Actions, three to four weeks part-time is a reasonable plan. If you're new to it, build a few real workflows alongside your study.

Are these real GH-200 exam questions?

No. Microsoft exam questions are confidential, and sharing them breaks the agreement every candidate accepts. These are original questions written to the published skills outline, so they test the same knowledge in the same style.

Is CertBuddi free?

You can enrol free with no card. Free accounts get the opening modules of every course; Pro (£9.99 a month, or £79.99 a year) unlocks every module, the full timed mock exam and an adaptive study plan.

How should I use these practice questions?

Answer each one before you look at the explanation, and keep a list of the ones you get wrong. That list is your study plan: it's made of exactly the things you don't know yet.

CertBuddi is an independent study aid, not affiliated with or endorsed by Microsoft. These are original practice questions, not real exam questions.