---
name: package and publish GitHub (draft) release
# https://github.com/product-os/flowzone/tree/master/.github/actions
inputs:
  json:
    description: "JSON stringified object containing all the inputs from the calling workflow"
    required: true
  secrets:
    description: "JSON stringified object containing all the secrets from the calling workflow"
    required: true

  # --- custom environment
  NODE_VERSION:
    type: string
    # Beware that native modules will be built for this version,
    # which might not be compatible with the one used by pkg (see forge.sidecar.ts)
    # https://github.com/vercel/pkg-fetch/releases
    default: "20.x"
  VERBOSE:
    type: string
    default: "true"

runs:
  # https://docs.github.com/en/actions/creating-actions/creating-a-composite-action
  using: "composite"
  steps:
    - name: Download custom source artifact
      uses: actions/download-artifact@v4
      with:
        name: custom-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}-${{ runner.os }}-${{ runner.arch }}
        path: ${{ runner.temp }}

    - name: Extract custom source artifact
      if: runner.os != 'Windows'
      shell: bash
      working-directory: .
      run: tar -xf ${{ runner.temp }}/custom.tgz

    - name: Extract custom source artifact
      if: runner.os == 'Windows'
      shell: pwsh
      working-directory: .
      run: C:\"Program Files"\Git\usr\bin\tar.exe --force-local -xf ${{ runner.temp }}\custom.tgz

    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: ${{ inputs.NODE_VERSION }}
        cache: npm

    - name: Install host dependencies
      if: runner.os == 'Linux'
      shell: bash
      run: sudo apt-get install -y --no-install-recommends fakeroot dpkg rpm

    - name: Install host dependencies
      if: runner.os == 'macOS'
      # FIXME: Python 3.12 dropped distutils that node-gyp depends upon.
      # This is a temporary workaround to make the job use Python 3.11 until
      # we update to npm 10+.
      uses: actions/setup-python@d27e3f3d7c64b4bbf8e4abfb9b63b83e846e0435 # v4
      with:
        python-version: '3.11'

    # https://www.electron.build/code-signing.html
    # https://dev.to/rwwagner90/signing-electron-apps-with-github-actions-4cof
    - name: Import Apple code signing certificate
      if: runner.os == 'macOS'
      shell: bash
      run: |
        KEY_CHAIN=build.keychain
        CERTIFICATE_P12=certificate.p12

        # Recreate the certificate from the secure environment variable
        echo $CERTIFICATE_P12_B64 | base64 --decode > $CERTIFICATE_P12

        # Create a keychain
        security create-keychain -p actions $KEY_CHAIN

        # Make the keychain the default so identities are found
        security default-keychain -s $KEY_CHAIN

        # Unlock the keychain
        security unlock-keychain -p actions $KEY_CHAIN

        security import $CERTIFICATE_P12 -k $KEY_CHAIN -P $CERTIFICATE_PASSWORD -T /usr/bin/codesign

        security set-key-partition-list -S apple-tool:,apple: -s -k actions $KEY_CHAIN

        # remove certs
        rm -fr *.p12
      env:
        CERTIFICATE_P12_B64: ${{ fromJSON(inputs.secrets).APPLE_SIGNING }}
        CERTIFICATE_PASSWORD: ${{ fromJSON(inputs.secrets).APPLE_SIGNING_PASSWORD }}

    - name: Import Windows code signing certificate
      if: runner.os == 'Windows'
      id: import_win_signing_cert
      shell: powershell
      run: |
        Set-Content -Path ${{ runner.temp }}/certificate.base64 -Value $env:SM_CLIENT_CERT_FILE_B64
        certutil -decode ${{ runner.temp }}/certificate.base64 ${{ runner.temp }}/Certificate_pkcs12.p12
        Remove-Item -path ${{ runner.temp }} -include certificate.base64

        echo "certFilePath=${{ runner.temp }}/Certificate_pkcs12.p12" >> $GITHUB_OUTPUT

      env:
        SM_CLIENT_CERT_FILE_B64: ${{ fromJSON(inputs.secrets).SM_CLIENT_CERT_FILE_B64 }}

    - name: Package release
      shell: bash
      # IMPORTANT: before making changes to this step please consult @engineering in balena's chat.
      run: |
        ## FIXME: causes issues with `xxhash` which tries to load a debug build which doens't exist and cannot be compiled
        # if [[ '${{ inputs.VERBOSE }}' =~ on|On|Yes|yes|true|True ]]; then
        #  export DEBUG='electron-forge:*,sidecar'
        # fi

        APPLICATION_VERSION="$(jq -r '.version' package.json)"
        HOST_ARCH="$(echo "${RUNNER_ARCH}" | tr '[:upper:]' '[:lower:]')"

        if [[ "${RUNNER_OS}" == Linux ]]; then
          PLATFORM=Linux
          SHA256SUM_BIN=sha256sum

        elif [[ "${RUNNER_OS}" == macOS ]]; then
          PLATFORM=Darwin
          SHA256SUM_BIN='shasum -a 256'

        elif [[ "${RUNNER_OS}" == Windows ]]; then
          PLATFORM=Windows
          SHA256SUM_BIN=sha256sum

          # Install DigiCert Signing Manager Tools      
          curl --silent --retry 3 --fail https://one.digicert.com/signingmanager/api-ui/v1/releases/smtools-windows-x64.msi/download \
            -H "x-api-key:$SM_API_KEY" \
            -o smtools-windows-x64.msi
          msiexec -i smtools-windows-x64.msi -qn
          PATH="/c/Program Files/DigiCert/DigiCert One Signing Manager Tools:${PATH}"
          smksp_registrar.exe list
          smctl.exe keypair ls
          /c/Windows/System32/certutil.exe -csp "DigiCert Signing Manager KSP" -key -user
          smksp_cert_sync.exe

          # (signtool.exe) https://github.com/actions/runner-images/blob/main/images/win/Windows2019-Readme.md#installed-windows-sdks
          PATH="/c/Program Files (x86)/Windows Kits/10/bin/${runner_arch}:${PATH}"

        else
          echo "ERROR: unexpected runner OS: ${RUNNER_OS}"
          exit 1
        fi

        # Currently, we can only build for the host architecture.
        npx electron-forge make

        echo "version=${APPLICATION_VERSION}" >> $GITHUB_OUTPUT

        # collect all artifacts from subdirectories under a common top-level directory
        mkdir -p dist
        find ./out/make -type f \( \
          -iname "*.zip" -o        \
          -iname "*.dmg" -o        \
          -iname "*.rpm" -o        \
          -iname "*.deb" -o        \
          -iname "*.AppImage" -o   \
          -iname "*Setup.exe"      \
        \) -ls -exec cp '{}' dist/ \;

        if [[ -n "${SHA256SUM_BIN}" ]]; then
          # Compute and save digests.
          cd dist/
          ${SHA256SUM_BIN} *.* >"SHA256SUMS.${PLATFORM}.${HOST_ARCH}.txt"
        fi
      env:
        # ensure we sign the artifacts
        NODE_ENV: production
        # analytics tokens
        SENTRY_TOKEN: https://739bbcfc0ba4481481138d3fc831136d@o95242.ingest.sentry.io/4504451487301632
        AMPLITUDE_TOKEN: 'balena-etcher'
        # Apple notarization
        XCODE_APP_LOADER_EMAIL: ${{ fromJSON(inputs.secrets).XCODE_APP_LOADER_EMAIL }}
        XCODE_APP_LOADER_PASSWORD: ${{ fromJSON(inputs.secrets).XCODE_APP_LOADER_PASSWORD }}
        XCODE_APP_LOADER_TEAM_ID: ${{ fromJSON(inputs.secrets).XCODE_APP_LOADER_TEAM_ID }}
        # Windows signing
        SM_CLIENT_CERT_PASSWORD: ${{ fromJSON(inputs.secrets).SM_CLIENT_CERT_PASSWORD }}
        SM_CLIENT_CERT_FILE: '${{ runner.temp }}\Certificate_pkcs12.p12'
        SM_HOST: ${{ fromJSON(inputs.secrets).SM_HOST }}
        SM_API_KEY: ${{ fromJSON(inputs.secrets).SM_API_KEY }}
        SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ fromJSON(inputs.secrets).SM_CODE_SIGNING_CERT_SHA1_HASH }}
        TIMESTAMP_SERVER: http://timestamp.digicert.com

    - name: Upload artifacts
      uses: actions/upload-artifact@v4
      with:
        name: gh-release-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}-${{ runner.os }}-${{ runner.arch }}
        path: dist
        retention-days: 1
        if-no-files-found: error
