This is an automated email from the ASF dual-hosted git repository.
hello-stephen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new d9f83731673 [improvement](workflow) Fence PR checks by SHA and reject
stale starts (#67119)
d9f83731673 is described below
commit d9f837316734a0905064c02ff99d1aaab14e1786
Author: Dongyang Li <[email protected]>
AuthorDate: Wed Sep 16 16:42:26 2026 +0800
[improvement](workflow) Fence PR checks by SHA and reject stale starts
(#67119)
### What problem does this PR solve?
Issue Number: N/A
Related PR: N/A
Problem Summary:
Four frequent PR workflows originally used only the PR number as a job
concurrency key. GitHub does not guarantee that jobs enter a concurrency
group in the same order as PR events. A delayed old event or a manual
rerun of an old validation could therefore cancel the newer check.
This PR changes FE Code Style Checker, Code Formatter, Gitleaks PR
Check, and License Check to:
- isolate cancellation by workflow, PR number, and the immutable GitHub
validation SHA;
- read the current PR head SHA through the Pulls API as the first step,
before checkout or other costly work;
- fail an obsolete event explicitly if its recorded head SHA no longer
matches the current PR head.
Checkstyle and Gitleaks receive read-only Pull requests permission for
this check. License Check runs on master push remain independent and do
not perform the PR preflight. Code Review Runner is intentionally
outside this PR because its cancellation path also controls review
status, comments, and session state.
Repeated events or reruns for the same validation SHA still coalesce.
Different validation SHAs no longer cancel each other, so this is not
cross-SHA latest-only: an old job already running can finish, while an
old job that starts after the PR has advanced fails before checkout. The
one-time preflight does not guarantee that a PR stays current throughout
a long-running job.
#### Historical usage data and expected effect
The August 20, 21, and 24 sample contained 1,727 jobs across these four
workflows. Forty old jobs overlapped later same-PR events, representing
about 61.5 runner minutes under a PR-only cancellation estimate. That
figure is an upper bound for the earlier design, not a saving claimed
for this SHA-isolated design. The new design prevents reverse-order
cancellation and avoids the substantive work of stale jobs that start
after a PR update; it still consumes runner startup and the preflight
call.
### Release note
None
### Check List (For Author)
- Test: Manual test. Ran actionlint on the four workflows with only the
pre-existing Checkstyle checkout v3 warning excluded, checked the scoped
diff, and read back the PR head through the same Pulls API endpoint. The
new SHA checks were queued at the time of this edit; remote terminal
validation is not yet claimed.
- Behavior changed: Yes. Cancellation is scoped to the same PR and
validation SHA, and stale starts fail before checkout.
- Does this need documentation: No
### Check List (For Reviewer who merge this PR)
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label
---
.github/workflows/checkstyle.yaml | 20 +++++++++++++++++++-
.github/workflows/clang-format.yml | 15 +++++++++++++++
.github/workflows/gitleaks-pr-check.yml | 16 ++++++++++++++++
.github/workflows/license-eyes.yml | 16 ++++++++++++++++
4 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/checkstyle.yaml
b/.github/workflows/checkstyle.yaml
index 74fa4156ca8..f4de13ea899 100644
--- a/.github/workflows/checkstyle.yaml
+++ b/.github/workflows/checkstyle.yaml
@@ -22,12 +22,31 @@ on:
pull_request:
workflow_dispatch:
+permissions:
+ contents: read
+ pull-requests: read
+
jobs:
java-checkstyle:
name: "CheckStyle"
runs-on: ubuntu-latest
+ concurrency:
+ group: fe-code-style-${{ github.event.pull_request.number ||
github.run_id }}-${{ github.sha }}
+ cancel-in-progress: true
if: github.event_name == 'pull_request'
steps:
+ - name: Verify current PR head
+ env:
+ GH_TOKEN: ${{ github.token }}
+ PR_NUMBER: ${{ github.event.pull_request.number }}
+ EXPECTED_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
+ run: |
+ current_head_sha=$(gh api
"repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}" --jq '.head.sha')
+ if [[ "${current_head_sha}" != "${EXPECTED_HEAD_SHA}" ]]; then
+ echo "::error::PR #${PR_NUMBER} moved from ${EXPECTED_HEAD_SHA} to
${current_head_sha}; refusing stale validation"
+ exit 1
+ fi
+
- name: Checkout
uses: actions/checkout@v3
with:
@@ -56,4 +75,3 @@ jobs:
if: steps.filter.outputs.fe_changes == 'true'
run:
cd fe && mvn clean checkstyle:check
-
diff --git a/.github/workflows/clang-format.yml
b/.github/workflows/clang-format.yml
index 7d73013a337..ca2ec189c13 100644
--- a/.github/workflows/clang-format.yml
+++ b/.github/workflows/clang-format.yml
@@ -31,8 +31,23 @@ jobs:
clang-format:
name: "Clang Formatter"
runs-on: ubuntu-latest
+ concurrency:
+ group: code-formatter-${{ github.event.pull_request.number ||
github.run_id }}-${{ github.sha }}
+ cancel-in-progress: true
if: github.event_name == 'pull_request'
steps:
+ - name: Verify current PR head
+ env:
+ GH_TOKEN: ${{ github.token }}
+ PR_NUMBER: ${{ github.event.pull_request.number }}
+ EXPECTED_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
+ run: |
+ current_head_sha=$(gh api
"repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}" --jq '.head.sha')
+ if [[ "${current_head_sha}" != "${EXPECTED_HEAD_SHA}" ]]; then
+ echo "::error::PR #${PR_NUMBER} moved from ${EXPECTED_HEAD_SHA} to
${current_head_sha}; refusing stale validation"
+ exit 1
+ fi
+
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v7
with:
diff --git a/.github/workflows/gitleaks-pr-check.yml
b/.github/workflows/gitleaks-pr-check.yml
index 9ac7991a957..2436429e7c5 100644
--- a/.github/workflows/gitleaks-pr-check.yml
+++ b/.github/workflows/gitleaks-pr-check.yml
@@ -23,15 +23,31 @@ on:
permissions:
contents: read
+ pull-requests: read
jobs:
gitleaks:
name: Check for secrets
runs-on: ubuntu-latest
+ concurrency:
+ group: gitleaks-${{ github.event.pull_request.number || github.run_id
}}-${{ github.sha }}
+ cancel-in-progress: true
env:
GITLEAKS_VERSION: 8.30.0
GITLEAKS_SHA256:
79a3ab579b53f71efd634f3aaf7e04a0fa0cf206b7ed434638d1547a2470a66e
steps:
+ - name: Verify current PR head
+ env:
+ GH_TOKEN: ${{ github.token }}
+ PR_NUMBER: ${{ github.event.pull_request.number }}
+ EXPECTED_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
+ run: |
+ current_head_sha=$(gh api
"repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}" --jq '.head.sha')
+ if [[ "${current_head_sha}" != "${EXPECTED_HEAD_SHA}" ]]; then
+ echo "::error::PR #${PR_NUMBER} moved from ${EXPECTED_HEAD_SHA} to
${current_head_sha}; refusing stale validation"
+ exit 1
+ fi
+
- name: Checkout
uses: actions/checkout@v4
with:
diff --git a/.github/workflows/license-eyes.yml
b/.github/workflows/license-eyes.yml
index 1e4cf021657..5d11cf04e82 100644
--- a/.github/workflows/license-eyes.yml
+++ b/.github/workflows/license-eyes.yml
@@ -32,10 +32,26 @@ jobs:
license-check:
name: "License Check"
runs-on: ubuntu-latest
+ concurrency:
+ group: license-check-${{ github.event.pull_request.number ||
github.run_id }}-${{ github.sha }}
+ cancel-in-progress: true
if: |
(github.event_name == 'pull_request') ||
(github.event_name == 'push' && github.ref == 'refs/heads/master')
steps:
+ - name: Verify current PR head
+ if: github.event_name == 'pull_request'
+ env:
+ GH_TOKEN: ${{ github.token }}
+ PR_NUMBER: ${{ github.event.pull_request.number }}
+ EXPECTED_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
+ run: |
+ current_head_sha=$(gh api
"repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}" --jq '.head.sha')
+ if [[ "${current_head_sha}" != "${EXPECTED_HEAD_SHA}" ]]; then
+ echo "::error::PR #${PR_NUMBER} moved from ${EXPECTED_HEAD_SHA} to
${current_head_sha}; refusing stale validation"
+ exit 1
+ fi
+
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v7
with:
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]