mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-09 12:26:34 +00:00
build ide on self hosted runner
This commit is contained in:
parent
c1f1885e3c
commit
b7d1d4d80b
92
.github/workflows/build.yml
vendored
92
.github/workflows/build.yml
vendored
@ -55,7 +55,7 @@ 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: |
|
||||||
@ -75,16 +75,10 @@ env:
|
|||||||
artifacts:
|
artifacts:
|
||||||
- path: '*Windows_64bit.exe'
|
- path: '*Windows_64bit.exe'
|
||||||
name: Windows_X86-64_interactive_installer
|
name: Windows_X86-64_interactive_installer
|
||||||
- path: '*Windows_64bit_unsigned.exe'
|
|
||||||
name: Windows_X86-64_interactive_installer_unsigned
|
|
||||||
- path: '*Windows_64bit.msi'
|
- path: '*Windows_64bit.msi'
|
||||||
name: Windows_X86-64_MSI
|
name: Windows_X86-64_MSI
|
||||||
- path: '*Windows_64bit_unsigned.msi'
|
|
||||||
name: Windows_X86-64_MSI_unsigned
|
|
||||||
- path: '*Windows_64bit.zip'
|
- path: '*Windows_64bit.zip'
|
||||||
name: Windows_X86-64_zip
|
name: Windows_X86-64_zip
|
||||||
- path: '*Windows_64bit_unsigned.zip'
|
|
||||||
name: Windows_X86-64_zip_unsigned
|
|
||||||
- config:
|
- config:
|
||||||
name: Linux
|
name: Linux
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -278,6 +272,7 @@ 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
|
||||||
|
IS_WINDOWS_CONFIG: ${{ matrix.config.name == 'Windows' }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
config: ${{ fromJson(needs.select-targets.outputs.build-matrix) }}
|
config: ${{ fromJson(needs.select-targets.outputs.build-matrix) }}
|
||||||
@ -301,7 +296,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 && env.IS_WINDOWS_CONFIG == false
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ env.NODE_VERSION }}
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
@ -309,26 +304,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 && env.IS_WINDOWS_CONFIG == false
|
||||||
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 && env.IS_WINDOWS_CONFIG == false
|
||||||
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 && env.IS_WINDOWS_CONFIG == false
|
||||||
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 && env.IS_WINDOWS_CONFIG == false
|
||||||
uses: arduino/setup-task@v2
|
uses: arduino/setup-task@v2
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@ -336,7 +331,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 && env.IS_WINDOWS_CONFIG == false
|
||||||
uses: arduino/setup-task@v1
|
uses: arduino/setup-task@v1
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@ -353,7 +348,6 @@ jobs:
|
|||||||
IS_NIGHTLY: ${{ needs.build-type-determination.outputs.is-nightly }}
|
IS_NIGHTLY: ${{ needs.build-type-determination.outputs.is-nightly }}
|
||||||
IS_RELEASE: ${{ needs.build-type-determination.outputs.is-release }}
|
IS_RELEASE: ${{ needs.build-type-determination.outputs.is-release }}
|
||||||
CAN_SIGN: ${{ secrets[matrix.config.certificate-secret] != '' }}
|
CAN_SIGN: ${{ secrets[matrix.config.certificate-secret] != '' }}
|
||||||
IS_WINDOWS_CONFIG: ${{ matrix.config.name == 'Windows' }}
|
|
||||||
# The CREATE_* environment vars are only used to run tests. These secrets are optional. Dependent tests will
|
# The CREATE_* environment vars are only used to run tests. These secrets are optional. Dependent tests will
|
||||||
# be skipped if not available.
|
# be skipped if not available.
|
||||||
CREATE_USERNAME: ${{ secrets.CREATE_USERNAME }}
|
CREATE_USERNAME: ${{ secrets.CREATE_USERNAME }}
|
||||||
@ -415,76 +409,11 @@ jobs:
|
|||||||
name: ${{ env.JOB_TRANSFER_ARTIFACT }}
|
name: ${{ env.JOB_TRANSFER_ARTIFACT }}
|
||||||
path: ${{ env.BUILD_ARTIFACTS_PATH }}
|
path: ${{ env.BUILD_ARTIFACTS_PATH }}
|
||||||
|
|
||||||
sign-windows:
|
|
||||||
runs-on: [self-hosted, windows-sign-pc]
|
|
||||||
needs: build
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
env:
|
|
||||||
BUILD_ARTIFACTS_PATH: electron-app/dist/build-artifacts
|
|
||||||
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"
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Download artifact
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: ${{ env.JOB_TRANSFER_ARTIFACT }}
|
|
||||||
path: ${{ env.BUILD_ARTIFACTS_PATH }}
|
|
||||||
|
|
||||||
- name: Find and process exe and msi artifacts
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
CERT_PASSWORD: ${{ secrets.INSTALLER_CERT_WINDOWS_PASSWORD }}
|
|
||||||
CONTAINER_NAME: ${{ secrets.INSTALLER_CERT_WINDOWS_CONTAINER }}
|
|
||||||
# https://stackoverflow.com/questions/17927895/automate-extended-validation-ev-code-signing-with-safenet-etoken
|
|
||||||
run: |
|
|
||||||
shopt -s nullglob
|
|
||||||
for ARTIFACT in "${{ env.BUILD_ARTIFACTS_PATH }}"/*_unsigned.{exe,msi}; do
|
|
||||||
echo "Processing $ARTIFACT"
|
|
||||||
FILENAME=$(basename "$ARTIFACT")
|
|
||||||
BASE_NAME="${FILENAME%.*}"
|
|
||||||
EXTENSION="${FILENAME##*.}"
|
|
||||||
# Remove '_unsigned' from the base name
|
|
||||||
SIGNED_BASE_NAME="${BASE_NAME%_unsigned}"
|
|
||||||
|
|
||||||
# Sign and rename EXE and MSI files
|
|
||||||
if [[ "$EXTENSION" == "exe" || "$EXTENSION" == "msi" ]]; then
|
|
||||||
echo "Signing $ARTIFACT"
|
|
||||||
"${{ env.SIGNTOOL_PATH }}" sign -d "Arduino IDE" -f ${{ env.INSTALLER_CERT_WINDOWS_CER }} -csp "eToken Base Cryptographic Provider" -k "[{{${{ env.CERT_PASSWORD }}}}]=${{ env.CONTAINER_NAME }}" -fd sha256 -tr http://timestamp.digicert.com -td SHA256 -v "$ARTIFACT"
|
|
||||||
SIGNED_ARTIFACT_PATH="${{ env.BUILD_ARTIFACTS_PATH }}/${SIGNED_BASE_NAME}.${EXTENSION}"
|
|
||||||
mv "$ARTIFACT" "$SIGNED_ARTIFACT_PATH"
|
|
||||||
echo "Renamed $ARTIFACT to $SIGNED_ARTIFACT_PATH"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
- name: Upload signed EXE
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: Windows_X86-64_interactive_installer
|
|
||||||
path: ${{ env.BUILD_ARTIFACTS_PATH }}/*Windows_64bit.exe
|
|
||||||
|
|
||||||
- name: Upload signed MSI
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: Windows_X86-64_MSI
|
|
||||||
path: ${{ env.BUILD_ARTIFACTS_PATH }}/*Windows_64bit.msi
|
|
||||||
|
|
||||||
# This step is needed because the self hosted runner does not delete files automatically
|
|
||||||
- name: Clean up artifacts
|
|
||||||
run: rm -rf ${{ env.BUILD_ARTIFACTS_PATH }}
|
|
||||||
|
|
||||||
merge-channel-files:
|
merge-channel-files:
|
||||||
needs:
|
needs:
|
||||||
- build-type-determination
|
- build-type-determination
|
||||||
- select-targets
|
- select-targets
|
||||||
- build
|
- build
|
||||||
- sign-windows
|
|
||||||
if: needs.select-targets.outputs.merge-channel-files == 'true'
|
if: needs.select-targets.outputs.merge-channel-files == 'true'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions: {}
|
permissions: {}
|
||||||
@ -548,7 +477,6 @@ jobs:
|
|||||||
needs:
|
needs:
|
||||||
- select-targets
|
- select-targets
|
||||||
- build
|
- build
|
||||||
- sign-windows
|
|
||||||
if: always() && needs.build.result != 'skipped'
|
if: always() && needs.build.result != 'skipped'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
@ -573,7 +501,6 @@ jobs:
|
|||||||
needs:
|
needs:
|
||||||
- build-type-determination
|
- build-type-determination
|
||||||
- build
|
- build
|
||||||
- sign-windows
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
BODY: ${{ steps.changelog.outputs.BODY }}
|
BODY: ${{ steps.changelog.outputs.BODY }}
|
||||||
@ -623,7 +550,6 @@ jobs:
|
|||||||
- build-type-determination
|
- build-type-determination
|
||||||
- merge-channel-files
|
- merge-channel-files
|
||||||
- changelog
|
- changelog
|
||||||
- sign-windows
|
|
||||||
if: >
|
if: >
|
||||||
always() &&
|
always() &&
|
||||||
needs.build-type-determination.result == 'success' &&
|
needs.build-type-determination.result == 'success' &&
|
||||||
@ -657,7 +583,6 @@ jobs:
|
|||||||
- build-type-determination
|
- build-type-determination
|
||||||
- merge-channel-files
|
- merge-channel-files
|
||||||
- changelog
|
- changelog
|
||||||
- sign-windows
|
|
||||||
if: >
|
if: >
|
||||||
always() &&
|
always() &&
|
||||||
needs.build-type-determination.result == 'success' &&
|
needs.build-type-determination.result == 'success' &&
|
||||||
@ -709,7 +634,6 @@ jobs:
|
|||||||
- publish
|
- publish
|
||||||
- release
|
- release
|
||||||
- artifacts
|
- artifacts
|
||||||
- sign-windows
|
|
||||||
if: always() && needs.build.result != 'skipped'
|
if: always() && needs.build.result != 'skipped'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
@ -133,7 +133,8 @@
|
|||||||
"msi",
|
"msi",
|
||||||
"nsis",
|
"nsis",
|
||||||
"zip"
|
"zip"
|
||||||
]
|
],
|
||||||
|
"sign": "./scripts/windowsCustomSign.js"
|
||||||
},
|
},
|
||||||
"mac": {
|
"mac": {
|
||||||
"darkModeSupport": true,
|
"darkModeSupport": true,
|
||||||
|
@ -100,7 +100,7 @@ async function getArtifactName(version) {
|
|||||||
switch (platform) {
|
switch (platform) {
|
||||||
case 'win32': {
|
case 'win32': {
|
||||||
if (arch === 'x64') {
|
if (arch === 'x64') {
|
||||||
return `${name}_${version}_Windows_64bit_unsigned.\$\{ext}`;
|
return `${name}_${version}_Windows_64bit.\$\{ext}`;
|
||||||
}
|
}
|
||||||
throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
|
throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
|
||||||
}
|
}
|
||||||
|
26
electron-app/scripts/windowsCustomSign.js
Normal file
26
electron-app/scripts/windowsCustomSign.js
Normal file
@ -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…
x
Reference in New Issue
Block a user