# .github/workflows/release.yml

# Need to write to repo contents to upload the app to GitHub Release
# See: https://www.electronforge.io/config/publishers/github#authentication
permissions:
  contents: write

name: Release app
on:
  workflow_dispatch:
jobs:
  build:
    environment: release
    strategy:
      # Continue building other platforms even if one fails
      fail-fast: false
      # Uncomment max-parallel to prevent race condition (where multiple releases are
      # created concurrently). Typically though, we'll create a release manually ahead of time
      # which prevents the race.
      # max-parallel: 1
      matrix:
        os: [
            { name: "windows", image: "windows-latest" },
            # See https://github.com/dyad-sh/dyad/issues/96
            { name: "linux", image: "ubuntu-22.04" },
            { name: "macos-intel", image: "macos-15-intel" },
            { name: "macos", image: "macos-latest" },
          ]
    runs-on: ${{ matrix.os.image }}
    steps:
      - name: Github checkout
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
      - name: Use Node.js
        uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
        with:
          node-version: 20
      - name: Install npm 11.8.0
        run: npm install -g npm@11.8.0
      - run: npm ci
        env:
          # Required for @vscode/ripgrep to download binaries without hitting GitHub API rate limits
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: add macos cert
        if: contains(matrix.os.name, 'macos')
        env:
          MACOS_CERT_P12: ${{ secrets.MACOS_CERT_P12 }}
          MACOS_CERT_PASSWORD: ${{ secrets.MACOS_CERT_PASSWORD }}
        run: chmod +x tools/add-macos-cert.sh && . ./tools/add-macos-cert.sh
      # Windows only
      - name: Install Azure Trusted Signing
        if: contains(matrix.os.name, 'windows')
        shell: powershell
        run: |
          winget install -e --id Microsoft.Azure.TrustedSigningClientTools --source winget --accept-source-agreements --accept-package-agreements

          $known = Join-Path $env:LOCALAPPDATA "Microsoft\MicrosoftTrustedSigningClientTools\Azure.CodeSigning.Dlib.dll"
          $dllPath = $null

          if (Test-Path $known) {
            $dllPath = $known
          } else {
            $searchPaths = @(
              (Join-Path $env:LOCALAPPDATA "Microsoft\MicrosoftTrustedSigningClientTools"),
              "C:\Program Files",
              "$env:LOCALAPPDATA",
              "$env:LOCALAPPDATA\Microsoft\WinGet\Packages",
              "C:\Users\runneradmin\AppData\Local\Microsoft\WinGet\Packages"
            )

            foreach ($searchPath in $searchPaths) {
              if (Test-Path $searchPath) {
                Write-Host "Searching in: $searchPath"
                $found = Get-ChildItem -Path $searchPath -Recurse -Filter "Azure.CodeSigning.Dlib.dll" -ErrorAction SilentlyContinue |
                  Sort-Object { $_.FullName -notlike "*x64*" } |
                  Select-Object -First 1 -ExpandProperty FullName
                if ($found) { $dllPath = $found; break }
              }
            }
          }

          if ($dllPath) {
            Write-Host "Found DLL at: $dllPath"
            "AZURE_CODE_SIGNING_DLIB=$dllPath" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
          } else {
            Write-Error "Could not find Azure.CodeSigning.Dlib.dll"
            exit 1
          }

      - name: Find Windows 11 SDK SignTool
        if: contains(matrix.os.name, 'windows')
        shell: powershell
        run: |
          $sdkPath = "C:\Program Files (x86)\Windows Kits\10\bin"
          $signTool = Get-ChildItem -Path $sdkPath -Recurse -Filter "signtool.exe" |
            Where-Object { $_.FullName -match "\\x64\\" } |
            Sort-Object { [version]($_.FullName -replace '.*\\(\d+\.\d+\.\d+\.\d+)\\.*', '$1') } -Descending |
            Select-Object -First 1

          if ($signTool) {
            Write-Host "Found SignTool at: $($signTool.FullName)"
            "SIGNTOOL_PATH=$($signTool.FullName)" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
          } else {
            Write-Error "Could not find x64 signtool.exe"
            exit 1
          }

      - name: Create Azure signing metadata
        if: contains(matrix.os.name, 'windows')
        shell: pwsh
        run: |
          @'
          {
            "Endpoint": "https://eus.codesigning.azure.net/",
            "CodeSigningAccountName": "dyad",
            "CertificateProfileName": "dyad-tech"
          }
          '@ | Out-File -Encoding utf8 signing-metadata.json

          echo "AZURE_METADATA_JSON=$PWD\signing-metadata.json" >> $env:GITHUB_ENV

      # - name: Set up certificate
      #   if: contains(matrix.os.name, 'windows')
      #   run: |
      #     echo "${{ secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
      #   shell: bash
      # - name: Set variables
      #   if: contains(matrix.os.name, 'windows')
      #   id: variables
      #   run: |
      #     echo "SM_HOST=${{ secrets.SM_HOST }}" >> "$GITHUB_ENV"
      #     echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> "$GITHUB_ENV"
      #     echo "SM_CLIENT_CERT_FILE=D:\\Certificate_pkcs12.p12" >> "$GITHUB_ENV"
      #     echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> "$GITHUB_ENV"
      #   shell: bash
      # - name: Code signing with Software Trust Manager
      #   if: contains(matrix.os.name, 'windows')
      #   uses: digicert/ssm-code-signing@v1.1.0
      # - name: Sync certificate (Windows)
      #   if: contains(matrix.os.name, 'windows')
      #   run: |
      #     smctl windows certsync --keypair-alias=${{ secrets.DIGICERT_KEYPAIR_ALIAS }}
      #   shell: bash
      # Publish (all platforms)
      - name: Publish app
        uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
        with:
          timeout_minutes: 30
          max_attempts: 3
          command: ./node_modules/.bin/electron-forge publish
        env:
          DEBUG: "@electron/*,electron-forge:*,electron-osx-sign*,electron-notarize*,electron-windows-installer:main,electron-windows-sign"
          NODE_OPTIONS: "--max-old-space-size=4096"
          # SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.SM_CODE_SIGNING_CERT_SHA1_HASH }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
          APPLE_ID: ${{ secrets.APPLE_ID }}
          APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
          AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
          AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
          AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
          WINDOWS_SIGN: ${{ contains(matrix.os.name, 'windows') && 'true' || '' }}

  verify-assets:
    name: Verify Release Assets
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Github checkout
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
      - name: Use Node.js
        uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
        with:
          node-version: 20
      - name: Verify all release assets are uploaded
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: node scripts/verify-release-assets.js
