name: Run bouf Packaging
description: Generates signed OBS install files
inputs:
  gcpWorkloadIdentityProvider:
    description: GCP Identity Provider Pool ID
    required: true
  gcpServiceAccountName:
    description: Google service account name
    required: true
  version:
    description: Version string (e.g., 30.0.0-rc1)
    required: true
  channel:
    description: Update channel
    required: false
    default: 'stable'
  architecture:
    description: OBS build architecture
    required: false
    default: 'x64'

runs:
  using: composite
  steps:
    - name: Extract Artifact
      shell: pwsh
      run: |
        Expand-Archive -Path build\*.zip -DestinationPath build
        Remove-Item build\*.zip

    - name: Setup bouf
      shell: pwsh
      env:
        BOUF_TAG: 'v0.6.5'
        BOUF_HASH: '2e16d5116415579b5dd8cd68b3fe6edaa7513938427567121942f592292605d5'
        BOUF_NSIS_HASH: 'e323043627cfeebd237d306afc001c8c36a3c37f6ecef2b349a19a3209ae3450'
        GH_TOKEN: ${{ github.token }}
      run: |
        # Download bouf release
        . ${env:GITHUB_ACTION_PATH}\Ensure-Location.ps1
        . ${env:GITHUB_ACTION_PATH}\Invoke-External.ps1
        Ensure-Location bouf
        $windows_zip = "bouf-windows-${env:BOUF_TAG}.zip"
        $nsis_zip = "bouf-nsis-${env:BOUF_TAG}.zip"
        Invoke-External gh release download "${env:BOUF_TAG}" -R "obsproject/bouf" -p $windows_zip -p $nsis_zip
        
        if ((Get-FileHash $windows_zip -Algorithm SHA256).Hash -ne "${env:BOUF_HASH}") {
          throw "bouf hash does not match."
        }
        if ((Get-FileHash $nsis_zip -Algorithm SHA256).Hash -ne "${env:BOUF_NSIS_HASH}") {
          throw "NSIS package hash does not match."
        }
        
        Expand-Archive -Path $windows_zip -DestinationPath bin
        Expand-Archive -Path $nsis_zip -DestinationPath nsis

    - name: Setup Google CNG Provider
      shell: pwsh
      env:
        CNG_TAG: 'cng-v1.1'
        GH_TOKEN: ${{ github.token }}
      run: |
        # Download Google CNG provider release from github
        . ${env:GITHUB_ACTION_PATH}\Ensure-Location.ps1
        . ${env:GITHUB_ACTION_PATH}\Invoke-External.ps1
        Ensure-Location gcng
        
        Invoke-External gh release download "${env:CNG_TAG}" -R "GoogleCloudPlatform/kms-integrations" -p "*amd64.zip"
        Expand-Archive -Path *.zip
        $sigPath = Get-ChildItem *.sig -Recurse
        $msiPath = Get-ChildItem *.msi -Recurse
        # Verify digital signature against Google's public key
        Invoke-External openssl dgst -sha384 -verify "${env:GITHUB_ACTION_PATH}/cng-release-signing-key.pem" -signature $sigPath $msiPath
        # Finally, install the CNG provider
        Invoke-External msiexec /i $msiPath /qn /norestart

    - name: Install rclone
      shell: pwsh
      run: |
        choco install rclone --version=1.69.3 -y --no-progress
    
    - name: 'Authenticate to Google Cloud'
      uses: 'google-github-actions/auth@5a50e581162a13f4baa8916d01180d2acbc04363'
      with:
        workload_identity_provider: ${{ inputs.gcpWorkloadIdentityProvider }}
        service_account: ${{ inputs.gcpServiceAccountName }}

    - name: Download Previous Build
      shell: pwsh
      env:
        RCLONE_GCS_ENV_AUTH: 'true'
      run: |
        . ${env:GITHUB_ACTION_PATH}\Ensure-Location.ps1
        Ensure-Location "${{ github.workspace }}/old_builds"
        rclone copy --transfers 100 ":gcs:obs-latest/${{ inputs.architecture }}/${{ inputs.channel }}" .

    - name: Sign Game Capture with RSA cert
      shell: pwsh
      run: |
        . ${env:GITHUB_ACTION_PATH}\Invoke-External.ps1
        $SignToolExe = "C:\Program Files (x86)\Windows Kits\10\App Certification Kit\signtool.exe"
        $signArgs = @(
           "sign"
           "/fd",   "sha256"
           "/t",    "http://timestamp.digicert.com"
           "/f",    "repo/.github/actions/windows-signing/prod-gc.crt"
           "/csp",  "Google Cloud KMS Provider"
           "/kc",   "projects/ci-signing/locations/global/keyRings/production/cryptoKeys/game-capture-release-sign-hsm/cryptoKeyVersions/1"
           "${{ github.workspace }}/build/data/obs-plugins/win-capture/*.dll"
        )
        Invoke-External $SignToolExe @signArgs

    - name: Run bouf
      shell: pwsh
      run: |
        . ${env:GITHUB_ACTION_PATH}\Invoke-External.ps1
        $boufArgs = @(
           "--config",     "${env:GITHUB_ACTION_PATH}/config_${{ inputs.architecture }}.toml"
           "--version",    "${{ inputs.version }}"
           "--branch",     "${{ inputs.channel }}"
           "-i",           "${{ github.workspace }}/build"
           "-p",           "${{ github.workspace }}/old_builds"
           "-o",           "${{ github.workspace }}/output"
           "--packaging-only"
        )
        Invoke-External "${{ github.workspace }}\bouf\bin\bouf.exe" @boufArgs

    - name: Sync Latest Build
      shell: pwsh
      env:
        RCLONE_INCLUDE: '**/${{ inputs.version }}/**'
        RCLONE_GCS_ENV_AUTH: 'true'
        RCLONE_GCS_BUCKET_POLICY_ONLY: 'true'
      run: |
        rclone sync --delete-excluded --transfers 100 "${{ github.workspace }}/old_builds" ":gcs:obs-latest/${{ inputs.architecture }}/${{ inputs.channel }}"

    - name: Upload Build to Archive
      shell: pwsh
      env:
        RCLONE_GCS_ENV_AUTH: 'true'
        RCLONE_GCS_BUCKET_POLICY_ONLY: 'true'
      run: |
        rclone copy --transfers 100 "${{ github.workspace }}/old_builds" ":gcs:obs-builds/${{ inputs.architecture }}"
