hunk.code_window:       shell: bash
         run: yarn config set nmMode hardlinks-local
       - name: yarn install
         uses: nick-fields/retry@v2
         with:
           timeout_minutes: 10
           max_attempts: 3
           retry_on: timeout
           command: yarn install ${{ inputs.extra-flags }}
         env:
           HUSKY: '0'
           PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1'
  
hunk.labels: keep keep keep keep replace replace replace replace replace replace keep keep keep
hunk.after_edit:       if: ${{ inputs.package-install == 'true' }}
         continue-on-error: true
         shell: bash
         run: yarn install ${{ inputs.extra-flags }}
         env:
           HUSKY: '0'
           PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1'
           ELECTRON_SKIP_BINARY_DOWNLOAD: '1'
           SENTRYCLI_SKIP_DOWNLOAD: '1'
       - name: yarn install (try again)
         if: ${{ steps.install.outcome == 'failure' }}
         shell: bash
         run: yarn install ${{ inputs.extra-flags }}
  
hunk.file_path: .github/actions/setup-node/action.yml
hunk.type: replace
file: name: Release Desktop App
  
  on:
    push:
      tags:
        - 'v[0-9]+.[0-9]+.[0-9]+-canary.[0-9]+'
    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
  
  env:
    BUILD_TYPE: ${{ github.event.inputs.build-type || (github.ref_type == 'tag' && contains(github.ref, 'canary') && 'canary') }}
    DEBUG: napi:*
    APP_NAME: affine
    MACOSX_DEPLOYMENT_TARGET: '10.13'
  
  jobs:
    before-make:
      runs-on: ubuntu-latest
      environment: production
      outputs:
        RELEASE_VERSION: ${{ steps.get-canary-version.outputs.RELEASE_VERSION }}
      steps:
        - uses: actions/checkout@v3
        - name: Setup Node.js
          uses: ./.github/actions/setup-node
        - name: Setup @sentry/cli
          uses: ./.github/actions/setup-sentry
        - name: Get canary version
          id: get-canary-version
          if: ${{ github.ref_type == 'tag' }}
          run: |
            TAG_VERSION=${GITHUB_REF#refs/tags/v}
            PACKAGE_VERSION=$(node -p "require('./apps/electron/package.json').version")
            if [ "$TAG_VERSION" != "$PACKAGE_VERSION" ]; then
              echo "Tag version ($TAG_VERSION) does not match package.json version ($PACKAGE_VERSION)"
              exit 1
            fi
            echo "RELEASE_VERSION=$(node -p "require('./apps/electron/package.json').version")" >> $GITHUB_OUTPUT
        - 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 || steps.get-canary-version.outputs.RELEASE_VERSION }}
  
        - name: Upload core artifact
          uses: actions/upload-artifact@v3
          with:
            name: core
            path: apps/electron/resources/web-static
  
    make-distribution:
      environment: production
      strategy:
        # all combinations: macos-latest x64, macos-latest arm64, ubuntu-latest x64
        # For windows, we need a separate approach
        matrix:
          spec:
            - runner: macos-latest
              platform: darwin
              arch: x64
              target: x86_64-apple-darwin
            - runner: macos-latest
              platform: darwin
              arch: arm64
              target: aarch64-apple-darwin
            - runner: ubuntu-latest
              platform: linux
              arch: x64
              target: x86_64-unknown-linux-gnu
      runs-on: ${{ matrix.spec.runner }}
      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: Setup Maker
          uses: ./.github/actions/setup-maker
        - 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: core
            path: apps/electron/resources/web-static
  
        - name: Build Plugins
          run: yarn run build:plugins
  
        - name: Build Desktop 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 (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
            mv apps/electron/out/*/make/AppImage/x64/*.AppImage ./builds/affine-${{ env.BUILD_TYPE }}-linux-x64.AppImage
  
        - name: Upload Artifact
          uses: actions/upload-artifact@v3
          with:
            name: affine-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}-builds
            path: builds
  
    package-distribution-windows:
      environment: production
      strategy:
        # all combinations: macos-latest x64, macos-latest arm64, ubuntu-latest x64
        # For windows, we need a separate approach
        matrix:
          spec:
            - runner: windows-latest
              platform: win32
              arch: x64
              target: x86_64-pc-windows-msvc
      runs-on: ${{ matrix.spec.runner }}
      needs: before-make
      outputs:
        FILES_TO_BE_SIGNED: ${{ steps.get_files_to_be_signed.outputs.FILES_TO_BE_SIGNED }}
      env:
        SKIP_GENERATE_ASSETS: 1
      steps:
        - uses: actions/checkout@v3
        - name: Setup Node.js
          timeout-minutes: 10
          uses: ./.github/actions/setup-node
        - name: Setup Maker
          timeout-minutes: 10
          uses: ./.github/actions/setup-maker
        - 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: core
            path: apps/electron/resources/web-static
  
        - name: Build Plugins
          run: yarn run build:plugins
  
        - name: Build Desktop Layers
          run: yarn workspace @affine/electron build
  
        - name: package
          run: yarn workspace @affine/electron package --platform=${{ matrix.spec.platform }} --arch=${{ matrix.spec.arch }}
  
        - name: get all files to be signed
          id: get_files_to_be_signed
          run: |
            Set-Variable -Name FILES_TO_BE_SIGNED -Value ((Get-ChildItem -Path apps/electron/out -Recurse -File | Where-Object { $_.Extension -in @(".exe", ".node", ".dll", ".msi") } | ForEach-Object { '"' + $_.FullName.Replace((Get-Location).Path + '\apps\electron\out\', '') + '"' }) -join ' ')
            "FILES_TO_BE_SIGNED=$FILES_TO_BE_SIGNED" >> $env:GITHUB_OUTPUT
            echo $FILES_TO_BE_SIGNED
  
        - name: Zip artifacts for faster upload
          run: Compress-Archive -CompressionLevel Fastest -Path apps/electron/out/* -DestinationPath archive.zip
  
        - name: Save packaged artifacts for signing
          uses: actions/upload-artifact@v3
          with:
            name: packaged-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}
            path: |
              archive.zip
              !**/*.map
  
    sign-packaged-artifacts-windows:
      needs: package-distribution-windows
      uses: ./.github/workflows/windows-signer.yml
      with:
        files: ${{ needs.package-distribution-windows.outputs.FILES_TO_BE_SIGNED }}
        artifact-name: packaged-win32-x64
  
    make-windows-installer:
      environment: production
      needs: sign-packaged-artifacts-windows
      strategy:
        # all combinations: macos-latest x64, macos-latest arm64, ubuntu-latest x64
        # For windows, we need a separate approach
        matrix:
          spec:
            - runner: windows-latest
              platform: win32
              arch: x64
              target: x86_64-pc-windows-msvc
      runs-on: ${{ matrix.spec.runner }}
      outputs:
        FILES_TO_BE_SIGNED: ${{ steps.get_files_to_be_signed.outputs.FILES_TO_BE_SIGNED }}
      steps:
        - uses: actions/checkout@v3
        - name: Setup Node.js
          timeout-minutes: 10
          uses: ./.github/actions/setup-node
        - name: Download and overwrite packaged artifacts
          uses: actions/download-artifact@v3
          with:
            name: signed-packaged-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}
            path: .
        - name: unzip file
          run: Expand-Archive -Path signed.zip -DestinationPath apps/electron/out
  
        - name: Make squirrel.windows installer
          run: yarn workspace @affine/electron make-squirrel --platform=${{ matrix.spec.platform }} --arch=${{ matrix.spec.arch }}
  
        - name: Zip artifacts for faster upload
          run: Compress-Archive -CompressionLevel Fastest -Path apps/electron/out/${{ env.BUILD_TYPE }}/make/* -DestinationPath archive.zip
  
        - name: get all files to be signed
          id: get_files_to_be_signed
          run: |
            Set-Variable -Name FILES_TO_BE_SIGNED -Value ((Get-ChildItem -Path apps/electron/out/${{ env.BUILD_TYPE }}/make -Recurse -File | Where-Object { $_.Extension -in @(".exe", ".node", ".dll", ".msi") } | ForEach-Object { '"' + $_.FullName.Replace((Get-Location).Path + '\apps\electron\out\${{ env.BUILD_TYPE }}\make\', '') + '"' }) -join ' ')
            "FILES_TO_BE_SIGNED=$FILES_TO_BE_SIGNED" >> $env:GITHUB_OUTPUT
            echo $FILES_TO_BE_SIGNED
  
        - name: Save installer for signing
          uses: actions/upload-artifact@v3
          with:
            name: installer-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}
            path: archive.zip
  
    sign-installer-artifacts-windows:
      needs: make-windows-installer
      uses: ./.github/workflows/windows-signer.yml
      with:
        files: ${{ needs.make-windows-installer.outputs.FILES_TO_BE_SIGNED }}
        artifact-name: installer-win32-x64
  
    finalize-installer-windows:
      environment: production
      needs: sign-installer-artifacts-windows
      strategy:
        # all combinations: macos-latest x64, macos-latest arm64, ubuntu-latest x64
        # For windows, we need a separate approach
        matrix:
          spec:
            - runner: windows-latest
              platform: win32
              arch: x64
              target: x86_64-pc-windows-msvc
      runs-on: ${{ matrix.spec.runner }}
      steps:
        - name: Download and overwrite installer artifacts
          uses: actions/download-artifact@v3
          with:
            name: signed-installer-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}
            path: .
        - name: unzip file
          run: Expand-Archive -Path signed.zip -DestinationPath apps/electron/out/${{ env.BUILD_TYPE }}/make
  
        - name: Save artifacts
          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
  
        - name: Upload Artifact
          uses: actions/upload-artifact@v3
          with:
            name: affine-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}-builds
            path: builds
  
    release:
      needs: [before-make, make-distribution, finalize-installer-windows]
      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 || needs.before-make.outputs.RELEASE_VERSION }}
        - name: Create Release Draft
          uses: softprops/action-gh-release@v1
          env:
            GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
          with:
            name: ${{ github.event.inputs.version || needs.before-make.outputs.RELEASE_VERSION }}
            body: ''
            draft: ${{ github.event.inputs.is-draft || true }}
            prerelease: ${{ github.event.inputs.is-pre-release || needs.before-make.outputs.version }}
            files: |
              ./VERSION
              ./*.zip
              ./*.dmg
              ./*.exe
              ./RELEASES
              ./*.AppImage
              ./*.apk
              ./*.yml
  