GitHub free practice

Free GH-200 practice questions

15 real GH-200 sample questions, each with a worked explanation and a rationale for every option, right and wrong. No account, no card. This is the reasoning the GH-200 tests: knowing why the tempting answer is wrong, not just spotting the right one.

The real GH-200 is About 60 to 65 questions questions in 100 minutes, pass mark 700 / 1000. For a domain-by-domain breakdown and a study plan, read the GH-200 study guide. The full bank has 267 questions.

Author and manage workflows (25% of the exam)

Free sampleAuthor and manage workflowsmedium

A maintenance workflow must run automatically every night at 02:00 UTC to prune stale caches, with no human starting it and no code change needed to fire it. Which trigger should be configured at the top of the workflow file?

on:
  <trigger>:
    - cron: '0 2 * * *'
  • Aschedule, because it accepts one or more cron expressions and triggers the workflow on the defined recurring time-based interval. Correct
  • Bworkflow_dispatch, because a recurring nightly job is started from the Actions tab and the cron expression sets the default run time.
  • Crepository_dispatch, because it listens for a timed webhook that GitHub emits internally to drive cron-based recurring runs.
  • Dpush, because adding a cron filter under the push event tells GitHub to replay the last push on the recurring schedule.
Recognise that the schedule event with a cron expression is the trigger for recurring time-based workflow runs. GitHub Actions runs a workflow on a recurring timetable only through the schedule event, which accepts cron expressions evaluated in UTC. A cron entry such as '0 2 * * *' therefore fires the workflow nightly at 02:00 UTC with no commit and no manual action. The other events fire on a push, a manual button, or an externally posted custom event, and none of them honours a cron field.

Why A is correct: The schedule event takes a list of cron expressions evaluated against UTC, so '0 2 * * *' fires the workflow every night at 02:00 without any human action or code change.

Why B is wrong: Tempting because workflow_dispatch also appears under on, but it only enables a manual run button and accepts no cron field, so it cannot fire the job automatically at 02:00 UTC.

Why C is wrong: Tempting because repository_dispatch is also event driven, but it fires only when an external system posts a custom event to the API, not on any internal timer, so a cron field is ignored here.

Why D is wrong: Tempting because push is a very common trigger, but it fires only when commits are pushed and supports no cron field, so it cannot produce a nightly time-based run.

Free sampleAuthor and manage workflowsmedium

An engineer needs to let teammates start a release workflow on demand from the Actions tab and have them choose a deployment environment from a typed field when they do. Which trigger configuration meets both requirements?

on:
  <trigger>:
    inputs:
      environment:
        type: choice
        options: [staging, production]
  • Aschedule, with an inputs block listing the environment choices, so the run is launched on demand and reads the selected value.
  • Bworkflow_dispatch, because it adds a manual run button in the Actions tab and supports an inputs block including typed choice fields. Correct
  • Cpush, with branch filters mapped to the inputs choices, so pushing to a branch starts the run and selects the matching environment.
  • Drepository_dispatch, because it shows a manual button in the Actions tab and exposes the same inputs choices to the person starting the run.
Use workflow_dispatch to expose a manual run button with typed inputs such as a choice field. Only the workflow_dispatch event adds a Run workflow button in the Actions tab and supports an inputs block, where a field can be declared as type choice with a fixed set of options. That combination gives teammates an on-demand launch and a typed environment selector. The schedule and push events fire automatically and accept no inputs, and repository_dispatch is driven by an API call rather than a tab button.

Why A is wrong: Tempting because inputs look plausible under any event, but schedule fires only on a cron timer, offers no manual launch button, and does not accept an inputs block at all.

Why B is correct: The workflow_dispatch event enables a manual run control in the Actions tab and accepts an inputs block, so a choice-typed environment field is presented for the operator to select before the run.

Why C is wrong: Tempting because push starts runs from developer activity, but it fires automatically on commits rather than on demand and provides no typed input prompt for the operator to choose an environment.

Why D is wrong: Tempting because it is also manually driven, but repository_dispatch is started by an API call carrying a client_payload, not by an Actions tab button, and it does not render a typed inputs form.

Free sampleAuthor and manage workflowsmedium

A workflow should run its build only when a push changes files under the src directory on the main branch, and stay idle for pushes that touch documentation elsewhere. Which on configuration scopes the trigger to that intent with the least extra logic?

