diff --git a/.github/actions/build-zui/action.yml b/.github/actions/build-zui/action.yml index 5877eff3c7..5cf895a8cc 100644 --- a/.github/actions/build-zui/action.yml +++ b/.github/actions/build-zui/action.yml @@ -8,9 +8,13 @@ inputs: required: true # Windows Inputs - csc_key_password: + ssl_com_username: required: true - csc_link: + ssl_com_password: + required: true + ssl_com_totp_secret: + required: true + ssl_com_credential_id: required: true # Mac Inputs @@ -47,16 +51,38 @@ runs: security find-identity -p codesigning -v shell: bash + - name: Checkout esigner-codesign repository + if: runner.os == 'Windows' + uses: actions/checkout@v3 + with: + repository: 'SSLcom/esigner-codesign' + path: esigner-codesign + + - name: Expose the Artifact Path + id: paths + run: echo "artifact=$(yarn artifact-path)" >> "$GITHUB_OUTPUT" + shell: bash + - name: Build & Publish run: ${{ inputs.cmd }} shell: bash env: GH_TOKEN: ${{ inputs.gh_token }} - WIN_CSC_KEY_PASSWORD: ${{ inputs.csc_key_password }} - WIN_CSC_LINK: ${{ inputs.csc_link }} APPLE_ID: ${{ inputs.apple_id }} APPLE_ID_PASSWORD: ${{ inputs.apple_id_password }} APPLE_TEAM_ID: ${{ inputs.apple_team_id }} + CODE_SIGN_SCRIPT_PATH: ${{ github.workspace }}/esigner-codesign/dist/index.js + INPUT_FILE_PATH: ${{ steps.paths.outputs.artifact }} + INPUT_USERNAME: ${{ inputs.ssl_com_username }} + INPUT_PASSWORD: ${{ inputs.ssl_com_password }} + INPUT_TOTP_SECRET: ${{ inputs.ssl_com_totp_secret }} + INPUT_CREDENTIAL_ID: ${{ inputs.ssl_com_credential_id }} + + - name: Check for successful signing with SignTool + if: runner.os == 'Windows' + run: | + "C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\signtool.exe" verify /pa "${{ steps.paths.outputs.artifact }}" + shell: cmd - name: Check notorization with gatekeeper if: runner.os == 'macOS' diff --git a/.github/workflows/build-insiders.yml b/.github/workflows/build-insiders.yml index d992bc9671..36ed7106b8 100644 --- a/.github/workflows/build-insiders.yml +++ b/.github/workflows/build-insiders.yml @@ -56,8 +56,10 @@ jobs: cmd: yarn nx package-insiders zui gh_token: ${{ secrets.PAT_TOKEN }} # Windows - csc_key_password: ${{ secrets.WINDOWS_SIGNING_PASSPHRASE }} - csc_link: ${{ secrets.WINDOWS_SIGNING_PFX_BASE64 }} + ssl_com_username: ${{ secrets.WINDOWS_SIGNING_SSL_COM_USERNAME }} + ssl_com_password: ${{ secrets.WINDOWS_SIGNING_SSL_COM_PASSWORD }} + ssl_com_totp_secret: ${{ secrets.WINDOWS_SIGNING_SSL_COM_TOTP_SECRET }} + ssl_com_credential_id: ${{ secrets.WINDOWS_SIGNING_SSL_COM_CREDENTIAL_ID }} # Mac apple_id: ${{ secrets.APPLEID_USER }} apple_id_password: ${{ secrets.APPLEID_PASSWORD }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 957eefd265..8d5fc25e06 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,8 +25,10 @@ jobs: cmd: yarn nx package-zui zui gh_token: ${{ secrets.GITHUB_TOKEN }} # Windows - csc_key_password: ${{ secrets.WINDOWS_SIGNING_PASSPHRASE }} - csc_link: ${{ secrets.WINDOWS_SIGNING_PFX_BASE64 }} + ssl_com_username: ${{ secrets.WINDOWS_SIGNING_SSL_COM_USERNAME }} + ssl_com_password: ${{ secrets.WINDOWS_SIGNING_SSL_COM_PASSWORD }} + ssl_com_totp_secret: ${{ secrets.WINDOWS_SIGNING_SSL_COM_TOTP_SECRET }} + ssl_com_credential_id: ${{ secrets.WINDOWS_SIGNING_SSL_COM_CREDENTIAL_ID }} # Mac apple_id: ${{ secrets.APPLEID_USER }} apple_id_password: ${{ secrets.APPLEID_PASSWORD }} diff --git a/.github/workflows/release-insiders.yml b/.github/workflows/release-insiders.yml index d1b731b1a4..6a1e581416 100644 --- a/.github/workflows/release-insiders.yml +++ b/.github/workflows/release-insiders.yml @@ -56,8 +56,10 @@ jobs: cmd: yarn nx release-insiders zui gh_token: ${{ secrets.PAT_TOKEN }} # Windows - csc_key_password: ${{ secrets.WINDOWS_SIGNING_PASSPHRASE }} - csc_link: ${{ secrets.WINDOWS_SIGNING_PFX_BASE64 }} + ssl_com_username: ${{ secrets.WINDOWS_SIGNING_SSL_COM_USERNAME }} + ssl_com_password: ${{ secrets.WINDOWS_SIGNING_SSL_COM_PASSWORD }} + ssl_com_totp_secret: ${{ secrets.WINDOWS_SIGNING_SSL_COM_TOTP_SECRET }} + ssl_com_credential_id: ${{ secrets.WINDOWS_SIGNING_SSL_COM_CREDENTIAL_ID }} # Mac apple_id: ${{ secrets.APPLEID_USER }} apple_id_password: ${{ secrets.APPLEID_PASSWORD }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b94f2e9487..0ec9586cae 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,8 +25,10 @@ jobs: cmd: yarn nx release-zui zui gh_token: ${{ secrets.GITHUB_TOKEN }} # Windows - csc_key_password: ${{ secrets.WINDOWS_SIGNING_PASSPHRASE }} - csc_link: ${{ secrets.WINDOWS_SIGNING_PFX_BASE64 }} + ssl_com_username: ${{ secrets.WINDOWS_SIGNING_SSL_COM_USERNAME }} + ssl_com_password: ${{ secrets.WINDOWS_SIGNING_SSL_COM_PASSWORD }} + ssl_com_totp_secret: ${{ secrets.WINDOWS_SIGNING_SSL_COM_TOTP_SECRET }} + ssl_com_credential_id: ${{ secrets.WINDOWS_SIGNING_SSL_COM_CREDENTIAL_ID }} # Mac apple_id: ${{ secrets.APPLEID_USER }} apple_id_password: ${{ secrets.APPLEID_PASSWORD }} diff --git a/apps/zui/electron-builder.json b/apps/zui/electron-builder.json index 9ed8a20ca3..4830d1e82b 100644 --- a/apps/zui/electron-builder.json +++ b/apps/zui/electron-builder.json @@ -4,6 +4,11 @@ "asarUnpack": ["zdeps", "LICENSE.txt", "acknowledgments.txt", "**/*.node"], "directories": {"output": "../../dist/apps/zui"}, "protocols": [{"name": "zui", "schemes": ["zui"]}], + "win": { + "target": ["nsis"], + "signingHashAlgorithms": ["sha256"], + "sign": "./scripts/sign.js" + }, "linux": {"target": ["deb", "rpm"]}, "rpm": {"depends": ["openssl"]}, "deb": {"depends": ["openssl"]}, diff --git a/apps/zui/scripts/artifact.js b/apps/zui/scripts/artifact.js new file mode 100644 index 0000000000..7da4f67104 --- /dev/null +++ b/apps/zui/scripts/artifact.js @@ -0,0 +1,18 @@ +const pkg = require("../package.json") +const {join} = require("node:path") + +class Artifact { + get name() { + return `${pkg.productName} Setup ${pkg.version}.exe` + } + + get dir() { + return join(__dirname, "../../../dist/apps/zui") + } + + get path() { + return join(this.dir, this.name) + } +} + +module.exports = new Artifact() diff --git a/apps/zui/scripts/sign.js b/apps/zui/scripts/sign.js new file mode 100644 index 0000000000..02c721a763 --- /dev/null +++ b/apps/zui/scripts/sign.js @@ -0,0 +1,55 @@ +const {execSync} = require("child_process") +const artifact = require("./artifact") + +// Code below for code signing with SSL.com cert in electron-builder via GitHub +// Inspired from this comment: +// https://github.com/electron-userland/electron-builder/issues/6158#issuecomment-1994110062 + +function sign() { + const scriptPath = process.env.CODE_SIGN_SCRIPT_PATH + process.env.INPUT_COMMAND = "sign" + process.env.INPUT_OVERRIDE = "true" + process.env.INPUT_MALWARE_BLOCK = "false" + process.env.INPUT_CLEAN_LOGS = "false" + process.env.INPUT_JVM_MAX_MEMORY = "1024M" + process.env.INPUT_ENVIRONMENT_NAME = "PROD" + + try { + const output = execSync(`node "${scriptPath}"`).toString() + console.log(`Signing Output: ${output}`) + return true + } catch (error) { + console.error(`Signing Error: ${error.message}`) + if (error.stdout) { + console.log(`Signing Stdout: ${error.stdout.toString()}`) + } + if (error.stderr) { + console.error(`Signing Stderr: ${error.stderr.toString()}`) + } + return false + } +} + +function shouldSign(filePath) { + if (filePath !== artifact.path) { + console.log("Signing Skipped: path not in whitelist '", filePath, "'") + return false + } else { + console.log("Signing Started: '" + filePath + "'") + return true + } +} + +exports.default = async function (configuration) { + if (!process.env.CODE_SIGN_SCRIPT_PATH) { + console.log( + "Signing Skipped: no script path provided in CODE_SIGN_SCRIPT_PATH" + ) + return true + } + if (shouldSign(configuration.path)) { + return sign() + } else { + return true + } +} diff --git a/package.json b/package.json index 6cbb628aa9..8d23713f35 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "test": "nx run-many -t test --all --exclude zui-player --skip-nx-cache", "start": "nx start zui", "e2e": "NODE_ENV=production nx test zui-player", - "e2e:ci": "NODE_ENV=production nx ci zui-player" + "e2e:ci": "NODE_ENV=production nx ci zui-player", + "artifact-path": "node tools/scripts/artifact-path.js" }, "devDependencies": { "@nx-go/nx-go": "^2.7.0", diff --git a/tools/scripts/artifact-path.js b/tools/scripts/artifact-path.js new file mode 100644 index 0000000000..637d2caba2 --- /dev/null +++ b/tools/scripts/artifact-path.js @@ -0,0 +1,3 @@ +const artifact = require('../../apps/zui/scripts/artifact'); + +console.log(artifact.path);