Skip to content

Instantly share code, notes, and snippets.

@lktslionel
Last active January 9, 2023 10:08
Show Gist options
  • Save lktslionel/db734c96f21de173a497b17707303121 to your computer and use it in GitHub Desktop.
Save lktslionel/db734c96f21de173a497b17707303121 to your computer and use it in GitHub Desktop.
Packaging & Auto-discovery of docker-based GitHub Actions using GitHub CLI

Docker-based GitHub Actions Packaging & Discovery

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.


Contents


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:

  1. Validate the action.yml file
  2. Encode the action.yml contents as docker labels and embed the result into the docker image being built
  3. 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment