Skip to content

ci(lint): expand jscpd to use branch comparison #15815

ci(lint): expand jscpd to use branch comparison

ci(lint): expand jscpd to use branch comparison #15815

Workflow file for this run

# github actions: https://docs.github.com/en/actions/use-cases-and-examples/building-and-testing/building-and-testing-nodejs
# setup-node: https://github.com/actions/setup-node
name: CI
on:
push:
branches: [master, staging]
pull_request:
branches: [master, feature/*, staging]
# Default = opened + synchronize + reopened.
# We also want "edited" so that lint-commits runs when PR title is updated.
# https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request
types:
- edited
- opened
- reopened
- synchronize
# Cancel old jobs when a pull request is updated.
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
dupe-check:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Install dependencies
run: |
npm install -g jscpd diff-so-fancy
- name: Run jscpd on entire codebase
run: jscpd --config "$GITHUB_WORKSPACE/.github/workflows/jscpd.json"
- name: Get the diff
run: git diff --name-only origin/${{ github.event.pull_request.base.ref }}..${{ github.head_ref }} >> diff_output.txt
- name: Upload unfiltered jscpd report
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 if filtered jscpd report exists
id: check_filtered_report
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 jscpd report
if: env.filtered_report_exists == 'true'
uses: actions/upload-artifact@v4
with:
name: filtered-jscpd-report
path: ./filtered-jscpd-report.json
- name: Post GitHub comment
if: env.filtered_report_exists == 'true'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const filteredReport = JSON.parse(fs.readFileSync('filtered-jscpd-report.json', 'utf8'));
let comment = "Whoa there, partner! 🌵🤠 We wrangled some duplicated code in your PR:\n\n";
function link(dup) {
return `https://github.com/${{ github.event.repository.full_name }}/blob/${{ github.event.pull_request.head.sha }}/${dup.name}#L${dup.start + 1}-L${dup.end - 1}`
}
filteredReport.forEach(duplication => {
const firstFile = duplication.firstFile;
const secondFile = duplication.secondFile;
const lines = duplication.lines;
comment += `- [\`${firstFile.name}\`](${link(firstFile)}) has ${lines} duplicated lines with [\`${secondFile.name}\`](${link(secondFile)})\n`;
});
comment += "\nReducing code duplication by importing common functions from a library not only makes our code cleaner but also easier to maintain. Please move the common code from both files into a library and import it in each. We hate that we have to mention this, however, commits designed to hide from this utility by renaming variables or reordering an object are poor conduct. We will not look upon them kindly! Keep up the great work! 🚀";
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});
- name: Fail if duplications are found
if: env.filtered_report_exists == 'true'
run: |
echo "Duplications found, failing the check."
exit 1
lint-commits:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 20
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Check PR title
run: |
node "$GITHUB_WORKSPACE/.github/workflows/lintcommit.js"
lint:
needs: lint-commits
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
vscode-version: [stable]
env:
NODE_OPTIONS: '--max-old-space-size=8192'
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run testCompile
- run: npm run lint
macos:
needs: lint-commits
name: test macOS
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
node-version: [18.x]
vscode-version: [minimum, stable, insiders]
env:
VSCODE_TEST_VERSION: ${{ matrix.vscode-version }}
NODE_OPTIONS: '--max-old-space-size=8192'
AWS_TOOLKIT_TEST_CACHE_DIR: '/tmp/.vscode-test/'
AWS_TOOLKIT_TEST_USER_DIR: '/tmp/.vscode-test/user-data/'
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- name: Tests
uses: coactions/setup-xvfb@v1
with:
run: npm test
- name: Code coverage (Toolkit)
env:
# Unset NODE_OPTIONS because of https://github.com/codecov/uploader/issues/475
NODE_OPTIONS: ''
if: ${{ github.repository == 'aws/aws-toolkit-vscode' && github.ref == 'master' }}
uses: codecov/codecov-action@v4
with:
flags: macos-toolkit-unittests
verbose: true
file: ./coverage/toolkit/lcov.info
token: ${{ secrets.CODECOV_TOKEN }}
- name: Code coverage (Amazon Q)
env:
# Unset NODE_OPTIONS because of https://github.com/codecov/uploader/issues/475
NODE_OPTIONS: ''
if: ${{ github.repository == 'aws/aws-toolkit-vscode' && github.ref == 'master' }}
uses: codecov/codecov-action@v4
with:
flags: macos-amazonq-unittests
verbose: true
file: ./coverage/amazonq/lcov.info
token: ${{ secrets.CODECOV_TOKEN }}
web:
needs: lint-commits
name: test Web
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
node-version: [18.x]
vscode-version: [stable, insiders]
env:
VSCODE_TEST_VERSION: ${{ matrix.vscode-version }}
NODE_OPTIONS: '--max-old-space-size=8192'
AWS_TOOLKIT_TEST_CACHE_DIR: '/tmp/.vscode-test/'
AWS_TOOLKIT_TEST_USER_DIR: '/tmp/.vscode-test/user-data/'
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- name: Tests
uses: coactions/setup-xvfb@v1
with:
run: npm run testWeb
windows:
needs: lint-commits
name: test Windows
runs-on: windows-2019
strategy:
fail-fast: false
matrix:
node-version: [18.x]
vscode-version: [stable, insiders]
env:
VSCODE_TEST_VERSION: ${{ matrix.vscode-version }}
NODE_OPTIONS: '--max-old-space-size=8192'
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- name: Tests
run: npm test
- name: Code coverage
env:
# Unset NODE_OPTIONS because of https://github.com/codecov/uploader/issues/475
NODE_OPTIONS: ''
if: ${{ github.repository == 'aws/aws-toolkit-vscode' && github.ref == 'master' }}
uses: codecov/codecov-action@v4
with:
flags: windows-unittests
verbose: true
file: ./coverage/lcov.info
token: ${{ secrets.CODECOV_TOKEN }}