From 65830ae53384b41bb50426f282d006f0ee8a7ed5 Mon Sep 17 00:00:00 2001 From: Jose Armesto Date: Wed, 3 Jun 2026 15:35:27 +0200 Subject: [PATCH] perf: consolidate git-cliff invocations behind a single install MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces two `orhun/git-cliff-action` invocations (one for --bumped-version, one for --latest --strip all) with: 1. One install step via giantswarm/install-binary-action 2. One shell step that runs git-cliff twice: --bump --context to emit the JSON context (one set of GitHub API calls for PR lookups), then --from-context to render the body from that cached JSON (no API calls, no commit walk — ~40ms locally). Savings per workflow run: avoids re-installing git-cliff (~1s × 2) and re-doing the API PR-lookup pass (~3s × 2). Net ~5–8s shaved off a ~15-second run. Side benefits: - `steps.cliff.outputs.version` is now read straight from the JSON via `jq -r '.[0].version'`, which is what the older git-cliff-action's `version` output was trying (and silently failing) to do for --bumped-version. Removes the trim-content workaround we had to do in the decide step. - Renders the body upfront (cheap) rather than only after the tag push. Result is identical because --bump uses the bumped version; the cached context already reflects what `--latest` would have seen post-push. Local validation: $ git-cliff --bump --context > ctx.json $ jq -r '.[0].version' ctx.json v1.5.0 $ time git-cliff --from-context ctx.json --strip all ... (rendered body) ... git-cliff --from-context 0.01s user 0.02s system 96% cpu 0.038 total --- .github/workflows/auto-release.yaml | 57 +++++++++++++++-------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/.github/workflows/auto-release.yaml b/.github/workflows/auto-release.yaml index badebb7..3e400c4 100644 --- a/.github/workflows/auto-release.yaml +++ b/.github/workflows/auto-release.yaml @@ -49,28 +49,43 @@ jobs: fetch-depth: 0 # full history so git-cliff sees every commit fetch-tags: true # ensure tags are present (shallow runners drop them by default) - - name: Compute next version with git-cliff - id: cliff - uses: orhun/git-cliff-action@f50e11560dce63f7c33227798f90b924471a88b5 # v4.8.0 + # Install git-cliff once and call it from shell so we can do all the + # expensive work (commits walk + GitHub API PR lookups) in a single + # invocation, then cheaply re-render from the cached JSON context. + # Replaces two separate orhun/git-cliff-action invocations that each + # re-installed git-cliff and re-paid the API-lookup cost. + - name: Install git-cliff + uses: giantswarm/install-binary-action@5bef88f65012037dd836117c8d344b21bb559854 # v4.1.0 with: - config: cliff.toml - args: --bumped-version + binary: git-cliff + version: "2.13.1" + download_url: 'https://github.com/orhun/git-cliff/releases/download/v${version}/git-cliff-${version}-x86_64-unknown-linux-gnu.tar.gz' + tarball_binary_path: 'git-cliff-${version}/git-cliff' + smoke_test: '${binary} --version' + + - name: Compute next version and render release notes + id: cliff + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + # Single expensive call: walks commits, queries the GitHub API for + # per-commit PR lookups, emits the full JSON context. + git-cliff --bump --context > cliff-context.json + NEXT=$(jq -r '.[0].version' cliff-context.json) + echo "next computed: ${NEXT:-}" + echo "version=${NEXT}" >> "$GITHUB_OUTPUT" + # Cheap render from the cached context — no API calls, no git walk. + # `--strip all` drops header/footer; body-only is what gh release + # create --notes-file expects. + git-cliff --from-context cliff-context.json --strip all --output release-notes.md - name: Decide whether to tag id: decide env: - # The git-cliff-action's `version` output is unreliable for - # `--bumped-version`: it parses from a `--context` JSON dump and that - # dump doesn't populate the way jq expects for that mode, so the - # output ends up empty. The action's `content` output, on the other - # hand, captures what git-cliff writes to its output destination - # (via the GIT_CLIFF_OUTPUT env var the action sets), which for - # `--bumped-version` is just the version string. Trim trailing - # whitespace / newline. - NEXT_RAW: ${{ steps.cliff.outputs.content }} + NEXT: ${{ steps.cliff.outputs.version }} run: | set -euo pipefail - NEXT=$(echo "$NEXT_RAW" | tr -d '[:space:]') # `git describe --tags --abbrev=0` returns the closest tag reachable # from HEAD — NOT the highest tag in the repo overall. This matters # for backports: on release-2.x, HEAD's reachable history terminates @@ -80,7 +95,6 @@ jobs: last=$(git describe --tags --abbrev=0 --match='v*.*.*' 2>/dev/null || echo "") echo "branch: ${GITHUB_REF_NAME}" echo "last reachable tag: ${last:-}" - echo "next computed: ${NEXT:-}" if [ -z "${NEXT}" ] || [ "${NEXT}" = "${last}" ]; then echo "No releasable commits since ${last:-inception}; skipping tag." echo "tag=" >> "$GITHUB_OUTPUT" @@ -104,17 +118,6 @@ jobs: git tag -a "$TAG" -m "Release $TAG" git push origin "$TAG" - # Re-run cliff after the tag exists locally so `--latest` resolves to - # the just-created version. Renders only the body (commit groups) — no - # header/footer noise — into a file goreleaser-style `gh release create - # --notes-file` can consume directly without quoting headaches. - - name: Render release notes - if: steps.decide.outputs.tag != '' - uses: orhun/git-cliff-action@f50e11560dce63f7c33227798f90b924471a88b5 # v4.8.0 - with: - config: cliff.toml - args: --latest --strip all --output release-notes.md - - name: Create GitHub Release if: steps.decide.outputs.tag != '' env: