Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 37 additions & 13 deletions .github/workflows/release-auto-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ name: Release Auto-Tag

on:
workflow_dispatch: {}
# schedule:
# - cron: "0 14 * * 1-5" # 7 AM PDT, weekdays only
schedule:
- cron: "0 16 * * *"
timezone: "Europe/Zurich"

permissions:
contents: write
Expand All @@ -19,17 +20,40 @@ concurrency:
jobs:
create-tag:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: main
fetch-depth: 0

- name: Determine next patch version
- name: Determine next pre-release version
id: version
run: |
latest=$(git tag -l 'v*.*.*' --sort=-v:refname | head -1)
if [ -z "$latest" ]; then
echo "::error::No existing v*.*.* tags found"
set -euo pipefail
tags=$(git tag -l)
latest=$(printf '%s\n' "$tags" | \
{ grep -E '^v[0-9]+\.[0-9]+\.[0-9]+(-pre\.[1-9][0-9]*)?$' || true; } | \
sort -V | tail -1)
if [[ ! "$latest" =~ ^(v[0-9]+\.[0-9]+\.[0-9]+)-pre\.([1-9][0-9]*)$ ]]; then
echo "No active pre-release series — skipping tag creation"
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
base=${BASH_REMATCH[1]}
number=${BASH_REMATCH[2]}
if ! git show-ref --verify --quiet "refs/tags/${base}-pre.1"; then
echo "No ${base}-pre.1 seed — skipping tag creation"
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
if git show-ref --verify --quiet "refs/tags/${base}"; then
echo "$base is already stable — skipping tag creation"
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
if ! git merge-base --is-ancestor "$latest" HEAD; then
echo "::error::Latest pre-release $latest is not an ancestor of main"
exit 1
fi
echo "Latest tag: $latest"
Expand All @@ -43,10 +67,7 @@ jobs:
exit 0
fi

major=$(echo "$latest" | sed 's/^v//' | cut -d. -f1)
minor=$(echo "$latest" | sed 's/^v//' | cut -d. -f2)
patch=$(echo "$latest" | sed 's/^v//' | cut -d. -f3)
next="v${major}.${minor}.$((patch + 1))"
next="${base}-pre.$((number + 1))"

if git tag -l "$next" | grep -q .; then
echo "::error::Tag $next already exists"
Expand All @@ -58,15 +79,18 @@ jobs:

- name: Create and push tag
if: steps.version.outputs.skip != 'true'
env:
NEXT_TAG: ${{ steps.version.outputs.next }}
run: |
git tag ${{ steps.version.outputs.next }}
git push origin ${{ steps.version.outputs.next }}
git tag "$NEXT_TAG"
git push origin "refs/tags/$NEXT_TAG"

- name: Trigger Release Tag workflow
if: steps.version.outputs.skip != 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NEXT_TAG: ${{ steps.version.outputs.next }}
run: |
gh workflow run release-tag.yml \
--ref main \
-f tag=${{ steps.version.outputs.next }}
-f tag="$NEXT_TAG"
15 changes: 11 additions & 4 deletions architecture/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -441,10 +441,17 @@ job republishes the analysis job's outcome as the
required statuses, so they do not gate merges.

Codex Security findings are informational during the observation phase, and the
workflow only reports on candidates that already exist. Creating pre-release
tags and gating stable promotion on qualification results are part of
[RFC 0014](../rfc/0014-release-stability/release-qualification.md) and are not
implemented yet.
workflow only reports on candidates that already exist. Gating stable promotion
on qualification results remains proposed in
[RFC 0014](../rfc/0014-release-stability/release-qualification.md).

`release-auto-tag.yml` runs daily at 16:00 Europe/Zurich (including daylight saving
time changes) and supports manual dispatch.
Maintainers choose the next version by creating `vX.Y.Z-pre.1`. The workflow
increments the highest release series' pre-release number on `main` only when
that seed exists, its stable tag does not exist, and new commits are available.
It never chooses a minor or patch version or creates the initial seed. After
pushing the tag, it explicitly dispatches `release-tag.yml` to build the candidate.

## Artifact Scanning

Expand Down
Loading