Stephen Mwangi
Push rock to GitHub Container Registry
Recently, I needed to push an OCI image created with Rockcraft Rockcraft is a tool used to create rocks - a new generation of secure, stable and OCI-compliant container images, based on Ubuntu. to the GitHub Container Registry (GHCR) and generate an artifact attestation for it. I ended up having to do a bit of digging and tinkering to come up with a GitHub workflow that I liked, so I thought I would share it here in case someone else encounters the same problem.
You can use this GitHub Action to push to GHCR but it can be adapted to push to any container registry. Make sure to replace <username>
with your GitHub username/organization and <repository>
with the name of your repository in the last 2 steps. This workflow also assumes that you have a rockcraft.yaml
file in the root of your repository but you can modify it to point to a different location. I’ve added these as TODOs
.
name: Push Image to GitHub Container Registry
on:
push:
branches:
- main
workflow_dispatch: {}
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write # required to work with repository contents
packages: write # required to push the image to the container registry
attestations: write # required to persist the attestation
id-token: write # required to mint the OIDC token needed to request a Sigstore signing certificate
steps:
- name: Check out the repository
uses: actions/checkout@v4
# LXD is required to pack the rock
- name: Setup LXD
uses: canonical/setup-lxd@main
- name: Install Rockcraft
run: |
sudo snap install rockcraft --classic
sudo snap install yq
- name: Build rock
run: |
ROCKCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=True rockcraft pack --verbose
- name: Log in to the container registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# TODO: Replace <username> and <repository>
# TODO: Change path to rockcraft.yaml if it's not in the root of the repository
- name: Push image to container registry
id: push
run: |
NAME=$(yq .name rockcraft.yaml)
VERSION=$(yq .version rockcraft.yaml)
rockcraft.skopeo --insecure-policy copy \
oci-archive:${NAME}_${VERSION}_amd64.rock \
docker://ghcr.io/<username>/<repository>:${VERSION} \
--dest-creds ${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}
DIGEST=$(rockcraft.skopeo inspect --format "{{.Digest}}" docker://ghcr.io/<username>/<repository>:${VERSION})
echo "digest=${DIGEST}" >> $GITHUB_OUTPUT
# TODO: Replace <username> and <repository>
- name: Generate attestation
uses: actions/attest-build-provenance@v1
with:
subject-name: ghcr.io/<username>/<repository>
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
Happy crafting! ✨