on:
  push:
    branches: [main]
    <filter>:
      - 'src/**'
  • AUse a tags filter listing 'src/**', because tag patterns restrict a push trigger to commits that modify files inside the named directory.
  • BUse a branches filter listing 'src/**', because adding the directory glob alongside main narrows the branch filter to that path.
  • CUse a paths filter listing 'src/**', because the push then fires only when the pushed commits change files matching that path glob on main. Correct
  • DUse a paths-ignore filter listing 'src/**', because excluding that glob tells the push trigger to run only when those files change.
Scope a push trigger to specific files with a paths filter, distinct from branches, tags, and paths-ignore. A push trigger can be narrowed by both branch and file path. The paths filter runs the workflow only when at least one changed file matches a listed glob, so branches main combined with paths 'src/**' fires solely for source changes on main. A branches or tags filter matches ref names rather than files, and paths-ignore would do the opposite by skipping the very changes the team wants to build.

Why A is wrong: Tempting because tags is a real push filter, but it matches Git tag names rather than changed file paths, so it cannot limit the run to pushes that touch the src directory.

Why B is wrong: Tempting because branches already appears in the snippet, but a branches filter matches branch names, not file paths, so 'src/**' there would simply never match a branch and the build would not run.

Why C is correct: The paths filter restricts a push or pull_request trigger to runs where at least one changed file matches the glob, so combining branches main with paths 'src/**' runs the build only for source changes.

Why D is wrong: Tempting because it names the right glob, but paths-ignore inverts the intent and skips the run when src files change, firing instead for unrelated documentation edits.

Manage GitHub Actions for the enterprise (24% of the exam)

Free sampleManage GitHub Actions for the enterprisemedium

A platform team wants every repository in an organisation to run the same security-scanning logic, with a single central definition that all repositories call rather than copy, so that fixing a bug in one place immediately updates all consumers. Which GitHub Actions component should the team author to govern this shared logic centrally?

  • AA starter workflow published from the organisation .github repository, because selecting it seeds each repository with the scanning logic so every team runs an identical copy of the security checks.
  • BA composite action stored in a shared action repository, because bundling the scanning steps into one action lets every workflow reference the same security logic from a single source of truth.
  • CA reusable workflow called through the uses key at job level, because consumers reference the central definition by path and a fix made there takes effect for every repository that calls it. Correct
  • DA workflow template uploaded through the organisation settings page, because the organisation then pushes the security-scanning definition to every repository automatically without each team referencing it.
Choose a reusable workflow when shared logic must stay a single central definition so that fixes propagate to every consuming repository. A reusable workflow is defined once and consumers reference it through the uses key at job level, so they execute the central file rather than a copy. A change made to that file therefore applies to every caller on its next run. Starter workflows copy themselves into each repository, so later fixes never reach existing copies, and a composite action only groups steps inside a job rather than defining a shareable end-to-end workflow.

Why A is wrong: Tempting because starter workflows standardise how new repositories begin, but selecting one copies the file into the repository, so a later central fix does not propagate to the copies already created.

Why B is wrong: Tempting because a composite action does centralise a sequence of steps, but it slots inside a job's steps rather than defining whole jobs, so it cannot govern an end-to-end shared workflow on its own.

Why C is correct: A reusable workflow lives in one repository and is referenced through uses at job level, so consumers run the central definition itself and any fix there immediately reaches every repository that calls it.

Why D is wrong: Tempting because organisation settings hold many shared resources, but templates are not uploaded there and GitHub does not auto-push a definition into every repository; sharing is done through repositories and the uses key.

Free sampleManage GitHub Actions for the enterprisemedium

An organisation administrator is publishing a custom deployment starter workflow so that all of the organisation's repositories see it when opening the Actions tab. Within which repository must the template files and their metadata be committed for GitHub to offer the starter workflow across the organisation?

<repo>/
  workflow-templates/
    deploy.yml
    deploy.properties.json
  • AA repository named .github-private owned by the organisation, because private starter workflows are sourced from that dedicated repository rather than from the standard public organisation profile repository.
  • BEach consuming repository's own .github/workflows directory, because a starter workflow is only offered for selection once a copy of the template already exists in the repository that will use it.
  • CA repository named workflow-templates owned by the organisation, because GitHub matches the repository name to the directory convention and lists every template file it finds inside that repository.
  • DThe organisation's .github repository, because GitHub sources organisation starter workflows from a workflow-templates directory in that repository and offers them to the organisation's repositories. Correct
