GitHub Actions · 40% of the exam

Author and Maintain Workflows: free practice questions

5 sample questions from our 36-question bank for this domain — answers and explanations included. These are the same scenario-based style as the real GitHub exam.

1. A team wants to trigger a workflow in Repository B from an external system (e.g., a deployment pipeline outside GitHub) using an HTTP POST request, passing a custom payload with a `service` field. Which event and configuration should they use in Repository B's workflow?

  • A. Use `workflow_dispatch` and call the GitHub API's workflow dispatch endpoint with the payload as `inputs`
  • B. Use `repository_dispatch` with a `types` filter and send a POST to the repository's dispatches endpoint with an `event_type` and `client_payload`✓ Correct
  • C. Use `push` with a path filter so the external system can push a file to trigger the workflow
  • D. Use `schedule` with a very short cron interval so the workflow polls frequently and reads the payload from a repository variable
Explanation

`repository_dispatch` is the correct event for triggering a workflow from **external** systems via the GitHub REST API. The caller POSTs to `/repos/{owner}/{repo}/dispatches` with an `event_type` and optional `client_payload`, and the workflow filters on `types`. The custom `service` field would be in `client_payload` and accessible via `${{ github.event.client_payload.service }}`. **A** is wrong because `workflow_dispatch` requires a user or GitHub App to trigger it via the API or UI; it does not accept arbitrary `client_payload` — it only accepts predefined `inputs`. While it can be triggered via API, it lacks the `client_payload` flexibility needed. **C** is wrong because forcing a file push is a workaround, not a proper mechanism, and couples the external system to repository content. **D** is wrong because `schedule` cannot receive payloads at all; it only runs at fixed times.

2. A workflow runs on every push to any branch. A developer wants to skip the workflow run without editing the YAML file for a specific commit. Which approach will cause GitHub Actions to skip the run for that commit?

  • A. Include `[skip ci]`, `[ci skip]`, or `skip-checks: true` in the commit message.✓ Correct
  • B. Add a `workflow_ignore` label to the commit via the GitHub API before pushing.
  • C. Set the secret `ACTIONS_SKIP=true` in the repository settings before pushing.
  • D. Push with the `--no-verify` flag to bypass GitHub Actions triggers.
Explanation

Option A is correct. GitHub Actions natively recognizes skip directives in commit messages, including `[skip ci]`, `[ci skip]`, `[no ci]`, `[skip actions]`, and the trailer `skip-checks: true`. When present, the workflow is not triggered. Option B is wrong because there is no `workflow_ignore` label concept in GitHub; labels are applied to issues and pull requests, not commits for this purpose. Option C is wrong because there is no built-in `ACTIONS_SKIP` secret mechanism — setting such a secret has no effect on whether a workflow is triggered. Option D is wrong because `git push --no-verify` bypasses local Git hooks (like pre-push), not GitHub-side Actions triggers.

3. A workflow step needs to share a computed value (e.g., a version string) with a later step in the same job. Which mechanism should be used in a current GitHub Actions runner?

  • A. Write `VERSION=1.2.3` to the file path stored in `$GITHUB_OUTPUT`, then reference it with `steps.<step-id>.outputs.VERSION`.✓ Correct
  • B. Write `VERSION=1.2.3` to the file path stored in `$GITHUB_ENV`, then reference it with `steps.<step-id>.outputs.VERSION`.
  • C. Use `echo "::set-output name=VERSION::1.2.3"` workflow command, then reference it with `steps.<step-id>.outputs.VERSION`.
  • D. Write `VERSION=1.2.3` to the file path stored in `$GITHUB_OUTPUT`, then reference it with `env.VERSION`.
Explanation

