name: CI
on: [push, pull_request]

jobs:
  unit-tests:
    name: Unit tests
    strategy:
      matrix:
        os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest, macos-26-intel, windows-11-arm]
        go: ['1.25', '1.26']
    runs-on: ${{ matrix.os }}
    steps:
      - name: Install dependencies on macOS
        run: |
          set -x
          brew install --quiet shellcheck python3 pipx
          # https://pipx.pypa.io/stable/installation/
          pipx ensurepath
          pipx install pyflakes
          shellcheck --version
          pyflakes --version
        if: ${{ runner.os == 'macOS' }}
      - name: Install dependencies on Linux
        run: |
          set -x
          sudo apt-get install -y shellcheck
          pip install pyflakes
          shellcheck --version
          pyflakes --version
        if: ${{ runner.os == 'Linux' }}
      - name: Install dependencies on Windows
        run: |
          winget install --id koalaman.shellcheck --disable-interactivity --accept-package-agreements --accept-source-agreements
          pip install pyflakes
          pyflakes --version
        if: ${{ runner.os == 'Windows' }}
      - uses: actions/checkout@v6
      - uses: actions/setup-go@v6
        with:
          go-version: ${{ matrix.go }}
          check-latest: true
      - run: go test -v -race -coverprofile coverage.txt -covermode=atomic ./...
        # Arm Windows doesn't support -race
        if: ${{ matrix.os != 'windows-11-arm' }}
      - run: go test -v -coverprofile coverage.txt -covermode=atomic ./...
        if: ${{ matrix.os == 'windows-11-arm' }}
      - run: go tool cover -func ./coverage.txt
      # Check build without CGO
      - run: go build ./cmd/actionlint
        env:
          # Note: -race requires cgo
          CGO_ENABLED: 0
      # Set -race for catching data races on dog fooding (#333)
      - run: go build -race ./cmd/actionlint
        if: ${{ matrix.os != 'windows-11-arm' }}
      - name: Dog fooding 🐶
        run: |
          echo "::add-matcher::.github/actionlint-matcher.json"
          ./actionlint -color
      - uses: codecov/codecov-action@v5
        with:
          env_vars: OS
          token: ${{ secrets.CODECOV_TOKEN }}
        env:
          OS: ${{ matrix.os }}
  wasm:
    name: Wasm
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./playground
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-go@v6
        with:
          go-version: '1.26'
          check-latest: true
      - uses: actions/setup-node@v6
        with:
          node-version: "lts/*"
          cache: npm
          cache-dependency-path: ./playground/package-lock.json
      - name: Build playground
        run: make build
      - name: Lint playground
        run: npm run lint
      - name: Run tests for wasm
        run: npm test
  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-go@v6
        with:
          go-version: '1.26'
          check-latest: true
      - name: Install dependencies
        run: |
          sudo apt-get install -y shellcheck
          pip install pyflakes
          shellcheck --version
          pyflakes --version
      - name: Check Go sources are formatted
        run: |
          diffs="$(gofmt -d ./*.go ./cmd/actionlint/*.go ./scripts/*/*.go ./playground/*.go)"
          if [[ "$diffs" != "" ]]; then
            echo "$diffs" >&2
            exit 1
          fi
      - name: Install staticcheck and govulncheck
        run: |
          go install honnef.co/go/tools/cmd/staticcheck@latest
          go install golang.org/x/vuln/cmd/govulncheck@latest
          echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"
      - run: make lint SKIP_GO_GENERATE=true
      - name: Lint bash scripts
        run: shellcheck ./scripts/*.bash ./playground/*.bash
  docker:
    name: Dockerfile
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Build image
        id: image
        uses: docker/build-push-action@v7
        with:
          build-args: |
            GOLANG_VER=1.26
          push: false
      - name: Test Docker image
        run: docker container run
          --mount type=bind,source="$(pwd)",target=/mnt/app
          --workdir /mnt/app
          -- ${{ steps.image.outputs.digest }} -color -verbose
      - name: Lint Dockerfile with hadolint
        run: docker run --rm -i hadolint/hadolint hadolint --ignore DL3018 --strict-labels - < Dockerfile
