From b30629411a2e9b0fa306f1e489af13a6d4aa0b5d Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Sivakumar Date: Wed, 12 Aug 2026 22:18:37 +0530 Subject: [PATCH] fix(ci): diff/scan full pushed commit range, not just HEAD^..HEAD Multi-commit pushes (e.g. this repo's mirror sync from GitHub) were silently skipping every service's build: the 'does this service need building' check only looked at the last commit vs its immediate parent. A push landing 3 commits where only the final one was a no-op (docs/.gitignore) meant the actual code commit's changes were never seen, so all 19 services reported 'no changes relevant - skipping' even though real backend code had changed. Use github.event.before (the pre-push SHA) to diff/scan the whole pushed range when available, falling back to HEAD^..HEAD only when that ref is unavailable. Co-Authored-By: Claude Sonnet 5 --- .forgejo/workflows/build.yaml | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 81500a2..4156cb6 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -57,15 +57,35 @@ jobs: service="${{ matrix.service }}" svc_dir="$(echo "$service" | tr '-' '_')" - if git rev-parse --verify HEAD^ >/dev/null 2>&1; then - CHANGED_FILES="$(git diff --name-only HEAD^ HEAD)" + # A push can carry more than one commit (e.g. a fast-forward + # merge or a mirror sync). Diffing only HEAD^..HEAD silently + # ignores every commit before the last one in the push, so a + # multi-commit push whose final commit is a no-op (docs, + # .gitignore, ...) skips rebuilding services even though an + # earlier commit in the same push touched their code. Prefer + # the pre-push SHA the trigger event actually gives us and + # diff/scan the whole pushed range; only fall back to + # HEAD^..HEAD when that's unavailable (e.g. manual re-run). + BEFORE_SHA="${{ github.event.before }}" + if [ -n "$BEFORE_SHA" ] && [ "$BEFORE_SHA" != "0000000000000000000000000000000000000000" ] \ + && git rev-parse --verify "${BEFORE_SHA}^{commit}" >/dev/null 2>&1; then + RANGE="${BEFORE_SHA}..HEAD" + elif git rev-parse --verify HEAD^ >/dev/null 2>&1; then + RANGE="HEAD^..HEAD" + else + RANGE="" + fi + + if [ -n "$RANGE" ]; then + CHANGED_FILES="$(git diff --name-only $RANGE)" + COMMIT_MSGS="$(git log --pretty=%B $RANGE | tr '\n' ' ')" else CHANGED_FILES="$(git ls-files)" + COMMIT_MSGS="$(git log -1 --pretty=%B | tr '\n' ' ')" fi - LAST_COMMIT_MSG="$(git log -1 --pretty=%B | tr '\n' ' ')" build=false - if echo "$LAST_COMMIT_MSG" | grep -Eiq 'trigger build|force build|rebuild all'; then + if echo "$COMMIT_MSGS" | grep -Eiq 'trigger build|force build|rebuild all'; then build=true elif echo "$CHANGED_FILES" | grep -Eq '^(\.forgejo/workflows/|Dockerfile|Cargo\.toml|Cargo\.lock|crates/|scripts/)'; then build=true