-
Notifications
You must be signed in to change notification settings - Fork 6
195 lines (169 loc) · 8.28 KB
/
Copy pathcontainer-build.yaml
File metadata and controls
195 lines (169 loc) · 8.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
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