Skip to content

[TEST] Update Windows Cert #2466

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,19 @@ env:
- config:
# Human identifier for the job.
name: Windows
runs-on: windows-2019
runs-on: [self-hosted, windows-sign-pc]
# The value is a string representing a JSON document.
# Setting this to null causes the job to run directly in the runner machine instead of in a container.
container: |
null
# Name of the secret that contains the certificate.
certificate-secret: WINDOWS_SIGNING_CERTIFICATE_PFX
certificate-secret: INSTALLER_CERT_WINDOWS_CER
# Name of the secret that contains the certificate password.
certificate-password-secret: WINDOWS_SIGNING_CERTIFICATE_PASSWORD
certificate-password-secret: INSTALLER_CERT_WINDOWS_PASSWORD
# File extension for the certificate.
certificate-extension: pfx
# Container for windows cert signing
certificate-container: INSTALLER_CERT_WINDOWS_CONTAINER
# Quoting on the value is required here to allow the same comparison expression syntax to be used for this
# and the companion needs.select-targets.outputs.merge-channel-files property (output values always have string
# type).
Expand Down Expand Up @@ -270,6 +272,8 @@ jobs:
env:
# Location of artifacts generated by build.
BUILD_ARTIFACTS_PATH: electron-app/dist/build-artifacts
IS_WINDOWS_CONFIG: ${{ matrix.config.name == 'Windows' }}
IS_MACOS_CONFIG: ${{ matrix.config.name == 'macOS x86' }}
strategy:
matrix:
config: ${{ fromJson(needs.select-targets.outputs.build-matrix) }}
Expand All @@ -293,42 +297,42 @@ jobs:
uses: actions/checkout@v3

- name: Install Node.js
if: fromJSON(matrix.config.container) == null
if: fromJSON(matrix.config.container) == null && env.IS_WINDOWS_CONFIG == false
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: 'https://registry.npmjs.org'
cache: 'yarn'

- name: Install Python 3.x
if: fromJSON(matrix.config.container) == null
if: fromJSON(matrix.config.container) == null && env.IS_WINDOWS_CONFIG == false
uses: actions/setup-python@v5
with:
python-version: '3.11.x'

- name: Install Go
if: fromJSON(matrix.config.container) == null
if: fromJSON(matrix.config.container) == null && env.IS_WINDOWS_CONFIG == false
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}

- name: Install Go
# actions/setup-go@v5 has dependency on a higher version of glibc than available in the Linux container.
if: fromJSON(matrix.config.container) != null
if: fromJSON(matrix.config.container) != null && env.IS_WINDOWS_CONFIG == false
uses: actions/setup-go@v4
with:
go-version: ${{ env.GO_VERSION }}

- name: Install Taskfile
if: fromJSON(matrix.config.container) == null
if: fromJSON(matrix.config.container) == null && env.IS_WINDOWS_CONFIG == false
uses: arduino/setup-task@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
version: 3.x

- name: Install Taskfile
# actions/setup-task@v2 has dependency on a higher version of glibc than available in the Linux container.
if: fromJSON(matrix.config.container) != null
if: fromJSON(matrix.config.container) != null && env.IS_WINDOWS_CONFIG == false
uses: arduino/setup-task@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -352,7 +356,7 @@ jobs:
CREATE_CLIENT_SECRET: ${{ secrets.CREATE_CLIENT_SECRET }}
run: |
# See: https://www.electron.build/code-signing
if [ $CAN_SIGN = false ]; then
if [ $CAN_SIGN = false ] || [ $IS_WINDOWS_CONFIG = true ]; then
echo "Skipping the app signing: certificate not provided."
else
export CSC_LINK="${{ runner.temp }}/signing_certificate.${{ matrix.config.certificate-extension }}"
Expand All @@ -372,7 +376,7 @@ jobs:
yarn --cwd electron-app rebuild
yarn --cwd electron-app build
yarn --cwd electron-app package

