From fded3a04d4155ed81175dc41e2fa0ce0138ca5fc Mon Sep 17 00:00:00 2001 From: keligrubb Date: Wed, 15 Apr 2026 03:03:04 +0000 Subject: [PATCH] ci: split push release/publish and harden workflows (#27) ### Added * Separate release from Docker/Helm publish * enrich releases with PRbodies when available * tighten release.sh validation and idempotency * trim PR docker-build metadata for act-runner stability Reviewed-on: https://git.keligrubb.com/keligrubb/kestrelos/pulls/27 Co-authored-by: keligrubb Co-committed-by: keligrubb --- .gitea/workflows/pr.yml | 7 +++++++ .gitea/workflows/push.yml | 35 +++++++++++++++++++++++++++++++---- scripts/release.sh | 11 +++++++++-- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index e4fc2e0..56ecfaa 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -79,7 +79,14 @@ jobs: - name: Build (dry run) uses: https://git.keligrubb.com/actions/docker-build-push-action@v7 + env: + # Keeps GITHUB_OUTPUT small; Gitea act-runner can choke on multiline + # outputs when PR webhook payloads (e.g. Renovate bodies) are huge. + DOCKER_BUILD_SUMMARY: "false" + DOCKER_BUILD_RECORD_UPLOAD: "false" with: context: . push: false + provenance: false + sbom: false tags: ${{ steps.image.outputs.tag }} diff --git a/.gitea/workflows/push.yml b/.gitea/workflows/push.yml index a5e676d..bac4a21 100644 --- a/.gitea/workflows/push.yml +++ b/.gitea/workflows/push.yml @@ -5,13 +5,25 @@ on: branches: [main] jobs: - release-docker-helm: + release: runs-on: ubuntu-latest steps: - uses: https://git.keligrubb.com/actions/checkout@v6 with: token: ${{ secrets.KESTRELOS_REPO_TOKEN }} + - name: Get PR description for changelog + env: + GITEA_REPO_TOKEN: ${{ secrets.KESTRELOS_REPO_TOKEN }} + run: | + sudo rm -f /etc/apt/sources.list.d/microsoft*.list /etc/apt/sources.list.d/azure*.list 2>/dev/null || true + sudo apt-get update -qq && sudo apt-get install -y -qq jq + RESP=$(curl -sf -H "Authorization: token $GITEA_REPO_TOKEN" \ + "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/commits/${{ github.sha }}/pull") || true + if [ -n "$RESP" ]; then + echo "$RESP" | jq -r '.body // empty' > .ci_pr_body 2>/dev/null || true + fi + - name: Release (bump, tag, push, create release) env: CI_REPO_OWNER: ${{ github.actor }} @@ -20,9 +32,19 @@ jobs: CI_COMMIT_MESSAGE: ${{ github.event.head_commit.message }} GITEA_REPO_TOKEN: ${{ secrets.KESTRELOS_REPO_TOKEN }} run: | + sudo rm -f /etc/apt/sources.list.d/microsoft*.list /etc/apt/sources.list.d/azure*.list 2>/dev/null || true sudo apt-get update -qq && sudo apt-get install -y -qq git wget ./scripts/release.sh + publish: + needs: release + runs-on: ubuntu-latest + steps: + - uses: https://git.keligrubb.com/actions/checkout@v6 + with: + ref: main + token: ${{ secrets.KESTRELOS_REPO_TOKEN }} + - name: Log in to container registry uses: https://git.keligrubb.com/actions/docker-login-action@v4 with: @@ -40,14 +62,19 @@ jobs: load: true tags: kestrelos:built - - name: Push Docker image (all tags from .tags) + - name: Push Docker image (version + latest) run: | + VERSION=$(awk '/"version"/ { match($0, /[0-9]+\.[0-9]+\.[0-9]+/); print substr($0, RSTART, RLENGTH); exit }' package.json) + case "$VERSION" in + [0-9]*.[0-9]*.[0-9]*) ;; + *) echo "error: package.json version must be x.y.z (got: $VERSION)"; exit 1 ;; + esac REGISTRY="git.keligrubb.com" IMAGE="$REGISTRY/${{ github.repository }}" - while read -r tag; do + for tag in "$VERSION" latest; do docker tag kestrelos:built "$IMAGE:$tag" docker push "$IMAGE:$tag" - done < .tags + done - name: Set up Helm uses: https://git.keligrubb.com/actions/setup-helm@v5 diff --git a/scripts/release.sh b/scripts/release.sh index b5c682d..27045b2 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -20,10 +20,18 @@ echo "$msg" | grep -Eqi '(^|[[:space:]])[a-zA-Z]+(\([^)]*\))?!:' && bump=major echo "$msg" | grep -qi minor: && [ "$bump" != "major" ] && bump=minor echo "$msg" | grep -qi major: && bump=major cur=$(awk '/"version"/ { match($0, /[0-9]+\.[0-9]+\.[0-9]+/); print substr($0, RSTART, RLENGTH); exit }' package.json) +case "$cur" in + [0-9]*.[0-9]*.[0-9]*) ;; + *) echo "error: package.json version must be x.y.z (got: $cur)"; exit 1 ;; +esac major=$(echo "$cur" | cut -d. -f1); minor=$(echo "$cur" | cut -d. -f2); patch=$(echo "$cur" | cut -d. -f3) case "$bump" in major) major=$((major+1)); minor=0; patch=0 ;; minor) minor=$((minor+1)); patch=0 ;; patch) patch=$((patch+1)) ;; esac newVersion="$major.$minor.$patch" -[ -z "$cur" ] && { echo "error: could not read version from package.json"; exit 1; } + +url="https://${CI_REPO_OWNER}:${GITEA_REPO_TOKEN}@${CI_FORGE_URL#https://}/${CI_REPO_OWNER}/${CI_REPO_NAME}.git" +if [ -n "$(git ls-remote "$url" "refs/tags/v$newVersion" 2>/dev/null)" ]; then + exit 0 +fi # changelog entry (strip explicit bump prefixes & any conventional-commit type(scope):); optional PR description enriches it changelogEntry=$( @@ -59,7 +67,6 @@ $changelogFull git config user.email "ci@kestrelos" && git config user.name "CI" git add package.json helm/kestrelos/Chart.yaml helm/kestrelos/values.yaml CHANGELOG.md git commit -m "release v$newVersion [skip ci]" -url="https://${CI_REPO_OWNER}:${GITEA_REPO_TOKEN}@${CI_FORGE_URL#https://}/${CI_REPO_OWNER}/${CI_REPO_NAME}.git" git tag "v$newVersion" # artifact for docker (tag list) printf '%s\n%s\n' "$newVersion" "latest" > .tags