name: Release Desktop App

on:
  workflow_dispatch:
    inputs:
      version:
        description: App Version
        required: true
        default: 0.0.0
      is-draft:
        description: 'Draft Release?'
        type: boolean
        required: true
        default: true
      is-pre-release:
        description: 'Pre Release? (labeled as "PreRelease")'
        type: boolean
        required: true
        default: true
      build-type:
        description: 'Build Type (canary, beta or stable)'
        type: string
        required: true
        default: canary

permissions:
  actions: write
  contents: write
  security-events: write

concurrency:
  # The concurrency group contains the workflow name and the branch name for
  # pull requests or the commit hash for any other events.
  group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
  cancel-in-progress: true

env:
  BUILD_TYPE: ${{ github.event.inputs.build-type }}
  DEBUG: napi:*
  APP_NAME: affine
  MACOSX_DEPLOYMENT_TARGET: '10.13'

jobs:
  before-make:
    runs-on: ubuntu-latest
    environment: ${{ github.ref_name == 'master' && 'production' || 'development' }}
    steps:
      - uses: actions/checkout@v3
      - name: Setup Node.js
        uses: ./.github/actions/setup-node
      - name: generate-assets
        run: yarn workspace @affine/electron generate-assets
        env:
          SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
          SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
          SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
          RELEASE_VERSION: ${{ github.event.inputs.version }}

      - name: Upload Artifact (web-static)
        uses: actions/upload-artifact@v3
        with:
          name: before-make-web-static
          path: apps/electron/resources/web-static

  make-distribution:
    environment: ${{ github.ref_name == 'master' && 'production' || 'development' }}
    strategy:
      # all combinations: macos-latest x64, macos-latest arm64, windows-latest x64, ubuntu-latest x64
      matrix:
        spec:
          - {
              os: macos-latest,
              platform: darwin,
              arch: x64,
              target: x86_64-apple-darwin,
            }
          - {
              os: macos-latest,
              platform: darwin,
              arch: arm64,
              target: aarch64-apple-darwin,
            }
          - {
              os: ubuntu-latest,
              platform: linux,
              arch: x64,
              target: x86_64-unknown-linux-gnu,
            }
          - {
              os: windows-latest,
              platform: win32,
              arch: x64,
              target: x86_64-pc-windows-msvc,
            }
    runs-on: ${{ matrix.spec.os }}
    needs: before-make
    env:
      APPLE_ID: ${{ secrets.APPLE_ID }}
      APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
      APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
      SKIP_GENERATE_ASSETS: 1
    steps:
      - uses: actions/checkout@v3
      - name: Setup Node.js
        uses: ./.github/actions/setup-node
      - name: Build AFFiNE native
        uses: ./.github/actions/build-rust
        with:
          target: ${{ matrix.spec.target }}
          nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
      - uses: actions/download-artifact@v3
        with:
          name: before-make-web-static
          path: apps/electron/resources/web-static

      - name: Build layers
        run: yarn workspace @affine/electron build

      - name: Signing By Apple Developer ID
        if: ${{ matrix.spec.platform == 'darwin' }}
        uses: apple-actions/import-codesign-certs@v2
        with:
          p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
          p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}

      - name: make
        run: yarn workspace @affine/electron make --platform=${{ matrix.spec.platform }} --arch=${{ matrix.spec.arch }}

      - name: Save artifacts (mac)
        if: ${{ matrix.spec.platform == 'darwin' }}
        run: |
          mkdir -p builds
          mv apps/electron/out/*/make/*.dmg ./builds/affine-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.dmg
          mv apps/electron/out/*/make/zip/darwin/${{ matrix.spec.arch }}/*.zip ./builds/affine-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.zip
      - name: Save artifacts (windows)
        if: ${{ matrix.spec.platform == 'win32' }}
        run: |
          mkdir -p builds
          mv apps/electron/out/*/make/zip/win32/x64/AFFiNE*-win32-x64-*.zip ./builds/affine-${{ env.BUILD_TYPE }}-windows-x64.zip
          mv apps/electron/out/*/make/squirrel.windows/x64/*.exe ./builds/affine-${{ env.BUILD_TYPE }}-windows-x64.exe
          mv apps/electron/out/*/make/squirrel.windows/x64/*.msi ./builds/affine-${{ env.BUILD_TYPE }}-windows-x64.msi
          mv apps/electron/out/*/make/squirrel.windows/x64/*.nupkg ./builds/affine-${{ env.BUILD_TYPE }}-windows-x64.nupkg

      - name: Save artifacts (linux)
        if: ${{ matrix.spec.platform == 'linux' }}
        run: |
          mkdir -p builds
          mv apps/electron/out/*/make/zip/linux/x64/*.zip ./builds/affine-${{ env.BUILD_TYPE }}-linux-x64.zip

      - name: Upload Artifact
        uses: actions/upload-artifact@v3
        with:
          name: affine-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}-builds
          path: builds

  release:
    needs: make-distribution
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - name: Download Artifacts (macos-x64)
        uses: actions/download-artifact@v3
        with:
          name: affine-darwin-x64-builds
          path: ./
      - name: Download Artifacts (macos-arm64)
        uses: actions/download-artifact@v3
        with:
          name: affine-darwin-arm64-builds
          path: ./
      - name: Download Artifacts (windows-x64)
        uses: actions/download-artifact@v3
        with:
          name: affine-win32-x64-builds
          path: ./
      - name: Download Artifacts (linux-x64)
        uses: actions/download-artifact@v3
        with:
          name: affine-linux-x64-builds
          path: ./
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - name: Generate Release yml
        run: |
          cp ./apps/electron/scripts/generate-yml.js .
          node generate-yml.js
        env:
          RELEASE_VERSION: ${{ github.event.inputs.version }}
      - name: Create Release Draft
        uses: softprops/action-gh-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
        with:
          name: Desktop APP ${{ github.event.inputs.version }}
          body: 'TODO: Add release notes here'
          draft: ${{ github.event.inputs.is-draft }}
          prerelease: ${{ github.event.inputs.is-pre-release }}
          files: |
            ./VERSION
            ./*.zip
            ./*.dmg
            ./*.exe
            ./*.nupkg
            ./RELEASES
            ./*.AppImage
            ./*.apk
            ./*.yml
