From 5198ab16d7959039b19e68691b461055e87df3eb Mon Sep 17 00:00:00 2001 From: schapron Date: Mon, 27 Jul 2026 17:15:55 +0200 Subject: [PATCH 01/13] feat(secu): gitleaks v5 custom --- .github/workflows/gitleaks-analysis.yml | 86 +++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 7 deletions(-) diff --git a/.github/workflows/gitleaks-analysis.yml b/.github/workflows/gitleaks-analysis.yml index f5f83de..b7cb34a 100644 --- a/.github/workflows/gitleaks-analysis.yml +++ b/.github/workflows/gitleaks-analysis.yml @@ -3,6 +3,10 @@ name: gitleaks on: workflow_call: +env: + # Pinned gitleaks release. + GITLEAKS_VERSION: "8.30.1" + jobs: secret-scan: name: Run Gitleaks @@ -14,11 +18,79 @@ jobs: with: fetch-depth: 0 + - name: Install Gitleaks + run: | + ASSET="gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" + BASE_URL="https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}" + + workdir="$(mktemp -d)" + cd "$workdir" + + curl -sSfL -o "${ASSET}" "${BASE_URL}/${ASSET}" + curl -sSfL -o checksums.txt "${BASE_URL}/gitleaks_${GITLEAKS_VERSION}_checksums.txt" + + # Verify integrity + grep " ${ASSET}\$" checksums.txt | sha256sum -c - + + mkdir -p "$HOME/.local/bin" + tar -xzf "${ASSET}" -C "$HOME/.local/bin" gitleaks + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + + "$HOME/.local/bin/gitleaks" version + - name: Run secret scan - uses: gitleaks/gitleaks-action@e0c47f4f8be36e29cdc102c57e68cb5cbf0e8d1e # v3.0.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GITLEAKS_LICENSE: "Centreon" - GITLEAKS_ENABLE_COMMENTS: false - GITLEAKS_ENABLE_UPLOAD_ARTIFACT: false - GITLEAKS_ENABLE_SUMMARY: false + run: | + # Build the commit range from the triggering event. + LOG_OPTS="" + case "${{ github.event_name }}" in + pull_request) + HEAD="${{ github.event.pull_request.head.sha }}" + BASE="$(git merge-base "${{ github.event.pull_request.base.sha }}" "${HEAD}")" + echo "Scanning PR range: ${BASE}..${HEAD}" + LOG_OPTS="--no-merges --first-parent ${BASE}..${HEAD}" + ;; + push) + BEFORE="${{ github.event.before }}" + AFTER="${{ github.event.after }}" + # New branch rewritten history: fall back to a full scan rather than a bad range. + if [ -z "${BEFORE}" ] \ + || [ "${BEFORE}" = "0000000000000000000000000000000000000000" ] \ + || ! git cat-file -e "${BEFORE}^{commit}" 2>/dev/null; then + echo "Push without a valid previous commit: scanning full history." + else + echo "Scanning push range: ${BEFORE}..${AFTER}" + LOG_OPTS="--no-merges ${BEFORE}..${AFTER}" + fi + ;; + *) + # workflow_dispatch: scan the full history. + echo "Event '${{ github.event_name }}': scanning full history." + ;; + esac + + # Execute analysis + EXIT_CODE=0 + if [ -n "${LOG_OPTS}" ]; then + gitleaks detect \ + --source . \ + --log-opts="${LOG_OPTS}" \ + --exit-code=2 \ + --redact \ + --verbose || EXIT_CODE=$? + else + gitleaks detect \ + --source . \ + --exit-code=2 \ + --redact \ + --verbose || EXIT_CODE=$? + fi + + if [ "${EXIT_CODE}" -eq 0 ]; then + echo "No secrets found." + elif [ "${EXIT_CODE}" -eq 2 ]; then + echo "::error::Gitleaks has detected secrets in this branch!" + exit 1 + else + echo "::warning::Gitleaks encountered a git error (exit code: ${EXIT_CODE}). Scan skipped for this run." + exit 0 + fi From f68701b3aa06cf043d8a9b94515bad35684f7a48 Mon Sep 17 00:00:00 2001 From: schapron Date: Tue, 28 Jul 2026 11:21:21 +0200 Subject: [PATCH 02/13] enh(secu): manage invalid-revision range error --- .github/workflows/gitleaks-analysis.yml | 115 ++++++++++++++++++------ 1 file changed, 86 insertions(+), 29 deletions(-) diff --git a/.github/workflows/gitleaks-analysis.yml b/.github/workflows/gitleaks-analysis.yml index b7cb34a..a1c7a73 100644 --- a/.github/workflows/gitleaks-analysis.yml +++ b/.github/workflows/gitleaks-analysis.yml @@ -3,6 +3,11 @@ name: gitleaks on: workflow_call: +# Cancel superseded PR scans; queue push/scheduled runs so a protected-branch scan is never dropped. +concurrency: + group: gitleaks-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + env: # Pinned gitleaks release. GITLEAKS_VERSION: "8.30.1" @@ -39,38 +44,90 @@ jobs: "$HOME/.local/bin/gitleaks" version - name: Run secret scan + env: + EVENT_NAME: ${{ github.event_name }} + PR_NUMBER: ${{ github.event.pull_request.number }} + PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} + PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} + PUSH_BEFORE: ${{ github.event.before }} + PUSH_AFTER: ${{ github.event.after }} run: | - # Build the commit range from the triggering event. + set -u + + # checkout pins the PR merge ref at trigger time, so a mid-run push can + # leave the head commit out of the clone. Resolve the range in a loop, + # re-fetching between attempts, and scan only once it is valid. LOG_OPTS="" - case "${{ github.event_name }}" in - pull_request) - HEAD="${{ github.event.pull_request.head.sha }}" - BASE="$(git merge-base "${{ github.event.pull_request.base.sha }}" "${HEAD}")" - echo "Scanning PR range: ${BASE}..${HEAD}" - LOG_OPTS="--no-merges --first-parent ${BASE}..${HEAD}" - ;; - push) - BEFORE="${{ github.event.before }}" - AFTER="${{ github.event.after }}" - # New branch rewritten history: fall back to a full scan rather than a bad range. - if [ -z "${BEFORE}" ] \ - || [ "${BEFORE}" = "0000000000000000000000000000000000000000" ] \ - || ! git cat-file -e "${BEFORE}^{commit}" 2>/dev/null; then - echo "Push without a valid previous commit: scanning full history." - else - echo "Scanning push range: ${BEFORE}..${AFTER}" - LOG_OPTS="--no-merges ${BEFORE}..${AFTER}" + HEAD_SHA="${PR_HEAD_SHA}" + + # Sets LOG_OPTS (empty => full scan); returns non-zero if the range is + # unresolvable. Validated with gitleaks' exact flags. + compute_range() { + case "${EVENT_NAME}" in + pull_request) + git cat-file -e "${HEAD_SHA}^{commit}" 2>/dev/null || return 1 + base="$(git merge-base "${PR_BASE_SHA}" "${HEAD_SHA}" 2>/dev/null)" || return 1 + LOG_OPTS="--no-merges --first-parent ${base}..${HEAD_SHA}" + ;; + push) + # New branch / rewritten history: full scan. + if [ -z "${PUSH_BEFORE}" ] \ + || [ "${PUSH_BEFORE}" = "0000000000000000000000000000000000000000" ] \ + || ! git cat-file -e "${PUSH_BEFORE}^{commit}" 2>/dev/null; then + LOG_OPTS="" + else + LOG_OPTS="--no-merges ${PUSH_BEFORE}..${PUSH_AFTER}" + fi + ;; + *) + # workflow_dispatch, etc: full scan. + LOG_OPTS="" + ;; + esac + + if [ -n "${LOG_OPTS}" ]; then + # shellcheck disable=SC2086 + git log ${LOG_OPTS} >/dev/null 2>&1 || return 1 + fi + return 0 + } + + # Fetch the refs the range needs (actions/checkout can't be re-run in a + # loop). Falls back to the live PR tip if the head SHA was force-pushed away. + refetch() { + if [ "${EVENT_NAME}" = "pull_request" ] && [ -n "${PR_NUMBER}" ]; then + git fetch --no-tags --force origin \ + "+refs/pull/${PR_NUMBER}/head:refs/remotes/origin/pr/${PR_NUMBER}" || true + if ! git cat-file -e "${HEAD_SHA}^{commit}" 2>/dev/null; then + HEAD_SHA="$(git rev-parse "refs/remotes/origin/pr/${PR_NUMBER}" 2>/dev/null || echo "${HEAD_SHA}")" fi - ;; - *) - # workflow_dispatch: scan the full history. - echo "Event '${{ github.event_name }}': scanning full history." - ;; - esac - - # Execute analysis + else + git fetch --no-tags --force origin "+refs/heads/*:refs/remotes/origin/*" || true + fi + } + + attempt=1 + max_attempts=3 + while : ; do + if compute_range; then + echo "Commit range resolved on attempt ${attempt}: ${LOG_OPTS:-}" + break + fi + + if [ "${attempt}" -ge "${max_attempts}" ]; then + echo "::error::Could not resolve a valid commit range after ${max_attempts} attempts." + echo "::error::The scan target is missing from the checkout (likely a force-push race); re-run this job." + exit 1 + fi + + echo "Commit range not resolvable yet; re-fetching refs (attempt ${attempt})." + refetch + attempt=$((attempt + 1)) + done + EXIT_CODE=0 if [ -n "${LOG_OPTS}" ]; then + # shellcheck disable=SC2086 gitleaks detect \ --source . \ --log-opts="${LOG_OPTS}" \ @@ -91,6 +148,6 @@ jobs: echo "::error::Gitleaks has detected secrets in this branch!" exit 1 else - echo "::warning::Gitleaks encountered a git error (exit code: ${EXIT_CODE}). Scan skipped for this run." - exit 0 + echo "::error::Gitleaks encountered an unexpected error (exit code: ${EXIT_CODE})." + exit 1 fi From 699bd1139a20b42b6adcde651c3d95b6ce0a5112 Mon Sep 17 00:00:00 2001 From: schapron Date: Tue, 28 Jul 2026 11:27:30 +0200 Subject: [PATCH 03/13] enh PR tpl --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1d3b0b0..88fb7e6 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,4 +2,4 @@ **What are your needs or what are you planning to do in this PR?** -> +> From 44080d760e4491df1f51a061d4bce2a4790426fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Chapron?= <34628915+sc979@users.noreply.github.com> Date: Tue, 28 Jul 2026 11:43:52 +0200 Subject: [PATCH 04/13] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com> Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com> --- .github/workflows/gitleaks-analysis.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/gitleaks-analysis.yml b/.github/workflows/gitleaks-analysis.yml index a1c7a73..966dcac 100644 --- a/.github/workflows/gitleaks-analysis.yml +++ b/.github/workflows/gitleaks-analysis.yml @@ -86,7 +86,6 @@ jobs: esac if [ -n "${LOG_OPTS}" ]; then - # shellcheck disable=SC2086 git log ${LOG_OPTS} >/dev/null 2>&1 || return 1 fi return 0 @@ -107,7 +106,7 @@ jobs: } attempt=1 - max_attempts=3 + max_attempts=5 while : ; do if compute_range; then echo "Commit range resolved on attempt ${attempt}: ${LOG_OPTS:-}" @@ -115,8 +114,8 @@ jobs: fi if [ "${attempt}" -ge "${max_attempts}" ]; then - echo "::error::Could not resolve a valid commit range after ${max_attempts} attempts." - echo "::error::The scan target is missing from the checkout (likely a force-push race); re-run this job." + echo "::error::Could not resolve a valid commit range after ${max_attempts} attempts. Skipping" + echo "::error::The scan target is missing from the checkout (likely a force-push race); re-run this job. Skipping" exit 1 fi @@ -149,5 +148,5 @@ jobs: exit 1 else echo "::error::Gitleaks encountered an unexpected error (exit code: ${EXIT_CODE})." - exit 1 + exit 0 fi From 83ce798d9dc04c4ecc773dd5a8b6727ca0a38b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Chapron?= <34628915+sc979@users.noreply.github.com> Date: Tue, 28 Jul 2026 13:41:55 +0200 Subject: [PATCH 05/13] Apply suggestion from @sc979 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com> --- .github/workflows/gitleaks-analysis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/gitleaks-analysis.yml b/.github/workflows/gitleaks-analysis.yml index 966dcac..6dbba5f 100644 --- a/.github/workflows/gitleaks-analysis.yml +++ b/.github/workflows/gitleaks-analysis.yml @@ -148,5 +148,6 @@ jobs: exit 1 else echo "::error::Gitleaks encountered an unexpected error (exit code: ${EXIT_CODE})." - exit 0 + # exit 0 + exit 1 fi From 1c2beaf4f3860f219d65ad80fcd205f84d4e05be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Chapron?= <34628915+sc979@users.noreply.github.com> Date: Wed, 29 Jul 2026 11:24:43 +0200 Subject: [PATCH 06/13] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com> Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com> --- .github/workflows/gitleaks-analysis.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/gitleaks-analysis.yml b/.github/workflows/gitleaks-analysis.yml index 6dbba5f..f4add46 100644 --- a/.github/workflows/gitleaks-analysis.yml +++ b/.github/workflows/gitleaks-analysis.yml @@ -3,7 +3,6 @@ name: gitleaks on: workflow_call: -# Cancel superseded PR scans; queue push/scheduled runs so a protected-branch scan is never dropped. concurrency: group: gitleaks-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} @@ -55,7 +54,7 @@ jobs: set -u # checkout pins the PR merge ref at trigger time, so a mid-run push can - # leave the head commit out of the clone. Resolve the range in a loop, + # leave the head commit out of the clone. Resolving the range in a loop, # re-fetching between attempts, and scan only once it is valid. LOG_OPTS="" HEAD_SHA="${PR_HEAD_SHA}" @@ -109,7 +108,7 @@ jobs: max_attempts=5 while : ; do if compute_range; then - echo "Commit range resolved on attempt ${attempt}: ${LOG_OPTS:-}" + echo "::warning::Commit range resolved on attempt ${attempt}: ${LOG_OPTS:-}" break fi @@ -126,7 +125,6 @@ jobs: EXIT_CODE=0 if [ -n "${LOG_OPTS}" ]; then - # shellcheck disable=SC2086 gitleaks detect \ --source . \ --log-opts="${LOG_OPTS}" \ @@ -148,6 +146,5 @@ jobs: exit 1 else echo "::error::Gitleaks encountered an unexpected error (exit code: ${EXIT_CODE})." - # exit 0 - exit 1 + exit 0 fi From 2ffcf123f3a2db46f5d023d71cd93784d403a430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Chapron?= <34628915+sc979@users.noreply.github.com> Date: Wed, 29 Jul 2026 11:27:14 +0200 Subject: [PATCH 07/13] Apply suggestion from @sc979 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com> --- .github/workflows/gitleaks-analysis.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/gitleaks-analysis.yml b/.github/workflows/gitleaks-analysis.yml index f4add46..3f16f7d 100644 --- a/.github/workflows/gitleaks-analysis.yml +++ b/.github/workflows/gitleaks-analysis.yml @@ -1,11 +1,12 @@ name: gitleaks -on: - workflow_call: - concurrency: group: gitleaks-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} + cancel-in-progress: true + +on: +workflow_call: + env: # Pinned gitleaks release. From 980cfe234de7d3fff372b63e38330f4e6ef652f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Chapron?= <34628915+sc979@users.noreply.github.com> Date: Wed, 29 Jul 2026 11:27:29 +0200 Subject: [PATCH 08/13] Apply suggestion from @sc979 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com> --- .github/workflows/gitleaks-analysis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/gitleaks-analysis.yml b/.github/workflows/gitleaks-analysis.yml index 3f16f7d..f6a95b6 100644 --- a/.github/workflows/gitleaks-analysis.yml +++ b/.github/workflows/gitleaks-analysis.yml @@ -7,7 +7,6 @@ concurrency: on: workflow_call: - env: # Pinned gitleaks release. GITLEAKS_VERSION: "8.30.1" From 986cc4ac418acf86df6bce93a263d2ed3c1a92f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Chapron?= <34628915+sc979@users.noreply.github.com> Date: Wed, 29 Jul 2026 11:28:13 +0200 Subject: [PATCH 09/13] Apply suggestion from @sc979 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com> --- .github/workflows/gitleaks-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gitleaks-analysis.yml b/.github/workflows/gitleaks-analysis.yml index f6a95b6..dde2da9 100644 --- a/.github/workflows/gitleaks-analysis.yml +++ b/.github/workflows/gitleaks-analysis.yml @@ -1,7 +1,7 @@ name: gitleaks concurrency: - group: gitleaks-${{ github.event.pull_request.number || github.ref }} + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true on: From d431396e42651612e78def9d79a336045d2d3c1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Chapron?= <34628915+sc979@users.noreply.github.com> Date: Wed, 29 Jul 2026 12:03:34 +0200 Subject: [PATCH 10/13] Apply suggestion from @sc979 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com> --- .github/workflows/gitleaks-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gitleaks-analysis.yml b/.github/workflows/gitleaks-analysis.yml index dde2da9..cd21a9a 100644 --- a/.github/workflows/gitleaks-analysis.yml +++ b/.github/workflows/gitleaks-analysis.yml @@ -5,7 +5,7 @@ concurrency: cancel-in-progress: true on: -workflow_call: + workflow_call: env: # Pinned gitleaks release. From d9cd493e8dabbb7c561f89f9009ce8fe7a1950a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Chapron?= <34628915+sc979@users.noreply.github.com> Date: Wed, 29 Jul 2026 12:07:32 +0200 Subject: [PATCH 11/13] remove concurrency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit already managed by the triggering pipeline. causing failing loop Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com> --- .github/workflows/gitleaks-analysis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/gitleaks-analysis.yml b/.github/workflows/gitleaks-analysis.yml index cd21a9a..a952de1 100644 --- a/.github/workflows/gitleaks-analysis.yml +++ b/.github/workflows/gitleaks-analysis.yml @@ -1,9 +1,5 @@ name: gitleaks -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - on: workflow_call: From 0f586a98e73334d6854c37f9895d2757037a8075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Chapron?= <34628915+sc979@users.noreply.github.com> Date: Wed, 29 Jul 2026 12:11:15 +0200 Subject: [PATCH 12/13] Update gitleaks-analysis.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com> --- .github/workflows/gitleaks-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gitleaks-analysis.yml b/.github/workflows/gitleaks-analysis.yml index a952de1..6305c7f 100644 --- a/.github/workflows/gitleaks-analysis.yml +++ b/.github/workflows/gitleaks-analysis.yml @@ -104,7 +104,7 @@ jobs: max_attempts=5 while : ; do if compute_range; then - echo "::warning::Commit range resolved on attempt ${attempt}: ${LOG_OPTS:-}" + echo "::info::Commit range resolved on attempt ${attempt}: ${LOG_OPTS:-}" break fi From 6896e16eb6e3927ae088cbd1250f9a8640fa18c1 Mon Sep 17 00:00:00 2001 From: schapron Date: Wed, 29 Jul 2026 16:05:16 +0200 Subject: [PATCH 13/13] ci(secu): limit new-branch scan to its own commits On a push that creates a new branch (or rewrites history), the gitleaks range fell back to a full-history scan. Because a branch usually forks off the default branch, that re-scanned commits already living in the default branch and re-reported pre-existing secrets that the branch never introduced. Resolve the range against the default branch instead: scan only merge-base(origin/, after)..after, i.e. the commits unique to the branch. The empty-"before" case now follows the same path, so it is consistent with a real new branch. When the default branch cannot be resolved, fall back to a full scan (over-scan is the safe direction). Also correct the range-resolved log to ::notice:: (::info:: is not a valid workflow command). Assisted-by: Claude Code (claude-opus-4-8) --- .github/workflows/gitleaks-analysis.yml | 28 ++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/.github/workflows/gitleaks-analysis.yml b/.github/workflows/gitleaks-analysis.yml index 6305c7f..ed349ae 100644 --- a/.github/workflows/gitleaks-analysis.yml +++ b/.github/workflows/gitleaks-analysis.yml @@ -46,6 +46,7 @@ jobs: PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} PUSH_BEFORE: ${{ github.event.before }} PUSH_AFTER: ${{ github.event.after }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} run: | set -u @@ -65,13 +66,26 @@ jobs: LOG_OPTS="--no-merges --first-parent ${base}..${HEAD_SHA}" ;; push) - # New branch / rewritten history: full scan. - if [ -z "${PUSH_BEFORE}" ] \ - || [ "${PUSH_BEFORE}" = "0000000000000000000000000000000000000000" ] \ - || ! git cat-file -e "${PUSH_BEFORE}^{commit}" 2>/dev/null; then - LOG_OPTS="" - else + if [ -n "${PUSH_BEFORE}" ] \ + && [ "${PUSH_BEFORE}" != "0000000000000000000000000000000000000000" ] \ + && git cat-file -e "${PUSH_BEFORE}^{commit}" 2>/dev/null; then + # Existing branch: scan exactly the commits this push added. LOG_OPTS="--no-merges ${PUSH_BEFORE}..${PUSH_AFTER}" + elif base="$(git merge-base "refs/remotes/origin/${DEFAULT_BRANCH}" "${PUSH_AFTER}" 2>/dev/null)" \ + && [ -n "${base}" ]; then + # New branch (before is the zero SHA or empty) or rewritten + # history: scan only the commits unique to this branch, i.e. + # since it diverged from the default branch. The shared base + # history is already covered by the default branch's own scans, + # so a full scan there would just re-report pre-existing, + # unrelated findings. (fetch-depth: 0 makes origin/ + # available in the clone.) + LOG_OPTS="--no-merges ${base}..${PUSH_AFTER}" + else + # Default branch not resolvable (unrelated history, or the ref + # is missing): fall back to a full scan rather than risk + # missing anything. Over-scan is the safe direction. + LOG_OPTS="" fi ;; *) @@ -104,7 +118,7 @@ jobs: max_attempts=5 while : ; do if compute_range; then - echo "::info::Commit range resolved on attempt ${attempt}: ${LOG_OPTS:-}" + echo "::notice::Commit range resolved on attempt ${attempt}: ${LOG_OPTS:-}" break fi