diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d01227a..1128608 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -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 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f14bae0..f15ba5e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/tests/container_test.py b/tests/container_test.py index bddee4b..449c117 100644 --- a/tests/container_test.py +++ b/tests/container_test.py @@ -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 (