name: Build Windows

on:
  workflow_dispatch:

permissions:
  # Azure Trusted Signing uses OIDC federated credentials from GitHub.
  id-token: write
  contents: read

jobs:
  build:
    runs-on: windows-latest
    defaults:
      run:
        working-directory: js/desktop
    env:
      APP_ENV: prod
      AZURE_TENANT_ID: ${{ vars.AZURE_TENANT_ID }}
      AZURE_CLIENT_ID: ${{ vars.AZURE_CLIENT_ID }}

    steps:
      - uses: actions/checkout@v4

      - name: Enable corepack
        run: corepack enable
        shell: pwsh
        working-directory: .

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: yarn
          cache-dependency-path: js/desktop/yarn.lock

      - name: Install dependencies
        run: yarn install --frozen-lockfile --network-timeout 600000

      - name: Azure login (OIDC)
        uses: azure/login@v2
        with:
          tenant-id: ${{ vars.AZURE_TENANT_ID }}
          client-id: ${{ vars.AZURE_CLIENT_ID }}
          allow-no-subscriptions: true

      - name: Install Trusted Signing client dlib
        shell: pwsh
        working-directory: .
        run: |
          nuget install Microsoft.Trusted.Signing.Client -Version 1.0.60 -OutputDirectory $env:RUNNER_TEMP\trusted-signing -ExcludeVersion
          $dlib = Join-Path $env:RUNNER_TEMP "trusted-signing\Microsoft.Trusted.Signing.Client\bin\x64\Azure.CodeSigning.Dlib.dll"
          if (-not (Test-Path $dlib)) { throw "Dlib not found at $dlib" }
          "AZURE_DLIB_PATH=$dlib" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
          "AZURE_METADATA_JSON_PATH=$env:GITHUB_WORKSPACE\js\desktop\signing-metadata.json" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8

      - name: Locate signtool.exe
        shell: pwsh
        working-directory: .
        run: |
          $signtool = Get-ChildItem "C:\Program Files (x86)\Windows Kits\10\bin\*\x64\signtool.exe" -ErrorAction SilentlyContinue |
            Sort-Object FullName -Descending |
            Select-Object -First 1
          if (-not $signtool) { throw "signtool.exe not found in Windows Kits" }
          "SIGNTOOL_PATH=$($signtool.FullName)" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8

      - name: Authenticate to Google Cloud
        uses: google-github-actions/auth@v2
        with:
          credentials_json: ${{ secrets.PROD_GKE_SERVICE_ACCOUNT_KEY }}

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

      - name: Publish signed installer (x64)
        run: yarn publish:win

      - name: Invalidate RELEASES cache
        shell: pwsh
        working-directory: .
        run: gsutil setmeta -h "Cache-Control:no-cache, no-store, must-revalidate" gs://flowy-releases/llink/win32/x64/RELEASES

      - name: Upload installers (debug artifact)
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: flowy-llink-windows-signed
          path: js/desktop/out/make/**/*
          if-no-files-found: warn

      # When Squirrel reports a generic "Failed to sign", the real error from
      # @electron/windows-sign is written to this log by the fake signtool stub.
      - name: Upload signing log (on failure)
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: electron-windows-sign-log
          path: js/desktop/node_modules/electron-winstaller/vendor/electron-windows-sign.log
          if-no-files-found: ignore
