name: Cog HA-Matter Release

# ADR-116 P8 — Build + sign + bundle the cog-ha-matter cog on a
# version tag. Upload to gs://cognitum-apps/ runs only when the
# GCP_CREDENTIALS + COGNITUM_OWNER_SIGNING_KEY secrets are set, so
# this workflow is safe to merge before the production credentials
# land — it'll bundle release artifacts to the workflow run page
# either way.

on:
  push:
    tags:
      - 'cog-ha-matter-v*'
  workflow_dispatch:
    inputs:
      dry_run:
        description: 'Build + sign + bundle but skip GCS upload'
        required: false
        default: 'true'

env:
  CARGO_TERM_COLOR: always
  CRATE: cog-ha-matter

jobs:
  build-x86_64:
    name: Build x86_64
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: x86_64-unknown-linux-gnu

      - name: Cache cargo registry
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            v2/target
          key: cog-ha-matter-x86_64-${{ hashFiles('v2/Cargo.lock') }}

      - name: Build release binary
        working-directory: v2/crates/cog-ha-matter/cog
        run: make build-x86_64

      - name: Compute SHA-256
        working-directory: v2/crates/cog-ha-matter/cog
        run: make sign-x86_64

      - name: Sign with Ed25519 (gated)
        if: ${{ env.SIGNING_KEY != '' }}
        env:
          SIGNING_KEY: ${{ secrets.COGNITUM_OWNER_SIGNING_KEY }}
        working-directory: v2/crates/cog-ha-matter/cog
        run: |
          printf '%s' "$SIGNING_KEY" \
            | openssl pkeyutl -sign -inkey /dev/stdin -rawin \
                -in dist/cog-ha-matter-x86_64.sha256 \
            | base64 -w0 > dist/cog-ha-matter-x86_64.sig
          echo "Signed cog-ha-matter-x86_64 ($(wc -c < dist/cog-ha-matter-x86_64.sig) bytes)"

      - name: Upload workflow artifact
        uses: actions/upload-artifact@v4
        with:
          name: cog-ha-matter-x86_64
          path: |
            v2/crates/cog-ha-matter/cog/dist/cog-ha-matter-x86_64
            v2/crates/cog-ha-matter/cog/dist/cog-ha-matter-x86_64.sha256
            v2/crates/cog-ha-matter/cog/dist/cog-ha-matter-x86_64.sig
          if-no-files-found: warn

  build-arm:
    name: Build aarch64 (arm)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: aarch64-unknown-linux-gnu

      - name: Install cross-compiler
        run: |
          sudo apt-get update
          sudo apt-get install -y gcc-aarch64-linux-gnu

      - name: Cache cargo registry
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            v2/target
          key: cog-ha-matter-arm-${{ hashFiles('v2/Cargo.lock') }}

      - name: Build release binary
        working-directory: v2
        env:
          CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
        run: |
          cargo build -p cog-ha-matter --release --target aarch64-unknown-linux-gnu
          mkdir -p crates/cog-ha-matter/cog/dist
          cp target/aarch64-unknown-linux-gnu/release/cog-ha-matter \
             crates/cog-ha-matter/cog/dist/cog-ha-matter-arm
          # ^ matches Makefile's `dist/$(CRATE)-arm` so `make sign-arm` finds it

      - name: Compute SHA-256
        working-directory: v2/crates/cog-ha-matter/cog
        run: make sign-arm

      - name: Sign with Ed25519 (gated)
        if: ${{ env.SIGNING_KEY != '' }}
        env:
          SIGNING_KEY: ${{ secrets.COGNITUM_OWNER_SIGNING_KEY }}
        working-directory: v2/crates/cog-ha-matter/cog
        run: |
          printf '%s' "$SIGNING_KEY" \
            | openssl pkeyutl -sign -inkey /dev/stdin -rawin \
                -in dist/cog-ha-matter-arm.sha256 \
            | base64 -w0 > dist/cog-ha-matter-arm.sig
          echo "Signed cog-ha-matter-arm ($(wc -c < dist/cog-ha-matter-arm.sig) bytes)"

      - name: Upload workflow artifact
        uses: actions/upload-artifact@v4
        with:
          name: cog-ha-matter-arm
          path: |
            v2/crates/cog-ha-matter/cog/dist/cog-ha-matter-arm
            v2/crates/cog-ha-matter/cog/dist/cog-ha-matter-arm.sha256
            v2/crates/cog-ha-matter/cog/dist/cog-ha-matter-arm.sig
          if-no-files-found: warn

  publish-gcs:
    name: Upload to GCS (gated)
    needs: [build-x86_64, build-arm]
    runs-on: ubuntu-latest
    # Skip on dry-run dispatch; skip on tags when GCP_CREDENTIALS unset.
    if: >
      github.event_name == 'push' &&
      vars.HAS_GCP_CREDENTIALS == 'true'
    steps:
      - uses: actions/checkout@v4

      - name: Download x86_64 artifact
        uses: actions/download-artifact@v4
        with:
          name: cog-ha-matter-x86_64
          path: dist/

      - name: Download arm artifact
        uses: actions/download-artifact@v4
        with:
          name: cog-ha-matter-arm
          path: dist/

      - name: Auth to GCP
        uses: google-github-actions/auth@v2
        with:
          credentials_json: ${{ secrets.GCP_CREDENTIALS }}

      - name: Set up gcloud
        uses: google-github-actions/setup-gcloud@v2

      - name: Upload binaries + sidecars
        run: |
          gsutil cp dist/cog-ha-matter-x86_64       gs://cognitum-apps/cogs/x86_64/cog-ha-matter-x86_64
          gsutil cp dist/cog-ha-matter-x86_64.sha256 gs://cognitum-apps/cogs/x86_64/cog-ha-matter-x86_64.sha256
          gsutil cp dist/cog-ha-matter-arm           gs://cognitum-apps/cogs/arm/cog-ha-matter-arm
          gsutil cp dist/cog-ha-matter-arm.sha256    gs://cognitum-apps/cogs/arm/cog-ha-matter-arm.sha256
          if [ -f dist/cog-ha-matter-x86_64.sig ]; then
            gsutil cp dist/cog-ha-matter-x86_64.sig gs://cognitum-apps/cogs/x86_64/cog-ha-matter-x86_64.sig
          fi
          if [ -f dist/cog-ha-matter-arm.sig ]; then
            gsutil cp dist/cog-ha-matter-arm.sig    gs://cognitum-apps/cogs/arm/cog-ha-matter-arm.sig
          fi

      - name: Print app-registry.json snippet for the cognitum-one PR
        run: |
          for arch in arm x86_64; do
            sha=$(cat dist/cog-cog-ha-matter-$arch.sha256)
            sig=$([ -f dist/cog-cog-ha-matter-$arch.sig ] && cat dist/cog-cog-ha-matter-$arch.sig || echo "")
            cat <<EOF
          --- $arch ---
          {
            "id": "ha-matter",
            "version": "${GITHUB_REF_NAME#cog-ha-matter-v}",
            "binary_url": "https://storage.googleapis.com/cognitum-apps/cogs/$arch/cog-cog-ha-matter-$arch",
            "binary_sha256": "$sha",
            "binary_signature": "$sig",
            "description": "Home Assistant + Matter Cognitum Seed cog (mDNS + witness chain)",
            "min_seed_version": "0.6.0",
            "installable_on": ["$arch"]
          }
          EOF
          done
