CI Toolkit Buildkite Plugin
A library of commonly used commands for your CI builds.
Example
For a directory structure that looks like:
my-project/
├── node_modules/
├── package.json
├── package-lock.json
Add the following to your pipeline.yml:
steps:
- command: |
# To persist the cache
save_cache node_modules/ $(hash_file package-lock.json)
# To restore the cache, if present
restore_cache $(hash_file package-lock.json)
plugins:
- automattic/a8c-ci-toolkit#7.0.0:
bucket: a8c-ci-cache # optional
Don’t forget to verify what the latest release is and use that value instead of 7.0.0.
Configuration
bucket (Optional, string)
The name of the S3 bucket to fallback to if the CACHE_BUCKET_NAME environment variable is not set in the CI host. Used by save_cache and restore_cache.
Using the commands inside a Docker container
The commands are made available by adding this plugin’s bin/ directory to the $PATH of the CI job. A step that runs its command inside a container — via the docker plugin, say — doesn’t get them, because the plugin’s files live on the agent host rather than in the image.
For those steps, this plugin exports $A8C_CI_TOOLKIT_PLUGIN_DIR, the absolute path to its own checkout on the host. Mount that into the container and put its bin/ on the $PATH there:
steps:
- command: |
export PATH="$$PATH:/a8c-ci-toolkit/bin"
checkout_release_branch "$RELEASE_VERSION"
plugins:
- automattic/a8c-ci-toolkit#7.0.0
- docker#v5.13.0:
image: node:22-bookworm
expand-volume-vars: true
volumes:
- "$$A8C_CI_TOOLKIT_PLUGIN_DIR:/a8c-ci-toolkit:ro"
Three things make that work:
- Listing this plugin alongside
docker. Every plugin’senvironmenthook runs before any plugin’scommandhook, so the variable is exported before thedockerplugin assembles itsdocker runarguments — whichever order the two are listed in. expand-volume-vars: true, without which thedockerplugin passes thevolumesentry through verbatim instead of interpolating the variable.- The
$$in both$$A8C_CI_TOOLKIT_PLUGIN_DIRand$$PATH. A single$is resolved when the pipeline is uploaded, where neither variable has a value yet;$$defers it to when the job runs. Note that this is only needed if you write that line directly in the.yml; if instead yourcommand:calls a dedicated.shscript you can doexport PATH=$PATH:/a8c-ci-toolkit/binin that.shfile instead of in the.ymland avoid the need for the$$escape.
Only the commands whose dependencies the image provides will work, of course — checkout_release_branch needs bash and git inside the container, for instance.
Developing
To run the linter and tests:
make lint
make test
Contributing
- Fork the repo
- Make the changes
- Run the tests
- Commit and push your changes
- Send a pull request
Releasing
- Make a PR to update references of the version number in this
README.mdand to update theCHANGELOG.mdaccording to the<!-- instructions -->to prepare it for a new release. - Merge the PR
- Create a new GitHub Release, named after the new version number, and pasting the content of the
CHANGELOG.mdsection corresponding to the new version as description. This will have the side effect of creating agit tagtoo, which is all we need for the new version to be available.