name: Package for Windows
description: Create a Windows package for PineconeMC

inputs:
  version:
    description: Launcher version
    required: true
  build-type:
    description: Type for the build
    required: true
    default: Debug
  artifact-name:
    description: Name of the uploaded artifact
    required: true
  msystem:
    description: MSYS2 subsystem to use
    required: false
  azure-client-id:
    description: Client ID for the Azure Signer Application
    required: true
  azure-tenant-id:
    description: Tenant ID for the Azure Signer Application
    required: true
  azure-subscription-id:
    description: Subscription ID for the Azure Signer Application
    required: true

runs:
  using: composite

  steps:
    - name: Package (MinGW)
      if: ${{ inputs.msystem != '' }}
      shell: msys2 {0}
      env:
        BUILD_DIR: build
        INSTALL_DIR: install
      run: |
        cmake --install ${{ env.BUILD_DIR }} --config ${{ inputs.build-type }}
        touch ${{ env.INSTALL_DIR }}/manifest.txt
        for l in $(find ${{ env.INSTALL_DIR }} -type f); do l=$(cygpath -u $l); l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_DIR }}/}; l=${l#./}; echo $l; done >> ${{ env.INSTALL_DIR }}/manifest.txt

    - name: Package (MSVC)
      if: ${{ inputs.msystem == '' }}
      shell: pwsh
      env:
        BUILD_DIR: build
        INSTALL_DIR: install
      run: |
        cmake --install ${{ env.BUILD_DIR }} --config ${{ inputs.build-type }}

        cd ${{ github.workspace }}

        Get-ChildItem ${{ env.INSTALL_DIR }} -Recurse | ForEach FullName | Resolve-Path -Relative | %{ $_.TrimStart('.\') } | %{ $_.TrimStart('${{ env.INSTALL_DIR }}') } | %{ $_.TrimStart('\') } | Out-File -FilePath ${{ env.INSTALL_DIR }}/manifest.txt

    - name: Emit warning for unsigned builds
      if: ${{ env.CI_HAS_ACCESS_TO_AZURE == '' || inputs.azure-client-id == '' }}
      shell: pwsh
      run: |
        ":warning: Skipped code signing for Windows, as certificate was not present." >> $env:GITHUB_STEP_SUMMARY

    - name: Login to Azure
      if: ${{ env.CI_HAS_ACCESS_TO_AZURE != '' && inputs.azure-client-id != '' }}
      uses: azure/login@v3
      with:
        client-id: ${{ inputs.azure-client-id }}
        tenant-id: ${{ inputs.azure-tenant-id }}
        subscription-id: ${{ inputs.azure-subscription-id }}

    - name: Sign executables
      if: ${{ env.CI_HAS_ACCESS_TO_AZURE != '' && inputs.azure-client-id != '' }}
      uses: azure/artifact-signing-action@v1
      with:
        endpoint: https://eus.codesigning.azure.net/
        trusted-signing-account-name: PineconeMC
        certificate-profile-name: PineconeMC
        files-folder: ${{ github.workspace }}\install\
        files-folder-filter: dll,exe
        files-folder-recurse: true
        files-folder-depth: 2
        # recommended in https://github.com/Azure/artifact-signing-action#timestamping-1
        timestamp-rfc3161: 'http://timestamp.acs.microsoft.com'
        timestamp-digest: 'SHA256'
        # TODO(@getchoo): Is this all really needed???
        # https://github.com/Azure/trusted-signing-action/blob/fc390cf8ed0f14e248a542af1d838388a47c7a7c/docs/OIDC.md
        exclude-environment-credential: true
        exclude-workload-identity-credential: true
        exclude-managed-identity-credential: true
        exclude-shared-token-cache-credential: true
        exclude-visual-studio-credential: true
        exclude-visual-studio-code-credential: true
        exclude-azure-cli-credential: false
        exclude-azure-powershell-credential: true
        exclude-azure-developer-cli-credential: true
        exclude-interactive-browser-credential: true

    - name: Package (MinGW, portable)
      if: ${{ inputs.msystem != '' }}
      shell: msys2 {0}
      env:
        BUILD_DIR: build
        INSTALL_DIR: install
        INSTALL_PORTABLE_DIR: install-portable
      run: |
        cp -r ${{ env.INSTALL_DIR }} ${{ env.INSTALL_PORTABLE_DIR }}  # cmake install on Windows is slow, let's just copy instead
        cmake --install ${{ env.BUILD_DIR }} --config ${{ inputs.build-type }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable
        for l in $(find ${{ env.INSTALL_PORTABLE_DIR }} -type f); do l=$(cygpath -u $l); l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_PORTABLE_DIR }}/}; l=${l#./}; echo $l; done >> ${{ env.INSTALL_PORTABLE_DIR }}/manifest.txt

    - name: Package (MSVC, portable)
      if: ${{ inputs.msystem == '' }}
      shell: pwsh
      env:
        BUILD_DIR: build
        INSTALL_DIR: install
        INSTALL_PORTABLE_DIR: install-portable
      run: |
        cp -r ${{ env.INSTALL_DIR }} ${{ env.INSTALL_PORTABLE_DIR }}  # cmake install on Windows is slow, let's just copy instead
        cmake --install ${{ env.BUILD_DIR }} --config ${{ inputs.build-type }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable

        Get-ChildItem ${{ env.INSTALL_PORTABLE_DIR }} -Recurse | ForEach FullName | Resolve-Path -Relative | %{ $_.TrimStart('.\') } | %{ $_.TrimStart('${{ env.INSTALL_PORTABLE_DIR }}') } | %{ $_.TrimStart('\') } | Out-File -FilePath ${{ env.INSTALL_DIR }}/manifest.txt

    - name: Package (installer)
      shell: pwsh
      env:
        BUILD_DIR: build
        INSTALL_DIR: install

        NSCURL_VERSION: "v24.9.26.122"
        NSCURL_SHA256: "AEE6C4BE3CB6455858E9C1EE4B3AFE0DB9960FA03FE99CCDEDC28390D57CCBB0"
      run: |
        New-Item -Name NSISPlugins -ItemType Directory
        Invoke-Webrequest https://github.com/negrutiu/nsis-nscurl/releases/download/"${{ env.NSCURL_VERSION }}"/NScurl.zip -OutFile NSISPlugins\NScurl.zip
        $nscurl_hash = Get-FileHash NSISPlugins\NScurl.zip -Algorithm Sha256 | Select-Object -ExpandProperty Hash
        if ( $nscurl_hash -ne "${{ env.nscurl_sha256 }}") {
          echo "::error:: NSCurl.zip sha256 mismatch"
          exit 1
        }
        Expand-Archive -Path NSISPlugins\NScurl.zip -DestinationPath NSISPlugins\NScurl

        cd ${{ env.INSTALL_DIR }}
        makensis -NOCD "${{ github.workspace }}/${{ env.BUILD_DIR }}/program_info/win_install.nsi"

    - name: Sign installer
      if: ${{ env.CI_HAS_ACCESS_TO_AZURE != '' && inputs.azure-client-id != '' }}
      uses: azure/artifact-signing-action@v1
      with:
        endpoint: https://eus.codesigning.azure.net/
        trusted-signing-account-name: PineconeMC
        certificate-profile-name: PineconeMC

        files: |
          ${{ github.workspace }}\ElyPrismLauncher-Setup.exe

        # recommended in https://github.com/Azure/artifact-signing-action#timestamping-1
        timestamp-rfc3161: 'http://timestamp.acs.microsoft.com'
        timestamp-digest: 'SHA256'
        # TODO(@getchoo): Is this all really needed???
        # https://github.com/Azure/trusted-signing-action/blob/fc390cf8ed0f14e248a542af1d838388a47c7a7c/docs/OIDC.md
        exclude-environment-credential: true
        exclude-workload-identity-credential: true
        exclude-managed-identity-credential: true
        exclude-shared-token-cache-credential: true
        exclude-visual-studio-credential: true
        exclude-visual-studio-code-credential: true
        exclude-azure-cli-credential: false
        exclude-azure-powershell-credential: true
        exclude-azure-developer-cli-credential: true
        exclude-interactive-browser-credential: true

    - name: Upload binary zip
      uses: actions/upload-artifact@v7
      with:
        name: PineconeMC-${{ inputs.artifact-name }}-${{ inputs.version }}-${{ inputs.build-type }}
        path: install/**

    - name: Upload portable zip
      uses: actions/upload-artifact@v7
      with:
        name: PineconeMC-${{ inputs.artifact-name }}-Portable-${{ inputs.version }}-${{ inputs.build-type }}
        path: install-portable/**

    - name: Upload installer
      uses: actions/upload-artifact@v7
      with:
        name: PineconeMC-${{ inputs.artifact-name }}-Setup-${{ inputs.version }}-${{ inputs.build-type }}
        path: PineconeMC-Setup.exe
