The Node.js® Website
at main 13 kB view raw
1# Security Notes 2# Only selected Actions are allowed within this repository. Please refer to (https://github.com/nodejs/nodejs.org/settings/actions) 3# for the full list of available actions. If you want to add a new one, please reach out a maintainer with Admin permissions. 4# REVIEWERS, please always double-check security practices before merging a PR that contains Workflow changes!! 5# AUTHORS, please only use actions with explicit SHA references, and avoid using `@master` or `@main` references or `@version` tags. 6 7name: Linting and Tests 8 9on: 10 push: 11 branches: 12 - main 13 pull_request_target: 14 branches: 15 - main 16 types: 17 - labeled 18 merge_group: 19 20defaults: 21 run: 22 # This ensures that the working directory is the root of the repository 23 working-directory: ./ 24 25permissions: 26 contents: read 27 actions: read 28 # This permission is required by `MishaKav/jest-coverage-comment` 29 pull-requests: write 30 31jobs: 32 base: 33 name: Base Tasks 34 runs-on: ubuntu-latest 35 outputs: 36 turbo_args: ${{ steps.turborepo_arguments.outputs.turbo_args }} 37 38 steps: 39 - name: Harden Runner 40 uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 41 with: 42 egress-policy: audit 43 44 - name: Provide Turborepo Arguments 45 # This step is responsible for providing a reusable string that can be used within other steps and jobs 46 # that use the `turbo` cli command as a way of easily providing shared arguments to the `turbo` command 47 id: turborepo_arguments 48 # See https://turbo.build/repo/docs/reference/command-line-reference/run#--cache-dir 49 # See https://turbo.build/repo/docs/reference/command-line-reference/run#--force 50 run: echo "turbo_args=--force=true --cache-dir=.turbo/cache" >> "$GITHUB_OUTPUT" 51 52 lint: 53 # This Job should run either on `merge_groups` or `push` events 54 # or `pull_request_target` event with a `labeled` action with a label named `github_actions:pull-request` 55 # since we want to run lint checks against any changes on pull requests, or the final patch on merge groups 56 # or if direct pushes happen to main (or when changes in general land on the `main` (default) branch) 57 # Note that the reason why we run this on pushes against `main` is that on rare cases, maintainers might do direct pushes against `main` 58 if: | 59 (github.event_name == 'push' || github.event_name == 'merge_group') || 60 (github.event_name == 'pull_request_target' && 61 github.event.label.name == 'github_actions:pull-request') 62 63 name: Lint 64 runs-on: ubuntu-latest 65 needs: [base] 66 67 steps: 68 - name: Harden Runner 69 uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 70 with: 71 egress-policy: audit 72 73 - name: Git Checkout 74 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 75 with: 76 # Since we checkout the HEAD of the current Branch, if the Pull Request comes from a Fork 77 # we want to clone the fork's repository instead of the base repository 78 # this allows us to have the correct history tree of the perspective of the Pull Request's branch 79 # If the Workflow is running on `merge_group` or `push` events it fallsback to the base repository 80 repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} 81 # We checkout the branch itself instead of a specific SHA (Commit) as we want to ensure that this Workflow 82 # is always running with the latest `ref` (changes) of the Pull Request's branch 83 # If the Workflow is running on `merge_group` or `push` events it fallsback to `github.ref` which will often be `main` 84 # or the merge_group `ref` 85 ref: ${{ github.event.pull_request.head.ref || github.ref }} 86 87 - name: Restore Lint Cache 88 uses: actions/cache/restore@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 89 with: 90 path: | 91 .turbo/cache 92 node_modules/.cache 93 .eslintmdcache 94 .eslintjscache 95 .stylelintcache 96 .prettiercache 97 # We want to restore Turborepo Cache and ESlint and Prettier Cache 98 # The ESLint and Prettier cache's are useful to reduce the overall runtime of ESLint and Prettier 99 # as they will only run on files that have changed since the last cached run 100 # this might of course lead to certain files not being checked against the linter, but the chances 101 # of such situation from happening are very slim as the checksums of both files would need to match 102 key: cache-lint-${{ hashFiles('package-lock.json') }}- 103 restore-keys: | 104 cache-lint-${{ hashFiles('package-lock.json') }}- 105 cache-lint- 106 107 - name: Set up Node.js 108 uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 109 with: 110 # We want to ensure that the Node.js version running here respects our supported versions 111 node-version-file: '.nvmrc' 112 cache: 'npm' 113 114 - name: Install npm packages 115 # We want to avoid npm from running the Audit Step and Funding messages on a CI environment 116 # We also use `npm i` instead of `npm ci` so that the node_modules/.cache folder doesn't get deleted 117 run: npm i --no-audit --no-fund --ignore-scripts --userconfig=/dev/null 118 119 - name: Run `turbo lint` 120 id: eslint-step 121 # We run the ESLint and Prettier commands on all Workflow triggers of the `Lint` job, besides if 122 # the Pull Request comes from a Crowdin Branch, as we don't want to run ESLint and Prettier on Crowdin PRs 123 # Note: Linting and Prettifying of files on Crowdin PRs is handled by the `translations-pr.yml` Workflow 124 if: | 125 (github.event_name == 'push' || github.event_name == 'merge_group') || 126 (github.event_name == 'pull_request_target' && 127 github.event.pull_request.head.ref != 'chore/crowdin') 128 # We want to enforce that the actual `turbo@latest` package is used instead of a possible hijack from the user 129 # the `${{ needs.base.outputs.turbo_args }}` is a string substitution happening from the base job 130 run: npx --package=turbo@latest -- turbo lint ${{ needs.base.outputs.turbo_args }} 131 132 - name: Run `turbo prettier` 133 if: steps.eslint-step.outcome == 'success' 134 # We want to enforce that the actual `turbo@latest` package is used instead of a possible hijack from the user 135 # the `${{ needs.base.outputs.turbo_args }}` is a string substitution happening from the base job 136 run: npx --package=turbo@latest -- turbo prettier ${{ needs.base.outputs.turbo_args }} 137 138 - name: Run `tsc build` 139 # We want to ensure that the whole codebase is passing and successfully compiles with TypeScript 140 run: npx --package=typescript@latest -- tsc --build . 141 142 - name: Save Lint Cache 143 # We only want to save caches on `push` events or `pull_request_target` events 144 # and if it is a `pull_request_target` event, we want to avoid saving the cache if the PR comes from Dependabot 145 # or if it comes from an automated Crowdin Pull Request 146 # The reason we save caches on `push` is because caches creates on `main` (default) branches can be reused within 147 # other Pull Requests and PRs coming from forks 148 if: | 149 github.event_name == 'push' || 150 (github.event_name == 'pull_request_target' && 151 startsWith(github.event.pull_request.head.ref, 'dependabot/') == false && 152 github.event.pull_request.head.ref != 'chore/crowdin') 153 uses: actions/cache/save@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 154 with: 155 path: | 156 .turbo/cache 157 node_modules/.cache 158 .eslintmdcache 159 .eslintjscache 160 .stylelintcache 161 .prettiercache 162 key: cache-lint-${{ hashFiles('package-lock.json') }}-${{ hashFiles('.turbo/cache/**') }} 163 164 tests: 165 # This Job should run either on `merge_groups` or `push` events 166 # or `pull_request_target` event with a `labeled` action with a label named `github_actions:pull-request` 167 # since we want to run lint checks against any changes on pull requests and on final patches against a pull request. 168 # We don't need to execute the tests again on pushes against (`main`) as the merge group should already handle that 169 if: | 170 (github.event_name == 'push' || github.event_name == 'merge_group') || 171 (github.event_name == 'pull_request_target' && 172 github.event.label.name == 'github_actions:pull-request') 173 174 name: Tests 175 runs-on: ubuntu-latest 176 needs: [base] 177 178 environment: 179 name: Storybook 180 url: ${{ steps.chromatic-deploy.outputs.storybookUrl }} 181 182 steps: 183 - name: Harden Runner 184 uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 185 with: 186 egress-policy: audit 187 188 - name: Git Checkout 189 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 190 with: 191 # Since we checkout the HEAD of the current Branch, if the Pull Request comes from a Fork 192 # we want to clone the fork's repository instead of the base repository 193 # this allows us to have the correct history tree of the perspective of the Pull Request's branch 194 # If the Workflow is running on `merge_group` or `push` events it fallsback to the base repository 195 repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} 196 # We checkout the branch itself instead of a specific SHA (Commit) as we want to ensure that this Workflow 197 # is always running with the latest `ref` (changes) of the Pull Request's branch 198 # If the Workflow is running on `merge_group` or `push` events it fallsback to `github.ref` which will often be `main` 199 # or the merge_group `ref` 200 ref: ${{ github.event.pull_request.head.ref || github.ref }} 201 # The Chromatic (@chromaui/action) Action requires a full history of the current branch in order to be able to compare 202 # previous changes and previous commits and determine which Storybooks should be tested against and what should be built 203 fetch-depth: 0 204 205 - name: Set up Node.js 206 uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 207 with: 208 # We want to ensure that the Node.js version running here respects our supported versions 209 node-version-file: '.nvmrc' 210 cache: 'npm' 211 212 - name: Install npm packages 213 # We want to avoid npm from running the Audit Step and Funding messages on a CI environment 214 # We also use `npm i` instead of `npm ci` so that the node_modules/.cache folder doesn't get deleted 215 run: npm i --no-audit --no-fund --userconfig=/dev/null 216 217 - name: Run Unit Tests 218 # We want to run Unit Tests in every circumstance, including Crowdin PRs and Dependabot PRs to ensure 219 # that changes to dependencies or translations don't break the Unit Tests 220 # We want to enforce that the actual `turbo@latest` package is used instead of a possible hijack from the user 221 # the `${{ needs.base.outputs.turbo_args }}` is a string substitution happening from the base job 222 run: npx --package=turbo@latest -- turbo test:unit ${{ needs.base.outputs.turbo_args }} -- --ci --coverage 223 224 - name: Start Visual Regression Tests (Chromatic) 225 # This assigns the Environment Deployment for Storybook 226 id: chromatic-deploy 227 # We only need to run Storybook Builds and Storybook Visual Regression Tests within Pull Requests that actually 228 # introduce changes to the Storybook. Hence, we skip running these on Crowdin PRs and Dependabot PRs 229 if: | 230 github.event_name == 'push' || 231 (github.event_name == 'pull_request_target' && 232 startsWith(github.event.pull_request.head.ref, 'dependabot/') == false && 233 github.event.pull_request.head.ref != 'chore/crowdin') 234 # sha reference has no stable git tag reference or URL. see https://github.com/chromaui/chromatic-cli/issues/797 235 uses: chromaui/action@807600692d28833b717c155e15ed20905cdc865c 236 with: 237 buildScriptName: storybook:build 238 projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} 239 exitOnceUploaded: true 240 onlyChanged: true 241 242 - name: Jest Coverage Comment 243 # We don't need to post the Jest Coverage comment on Crowdin PRs and Dependabot PRs 244 # as in general they introduce no changes to the Unit Tests and the Codebase 245 # We reuse the checks from the Chromatic Deploy step as they're the same conditions 246 if: steps.chromatic-deploy.outcome == 'success' 247 # This comments the current Jest Coverage Report containing JUnit XML reports 248 # and a Code Coverage Summary 249 uses: MishaKav/jest-coverage-comment@c2d5cfd6c32e8799c6deb0fd76a8e2d9ad8b35c2 # v1.0.25 250 with: 251 title: 'Unit Test Coverage Report' 252 junitxml-path: ./junit.xml 253 junitxml-title: Unit Test Report