on:
  push:
    branches:
      - master
      - release
  pull_request:
  workflow_dispatch:
name: ci

jobs:
  unit-test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: [20, 22, 24]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: node --version
      # Note: --ignore-scripts skips an otherwise unnecessary Auspice build, but
      # also skips life cycle scripts for dependencies. If the job fails here,
      # try removing this flag.
      - run: npm ci --loglevel verbose --ignore-scripts
      - run: npm test

  build-and-smoke-test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: [20, 22, 24]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      # Build is implicit with the "prepare" life cycle script
      - run: npm ci --loglevel verbose
      - run: npm run get-data
      - run: npx playwright install chromium
      - run: npm run smoke-test

  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 24
      # Note: --ignore-scripts skips an otherwise unnecessary Auspice build, but
      # also skips life cycle scripts for dependencies. If the job fails here,
      # try removing this flag.
      - run: npm ci --loglevel verbose --ignore-scripts
      - run: npm run lint

  type-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 24
      # Note: --ignore-scripts skips an otherwise unnecessary Auspice build, but
      # also skips life cycle scripts for dependencies. If the job fails here,
      # try removing this flag.
      - run: npm ci --loglevel verbose --ignore-scripts
      - run: npm run type-check

  bundlesize:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 24
      - run: npm ci --loglevel verbose
      - run: npx --yes bundlesize

  # Ensure package-lock.json is synced with package.json.
  check-lockfile:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          # Node.js version doesn't matter; npm version is more important when
          # it comes to lockfiles.
          node-version: 24
      - run: npm install -g npm@11
      - run: npm install --ignore-scripts
      - run: |
          if git diff --exit-code package-lock.json; then
              echo "package-lock.json is up to date." >&2
          else
              echo "package-lock.json needs updating. Please run 'npm install --ignore-scripts' locally and commit the changes." >&2
              exit 1
          fi

  publish:
    if: ${{ github.ref == 'refs/heads/release' }}
    needs: [build-and-smoke-test, unit-test, lint, type-check, check-lockfile]
    runs-on: ubuntu-latest
    permissions:
      id-token: write  # Required for OIDC
      contents: read
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 24
          registry-url: https://registry.npmjs.org/
      - run: node --version
      - run: npm ci --loglevel verbose
      - run: npm publish

  rebuild-docker-image:
    needs: [publish]
    runs-on: ubuntu-latest
    steps:
    - run: gh workflow run ci.yml --repo nextstrain/docker-base
      env:
        GITHUB_TOKEN: ${{ secrets.GH_TOKEN_NEXTSTRAIN_BOT_WORKFLOW_DISPATCH }}
