Skip to content

Commit e6c3708

Browse files
Kasturi NarraKasturi Narra
authored andcommitted
Separate OKD build and push phases
1 parent dfa6c32 commit e6c3708

File tree

2 files changed

+196
-17
lines changed

2 files changed

+196
-17
lines changed

.github/actions/build-okd/action.yaml

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,23 +51,30 @@ runs:
5151
set -euo pipefail
5252
5353
cd ${GITHUB_WORKSPACE}/
54+
# The 'staging' mode builds images locally AND pushes them to staging registry
55+
# Staging registry is automatically derived as: $(dirname target-registry)/okd-staging
56+
# This allows testing before promoting to production
5457
TARGET_REGISTRY="${{ inputs.target-registry }}" ./src/okd/build_images.sh \
58+
staging \
5559
"${{ inputs.okd-version-tag }}" \
5660
"${{ inputs.ushift-gitref }}" \
5761
"${{ inputs.target-arch }}"
5862
59-
- name: Build MicroShift RPMs
63+
- name: Build MicroShift RPMs using staging OKD images
6064
shell: bash
6165
run: |
6266
# See https://github.com/microshift-io/microshift/blob/main/docs/build.md
6367
# for more information about the build process.
6468
65-
# Run the RPM build process.
69+
# Run the RPM build process using images from staging registry
70+
# Staging registry is derived as: $(dirname target-registry)/okd-staging
6671
cd ${GITHUB_WORKSPACE}/
72+
PRODUCTION_REGISTRY="${{ inputs.target-registry }}"
73+
STAGING_REGISTRY="$(dirname "${PRODUCTION_REGISTRY}")/okd-staging"
6774
make rpm \
6875
USHIFT_GITREF="${{ inputs.ushift-gitref }}" \
6976
OKD_VERSION_TAG="${{ inputs.okd-version-tag }}" \
70-
OKD_RELEASE_IMAGE="${{ inputs.target-registry }}/okd-release-${{ steps.detect-cpu-arch.outputs.go_arch }}" \
77+
OKD_RELEASE_IMAGE_AARCH64="${STAGING_REGISTRY}/okd-release-arm64" \
7178
RPM_OUTDIR=/mnt/rpms
7279
7380
- name: Build MicroShift bootc container image
@@ -97,6 +104,79 @@ runs:
97104
make run-healthy
98105
make stop
99106
107+
- name: Push OKD images to production registry
108+
if: success()
109+
shell: bash
110+
run: |
111+
set -euo pipefail
112+
113+
cd ${GITHUB_WORKSPACE}/
114+
# Only push to production if all tests passed
115+
# This ensures we don't publish broken OKD images to production
116+
TARGET_REGISTRY="${{ inputs.target-registry }}" ./src/okd/build_images.sh \
117+
production \
118+
"${{ inputs.okd-version-tag }}" \
119+
"${{ inputs.ushift-gitref }}" \
120+
"${{ inputs.target-arch }}"
121+
122+
- name: Cleanup staging registry
123+
if: always()
124+
shell: bash
125+
continue-on-error: true
126+
env:
127+
GH_TOKEN: ${{ inputs.token }}
128+
run: |
129+
set -euo pipefail
130+
131+
# GitHub Container Registry cleanup using gh CLI
132+
# Dynamically discovers and deletes all staging packages
133+
PRODUCTION_REGISTRY="${{ inputs.target-registry }}"
134+
STAGING_REGISTRY="$(dirname "${PRODUCTION_REGISTRY}")/okd-staging"
135+
OWNER=$(echo "${STAGING_REGISTRY}" | cut -d'/' -f2)
136+
137+
echo "Discovering staging packages for cleanup..."
138+
echo "Owner: ${OWNER}"
139+
140+
# Try to get packages - first try user endpoint, then org endpoint
141+
# Use --paginate to handle multiple pages of results
142+
if packages=$(gh api --paginate "/users/${OWNER}/packages" \
143+
-F package_type=container \
144+
--jq '.[] | select(.name | startswith("okd-staging/")) | .name' 2>/dev/null); then
145+
echo "Queried user packages"
146+
elif packages=$(gh api --paginate "/orgs/${OWNER}/packages" \
147+
-F package_type=container \
148+
--jq '.[] | select(.name | startswith("okd-staging/")) | .name' 2>/dev/null); then
149+
echo "Queried organization packages"
150+
else
151+
echo "ERROR: Failed to query packages for ${OWNER}"
152+
exit 1
153+
fi
154+
155+
if [ -z "${packages}" ]; then
156+
echo "No staging packages found to clean up"
157+
exit 0
158+
fi
159+
160+
echo "Found packages to delete:"
161+
echo "${packages}" | sed 's/^/ - /'
162+
echo ""
163+
164+
# Delete each package
165+
while IFS= read -r package; do
166+
# URL-encode package name (replace / with %2F)
167+
encoded_package="${package//\//%2F}"
168+
169+
echo "Deleting package: ${OWNER}/${package}"
170+
if gh api --method DELETE "/users/${OWNER}/packages/container/${encoded_package}" \
171+
-H "Accept: application/vnd.github+json" &>/dev/null; then
172+
echo " ✓ Deleted"
173+
else
174+
echo " ⚠ Failed or already deleted"
175+
fi
176+
done <<< "${packages}"
177+
178+
echo "Staging registry cleanup completed"
179+
100180
# Uncomment this to enable tmate-debug on failure
101181
# - name: Pause and open tmate debug session
102182
# if: failure()

