name: release-binaries

on:
  push:
    tags:
      - "v*"
  workflow_dispatch:

permissions:
  contents: write

jobs:
  web:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: npm
          cache-dependency-path: web/package-lock.json
      - name: Build embedded web UI
        working-directory: web
        run: |
          npm ci --no-audit --no-fund
          npm run build
      - name: Upload embedded web UI
        uses: actions/upload-artifact@v4
        with:
          name: web-dist
          path: web/dist
          if-no-files-found: error
          retention-days: 1

  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version-file: go.mod
          cache: true
      - name: Test
        run: go test ./...

  binaries:
    needs: [web, test]
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: linux-amd64
            goarch: amd64
            goarm: ""
            filename: vocat-linux-amd64
          - target: linux-386
            goarch: "386"
            goarm: ""
            filename: vocat-linux-386
          - target: linux-arm64
            goarch: arm64
            goarm: ""
            filename: vocat-linux-arm64
          - target: linux-armv7
            goarch: arm
            goarm: "7"
            filename: vocat-linux-armv7
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version-file: go.mod
          cache: true
      - name: Download embedded web UI
        uses: actions/download-artifact@v4
        with:
          name: web-dist
          path: web/dist
      - name: Build ${{ matrix.target }}
        env:
          GOOS: linux
          GOARCH: ${{ matrix.goarch }}
          GOARM: ${{ matrix.goarm }}
          CGO_ENABLED: "0"
          OUTPUT: dist/${{ matrix.filename }}
          VERSION: ${{ github.ref_name }}
        run: |
          mkdir -p dist
          VERSION="${VERSION#v}"
          BUILD_TIME="$(git show -s --format=%cI HEAD)"
          go build -trimpath \
            -ldflags "-s -w -X vocat/internal/buildinfo.Version=${VERSION} -X vocat/internal/buildinfo.BuildTime=${BUILD_TIME}" \
            -o "$OUTPUT" \
            ./cmd/vocat
          chmod 0755 "$OUTPUT"
      - name: Upload ${{ matrix.target }}
        uses: actions/upload-artifact@v4
        with:
          name: binary-${{ matrix.target }}
          path: dist/${{ matrix.filename }}
          if-no-files-found: error
          retention-days: 1

  github-release:
    if: github.ref_type == 'tag'
    needs: binaries
    runs-on: ubuntu-latest
    env:
      GH_TOKEN: ${{ github.token }}
    steps:
      - name: Download binaries
        uses: actions/download-artifact@v4
        with:
          pattern: binary-*
          path: dist
          merge-multiple: true
      - name: Generate checksums
        working-directory: dist
        run: sha256sum vocat-linux-* | sort > SHA256SUMS
      - name: Create or update GitHub Release
        run: |
          if gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
            gh release upload "$GITHUB_REF_NAME" dist/* --repo "$GITHUB_REPOSITORY" --clobber
          else
            gh release create "$GITHUB_REF_NAME" dist/* \
              --repo "$GITHUB_REPOSITORY" \
              --title "$GITHUB_REF_NAME" \
              --generate-notes \
              --verify-tag
          fi
