Browse the docs
CI/CD
GitHub Actions
Install a pinned crunu in a GitHub Actions job with the setup-crunu action or three commands, run tests with staging variables, and bind the token with OIDC.
Last updated
On this page
In GitHub Actions, a job installs crunu, then runs your command with crunu run. The service token goes into repository secrets and the other values into repository variables. Read Any CI with a service token first for how to create the token.
Repository settings
| Name | Where | Value |
|---|---|---|
CRUNU_TOKEN | secrets | the service token crunu_svc_… |
CRUNU_SERVER | variables | https://app.crunu.com, or your own server's address |
CRUNU_VERSION | variables | from the CI setup block on the token's page |
CRUNU_INSTALL_URL | variables | from the same block |
CRUNU_INSTALL_SHA256 | variables | from the same block |
CRUNU_BINARY_SHA256 | variables | from the same block |
With three commands
jobs:
test:
runs-on: ubuntu-latest
permissions:
id-token: write # only if the token has a CI binding
contents: read
steps:
- uses: actions/checkout@v4
- name: Install crunu
run: |
curl -sSf "${{ vars.CRUNU_INSTALL_URL }}" -o /tmp/crunu-install.sh
echo "${{ vars.CRUNU_INSTALL_SHA256 }} /tmp/crunu-install.sh" | sha256sum -c -
sh /tmp/crunu-install.sh --version "${{ vars.CRUNU_VERSION }}" --sha256 "${{ vars.CRUNU_BINARY_SHA256 }}" --user-install
- name: Tests
env:
CRUNU_TOKEN: ${{ secrets.CRUNU_TOKEN }}
CRUNU_SERVER: ${{ vars.CRUNU_SERVER }}
run: exec crunu run --env web-app/staging -- npm testWith the setup-crunu action
Crunu includes an action, setup-crunu, in the deploy/ci/github-action/ directory of its source. It installs a pinned crunu, checks the SHA-256 of both the install script and the binary, and adds crunu to PATH for the following steps. It doesn't contact the Crunu server and doesn't publish anything.
The action isn't published in the GitHub Marketplace. Where to keep it is up to you:
- A copy in your repository (recommended). Copy
action.ymlandsetup-crunu.shinto.github/actions/setup-crunu/and use it asuses: ./.github/actions/setup-crunu. The code that gets access to your pipeline's secrets then sits next to your code and goes through the same review. - A separate repository. Publish the directory as its own repository and pin it by the full commit SHA, not by a tag, because a tag can be moved.
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-crunu
with:
version: ${{ vars.CRUNU_VERSION }}
install-url: ${{ vars.CRUNU_INSTALL_URL }}
install-sha256: ${{ vars.CRUNU_INSTALL_SHA256 }}
sha256: ${{ vars.CRUNU_BINARY_SHA256 }}
- name: Tests with staging variables
env:
CRUNU_TOKEN: ${{ secrets.CRUNU_TOKEN }}
CRUNU_SERVER: ${{ vars.CRUNU_SERVER }}
run: exec crunu run --env web-app/staging -- npm test| Input | Required | Value |
|---|---|---|
version | yes | the crunu version, for example 6.0.0 |
install-url | yes, unless releases-url is set | the address of install.sh for this version |
releases-url | instead of install-url | the release directory. Files of a version are in a subdirectory named after it |
install-sha256 | yes | SHA-256 of install.sh |
sha256 | yes | SHA-256 of the binary. One checksum for Linux amd64, or one per platform such as amd64=… arm64=… for Linux and darwin-arm64=… for macOS |
bin-dir | no | an absolute directory for crunu. Defaults to a temporary directory of the job |
Outputs: path, the full path to crunu, and version, what crunu version reported. Input values reach the script as environment variables, never as text inside a shell command.
The action works on Linux and macOS runners, amd64 and arm64, including self-hosted ones. Windows isn't supported, because crunu is built only for Linux and macOS.
What is checked
- The checksum of
install.shis verified before it runs. On a mismatch nothing is installed and the step fails with exit code 1. install.shdownloads the binary for the runner's platform, checks its checksum, checks that it starts, and only then puts it in place.crunu versionmust report the version you asked for.- Invalid inputs, such as a missing checksum, an address that isn't
https://, or a relativebin-dir, fail with exit code 2 before anything is downloaded.
Where the token is visible
Put CRUNU_TOKEN in the env of the one step that runs crunu. Job-level and workflow-level variables reach every step and every process.
The command under crunu run doesn't get CRUNU_TOKEN. On Linux, crunu also closes its own environment in /proc to other processes of the same user. The shell of the step still holds the token, so start crunu with exec as the last command of the run block.
GitHub-hosted runners allow sudo without a password, and a process running as root can read any other process's environment. Against a malicious dependency in the job, the protection is a small grant: only the environment the job needs, without production.
Binding the token to a repository and branch
With a CI binding, the token works only together with a JWT that GitHub issues to the job. Add permissions: id-token: write to the job. crunu requests the JWT itself, with the server address as the audience.
A typical rule for a production token: provider GitHub, repository: kiteline/web-app, ref: refs/heads/main, environment: production, audience https://app.crunu.com. See Bind a service token to CI with OIDC for every field.