Skip to content

Commit 828431e

Browse files
davdhacsclaudeporridge
authored
Update "latest" tagged images on new tag (#248)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Marcin Owsiany <porridge@redhat.com>
1 parent 70db8b4 commit 828431e

3 files changed

Lines changed: 138 additions & 0 deletions

File tree

.github/workflows/build.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,23 @@ jobs:
3737
id: build-and-push-image
3838
with:
3939
image-flavor: "${{ matrix.image-flavor }}"
40+
- name: Push latest tag
41+
if: startsWith(github.ref, 'refs/tags/')
42+
run: |
43+
if ! git merge-base --is-ancestor "${{ github.sha }}" origin/main; then
44+
echo "Skipping latest push: tagged commit is not on main"
45+
exit 0
46+
fi
47+
CURRENT="${{ github.ref_name }}"
48+
LATEST="$(git tag --merged origin/main --sort=-version:refname | head -1)"
49+
if [[ "${CURRENT}" != "${LATEST}" ]]; then
50+
echo "Skipping latest push: ${CURRENT} is not the highest version tag on main (${LATEST} is)"
51+
exit 0
52+
fi
53+
IMAGE="${{ steps.build-and-push-image.outputs.image-tag }}"
54+
LATEST_IMAGE="quay.io/stackrox-io/apollo-ci:${{ matrix.image-flavor }}-latest"
55+
docker tag "${IMAGE}" "${LATEST_IMAGE}"
56+
docker push "${LATEST_IMAGE}"
4057
- name: Save image info
4158
run: |
4259
mkdir -p image-info
@@ -67,6 +84,23 @@ jobs:
6784
id: build-and-push-image
6885
with:
6986
image-flavor: "${{ matrix.image-flavor }}"
87+
- name: Push latest tag
88+
if: startsWith(github.ref, 'refs/tags/')
89+
run: |
90+
if ! git merge-base --is-ancestor "${{ github.sha }}" origin/main; then
91+
echo "Skipping latest push: tagged commit is not on main"
92+
exit 0
93+
fi
94+
CURRENT="${{ github.ref_name }}"
95+
LATEST="$(git tag --merged origin/main --sort=-version:refname | head -1)"
96+
if [[ "${CURRENT}" != "${LATEST}" ]]; then
97+
echo "Skipping latest push: ${CURRENT} is not the highest version tag on main (${LATEST} is)"
98+
exit 0
99+
fi
100+
IMAGE="${{ steps.build-and-push-image.outputs.image-tag }}"
101+
LATEST_IMAGE="quay.io/stackrox-io/apollo-ci:${{ matrix.image-flavor }}-latest"
102+
docker tag "${IMAGE}" "${LATEST_IMAGE}"
103+
docker push "${LATEST_IMAGE}"
70104
- name: Save image info
71105
run: |
72106
mkdir -p image-info
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Promote to stable
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: "Version to promote (e.g. 0.5.7). Defaults to 'latest'."
8+
required: false
9+
default: "latest"
10+
11+
env:
12+
QUAY_STACKROX_IO_RW_USERNAME: ${{ secrets.QUAY_STACKROX_IO_RW_USERNAME }}
13+
QUAY_STACKROX_IO_RW_PASSWORD: ${{ secrets.QUAY_STACKROX_IO_RW_PASSWORD }}
14+
15+
jobs:
16+
promote-stable:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Log in to Quay
20+
run: |
21+
docker login -u "$QUAY_STACKROX_IO_RW_USERNAME" --password-stdin <<<"$QUAY_STACKROX_IO_RW_PASSWORD" quay.io
22+
- name: Retag all flavors as stable
23+
run: |
24+
VERSION="${{ inputs.version }}"
25+
VERSION="${VERSION:-latest}"
26+
for flavor in scanner-build scanner-test stackrox-build stackrox-test stackrox-ui-test jenkins-plugin; do
27+
SRC="quay.io/stackrox-io/apollo-ci:${flavor}-${VERSION}"
28+
DST="quay.io/stackrox-io/apollo-ci:${flavor}-stable"
29+
echo "Promoting ${SRC} → ${DST}"
30+
docker buildx imagetools create --tag "${DST}" "${SRC}"
31+
done

README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,79 @@ This repository holds the Dockerfiles for images used in StackRox CI & builds.
77
[gha-badge]: https://github.com/stackrox/rox-ci-image/actions/workflows/build.yaml/badge.svg
88
[gha-link]: https://github.com/stackrox/rox-ci-image/actions/workflows/build.yaml
99

10+
## Image Tags and Release Process
11+
12+
Each image flavor (e.g. `stackrox-test`, `scanner-test`) is pushed to
13+
`quay.io/stackrox-io/apollo-ci` with three types of tags:
14+
15+
| Tag | Example | Updated when | Use in |
16+
|-----|---------|-------------|--------|
17+
| **versioned** | `stackrox-test-0.5.7` | Every merge to main (auto-tagged) | Release branch prow configs, pinned references |
18+
| **latest** | `stackrox-test-latest` | Every new version tag on main | Testing rox-ci-image version in openshift/release PRs with `/pj-rehearse` before promoting to stable. |
19+
| **stable** | `stackrox-test-stable` | Manual promotion via workflow | Master/nightly prow configs in openshift/release |
20+
21+
### How it works
22+
23+
1. **Merge to main** -- `tag.yaml` auto-creates a semver tag (e.g. `0.5.8`)
24+
2. **Tag push** -- `build.yaml` builds all images, pushes versioned tags, and
25+
updates `latest` (only if the tag is the highest version on main)
26+
3. **Promote to stable** -- [run manually](https://github.com/stackrox/rox-ci-image/actions/workflows/promote-stable.yaml) when ready:
27+
```bash
28+
gh workflow run promote-stable.yaml
29+
# or with a specific version:
30+
gh workflow run promote-stable.yaml -f version=0.5.8
31+
```
32+
This does a server-side retag (no rebuild) of all image flavors from the
33+
specified version (default: `latest`) to `stable`.
34+
35+
### Updating prow jobs in openshift/release
36+
37+
Prow [job configs](https://github.com/openshift/release/tree/main/ci-operator/config/stackrox/stackrox) in the `openshift/release` repository reference these images via
38+
`build_root.image_stream_tag`. The tags must first be mirrored in
39+
`core-services/image-mirroring/_config.yaml`.
40+
41+
- **Master/nightly configs**: use `stable` tag -- periodically, automatically picks up
42+
promoted versions without config changes.
43+
- **Release branch configs**: pin to a specific version (e.g. `scanner-test-0.5.7`)
44+
for reproducibility.
45+
- **`latest` tag**: use only for testing PRs against openshift/release.
46+
`latest` is a moving target and should not be used for required jobs --
47+
it is intended only for validation before promoting to `stable`.
48+
49+
### Mirroring new versions to openshift CI
50+
51+
To mirror a new versioned tag for release branch use:
52+
53+
1. Add an entry to `core-services/image-mirroring/_config.yaml` in openshift/release
54+
2. PR requires testplatform team review
55+
56+
The `latest` and `stable` floating tags are mirrored once and do not need
57+
updates per version.
58+
59+
## Step-by-step: Making a CI Image Change
60+
61+
Example: you need to bump a dependency or add a tool to the CI image.
62+
63+
1. **Make your change** on a branch and open a PR in this repo.
64+
2. **Merge to main** -- once approved, merge the PR. The `tag.yaml` workflow
65+
auto-creates a semver tag (e.g. `0.5.8`).
66+
3. **Wait for the build** -- the `build.yaml` workflow builds all image flavors
67+
and pushes both versioned and `latest` tags to quay.io.
68+
4. **Test in openshift/release** -- open a PR in `openshift/release` that
69+
references the `latest` tag and run `/pj-rehearse` to validate affected
70+
prow jobs. No config change is needed if the jobs already use `latest`.
71+
5. **Promote to stable** -- once rehearsals pass, [run the promote-stable
72+
workflow](https://github.com/stackrox/rox-ci-image/actions/workflows/promote-stable.yaml)
73+
(or `gh workflow run promote-stable.yaml`). This retags `latest``stable`.
74+
Master/nightly prow jobs pick up the new image automatically.
75+
6. **Pin release branches** (if needed) -- for release branch configs, update
76+
`openshift/release` to reference the specific versioned tag
77+
(e.g. `stackrox-test-0.5.8`). This requires testplatform review.
78+
79+
> **Note:** There is only one `latest` tag per flavor, so only one
80+
> rox-ci-image change can be tested via rehearsal at a time. Coordinate
81+
> with others if multiple changes are in flight.
82+
1083
## Updating the Go Version
1184

1285
To bump the Go version across all Docker images in this repository, use the automated script:

0 commit comments

Comments
 (0)