Skip to content

chore(deps): update actions/checkout digest to df4cb1c (#181) #180

chore(deps): update actions/checkout digest to df4cb1c (#181)

chore(deps): update actions/checkout digest to df4cb1c (#181) #180

name: Container image build
on:
push:
branches:
- main
- release-1.[0-9]+
tags:
- '[0-9]+.[0-9]+.[0-9]+'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
IMAGE_NAME: ${{ vars.REGISTRY_ORG }}/rhdh-must-gather
jobs:
image-publish:
name: Publish Container Image
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Log into registry ${{ vars.REGISTRY }}
uses: redhat-actions/podman-login@4934294ad0449894bcd1e9f191899d7292469603 # v1
with:
registry: ${{ vars.REGISTRY }}
username: ${{ vars.QUAY_USERNAME }}
password: ${{ secrets.QUAY_TOKEN }}
# Install the cosign tool
# https://github.com/sigstore/cosign-installer
- name: Install cosign
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
with:
cosign-release: 'v2.2.4'
# Generate image tags and build args based on ref type
- name: Prepare build variables
id: prep
run: |
SHORT_SHA=$(git rev-parse --short=9 HEAD)
# Calculate expiration date (2 weeks from now as Unix timestamp)
EXPIRATION_TIMESTAMP=$(date -u -d "+14 days" +"%s")
echo "EXPIRATION_TIMESTAMP=${EXPIRATION_TIMESTAMP}" >> "$GITHUB_OUTPUT"
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
# Git tag: push the tag version and derive major/minor tags
TAG_VERSION=${GITHUB_REF#refs/tags/}
echo "IMAGE_TAG=${TAG_VERSION}" >> "$GITHUB_OUTPUT"
echo "VERSION=${TAG_VERSION}" >> "$GITHUB_OUTPUT"
# Parse semantic version to extract major and major.minor
if [[ ${TAG_VERSION} =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
MAJOR="${BASH_REMATCH[1]}"
MINOR="${BASH_REMATCH[2]}"
echo "EXTRA_TAGS=${MAJOR} ${MAJOR}.${MINOR}" >> "$GITHUB_OUTPUT"
else
echo "EXTRA_TAGS=" >> "$GITHUB_OUTPUT"
fi
elif [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
# Main branch: push latest and latest-${commit}
echo "IMAGE_TAG=latest" >> "$GITHUB_OUTPUT"
echo "EXTRA_TAGS=latest-${SHORT_SHA}" >> "$GITHUB_OUTPUT"
VERSION="0.0.0-$(git describe --no-match --always --abbrev=9 --dirty --broken 2>/dev/null || echo unknown)"
echo "VERSION=${VERSION}" >> "$GITHUB_OUTPUT"
elif [[ "${{ github.ref }}" == refs/heads/release-* ]]; then
# Release branch: extract version and push latest-1.x and latest-1.x-${commit}
BRANCH_NAME=${GITHUB_REF#refs/heads/}
RELEASE_VERSION=${BRANCH_NAME#release-}
echo "IMAGE_TAG=latest-${RELEASE_VERSION}" >> "$GITHUB_OUTPUT"
echo "EXTRA_TAGS=latest-${RELEASE_VERSION}-${SHORT_SHA}" >> "$GITHUB_OUTPUT"
VERSION="0.0.0-$(git describe --no-match --always --abbrev=9 --dirty --broken 2>/dev/null || echo unknown)"
echo "VERSION=${VERSION}" >> "$GITHUB_OUTPUT"
fi
# Build and push using Makefile
- name: Build and push container image
id: build-push
run: |
# Get the VERSION from prep step
VERSION="${{ steps.prep.outputs.VERSION }}"
# Build and push main tag
make image-push \
CONTAINER_TOOL=podman \
REGISTRY=${{ vars.REGISTRY }} \
IMAGE_NAME=${{ env.IMAGE_NAME}} \
IMAGE_TAG=${{ steps.prep.outputs.IMAGE_TAG }} \
BUILD_ARGS="--build-arg RHDH_MUST_GATHER_VERSION=${VERSION}"
# Get image digest
DIGEST=$(podman inspect --format='{{index .RepoDigests 0}}' ${{ vars.REGISTRY }}/${{ env.IMAGE_NAME}}:${{ steps.prep.outputs.IMAGE_TAG }} | cut -d'@' -f2)
echo "digest=${DIGEST}" >> "$GITHUB_OUTPUT"
# Save main tag for signing
echo "${{ vars.REGISTRY }}/${{ env.IMAGE_NAME}}:${{ steps.prep.outputs.IMAGE_TAG }}" > /tmp/image-tags.txt
# Push extra tags if specified
- name: Push extra tags
if: steps.prep.outputs.EXTRA_TAGS != ''
run: |
# Process each extra tag (space-separated)
for TAG in ${{ steps.prep.outputs.EXTRA_TAGS }}; do
echo "Processing tag: ${TAG}"
# All extra tags reuse the main image to preserve digest
echo "Tagging and pushing: ${TAG}"
podman tag ${{ vars.REGISTRY }}/${{ env.IMAGE_NAME}}:${{ steps.prep.outputs.IMAGE_TAG }} ${{ vars.REGISTRY }}/${{ env.IMAGE_NAME}}:${TAG}
podman push ${{ vars.REGISTRY }}/${{ env.IMAGE_NAME}}:${TAG}
# Track commit-SHA tags for expiration
if [[ ${TAG} == latest-* ]]; then
echo "${TAG}" >> /tmp/expiry-tags.txt
fi
# Add tag for signing
echo "${{ vars.REGISTRY }}/${{ env.IMAGE_NAME}}:${TAG}" >> /tmp/image-tags.txt
done
# Set expiration on commit-SHA tags via Quay.io API
# Note: This requires an OAuth Application token, not a robot account token
# Create an OAuth app in Quay.io and store the token as QUAY_OAUTH_TOKEN secret
- name: Set expiration on commit-SHA tags
if: steps.prep.outputs.EXTRA_TAGS != ''
env:
# Use QUAY_OAUTH_TOKEN if available, otherwise fall back to QUAY_TOKEN
API_TOKEN: ${{ secrets.QUAY_OAUTH_TOKEN || secrets.QUAY_TOKEN }}
run: |
# Check if there are any commit-SHA tags to expire
if [ ! -f /tmp/expiry-tags.txt ]; then
echo "No commit-SHA tags to set expiration on"
exit 0
fi
# Extract namespace and repo name from IMAGE_NAME
NAMESPACE=$(echo "${{ env.IMAGE_NAME }}" | cut -d'/' -f1)
REPO=$(echo "${{ env.IMAGE_NAME }}" | cut -d'/' -f2)
# Set expiration for each commit-SHA tag
while IFS= read -r TAG; do
echo "Setting expiration on ${TAG} to ${{ steps.prep.outputs.EXPIRATION_TIMESTAMP }} (Unix timestamp)"
RESPONSE=$(curl -s -w "\n%{http_code}" -X PUT \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"expiration\": ${{ steps.prep.outputs.EXPIRATION_TIMESTAMP }}}" \
"https://${{ vars.REGISTRY }}/api/v1/repository/${NAMESPACE}/${REPO}/tag/${TAG}")
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" -ne 200 ] && [ "$HTTP_CODE" -ne 201 ]; then
echo "Warning: Failed to set expiration on ${TAG} (HTTP $HTTP_CODE): $BODY"
echo "This may be due to using a robot account token instead of an OAuth application token"
else
echo "✓ Expiration set successfully on ${TAG}"
fi
done < /tmp/expiry-tags.txt
# Sign the resulting image digests
# https://github.com/sigstore/cosign
- name: Sign the published images
env:
DIGEST: ${{ steps.build-push.outputs.digest }}
run: |
# Sign all tags
while IFS= read -r tag; do
echo "Signing ${tag}@${DIGEST}"
cosign sign --yes "${tag}@${DIGEST}"
done < /tmp/image-tags.txt
- name: Summary
run: |
echo "### Build Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Version**: ${{ steps.prep.outputs.VERSION }}" >> $GITHUB_STEP_SUMMARY
echo "- **Registry**: ${{ vars.REGISTRY }}" >> $GITHUB_STEP_SUMMARY
echo "- **Main Tag**: \`${{ steps.prep.outputs.IMAGE_TAG }}\`" >> $GITHUB_STEP_SUMMARY
if [ -n "${{ steps.prep.outputs.EXTRA_TAGS }}" ]; then
echo "- **Extra Tags**:" >> $GITHUB_STEP_SUMMARY
for TAG in ${{ steps.prep.outputs.EXTRA_TAGS }}; do
echo " - \`${TAG}\`" >> $GITHUB_STEP_SUMMARY
done
fi
echo "- **Digest**: \`${{ steps.build-push.outputs.digest }}\`" >> $GITHUB_STEP_SUMMARY
echo "- **Signed**: ✅" >> $GITHUB_STEP_SUMMARY