# Release workflow for @googleworkspace/cli
#
# Triggered by pushing a semver tag (e.g. v0.22.3).
# Builds platform binaries, creates a GitHub Release, publishes to npm and crates.io.

name: Release
permissions:
  contents: write
  attestations: write
  id-token: write

on:
  pull_request:
  push:
    tags:
      - 'v[0-9]+.[0-9]+.[0-9]+*'

env:
  CARGO_TERM_COLOR: always

jobs:
  plan:
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.meta.outputs.version }}
      prerelease: ${{ steps.meta.outputs.prerelease }}
      publishing: ${{ github.ref_type == 'tag' }}
    steps:
      - id: meta
        run: |
          TAG="${GITHUB_REF_NAME}"
          VERSION="${TAG#v}"
          echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
          if [[ "$VERSION" == *-* ]]; then
            echo "prerelease=true" >> "$GITHUB_OUTPUT"
          else
            echo "prerelease=false" >> "$GITHUB_OUTPUT"
          fi

  build:
    needs: plan
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: aarch64-apple-darwin
            runner: macos-latest
            archive: tar.gz
          - target: x86_64-apple-darwin
            runner: macos-latest
            archive: tar.gz
          - target: aarch64-unknown-linux-gnu
            runner: ubuntu-latest
            archive: tar.gz
            cross: true
          - target: aarch64-unknown-linux-musl
            runner: ubuntu-latest
            archive: tar.gz
            cross: true
          - target: x86_64-unknown-linux-gnu
            runner: ubuntu-latest
            archive: tar.gz
          - target: x86_64-unknown-linux-musl
            runner: ubuntu-latest
            archive: tar.gz
            cross: true
          - target: x86_64-pc-windows-msvc
            runner: windows-latest
            archive: zip
    runs-on: ${{ matrix.runner }}
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

      - uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
        with:
          targets: ${{ matrix.target }}

      - name: Install cross
        if: matrix.cross
        run: cargo install cross --git https://github.com/cross-rs/cross --tag v0.2.5

      - name: Build
        run: |
          if [ "${{ matrix.cross }}" = "true" ]; then
            cross build --release --target ${{ matrix.target }} --locked
          else
            cargo build --release --target ${{ matrix.target }} --locked
          fi
        shell: bash

      - name: Package (unix)
        if: matrix.archive == 'tar.gz'
        run: |
          ARTIFACT="google-workspace-cli-${{ matrix.target }}"
          mkdir -p staging
          cp "target/${{ matrix.target }}/release/gws" staging/
          cp LICENSE README.md CHANGELOG.md staging/
          tar czf "${ARTIFACT}.tar.gz" -C staging .
          shasum -a 256 "${ARTIFACT}.tar.gz" > "${ARTIFACT}.tar.gz.sha256"
        shell: bash

      - name: Package (windows)
        if: matrix.archive == 'zip'
        run: |
          $ARTIFACT = "google-workspace-cli-${{ matrix.target }}"
          New-Item -ItemType Directory -Path $ARTIFACT
          Copy-Item "target/${{ matrix.target }}/release/gws.exe" "$ARTIFACT/"
          Copy-Item LICENSE, README.md, CHANGELOG.md "$ARTIFACT/"
          Compress-Archive -Path "$ARTIFACT/*" -DestinationPath "$ARTIFACT.zip"
          (Get-FileHash "$ARTIFACT.zip" -Algorithm SHA256).Hash.ToLower() + "  $ARTIFACT.zip" | Out-File -Encoding ascii "$ARTIFACT.zip.sha256"
        shell: pwsh

      - name: Attest
        if: github.ref_type == 'tag'
        uses: actions/attest-build-provenance@43d14bc2b83dec42d39ecae14e916627a18bb661 # v3
        with:
          subject-path: google-workspace-cli-${{ matrix.target }}.${{ matrix.archive }}

      - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
        with:
          name: binary-${{ matrix.target }}
          path: |
            google-workspace-cli-${{ matrix.target }}.${{ matrix.archive }}
            google-workspace-cli-${{ matrix.target }}.${{ matrix.archive }}.sha256

  release:
    needs: [plan, build]
    if: github.ref_type == 'tag'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

      - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
        with:
          pattern: binary-*
          path: artifacts/
          merge-multiple: true

      - name: Create GitHub Release
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          PRERELEASE_FLAG=""
          if [ "${{ needs.plan.outputs.prerelease }}" = "true" ]; then
            PRERELEASE_FLAG="--prerelease"
          fi
          
          NOTES="## Installation
          
          Download the archive for your OS and architecture from the assets below.
          
          ### Linux / macOS
          
          Replace \`<target>\` with your platform (e.g., \`aarch64-apple-darwin\` or \`x86_64-unknown-linux-gnu\`).
          
          \`\`\`bash
          # 1. Download the archive and its checksum
          curl -sLO https://github.com/googleworkspace/cli/releases/download/${{ github.ref_name }}/google-workspace-cli-<target>.tar.gz
          curl -sLO https://github.com/googleworkspace/cli/releases/download/${{ github.ref_name }}/google-workspace-cli-<target>.tar.gz.sha256
          
          # 2. Verify the checksum
          shasum -a 256 -c google-workspace-cli-<target>.tar.gz.sha256
          
          # 3. Extract and install
          tar -xzf google-workspace-cli-<target>.tar.gz
          chmod +x gws
          sudo mv gws /usr/local/bin/
          \`\`\`
          
          ### Windows
          
          1. Download \`google-workspace-cli-x86_64-pc-windows-msvc.zip\` and its \`.sha256\` file
          2. Verify the checksum (e.g., using PowerShell \`Get-FileHash\`)
          3. Extract the archive and move \`gws.exe\` to a directory included in your system \`PATH\`.
          
          ---
          "

          gh release create "${{ github.ref_name }}" \
            --target "${{ github.sha }}" \
            --title "${{ github.ref_name }}" \
            --notes "$NOTES" \
            --generate-notes \
            $PRERELEASE_FLAG \
            artifacts/*

  publish-npm:
    needs: [plan, release]
    runs-on: ubuntu-latest
    if: ${{ needs.plan.outputs.publishing == 'true' && needs.plan.outputs.prerelease == 'false' }}
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

      - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
        with:
          node-version: '20.x'
          registry-url: 'https://wombat-dressing-room.appspot.com'

      - name: Publish to npm
        working-directory: npm
        run: npm publish --access public
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

  publish-cargo:
    needs: [plan, release]
    runs-on: ubuntu-latest
    if: ${{ needs.plan.outputs.publishing == 'true' && needs.plan.outputs.prerelease == 'false' }}
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

      - uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable

      # Publish library crate first (CLI depends on it)
      - name: Publish google-workspace
        run: cargo publish --package google-workspace
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

      # Wait for crates.io to index the library crate
      - name: Wait for crates.io index
        run: sleep 30

      - name: Publish google-workspace-cli
        run: cargo publish --package google-workspace-cli
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
