name: Publish

on:
  push:
    tags:
      - v*

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      deployments: write
      id-token: write
      packages: write
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v7
        with:
          node-version: 22

      - run: npm ci
      - run: npm test

      - name: Create GitHub Deployment
        id: deployment
        uses: actions/github-script@v7
        with:
          script: |
            const { data } = await github.rest.repos.createDeployment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              ref: context.sha,
              environment: "npm",
              auto_merge: false,
              required_contexts: [],
              description: `Publish npm package v${context.ref.split("/").pop()}`,
            });
            core.setOutput("deployment_id", data.id);

      - name: Set Deployment Status (in_progress)
        uses: actions/github-script@v7
        with:
          script: |
            await github.rest.repos.createDeploymentStatus({
              owner: context.repo.owner,
              repo: context.repo.repo,
              deployment_id: ${{ steps.deployment.outputs.deployment_id }},
              state: "in_progress",
              environment: "npm",
              environment_url: "https://www.npmjs.com/package/eckra",
            });

      - name: Publish to npm
        run: |
          npm install -g npm@latest
          npm publish --provenance --access public

      - name: Publish to GitHub Packages
        run: |
          npm config set registry https://npm.pkg.github.com
          npm config set //npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}
          jq '.name = "@sudoeren/eckra" | .publishConfig = { "registry": "https://npm.pkg.github.com" }' package.json > package-gh.json
          mv package.json package.bak
          mv package-gh.json package.json
          npm publish
          mv package.bak package.json
        env:
          NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Generate release notes
        id: notes
        run: |
          body=$(node scripts/release-notes.js)
          echo "body<<EOF" >> $GITHUB_OUTPUT
          echo "$body" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - uses: softprops/action-gh-release@v3
        with:
          body: ${{ steps.notes.outputs.body }}

      - name: Set Deployment Status (success)
        if: success()
        uses: actions/github-script@v7
        with:
          script: |
            await github.rest.repos.createDeploymentStatus({
              owner: context.repo.owner,
              repo: context.repo.repo,
              deployment_id: ${{ steps.deployment.outputs.deployment_id }},
              state: "success",
              environment: "npm",
              environment_url: "https://www.npmjs.com/package/eckra",
              description: "Published to npm",
            });

      - name: Set Deployment Status (failure)
        if: failure() && steps.deployment.outputs.deployment_id != ''
        uses: actions/github-script@v7
        with:
          script: |
            await github.rest.repos.createDeploymentStatus({
              owner: context.repo.owner,
              repo: context.repo.repo,
              deployment_id: ${{ steps.deployment.outputs.deployment_id }},
              state: "failure",
              environment: "npm",
              environment_url: "https://www.npmjs.com/package/eckra",
              description: "Publish failed",
            });

  # Built on macOS, where pkg can ad-hoc sign the Apple Silicon binaries
  # (unsigned arm64 binaries are killed by the kernel). pkg cross-compiles
  # the Linux/Windows targets too, so a single job produces every asset.
  binaries:
    needs: publish
    runs-on: macos-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v7
        with:
          node-version: 22
          cache: npm
      - name: Cache pkg base binaries
        uses: actions/cache@v6
        with:
          path: ~/.pkg-cache
          key: pkg-cache-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
      - run: npm ci
      - name: Build standalone binaries
        run: npm run build:binaries:all
      - name: Generate checksums
        run: cd dist && shasum -a 256 eckra-linux-x64 eckra-linux-arm64 eckra-win-x64.exe eckra-macos-x64 eckra-macos-arm64 > SHA256SUMS
      - name: Update Scoop manifest
        run: node scripts/update-scoop.mjs
      - name: Update Homebrew formula
        run: node scripts/update-homebrew.mjs
      - name: Commit packaging manifests
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add packaging/ Formula/
          if git diff --cached --quiet; then
            echo "No packaging changes to commit"
          else
            git commit -m "chore: update packaging manifests for ${{ github.ref_name }}"
            git push origin HEAD:master
          fi
      - name: Upload release assets
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh release upload "${{ github.ref_name }}" \
            dist/eckra-linux-x64 \
            dist/eckra-linux-arm64 \
            dist/eckra-win-x64.exe \
            dist/eckra-macos-x64 \
            dist/eckra-macos-arm64 \
            dist/SHA256SUMS \
            --clobber
