Skip to content

Commit 5db2cbd

Browse files
authored
Merge pull request #59 from browserstack/LOC-6563-cd-kms-signing
CD: migrate nupkg signing from PFX to GCP KMS via Jsign (LOC-6563)
2 parents 085ce6a + d901df4 commit 5db2cbd

3 files changed

Lines changed: 83 additions & 17 deletions

File tree

.github/workflows/cd.yml

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,34 +26,50 @@ jobs:
2626
uses: actions/setup-dotnet@v3
2727
with:
2828
dotnet-version: 6.0.x
29+
- name: Setup GCP credentials
30+
working-directory: ${{ github.workspace }}
31+
run: |
32+
printf '%s' "$GCP_SA_KEY_RAW" > $RUNNER_TEMP/gcp-sa-key.json
33+
chmod 600 $RUNNER_TEMP/gcp-sa-key.json
34+
echo "GOOGLE_APPLICATION_CREDENTIALS=$RUNNER_TEMP/gcp-sa-key.json" >> $GITHUB_ENV
35+
env:
36+
GCP_SA_KEY_RAW: ${{ secrets.GCP_SA_KEY }}
37+
shell: bash
38+
- name: Install google-auth
39+
working-directory: ${{ github.workspace }}
40+
run: python3 -m pip install google-auth requests
41+
shell: bash
42+
- name: Setup Java
43+
uses: actions/setup-java@v4
44+
with:
45+
distribution: 'temurin'
46+
java-version: '17'
2947
- name: Run Integration Tests
3048
env:
3149
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
3250
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
3351
run: dotnet test BrowserStackLocalIntegrationTests --no-build -p:Configuration=Release
3452
- name: Pack NuGet Package
3553
run: msbuild BrowserStackLocal -t:pack -p:Configuration=Release
36-
- name: Setup nuget
37-
uses: nuget/setup-nuget@v1
38-
with:
39-
nuget-api-key: ${{ secrets.NUGET_API_KEY }}
40-
nuget-version: '5.x'
41-
- name: Create PFX certificate
42-
id: createPfx
43-
shell: pwsh
44-
env:
45-
PFX_CONTENT: ${{ secrets.BASE64_PFX_CONTENT }}
46-
run: |
47-
$pfxPath = Join-Path -Path $env:RUNNER_TEMP -ChildPath "cert.pfx";
48-
$encodedBytes = [System.Convert]::FromBase64String($env:PFX_CONTENT);
49-
Set-Content $pfxPath -Value $encodedBytes -AsByteStream;
50-
Write-Output "::set-output name=PFX_PATH::$pfxPath";
5154
- name: Sign Nuget Package
52-
run: nuget sign .\BrowserStackLocal\bin\Release\*.nupkg -certificatePath "${{ steps.createPfx.outputs.PFX_PATH }}" -certificatePassword "${{secrets.CERT_PASSWORD}}" -Timestamper "http://timestamp.comodoca.com"
55+
working-directory: ${{ github.workspace }}
56+
run: |
57+
chmod +x ./scripts/sign_nupkg.sh
58+
./scripts/sign_nupkg.sh
59+
shell: bash
5360
- name: Save artifact
5461
uses: actions/upload-artifact@v4
5562
with:
5663
name: BrowserStackLocal.nupkg
5764
path: .\BrowserStackLocal\BrowserStackLocal\bin\Release\*.nupkg
5865
- name: Push package to Nuget Repository
59-
run: nuget push **\*.nupkg -Source 'https://api.nuget.org/v3/index.json' -ApiKey ${{secrets.NUGET_API_KEY}}
66+
working-directory: ${{ github.workspace }}
67+
run: dotnet nuget push BrowserStackLocal/BrowserStackLocal/bin/Release/*.nupkg --api-key "$NUGET_API_KEY" --source https://api.nuget.org/v3/index.json
68+
env:
69+
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
70+
shell: bash
71+
- name: Cleanup credentials
72+
if: always()
73+
working-directory: ${{ github.workspace }}
74+
run: rm -f $RUNNER_TEMP/gcp-sa-key.json
75+
shell: bash

comodo_signing_cert.crt

1.57 KB
Binary file not shown.

scripts/sign_nupkg.sh

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/bin/bash
2+
set -e
3+
4+
if [ -z "$GOOGLE_APPLICATION_CREDENTIALS" ] || [ ! -f "$GOOGLE_APPLICATION_CREDENTIALS" ]; then
5+
echo "ERROR: GOOGLE_APPLICATION_CREDENTIALS is not set or file does not exist"
6+
exit 1
7+
fi
8+
9+
# Exchange SA credentials for an OAuth access token scoped to cloudkms.
10+
# gcloud is NOT installed on windows-latest runners; google-auth Python lib
11+
# is the reliable path (see browserstack-csharp-sdk PR #704 for the
12+
# enumeration of failed alternatives).
13+
GCP_ACCESS_TOKEN=$(python3 -c "
14+
import google.auth
15+
import google.auth.transport.requests
16+
creds, _ = google.auth.default(scopes=['https://www.googleapis.com/auth/cloudkms'])
17+
creds.refresh(google.auth.transport.requests.Request())
18+
print(creds.token)
19+
")
20+
21+
# Download Jsign 7.0 + SHA-256 verify (supply-chain integrity).
22+
JSIGN_VERSION="7.0"
23+
JSIGN_SHA256="325df319621e7fa74384c8852efdb5828871bf6405648a4c621ee5fc37c59b6c"
24+
curl -fsL "https://github.com/ebourg/jsign/releases/download/${JSIGN_VERSION}/jsign-${JSIGN_VERSION}.jar" -o jsign.jar
25+
echo "${JSIGN_SHA256} jsign.jar" | sha256sum -c - || { echo "ERROR: Jsign checksum verification failed"; exit 1; }
26+
27+
# Sign every nupkg produced by the pack step.
28+
SIGNED_ANY=0
29+
for NUPKG in BrowserStackLocal/BrowserStackLocal/bin/Release/*.nupkg; do
30+
if [ ! -f "$NUPKG" ]; then
31+
continue
32+
fi
33+
echo "Signing $NUPKG"
34+
java -jar jsign.jar \
35+
--storetype GOOGLECLOUD \
36+
--storepass "$GCP_ACCESS_TOKEN" \
37+
--keystore "projects/browserstack-production/locations/us-east1/keyRings/prod-comodo-win-cert-keyring" \
38+
--alias "prod-comodo-win-cert-key/cryptoKeyVersions/1" \
39+
--certfile comodo_signing_cert.crt \
40+
--tsaurl http://timestamp.sectigo.com \
41+
"$NUPKG"
42+
SIGNED_ANY=1
43+
done
44+
45+
if [ "$SIGNED_ANY" -eq 0 ]; then
46+
echo "ERROR: no .nupkg files found under BrowserStackLocal/BrowserStackLocal/bin/Release/"
47+
exit 1
48+
fi
49+
50+
echo "Signing complete"

0 commit comments

Comments
 (0)