3 minutes
Your YAML could be DRYer
Github Actions are the go-to continuous integration tool for plenty of reasons - chief among them: first-party support with Github, pretty decent performance, and relatively cheap runner instances.
However, one place Github Actions has fallen short relative to other YAML-based players in the space (namely CircleCI) has been the inability to DRY up the YAML config files.
However, with a cool new 1 feature called Composite Run Steps, your repeated shell script invocations can now happily live in a separate YAML file!
Don’t read the docs
The documentation for Composite Run Steps (linked at the bottom) are great, but they make the terrible assumption that you want to create a whole different repository for your composite action.
If that’s your use-case, great! Otherwise, I’m guessing the far more common use-case is to warehouse code, workflow files, and composite action files in the same repository!
Fortunately, this is possible, the solution just is buried in a Github Community link instead of being plainly available in big bold letters at the top of the Github’s documentation.
3 Steps to DRYer YAML
-
Go through the official docs for creating a Composite Run Step Action, except ignore everything about creating a new repository โ just name your action metadata file as
/.github/actions/my-action-name/action.yml
As you’ll see in a moment, the
my-action-name
is important, since that’s how you’ll reference your action. It can be anything that’s legal as a file-path. -
In your actual Workflow yaml file, replace your repeated shell scripts with the following line; for example:
- - run: sudo apt-get install androidsdk - - run: alias sdkmanager="androidsdk" - - name: Update Android Deps - run: sdkmanager "build-tools;31.0.0-rc5" "platform-tools" "platforms;android-30" "cmdline-tools;latest" "extras;android;m2repository" "extras;google;m2repository" --verbose - env: - ANDROID_SDK_ROOT: /opt/android/sdk + - uses: ./.github/actions/my-action-name
-
Revel in your victory; your workflow files are just a wee bit smaller! ๐
If you’re a visual person, your file heirarchy should look like this:
repo-root/
โโโ.github/
โ โโโactions/
โ โ โโโmy-android-action/
โ โ โโโaction.yml
โ โโโworkflows/
โ โโโworkflow.yml
โโโ:app
In my case, across 2 workflow files, I converted 40 lines of YAML to 14 lines, with the benefit of better maintainability moving forward.
Limitations
As of this writing (06/2021) Composite Run Step Actions don’t support importing other actions – meaning you’ll have to do anything involving a uses
statement the old-fashioned way, for now2:
- name: Build App
uses: eskatos/gradle-command-action@v1
id: gradle
with:
wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true
arguments: :app:assembleDebug --scan
Composite Run Actions also don’t support conditionals, timeouts, referencing secrets, and a few other things. The Metadata Syntax doc has the full enumeration of allowable items; everything else is unsupported.
Wrap-up
What did I miss? Is there some super-secret way to reuse YAML I don’t know about?
Send me a note at @JvmName!
Links/References
-
Github’s Composite Run Steps docs
https://docs.github.com/en/actions/creating-actions/creating-a-composite-run-steps-action
-
Metadata Syntax Doc:
-
GitHub Composite Actions - STOP wasting your time and create reusable actions
https://dev.to/n3wt0n/github-composite-actions-nest-actions-within-actions-3e5l -
Github Community
https://github.community/t/path-to-action-in-the-same-repository-as-workflow/16952/7
-
“New” meaning “I just discovered it yesterday”; I have no idea how long it’s been out. ↩︎
-
It looks like Github has an Architecture Decision Record that’s been accepted…so now it’s just a matter of time? ↩︎