name: Mac Store Release on Release
on:
  release:
    types: [published]
  workflow_dispatch:
    inputs: {}

jobs:
  mac-store-release:
    runs-on: macos-latest
    env:
      UNSPLASH_KEY: ${{ secrets.UNSPLASH_KEY }}
      UNSPLASH_CLIENT_ID: ${{ secrets.UNSPLASH_CLIENT_ID }}

    if: '!github.event.release.prerelease'

    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2
        with:
          egress-policy: audit
          allowed-endpoints: >
            api.github.com:443
            github.com:443
            objects.githubusercontent.com:443
            registry.npmjs.org:443
            www.apple.com:443
            appstoreconnect.apple.com:443

      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
        with:
          node-version: 20
      - name: Check out Git repository
        uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
        with:
          persist-credentials: false
      # work around for npm installs from git+https://github.com/johannesjo/J2M.git
      - name: Reconfigure git to use HTTP authentication
        run: >
          git config --global url."https://github.com/".insteadOf
          ssh://git@github.com/

      - name: Install Apple WWDR intermediate certificate
        run: |
          curl -fsSL https://www.apple.com/certificateauthority/AppleWWDRCAG4.cer -o /tmp/AppleWWDRCAG4.cer
          sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /tmp/AppleWWDRCAG4.cer

      - name: Get npm cache directory
        id: npm-cache-dir
        run: |
          echo "::set-output name=dir::$(npm config get cache)"
      - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5
        id: npm-cache # use this to check for `cache-hit` ==> if: steps.npm-cache.outputs.cache-hit != 'true'
        with:
          path: ${{ steps.npm-cache-dir.outputs.dir }}
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-

      - name: Configure signing keychain
        env:
          MAC_CERTS: ${{ secrets.mac_certs }}
          MAC_CERTS_PASSWORD: ${{ secrets.mac_certs_password }}
        run: |
          CERT_PATH="$RUNNER_TEMP/mac-certs.p12"
          KEYCHAIN_NAME="build.keychain"
          KEYCHAIN_PATH="$HOME/Library/Keychains/${KEYCHAIN_NAME}-db"
          echo "$MAC_CERTS" | base64 --decode > "$CERT_PATH"
          echo "=== DIAGNOSTIC: Decoded .p12 SHA256 ==="
          shasum -a 256 "$CERT_PATH"
          echo "========================================"
          security create-keychain -p "" "$KEYCHAIN_NAME"
          security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
          security unlock-keychain -p "" "$KEYCHAIN_PATH"
          curl -fsSL https://www.apple.com/certificateauthority/AppleWWDRCAG4.cer -o "$RUNNER_TEMP/AppleWWDRCAG4.cer"
          security import "$RUNNER_TEMP/AppleWWDRCAG4.cer" -k "$KEYCHAIN_PATH" -T /usr/bin/codesign
          security import "$CERT_PATH" -k "$KEYCHAIN_PATH" -P "$MAC_CERTS_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/pkgbuild -T /usr/bin/productbuild
          security list-keychains -s "$KEYCHAIN_PATH" "$HOME/Library/Keychains/login.keychain-db"
          security default-keychain -s "$KEYCHAIN_PATH"
          security set-key-partition-list -S apple-tool:,apple: -k "" "$KEYCHAIN_PATH"
          security find-identity -v -p codesigning "$KEYCHAIN_PATH"
          security find-identity -v -p macappstore "$KEYCHAIN_PATH"
          {
            echo "CSC_KEYCHAIN=$KEYCHAIN_PATH"
            echo "CSC_LINK=file://$CERT_PATH"
            echo "CSC_KEY_PASSWORD=$MAC_CERTS_PASSWORD"
          } >> "$GITHUB_ENV"

      - name: List available signing identities codesigning
        run: security find-identity -v -p codesigning

      - name: List available signing identities macappstore
        run: security find-identity -v -p macappstore

      - name: Workaround for nx issue and dmg licence issue
        run: npm install @nx/nx-darwin-arm64 dmg-license

      - name: Install npm Packages
        #  if: steps.npm-cache.outputs.cache-hit != 'true'
        run: npm i

      - run: 'echo "$PROVISION_PROFILE" | base64 --decode > embedded.provisionprofile'
        shell: bash
        env:
          PROVISION_PROFILE: ${{secrets.mas_provision_profile}}

      - name: Verify provisioning profile certificate
        run: |
          security cms -D -i embedded.provisionprofile > /tmp/profile.plist
          python3 << 'EOF'
          import plistlib
          import subprocess
          import hashlib

          with open('/tmp/profile.plist', 'rb') as f:
              plist_data = plistlib.load(f)

          cert_data = plist_data['DeveloperCertificates'][0]
          fingerprint = hashlib.sha1(cert_data).hexdigest().upper()

          # Write to temp file and extract subject
          with open('/tmp/cert.der', 'wb') as f:
              f.write(cert_data)

          result = subprocess.run(['openssl', 'x509', '-in', '/tmp/cert.der', '-inform', 'DER',
                                  '-noout', '-subject', '-fingerprint', '-sha1'],
                                 capture_output=True, text=True)

          print("=== PROVISIONING PROFILE CERTIFICATE ===")
          print(result.stdout)
          print(f"SHA1 Fingerprint: {fingerprint}")
          print("========================================")
          EOF

      - run: npm run env # Generate env.generated.ts

      #      - name: Lint
      #        run: npm run lint
      #
      #      - name: Test Unit
      #        run: npm run test

      #      - name: Test E2E
      #        run: npm run e2e

      - name: Build Frontend & Electron
        run: npm run build

      - name: Build Electron app
        run: npm run dist:mac:mas:buildOnly

      - name: Verify code signing used in built app
        run: |
          echo "=== Checking code signature of main executable ==="
          codesign -dv --verbose=4 ".tmp/app-builds/mas-universal/Super Productivity.app" 2>&1 | grep -E "Authority|Identifier|Signature"
          echo ""
          echo "=== Checking provisioning profile embedded in app ==="
          security cms -D -i ".tmp/app-builds/mas-universal/Super Productivity.app/Contents/embedded.provisionprofile" > /tmp/built-profile.plist
          python3 << 'EOF'
          import plistlib
          import subprocess
          import hashlib

          with open('/tmp/built-profile.plist', 'rb') as f:
              plist_data = plistlib.load(f)

          cert_data = plist_data['DeveloperCertificates'][0]
          fingerprint = hashlib.sha1(cert_data).hexdigest().upper()

          print(f"Provisioning profile expects certificate: {fingerprint}")
          EOF

      - run: ls .tmp/app-builds
        shell: bash

      - name: Validate App
        run: ls .tmp/app-builds; ls .tmp/app-builds/mas-universal; xcrun altool --type macos --validate-app -f .tmp/app-builds/mas-universal/super*.pkg -u ${{secrets.APPLE_ID}} -p ${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}
        env:
          APPLE_ID: ${{secrets.APPLE_ID}}
          APPLE_APP_SPECIFIC_PASSWORD: ${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}

      - name: Push to Store
        run: xcrun altool --type macos --upload-app -f .tmp/app-builds/mas-universal/super*.pkg -u ${{secrets.APPLE_ID}} -p ${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}
        env:
          APPLE_ID: ${{secrets.APPLE_ID}}
          APPLE_APP_SPECIFIC_PASSWORD: ${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}
