diff --git a/.github/workflows/release-draft.yml b/.github/workflows/release-draft.yml new file mode 100644 index 00000000..cf843acb --- /dev/null +++ b/.github/workflows/release-draft.yml @@ -0,0 +1,97 @@ +name: release-draft + +on: + workflow_dispatch: + workflow_call: + push: + # branches: + # - main + +env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +jobs: + run-test: + uses: platformatic/meraki/.github/workflows/test.yml@main + + release-linux: + needs: run-test + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/setup-node@v3 + with: + node-version: 18 + - run: npm ci + - run: npm run build:linux + - run: npm run release:linux + + release-windows: + needs: run-test + runs-on: windows-latest + timeout-minutes: 15 + env: + DIGICERT_FINGERPRINT: ${{ secrets.SM_CODE_SIGNING_CERT_SHA1_HASH }} + SM_HOST: ${{ secrets.SM_HOST }} + SM_API_KEY: ${{ secrets.SM_API_KEY }} + SM_CLIENT_CERT_FILE: D:\\Certificate_pkcs12.p12 + SM_CLIENT_CERT_PASSWORD: ${{ secrets.SM_CLIENT_CERT_PASSWORD }} + steps: + - name: Set up certificate + run: | + echo "${{ secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12 + shell: bash + + - name: Set variables + id: variables + run: | + dir + echo "::set-output name=version::${GITHUB_REF#refs/tags/v}" + echo "::set-output name=CERTIFICATE_NAME::gt-certificate" + echo "C:\Program Files (x86)\Windows Kits\10\App Certification Kit" >> $GITHUB_PATH + echo "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools" >> $GITHUB_PATH + echo "C:\Program Files\DigiCert\DigiCert Keylocker Tools" >> $GITHUB_PATH + shell: bash + + - name: Setup Keylocker KSP on windows + run: | + curl -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/Keylockertools-windows-x64.msi/download -H "x-api-key:%SM_API_KEY%" -o Keylockertools-windows-x64.msi + msiexec /i Keylockertools-windows-x64.msi /quiet /qn + smksp_registrar.exe list + smctl.exe keypair ls + C:\Windows\System32\certutil.exe -csp "DigiCert Signing Manager KSP" -key -user + shell: cmd + + - name: Certificates Sync + run: | + smctl windows certsync + shell: cmd + + - name: SMCTL healthcheck + run: | + smctl healthcheck + shell: cmd + + - uses: actions/setup-node@v3 + with: + node-version: 18 + + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - run: npm ci + - run: npm run build:win + - run: npm run release:win + + release-mac: + needs: run-test + runs-on: macos-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/setup-node@v3 + with: + node-version: 18 + - run: npm ci + - run: npm run build + - run: npm run release:mac + diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index c75c96f1..00000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: release - -on: - workflow_dispatch: - workflow_call: - push: - branches: - - main - -env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - -jobs: - release-linux: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@v3 - with: - node-version: 18 - - run: npm ci - - run: npm run build:linux - - run: npm run release:linux - - release-windows: - runs-on: windows-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@v3 - with: - node-version: 18 - - run: npm ci - - run: npm run build:win - - run: npm run release:win - - release-mac: - runs-on: macos-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@v3 - with: - node-version: 18 - - run: npm ci - - run: npm run build - - run: npm run release:mac - diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml deleted file mode 100644 index c79a6188..00000000 --- a/.github/workflows/releases.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: release - -on: - workflow_dispatch: - workflow_call: - -jobs: - release-linux: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - run: echo "linux release not implemented yet" - - release-win: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - run: echo "win release not implemented yet" - - release-mac: - runs-on: macos-latest - timeout-minutes: 15 - steps: - - run: echo "win release not implemented yet" - - diff --git a/electron-builder.yml b/electron-builder.yml index 070f4b6f..03874e2e 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -13,7 +13,7 @@ asarUnpack: win: executableName: meraki icon: build/icon.png - sign: ./sign-win/sign-win.js + sign: ./sign-win.js nsis: artifactName: ${productName}-${version}-setup.${ext} shortcutName: ${productName} diff --git a/sign-win.js b/sign-win.js new file mode 100644 index 00000000..b02339d8 --- /dev/null +++ b/sign-win.js @@ -0,0 +1,24 @@ +// This is a callback that can be used to sign the executable on Windows. +// See: https://www.electron.build/configuration/win +// We are using this callback instead of the electron-builder built-in mechanism +// because we want to use the DigiCert signing tool to sign the executable. +// See also: https://docs.digicert.com/en/digicert-keylocker/sign-with-digicert-signing-tools/sign-with-smctl.html +exports.default = async function (configuration) { + const { execa } = await import('execa') + console.log('Signing: ', configuration.path) + const execPath = configuration.path + const { stdout, exitCode } = await execa('smctl', [ + 'sign', + '--fingerprint', + process.env.DIGICERT_FINGERPRINT, + '--input', + execPath + ]) + // `smctl` returns exit code 0 even if the signing fails :(. ) + // So we need to check the output for errors. + // See also: https://docs.digicert.com/en/digicert-keylocker/sign-with-digicert-signing-tools/sign-with-smctl.html + if (stdout.includes('FAILED')) { + console.error('Signing failed:', stdout, exitCode) + throw new Error(stdout) + } +} diff --git a/sign-win/README.md b/sign-win/README.md deleted file mode 100644 index 010567a5..00000000 --- a/sign-win/README.md +++ /dev/null @@ -1 +0,0 @@ -See: https://www.electron.build/tutorials/code-signing-windows-apps-on-unix#signing-windows-app-on-maclinux-using-jsign diff --git a/sign-win/hardwareToken.cfg b/sign-win/hardwareToken.cfg deleted file mode 100644 index 8ae27a34..00000000 --- a/sign-win/hardwareToken.cfg +++ /dev/null @@ -1,4 +0,0 @@ -name = HardwareToken -# Check the path on linux -library = /Library/Frameworks/eToken.framework/Versions/A/libeToken.dylib -slotListIndex = 0 diff --git a/sign-win/jsign-5.0.jar b/sign-win/jsign-5.0.jar deleted file mode 100644 index f39f9fe5..00000000 Binary files a/sign-win/jsign-5.0.jar and /dev/null differ diff --git a/sign-win/sign-win.js b/sign-win/sign-win.js deleted file mode 100644 index d2dfd6b5..00000000 --- a/sign-win/sign-win.js +++ /dev/null @@ -1,18 +0,0 @@ -exports.default = async function (configuration) { - const CERTIFICATE_NAME = process.env.WINDOWS_SIGN_CERTIFICATE_NAME - const TOKEN_PASSWORD = process.env.WINDOWS_SIGN_TOKEN_PASSWORD - - if (!CERTIFICATE_NAME || !TOKEN_PASSWORD) { - console.log('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@') - console.log('Missing environment variable WINDOWS_SIGN_CERTIFICATE_NAME or TOKEN_PASSWORD, NOT signing!') - console.log('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@') - return - } - - require('child_process').execSync( - `java -jar ./sign-win/jsign-5.0.jar --keystore hardwareToken.cfg --storepass "${TOKEN_PASSWORD}" --storetype PKCS11 --tsaurl http://timestamp.digicert.com --alias "${CERTIFICATE_NAME}" "${configuration.path}"`, - { - stdio: 'inherit' - } - ) -}