Publish organisation starter workflows from a workflow-templates directory inside the organisation's .github repository. GitHub discovers organisation starter workflows by reading a workflow-templates directory in the organisation's special .github repository, where each template has a YAML file and a matching properties.json describing it. The .github-private repository is only for private profile content, the workflow-templates name is a directory not a repository, and per-repository .github/workflows folders hold running workflows rather than published templates.

Why A is wrong: Tempting because .github-private exists for private profile READMEs, but starter workflows are not sourced from it; the workflow-templates directory must live in the organisation's .github repository.

Why B is wrong: Tempting because workflows execute from .github/workflows, but placing a template there per repository defeats central publishing; starter workflows are offered before any copy exists in the consumer.

Why C is wrong: Tempting because workflow-templates is the correct directory name, but it is a folder inside the .github repository rather than a separately named repository, so a repository by that name is not recognised.

Why D is correct: GitHub reads organisation starter workflows from a workflow-templates directory in the organisation's .github repository, so committing the template and its properties file there makes it appear in the Actions tab for that organisation.

Free sampleManage GitHub Actions for the enterprisemedium

A governance lead wants the organisation's deployment starter workflow to be visible only to the organisation's own internal and private repositories, and not to anyone outside the organisation. Which property of the .github repository that hosts the workflow-templates directory controls who can see the published starter workflow?

  • AThe visibility of the .github repository itself, because setting it to internal or private limits the published starter workflow to the organisation's own internal and private repositories. Correct
  • BA branch protection rule on the default branch of the .github repository, because only repositories that satisfy the configured protections are permitted to list and select the published template.
  • CAn Actions access setting on the .github repository naming each permitted repository, because a starter workflow is shared the same way a private reusable workflow grants access to specific callers.
  • DA CODEOWNERS entry covering the workflow-templates directory, because the listed owners are the only accounts that may both edit the template and view it from the organisation's repositories.
Control who can see an organisation starter workflow by setting the visibility of the .github repository that hosts it. The audience for a published starter workflow follows the visibility of the .github repository that contains the workflow-templates directory. Making that repository internal or private confines the template to the organisation's own internal and private repositories, while a public .github repository would expose it more widely. Branch protection, Actions access lists, and CODEOWNERS govern how the template files are changed or reviewed, not which repositories see the published template.

Why A is correct: A starter workflow inherits the visibility of the .github repository that hosts it, so setting that repository to internal or private restricts the template to the organisation's own repositories rather than the public.

Why B is wrong: Tempting because branch protection governs changes to the template files, but it controls who may merge into the branch, not which repositories can see the published starter workflow in the Actions tab.

Why C is wrong: Tempting because private reusable workflows do use Actions access lists, but starter-workflow visibility follows the .github repository's visibility rather than a per-caller Actions access grant.

Why D is wrong: Tempting because CODEOWNERS does gate review of the template files, but it assigns reviewers for changes and does not determine which repositories can see the published starter workflow.

Consume and troubleshoot workflows (18% of the exam)

Free sampleConsume and troubleshoot workflowsmedium

A run-history list shows a workflow that executed without any new commit, with no operator named as the actor and no external API call recorded. The workflow file declares the on block below. Which trigger most likely produced this run?

on:
  push:
    branches: [main]
  workflow_dispatch:
  schedule:
    - cron: '0 6 * * 1'
  • AThe push event, because the run history records a commit to main even when the diff is empty and the user interface omits the pushing actor.
  • BThe workflow_dispatch event, because a teammate clicked Run workflow and GitHub anonymises the actor on manually started runs to protect the operator.
  • CThe repository_dispatch event, because an outside system posted a custom payload that the run history hides from the actor and commit columns by design.
  • DThe schedule event, because a cron-triggered run fires on its own timetable with no commit and is attributed to the workflow rather than to any human or external caller. Correct
Infer the trigger of a workflow run from run-history clues such as the absence of a commit, an actor, or an external call. When a run has no associated commit, no named operator, and no recorded API dispatch, the remaining time-based trigger is the cause. A scheduled run fires from its cron timetable with no human or external initiator, so GitHub attributes it to the workflow rather than to an actor. A push run always references a head commit, a manual workflow_dispatch run records the operator, and repository_dispatch requires an external API call, none of which fits the evidence.

