Reuse GitHub Actions workflows across repositories
On first run, ghat
will copy a workflow from another GitHub repo. Successive runs will update the existing workflows and preserve the env
variables.
- Write workflows once, use them in any repository
- Update your workflows without copy-pasting YAML
- Preserve local
env
variables - Customize workflows before importing them
The good parts:
ghat
does not run every time on your CIghat
doesn't have to be a dependency of your projectghat
is node-based, but can install any type of workflows- Workflow changes need to be committed by the user, so you don't have to worry about it suddenly breaking "because of a dependency"
Requirements:
- git
- npm or yarn (you can use
npx ghat ...
oryarn dlx ghat ...
to run it without installing it) - a writable
~/.degit
cache folder as required by degit
ghat
uses degit to fetch any repository or specific YAML file/folder within it. Below you can find some examples using the workflows in fregante/ghatemplates.
$ ghat --help
Description
Reuse GitHub Actions workflows across repositories
Usage
$ ghat <source> [options]
Options
--exclude Any part of the YAML file to be removed (can be repeated)
--set Value to add (can be repeated). The value is interpreted as YAML/JSON. Writing JSON on the CLI is tricky, so you might want to wrap the whole flag value
-v, --version Displays current version
-h, --help Displays this message
Examples
$ ghat fregante/ghatemplates/node
$ ghat fregante/ghatemplates/node --exclude jobs.Build --exclude jobs.Test
$ ghat fregante/ghatemplates/node --set on=push
$ ghat fregante/ghatemplates/node --set 'jobs.Test.container=node:12.15'
$ ghat fregante/ghatemplates/node-multi --set jobs.build.strategy.matrix.node-version=\[8.x,10.x\]
$ ghat fregante/ghatemplates/node/build.yml
If you provide a user/repo
address, ghat
will fetch the repository and look for *.yml
/*.yaml
files at the top level. If none are found, it will assume you want to copy the repo’s active workflows from .github/workflows
npx ghat fregante/ghat
# Copies *.yml OR .github/workflows/*.yml
npx ghat fregante/ghatemplates/node
# Copies node/*.yml into the local .github/workflows. It's NOT recursive
npx ghat fregante/ghatemplates/node/ci.yml
# Copies node/ci.yml into the local .github/workflows/ci.yml
You can exclude any property from the template by using the --exclude <path>
flag, multiple times.
path
is parsed by dot-prop, so refer to its documentation.
--exclude on.schedule
You can set/overwrite any value with the --set <path>=<value>
flag, multiple times.
path
is parsed by dot-prop, so refer to its documentation.value
is a YAML/JSON value passed directly to the YAML parser.
Note: writing JSON on the command line is a little tricky, so if you're running into errors, try wrapping the whole flag value into a string, for example:
--set 'on.schedule=[{"cron": "42 17 * * 4"}]'
When you fetch a workflow that already exists locally, the local file will be overridden, except for the top-level env
object. For example:
env:
ADJECTIVE: cool
# DO NOT EDIT BELOW - use `npx ghat fregante/workflows/demo`
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo My workflow is $ADJECTIVE
env:
ADJECTIVE: the default
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo This new workflow is "$ADJECTIVE" since it was updated
Only the top-level env
will be preserved, the rest will be updated.
env:
ADJECTIVE: cool
# DO NOT EDIT BELOW - use `npx ghat fregante/workflows/demo`
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo This new workflow is "$ADJECTIVE" since it was updated
GitHub Actions Templating
I won’t pretend to know exactly what a Ghat is, but you should know check them out, they’re beautiful. 🇮🇳
MIT © Federico Brigante