Skip to content

Commit e300353

Browse files
authored
build(jscpd): validate branch name before running CI (#6124)
## Problem ... ## Solution - (title) - Refactor github actions such that JSCPD requires `lint-commits`. - Add step to `lint-commits` that verifies branch name according to rules here: https://docs.github.com/en/get-started/using-git/dealing-with-special-characters-in-branch-and-tag-names#naming-branches-and-tags - Note this means that no CI tasks will run on PRs with branches that don't fit naming conventions. --- <!--- REMINDER: Ensure that your PR meets the guidelines in CONTRIBUTING.md --> License: I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 226dd6f commit e300353

File tree

3 files changed

+153
-86
lines changed

3 files changed

+153
-86
lines changed

.github/workflows/copyPasteDetection.yml

Lines changed: 0 additions & 86 deletions
This file was deleted.

.github/workflows/lintbranch.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Check that branch name conforms to GitHub naming convention:
2+
// https://docs.github.com/en/get-started/using-git/dealing-with-special-characters-in-branch-and-tag-names#naming-branches-and-tags
3+
4+
// To run self-tests,
5+
// node lintbranch.js test
6+
// TODO: deduplicate code from lintbranch.js and lintcommit.js.
7+
8+
function isValid(branchName) {
9+
const branchNameRegex = /^[a-zA-Z][a-zA-Z0-9._/-]*$/
10+
11+
return branchNameRegex.test(branchName)
12+
}
13+
14+
function run(branchName) {
15+
if (isValid(branchName)) {
16+
console.log(`Branch name "${branchName}" is valid.`)
17+
process.exit(0)
18+
} else {
19+
const helpUrl =
20+
'https://docs.github.com/en/get-started/using-git/dealing-with-special-characters-in-branch-and-tag-names#naming-branches-and-tags'
21+
console.log(`Branch name "${branchName}" is invalid see ${helpUrl} for more information.`)
22+
process.exit(1)
23+
}
24+
}
25+
26+
function _test() {
27+
const tests = {
28+
'feature/branch-name': true,
29+
feature_123: true,
30+
'my-branch': true,
31+
'123invalid-start': false,
32+
'!invalid@start': false,
33+
'': false,
34+
'another/valid-name134': true,
35+
'feature/123";id;{echo,Y2F0IC9ldGMvcGFzc3dk}|{base64,-d}|{bash,-i};#': false,
36+
}
37+
38+
let passed = 0
39+
let failed = 0
40+
41+
for (const [branchName, expected] of Object.entries(tests)) {
42+
const result = isValid(branchName)
43+
if (result === expected) {
44+
console.log(`✅ Test passed for "${branchName}"`)
45+
passed++
46+
} else {
47+
console.log(`❌ Test failed for "${branchName}" (expected "${expected}", got "${result}")`)
48+
failed++
49+
}
50+
}
51+
52+
console.log(`\n${passed} tests passed, ${failed} tests failed`)
53+
}
54+
55+
function main() {
56+
const mode = process.argv[2]
57+
58+
if (mode === 'test') {
59+
_test()
60+
} else if (mode === 'run') {
61+
run(process.argv[3])
62+
} else {
63+
throw new Error(`Unknown mode: ${mode}`)
64+
}
65+
}
66+
67+
main()

.github/workflows/node.js.yml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ jobs:
3232
- uses: actions/setup-node@v4
3333
with:
3434
node-version: '20'
35+
- name: Check Branch title
36+
env:
37+
BRANCH_NAME: ${{ github.head_ref }}
38+
run: |
39+
node "$GITHUB_WORKSPACE/.github/workflows/lintbranch.js" run "$BRANCH_NAME"
3540
- name: Check PR title
3641
run: |
3742
node "$GITHUB_WORKSPACE/.github/workflows/lintcommit.js"
@@ -55,6 +60,87 @@ jobs:
5560
- run: npm run testCompile
5661
- run: npm run lint
5762

63+
jscpd:
64+
needs: lint-commits
65+
if: ${{ github.event_name == 'pull_request'}}
66+
runs-on: ubuntu-latest
67+
strategy:
68+
matrix:
69+
node-version: [18.x]
70+
env:
71+
NODE_OPTIONS: '--max-old-space-size=8192'
72+
73+
steps:
74+
- uses: actions/checkout@v4
75+
with:
76+
fetch-depth: 0
77+
78+
- name: Use Node.js ${{ matrix.node-version }}
79+
uses: actions/setup-node@v4
80+
with:
81+
node-version: ${{ matrix.node-version }}
82+
83+
- name: Fetch fork upstream
84+
env:
85+
REPO_NAME: ${{ github.event.pull_request.head.repo.full_name }}
86+
run: |
87+
git remote add forkUpstream https://github.com/$REPO_NAME # URL of the fork
88+
git fetch forkUpstream # Fetch fork
89+
90+
- name: Compute git diff
91+
env:
92+
CURRENT_BRANCH: ${{ github.head_ref }}
93+
TARGET_BRANCH: ${{ github.event.pull_request.base.ref }}
94+
run: git diff --name-only origin/$TARGET_BRANCH forkUpstream/$CURRENT_BRANCH > diff_output.txt
95+
96+
- run: npm install -g jscpd
97+
98+
- run: jscpd --config "$GITHUB_WORKSPACE/.github/workflows/jscpd.json"
99+
100+
- if: always()
101+
uses: actions/upload-artifact@v4
102+
with:
103+
name: unfiltered-jscpd-report
104+
path: ./jscpd-report.json
105+
106+
- name: Filter jscpd report for changed files
107+
run: |
108+
if [ ! -f ./jscpd-report.json ]; then
109+
echo "jscpd-report.json not found"
110+
exit 1
111+
fi
112+
echo "Filtering jscpd report for changed files..."
113+
CHANGED_FILES=$(jq -R -s -c 'split("\n")[:-1]' diff_output.txt)
114+
echo "Changed files: $CHANGED_FILES"
115+
jq --argjson changed_files "$CHANGED_FILES" '
116+
.duplicates | map(select(
117+
(.firstFile?.name as $fname | $changed_files | any(. == $fname)) or
118+
(.secondFile?.name as $sname | $changed_files | any(. == $sname))
119+
))
120+
' ./jscpd-report.json > filtered-jscpd-report.json
121+
cat filtered-jscpd-report.json
122+
123+
- name: Check for duplicates
124+
run: |
125+
if [ $(wc -l < ./filtered-jscpd-report.json) -gt 1 ]; then
126+
echo "filtered_report_exists=true" >> $GITHUB_ENV
127+
else
128+
echo "filtered_report_exists=false" >> $GITHUB_ENV
129+
fi
130+
- name: upload filtered report (if applicable)
131+
if: env.filtered_report_exists == 'true'
132+
uses: actions/upload-artifact@v4
133+
with:
134+
name: filtered-jscpd-report
135+
path: ./filtered-jscpd-report.json
136+
137+
- name: Fail and log found duplicates.
138+
if: env.filtered_report_exists == 'true'
139+
run: |
140+
cat ./filtered-jscpd-report.json
141+
echo "Duplications found, failing the check."
142+
exit 1
143+
58144
macos:
59145
needs: lint-commits
60146
name: test macOS

0 commit comments

Comments
 (0)