Why A is wrong: Tempting because push is listed first in the on block, but a push run always references a head commit and names the pusher as actor, neither of which appears in this run.

Why B is wrong: Tempting because workflow_dispatch needs no commit, but a manual run always records the person who clicked Run workflow as the actor, so an unnamed operator rules it out.

Why C is wrong: Tempting because that event also lacks a commit, but repository_dispatch is not in the on block and the stem states no external API call was recorded, so it cannot be the cause.

Why D is correct: A scheduled run fires from the cron timetable with no commit and no operator, and run history attributes it to the workflow itself, matching the empty actor and absent commit observed.

Free sampleConsume and troubleshoot workflowsmedium

A pull request opened from a fork triggers the workflow below, and the run history shows the build job completing but the deploy job being skipped rather than failing. The deploy job carries the condition shown. Why was deploy skipped on this run?

jobs:
  deploy:
    needs: build
    if: github.event_name == 'push'
    runs-on: ubuntu-latest
  • ABecause the run was triggered by pull_request, the if expression github.event_name == 'push' evaluates to false, so the deploy job is skipped rather than executed. Correct
  • BBecause the build job emitted a failure annotation that propagated through needs: build, marking deploy as skipped instead of failed on the run summary.
  • CBecause forked pull requests run with a read-only GITHUB_TOKEN, and GitHub automatically skips any job that requests deployment permissions it cannot grant.
  • DBecause the if condition compares github.event_name with workflow_dispatch, and a pull_request run never matches that string, so the deploy job evaluates to false.
Explain a skipped job in run history by evaluating its job-level if condition against the run's triggering event. A job-level if is evaluated against the run context. The triggering event here is pull_request, so github.event_name equals 'pull_request', and the expression github.event_name == 'push' resolves to false. GitHub marks a job whose if condition is false as skipped, which is distinct from a failure. The build job is unaffected because it carries no such condition, and the run history therefore shows build complete and deploy skipped.

Why A is correct: On a pull_request run github.event_name is 'pull_request', so the job-level if testing for 'push' resolves to false, and a job whose if is false is reported as skipped, not failed.

Why B is wrong: Tempting because needs links the jobs, but the stem says build completed, and a failed dependency would block deploy with a skipped-due-to-failure note, not satisfy the event condition.

Why C is wrong: Tempting because fork runs do get a read-only token, but token scope does not auto-skip a job; a permission shortfall surfaces as a step failure, not a skipped job.

Why D is wrong: Tempting because an event_name mismatch is the right mechanism, but the condition tests for push, not workflow_dispatch, so this misreads the value being compared.

Free sampleConsume and troubleshoot workflowsmedium

Two pushes to main arrive within seconds of each other. The workflow declares the concurrency block below. Reviewing the run history, what outcome should an engineer expect for the run started by the first push?

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
  • AThe first run queues behind the second and resumes once the newer run finishes, because cancel-in-progress only pauses an active run until the queue drains.
  • BThe first run is cancelled when the second push starts a newer run in the same concurrency group, and run history records it with a cancelled status. Correct
  • CThe first run completes normally and the second run is cancelled, because cancel-in-progress always protects the run that entered the concurrency group earliest.
  • DBoth runs execute fully in parallel, because each push to main produces a distinct concurrency group keyed by its own unique commit SHA value.
Predict how concurrency with cancel-in-progress affects an earlier in-progress run when a newer run joins the same group. The concurrency group key combines github.workflow and github.ref, so two pushes to the same branch fall into one group. With cancel-in-progress set to true, starting a newer run in that group cancels any run already in progress. The first push's run is therefore cancelled when the second push's run begins, and run history records a cancelled status. The key uses the ref rather than the commit SHA, so the runs are not separated into different groups.

Why A is wrong: Tempting because concurrency can queue runs, but cancel-in-progress: true cancels rather than pauses the older run, and a cancelled run does not resume later.

Why B is correct: Both pushes share the group key built from workflow and ref, and cancel-in-progress: true cancels the in-progress first run when the newer run begins, so it shows as cancelled.

Why C is wrong: Tempting because protecting the earliest run sounds fair, but cancel-in-progress cancels the older in-progress run in favour of the newest, so the first run is the one that stops.

