mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-06-12 07:06:32 +00:00
[chore] Update Windows signing Cert to eToken (#2452)
This commit is contained in:
parent
aa9b10d68e
commit
2e78e96b75
56
.github/workflows/build.yml
vendored
56
.github/workflows/build.yml
vendored
@ -55,21 +55,28 @@ env:
|
|||||||
- config:
|
- config:
|
||||||
# Human identifier for the job.
|
# Human identifier for the job.
|
||||||
name: Windows
|
name: Windows
|
||||||
runs-on: windows-2019
|
runs-on: [self-hosted, windows-sign-pc]
|
||||||
# The value is a string representing a JSON document.
|
# 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.
|
# Setting this to null causes the job to run directly in the runner machine instead of in a container.
|
||||||
container: |
|
container: |
|
||||||
null
|
null
|
||||||
# Name of the secret that contains the certificate.
|
# 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.
|
# 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.
|
# File extension for the certificate.
|
||||||
certificate-extension: pfx
|
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
|
# 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
|
# and the companion needs.select-targets.outputs.merge-channel-files property (output values always have string
|
||||||
# type).
|
# type).
|
||||||
mergeable-channel-file: 'false'
|
mergeable-channel-file: 'false'
|
||||||
|
# as this runs on a self hosted runner, we need to avoid building with the default working directory path,
|
||||||
|
# otherwise paths in the build job will be too long for `light.exe`
|
||||||
|
# we use the below as a Symbolic link (just changing the wd will break the checkout action)
|
||||||
|
# this is a work around (see: https://github.com/actions/checkout/issues/197).
|
||||||
|
working-directory: 'C:\a'
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: '*Windows_64bit.exe'
|
- path: '*Windows_64bit.exe'
|
||||||
name: Windows_X86-64_interactive_installer
|
name: Windows_X86-64_interactive_installer
|
||||||
@ -270,6 +277,14 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
# Location of artifacts generated by build.
|
# Location of artifacts generated by build.
|
||||||
BUILD_ARTIFACTS_PATH: electron-app/dist/build-artifacts
|
BUILD_ARTIFACTS_PATH: electron-app/dist/build-artifacts
|
||||||
|
# to skip passing signing credentials to electron-builder
|
||||||
|
IS_WINDOWS_CONFIG: ${{ matrix.config.name == 'Windows' }}
|
||||||
|
INSTALLER_CERT_WINDOWS_CER: "/tmp/cert.cer"
|
||||||
|
# We are hardcoding the path for signtool because is not present on the windows PATH env var by default.
|
||||||
|
# Keep in mind that this path could change when upgrading to a new runner version
|
||||||
|
SIGNTOOL_PATH: "C:/Program Files (x86)/Windows Kits/10/bin/10.0.19041.0/x86/signtool.exe"
|
||||||
|
WIN_CERT_PASSWORD: ${{ secrets.INSTALLER_CERT_WINDOWS_PASSWORD }}
|
||||||
|
WIN_CERT_CONTAINER_NAME: ${{ secrets.INSTALLER_CERT_WINDOWS_CONTAINER }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
config: ${{ fromJson(needs.select-targets.outputs.build-matrix) }}
|
config: ${{ fromJson(needs.select-targets.outputs.build-matrix) }}
|
||||||
@ -283,6 +298,12 @@ jobs:
|
|||||||
timeout-minutes: 90
|
timeout-minutes: 90
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Symlink custom working directory
|
||||||
|
shell: cmd
|
||||||
|
if: runner.os == 'Windows' && matrix.config.working-directory
|
||||||
|
run: |
|
||||||
|
if not exist "${{ matrix.config.working-directory }}" mklink /d "${{ matrix.config.working-directory }}" "C:\actions-runner\_work\arduino-ide\arduino-ide"
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
if: fromJSON(matrix.config.container) == null
|
if: fromJSON(matrix.config.container) == null
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@ -293,7 +314,7 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install Node.js
|
- name: Install Node.js
|
||||||
if: fromJSON(matrix.config.container) == null
|
if: fromJSON(matrix.config.container) == null && runner.os != 'Windows'
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ env.NODE_VERSION }}
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
@ -301,26 +322,26 @@ jobs:
|
|||||||
cache: 'yarn'
|
cache: 'yarn'
|
||||||
|
|
||||||
- name: Install Python 3.x
|
- name: Install Python 3.x
|
||||||
if: fromJSON(matrix.config.container) == null
|
if: fromJSON(matrix.config.container) == null && runner.os != 'Windows'
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.11.x'
|
python-version: '3.11.x'
|
||||||
|
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
if: fromJSON(matrix.config.container) == null
|
if: fromJSON(matrix.config.container) == null && runner.os != 'Windows'
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ${{ env.GO_VERSION }}
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
# actions/setup-go@v5 has dependency on a higher version of glibc than available in the Linux container.
|
# 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 && runner.os != 'Windows'
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: ${{ env.GO_VERSION }}
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
||||||
- name: Install Taskfile
|
- name: Install Taskfile
|
||||||
if: fromJSON(matrix.config.container) == null
|
if: fromJSON(matrix.config.container) == null && runner.os != 'Windows'
|
||||||
uses: arduino/setup-task@v2
|
uses: arduino/setup-task@v2
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@ -328,7 +349,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Taskfile
|
- name: Install Taskfile
|
||||||
# actions/setup-task@v2 has dependency on a higher version of glibc than available in the Linux container.
|
# 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 && runner.os != 'Windows'
|
||||||
uses: arduino/setup-task@v1
|
uses: arduino/setup-task@v1
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@ -350,9 +371,10 @@ jobs:
|
|||||||
CREATE_USERNAME: ${{ secrets.CREATE_USERNAME }}
|
CREATE_USERNAME: ${{ secrets.CREATE_USERNAME }}
|
||||||
CREATE_PASSWORD: ${{ secrets.CREATE_PASSWORD }}
|
CREATE_PASSWORD: ${{ secrets.CREATE_PASSWORD }}
|
||||||
CREATE_CLIENT_SECRET: ${{ secrets.CREATE_CLIENT_SECRET }}
|
CREATE_CLIENT_SECRET: ${{ secrets.CREATE_CLIENT_SECRET }}
|
||||||
|
working-directory: ${{ runner.os == 'Windows' && matrix.config.working-directory || './' }}
|
||||||
run: |
|
run: |
|
||||||
# See: https://www.electron.build/code-signing
|
# 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."
|
echo "Skipping the app signing: certificate not provided."
|
||||||
else
|
else
|
||||||
export CSC_LINK="${{ runner.temp }}/signing_certificate.${{ matrix.config.certificate-extension }}"
|
export CSC_LINK="${{ runner.temp }}/signing_certificate.${{ matrix.config.certificate-extension }}"
|
||||||
@ -372,13 +394,14 @@ jobs:
|
|||||||
yarn --cwd electron-app rebuild
|
yarn --cwd electron-app rebuild
|
||||||
yarn --cwd electron-app build
|
yarn --cwd electron-app build
|
||||||
yarn --cwd electron-app package
|
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
|
# 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.
|
# overwrite the file generated by the first in the workflow artifact.
|
||||||
- name: Stage channel file for merge
|
- name: Stage channel file for merge
|
||||||
if: >
|
if: >
|
||||||
needs.select-targets.outputs.merge-channel-files == 'true' &&
|
needs.select-targets.outputs.merge-channel-files == 'true' &&
|
||||||
matrix.config.mergeable-channel-file == 'true'
|
matrix.config.mergeable-channel-file == 'true'
|
||||||
|
working-directory: ${{ runner.os == 'Windows' && matrix.config.working-directory || './' }}
|
||||||
run: |
|
run: |
|
||||||
staged_channel_files_path="${{ runner.temp }}/staged-channel-files"
|
staged_channel_files_path="${{ runner.temp }}/staged-channel-files"
|
||||||
mkdir "$staged_channel_files_path"
|
mkdir "$staged_channel_files_path"
|
||||||
@ -398,13 +421,20 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
name: ${{ env.STAGED_CHANNEL_FILES_ARTIFACT }}
|
name: ${{ env.STAGED_CHANNEL_FILES_ARTIFACT }}
|
||||||
path: ${{ env.STAGED_CHANNEL_FILES_PATH }}
|
path: ${{ runner.os == 'Windows' && matrix.config.working-directory && format('{0}/{1}', matrix.config.working-directory, env.STAGED_CHANNEL_FILES_PATH) || env.STAGED_CHANNEL_FILES_PATH }}
|
||||||
|
|
||||||
|
|
||||||
- name: Upload [GitHub Actions]
|
- name: Upload [GitHub Actions]
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{ env.JOB_TRANSFER_ARTIFACT }}
|
name: ${{ env.JOB_TRANSFER_ARTIFACT }}
|
||||||
path: ${{ env.BUILD_ARTIFACTS_PATH }}
|
path: ${{ runner.os == 'Windows' && matrix.config.working-directory && format('{0}/{1}', matrix.config.working-directory, env.BUILD_ARTIFACTS_PATH) || env.BUILD_ARTIFACTS_PATH }}
|
||||||
|
|
||||||
|
- name: Manual Clean up for self-hosted runners
|
||||||
|
if: runner.os == 'Windows' && matrix.config.working-directory
|
||||||
|
shell: cmd
|
||||||
|
run: |
|
||||||
|
rmdir /s /q "${{ matrix.config.working-directory }}\${{ env.BUILD_ARTIFACTS_PATH }}"
|
||||||
|
|
||||||
merge-channel-files:
|
merge-channel-files:
|
||||||
needs:
|
needs:
|
||||||
|
65
.github/workflows/check-certificates.yml
vendored
65
.github/workflows/check-certificates.yml
vendored
@ -74,9 +74,11 @@ jobs:
|
|||||||
- identifier: macOS signing certificate # Text used to identify certificate in notifications.
|
- 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.
|
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.
|
password-secret: KEYCHAIN_PASSWORD # Name of the secret that contains the certificate password.
|
||||||
|
type: pkcs12
|
||||||
- identifier: Windows signing certificate
|
- identifier: Windows signing certificate
|
||||||
certificate-secret: WINDOWS_SIGNING_CERTIFICATE_PFX
|
certificate-secret: INSTALLER_CERT_WINDOWS_CER
|
||||||
password-secret: WINDOWS_SIGNING_CERTIFICATE_PASSWORD
|
# The password for the Windows certificate is not needed, because its not a container, but a single certificate.
|
||||||
|
type: x509
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set certificate path environment variable
|
- name: Set certificate path environment variable
|
||||||
@ -95,7 +97,7 @@ jobs:
|
|||||||
CERTIFICATE_PASSWORD: ${{ secrets[matrix.certificate.password-secret] }}
|
CERTIFICATE_PASSWORD: ${{ secrets[matrix.certificate.password-secret] }}
|
||||||
run: |
|
run: |
|
||||||
(
|
(
|
||||||
openssl pkcs12 \
|
openssl ${{ matrix.certificate.type }} \
|
||||||
-in "${{ env.CERTIFICATE_PATH }}" \
|
-in "${{ env.CERTIFICATE_PATH }}" \
|
||||||
-legacy \
|
-legacy \
|
||||||
-noout \
|
-noout \
|
||||||
@ -122,26 +124,43 @@ jobs:
|
|||||||
CERTIFICATE_PASSWORD: ${{ secrets[matrix.certificate.password-secret] }}
|
CERTIFICATE_PASSWORD: ${{ secrets[matrix.certificate.password-secret] }}
|
||||||
id: get-days-before-expiration
|
id: get-days-before-expiration
|
||||||
run: |
|
run: |
|
||||||
EXPIRATION_DATE="$(
|
if [[ ${{ matrix.certificate.type }} == "pkcs12" ]]; then
|
||||||
(
|
EXPIRATION_DATE="$(
|
||||||
openssl pkcs12 \
|
(
|
||||||
-in "${{ env.CERTIFICATE_PATH }}" \
|
openssl pkcs12 \
|
||||||
-clcerts \
|
-in "${{ env.CERTIFICATE_PATH }}" \
|
||||||
-legacy \
|
-clcerts \
|
||||||
-nodes \
|
-legacy \
|
||||||
-passin env:CERTIFICATE_PASSWORD
|
-nodes \
|
||||||
) | (
|
-passin env:CERTIFICATE_PASSWORD
|
||||||
openssl x509 \
|
) | (
|
||||||
-noout \
|
openssl x509 \
|
||||||
-enddate
|
-noout \
|
||||||
) | (
|
-enddate
|
||||||
grep \
|
) | (
|
||||||
--max-count=1 \
|
grep \
|
||||||
--only-matching \
|
--max-count=1 \
|
||||||
--perl-regexp \
|
--only-matching \
|
||||||
'notAfter=(\K.*)'
|
--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))"
|
DAYS_BEFORE_EXPIRATION="$((($(date --utc --date="$EXPIRATION_DATE" +%s) - $(date --utc +%s)) / 60 / 60 / 24))"
|
||||||
|
|
||||||
|
@ -133,7 +133,8 @@
|
|||||||
"msi",
|
"msi",
|
||||||
"nsis",
|
"nsis",
|
||||||
"zip"
|
"zip"
|
||||||
]
|
],
|
||||||
|
"sign": "./scripts/windowsCustomSign.js"
|
||||||
},
|
},
|
||||||
"mac": {
|
"mac": {
|
||||||
"darkModeSupport": true,
|
"darkModeSupport": true,
|
||||||
|
30
electron-app/scripts/windowsCustomSign.js
Normal file
30
electron-app/scripts/windowsCustomSign.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
const childProcess = require('child_process');
|
||||||
|
|
||||||
|
exports.default = async function (configuration) {
|
||||||
|
if (!process.env.GITHUB_ACTIONS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SIGNTOOL_PATH = process.env.SIGNTOOL_PATH;
|
||||||
|
const INSTALLER_CERT_WINDOWS_CER = process.env.INSTALLER_CERT_WINDOWS_CER;
|
||||||
|
const CERT_PASSWORD = process.env.WIN_CERT_PASSWORD;
|
||||||
|
const CONTAINER_NAME = process.env.WIN_CERT_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 one of the following variables was not provided: SIGNTOOL_PATH (${SIGNTOOL_PATH}), INSTALLER_CERT_WINDOWS_CERT (${INSTALLER_CERT_WINDOWS_CER}), CERT_PASSWORD (${CERT_PASSWORD}), CONTAINER_NAME (${CONTAINER_NAME})`
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user