cicd: bump the version before tagging so releases report their own version (#365)

*  cicd: bump the version before tagging instead of after

The version reported to the Crowdsec LAPI lives in version.go, so it must
be correct in the very commit the tag points at. Every mechanism so far
updated it *after* the tag existed, which cannot work:

- release.yml ran on `release: published` and force-moved the tag. It also
  failed on all four of its runs and was removed in #360.
- The Renovate customManager on version.go uses the github-tags datasource,
  so it can only propose vX once vX is already tagged. The bump always lands
  after the tag.

Result: v1.7.0 is tagged at a commit reading v1.6.0 (#363), same shape as
the earlier #322.

Replace both with a two-step flow that bumps first and tags last, so the
released source always matches its tag.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* 🍱 reduce loc + remove claude code comment

* 🍱 remove useless spellcheck disable

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: maxlerebourg <maxlerebourg@gmail.com>
This commit is contained in:
mathieuHa
2026-07-30 20:18:15 +02:00
committed by GitHub
co-authored by Claude Opus 5 maxlerebourg
parent ed4a9e8262
commit 99cf9712f4
4 changed files with 139 additions and 12 deletions
+83
View File
@@ -0,0 +1,83 @@
name: Release (1/2) Prepare
# Step 1 of the release process: bump pluginVersion *before* the tag exists.
#
# The version reported to the Crowdsec LAPI lives in version.go, so it has to
# be correct in the very commit the tag points at. Anything that patches
# version.go after the release is published is too late: Traefik's plugin
# service caches the plugin archive per module+version, so users keep the
# source that was there when the tag was first resolved (see #322, #363).
#
# This workflow opens a "release" PR containing only that bump. Merging it
# triggers Release (2/2) Publish, which creates the tag and the GitHub release
# on the merged commit.
on:
workflow_dispatch:
inputs:
version:
description: "Version to release, e.g. v1.7.1 or v1.8.0-alpha"
required: true
type: string
permissions:
contents: write
pull-requests: write
jobs:
prepare:
name: Open release PR for ${{ inputs.version }}
runs-on: ubuntu-latest
steps:
- name: Check out main
uses: actions/checkout@v7
with:
ref: main
fetch-depth: 0
- name: Validate version
env:
VERSION: ${{ inputs.version }}
run: |
if ! [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.]+)?$ ]]; then
echo "::error::'$VERSION' is not a vX.Y.Z / vX.Y.Z-suffix version"
exit 1
fi
if git rev-parse -q --verify "refs/tags/$VERSION" >/dev/null; then
echo "::error::tag $VERSION already exists"
exit 1
fi
- name: Bump version.go
env:
VERSION: ${{ inputs.version }}
run: |
sed -i 's/pluginVersion = "[^"]*"/pluginVersion = "'"$VERSION"'"/' version.go
cat version.go
if git diff --quiet -- version.go; then
echo "::error::version.go already reads $VERSION, nothing to release"
exit 1
fi
- name: Push release branch and open PR
env:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ inputs.version }}
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git switch -c "release/$VERSION"
git commit -am "🔖 release $VERSION"
git push -u origin "release/$VERSION"
cat > /tmp/pr-body.md <<EOF
Bumps \`pluginVersion\` to \`$VERSION\` so the tag carries the version
the plugin reports to the Crowdsec LAPI.
Merging this PR tags \`$VERSION\` on the resulting commit and publishes
the GitHub release automatically.
> Keep the PR title as-is: **Release (2/2) Publish** matches on it.
EOF
gh pr create --base main --head "release/$VERSION" --title "🔖 release $VERSION" --body-file /tmp/pr-body.md
+53
View File
@@ -0,0 +1,53 @@
name: Release (2/2) Publish
# Step 2 of the release process: tag and publish the commit prepared by
# Release (1/2) Prepare.
#
# Triggered by the release PR landing on main. The tag is created on that
# commit, so version.go inside the released source always matches the tag —
# no post-release patching, no force-moved tags.
on:
push:
branches: [main]
paths: ["version.go"]
permissions:
contents: write
jobs:
publish:
name: Tag and publish
runs-on: ubuntu-latest
steps:
- name: Check out the pushed commit
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Resolve release version
id: resolve
run: |
version="$(git log -1 --format='%B' | grep -oP '🔖 release \Kv[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.]+)?' || true)"
[ -z "$version" ] && { echo "version.go changed outside a release commit, nothing to do"; echo "release=false" >> "$GITHUB_OUTPUT"; exit 0; }
in_source="$(sed -n 's/.*pluginVersion = "\([^"]*\)".*/\1/p' version.go)"
[ "$in_source" != "$version" ] && { echo "::error::commit says $version but version.go reads $in_source"; exit 1; }
git rev-parse -q --verify "refs/tags/$version" >/dev/null && { echo "::error::tag $version already exists"; exit 1; }
echo "release=true" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "prerelease=$([[ "$version" == *-* ]] && echo '--prerelease')" >> "$GITHUB_OUTPUT"
- name: Tag and create the GitHub release
if: steps.resolve.outputs.release == 'true'
env:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ steps.resolve.outputs.version }}
PRERELEASE: ${{ steps.resolve.outputs.prerelease }}
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "$VERSION" -m "$VERSION"
git push origin "$VERSION"
gh release create "$VERSION" --title "$VERSION" --generate-notes $PRERELEASE