Option A is correct. The modern approach (replacing the deprecated `set-output` command) is to append `KEY=VALUE` to the file referenced by `$GITHUB_OUTPUT`, and then read it back via the `steps.<step-id>.outputs.KEY` expression in subsequent steps of the same job. Option B is wrong because `$GITHUB_ENV` sets environment variables accessible as `env.KEY` — not as step outputs; you cannot read env variables via `steps.<id>.outputs`. Option C is wrong because the `::set-output` workflow command was deprecated in September 2022 and has since been disabled; using it will cause the step to fail on current runners. Option D is wrong about the access path: values written to `$GITHUB_OUTPUT` are accessible via `steps.<step-id>.outputs.KEY`, not via `env.KEY` — `env.KEY` is the path for variables written to `$GITHUB_ENV`.

4. A developer is authoring a composite action (`action.yml`) that needs to expose the value computed by one of its internal shell steps as an output named `artifact_path` that callers can consume. Which configuration correctly defines and sets this output in a composite action?

  • A. Declare `outputs: artifact_path: value: ${{ steps.compute.outputs.artifact_path }}` in `action.yml` and in the shell step write `echo "artifact_path=$path" >> $GITHUB_OUTPUT` with the step's `id` set to `compute`.✓ Correct
  • B. Declare `outputs: artifact_path: description: 'path'` in `action.yml` and write `echo "::set-output name=artifact_path::$path"` in the shell step.
  • C. Write `echo "artifact_path=$path" >> $GITHUB_ENV` in the shell step; composite action outputs are automatically derived from environment variables.
  • D. Declare `outputs: artifact_path: value: ${{ env.artifact_path }}` in `action.yml` and write `echo "artifact_path=$path" >> $GITHUB_ENV` in the shell step.
Explanation

Option A is correct: composite actions require outputs to be explicitly declared in `action.yml` with a `value:` expression that maps to a step's output (via `${{ steps.<id>.outputs.<name> }}`). The shell step must write to `$GITHUB_OUTPUT` and have a matching `id`. This is the current, supported pattern. Option B is wrong: `::set-output` is a deprecated workflow command that has been retired; using it is no longer reliable, and the output declaration also lacks a `value:` mapping. Option C is wrong: environment variables written to `$GITHUB_ENV` are not automatically surfaced as action outputs; outputs must be explicitly declared and mapped. Option D is wrong: while `${{ env.artifact_path }}` can technically be used in a `value:` expression, relying on env vars to bridge step results to action outputs is fragile and not the recommended pattern; more importantly the `value:` expression is evaluated at the composite action level and the env var approach can cause ordering/scoping issues, making Option A the clearly correct and idiomatic answer.

5. A company wants to prevent concurrent deployments to the production environment from the same branch. They want any new run to cancel the currently running one if it exists. Which concurrency configuration achieves this?

  • A. concurrency: group: deploy-prod-${{ github.ref }} cancel-in-progress: true✓ Correct
  • B. concurrency: group: deploy-prod cancel-in-progress: false
  • C. concurrency: group: deploy-prod-${{ github.run_id }} cancel-in-progress: true
  • D. jobs: deploy: concurrency: deploy-prod cancel-in-progress: true
Explanation

Option A is correct. Using `${{ github.ref }}` in the group name scopes the concurrency group per branch, so simultaneous deployments from different branches don't interfere with each other. `cancel-in-progress: true` ensures the older run is cancelled when a new one starts for the same group. Option B is wrong because `cancel-in-progress: false` (the default) only queues the new run rather than cancelling the existing one — this prevents concurrent runs but doesn't cancel them. Option C is wrong because `${{ github.run_id }}` is unique per run, meaning every run gets its own concurrency group and they never compete — the concurrency setting becomes entirely ineffective. Option D is wrong because `cancel-in-progress` is not a valid key directly under a job's `concurrency` field when it is expressed as a scalar string; the correct structure uses an object with `group` and `cancel-in-progress` keys. Additionally, placing it only at the job level without scoping to `${{ github.ref }}` would conflict across branches.

31 more questions in this domain

Practice the full bank with instant grading, flashcards, and a timed mock exam.

Start practicing free