Why D is wrong: Tempting because each push has a unique SHA, but the group key uses github.ref not the SHA, so both runs land in the same group and are serialised, not parallelised.

Author and maintain actions (18% of the exam)

Free sampleAuthor and maintain actionsmedium

A team has three workflow steps that each run shell commands: install a CLI, authenticate it, then call it with arguments. They want to package exactly these run steps into one reusable unit that they can publish and call with a single uses: reference, without rewriting the logic in another language or building an image. Which action type should they author?

runs:
  using: "<type>"
  steps:
    - run: ./install.sh
      shell: bash
    - run: ./auth.sh
      shell: bash
  • AA JavaScript action, because the runner can only execute bundled shell run steps after they are first rewritten as a Node.js entry point that the toolkit invokes on each platform.
  • BA Docker container action, because grouping several shell commands into a single action is only supported once the commands are baked into an image that the runner pulls before each invocation.
  • CA composite action, because its action.yml uses a runs block with using: composite and a steps list, letting them bundle the existing shell run steps into one unit referenced through uses:. Correct
  • DA reusable workflow, because a file under .github/workflows called through workflow_call is the supported way to package shell run steps for reference by uses: inside another job's steps.
Choose a composite action to bundle a sequence of existing shell run steps into one unit referenced by uses without rewriting logic. A composite action declares runs.using as composite and lists steps, so it groups multiple run steps into a single action that other workflows reference with uses. JavaScript actions need a Node entry point, Docker actions need an image and run only on Linux, and reusable workflows are invoked at job level through workflow_call rather than as a step, so none of them packages plain shell steps as requested.

Why A is wrong: Tempting since JavaScript actions run directly on the runner, but they require rewriting the logic as a Node entry point, which the team explicitly wants to avoid for plain shell steps.

Why B is wrong: Tempting because containers also run shell commands, but a Docker action needs an image build and only runs on Linux runners, which is heavier than the shell-only packaging requested.

Why C is correct: Composite actions are defined by using: composite plus a steps list, which is exactly the construct for wrapping a sequence of run steps into one publishable action referenced with uses.

Why D is wrong: Tempting as reusable workflows also promote reuse, but they are called at the job level with uses under jobs, not as a step action, so they cannot bundle individual run steps.

Free sampleAuthor and maintain actionsmedium

An author is building a custom action that must run on GitHub-hosted Ubuntu, Windows, and macOS runners within the same workflow, and the logic is straightforward file manipulation with no special system packages. They want the type that executes natively on every one of those operating systems. Which action type best fits this cross-platform requirement?

  • AA Docker container action, because the container image abstracts the host so the identical action runs unchanged on Ubuntu, Windows, and macOS GitHub-hosted runners during the same workflow.
  • BA composite action, because bundling run steps with shell: bash guarantees the action behaves identically across Ubuntu, Windows, and macOS GitHub-hosted runners with no further changes.
  • CA starter workflow, because publishing the logic as an organisation template makes it run consistently on Ubuntu, Windows, and macOS GitHub-hosted runners whenever a repository adopts it.
  • DA JavaScript action, because it runs directly with the runner's Node.js runtime and is therefore supported on Ubuntu, Windows, and macOS GitHub-hosted runners without an image. Correct
Select a JavaScript action when a custom action must run natively across Ubuntu, Windows, and macOS GitHub-hosted runners. JavaScript actions run with the Node.js runtime that ships on every GitHub-hosted runner, so the same action works on Ubuntu, Windows, and macOS without modification. Docker container actions are restricted to Linux runners, composite actions rely on per-platform shells and tooling for their run steps, and a starter workflow is a copyable template rather than an action, so only the JavaScript action meets the cross-platform need.

Why A is wrong: Tempting because containers feel portable, but Docker container actions only run on Linux runners, so they cannot execute on the Windows and macOS runners the scenario requires.

Why B is wrong: Tempting as composite actions do run on every OS, but their run steps depend on the chosen shell and tools per platform, so identical behaviour is not guaranteed for shell logic.

Why C is wrong: Tempting since starter workflows aid reuse, but they are workflow templates a repository copies, not an action type, so they do not answer which custom action runs cross-platform.

Why D is correct: JavaScript actions execute on the runner's bundled Node.js, which exists on all GitHub-hosted operating systems, so the same action runs natively across Ubuntu, Windows, and macOS.

Free sampleAuthor and maintain actionsmedium

