diff --git a/.github/workflows/manual-release.yml b/.github/workflows/manual-release.yml index bee66ef..0891f73 100644 --- a/.github/workflows/manual-release.yml +++ b/.github/workflows/manual-release.yml @@ -57,6 +57,14 @@ jobs: env: MODE: production + # Download 'SSLcom/esigner-codesign' to a folder called 'esigner-codesign' in the root of the project + - name: Checkout esigner-codesign repository (Windows) + if: ${{github.ref == 'refs/heads/main' && matrix.os == 'windows-latest'}} + uses: actions/checkout@v3 + with: + repository: 'SSLcom/esigner-codesign' + path: esigner-codesign + - name: Compile artifacts and upload them to GitHub release # I use this action because it is capable of retrying multiple times if there are any issues with the distribution server uses: nick-fields/retry@v3 @@ -66,9 +74,7 @@ jobs: retry_wait_seconds: 15 retry_on: error shell: 'bash' - # Due to this issue https://github.com/electron-userland/electron-builder/issues/6411 the build with npx when rebuilding native dependencies hangs forever - # see https://github.com/cawa-93/vite-electron-builder/pull/953 - command: ./node_modules/.bin/electron-builder --config electron-builder.yml -c.extraMetadata.version=${{ github.event.inputs.version }} -c.mac.notarize.teamId=${{ env.APPLE_TEAM_ID }} --publish always + command: npx electron-builder --config electron-builder.cjs -c.extraMetadata.version=${{ github.event.inputs.version }} -c.mac.notarize.teamId=${{ env.APPLE_TEAM_ID }} --publish always env: # Code Signing params # See https://www.electron.build/code-signing @@ -81,23 +87,16 @@ jobs: APPLE_TEAM_ID: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }} # Publishing artifacts GH_TOKEN: ${{ secrets.github_token }} # GitHub token, automatically provided (No need to define this secret in the repo settings) - - - name: Sign Windows Build (exe) - uses: sslcom/esigner-codesign@develop - if: ${{ github.ref == 'refs/heads/main' && matrix.os == 'windows-latest' }} - with: - command: sign - username: ${{ secrets.ES_USERNAME }} - password: ${{ secrets.ES_PASSWORD }} - credential_id: ${{ secrets.WINDOWS_CREDENTIAL_ID_SIGNER }} - totp_secret: ${{ secrets.ES_TOTP_SECRET }} - file_path: "${{ env.GITHUB_WORKSPACE }}/dist/Decentraland Launcher-win-x64.exe" - output_path: "${{ env.GITHUB_WORKSPACE }}/dist/signed" - malware_block: false - environment_name: PROD - - - name: Replace signed exe - if: ${{ github.ref == 'refs/heads/main' && matrix.os == 'windows-latest' }} - shell: pwsh - run: | - Copy-Item -Path "${env:GITHUB_WORKSPACE}\dist\signed\Decentraland Launcher-win-x64.exe" -Destination "${env:GITHUB_WORKSPACE}\dist\Decentraland Launcher-win-x64.exe" -Force + # The following are the parameters required by the esigner-codesign action to work, we must explicitly pass in even the optional ones since we're not using the action directly, but from the checked out repo + CODE_SIGN_SCRIPT_PATH: "${{ github.workspace }}\\esigner-codesign\\dist\\index.js" + INPUT_COMMAND: "sign" + INPUT_FILE_PATH: "${{ github.workspace }}\\dist\\Decentraland Launcher-win-x64.exe" + INPUT_OVERRIDE: "true" + INPUT_MALWARE_BLOCK: "false" + INPUT_CLEAN_LOGS: "false" + INPUT_JVM_MAX_MEMORY: "1024M" + INPUT_ENVIRONMENT_NAME: "PROD" + INPUT_USERNAME: ${{ secrets.ES_USERNAME }} + INPUT_PASSWORD: ${{ secrets.ES_PASSWORD }} + INPUT_TOTP_SECRET: ${{ secrets.ES_TOTP_SECRET }} + INPUT_CREDENTIAL_ID: ${{ secrets.WINDOWS_CREDENTIAL_ID_SIGNER }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9ff25ac..14f69d4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -95,6 +95,14 @@ jobs: search_commit_body: true user_format_type: "json" + # Download 'SSLcom/esigner-codesign' to a folder called 'esigner-codesign' in the root of the project + - name: Checkout esigner-codesign repository (Windows) + if: ${{github.ref == 'refs/heads/main' && matrix.os == 'windows-latest' && !inputs.dry-run}} + uses: actions/checkout@v3 + with: + repository: 'SSLcom/esigner-codesign' + path: esigner-codesign + - name: Compile artifacts ${{ inputs.dry-run && '' || 'and upload them to github release' }} # I use this action because it is capable of retrying multiple times if there are any issues with the distribution server uses: nick-fields/retry@v3 @@ -104,9 +112,7 @@ jobs: retry_wait_seconds: 15 retry_on: error shell: 'bash' - # Due to this issue https://github.com/electron-userland/electron-builder/issues/6411 the build with npx when rebuilding native dependencies hangs forever - # see https://github.com/cawa-93/vite-electron-builder/pull/953 - command: ./node_modules/.bin/electron-builder --config electron-builder.yml -c.extraMetadata.version=${{ steps.version.outputs.version }} -c.mac.notarize.teamId=${{ env.APPLE_TEAM_ID }} --publish ${{ inputs.dry-run && 'never' || 'always' }} + command: npx electron-builder --config electron-builder.cjs -c.extraMetadata.version=${{ steps.version.outputs.version }} -c.mac.notarize.teamId=${{ env.APPLE_TEAM_ID }} --publish ${{ inputs.dry-run && 'never' || 'always' }} env: # Code Signing params # See https://www.electron.build/code-signing @@ -119,23 +125,17 @@ jobs: APPLE_TEAM_ID: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }} # Publishing artifacts GH_TOKEN: ${{ secrets.github_token }} # GitHub token, automatically provided (No need to define this secret in the repo settings) + # The following are the parameters required by the esigner-codesign action to work, we must explicitly pass in even the optional ones since we're not using the action directly, but from the checked out repo + CODE_SIGN_SCRIPT_PATH: "${{ github.workspace }}\\esigner-codesign\\dist\\index.js" + INPUT_COMMAND: "sign" + INPUT_FILE_PATH: "${{ github.workspace }}\\dist\\Decentraland Launcher-win-x64.exe" + INPUT_OVERRIDE: "true" + INPUT_MALWARE_BLOCK: "false" + INPUT_CLEAN_LOGS: "false" + INPUT_JVM_MAX_MEMORY: "1024M" + INPUT_ENVIRONMENT_NAME: "PROD" + INPUT_USERNAME: ${{ secrets.ES_USERNAME }} + INPUT_PASSWORD: ${{ secrets.ES_PASSWORD }} + INPUT_TOTP_SECRET: ${{ secrets.ES_TOTP_SECRET }} + INPUT_CREDENTIAL_ID: ${{ secrets.WINDOWS_CREDENTIAL_ID_SIGNER }} - - name: Sign Windows Build (exe) - uses: sslcom/esigner-codesign@develop - if: ${{github.ref == 'refs/heads/main' && matrix.os == 'windows-latest' && !inputs.dry-run}} - with: - command: sign - username: ${{ secrets.ES_USERNAME }} - password: ${{ secrets.ES_PASSWORD }} - credential_id: ${{ secrets.WINDOWS_CREDENTIAL_ID_SIGNER }} - totp_secret: ${{ secrets.ES_TOTP_SECRET }} - file_path: ${GITHUB_WORKSPACE}/dist/Decentraland Launcher-win-x64.exe - output_path: ${GITHUB_WORKSPACE}/dist/signed - malware_block: false - environment_name: PROD - - - name: Replace signed exe - if: ${{github.ref == 'refs/heads/main' && matrix.os == 'windows-latest' && !inputs.dry-run}} - shell: pwsh - run: | - Copy-Item -Path "${env:GITHUB_WORKSPACE}\dist\signed\Decentraland Launcher-win-x64.exe" -Destination "${env:GITHUB_WORKSPACE}\dist\Decentraland Launcher-win-x64.exe" -Force diff --git a/electron-builder.cjs b/electron-builder.cjs new file mode 100644 index 0000000..27e2691 --- /dev/null +++ b/electron-builder.cjs @@ -0,0 +1,147 @@ +const { execSync } = require('child_process'); + +const config = { + productName: 'Decentraland Launcher', + artifactName: 'Decentraland Launcher-${os}-${arch}.${ext}', + executableName: 'Decentraland Launcher', + directories: { + output: 'dist', + buildResources: 'buildResources', + }, + files: ['packages/**/dist/**'], + win: { + publisherName: 'Decentraland Foundation', + appId: 'Decentraland.Launcher', + icon: 'buildResources/icon.ico', + target: [ + { + target: 'nsis', + arch: ['x64'], + }, + ], + verifyUpdateCodeSignature: false, + signAndEditExecutable: true, + signingHashAlgorithms: ['sha256'], + rfc3161TimeStampServer: 'http://ts.ssl.com', + timeStampServer: 'http://ts.ssl.com', + extraResources: ['buildResources/icon.ico'], + }, + nsis: { + allowElevation: true, + allowToChangeInstallationDirectory: true, + createDesktopShortcut: true, + oneClick: false, + perMachine: true, + deleteAppDataOnUninstall: true, + include: 'buildResources/scripts/windowsInstaller.nsh', + installerSidebar: 'buildResources/background.bmp', + installerIcon: 'buildResources/icon.ico', + }, + mac: { + appId: 'com.Decentraland.Launcher', + icon: 'buildResources/icon.icns', + target: [ + { + target: 'default', + arch: ['x64', 'arm64'], + }, + ], + hardenedRuntime: true, + entitlements: 'buildResources/entitlements.mac.plist', + extendInfo: [ + { + NSMicrophoneUsageDescription: 'Need microphone access to use voice chat in the application', + }, + ], + extraResources: ['icon.icns'], + }, + dmg: { + title: 'Decentraland Launcher Installer', + background: 'buildResources/background.png', + window: { + width: 714, + height: 472, + }, + contents: [ + { + x: 230, + y: 215, + type: 'file', + }, + { + x: 460, + y: 215, + type: 'link', + path: '/Applications', + }, + ], + }, + publish: [ + { + provider: 'github', + vPrefixedTagName: false, + }, + ], + protocols: [ + { + name: 'decentraland', + schemes: ['decentraland'], + }, + ], +}; + +// Sign Windows .exe +if (process.env.CODE_SIGN_SCRIPT_PATH) { + config.win.sign = configuration => { + console.log('Requested signing for ', configuration.path); + + // Only proceed if the installer .exe file is in the configuration path - skip signing everything else + if (!configuration.path.endsWith('Decentraland Launcher-win-x64.exe')) { + console.log('This is not the installer .exe, skip signing'); + return true; + } + + const scriptPath = process.env.CODE_SIGN_SCRIPT_PATH; + + try { + // Execute the sign script synchronously + process.env.INPUT_COMMAND = 'sign'; // override the INPUT_COMMAND, it is already set in the "env" of the GitHub Action step, but for some reason it gets overwritten with 'npx electron-builder ...' so we must set it to 'sign' + process.env.INPUT_FILE_PATH = configuration.path; // set the file path to the installer .exe + const env = { + command: process.env.INPUT_COMMAND, + username: process.env.INPUT_USERNAME, + password: process.env.INPUT_PASSWORD, + credential_id: process.env.INPUT_CREDENTIAL_ID, + totp_secret: process.env.INPUT_TOTP_SECRET, + file_path: process.env.INPUT_FILE_PATH, + output_path: process.env.INPUT_OUTPUT_PATH, + malware_block: process.env.INPUT_MALWARE_BLOCK, + override: process.env.INPUT_OVERRIDE, + clean_logs: process.env.INPUT_CLEAN_LOGS, + environment_name: process.env.INPUT_ENVIRONMENT_NAME, + jvm_max_memory: process.env.INPUT_JVM_MAX_MEMORY, + }; + console.log('env:', JSON.stringify(env, null, 2)); + const output = execSync(`node "${scriptPath}"`, { + env: { ...process.env, ...env }, + }).toString(); + console.log(`Script output: ${output}`); + } catch (error) { + console.error(`Error executing script: ${error.message}`); + if (error.stdout) { + console.log(`Script stdout: ${error.stdout.toString()}`); + } + if (error.stderr) { + console.error(`Script stderr: ${error.stderr.toString()}`); + } + return false; + } + + return true; // Return true at the end of successful signing + }; + + // sign only for Windows 10 and above - adjust for your code as needed + config.win.signingHashAlgorithms = ['sha256']; +} + +module.exports = config; diff --git a/electron-builder.yml b/electron-builder.yml deleted file mode 100644 index 1874440..0000000 --- a/electron-builder.yml +++ /dev/null @@ -1,76 +0,0 @@ -productName: Decentraland Launcher -artifactName: "Decentraland Launcher-${os}-${arch}.${ext}" -executableName: Decentraland Launcher - -directories: - output: dist - buildResources: buildResources - -files: - - packages/**/dist/** - -win: - publisherName: "Decentraland Foundation" - appId: Decentraland.Launcher - icon: buildResources/icon.ico - target: - - target: nsis - arch: - - x64 - verifyUpdateCodeSignature: false - signAndEditExecutable: true - signingHashAlgorithms: - - sha256 - rfc3161TimeStampServer: "http://ts.ssl.com" - timeStampServer: "http://ts.ssl.com" - extraResources: - - buildResources/icon.ico - -nsis: - allowElevation: true - allowToChangeInstallationDirectory: true - createDesktopShortcut: true - oneClick: false - perMachine: true - deleteAppDataOnUninstall: true - include: buildResources/scripts/windowsInstaller.nsh - installerSidebar: buildResources/background.bmp - installerIcon: buildResources/icon.ico - -mac: - appId: com.Decentraland.Launcher - icon: buildResources/icon.icns - target: - - target: default - arch: - - x64 - - arm64 - hardenedRuntime: true - entitlements: buildResources/entitlements.mac.plist - extendInfo: - - NSMicrophoneUsageDescription: "Need microphone access to use voice chat in the application" - extraResources: - - icon.icns - -dmg: - title: Decentraland Launcher Installer - background: buildResources/background.png - window: - width: 714 - height: 472 - contents: - - x: 230 - y: 215 - type: file - - x: 460 - y: 215 - type: link - path: /Applications - -publish: - - provider: github - vPrefixedTagName: false - -protocols: - - name: decentraland - schemes: ["decentraland"] diff --git a/package.json b/package.json index 8dac1e5..59f0eba 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "build:preload": "cd ./packages/preload && vite build", "build:renderer": "cd ./packages/renderer && vite build", "build:shared": "cd ./packages/shared && vite build", - "compile": "cross-env MODE=production npm run build && electron-builder build --config electron-builder.yml --dir", - "compile:installer": "rm -rf ./dist/ && cross-env MODE=production npm run build && electron-builder build --config electron-builder.yml --publish never", + "compile": "cross-env MODE=production npm run build && electron-builder build --config electron-builder.cjs --dir", + "compile:installer": "rm -rf ./dist/ && cross-env MODE=production npm run build && electron-builder build --config electron-builder.cjs --publish never", "test": "npm run test:main && npm run test:preload && npm run test:renderer && npm run test:e2e", "test:e2e": "npm run build && vitest run", "test:main": "vitest run -r packages/main --passWithNoTests", @@ -83,4 +83,4 @@ "tar": "^7.4.3", "uuid": "^10.0.0" } -} +} \ No newline at end of file