Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build(jscpd): validate branch name before running CI #6124

Merged
merged 12 commits into from
Dec 9, 2024
86 changes: 0 additions & 86 deletions .github/workflows/copyPasteDetection.yml

This file was deleted.

67 changes: 67 additions & 0 deletions .github/workflows/lintbranch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Check that branch name conforms to GitHub naming convention:
// https://docs.github.com/en/get-started/using-git/dealing-with-special-characters-in-branch-and-tag-names#naming-branches-and-tags

// To run self-tests,
// node lintbranch.js test
// TODO: deduplicate code from lintbranch.js and lintcommit.js.

function isValid(branchName) {
const branchNameRegex = /^[a-zA-Z][a-zA-Z0-9._/-]*$/

return branchNameRegex.test(branchName)
}

function run(branchName) {
if (isValid(branchName)) {
console.log(`Branch name "${branchName}" is valid.`)
process.exit(0)
} else {
const helpUrl =
'https://docs.github.com/en/get-started/using-git/dealing-with-special-characters-in-branch-and-tag-names#naming-branches-and-tags'
console.log(`Branch name "${branchName}" is invalid see ${helpUrl} for more information.`)
process.exit(1)
}
}

function _test() {
const tests = {
'feature/branch-name': true,
feature_123: true,
'my-branch': true,
'123invalid-start': false,
'!invalid@start': false,
'': false,
'another/valid-name134': true,
'feature/123";id;{echo,Y2F0IC9ldGMvcGFzc3dk}|{base64,-d}|{bash,-i};#': false,
}

let passed = 0
let failed = 0

for (const [branchName, expected] of Object.entries(tests)) {
const result = isValid(branchName)
if (result === expected) {
console.log(`✅ Test passed for "${branchName}"`)
passed++
} else {
console.log(`❌ Test failed for "${branchName}" (expected "${expected}", got "${result}")`)
failed++
}
}

console.log(`\n${passed} tests passed, ${failed} tests failed`)
}

function main() {
const mode = process.argv[2]

if (mode === 'test') {
_test()
} else if (mode === 'run') {
run(process.argv[3])
} else {
throw new Error(`Unknown mode: ${mode}`)
}
}

main()
86 changes: 86 additions & 0 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Check Branch title
env:
BRANCH_NAME: ${{ github.head_ref }}
run: |
node "$GITHUB_WORKSPACE/.github/workflows/lintbranch.js" run "$BRANCH_NAME"
- name: Check PR title
run: |
node "$GITHUB_WORKSPACE/.github/workflows/lintcommit.js"
Expand All @@ -55,6 +60,87 @@ jobs:
- run: npm run testCompile
- run: npm run lint

jscpd:
needs: lint-commits
if: ${{ github.event_name == 'pull_request'}}
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
env:
NODE_OPTIONS: '--max-old-space-size=8192'

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}

- name: Fetch fork upstream
env:
REPO_NAME: ${{ github.event.pull_request.head.repo.full_name }}
run: |
git remote add forkUpstream https://github.com/$REPO_NAME # URL of the fork
git fetch forkUpstream # Fetch fork

- name: Compute git diff
env:
CURRENT_BRANCH: ${{ github.head_ref }}
TARGET_BRANCH: ${{ github.event.pull_request.base.ref }}
run: git diff --name-only origin/$TARGET_BRANCH forkUpstream/$CURRENT_BRANCH > diff_output.txt

- run: npm install -g jscpd

- run: jscpd --config "$GITHUB_WORKSPACE/.github/workflows/jscpd.json"

- if: always()
uses: actions/upload-artifact@v4
with:
name: unfiltered-jscpd-report
path: ./jscpd-report.json

- name: Filter jscpd report for changed files
run: |
if [ ! -f ./jscpd-report.json ]; then
echo "jscpd-report.json not found"
exit 1
fi
echo "Filtering jscpd report for changed files..."
CHANGED_FILES=$(jq -R -s -c 'split("\n")[:-1]' diff_output.txt)
echo "Changed files: $CHANGED_FILES"
jq --argjson changed_files "$CHANGED_FILES" '
.duplicates | map(select(
(.firstFile?.name as $fname | $changed_files | any(. == $fname)) or
(.secondFile?.name as $sname | $changed_files | any(. == $sname))
))
' ./jscpd-report.json > filtered-jscpd-report.json
cat filtered-jscpd-report.json

- name: Check for duplicates
run: |
if [ $(wc -l < ./filtered-jscpd-report.json) -gt 1 ]; then
echo "filtered_report_exists=true" >> $GITHUB_ENV
else
echo "filtered_report_exists=false" >> $GITHUB_ENV
fi
- name: upload filtered report (if applicable)
if: env.filtered_report_exists == 'true'
uses: actions/upload-artifact@v4
with:
name: filtered-jscpd-report
path: ./filtered-jscpd-report.json

- name: Fail and log found duplicates.
if: env.filtered_report_exists == 'true'
run: |
cat ./filtered-jscpd-report.json
echo "Duplications found, failing the check."
exit 1

macos:
needs: lint-commits
name: test macOS
Expand Down
Loading