# Both macOS jobs generate a "channel update info file" with same path and name. The second job to complete would
# overwrite the file generated by the first in the workflow artifact.
- name: Stage channel file for merge
Expand Down
65 changes: 42 additions & 23 deletions .github/workflows/check-certificates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,11 @@ jobs:
- identifier: macOS signing certificate # Text used to identify certificate in notifications.
certificate-secret: APPLE_SIGNING_CERTIFICATE_P12 # Name of the secret that contains the certificate.
password-secret: KEYCHAIN_PASSWORD # Name of the secret that contains the certificate password.
type: pkcs12
- identifier: Windows signing certificate
certificate-secret: WINDOWS_SIGNING_CERTIFICATE_PFX
password-secret: WINDOWS_SIGNING_CERTIFICATE_PASSWORD
certificate-secret: INSTALLER_CERT_WINDOWS_CER
# The password for the Windows certificate is not needed, because its not a container, but a single certificate.
type: x509

steps:
- name: Set certificate path environment variable
Expand All @@ -95,7 +97,7 @@ jobs:
CERTIFICATE_PASSWORD: ${{ secrets[matrix.certificate.password-secret] }}
run: |
(
openssl pkcs12 \
openssl ${{ matrix.certificate.type }} \
-in "${{ env.CERTIFICATE_PATH }}" \
-legacy \
-noout \
Expand All @@ -122,26 +124,43 @@ jobs:
CERTIFICATE_PASSWORD: ${{ secrets[matrix.certificate.password-secret] }}
id: get-days-before-expiration
run: |
EXPIRATION_DATE="$(
(
openssl pkcs12 \
-in "${{ env.CERTIFICATE_PATH }}" \
-clcerts \
-legacy \
-nodes \
-passin env:CERTIFICATE_PASSWORD
) | (
openssl x509 \
-noout \
-enddate
) | (
grep \
--max-count=1 \
--only-matching \
--perl-regexp \
'notAfter=(\K.*)'
)
)"
if [[ ${{ matrix.certificate.type }} == "pkcs12" ]]; then
EXPIRATION_DATE="$(
(
openssl pkcs12 \
-in "${{ env.CERTIFICATE_PATH }}" \
-clcerts \
-legacy \
-nodes \
-passin env:CERTIFICATE_PASSWORD
) | (
openssl x509 \
-noout \
-enddate
) | (
grep \
--max-count=1 \
--only-matching \
--perl-regexp \
'notAfter=(\K.*)'
)
)"
elif [[ ${{ matrix.certificate.type }} == "x509" ]]; then
EXPIRATION_DATE="$(
(
openssl x509 \
-in ${{ env.CERTIFICATE_PATH }} \
-noout \
-enddate
) | (
grep \
--max-count=1 \
--only-matching \
--perl-regexp \
'notAfter=(\K.*)'
)
)"
fi

DAYS_BEFORE_EXPIRATION="$((($(date --utc --date="$EXPIRATION_DATE" +%s) - $(date --utc +%s)) / 60 / 60 / 24))"

Expand Down
3 changes: 2 additions & 1 deletion electron-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@
"msi",
"nsis",
"zip"
]
],
"sign": "./scripts/windowsCustomSign.js"
},
"mac": {
"darkModeSupport": true,
Expand Down
26 changes: 26 additions & 0 deletions electron-app/scripts/windowsCustomSign.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const childProcess = require('child_process');

exports.default = async function (configuration) {
const SIGNTOOL_PATH = process.env.SIGNTOOL_PATH;
const INSTALLER_CERT_WINDOWS_CER = process.env.INSTALLER_CERT_WINDOWS_CER;
const CERT_PASSWORD = process.env.CERT_PASSWORD;
const CONTAINER_NAME = process.env.CONTAINER_NAME;
const filePath = configuration.path;

if (
SIGNTOOL_PATH &&
INSTALLER_CERT_WINDOWS_CER &&
CERT_PASSWORD &&
CONTAINER_NAME
) {
childProcess.execSync(
`"${SIGNTOOL_PATH}" sign -d "Arduino IDE" -f "${INSTALLER_CERT_WINDOWS_CER}" -csp "eToken Base Cryptographic Provider" -k "[{{${CERT_PASSWORD}}}]=${CONTAINER_NAME}" -fd sha256 -tr http://timestamp.digicert.com -td SHA256 -v "${filePath}"`,
{ stdio: 'inherit' }
);
} else {
console.warn(
'Custom windows signing was no performed: SIGNTOOL_PATH, INSTALLER_CERT_WINDOWS_CER, CERT_PASSWORD, and CONTAINER_NAME environment variables were not provided.'
);
process.exit(1);
}
};
Loading