src/okd/build_images.sh

Lines changed: 113 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,23 @@ set -euo pipefail
44
export LC_ALL=C.UTF-8
55
export LANG=C.UTF-8
66

7-
TARGET_REGISTRY=${TARGET_REGISTRY:-ghcr.io/microshift-io/okd}
7+
# Production registry - must be provided via TARGET_REGISTRY environment variable
8+
# or defaults to the upstream registry if not specified
9+
PRODUCTION_REGISTRY="${TARGET_REGISTRY:-ghcr.io/microshift-io/okd}"
10+
# Automatically derive staging registry by appending '/okd-staging' subpath
11+
STAGING_REGISTRY="$(dirname "${PRODUCTION_REGISTRY}")/okd-staging"
812
PULL_SECRET=${PULL_SECRET:-~/.pull-secret.json}
913

1014
WORKDIR=$(mktemp -d /tmp/okd-build-images-XXXXXX)
1115
trap 'cd ; rm -rf "${WORKDIR}"' EXIT
1216

1317
usage() {
14-
echo "Usage: $(basename "$0") <okd-version> <ocp-branch> <target-arch>"
18+
echo "Usage: $(basename "$0") <mode> <okd-version> <ocp-branch> <target-arch>"
19+
echo " mode: Operation mode - 'staging' or 'production'"
20+
echo " 'staging' - Build OKD images locally and push to staging registry"
21+
echo " (${STAGING_REGISTRY})"
22+
echo " 'production' - Push previously built images to production registry"
23+
echo " (${PRODUCTION_REGISTRY})"
1524
echo " okd-version: The version of OKD to build (see https://amd64.origin.releases.ci.openshift.org/)"
1625
echo " ocp-branch: The branch of OCP to build (e.g. release-4.19)"
1726
echo " target-arch: The architecture of the target images (amd64 or arm64)"
@@ -320,17 +329,99 @@ create_new_okd_release() {
320329
# "ovn-kubernetes-microshift=${images_sha[ovn-kubernetes-microshift]}" \
321330
}
322331

332+
# Build OKD images locally and populate images_sha array
333+
build_okd_images() {
334+
echo "Building OKD images locally..."
335+
create_images
336+
337+
for key in "${!images[@]}" ; do
338+
# Skip haproxy-router for non-ARM64 architectures (see TODO at line 99)
339+
# haproxy28 package implementation for amd64 is not yet available
340+
if [ "${TARGET_ARCH}" != "arm64" ] && [ "${key}" = "haproxy-router" ] ; then
341+
continue
342+
fi
343+
images_sha["${key}"]="${images[$key]}"
344+
done
345+
346+
echo "Build completed successfully"
347+
}
348+
349+
# Push images and manifests to registry, then create OKD release
350+
push_okd_images() {
351+
echo "Pushing images to registry: ${TARGET_REGISTRY}"
352+
push_image_manifests
353+
create_new_okd_release
354+
echo "Push completed successfully"
355+
echo "OKD release image published to: ${OKD_RELEASE_IMAGE}"
356+
}
357+
358+
# Retag staging images to production names
359+
retag_staging_to_production() {
360+
local staging_image
361+
local production_image
362+
363+
echo "Re-tagging staging images to production names..."
364+
365+
for key in "${!images[@]}" ; do
366+
# Skip haproxy-router for non-ARM64 architectures (see TODO at line 99)
367+
# haproxy28 package implementation for amd64 is not yet available
368+
if [ "${TARGET_ARCH}" != "arm64" ] && [ "${key}" = "haproxy-router" ] ; then
369+
continue
370+
fi
371+
372+
production_image="${images[$key]}"
373+
staging_image="${production_image/${PRODUCTION_REGISTRY}/${STAGING_REGISTRY}}"
374+
375+
if ! podman image exists "${staging_image}" ; then
376+
echo "ERROR: Local staging image ${staging_image} not found."
377+
echo "Run staging build first: $0 staging ${OKD_VERSION} ${OCP_BRANCH} ${TARGET_ARCH}"
378+
exit 1
379+
fi
380+
381+
echo "Re-tagging ${staging_image} to ${production_image}"
382+
podman tag "${staging_image}" "${production_image}"
383+
images_sha["${key}"]="${production_image}"
384+
done
385+
}
386+
387+
# Staging mode: build images locally and push to staging registry
388+
push_staging() {
389+
check_podman_login
390+
check_release_image_exists
391+
build_okd_images
392+
push_okd_images
393+
echo ""
394+
echo "Images built and pushed to staging registry: ${STAGING_REGISTRY}"
395+
echo "OKD release image available at: ${OKD_RELEASE_IMAGE}"
396+
echo "After successful testing, push to production with:"
397+
echo " $0 production ${OKD_VERSION} ${OCP_BRANCH} ${TARGET_ARCH}"
398+
}
399+
400+
# Production mode: retag staging images and push to production registry
401+
push_production() {
402+
check_podman_login
403+
check_release_image_exists
404+
retag_staging_to_production
405+
push_okd_images
406+
}
407+
323408
#
324409
# Main
325410
#
326-
if [[ $# -ne 3 ]]; then
411+
if [[ $# -ne 4 ]]; then
327412
usage
328413
fi
329414

330-
OKD_VERSION="$1"
331-
OCP_BRANCH="$2"
332-
TARGET_ARCH="$3"
333-
OKD_RELEASE_IMAGE="${TARGET_REGISTRY}/okd-release-${TARGET_ARCH}:${OKD_VERSION}"
415+
MODE="$1"
416+
OKD_VERSION="$2"
417+
OCP_BRANCH="$3"
418+
TARGET_ARCH="$4"
419+
420+
# Validate mode
421+
if [[ "${MODE}" != "staging" ]] && [[ "${MODE}" != "production" ]]; then
422+
echo "ERROR: Invalid mode '${MODE}'. Must be 'staging' or 'production'"
423+
usage
424+
fi
334425

335426
# Determine the alternate architecture
336427
case "${TARGET_ARCH}" in
@@ -346,6 +437,15 @@ case "${TARGET_ARCH}" in
346437
;;
347438
esac
348439

440+
# Set target registry based on mode
441+
if [[ "${MODE}" == "staging" ]]; then
442+
TARGET_REGISTRY="${STAGING_REGISTRY}"
443+
elif [[ "${MODE}" == "production" ]]; then
444+
TARGET_REGISTRY="${PRODUCTION_REGISTRY}"
445+
fi
446+
447+
OKD_RELEASE_IMAGE="${TARGET_REGISTRY}/okd-release-${TARGET_ARCH}:${OKD_VERSION}"
448+
349449
# Populate associative arrays with image names and tags
350450
declare -A images
351451
declare -A images_sha
@@ -368,10 +468,9 @@ images=(
368468

369469
# Check the prerequisites
370470
check_prereqs
371-
check_podman_login
372-
check_release_image_exists
373-
# Create and push images
374-
create_images
375-
push_image_manifests
376-
# Create a new OKD release
377-
create_new_okd_release
471+
# Execute based on mode
472+
if [[ "${MODE}" == "staging" ]]; then
473+
push_staging
474+
elif [[ "${MODE}" == "production" ]]; then
475+
push_production
476+
fi

0 commit comments

Comments
 (0)