From 22fc6d6118197951bab1320931e14b848d7980e0 Mon Sep 17 00:00:00 2001 From: Casey Eickhoff <48574582+caseyisonit@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:28:22 -0700 Subject: [PATCH] chore: workflow documentation cleanup (#4926) Adds inline documentation to parts of our workflows so it's quicker to get context and know how to update VRT snapshots --- .circleci/config.yml | 4 + .eslintrc.json | 5 +- .github/actions/setup-job/action.yml | 15 +++ .github/workflows/beta-release.yml | 13 +- .github/workflows/coveralls.yml | 13 +- .github/workflows/pr-update.yml | 13 +- .github/workflows/publish.yml | 12 +- .github/workflows/smoke.yml | 18 +-- .github/workflows/test.yml | 125 +++++++----------- .prettierrc.yaml | 16 +-- .../documentation/src/components/layout.ts | 3 +- .../documentation/src/components/side-nav.ts | 1 - projects/documentation/src/utils/templates.ts | 4 +- tasks/build-lighthouse-comment.js | 24 +++- tasks/build-preview-urls-comment.js | 58 +++----- tasks/build-tachometer-comment.js | 15 ++- tasks/get-changed-packages.js | 45 +++++++ tasks/test-changes.js | 36 +---- 18 files changed, 208 insertions(+), 212 deletions(-) create mode 100644 .github/actions/setup-job/action.yml create mode 100644 tasks/get-changed-packages.js diff --git a/.circleci/config.yml b/.circleci/config.yml index f727f96587..02d38938ed 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,6 +8,10 @@ executors: environment: NODE_ENV: development parameters: + # In order to update the VRT baseline images: + # 1. Copy the hash of the latest golden images cache from the left sidebar in the VRT preview link (not to be confused with the arbitrary hash in the URL). + # 2. Paste the hash in the current_golden_images_hash default parameter below. + # 3. Commit this change to the PR branch where the changes exist. current_golden_images_hash: type: string default: 62ecc57a00a4e68cdacbad3ce6f0a205fda2e002 diff --git a/.eslintrc.json b/.eslintrc.json index 0d2d6bea0e..f85a33242f 100755 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,6 +1,7 @@ { "root": true, "plugins": [ + "@typescript-eslint", "notice", "@spectrum-web-components", "import", @@ -13,7 +14,7 @@ }, "parser": "@typescript-eslint/parser", "parserOptions": { - "ecmaVersion": 8, + "ecmaVersion": 2020, "sourceType": "module" }, "rules": { @@ -70,6 +71,8 @@ ] }, "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended", "plugin:lit-a11y/recommended", "plugin:require-extensions/recommended" diff --git a/.github/actions/setup-job/action.yml b/.github/actions/setup-job/action.yml new file mode 100644 index 0000000000..19066dd9a3 --- /dev/null +++ b/.github/actions/setup-job/action.yml @@ -0,0 +1,15 @@ +name: Setup Job +description: Common setup for all jobs +runs: + using: 'composite' + steps: + - name: Setup Node 20 + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'yarn' + registry-url: 'https://registry.npmjs.org' + + - name: Install dependencies + shell: bash + run: yarn --frozen-lockfile diff --git a/.github/workflows/beta-release.yml b/.github/workflows/beta-release.yml index e483c43a8a..04e799ec96 100644 --- a/.github/workflows/beta-release.yml +++ b/.github/workflows/beta-release.yml @@ -10,16 +10,11 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v3 + - name: Checkout PR branch + uses: actions/checkout@v4 - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: '20' - - - name: Install dependencies - run: yarn install --frozen-lockfile + - name: Setup Job and Install Dependencies + uses: ./.github/actions/setup-job - name: Set Git identity run: | diff --git a/.github/workflows/coveralls.yml b/.github/workflows/coveralls.yml index 6ba2418a09..1aac4ed22b 100644 --- a/.github/workflows/coveralls.yml +++ b/.github/workflows/coveralls.yml @@ -13,18 +13,11 @@ jobs: name: Generate and upload coverage report runs-on: ubuntu-latest steps: - - name: Checkout code + - name: Checkout PR branch uses: actions/checkout@v4 - - name: Setup Node 20 - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'yarn' - registry-url: 'https://registry.npmjs.org' - - - name: Install dependencies - run: yarn --frozen-lockfile + - name: Setup Job and Install Dependencies + uses: ./.github/actions/setup-job - name: Install Playwright run: yarn playwright install diff --git a/.github/workflows/pr-update.yml b/.github/workflows/pr-update.yml index f5f77382bf..55e1ff8efa 100644 --- a/.github/workflows/pr-update.yml +++ b/.github/workflows/pr-update.yml @@ -10,13 +10,12 @@ jobs: contents: read pull-requests: write steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - cache: yarn - node-version: 20 - - name: Install dependencies - run: yarn install --frozen-lockfile + - name: Checkout PR branch + uses: actions/checkout@v4 + + - name: Setup Job and Install Dependencies + uses: ./.github/actions/setup-job + # README: https://github.com/castastrophe/actions-pr-auto-update#auto-update-pull-requests - uses: castastrophe/actions-pr-auto-update@v1.1.0 with: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c87e2cc99c..f86439352b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -13,15 +13,11 @@ jobs: # Run the job if manually triggered or if the commit message includes '#publish' & the check suite has passed if: github.event_name == 'workflow_dispatch' || contains(github.event.head_commit.message, '#publish') steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'yarn' - registry-url: 'https://registry.npmjs.org' + - name: Checkout PR branch + uses: actions/checkout@v4 - - name: Install dependencies - run: yarn --frozen-lockfile + - name: Setup Job and Install Dependencies + uses: ./.github/actions/setup-job - name: Generate Docs run: yarn docs:ci diff --git a/.github/workflows/smoke.yml b/.github/workflows/smoke.yml index 3cada8cb69..8fb1e24ed3 100644 --- a/.github/workflows/smoke.yml +++ b/.github/workflows/smoke.yml @@ -9,20 +9,20 @@ jobs: timeout-minutes: 60 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: 'yarn' - registry-url: 'https://registry.npmjs.org' + - name: Checkout PR branch + uses: actions/checkout@v4 + + - name: Setup Job and Install Dependencies + uses: ./.github/actions/setup-job - - name: Install dependencies - run: yarn --frozen-lockfile - name: Install Playwright Browsers run: npx playwright install --with-deps + - name: Run Playwright tests run: npx playwright test projects/documentation/e2e/published.spec.ts - - uses: actions/upload-artifact@v4 + + - name: Upload Playwright Report + uses: actions/upload-artifact@v4 if: always() with: name: playwright-report diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a7e5714385..4be00aa031 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,31 +6,25 @@ on: jobs: comment-previews: - name: Comments preview URLs + name: Create preview URLs and comment - # We can't currently run benchmarks on PRs from forked repos, because the - # tachometer action reports results by posting a comment, and we can't post - # comments without a github token. + # The job will only run if the pull request is from the same repository. + # Benchmarks can't run on PRs from forked repos due to comment posting restrictions without a GitHub token. if: github.event.pull_request == null || github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - name: Checkout main + uses: actions/checkout@v4 with: ref: main - - uses: actions/checkout@v4 + - name: Checkout PR branch + uses: actions/checkout@v4 - - name: Setup Node 20 - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'yarn' - registry-url: 'https://registry.npmjs.org' - - - name: Install dependencies - run: yarn --frozen-lockfile + - name: Setup Job and Install Dependencies + uses: ./.github/actions/setup-job - - name: Post Previews + - name: Post Previews Comment uses: actions/github-script@v7 with: script: | @@ -43,28 +37,23 @@ jobs: runs-on: ubuntu-22.04 needs: comment-previews steps: - - uses: actions/checkout@v4 + - name: Checkout main + uses: actions/checkout@v4 with: ref: main - - uses: actions/checkout@v4 - - - name: Setup Node 20 - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'yarn' - registry-url: 'https://registry.npmjs.org' + - name: Checkout PR branch + uses: actions/checkout@v4 - - name: Install dependencies - run: yarn --frozen-lockfile + - name: Setup Job and Install Dependencies + uses: ./.github/actions/setup-job - name: Extract branch name shell: bash run: echo "branch=$(npx slugify-cli ${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}})" >> $GITHUB_OUTPUT id: extract_branch - - name: Lighthouse CI Action + - name: Run Lighthouse CI id: lighthouse uses: treosh/lighthouse-ci-action@v11 with: @@ -78,7 +67,7 @@ jobs: https://main--spectrum-web-components.netlify.app/ https://${{ steps.extract_branch.outputs.branch }}--spectrum-web-components.netlify.app/ - - name: Post Results + - name: Post Lighthouse Results Comment uses: actions/github-script@v7 with: script: | @@ -86,37 +75,33 @@ jobs: const body = buildLighthouseComment(${{ steps.lighthouse.outputs.links }}, ${{ steps.lighthouse.outputs.manifest }}, ${{ steps.lighthouse.outputs.assertionResults }}); const { commentOrUpdate } = await import('${{ github.workspace }}/tasks/comment-or-update.js'); commentOrUpdate(github, context, '## Lighthouse scores', body); + compare-firefox: name: Compare performance to latest release on Firefox - # We can't currently run benchmarks on PRs from forked repos, because the - # tachometer action reports results by posting a comment, and we can't post - # comments without a github token. + # The job will only run if the pull request is from the same repository. + # Benchmarks can't run on PRs from forked repos due to comment posting restrictions without a GitHub token. if: github.event.pull_request == null || github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v4 + - name: Checkout main + uses: actions/checkout@v4 with: ref: main - - uses: actions/checkout@v4 + - name: Checkout PR branch + uses: actions/checkout@v4 - - name: Setup Node 20 - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'yarn' - registry-url: 'https://registry.npmjs.org' + - name: Setup Job and Install Dependencies + uses: ./.github/actions/setup-job - - name: Install dependencies - run: yarn --frozen-lockfile - - - run: firefox --version + - name: Print Firefox version + run: firefox --version - name: Tachometer the changed packages run: yarn test:changed --browser=firefox - - name: Make at least one results file + - name: Create a dummy file to ensure at least one results file exists run: touch tachometer.firefox-ran.txt - name: Archive Firefox tachometer results @@ -130,32 +115,26 @@ jobs: compare-chrome: name: Compare performance to latest release on Chrome - # We can't currently run benchmarks on PRs from forked repos, because the - # tachometer action reports results by posting a comment, and we can't post - # comments without a github token. + # The job will only run if the pull request is from the same repository. + # Benchmarks can't run on PRs from forked repos due to comment posting restrictions without a GitHub token. if: github.event.pull_request == null || github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - name: Checkout main + uses: actions/checkout@v4 with: ref: main - - uses: actions/checkout@v4 - - - name: Setup Node 20 - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'yarn' - registry-url: 'https://registry.npmjs.org' + - name: Checkout PR branch + uses: actions/checkout@v4 - - name: Install dependencies - run: yarn --frozen-lockfile + - name: Setup Job and Install Dependencies + uses: ./.github/actions/setup-job - name: Tachometer the changed packages run: yarn test:changed - - name: Make at least one results file + - name: Create a dummy file to ensure at least one results file exists run: touch tachometer.chrome-ran.txt - name: Archive Chrome tachometer results @@ -167,30 +146,24 @@ jobs: tachometer.chrome-ran.txt comment-performance: - name: Comment performance results + name: Comment tachometer performance results needs: [compare-chrome, compare-firefox] - # We can't currently run benchmarks on PRs from forked repos, because the - # tachometer action reports results by posting a comment, and we can't post - # comments without a github token. + # The job will only run if the pull request is from the same repository. + # Benchmarks can't run on PRs from forked repos due to comment posting restrictions without a GitHub token. if: github.event.pull_request == null || github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - name: Checkout main + uses: actions/checkout@v4 with: ref: main - - uses: actions/checkout@v4 - - - name: Setup Node 20 - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'yarn' - registry-url: 'https://registry.npmjs.org' + - name: Checkout PR branch + uses: actions/checkout@v4 - - name: Install dependencies - run: yarn --frozen-lockfile + - name: Setup Job and Install Dependencies + uses: ./.github/actions/setup-job - name: Retrieve tachometer results archives uses: actions/download-artifact@v4 @@ -202,7 +175,7 @@ jobs: with: name: tachometer-results-chrome - - name: Post Performance + - name: Post Tachometer Performance Comment uses: actions/github-script@v7 with: script: | diff --git a/.prettierrc.yaml b/.prettierrc.yaml index 9d9029b409..649ec697a2 100644 --- a/.prettierrc.yaml +++ b/.prettierrc.yaml @@ -1,8 +1,8 @@ -printWidth: 80 -tabWidth: 4 -semi: true -singleQuote: true -trailingComma: es5 -bracketSpacing: true -arrowParens: always -htmlWhitespaceSensitivity: ignore +printWidth: 80 +tabWidth: 4 +semi: true +singleQuote: true +trailingComma: es5 +bracketSpacing: true +arrowParens: always +htmlWhitespaceSensitivity: ignore diff --git a/projects/documentation/src/components/layout.ts b/projects/documentation/src/components/layout.ts index 86253db3f3..a1cdd309e2 100644 --- a/projects/documentation/src/components/layout.ts +++ b/projects/documentation/src/components/layout.ts @@ -14,7 +14,6 @@ import { CSSResultArray, html, LitElement, - nothing, PropertyValues, TemplateResult, } from '@spectrum-web-components/base'; @@ -91,7 +90,7 @@ const lazyStyleFragment = ( name: Color | Scale, system: SystemVariant ): void => { - var fragmentName = `${name}-${system}`; + const fragmentName = `${name}-${system}`; switch (fragmentName) { case 'dark-spectrum' || 'darkest-spectrum': import('@spectrum-web-components/theme/theme-dark.js'); diff --git a/projects/documentation/src/components/side-nav.ts b/projects/documentation/src/components/side-nav.ts index 0899ccd64f..6a01da5211 100644 --- a/projects/documentation/src/components/side-nav.ts +++ b/projects/documentation/src/components/side-nav.ts @@ -25,7 +25,6 @@ import sideNavStyles from './side-nav.css'; import '@spectrum-web-components/sidenav/sp-sidenav.js'; import '@spectrum-web-components/sidenav/sp-sidenav-item.js'; import '@spectrum-web-components/underlay/sp-underlay.js'; -import { ifDefined } from '@spectrum-web-components/base/src/directives.js'; @customElement('docs-side-nav') export class SideNav extends LitElement { diff --git a/projects/documentation/src/utils/templates.ts b/projects/documentation/src/utils/templates.ts index 7e79655d9f..9f43bf4af6 100644 --- a/projects/documentation/src/utils/templates.ts +++ b/projects/documentation/src/utils/templates.ts @@ -18,13 +18,13 @@ import { } from '@spectrum-web-components/base'; export function toHtmlTemplateString(code: string): TemplateResult { - const stringArray = [`${code}`] as any; + const stringArray = [`${code}`] as string[] & { raw: string[] }; stringArray.raw = [`${code}`]; return html(stringArray as TemplateStringsArray); } export function toCssTemplateString(code: string): CSSResultGroup { - const stringArray = [`${code}`] as any; + const stringArray = [`${code}`] as string[] & { raw: string[] }; stringArray.raw = [`${code}`]; return css(stringArray as TemplateStringsArray); } diff --git a/tasks/build-lighthouse-comment.js b/tasks/build-lighthouse-comment.js index 04bcf5cb7e..2fe8486512 100644 --- a/tasks/build-lighthouse-comment.js +++ b/tasks/build-lighthouse-comment.js @@ -16,7 +16,7 @@ import prettyBytes from 'pretty-bytes'; const latestURL = 'https://opensource.adobe.com/spectrum-web-components/'; const mainURL = 'https://main--spectrum-web-components.netlify.app/'; -const winnerSign = ' 🏆'; +const winnerSign = ' 🏆'; // Emoji to indicate the best performance const totalIndex = 0; const fontIndex = 1; @@ -24,6 +24,7 @@ const scriptIndex = 2; const stylesheetIndex = 3; const documentIndex = 4; +// Format resource usage by index and add winner sign if applicable const formatResourceByIndex = (index, resource, resourcesRaw, winner) => resource === 'transferSize' ? prettyBytes(resourcesRaw[index][resource], { @@ -31,6 +32,7 @@ const formatResourceByIndex = (index, resource, resourcesRaw, winner) => }) + (winner ? winnerSign : '') : resourcesRaw[index][resource] + (winner ? winnerSign : ''); +// Format all resource usage categories const formatResources = (resource, resourcesRaw, winners) => ({ total: formatResourceByIndex( totalIndex, @@ -64,11 +66,13 @@ const formatResources = (resource, resourcesRaw, winners) => ({ ), }); +// Format all resources for size and count const formatAllResources = (resourcesRaw, winners) => ({ size: formatResources('transferSize', resourcesRaw, winners.size), count: formatResources('requestCount', resourcesRaw, winners.count), }); +// Determine if the current context is the winner for a specific resource const getWinnerByIndex = (index, test, context, competitorA, competitorB) => { return ( context[index][test] < competitorA[index][test] && @@ -76,6 +80,7 @@ const getWinnerByIndex = (index, test, context, competitorA, competitorB) => { ); }; +// Get winners for all resource categories const getWinners = (test, context, competitorA, competitorB) => ({ total: getWinnerByIndex( totalIndex, @@ -108,11 +113,13 @@ const getWinners = (test, context, competitorA, competitorB) => ({ font: getWinnerByIndex(fontIndex, test, context, competitorA, competitorB), }); +// Get winners for all resources (size and count) const getAllWiners = (context, competitorA, competitorB) => ({ size: getWinners('transferSize', context, competitorA, competitorB), count: getWinners('requestCount', context, competitorA, competitorB), }); +// Compare resource usage between branch, main, and latest const compareResourceUsage = (branch, main, latest) => { const branchWinners = getAllWiners(branch, latest, main); const mainWinners = getAllWiners(main, branch, latest); @@ -128,8 +135,10 @@ const compareResourceUsage = (branch, main, latest) => { }; }; -export const buildLighthouseComment = (links, manifest, assertionResults) => { +// Build the Lighthouse comment for the pull request +export const buildLighthouseComment = (links, manifest) => { const report = {}; + // Map the links to their respective categories (main, latest, branch) Object.keys(links).forEach((key) => { if (key === mainURL) { report.main = links[key]; @@ -139,6 +148,8 @@ export const buildLighthouseComment = (links, manifest, assertionResults) => { report.branch = links[key]; } }); + + // Find the representative run for branch, main, and latest const branch = manifest.find( (result) => result.isRepresentativeRun && @@ -151,6 +162,8 @@ export const buildLighthouseComment = (links, manifest, assertionResults) => { const latest = manifest.find( (result) => result.isRepresentativeRun && result.url === latestURL ); + + // Read and parse the resource summary from the Lighthouse JSON reports const branchResourcesRaw = JSON.parse( fs.readFileSync(branch.jsonPath, 'utf8') ).audits['resource-summary'].details.items; @@ -159,6 +172,8 @@ export const buildLighthouseComment = (links, manifest, assertionResults) => { const latestResourcesRaw = JSON.parse( fs.readFileSync(latest.jsonPath, 'utf8') ).audits['resource-summary'].details.items; + + // Compare resource usage between branch, main, and latest const { branchResources, mainResources, latestResources } = compareResourceUsage( branchResourcesRaw, @@ -166,7 +181,7 @@ export const buildLighthouseComment = (links, manifest, assertionResults) => { latestResourcesRaw ); - /* eslint-disable prettier/prettier */ + // Construct the comment with Lighthouse scores and resource usage const comment = `## Lighthouse scores | Category | Latest ([report](${report.latest})) | Main ([report](${report.main})) | Branch ([report](${report.branch})) | @@ -204,6 +219,7 @@ export const buildLighthouseComment = (links, manifest, assertionResults) => { | Document | ${latestResources.count.document} | ${mainResources.count.document} | ${branchResources.count.document} | | Font | ${latestResources.count.font} | ${mainResources.count.font} | ${branchResources.count.font} | `; - /* eslint-enable prettier/prettier */ + + // Return the constructed comment return comment; }; diff --git a/tasks/build-preview-urls-comment.js b/tasks/build-preview-urls-comment.js index b792f2c2a6..59269a46eb 100644 --- a/tasks/build-preview-urls-comment.js +++ b/tasks/build-preview-urls-comment.js @@ -12,38 +12,10 @@ governing permissions and limitations under the License. */ import slugify from '@sindresorhus/slugify'; -import { execSync } from 'child_process'; import crypto from 'crypto'; +import { getChangedPackages } from './get-changed-packages.js'; -// Duplicated from `tasks/test-changes.js` because GitHub Actions and CJS. 🤦 -const getChangedPackages = () => { - let command; - try { - command = execSync( - 'yarn --silent lerna ls --since origin/main --json --loglevel silent' - ); - } catch (error) { - console.log(error.message); - console.log(error.stdout.toString()); - return []; - } - let packageList; - packageList = JSON.parse(command.toString()).reduce((acc, item) => { - const name = item.name.replace('@spectrum-web-components/', ''); - if ( - // There are no benchmarks available in this directory. - item.location.search('projects') === -1 && - // The icons-* tests are particular and long, exclude in CI. - !name.startsWith('icons-') - ) { - acc.push(name); - } - return acc; - }, []); - return packageList; -}; - -const getHash = (context) => { +const createHash = (context) => { const md5 = crypto.createHash('md5'); md5.update(context); return md5.digest('hex'); @@ -51,11 +23,14 @@ const getHash = (context) => { export const buildPreviewURLComment = (ref) => { const packages = getChangedPackages(); + + // Extract the branch name from the ref and slugify it for URL usage const branch = ref.replace('refs/heads/', ''); const branchSlug = slugify(branch); + const previewLinks = []; - const combinations = [ + const previewCombinations = [ { system: 'Spectrum', color: 'Light', @@ -84,17 +59,22 @@ export const buildPreviewURLComment = (ref) => { }, ]; - combinations.forEach(({ system, color, scale, direction }) => { + // Generate preview links for each combination of system, color, scale, and direction + previewCombinations.forEach(({ system, color, scale, direction }) => { + // Create a unique context string for each combination const context = `${branch}-${system.toLowerCase()}-${color.toLowerCase()}-${scale.toLowerCase()}-${direction.toLowerCase()}`; + + // Add the generated preview link to the array previewLinks.push(` -- [${system} | ${color} | ${scale} | ${direction}](https://${getHash( +- [${system} | ${color} | ${scale} | ${direction}](https://${createHash( context )}--spectrum-web-components.netlify.app/review/)`); }); + // Add a high contrast mode preview link previewLinks.push( ` - - [High Contrast Mode | Medium | LTR](https://${getHash( +- [High Contrast Mode | Medium | LTR](https://${createHash( `${branch}-hcm` )}--spectrum-web-components.netlify.app/review/)` ); @@ -103,17 +83,21 @@ export const buildPreviewURLComment = (ref) => { - [Documentation Site](https://${branchSlug}--spectrum-web-components.netlify.app/) - [Storybook](https://${branchSlug}--spectrum-web-components.netlify.app/storybook/)`; + + // If there are changed packages, add a section with visual regression test results if (packages.length > 0) { comment += ` -
- Visual regression test results + +

Review the following VRT differences

When a visual regression test fails (or has previously failed while working on this branch), its results can be found in the following URLs: ${previewLinks.join('')} -
`; +If the changes are expected, update the current_golden_images_cache hash in the circleci config to accept the new images. Instructions are included in that file. +If the changes are unexpected, you can investigate the cause of the differences and update the code accordingly. +`; } return comment; diff --git a/tasks/build-tachometer-comment.js b/tasks/build-tachometer-comment.js index ef4afdd598..c456e7d5c1 100644 --- a/tasks/build-tachometer-comment.js +++ b/tasks/build-tachometer-comment.js @@ -23,11 +23,12 @@ const getTachometerResults = () => { for (const result of fg.sync(`./tach-results.*.json`)) { const file = fs.readFileSync(result, 'utf8'); // Grab the ${bowserName}.${package} part of the results file name as an array of [browserName, package]. - const [bowserName] = /tach-results\.(.*)\.json/ - .exec(result)[1] - .split('.'); - const json = JSON.parse(file); - results[bowserName].push(json.benchmarks); + const match = /tach-results\.(.*)\.json/.exec(result); + if (match) { + const [bowserName] = match[1].split('.'); + const json = JSON.parse(file); + results[bowserName].push(json.benchmarks); + } } return results; }; @@ -111,7 +112,9 @@ const buildTable = (results) => { `); results.forEach((result, i) => { - if (i % 2 > 0) return; + if (i % 2 > 0) { + return; + } const testName = `${result.name.split(':')[1]}`; const remote = result; const remoteDifferences = formatDifference(remote.differences[i + 1]); diff --git a/tasks/get-changed-packages.js b/tasks/get-changed-packages.js new file mode 100644 index 0000000000..e9a7ae323b --- /dev/null +++ b/tasks/get-changed-packages.js @@ -0,0 +1,45 @@ +#!/usr/bin/env node + +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { execSync } from 'child_process'; + +export const getChangedPackages = () => { + let command; + + try { + // Execute the command to list changed packages since the last commit on origin/main + command = execSync( + 'yarn --silent lerna ls --since origin/main --json --loglevel silent' + ); + } catch (error) { + console.log(error.message); + console.log(error.stdout.toString()); + return []; + } + + const packageList = JSON.parse(command.toString()).reduce((acc, item) => { + // Remove the '@spectrum-web-components/' prefix from the package name + const name = item.name.replace('@spectrum-web-components/', ''); + if ( + // Exclude packages located in the 'projects' directory as here are no benchmarks available + item.location.search('projects') === -1 && + // Exclude packages that start with 'icons-' as they are long-running tests + !name.startsWith('icons-') + ) { + acc.push(name); + } + return acc; + }, []); + + return packageList; +}; diff --git a/tasks/test-changes.js b/tasks/test-changes.js index d65e6df597..417575a28a 100644 --- a/tasks/test-changes.js +++ b/tasks/test-changes.js @@ -15,50 +15,22 @@ governing permissions and limitations under the License. import { execSync } from 'child_process'; import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; +import { getChangedPackages } from './get-changed-packages.js'; const { browser = 'chrome' } = yargs(hideBin(process.argv)).argv; -// Duplicated from `tasks/build-preview-urls-comments.cjs` because GitHub Actions and CJS. 🤦 -const getChangedPackages = () => { - let command; - try { - command = execSync( - 'yarn --silent lerna ls --since origin/main --json --loglevel silent --ignore "@swc-react/*"' - ); - } catch (error) { - console.log(error.message); - console.log(error.stdout.toString()); - return []; - } - let packageList; - try { - packageList = JSON.parse(command.toString()).reduce((acc, item) => { - const name = item.name.replace('@spectrum-web-components/', ''); - if ( - // There are no benchmarks available in this directory. - item.location.search('projects') === -1 && - // The icons-* tests are particular and long, exclude in CI. - !name.startsWith('icons-') - ) { - acc.push(name); - } - return acc; - }, []); - } catch (error) { - packageList = []; - } - return packageList; -}; - const testChangedPackages = () => { const packages = getChangedPackages(); + if (packages.length) { console.log( `Running tachometer on the following packages: ${packages.join( ', ' )}` ); + execSync('yarn build:tests'); + execSync( `yarn test:bench --browser ${browser} -j -p ${packages.join(' ')}`, {