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
As you’ll see in a moment, the
my-action-nameis 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.
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.
What did I miss? Is there some super-secret way to reuse YAML I don’t know about?
Send me a note at @JvmName!
Github’s Composite Run Steps docs
Metadata Syntax Doc:
GitHub Composite Actions - STOP wasting your time and create reusable actions