Skip to content
shellhacks.dev
CI/CD

Add to PATH in GitHub Actions

Add a directory to PATH for later steps by appending it to the file in GITHUB_PATH, one directory per line. The current step's own PATH is unchanged.

1 min read
Summarize in AI

A step downloads a tool into a local bin directory, and the next steps should find it without a full path.

Shell
export GITHUB_PATH=$(mktemp)
mkdir -p "$PWD/tools/bin"
printf '#!/bin/sh\necho hellotool 1.0\n' > tools/bin/hellotool
chmod +x tools/bin/hellotool
echo "$PWD/tools/bin" >> "$GITHUB_PATH"
echo "same step: $(command -v hellotool || echo 'not found')"
echo "what the runner reads:"
sed "s|$PWD|.|" "$GITHUB_PATH"
echo "later step, simulated:"
PATH="$(head -1 "$GITHUB_PATH"):$PATH" hellotool
Text
same step: not found
what the runner reads:
./tools/bin
later step, simulated:
hellotool 1.0

The runner prepends each line of the GITHUB_PATH file to PATH for every following step in the job, as the workflow commands reference says. The current step is not affected, so hellotool is not found there. The last line prepends the directory by hand to show what a later step sees. A temporary file replaces the runner's in this run.

One directory per line, and no PATH syntax with colons. A directory added this way comes first, so it can shadow a system tool of the same name, which is a supply chain risk if the directory is writable by untrusted steps. It does not persist beyond the job.

Share

More snippets

CI/CD

Check what changed in a pull request

List the files a pull request changed with git diff --name-only origin/main...HEAD. Three dots compare against the merge base, and a shallow checkout cannot do it.

2 min read
CI/CD

Print a warning annotation

Print ::warning file=...,line=...::message from a step to show an annotation on the run and in the pull request diff. Newlines in the text must be encoded.

1 min read
CI/CD

Run a script from the repo

Run a repository script from a workflow with run: ./script.sh only if Git stores it as executable. Otherwise the step fails with Permission denied, status 126.

2 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.