Skip to content

Commit 35b6c96

Browse files
committed
Avoid duplicate CI runs for PR branches
Signed-off-by: lucarlig <luca.carlig@ibm.com>
1 parent aca2088 commit 35b6c96

2 files changed

Lines changed: 51 additions & 2 deletions

File tree

.github/workflows/ci-rust-python-package.yaml

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,55 @@ on:
2121
- ".github/workflows/ci-rust-python-package.yaml"
2222
- ".github/workflows/release-rust-python-package.yaml"
2323

24+
concurrency:
25+
group: ci-rust-python-package-${{ github.event.pull_request.head.repo.full_name || github.repository }}-${{ github.head_ref || github.ref_name }}
26+
cancel-in-progress: true
27+
2428
permissions:
2529
contents: read
30+
pull-requests: read
2631

2732
jobs:
33+
dedupe:
34+
runs-on: ubuntu-latest
35+
outputs:
36+
should_run: ${{ steps.decide.outputs.should_run }}
37+
steps:
38+
- id: decide
39+
shell: bash
40+
env:
41+
EVENT_NAME: ${{ github.event_name }}
42+
REF_NAME: ${{ github.ref_name }}
43+
REF_TYPE: ${{ github.ref_type }}
44+
REPOSITORY: ${{ github.repository }}
45+
GITHUB_TOKEN: ${{ github.token }}
46+
run: |
47+
set -euo pipefail
48+
should_run=true
49+
50+
if [[ "${EVENT_NAME}" == "push" && "${REF_TYPE}" == "branch" ]]; then
51+
head="${REPOSITORY%%/*}:${REF_NAME}"
52+
prs_json=$(curl -fsSL \
53+
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
54+
-H "Accept: application/vnd.github+json" \
55+
"https://api.github.com/repos/${REPOSITORY}/pulls?state=open&head=${head}")
56+
open_pr_count=$(JSON_INPUT="$prs_json" python3 - <<'PY'
57+
import json
58+
import os
59+
60+
print(len(json.loads(os.environ["JSON_INPUT"])))
61+
PY
62+
)
63+
if [[ "${open_pr_count}" != "0" ]]; then
64+
should_run=false
65+
fi
66+
fi
67+
68+
echo "should_run=${should_run}" >> "$GITHUB_OUTPUT"
69+
2870
validate-and-detect:
71+
needs: dedupe
72+
if: needs.dedupe.outputs.should_run == 'true'
2973
runs-on: ubuntu-latest
3074
outputs:
3175
plugins: ${{ steps.detect.outputs.plugins }}
@@ -76,8 +120,8 @@ jobs:
76120
fi
77121
78122
build-test:
79-
needs: validate-and-detect
80-
if: needs.validate-and-detect.outputs.has_plugins == 'true'
123+
needs: [dedupe, validate-and-detect]
124+
if: needs.dedupe.outputs.should_run == 'true' && needs.validate-and-detect.outputs.has_plugins == 'true'
81125
strategy:
82126
fail-fast: false
83127
matrix:

tests/test_plugin_catalog.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,12 @@ def test_ci_workflow_uses_make_targets_for_plugin_checks(self) -> None:
338338
workflow = (
339339
REPO_ROOT / ".github" / "workflows" / "ci-rust-python-package.yaml"
340340
).read_text()
341+
self.assertIn("concurrency:", workflow)
342+
self.assertIn("cancel-in-progress: true", workflow)
343+
self.assertIn("github.head_ref || github.ref_name", workflow)
341344
self.assertIn("pull_request:\n branches: [main]", workflow)
345+
self.assertIn('pulls?state=open&head=', workflow)
346+
self.assertIn('if: needs.dedupe.outputs.should_run == \'true\'', workflow)
342347
self.assertNotIn("Validate plugin catalog", workflow)
343348
self.assertIn("run: make ci", workflow)
344349
self.assertIn("shell: bash", workflow)

0 commit comments

Comments
 (0)