Skip to content

Commit 74e49ab

Browse files
author
drsk
committed
COR-1627: streamline windows node signing process
- Moves the signing of the libraries and executables into the build script - Avoids repacking of cabinet files
1 parent 54025da commit 74e49ab

File tree

2 files changed

+244
-1
lines changed

2 files changed

+244
-1
lines changed
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
name: Windows signing streamlining
2+
3+
on:
4+
push:
5+
push:
6+
branches:cor_1627_streamline_windows_signing_process/windows
7+
8+
env:
9+
UBUNTU_VERSION: '22.04'
10+
STATIC_LIBRARIES_IMAGE_TAG: 'rust-1.82_ghc-9.10.2'
11+
RUST_VERSION: '1.82'
12+
STACK_VERSION: '3.7.1'
13+
FLATBUFFERS_VERSION: '23.5.26'
14+
GHC_VERSION: '9.10.2'
15+
PROTOC_VERSION: '28.3'
16+
STATIC_NODE_BINARY_IMAGE_NAME: 'static-node-binaries'
17+
DOCKER_ARTIFACT_NAME: 'image'
18+
AWS_ROLE_TO_ASSUME: 'arn:aws:iam::192549843005:role/github_concordium-node'
19+
S3_ARN_TEMPLATES: '{
20+
\"database-exporter\": {\"bucket\": \"distribution.concordium.software\", \"dir\": \"tools/linux\", \"name\": \"database-exporter_${VERSION}.deb\"},
21+
\"p2p-bootstrapper\": {\"bucket\": \"distribution.concordium.software\", \"dir\": \"tools/linux\", \"name\": \"p2p-bootstrapper_${VERSION}.deb\"},
22+
\"node-stagenet-linux\": {\"bucket\": \"distribution.stagenet.concordium.com\", \"dir\": \"deb\", \"name\": \"concordium-stagenet-node_${VERSION}_amd64.deb\"},
23+
\"node-flynet-linux\": {\"bucket\": \"distribution.flynet.concordium.com\", \"dir\": \"deb\", \"name\": \"concordium-flynet-node_${VERSION}_amd64.deb\"},
24+
\"node-testnet-linux\": {\"bucket\": \"distribution.testnet.concordium.com\", \"dir\": \"deb\", \"name\": \"concordium-testnet-node_${VERSION}_amd64.deb\"},
25+
\"node-mainnet-linux\": {\"bucket\": \"distribution.mainnet.concordium.software\", \"dir\": \"deb\", \"name\": \"concordium-mainnet-node_${VERSION}_amd64.deb\"},
26+
\"node-macos\": {\"bucket\": \"distribution.concordium.software\", \"dir\": \"macos\", \"name\": \"concordium-node-${VERSION}.pkg\"},
27+
\"node-windows\": {\"bucket\": \"distribution.concordium.software\", \"dir\": \"windows\", \"name\": \"Node-${VERSION}.msi\"}
28+
}'
29+
DOCKER_TAGS_TEMPLATES: '{
30+
\"docker-stagenet\": \"concordium/stagenet-node:${VERSION}\",
31+
\"docker-testnet\": \"concordium/testnet-node:${VERSION}\",
32+
\"docker-mainnet\": \"concordium/mainnet-node:${VERSION}\",
33+
\"docker-bootstrapper\": \"concordium/bootstrapper:${VERSION}\"
34+
}'
35+
REGISTRY: docker.io
36+
SERVICE: "${{ inputs.service }}"
37+
38+
permissions:
39+
id-token: write
40+
contents: read
41+
42+
jobs:
43+
44+
validate-preconditions:
45+
runs-on: ubuntu-latest
46+
outputs:
47+
s3_arns: ${{ steps.render.outputs.s3_arns }}
48+
docker_tags: ${{ steps.render.outputs.docker_tags }}
49+
release_type: ${{ steps.versions_derivation.outputs.release_type }}
50+
base_version: ${{ steps.versions_derivation.outputs.base_version }}
51+
version: ${{ steps.versions_derivation.outputs.version }}
52+
steps:
53+
- name: Checkout Repository
54+
uses: actions/checkout@v4
55+
56+
- name: Validate version
57+
id: versions_derivation
58+
run: |
59+
CARGO_VERSION=$(yq .package.version concordium-node/Cargo.toml)
60+
if [ -z "${{ env.SERVICE }}" ]; then
61+
IFS='-' read -r VERSION BUILD RELEASE_TYPE <<< "${{ github.ref_name }}"
62+
# if [ ! "$VERSION" = "$CARGO_VERSION" ]; then
63+
# echo "::error::${CARGO_VERSION} does not match ${VERSION}."
64+
# exit 1
65+
# fi
66+
else
67+
RELEASE_TYPE="${{ env.SERVICE }}"
68+
BUILD=$(git rev-parse --short HEAD)
69+
fi
70+
echo "::notice::RELEASE_TYPE=${RELEASE_TYPE}"
71+
echo "release_type=${RELEASE_TYPE}" >> "$GITHUB_OUTPUT"
72+
echo "version=${CARGO_VERSION}-${BUILD}" >> "$GITHUB_OUTPUT"
73+
echo "base_version=${CARGO_VERSION}" >> "$GITHUB_OUTPUT"
74+
- name: Templates rendering
75+
id: render
76+
run: |
77+
export VERSION="${{ steps.versions_derivation.outputs.version }}"
78+
echo "s3_arns=${{ env.S3_ARN_TEMPLATES }}" >> $GITHUB_OUTPUT
79+
echo "docker_tags=${{ env.DOCKER_TAGS_TEMPLATES }}" >> $GITHUB_OUTPUT
80+
81+
node-windows:
82+
runs-on: windows-latest
83+
# TODO (drsk) the next line needs to be in again after testing !!!
84+
# environment: release # This step needs to use the release context to access credentials for code signing.
85+
needs: [validate-preconditions]
86+
if: contains(fromJSON('["rc", "alpha", "node-windows"]'), needs.validate-preconditions.outputs.release_type)
87+
defaults:
88+
run:
89+
shell: pwsh
90+
steps:
91+
- name: Checkout Repository
92+
uses: actions/checkout@v4
93+
with:
94+
submodules: recursive
95+
96+
- name: Install dependencies
97+
run: |
98+
choco install yq jq -y
99+
shell: bash
100+
101+
- name: Extrapolate artifact name
102+
run: |
103+
ARTIFACT_NAME=$(echo '${{ needs.validate-preconditions.outputs.s3_arns }}' | jq -r '.["${{ github.job }}"].name')
104+
echo "ARTIFACT_NAME=${ARTIFACT_NAME}" >> $GITHUB_ENV
105+
shell: bash
106+
107+
- name: Install DigiCert Client tools (Windows only)
108+
id: digicert_client
109+
uses: digicert/[email protected]
110+
111+
- name: Import Windows certificate (Windows only)
112+
id: windows_certificate
113+
env:
114+
# Base64 encoding of the pfx/p12 certificate for Windows code signing.
115+
SM_CLIENT_CERT_FILE_B64: ${{ secrets.WINDOWS_SM_CLIENT_CERT_FILE_B64 }}
116+
run: |
117+
$CERTIFICATE_PATH_BASE64="$env:RUNNER_TEMP\cert-b64.txt"
118+
$CERTIFICATE_PATH="$env:RUNNER_TEMP\cert.pfx"
119+
120+
Set-Content -Path $CERTIFICATE_PATH_BASE64 -Value $env:SM_CLIENT_CERT_FILE_B64
121+
certutil -decode $CERTIFICATE_PATH_BASE64 $CERTIFICATE_PATH
122+
echo "CERTIFICATE_PATH=$CERTIFICATE_PATH" >> $env:GITHUB_OUTPUT
123+
124+
- name: Run smctl healthcheck to confirm if the tool is configured properly.
125+
working-directory: ${{steps.build.outputs.bin_dir}}
126+
env:
127+
WINDOWS_PKCS11_CONFIG: ${{ steps.digicert_client.outputs.PKCS11_CONFIG }}
128+
WINDOWS_SM_KEYPAIR_ALIAS: ${{ secrets.WINDOWS_SM_KEYPAIR_ALIAS }}
129+
SM_HOST: ${{ vars.WINDOWS_SM_HOST }}
130+
SM_API_KEY: ${{ secrets.WINDOWS_SM_API_KEY }}
131+
SM_CLIENT_CERT_FILE: ${{ steps.windows_certificate.outputs.CERTIFICATE_PATH }}
132+
SM_CLIENT_CERT_PASSWORD: ${{ secrets.WINDOWS_SM_CLIENT_CERT_PASSWORD }}
133+
run: |
134+
smctl healthcheck --all
135+
shell: cmd
136+
137+
- name: Install Rust
138+
uses: actions-rust-lang/setup-rust-toolchain@v1
139+
with:
140+
toolchain: ${{ env.RUST_VERSION }}-x86_64-pc-windows-msvc
141+
142+
- name: Install Rust
143+
uses: actions-rust-lang/setup-rust-toolchain@v1
144+
with:
145+
toolchain: ${{ env.RUST_VERSION }}-x86_64-pc-windows-gnu
146+
147+
- name: Setup node folder
148+
run: |
149+
mkdir -p "C:/Program Files/node/include"
150+
Add-Content -Path $env:GITHUB_PATH -Value "C:/Program Files/node"
151+
152+
- name: Install flatbuffers
153+
run: |
154+
curl -L -O https://github.com/google/flatbuffers/releases/download/v${{ env.FLATBUFFERS_VERSION }}/Windows.flatc.binary.zip
155+
unzip Windows.flatc.binary.zip
156+
mv flatc.exe "C:/Program Files/node/"
157+
158+
- name: Install protobuf (protoc)
159+
run: |
160+
curl -L -O https://github.com/protocolbuffers/protobuf/releases/download/v${{ env.PROTOC_VERSION }}/protoc-${{ env.PROTOC_VERSION }}-win64.zip
161+
unzip protoc-${{ env.PROTOC_VERSION }}-win64.zip
162+
mv bin/protoc.exe "C:/Program Files/node/"
163+
mv include/* "C:/Program Files/node/include"
164+
165+
- name: Setup Haskell
166+
uses: haskell-actions/setup@v2
167+
with:
168+
ghc-version: ${{ env.GHC_VERSION }}
169+
enable-stack: true
170+
stack-version: ${{ env.STACK_VERSION }}
171+
172+
- uses: milliewalky/setup-7-zip@v1
173+
174+
- name: Install GCC
175+
run: |
176+
curl -L -O https://github.com/brechtsanders/winlibs_mingw/releases/download/14.2.0posix-19.1.1-12.0.0-msvcrt-r2/winlibs-x86_64-posix-seh-gcc-14.2.0-llvm-19.1.1-mingw-w64msvcrt-12.0.0-r2.7z
177+
7z x winlibs-x86_64-posix-seh-gcc-14.2.0-llvm-19.1.1-mingw-w64msvcrt-12.0.0-r2.7z -oC:/gcc
178+
Add-Content -Path $env:GITHUB_PATH -Value "C:/gcc/mingw64/bin"
179+
180+
- name: Install LMDB
181+
run: stack exec -- pacman -S --noconfirm mingw-w64-x86_64-lmdb
182+
183+
- name: Build and Sign Windows Node
184+
env:
185+
WINDOWS_PKCS11_CONFIG: ${{ steps.digicert_client.outputs.PKCS11_CONFIG }}
186+
WINDOWS_SM_KEYPAIR_ALIAS: ${{ secrets.WINDOWS_SM_KEYPAIR_ALIAS }}
187+
SM_HOST: ${{ vars.WINDOWS_SM_HOST }}
188+
SM_API_KEY: ${{ secrets.WINDOWS_SM_API_KEY }}
189+
SM_CLIENT_CERT_FILE: ${{ steps.windows_certificate.outputs.CERTIFICATE_PATH }}
190+
SM_CLIENT_CERT_PASSWORD: ${{ secrets.WINDOWS_SM_CLIENT_CERT_PASSWORD }}
191+
SM_ARGS: "--verbose --exit-non-zero-on-fail --failfast"
192+
run: |
193+
./scripts/distribution/windows/build-all.ps1 -nodeVersion ${{ needs.validate-preconditions.outputs.version }} -rustVersion ${{ env.RUST_VERSION }}
194+
195+
- name: Sign installer with smctl
196+
working-directory: ${{steps.build.outputs.bin_dir}}
197+
env:
198+
WINDOWS_PKCS11_CONFIG: ${{ steps.digicert_client.outputs.PKCS11_CONFIG }}
199+
WINDOWS_SM_KEYPAIR_ALIAS: ${{ secrets.WINDOWS_SM_KEYPAIR_ALIAS }}
200+
SM_HOST: ${{ vars.WINDOWS_SM_HOST }}
201+
SM_API_KEY: ${{ secrets.WINDOWS_SM_API_KEY }}
202+
SM_CLIENT_CERT_FILE: ${{ steps.windows_certificate.outputs.CERTIFICATE_PATH }}
203+
SM_CLIENT_CERT_PASSWORD: ${{ secrets.WINDOWS_SM_CLIENT_CERT_PASSWORD }}
204+
SM_ARGS: "--verbose --exit-non-zero-on-fail --failfast"
205+
run: |
206+
smctl sign --keypair-alias ${{ env.WINDOWS_SM_KEYPAIR_ALIAS }} --input ./service/windows/installer/Node.msi --config-file ${{ env.WINDOWS_PKCS11_CONFIG }} ${{ env.SM_ARGS }}
207+
shell: cmd
208+
209+
- name: Rename the package to target filename.
210+
run: |
211+
cp ./service/windows/installer/Node.msi ./${{ env.ARTIFACT_NAME }}
212+
213+
- name: Upload artifact
214+
uses: actions/upload-artifact@v4
215+
with:
216+
name: ${{ github.job }}
217+
path: ${{ env.ARTIFACT_NAME }}

scripts/distribution/windows/build-all.ps1

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,30 @@ cargo +$rustVersion-x86_64-pc-windows-msvc build --release --locked
3030
Pop-Location
3131
if ($LASTEXITCODE -ne 0) { throw "Failed building node runner service" }
3232

33-
service\windows\installer\build.ps1 -toolchain $rustVersion-x86_64-pc-windows-msvc -nodeVersion $nodeVersion
33+
# Sign files if smctl is available and necessary environment variables are set.
34+
if ($env:WINDOWS_SM_KEYPAIR_ALIAS -and $env:WINDOWS_PKCS11_CONFIG -and $env:SM_ARGS -and (Get-Command "smctl" -ErrorAction SilentlyContinue)) {
35+
36+
# Move to the location of the script so that relative paths make sense
37+
Push-Location $PSScriptRoot
38+
39+
$StackInstallRoot = stack path --local-install-root
40+
41+
try {
42+
smctl sign --keypair-alias $env:WINDOWS_SM_KEYPAIR_ALIAS --input .\$StackInstallRoot\lib\ConcordiumConsensusDLL --config-file $env:WINDOWS_PKCS11_CONFIG $env:SM_ARGS
43+
smctl sign --keypair-alias $env:WINDOWS_SM_KEYPAIR_ALIAS --input ..\..\..\concordium-base\lib\ConcordiumBaseDLL --config-file $env:WINDOWS_PKCS11_CONFIG $env:SM_ARGS
44+
smctl sign --keypair-alias $env:WINDOWS_SM_KEYPAIR_ALIAS --input ..\..\..\concordium-base\smart-contracts\lib\ConcordiumSmartContractEngineDLL --config-file $env:WINDOWS_PKCS11_CONFIG $env:SM_ARGS
45+
smctl sign --keypair-alias $env:WINDOWS_SM_KEYPAIR_ALIAS --input ..\..\..\concordium-base\lib\Sha2DLL.dll --config-file $env:WINDOWS_PKCS11_CONFIG $env:SM_ARGS
46+
smctl sign --keypair-alias $env:WINDOWS_SM_KEYPAIR_ALIAS --input ..\target\x86_64-pc-windows-msvc\release\NodeRunnerService --config-file $env:WINDOWS_PKCS11_CONFIG $env:SM_ARGS
47+
smctl sign --keypair-alias $env:WINDOWS_SM_KEYPAIR_ALIAS --input ..\..\..\collector\target\release\NodeCollector --config-file $env:WINDOWS_PKCS11_CONFIG $env:SM_ARGS
48+
smctl sign --keypair-alias $env:WINDOWS_SM_KEYPAIR_ALIAS --input ..\..\..\concordium-node\target\release\ConcordiumNode --config-file $env:WINDOWS_PKCS11_CONFIG $env:SM_ARGS
49+
}
50+
finally{
51+
Pop-Location
52+
}
53+
54+
} else {
55+
Write-Output "Not signing: Missing required environment variables or smctl utility missing. WINDOWS_SM_KEYPAIR_ALIAS, WINDOWS_PKCS11_CONFIG, SM_ARGS need to be set."
56+
}
57+
58+
# Build the installer
59+
service\windows\installer\build.ps1 -toolchain $rustVersion-x86_64-pc-windows-msvc -nodeVersion $nodeVersion

0 commit comments

Comments
 (0)