A custom action must invoke a specialised command-line tool that is not available on GitHub-hosted runners and is awkward to install reliably at runtime, and the maintainer wants the action to ship with that tool and all its system dependencies already in place. The action only ever needs to run on Linux runners. Which action type meets this requirement most directly?

runs:
  using: "<type>"
  image: "Dockerfile"
  args:
    - ${{ inputs.target }}
  • AA Docker container action, because its image declared through using: docker packages the specialised tool and all system dependencies, giving a self-contained environment that runs on Linux runners. Correct
  • BA composite action, because listing run steps under using: composite lets the maintainer ship the specialised tool and its system dependencies inside the action package for use on Linux runners.
  • CA JavaScript action, because the bundled Node.js modules can embed the specialised command-line tool and its system dependencies so the action runs self-contained on Linux runners.
  • DA reusable workflow, because referencing it through workflow_call lets the maintainer ship the specialised tool and its system dependencies as a callable unit that runs on Linux runners.
Pick a Docker container action when a custom action must ship a specialised tool and its system dependencies as a self-contained Linux environment. A Docker container action runs inside an image that the author controls, so the specialised command-line tool and all of its system dependencies are baked in and present at execution. Composite and reusable units run on the host and rely on runtime installation, and JavaScript actions only bundle Node modules rather than arbitrary system binaries, so the container action is the direct fit, with the trade-off that it runs only on Linux runners.

Why A is correct: A Docker container action builds from an image that bundles the tool and its OS-level dependencies, giving the self-contained Linux environment the maintainer wants for an awkward-to-install binary.

Why B is wrong: Tempting because composite actions group setup steps, but they install tools at runtime on the host rather than packaging a self-contained environment, so the dependency problem remains.

Why C is wrong: Tempting since JavaScript actions bundle Node modules, but they cannot package arbitrary system binaries and OS dependencies, so the specialised tool still must exist on the host.

Why D is wrong: Tempting as reusable workflows centralise logic, but they still run on the host runner and bundle no environment, so they cannot supply a tool absent from GitHub-hosted runners.

Secure and optimize automation (15% of the exam)

Free sampleSecure and optimize automationmedium

A release job deploys to an environment named production. The team wants a mandatory cooling-off period after a run reaches the environment, so that anyone can cancel the deployment within a fixed delay before it actually proceeds, even when no human approval is required. Which environment protection rule provides this fixed delay?

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
  • AA required reviewers rule on the environment, because naming reviewers automatically inserts a fixed delay during which the queued deployment can still be cancelled.
  • BA concurrency group keyed on the environment name, because grouping the runs makes GitHub hold each queued deployment for a fixed cooling-off period before releasing it.
  • CA branch protection rule on the deployment branch, because requiring a status check there forces a fixed delay before the environment will accept the queued run.
  • DA wait timer rule on the environment, because it holds any run that reaches the environment for the configured number of minutes before the job is allowed to proceed. Correct
Use an environment wait timer protection rule to delay a deployment by a set number of minutes after it reaches the environment. The wait timer is one of the environment protection rules configured on the environment itself, and it holds any run that references the environment for the configured number of minutes before the deployment job continues. This produces a fixed, unattended cooling-off window during which the run can be cancelled. Required reviewers waits for a person rather than a clock, concurrency only orders runs by group key, and branch protection governs the repository branch instead of the environment.

Why A is wrong: Tempting because required reviewers also pause a run, but that rule waits for a named person to approve rather than counting down a fixed timer, so it provides no automatic delay window.

Why B is wrong: Tempting because concurrency does queue runs, but it only serialises or cancels by group key and never imposes a timed delay during which a pending deployment can be cancelled.

Why C is wrong: Tempting because branch protection gates merges, but it governs the repository branch and pull requests, not the timed pause an environment applies once a deployment job targets it.

Why D is correct: A wait timer is an environment protection rule that delays a deployment by a set number of minutes after it reaches the environment, giving a cancellation window without needing approval.

Free sampleSecure and optimize automationmedium

