GH-200 · Domain 3: Author and maintain actions · 19% of the exam
Task 3.1: Create and troubleshoot custom actions
JavaScript, Docker container and composite actions, which runners each supports, and diagnosing actions that fail to load, start or report their results.
Study it
JavaScript, composite and Docker container actions
Lesson coming
Containers and images behind Docker container actions
Try each one before opening the answer. Every option is explained, with the GitHub documentation page that proves it.
Question 1 · choose 1
A team is building an action that calls the GitHub API and parses JSON. Its users run jobs on Linux, Windows and macOS GitHub-hosted runners. The action must start quickly and must not depend on command-line tools that differ between runner images. Which kind of action should the team build?
AA Docker container action with the tools baked into its image
BA composite action that chains bash, jq and curl steps
CA JavaScript action written in pure JavaScript
DA reusable workflow with one job for each operating system the users run
Show the answer and why
AA Docker container action with the tools baked into its image
Incorrect
The image would fix the tools, but this type of action can't run on every runner operating system the users have.
BA composite action that chains bash, jq and curl steps
Incorrect
Those steps depend on tools and shells that vary between runner images.
CA JavaScript action written in pure JavaScript
Correct
Pure JavaScript runs on all GitHub-hosted runners, starts faster than a container and needs no extra binaries.
DA reusable workflow with one job for each operating system the users run
Incorrect
A reusable workflow isn't an action that users add as a step.
JavaScript actions run directly on the runner. To stay compatible with the Ubuntu, Windows and macOS GitHub-hosted runners, the packaged code should be pure JavaScript that doesn't rely on other binaries. A container action can't serve every operating system, and composite actions run whatever tools their steps call.
A new Docker container action fails at start with "exec: "/entrypoint.sh": permission denied". The Dockerfile copies entrypoint.sh and uses it as ENTRYPOINT. The author works on Windows. What should the author do?
AChange the base image to alpine
BRename the file to entrypoint.bash
CMove entrypoint.sh under /github/workspace
DMark the file executable in Git with git update-index --chmod=+x entrypoint.sh
Show the answer and why
AChange the base image to alpine
Incorrect
The base image doesn't make a copied file executable; the file's mode does.
BRename the file to entrypoint.bash
Incorrect
The name doesn't make a file executable.
CMove entrypoint.sh under /github/workspace
Incorrect
The workspace is mounted over that path, and the mode would still be wrong.
DMark the file executable in Git with git update-index --chmod=+x entrypoint.sh
Correct
The script must be executable, and setting the mode in Git keeps it on every clone.
The code a Docker action's ENTRYPOINT runs must be executable; otherwise the container fails with a permission denied error. GitHub's tutorial sets the mode in Git with git update-index --chmod=+x so it isn't reset on clone.
A JavaScript action starts a local proxy in main and stops it in a post script. When a job fails, the team wants the proxy left running so that a debugging step can inspect it, but after a successful job it must be stopped. What should action.yml set?
ANothing; post scripts already run only after successful jobs
Bpost-if: success() next to post
Cpre-if: failure() so that the proxy starts only when needed
Dpost-if: failure() next to post
Show the answer and why
ANothing; post scripts already run only after successful jobs
Incorrect
post runs by default whatever the outcome, since post-if defaults to always().
Bpost-if: success() next to post
Correct
Status functions in post-if check the job's status, so cleanup runs only after a successful job.
Cpre-if: failure() so that the proxy starts only when needed
Incorrect
pre-if controls the pre script, not the cleanup.
Dpost-if: failure() next to post
Incorrect
That would stop the proxy after failures only, the opposite of what's wanted.
JavaScript actions can declare pre and post scripts. post runs at the end of the job by default, because post-if defaults to always(). In post-if, status check functions evaluate the job's status, not the action's own status, so post-if: success() limits cleanup to successful jobs.
A team maintains a JavaScript action and a composite action that both take an input named region. Which two statements about reading that input are true? (Choose TWO.)
AThe JavaScript action can read it with core.getInput('region')
BThe composite action's steps get INPUT_REGION set automatically
CThe composite action's steps can read it as ${{ inputs.region }}
DInput names are case-sensitive: Region and region become separate environment variables
EThe JavaScript action must declare the input under runs
Show the answer and why
AThe JavaScript action can read it with core.getInput('region')
Correct
The toolkit reads the INPUT_REGION variable that GitHub creates.
BThe composite action's steps get INPUT_REGION set automatically
Incorrect
Composite actions don't automatically get INPUT_ variables.
CThe composite action's steps can read it as ${{ inputs.region }}
Correct
Composite actions access their inputs through the inputs context.
DInput names are case-sensitive: Region and region become separate environment variables
Incorrect
The variable name is converted to uppercase, so both map to INPUT_REGION.
EThe JavaScript action must declare the input under runs
Incorrect
Inputs are declared under inputs at the top of the metadata file.
For JavaScript and Docker container actions, GitHub creates an INPUT_<NAME> environment variable for each input, with the name uppercased; the toolkit's getInput reads it. Composite actions don't get these variables automatically and read inputs through the inputs context.
Where does GitHub publish the Node.js packages, such as @actions/core, for building JavaScript actions?
AThe actions/runner repository
BThe actions/starter-workflows repository
CThe actions/toolkit repository
DThe actions/runner-images repository
Show the answer and why
AThe actions/runner repository
Incorrect
That repository holds the runner application.
BThe actions/starter-workflows repository
Incorrect
That repository holds GitHub's workflow templates.
CThe actions/toolkit repository
Correct
The actions toolkit is a set of Node.js packages for building actions.
DThe actions/runner-images repository
Incorrect
That repository holds the GitHub-hosted runner images.
The GitHub Actions Toolkit provides Node.js packages that speed up building JavaScript actions; its source and documentation are in the actions/toolkit repository.
A developer writing a JavaScript action wants functions to read inputs, set outputs, log debug messages and set a failing exit status. Which package provides them?
A@actions/cache
B@actions/core
C@actions/artifact
D@actions/glob
Show the answer and why
A@actions/cache
Incorrect
That package saves and restores caches.
B@actions/core
Correct
It wraps workflow commands, inputs, outputs, exit status and debug messages.
C@actions/artifact
Incorrect
That package uploads and downloads artifacts.
D@actions/glob
Incorrect
That package matches file patterns.
The actions toolkit's @actions/core package provides an interface to the workflow commands, input and output variables, exit statuses and debug messages. @actions/github returns an authenticated Octokit client and the workflow contexts.
A Docker container action builds a project inside its container. The next workflow step must upload the build output as an artifact. Where should the action write the output?
ATo /tmp inside the container
BTo /github/workspace inside the container
CTo the container's home directory
DTo a Docker volume that the action creates itself
Show the answer and why
ATo /tmp inside the container
Incorrect
That directory disappears with the container.
BTo /github/workspace inside the container
Correct
That path is mapped to the runner's workspace, so later steps can use the files.
CTo the container's home directory
Incorrect
Later steps don't see the container's own file system.
DTo a Docker volume that the action creates itself
Incorrect
Later steps don't mount volumes the action creates.
When a container action runs, GitHub maps the runner's default working directory, GITHUB_WORKSPACE, to /github/workspace in the container. Files added there are available to subsequent steps in the same job, such as an artifact upload.
A Docker container action's Dockerfile starts with FROM node:latest. A reviewer asks the author to follow GitHub's Dockerfile guidance for actions. Which first line should the Dockerfile have?
AFROM node:22, an official image with a major version tag
BFROM node:latest, kept so that the action always gets the newest Node.js
CNo FROM line, with the base image named in action.yml instead
DFROM node:22-alpine, because Alpine-based images are recommended for actions
Show the answer and why
AFROM node:22, an official image with a major version tag
Correct
GitHub recommends official images and a version tag, preferably a major version, instead of latest.
BFROM node:latest, kept so that the action always gets the newest Node.js
Incorrect
GitHub's guidance is to use a version tag, for example node:10 instead of node:latest.
CNo FROM line, with the base image named in action.yml instead
Incorrect
The first instruction in the Dockerfile must be FROM, which selects the base image.
DFROM node:22-alpine, because Alpine-based images are recommended for actions
Incorrect
GitHub recommends Docker images based on the Debian operating system.
The first instruction in a Docker container action's Dockerfile must be FROM. GitHub's best practices for it are to use official Docker images, such as python or ruby, to use a version tag if one exists, preferably with a major version (node:10 rather than node:latest), and to use images based on the Debian operating system.