What if we can use GitHub Container Registry as a GitHub Action Registry (which is missing at the moment). This entails using the GitHub CLI to package a docker-based GitHub Actions and publish the action image with everything necessary to make it discoverable by the GitHub Workflow Engine.
This idea follow-up a conversation we had with Tug about a package registry dedicated to GitHub Actions. So, I started to reflect on it and I came up with a solution that involve using the GitHub Container Registry as the GitHub Action Registry.
What if you can use the GitHub CLI and the action.yml
metafile to package a docker-based action as a OCI-compliant docker image and the action to be auto-discovered by the GitHub Workflow Engine?
To make it work, the CLI has to provide a new command dedicated to manage actions
and the following sub commands:
gh actions create [--name <action-name>] <flags> # Scafflod a new github action project's directory tree according to their given flags
gh actions pack [--name <action-name>] <flags> # Package a github action as a fulling operational docker image
gh actions publish [--name <action-name>] <flags> # To publish the GitHub Action on the Docker GitHub Registry
Let's explore the purpose of each sub commands.
The goal of the pack
is to build the docker image or feed an existing docker image with labels coming from the result of
encoding the action.yml
meta file as docker labels.
Running the pack command should:
- Validate the
action.yml
file - Encode the
action.yml
contents as docker labels and embed the result into the docker image being built - Build the docker image using thoses labels with a set of
--label "NAME"="VALUE"
flags.
ℹ️ Embedding GitHub action metadata as labels within the docker image, enable querying those labels using tools like skopeo.
Let use the following sample GitHub action meta file contents to illustrate some approaches to make encoding works.
# action.yml
name: 'custom-docker-action'
description: 'custom-docker-action'
inputs:
an-input:
description: 'an-input'
required: true
runs:
using: 'docker'
image: 'Dockerfile'
args:
- ${{ inputs.an-input }}
- <arg2>
the pack
sub command will encode the metafile content as a collection of labels. As a result you will get some like this:
[
'"com.github.actions.meta.name"="custom-docker-action"',
'"com.github.actions.meta.description"=custom-docker-action"',
'"com.github.actions.meta.inputs.1.name"="an-input"',
'"com.github.actions.meta.inputs.1.description"="an-input"',
'"com.github.actions.meta.inputs.1.required"="true"',
'"com.github.actions.meta.runs.using"="docker"',
'"com.github.actions.meta.runs.image"="Dockerfile"',
'"com.github.actions.meta.runs.args"="${{ inputs.an-input }},<arg2>"'
]
Another approach is to encode the whole action.yml
file as base64 as pass it as a label to the docker build command as follows
# Build the docker image with metadata encoded as base64 and embed as a label within the docker image
docker build --label "com.github.actions.meta-base64-encoded"="$(base64 -i action.yml)" ...
# Eg:
docker build --label "com.github.actions.meta-base64-encoded"="bmFtZTogJ2N1c3RvbS1kb2NrZXItYWN0aW9uJwpk..." ...
If the action's metadata are embedded into the docker image as labels. The GitHub Workflow Engine could query and parse those labels to get the GitHub action metadata and dynamically get what it needs without having to use the action.yml file.
"com.github.actions.meta.*"
: For multiple labels entries"com.github.actions.meta-base64-encoded"
: For metadata contents encoded as base64