An organisation keeps an environment named production that holds deployment secrets. Security requires that only workflow runs originating from the main branch may deploy to this environment, while runs from feature branches must be refused even if their workflow references the environment. Which environment configuration enforces this restriction?

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
  • AConfigure a deployment branches rule on the production environment set to selected branches, listing main so only runs from that branch can deploy. Correct
  • BAdd the main branch to a repository CODEOWNERS file, because ownership of that branch limits which branches are permitted to deploy to the production environment.
  • CConfigure a branch protection rule on main that requires status checks, because protecting the branch stops feature branches from deploying to the production environment.
  • DAdd an if condition to the deploy job that checks the ref equals main, because the job is then skipped whenever the run starts from any other branch.
Restrict which branches can deploy to an environment by setting a deployment branches rule to selected branches. An environment can carry a deployment branches and tags rule that names exactly which refs may deploy to it. Setting it to selected branches and listing only main means GitHub refuses any run from another branch that targets the environment, enforced by the platform rather than by workflow steps. CODEOWNERS only assigns reviewers, branch protection governs activity on the branch itself, and an if condition is editable workflow logic rather than an enforced environment control.

Why A is correct: A deployment branches rule on the environment restricts which branches may deploy, so listing only main blocks any run from another branch from reaching the protected environment.

Why B is wrong: Tempting because CODEOWNERS controls review assignment, but it only requests reviews on changed paths and has no effect on which branch may deploy to a protected environment.

Why C is wrong: Tempting because branch protection secures main, but it governs merges and pushes to that branch and does not decide which branches are allowed to deploy to an environment.

Why D is wrong: Tempting because an if check can skip a job, but it is workflow logic that an author can edit or omit and is not an enforced environment rule on which branch may deploy.

Free sampleSecure and optimize automationmedium

While selecting a third-party action from the GitHub Marketplace, a developer sees that the publisher displays a verified creator badge. What does this badge actually tell the developer about the action?

  • AThe badge confirms that GitHub has audited the action's source code for security flaws, so pinning the action to a tag rather than a commit SHA is considered safe.
  • BThe badge confirms that GitHub has verified the identity of the organisation that owns the action, but it does not certify that the action's code is safe or free of vulnerabilities. Correct
  • CThe badge confirms that the action's releases are immutable, so once published a given version tag can never be altered to point at different code.
  • DThe badge confirms that the action requests only the minimum GITHUB_TOKEN permissions, so the consuming workflow need not set its own permissions block.
Recognise that a Marketplace verified creator badge attests to the publisher's identity, not to the security or quality of the action's code. The verified creator badge on the GitHub Marketplace indicates that GitHub has confirmed the identity of the organisation publishing the action. It is an identity signal, not a code review, so it does not certify that the action is free of vulnerabilities or that its permissions are minimal. Developers should still inspect the source, pin to a full commit SHA, and scope token permissions, because the badge alone does not guarantee the code is safe to run.

Why A is wrong: Tempting because the badge implies trust, but GitHub does not audit the code behind it, and a moving tag can still be repointed, so the safety claim about tag pinning is wrong.

Why B is correct: The verified creator badge attests only that GitHub confirmed the publishing organisation's identity, and it makes no statement about whether the action's code is secure or bug-free.

Why C is wrong: Tempting because immutability is a real release concern, but it is a separate publishing feature from the badge, which speaks only to the verified identity of the creator.

Why D is wrong: Tempting because least privilege is good practice, but the badge says nothing about token scopes, and a consumer should still set an explicit permissions block regardless.

Want the full bank?

267 GH-200 questions, every one with a worked explanation and a per-option rationale. No sign-up to start.

Practise GH-200 free

Frequently asked questions

Are these GH-200 practice questions free?

Yes. Every GH-200 question on this page is free to read with no sign-up, and each one carries a worked explanation and a rationale for every option. The full bank of 267 questions is on Examworthy.

Do the questions explain why the wrong answers are wrong?

Yes, and that is the point. Each option, correct or not, has its own rationale, so you learn to rule out the tempting wrong answer, not just recognise the right one. That is the reasoning the GH-200 tests.

Are these real GH-200 exam questions?

No. These are original, blueprint-aligned practice questions written to the public GitHub content outline. We never reproduce live exam items. They mirror the format and difficulty of the real exam.

How many questions are on the real GH-200?

The GH-200 is About 60 to 65 questions questions in 100 minutes, with a pass mark of 700 / 1000. For the full domain-by-domain breakdown and a study plan, read the study guide.

Examworthy is not affiliated with or endorsed by GitHub. All questions are original, blueprint-aligned practice material. We never reproduce live exam items. GH-200 and related marks belong to their respective owners.