diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc7c9d47147e..7a5688a48ecc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,9 +5,6 @@ on: branches: - main pull_request: - branches: - - '**' - merge_group: concurrency: group: '${{ github.workflow }} - ${{ github.head_ref || github.ref }}' @@ -23,304 +20,57 @@ env: defaults: run: shell: bash - -# -# Workflow for how the CI spawns jobs: -# 1) Run the install and cache the install artefacts -# 2) Run the build and cache the output -# - In parallel we also any steps that don't need the build (like prettier) -# 3) Run the steps that depend on the build -# - permissions: - contents: read # to fetch code (actions/checkout) + actions: read + contents: read jobs: - install: - name: Checkout and Install - environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job - runs-on: ubuntu-latest - env: - NX_CI_EXECUTION_ENV: 'ubuntu-latest' - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install - uses: ./.github/actions/prepare-install - with: - node-version: ${{ env.PRIMARY_NODE_VERSION }} - - build: - name: Build All Packages - environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job - needs: [install] - runs-on: ubuntu-latest - env: - NX_CI_EXECUTION_ENV: 'ubuntu-latest' - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install - uses: ./.github/actions/prepare-install - with: - node-version: ${{ env.PRIMARY_NODE_VERSION }} - - name: Build - uses: ./.github/actions/prepare-build - - generate_configs: - name: Generate Configs - environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job - needs: [build] - runs-on: ubuntu-latest - env: - NX_CI_EXECUTION_ENV: 'ubuntu-latest' - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install - uses: ./.github/actions/prepare-install - with: - node-version: ${{ env.PRIMARY_NODE_VERSION }} - - run: yarn nx run generate-configs - - run: git status --porcelain - - if: failure() - run: echo "Outdated result detected from yarn generate-configs. Please check in any file changes." - - lint_without_build: - name: Lint without build - environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job - needs: [install] - runs-on: ubuntu-latest - strategy: - matrix: - lint-task: ['check-spelling', 'check-format', 'lint-markdown'] - env: - NX_CI_EXECUTION_ENV: 'ubuntu-latest' - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install - uses: ./.github/actions/prepare-install - with: - node-version: ${{ env.PRIMARY_NODE_VERSION }} - - - name: Run Check - run: yarn ${{ matrix.lint-task }} - - lint_with_build: - name: Lint with build - environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job - # because we lint with our own tooling, we need to build - needs: [build] - runs-on: ubuntu-latest - strategy: - matrix: - lint-task: ['lint', 'typecheck', 'knip'] - env: - NX_CI_EXECUTION_ENV: 'ubuntu-latest' - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install - uses: ./.github/actions/prepare-install - with: - node-version: ${{ env.PRIMARY_NODE_VERSION }} - - name: Build - uses: ./.github/actions/prepare-build - - - name: Run Check - run: yarn ${{ matrix.lint-task }} - env: - ESLINT_USE_FLAT_CONFIG: true - - stylelint: - name: Stylelint + linux-main: environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job - needs: [install] runs-on: ubuntu-latest env: NX_CI_EXECUTION_ENV: 'ubuntu-latest' steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install - uses: ./.github/actions/prepare-install - with: - node-version: ${{ env.PRIMARY_NODE_VERSION }} - - name: Run stylelint check - run: yarn stylelint - working-directory: packages/website - - integration_tests: - name: Run integration tests on primary Node.js version - environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job - needs: [build] - runs-on: ubuntu-latest - env: - NX_CI_EXECUTION_ENV: 'ubuntu-latest' - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install - uses: ./.github/actions/prepare-install - with: - node-version: ${{ env.PRIMARY_NODE_VERSION }} - - name: Build - uses: ./.github/actions/prepare-build - - - name: Run integration tests - run: yarn test-integration - env: - CI: true - - unit_tests: - name: Run Unit Tests - environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job - needs: [build] - runs-on: ${{ matrix.os }} - strategy: - matrix: - exclude: - - os: windows-latest - node-version: 18 - os: [ubuntu-latest, windows-latest] - # just run on the oldest and latest supported versions and assume the intermediate versions are good - node-version: [18, 20] - package: - [ - 'ast-spec', - 'eslint-plugin', - 'eslint-plugin-internal', - 'parser', - 'project-service', - 'rule-tester', - 'scope-manager', - 'tsconfig-utils', - 'type-utils', - 'typescript-eslint', - 'typescript-estree', - 'utils', - 'visitor-keys', - ] - env: - NX_CI_EXECUTION_ENV: '${{ matrix.os }} - Node ${{ matrix.node-version }}' - COLLECT_COVERAGE: false - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - name: Install - uses: ./.github/actions/prepare-install + - uses: actions/checkout@v4 with: - node-version: ${{ matrix.node-version }} - - name: Build - uses: ./.github/actions/prepare-build - - # collect coverage on the primary node version - # we don't collect coverage on other node versions so they run faster - - name: Run unit tests with coverage for ${{ matrix.package }} - if: env.PRIMARY_NODE_VERSION == matrix.node-version && matrix.os == 'ubuntu-latest' - run: yarn nx run ${{ matrix.package }}:test -- --coverage - env: - CI: true - - name: Run unit tests for ${{ matrix.package }} - if: env.PRIMARY_NODE_VERSION != matrix.node-version || matrix.os != 'ubuntu-latest' - run: yarn nx test ${{ matrix.package }} - env: - CI: true + filter: tree:0 + fetch-depth: 0 - - name: Store coverage for uploading - if: env.PRIMARY_NODE_VERSION == matrix.node-version && matrix.os == 'ubuntu-latest' - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.package }}-coverage - path: packages/${{ matrix.package }}/coverage/lcov.info - # Sadly 1 day is the minimum - retention-days: 1 + - run: corepack enable - unit_tests_project_service: - name: Run Unit Tests with Project Service - environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job - needs: [build] - runs-on: ubuntu-latest - strategy: - matrix: - package: - ['eslint-plugin', 'eslint-plugin-internal', 'typescript-estree'] - env: - NX_CI_EXECUTION_ENV: 'ubuntu-latest' - COLLECT_COVERAGE: false, - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - name: Install - uses: ./.github/actions/prepare-install - with: - node-version: 18 - - name: Build - uses: ./.github/actions/prepare-build - - name: Run unit tests for ${{ matrix.package }} - run: yarn nx test ${{ matrix.package }} --coverage=false + # Enable task distribution via Nx Cloud + - run: yarn dlx nx-cloud start-ci-run --distribute-on="10 linux-large-js" --stop-agents-after="build,test,lint" --with-env-vars="SKIP_POSTINSTALL,GIT_FETCH_TAGS,HUSKY" env: - CI: true - TYPESCRIPT_ESLINT_PROJECT_SERVICE: true - - upload_coverage: - name: Upload Codecov Coverage - environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job - needs: [unit_tests] - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 + SKIP_POSTINSTALL: 'true' # Skip postinstall scripts on Nx Agents + GIT_FETCH_TAGS: 'true' # Fetch all tags on checkout on Nx Agents + HUSKY: '0' # Do not run husky install on Nx Agents - - name: Download coverage reports - uses: actions/download-artifact@v4 - with: - path: coverage + - uses: nrwl/nx-set-shas@v4 - - name: Publish code coverage report - uses: codecov/codecov-action@v4.6.0 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: coverage/**/lcov.info - flags: unittest - name: codecov - - publish_canary_version: - name: Publish the latest code as a canary version - environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job - runs-on: ubuntu-latest - permissions: - id-token: write - needs: [integration_tests, lint_with_build, lint_without_build, unit_tests] - if: github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main' - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 # we need the tags to be available - - - name: Install - uses: ./.github/actions/prepare-install + - uses: actions/setup-node@v4 with: node-version: ${{ env.PRIMARY_NODE_VERSION }} - registry-url: 'https://registry.npmjs.org' - - - name: Build - uses: ./.github/actions/prepare-build - - - name: Figure out and apply the next canary version - run: npx tsx tools/release/apply-canary-version.mts + cache: 'yarn' - - name: Publish all packages to npm with the canary tag - # NOTE: this needs to be npx, rather than yarn, to make sure the authenticated npm registry is used - run: npx nx release publish --tag canary --verbose + - name: Install dependencies + run: | + yarn install --immutable --inline-builds + yarn check-clean-workspace-after-install env: - NX_CLOUD_DISTRIBUTED_EXECUTION: false - # This secret is only accessible on the GitHub environment "main" - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - NPM_CONFIG_PROVENANCE: true + # CI optimizations. Overrides yarnrc.yml options (or their defaults) in the CI action. + YARN_ENABLE_GLOBAL_CACHE: 'false' # Use local cache folder to keep downloaded archives + YARN_NM_MODE: 'hardlinks-local' # Hardlinks-(local|global) reduces io / node_modules size + YARN_INSTALL_STATE_PATH: .yarn/ci-cache/install-state.gz # Very small speedup when lock does not change + # Other environment variables + HUSKY: '0' # By default do not run HUSKY install + SKIP_POSTINSTALL: 'true' + + # Trigger as many tasks as possible in parallel and let Nx Cloud orchestrate them based on their dependency relationships + - run: | + # Linting (failing on main) + # yarn nx run-many -t lint & + # Build (NOTE: website will be built by the Netlify GitHub App) + yarn nx run-many -t build --exclude=website --exclude=website-eslint & + # Unit tests with Project Service enabled + TYPESCRIPT_ESLINT_PROJECT_SERVICE=true yarn nx run-many -t test --coverage=false --projects eslint-plugin eslint-plugin-internal typescript-estree & + wait diff --git a/.github/workflows/ci__old.yml b/.github/workflows/ci__old.yml new file mode 100644 index 000000000000..7a9928b49eaf --- /dev/null +++ b/.github/workflows/ci__old.yml @@ -0,0 +1,326 @@ +# name: CI + +# on: +# push: +# branches: +# - main +# pull_request: +# branches: +# - '**' +# merge_group: + +# concurrency: +# group: '${{ github.workflow }} - ${{ github.head_ref || github.ref }}' +# cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +# env: +# PRIMARY_NODE_VERSION: 20 +# # Value will be controlled via GitHub environment (called "main") secret, will be read-write for main branch, read-only for other branches +# NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} +# # This increases the verbosity of the logs for everything, including Nx Cloud, but will hopefully surface more info about recent lint failures +# NX_VERBOSE_LOGGING: false + +# defaults: +# run: +# shell: bash + +# # +# # Workflow for how the CI spawns jobs: +# # 1) Run the install and cache the install artefacts +# # 2) Run the build and cache the output +# # - In parallel we also any steps that don't need the build (like prettier) +# # 3) Run the steps that depend on the build +# # + +# permissions: +# contents: read # to fetch code (actions/checkout) + +# jobs: +# install: +# name: Checkout and Install +# environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job +# runs-on: ubuntu-latest +# env: +# NX_CI_EXECUTION_ENV: 'ubuntu-latest' +# steps: +# - name: Checkout +# uses: actions/checkout@v4 +# - name: Install +# uses: ./.github/actions/prepare-install +# with: +# node-version: ${{ env.PRIMARY_NODE_VERSION }} + +# build: +# name: Build All Packages +# environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job +# needs: [install] +# runs-on: ubuntu-latest +# env: +# NX_CI_EXECUTION_ENV: 'ubuntu-latest' +# steps: +# - name: Checkout +# uses: actions/checkout@v4 +# - name: Install +# uses: ./.github/actions/prepare-install +# with: +# node-version: ${{ env.PRIMARY_NODE_VERSION }} +# - name: Build +# uses: ./.github/actions/prepare-build + +# generate_configs: +# name: Generate Configs +# environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job +# needs: [build] +# runs-on: ubuntu-latest +# env: +# NX_CI_EXECUTION_ENV: 'ubuntu-latest' +# steps: +# - name: Checkout +# uses: actions/checkout@v4 +# - name: Install +# uses: ./.github/actions/prepare-install +# with: +# node-version: ${{ env.PRIMARY_NODE_VERSION }} +# - run: yarn nx run generate-configs +# - run: git status --porcelain +# - if: failure() +# run: echo "Outdated result detected from yarn generate-configs. Please check in any file changes." + +# lint_without_build: +# name: Lint without build +# environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job +# needs: [install] +# runs-on: ubuntu-latest +# strategy: +# matrix: +# lint-task: ['check-spelling', 'check-format', 'lint-markdown'] +# env: +# NX_CI_EXECUTION_ENV: 'ubuntu-latest' +# steps: +# - name: Checkout +# uses: actions/checkout@v4 +# - name: Install +# uses: ./.github/actions/prepare-install +# with: +# node-version: ${{ env.PRIMARY_NODE_VERSION }} + +# - name: Run Check +# run: yarn ${{ matrix.lint-task }} + +# lint_with_build: +# name: Lint with build +# environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job +# # because we lint with our own tooling, we need to build +# needs: [build] +# runs-on: ubuntu-latest +# strategy: +# matrix: +# lint-task: ['lint', 'typecheck', 'knip'] +# env: +# NX_CI_EXECUTION_ENV: 'ubuntu-latest' +# steps: +# - name: Checkout +# uses: actions/checkout@v4 +# - name: Install +# uses: ./.github/actions/prepare-install +# with: +# node-version: ${{ env.PRIMARY_NODE_VERSION }} +# - name: Build +# uses: ./.github/actions/prepare-build + +# - name: Run Check +# run: yarn ${{ matrix.lint-task }} +# env: +# ESLINT_USE_FLAT_CONFIG: true + +# stylelint: +# name: Stylelint +# environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job +# needs: [install] +# runs-on: ubuntu-latest +# env: +# NX_CI_EXECUTION_ENV: 'ubuntu-latest' +# steps: +# - name: Checkout +# uses: actions/checkout@v4 +# - name: Install +# uses: ./.github/actions/prepare-install +# with: +# node-version: ${{ env.PRIMARY_NODE_VERSION }} +# - name: Run stylelint check +# run: yarn stylelint +# working-directory: packages/website + +# integration_tests: +# name: Run integration tests on primary Node.js version +# environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job +# needs: [build] +# runs-on: ubuntu-latest +# env: +# NX_CI_EXECUTION_ENV: 'ubuntu-latest' +# steps: +# - name: Checkout +# uses: actions/checkout@v4 +# - name: Install +# uses: ./.github/actions/prepare-install +# with: +# node-version: ${{ env.PRIMARY_NODE_VERSION }} +# - name: Build +# uses: ./.github/actions/prepare-build + +# - name: Run integration tests +# run: yarn test-integration +# env: +# CI: true + +# unit_tests: +# name: Run Unit Tests +# environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job +# needs: [build] +# runs-on: ${{ matrix.os }} +# strategy: +# matrix: +# exclude: +# - os: windows-latest +# node-version: 18 +# os: [ubuntu-latest, windows-latest] +# # just run on the oldest and latest supported versions and assume the intermediate versions are good +# node-version: [18, 20] +# package: +# [ +# 'ast-spec', +# 'eslint-plugin', +# 'eslint-plugin-internal', +# 'parser', +# 'project-service', +# 'rule-tester', +# 'scope-manager', +# 'tsconfig-utils', +# 'type-utils', +# 'typescript-eslint', +# 'typescript-estree', +# 'utils', +# 'visitor-keys', +# ] +# env: +# NX_CI_EXECUTION_ENV: '${{ matrix.os }} - Node ${{ matrix.node-version }}' +# COLLECT_COVERAGE: false +# steps: +# - name: Checkout +# uses: actions/checkout@v4 +# with: +# fetch-depth: 2 +# - name: Install +# uses: ./.github/actions/prepare-install +# with: +# node-version: ${{ matrix.node-version }} +# - name: Build +# uses: ./.github/actions/prepare-build + +# # collect coverage on the primary node version +# # we don't collect coverage on other node versions so they run faster +# - name: Run unit tests with coverage for ${{ matrix.package }} +# if: env.PRIMARY_NODE_VERSION == matrix.node-version && matrix.os == 'ubuntu-latest' +# run: yarn nx run ${{ matrix.package }}:test -- --coverage +# env: +# CI: true +# - name: Run unit tests for ${{ matrix.package }} +# if: env.PRIMARY_NODE_VERSION != matrix.node-version || matrix.os != 'ubuntu-latest' +# run: yarn nx test ${{ matrix.package }} +# env: +# CI: true + +# - name: Store coverage for uploading +# if: env.PRIMARY_NODE_VERSION == matrix.node-version && matrix.os == 'ubuntu-latest' +# uses: actions/upload-artifact@v4 +# with: +# name: ${{ matrix.package }}-coverage +# path: packages/${{ matrix.package }}/coverage/lcov.info +# # Sadly 1 day is the minimum +# retention-days: 1 + +# unit_tests_project_service: +# name: Run Unit Tests with Project Service +# environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job +# needs: [build] +# runs-on: ubuntu-latest +# strategy: +# matrix: +# package: +# ['eslint-plugin', 'eslint-plugin-internal', 'typescript-estree'] +# env: +# NX_CI_EXECUTION_ENV: 'ubuntu-latest' +# COLLECT_COVERAGE: false, +# steps: +# - name: Checkout +# uses: actions/checkout@v4 +# with: +# fetch-depth: 2 +# - name: Install +# uses: ./.github/actions/prepare-install +# with: +# node-version: 18 +# - name: Build +# uses: ./.github/actions/prepare-build +# - name: Run unit tests for ${{ matrix.package }} +# run: yarn nx test ${{ matrix.package }} --coverage=false +# env: +# CI: true +# TYPESCRIPT_ESLINT_PROJECT_SERVICE: true + +# upload_coverage: +# name: Upload Codecov Coverage +# environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job +# needs: [unit_tests] +# runs-on: ubuntu-latest +# steps: +# - name: Checkout +# uses: actions/checkout@v4 + +# - name: Download coverage reports +# uses: actions/download-artifact@v4 +# with: +# path: coverage + +# - name: Publish code coverage report +# uses: codecov/codecov-action@v4.6.0 +# with: +# token: ${{ secrets.CODECOV_TOKEN }} +# files: coverage/**/lcov.info +# flags: unittest +# name: codecov + +# publish_canary_version: +# name: Publish the latest code as a canary version +# environment: ${{ (github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main') && 'main' || '' }} # Have to specify per job +# runs-on: ubuntu-latest +# permissions: +# id-token: write +# needs: [integration_tests, lint_with_build, lint_without_build, unit_tests] +# if: github.repository == 'typescript-eslint/typescript-eslint' && github.ref == 'refs/heads/main' +# steps: +# - name: Checkout +# uses: actions/checkout@v4 +# with: +# fetch-depth: 0 # we need the tags to be available + +# - name: Install +# uses: ./.github/actions/prepare-install +# with: +# node-version: ${{ env.PRIMARY_NODE_VERSION }} +# registry-url: 'https://registry.npmjs.org' + +# - name: Build +# uses: ./.github/actions/prepare-build + +# - name: Figure out and apply the next canary version +# run: npx tsx tools/release/apply-canary-version.mts + +# - name: Publish all packages to npm with the canary tag +# # NOTE: this needs to be npx, rather than yarn, to make sure the authenticated npm registry is used +# run: npx nx release publish --tag canary --verbose +# env: +# NX_CLOUD_DISTRIBUTED_EXECUTION: false +# # This secret is only accessible on the GitHub environment "main" +# NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} +# NPM_CONFIG_PROVENANCE: true