Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the docker/metadata-action GitHub Action to generate our image metadata #207

Merged
merged 2 commits into from
Jan 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ updates:
- dependency-name: step-security/harden-runner
# Managed by cisagov/skeleton-docker
# - dependency-name: actions/download-artifact
# - dependency-name: actions/github-script
# - dependency-name: actions/upload-artifact
# - dependency-name: docker/build-push-action
# - dependency-name: docker/login-action
# - dependency-name: docker/metadata-action
# - dependency-name: docker/setup-buildx-action
# - dependency-name: docker/setup-qemu-action
# - dependency-name: github/codeql-action
Expand Down
158 changes: 22 additions & 136 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,54 +191,13 @@ jobs:
uses: mxschmitt/action-tmate@v3
if: env.RUN_TMATE
prepare:
# Calculates and publishes outputs that are used by other jobs.
#
# Outputs:
# created:
# The current date-time in RFC3339 format.
# repometa:
# The json metadata describing this repository.
# source_version:
# The source version as reported by the `bump-version show` command.
# tags:
# A comma separated list of Docker tags to be applied to the images on
# Docker Hub. The tags will vary depending on:
# - The event that triggered the build.
# - The branch the build is based upon.
# - The git tag the build is based upon.
#
# When a build is based on a git tag of the form `v*.*.*` the image will
# be tagged on Docker Hub with multiple levels of version specificity.
# For example, a git tag of `v1.2.3+a` will generate Docker tags of
# `:1.2.3_a`, `:1.2.3`, `:1.2`, `:1`, and `:latest`.
#
# Builds targeting the default branch will be tagged with `:edge`.
#
# Builds from other branches will be tagged with the branch name. Solidi
# (`/` characters - commonly known as slashes) in branch names are
# replaced with hyphen-minuses (`-` characters) in the Docker tag. For
# more information about the solidus see these links:
# * https://www.compart.com/en/unicode/U+002F
# * https://en.wikipedia.org/wiki/Slash_(punctuation)#Encoding
#
# Builds triggered by a push event are tagged with a short hash in the
# form: sha-12345678
#
# Builds triggered by a pull request are tagged with the pull request
# number in the form pr-123.
#
# Builds triggered using the GitHub GUI (workflow_dispatch) are tagged
# with the value specified by the user.
#
# Scheduled builds are tagged with `:nightly`.
# Generate Docker image metadata using the docker/metadata-action GitHub Action.
name: Prepare build variables
needs:
- diagnostics
outputs:
created: ${{ steps.prep.outputs.created }}
repometa: ${{ steps.repo.outputs.result }}
source_version: ${{ steps.prep.outputs.source_version }}
tags: ${{ steps.prep.outputs.tags }}
labels: ${{ steps.generate-metadata.outputs.labels }}
tags: ${{ steps.generate-metadata.outputs.tags }}
permissions:
# actions/checkout needs this to fetch code
contents: read
Expand All @@ -254,53 +213,24 @@ jobs:
with:
egress-policy: audit
- uses: actions/checkout@v4
- name: Gather repository metadata
id: repo
uses: actions/github-script@v7
- id: generate-metadata
name: Generate Docker image metadata
uses: docker/metadata-action@v5
with:
script: |
const repo = await github.rest.repos.get(context.repo)
return repo.data
- name: Calculate output values
id: prep
run: |
VERSION=noop
SEMVER="^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?$"
if [ "${{ github.event_name }}" = "schedule" ]; then
VERSION=nightly
elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
VERSION=${{ github.event.inputs.image-tag }}
elif [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
elif [[ $GITHUB_REF == refs/heads/* ]]; then
VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g')
if [ "${{ github.event.repository.default_branch }}" = "$VERSION" ];
then
VERSION=edge
fi
elif [[ $GITHUB_REF == refs/pull/* ]]; then
VERSION=pr-${{ github.event.number }}
fi
if [[ $VERSION =~ $SEMVER ]]; then
VERSION_NO_V=${VERSION#v}
MAJOR="${BASH_REMATCH[1]}"
MINOR="${BASH_REMATCH[2]}"
PATCH="${BASH_REMATCH[3]}"
TAGS="${IMAGE_NAME}:${VERSION_NO_V//+/_},${IMAGE_NAME}:${MAJOR}.${MINOR}.${PATCH},${IMAGE_NAME}:${MAJOR}.${MINOR},${IMAGE_NAME}:${MAJOR},${IMAGE_NAME}:latest"
else
TAGS="${IMAGE_NAME}:${VERSION}"
fi
if [ "${{ github.event_name }}" = "push" ]; then
TAGS="${TAGS},${IMAGE_NAME}:sha-${GITHUB_SHA::8}"
fi
for i in ${TAGS//,/ }
do
TAGS="${TAGS},ghcr.io/${i}"
done
echo "created=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
echo "source_version=$(./bump-version show)" >> $GITHUB_OUTPUT
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
echo tags=${TAGS}
images: |
${{ env.IMAGE_NAME }}
ghcr.io/${{ env.IMAGE_NAME }}
tags: |
type=edge
type=raw,event=workflow_dispatch,value=${{ github.event.inputs.image-tag }}
type=ref,event=branch
type=ref,event=pr
type=ref,event=tag
type=schedule
type=semver,pattern={{major}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{version}}
type=sha
- name: Setup tmate debug session
uses: mxschmitt/action-tmate@v3
if: github.event.inputs.remote-shell == 'true' || env.RUN_TMATE
Expand Down Expand Up @@ -350,29 +280,7 @@ jobs:
cache-to: type=local,dest=${{ env.BUILDX_CACHE_DIR }}
context: .
file: ./Dockerfile
labels: "\
org.opencontainers.image.created=${{
needs.prepare.outputs.created }}

org.opencontainers.image.description=${{
fromJson(needs.prepare.outputs.repometa).description }}

org.opencontainers.image.licenses=${{
fromJson(needs.prepare.outputs.repometa).license.spdx_id }}

org.opencontainers.image.revision=${{ github.sha }}

org.opencontainers.image.source=${{
fromJson(needs.prepare.outputs.repometa).clone_url }}

org.opencontainers.image.title=${{
fromJson(needs.prepare.outputs.repometa).name }}

org.opencontainers.image.url=${{
fromJson(needs.prepare.outputs.repometa).html_url }}

org.opencontainers.image.version=${{
needs.prepare.outputs.source_version }}"
labels: ${{ needs.prepare.outputs.labels }}
outputs: type=docker,dest=dist/image.tar
# Uncomment the following option if you are building an image for use
# on Google Cloud Run or AWS Lambda. The current default image output
Expand Down Expand Up @@ -516,29 +424,7 @@ jobs:
cache-to: type=local,dest=${{ env.BUILDX_CACHE_DIR }}
context: .
file: ./Dockerfile-x
labels: "\
org.opencontainers.image.created=${{
needs.prepare.outputs.created }}

org.opencontainers.image.description=${{
fromJson(needs.prepare.outputs.repometa).description }}

org.opencontainers.image.licenses=${{
fromJson(needs.prepare.outputs.repometa).license.spdx_id }}

org.opencontainers.image.revision=${{ github.sha }}

org.opencontainers.image.source=${{
fromJson(needs.prepare.outputs.repometa).clone_url }}

org.opencontainers.image.title=${{
fromJson(needs.prepare.outputs.repometa).name }}

org.opencontainers.image.url=${{
fromJson(needs.prepare.outputs.repometa).html_url }}

org.opencontainers.image.version=${{
needs.prepare.outputs.source_version }}"
labels: ${{ needs.prepare.outputs.labels }}
platforms: |
linux/amd64
linux/arm/v6
Expand Down
3 changes: 3 additions & 0 deletions tests/container_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ def test_log_version(dockerc, project_version, version_container):
), f"Container version output to log does not match project version file {VERSION_FILE}"


@pytest.mark.skipif(
RELEASE_TAG in [None, ""], reason="this is not a release (RELEASE_TAG not set)"
)
def test_container_version_label_matches(project_version, version_container):
"""Verify the container version label is the correct version."""
assert (
Expand Down
Loading