diff --git a/.github/workflows/release-auto-tag.yml b/.github/workflows/release-auto-tag.yml index b75881b755..f6a52203f9 100644 --- a/.github/workflows/release-auto-tag.yml +++ b/.github/workflows/release-auto-tag.yml @@ -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 @@ -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" @@ -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" @@ -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" diff --git a/architecture/build.md b/architecture/build.md index 4365356f97..cbb49fba33 100644 --- a/architecture/build.md +++ b/architecture/build.md @@ -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