diff --git a/.github/workflows/release-desktop.yml b/.github/workflows/release-desktop.yml index 1aaac39394..f6897a7a26 100644 --- a/.github/workflows/release-desktop.yml +++ b/.github/workflows/release-desktop.yml @@ -32,7 +32,7 @@ permissions: env: BUILD_TYPE: ${{ github.event.inputs.build-type }} - DEBUG: napi:* + DEBUG: 'affine:*,napi:*' APP_NAME: affine MACOSX_DEPLOYMENT_TARGET: '10.13' @@ -87,6 +87,7 @@ jobs: target: x86_64-unknown-linux-gnu runs-on: ${{ matrix.spec.runner }} needs: before-make + environment: ${{ github.event.inputs.build-type }} env: APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} @@ -163,10 +164,10 @@ jobs: if: ${{ matrix.spec.platform == 'linux' }} run: | mkdir -p builds - mv packages/frontend/apps/electron/out/*/make/zip/linux/x64/*.zip ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.zip - mv packages/frontend/apps/electron/out/*/make/*.AppImage ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.appimage - mv packages/frontend/apps/electron/out/*/make/deb/x64/*.deb ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.deb - mv packages/frontend/apps/electron/out/*/make/flatpak/*/*.flatpak ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.flatpak + mv packages/frontend/apps/electron/out/*/make/zip/linux/${{ matrix.spec.arch }}/*.zip ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.zip + mv packages/frontend/apps/electron/out/*/make/*.AppImage ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.appimage + mv packages/frontend/apps/electron/out/*/make/deb/${{ matrix.spec.arch }}/*.deb ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.deb + mv packages/frontend/apps/electron/out/*/make/flatpak/*/*.flatpak ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.flatpak - uses: actions/attest-build-provenance@v1 if: ${{ matrix.spec.platform == 'darwin' }} @@ -189,6 +190,7 @@ jobs: path: builds package-distribution-windows: + environment: ${{ github.event.inputs.build-type }} strategy: matrix: spec: @@ -196,10 +198,15 @@ jobs: platform: win32 arch: x64 target: x86_64-pc-windows-msvc + - runner: windows-latest + platform: win32 + arch: arm64 + target: aarch64-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 }} + FILES_TO_BE_SIGNED_x64: ${{ steps.get_files_to_be_signed.outputs.FILES_TO_BE_SIGNED_x64 }} + FILES_TO_BE_SIGNED_arm64: ${{ steps.get_files_to_be_signed.outputs.FILES_TO_BE_SIGNED_arm64 }} env: SKIP_GENERATE_ASSETS: 1 SENTRY_ORG: ${{ secrets.SENTRY_ORG }} @@ -243,7 +250,7 @@ jobs: id: get_files_to_be_signed run: | Set-Variable -Name FILES_TO_BE_SIGNED -Value ((Get-ChildItem -Path packages/frontend/apps/electron/out -Recurse -File | Where-Object { $_.Extension -in @(".exe", ".node", ".dll", ".msi") } | ForEach-Object { '"' + $_.FullName.Replace((Get-Location).Path + '\packages\frontend\apps\electron\out\', '') + '"' }) -join ' ') - "FILES_TO_BE_SIGNED=$FILES_TO_BE_SIGNED" >> $env:GITHUB_OUTPUT + "FILES_TO_BE_SIGNED_${{ matrix.spec.arch }}=$FILES_TO_BE_SIGNED" >> $env:GITHUB_OUTPUT echo $FILES_TO_BE_SIGNED - name: Zip artifacts for faster upload @@ -257,25 +264,35 @@ jobs: archive.zip !**/*.map - sign-packaged-artifacts-windows: + sign-packaged-artifacts-windows_x64: needs: package-distribution-windows uses: ./.github/workflows/windows-signer.yml with: - files: ${{ needs.package-distribution-windows.outputs.FILES_TO_BE_SIGNED }} + files: ${{ needs.package-distribution-windows.outputs.FILES_TO_BE_SIGNED_x64 }} artifact-name: packaged-win32-x64 + sign-packaged-artifacts-windows_arm64: + needs: package-distribution-windows + uses: ./.github/workflows/windows-signer.yml + with: + files: ${{ needs.package-distribution-windows.outputs.FILES_TO_BE_SIGNED_arm64 }} + artifact-name: packaged-win32-arm64 + make-windows-installer: - needs: sign-packaged-artifacts-windows + needs: + - sign-packaged-artifacts-windows_x64 + - sign-packaged-artifacts-windows_arm64 strategy: matrix: spec: - - runner: windows-latest - platform: win32 + - platform: win32 arch: x64 - target: x86_64-pc-windows-msvc - runs-on: ${{ matrix.spec.runner }} + - platform: win32 + arch: arm64 + runs-on: windows-latest outputs: - FILES_TO_BE_SIGNED: ${{ steps.get_files_to_be_signed.outputs.FILES_TO_BE_SIGNED }} + FILES_TO_BE_SIGNED_x64: ${{ steps.get_files_to_be_signed.outputs.FILES_TO_BE_SIGNED_x64 }} + FILES_TO_BE_SIGNED_arm64: ${{ steps.get_files_to_be_signed.outputs.FILES_TO_BE_SIGNED_arm64 }} steps: - uses: actions/checkout@v4 - name: Setup Version @@ -288,6 +305,8 @@ jobs: extra-flags: workspaces focus @affine/electron @affine/monorepo hard-link-nm: false nmHoistingLimits: workspaces + env: + npm_config_arch: ${{ matrix.spec.arch }} - name: Download and overwrite packaged artifacts uses: actions/download-artifact@v4 with: @@ -309,7 +328,7 @@ jobs: id: get_files_to_be_signed run: | Set-Variable -Name FILES_TO_BE_SIGNED -Value ((Get-ChildItem -Path packages/frontend/apps/electron/out/${{ env.BUILD_TYPE }}/make -Recurse -File | Where-Object { $_.Extension -in @(".exe", ".node", ".dll", ".msi") } | ForEach-Object { '"' + $_.FullName.Replace((Get-Location).Path + '\packages\frontend\apps\electron\out\${{ env.BUILD_TYPE }}\make\', '') + '"' }) -join ' ') - "FILES_TO_BE_SIGNED=$FILES_TO_BE_SIGNED" >> $env:GITHUB_OUTPUT + "FILES_TO_BE_SIGNED_${{ matrix.spec.arch }}=$FILES_TO_BE_SIGNED" >> $env:GITHUB_OUTPUT echo $FILES_TO_BE_SIGNED - name: Save installer for signing @@ -318,22 +337,36 @@ jobs: name: installer-${{ matrix.spec.platform }}-${{ matrix.spec.arch }} path: archive.zip - sign-installer-artifacts-windows: + sign-installer-artifacts-windows-x64: needs: make-windows-installer uses: ./.github/workflows/windows-signer.yml with: - files: ${{ needs.make-windows-installer.outputs.FILES_TO_BE_SIGNED }} + files: ${{ needs.make-windows-installer.outputs.FILES_TO_BE_SIGNED_x64 }} artifact-name: installer-win32-x64 + sign-installer-artifacts-windows-arm64: + needs: make-windows-installer + uses: ./.github/workflows/windows-signer.yml + with: + files: ${{ needs.make-windows-installer.outputs.FILES_TO_BE_SIGNED_arm64 }} + artifact-name: installer-win32-arm64 + finalize-installer-windows: - needs: [sign-installer-artifacts-windows, before-make] + needs: + [ + sign-installer-artifacts-windows-x64, + sign-installer-artifacts-windows-arm64, + before-make, + ] strategy: matrix: spec: - runner: windows-latest platform: win32 arch: x64 - target: x86_64-pc-windows-msvc + - runner: windows-latest + platform: win32 + arch: arm64 runs-on: ${{ matrix.spec.runner }} steps: - name: Download and overwrite installer artifacts @@ -347,16 +380,16 @@ jobs: - name: Save artifacts run: | mkdir -p builds - mv packages/frontend/apps/electron/out/*/make/zip/win32/x64/AFFiNE*-win32-x64-*.zip ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-x64.zip - mv packages/frontend/apps/electron/out/*/make/squirrel.windows/x64/*.exe ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-x64.exe - mv packages/frontend/apps/electron/out/*/make/nsis.windows/x64/*.exe ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-x64.nsis.exe + mv packages/frontend/apps/electron/out/*/make/zip/win32/${{ matrix.spec.arch }}/AFFiNE*-win32-${{ matrix.spec.arch }}-*.zip ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.zip + mv packages/frontend/apps/electron/out/*/make/squirrel.windows/${{ matrix.spec.arch }}/*.exe ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.exe + mv packages/frontend/apps/electron/out/*/make/nsis.windows/${{ matrix.spec.arch }}/*.exe ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.nsis.exe - uses: actions/attest-build-provenance@v1 with: subject-path: | - ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-x64.zip - ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-x64.exe - ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-x64.nsis.exe + ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.zip + ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.exe + ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.nsis.exe - name: Upload Artifact uses: actions/upload-artifact@v4 @@ -391,6 +424,11 @@ jobs: with: name: affine-win32-x64-builds path: ./ + - name: Download Artifacts (windows-arm64) + uses: actions/download-artifact@v4 + with: + name: affine-win32-arm64-builds + path: ./ - name: Download Artifacts (linux-x64) uses: actions/download-artifact@v4 with: diff --git a/packages/frontend/apps/electron/scripts/make-env.ts b/packages/frontend/apps/electron/scripts/make-env.ts index 355f18a43b..ce7439d052 100644 --- a/packages/frontend/apps/electron/scripts/make-env.ts +++ b/packages/frontend/apps/electron/scripts/make-env.ts @@ -1,8 +1,12 @@ import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { parseArgs } from 'node:util'; +import debug from 'debug'; import { z } from 'zod'; +const log = debug('affine:make-env'); + const ReleaseTypeSchema = z.enum(['stable', 'beta', 'canary', 'internal']); const __dirname = fileURLToPath(new URL('.', import.meta.url)); @@ -36,15 +40,27 @@ const icnsPath = path.join( const iconPngPath = path.join(ROOT, './resources/icons/icon.png'); const iconUrl = `https://cdn.affine.pro/app-icons/icon_${buildType}.ico`; -const arch = - process.argv.indexOf('--arch') > 0 - ? process.argv[process.argv.indexOf('--arch') + 1] - : process.arch; -const platform = - process.argv.indexOf('--platform') > 0 - ? process.argv[process.argv.indexOf('--platform') + 1] - : process.platform; +log(`buildType=${buildType}, productName=${productName}, icoPath=${icoPath}`); + +const { + values: { arch, platform }, +} = parseArgs({ + options: { + arch: { + type: 'string', + description: 'The architecture to build for', + default: process.arch, + }, + platform: { + type: 'string', + description: 'The platform to build for', + default: process.platform, + }, + }, +}); + +log(`parsed args: arch=${arch}, platform=${platform}`); const appIdMap = { internal: 'pro.affine.internal', diff --git a/packages/frontend/apps/electron/scripts/make-nsis.ts b/packages/frontend/apps/electron/scripts/make-nsis.ts index 50d46a3a0b..0110d7d1cf 100644 --- a/packages/frontend/apps/electron/scripts/make-nsis.ts +++ b/packages/frontend/apps/electron/scripts/make-nsis.ts @@ -16,7 +16,7 @@ import { ROOT, } from './make-env.js'; -const log = debug('make-nsis'); +const log = debug('affine:make-nsis'); async function make() { const appName = productName; diff --git a/packages/frontend/apps/electron/scripts/make-squirrel.ts b/packages/frontend/apps/electron/scripts/make-squirrel.ts index 87c1b9a990..2e9dc969ff 100644 --- a/packages/frontend/apps/electron/scripts/make-squirrel.ts +++ b/packages/frontend/apps/electron/scripts/make-squirrel.ts @@ -15,7 +15,7 @@ import { ROOT, } from './make-env.js'; -const log = debug('make-squirrel'); +const log = debug('affine:make-squirrel'); // taking from https://github.com/electron/forge/blob/main/packages/maker/squirrel/src/MakerSquirrel.ts // it was for forge's maker, but can be used standalone as well @@ -29,6 +29,7 @@ async function make() { buildType, `${appName}-${platform}-${arch}` ); + log('making squirrel.windows: appDirectory', appDirectory); await fs.ensureDir(outPath); const packageJSON = await fs.readJson(path.resolve(ROOT, 'package.json')); @@ -40,7 +41,7 @@ async function make() { exe: `${appName}.exe`, setupExe: `${appName}-${packageJSON.version} Setup.exe`, version: packageJSON.version, - appDirectory: appDirectory, + appDirectory, outputDirectory: outPath, iconUrl: iconUrl, setupIcon: icoPath,