44# git tag orb-v0.1.0 && git push origin orb-v0.1.0
55#
66# Pull: docker pull ghcr.io/<owner>/gittensory-selfhost:orb-v0.1.0
7+ #
8+ # Prerelease tags (#1937): orb-v0.1.0-rc.1 / orb-v0.1.0-beta.1 run the identical pipeline but never move
9+ # `latest` and are marked prerelease on the GitHub Release -- for beta-testing an image before it becomes
10+ # the stable/latest recommendation.
11+ #
12+ # git tag orb-v0.1.0-rc.1 && git push origin orb-v0.1.0-rc.1
713name : release-orb
814
915on :
1319 workflow_dispatch :
1420 inputs :
1521 version :
16- description : " Version to publish (e.g. 0.1.0)"
22+ description : " Version to publish (e.g. 0.1.0, or a prerelease 0.1.0-rc.1 / 0.1.0-beta.1 )"
1723 required : true
1824
1925permissions :
@@ -66,14 +72,23 @@ jobs:
6672 *) echo "expected an orb-v<semver> tag, got $REF_NAME" >&2; exit 1 ;;
6773 esac
6874 fi
69- if ! printf '%s' "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then
70- echo "expected semver version X.Y.Z, got $VERSION" >&2
75+ # #1937: a stable X.Y.Z tag is the only kind that ever moved `latest` or an unmarked GitHub
76+ # Release; a prerelease tag (X.Y.Z-rc.N / X.Y.Z-beta.N) publishes the SAME image/provenance/SBOM/
77+ # Sentry pipeline below, just flagged as prerelease and never pushed under `latest` (see the
78+ # "Resolve image tags" and "GitHub Release" steps).
79+ if ! printf '%s' "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+(-(rc|beta)\.[0-9]+)?$'; then
80+ echo "expected semver version X.Y.Z, or a prerelease X.Y.Z-rc.N / X.Y.Z-beta.N, got $VERSION" >&2
7181 exit 1
7282 fi
83+ PRERELEASE=false
84+ if printf '%s' "$VERSION" | grep -Eq -- '-(rc|beta)\.[0-9]+$'; then
85+ PRERELEASE=true
86+ fi
7387 {
7488 echo "v=${VERSION}"
7589 echo "tag=orb-v${VERSION}"
7690 echo "release=gittensory-orb@${VERSION}"
91+ echo "prerelease=${PRERELEASE}"
7792 } >> "$GITHUB_OUTPUT"
7893
7994 # Release jobs receive publishing/Sentry credentials, so avoid shared dependency caches here.
@@ -139,15 +154,31 @@ jobs:
139154 username : ${{ github.actor }}
140155 password : ${{ secrets.GITHUB_TOKEN }}
141156
157+ # #1937: `latest` must never move to a prerelease build -- an operator who blindly pulls `latest`
158+ # for a trial should always land on the newest STABLE image, not an in-flight rc/beta.
159+ - name : Resolve image tags
160+ id : tags
161+ env :
162+ PRERELEASE : ${{ steps.version.outputs.prerelease }}
163+ VERSION_TAG : ${{ steps.version.outputs.tag }}
164+ run : |
165+ set -euo pipefail
166+ {
167+ echo "list<<GTORBTAGS"
168+ echo "type=raw,value=${VERSION_TAG}"
169+ if [ "$PRERELEASE" != "true" ]; then
170+ echo "type=raw,value=latest"
171+ fi
172+ echo "type=sha,format=short"
173+ echo "GTORBTAGS"
174+ } >> "$GITHUB_OUTPUT"
175+
142176 - name : Image metadata
143177 id : meta
144178 uses : docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6
145179 with :
146180 images : ghcr.io/${{ github.repository_owner }}/gittensory-selfhost
147- tags : |
148- type=raw,value=${{ steps.version.outputs.tag }}
149- type=raw,value=latest
150- type=sha,format=short
181+ tags : ${{ steps.tags.outputs.list }}
151182 labels : |
152183 org.opencontainers.image.title=gittensory-orb
153184 org.opencontainers.image.description=Self-hostable Gittensory review engine
@@ -210,6 +241,7 @@ jobs:
210241 RELEASE_TAG : ${{ steps.version.outputs.tag }}
211242 RELEASE_ID : ${{ steps.version.outputs.release }}
212243 REPOSITORY_OWNER : ${{ github.repository_owner }}
244+ PRERELEASE : ${{ steps.version.outputs.prerelease }}
213245 run : |
214246 set -euo pipefail
215247 NOTES="$(cat <<EOF
@@ -224,14 +256,23 @@ jobs:
224256 Sentry release id baked into the image: \`${RELEASE_ID}\`.
225257 EOF
226258 )"
259+ # #1937: a prerelease tag never becomes the repo's "Latest release" and is visibly marked as such
260+ # on GitHub -- distinct from the image-tag `latest` decision above (Resolve image tags), which
261+ # this flag also drives at the version-resolution step.
262+ PRERELEASE_ARGS=()
263+ if [ "$PRERELEASE" = "true" ]; then
264+ PRERELEASE_ARGS=(--prerelease --latest=false)
265+ fi
227266 if gh release view "$REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
228267 gh release edit "$REF_NAME" --repo "$GITHUB_REPOSITORY" \
229268 --title "gittensory-orb ${RELEASE_TAG}" \
230- --notes "$NOTES"
269+ --notes "$NOTES" \
270+ "${PRERELEASE_ARGS[@]}"
231271 else
232272 gh release create "$REF_NAME" --repo "$GITHUB_REPOSITORY" \
233273 --verify-tag \
234274 --title "gittensory-orb ${RELEASE_TAG}" \
275+ "${PRERELEASE_ARGS[@]}" \
235276 --notes "$NOTES" \
236277 --generate-notes
237278 fi
0 commit comments