zeroclaw/.github/workflows/ci-auto-main-release.yml
2026-03-05 10:24:39 -05:00

170 lines
6.5 KiB
YAML

name: Auto Main Release Tag
on:
push:
branches: [main]
workflow_dispatch:
concurrency:
group: auto-main-release-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: write
env:
GIT_CONFIG_COUNT: "1"
GIT_CONFIG_KEY_0: core.hooksPath
GIT_CONFIG_VALUE_0: /dev/null
jobs:
tag-and-bump:
name: Tag current main + prepare next patch version
runs-on: [self-hosted, Linux, X64, light, cpu40]
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
- name: Skip release-prep commits
id: skip
shell: bash
run: |
set -euo pipefail
msg="$(git log -1 --pretty=%B | tr -d '\r')"
if [[ "${msg}" == *"[skip ci]"* && "${msg}" == chore\(release\):\ prepare\ v* ]]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- name: Enforce release automation actor policy
if: steps.skip.outputs.skip != 'true'
shell: bash
run: |
set -euo pipefail
actor="${GITHUB_ACTOR}"
actor_lc="$(echo "${actor}" | tr '[:upper:]' '[:lower:]')"
allowed_actors_lc="theonlyhennygod,jordanthejet"
if [[ ",${allowed_actors_lc}," != *",${actor_lc},"* ]]; then
echo "::error::Only maintainer actors (${allowed_actors_lc}) can trigger main release tagging. Actor: ${actor}"
exit 1
fi
- name: Resolve current and next version
if: steps.skip.outputs.skip != 'true'
id: version
shell: bash
run: |
set -euo pipefail
current_version="$(awk '
BEGIN { in_pkg=0 }
/^\[package\]/ { in_pkg=1; next }
in_pkg && /^\[/ { in_pkg=0 }
in_pkg && $1 == "version" {
value=$3
gsub(/"/, "", value)
print value
exit
}
' Cargo.toml)"
if [[ -z "${current_version}" ]]; then
echo "::error::Failed to resolve current package version from Cargo.toml"
exit 1
fi
if [[ ! "${current_version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::Cargo.toml version must be strict semver X.Y.Z (found: ${current_version})"
exit 1
fi
IFS='.' read -r major minor patch <<< "${current_version}"
next_patch="$((patch + 1))"
next_version="${major}.${minor}.${next_patch}"
{
echo "current=${current_version}"
echo "next=${next_version}"
echo "tag=v${current_version}"
} >> "$GITHUB_OUTPUT"
- name: Verify tag does not already exist
id: tag_check
if: steps.skip.outputs.skip != 'true'
shell: bash
run: |
set -euo pipefail
tag="${{ steps.version.outputs.tag }}"
if git ls-remote --exit-code --tags origin "refs/tags/${tag}" >/dev/null 2>&1; then
echo "::warning::Release tag ${tag} already exists on origin; skipping auto-tag/bump for this push."
echo "exists=true" >> "$GITHUB_OUTPUT"
else
echo "exists=false" >> "$GITHUB_OUTPUT"
fi
- name: Create and push annotated release tag
if: steps.skip.outputs.skip != 'true' && steps.tag_check.outputs.exists != 'true'
shell: bash
run: |
set -euo pipefail
tag="${{ steps.version.outputs.tag }}"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag -a "${tag}" -m "Release ${tag}"
git push origin "refs/tags/${tag}"
- name: Bump Cargo version for next release
if: steps.skip.outputs.skip != 'true' && steps.tag_check.outputs.exists != 'true'
shell: bash
run: |
set -euo pipefail
next="${{ steps.version.outputs.next }}"
awk -v new_version="${next}" '
BEGIN { in_pkg=0; done=0 }
/^\[package\]/ { in_pkg=1 }
in_pkg && /^\[/ && $0 !~ /^\[package\]/ { in_pkg=0 }
in_pkg && $1 == "version" && done == 0 {
sub(/"[^"]+"/, "\"" new_version "\"")
done=1
}
{ print }
' Cargo.toml > Cargo.toml.tmp
mv Cargo.toml.tmp Cargo.toml
awk -v new_version="${next}" '
BEGIN { in_pkg=0; zc_pkg=0; done=0 }
/^\[\[package\]\]/ { in_pkg=1; zc_pkg=0 }
in_pkg && /^name = "zeroclaw"$/ { zc_pkg=1 }
in_pkg && zc_pkg && /^version = "/ && done == 0 {
sub(/"[^"]+"/, "\"" new_version "\"")
done=1
}
{ print }
' Cargo.lock > Cargo.lock.tmp
mv Cargo.lock.tmp Cargo.lock
- name: Commit and push next-version prep
if: steps.skip.outputs.skip != 'true' && steps.tag_check.outputs.exists != 'true'
shell: bash
run: |
set -euo pipefail
next="${{ steps.version.outputs.next }}"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add Cargo.toml Cargo.lock
if git diff --cached --quiet; then
echo "No version changes detected; nothing to commit."
exit 0
fi
git commit -m "chore(release): prepare v${next} [skip ci]"
git push origin HEAD:main