Add certificates diagnostics for troubleshooting #1761
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Package SpacetimeDB CLI | |
| on: | |
| push: | |
| tags: | |
| - '**' | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| build-cli: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # WARNING - do not upgrade this runner to 24.04 or the self hosted runners because it will break downloads for | |
| # anyone who uses a linux distro that doesn't have glibc >= GLIBC_2.38 | |
| - { name: x86_64 Linux, target: x86_64-unknown-linux-gnu, runner: ubuntu-22.04 } | |
| - { name: aarch64 Linux, target: aarch64-unknown-linux-gnu, runner: arm-runner } | |
| # Disabled because musl builds weren't working and we didn't want to investigate. See https://github.com/clockworklabs/SpacetimeDB/pull/2964. | |
| # - { name: x86_64 Linux musl, target: x86_64-unknown-linux-musl, runner: bare-metal, container: alpine } | |
| # FIXME: arm musl build. "JavaScript Actions in Alpine containers are only supported on x64 Linux runners" | |
| # - { name: aarch64 Linux musl, target: aarch64-unknown-linux-musl, runner: arm-runner } | |
| - { name: aarch64 macOS, target: aarch64-apple-darwin, runner: macos-latest } | |
| - { name: x86_64 macOS, target: x86_64-apple-darwin, runner: macos-latest } | |
| - { name: x86_64 Windows, target: x86_64-pc-windows-msvc, runner: windows-latest } | |
| name: Build CLI for ${{ matrix.name }} | |
| runs-on: ${{ matrix.runner }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v3 | |
| - name: Show arch | |
| run: uname -a | |
| - name: Install musl dependencies | |
| # TODO: Should we use `matrix.container == 'alpine'` instead of the `endsWith` check? | |
| if: endsWith(matrix.target, '-musl') | |
| run: apk add gcc g++ bash curl linux-headers perl git make | |
| - name: Install Rust | |
| uses: dsherret/rust-toolchain-file@v1 | |
| - name: Set default rust toolchain | |
| run: rustup default $(rustup show active-toolchain | cut -d' ' -f1) | |
| - name: Install rust target | |
| run: rustup target add ${{ matrix.target }} | |
| - name: Add signtool.exe to PATH | |
| if: ${{ runner.os == 'Windows' }} | |
| shell: pwsh | |
| run: | | |
| $root = "${env:ProgramFiles(x86)}\Windows Kits\10\bin" | |
| $signtool = Get-ChildItem $root -Recurse -Filter signtool.exe -ErrorAction SilentlyContinue | | |
| Where-Object { $_.FullName -match '\\x64\\signtool\.exe$' } | | |
| Sort-Object FullName -Descending | | |
| Select-Object -First 1 | |
| if (-not $signtool) { throw "signtool.exe not found under $root" } | |
| "Found: $($signtool.FullName)" | |
| $dir = Split-Path $signtool.FullName | |
| Add-Content -Path $env:GITHUB_PATH -Value $dir | |
| - name: Decode DigiCert client auth certificate | |
| if: ${{ runner.os == 'Windows' && startsWith(github.ref, 'refs/tags/') }} | |
| shell: bash | |
| run: | | |
| echo "${{ secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12 | |
| - name: Setup DigiCert Software Trust Manager | |
| if: ${{ runner.os == 'Windows' && startsWith(github.ref, 'refs/tags/') }} | |
| uses: digicert/code-signing-software-trust-action@v1 | |
| env: | |
| SM_HOST: ${{ vars.SM_HOST }} | |
| SM_API_KEY: ${{ secrets.SM_API_KEY }} | |
| SM_CLIENT_CERT_FILE: D:\Certificate_pkcs12.p12 | |
| SM_CLIENT_CERT_PASSWORD: ${{ secrets.SM_CLIENT_CERT_PASSWORD }} | |
| - name: Sync DigiCert certificate to local store and verify | |
| if: ${{ runner.os == 'Windows' && startsWith(github.ref, 'refs/tags/') }} | |
| shell: pwsh | |
| env: | |
| SM_HOST: ${{ vars.SM_HOST }} | |
| SM_API_KEY: ${{ secrets.SM_API_KEY }} | |
| SM_CLIENT_CERT_FILE: D:\Certificate_pkcs12.p12 | |
| SM_CLIENT_CERT_PASSWORD: ${{ secrets.SM_CLIENT_CERT_PASSWORD }} | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| # Sync certificates from DigiCert cloud to local Windows certificate store | |
| # This is required so signtool can find the certificate | |
| smctl windows certsync | |
| # Run healthcheck to confirm everything is connected | |
| smctl healthcheck | |
| - name: Compile | |
| run: | | |
| cargo build --release --target ${{ matrix.target }} -p spacetimedb-cli -p spacetimedb-standalone -p spacetimedb-update | |
| - name: List synced certificates (diagnostic) | |
| if: ${{ runner.os == 'Windows' && startsWith(github.ref, 'refs/tags/') }} | |
| shell: pwsh | |
| env: | |
| SM_HOST: ${{ vars.SM_HOST }} | |
| SM_API_KEY: ${{ secrets.SM_API_KEY }} | |
| SM_CLIENT_CERT_FILE: D:\Certificate_pkcs12.p12 | |
| SM_CLIENT_CERT_PASSWORD: ${{ secrets.SM_CLIENT_CERT_PASSWORD }} | |
| run: | | |
| Write-Host "=== Certificates in CurrentUser\My ===" | |
| Get-ChildItem Cert:\CurrentUser\My | Format-Table Subject, Thumbprint, NotAfter -AutoSize | |
| Write-Host "=== Certificates in LocalMachine\My ===" | |
| Get-ChildItem Cert:\LocalMachine\My | Format-Table Subject, Thumbprint, NotAfter -AutoSize | |
| Write-Host "=== smctl keypair list ===" | |
| smctl keypair ls | |
| - name: Sign binaries for Windows | |
| if: ${{ runner.os == 'Windows' && startsWith(github.ref, 'refs/tags/') }} | |
| shell: pwsh | |
| env: | |
| SM_HOST: ${{ vars.SM_HOST }} | |
| SM_API_KEY: ${{ secrets.SM_API_KEY }} | |
| SM_CLIENT_CERT_FILE: D:\Certificate_pkcs12.p12 | |
| SM_CLIENT_CERT_PASSWORD: ${{ secrets.SM_CLIENT_CERT_PASSWORD }} | |
| DIGICERT_KEYPAIR_ALIAS: ${{ secrets.DIGICERT_KEYPAIR_ALIAS }} | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| $targetDir = Join-Path $env:GITHUB_WORKSPACE 'target\x86_64-pc-windows-msvc\release' | |
| # Find the code signing certificate synced from DigiCert | |
| $cert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Select-Object -First 1 | |
| if (-not $cert) { | |
| $cert = Get-ChildItem Cert:\LocalMachine\My -CodeSigningCert | Select-Object -First 1 | |
| } | |
| if (-not $cert) { | |
| throw "No code signing certificate found in certificate store" | |
| } | |
| $thumbprint = $cert.Thumbprint | |
| Write-Host "Using certificate: $($cert.Subject) [$thumbprint]" | |
| foreach ($exe in @('spacetimedb-update.exe','spacetimedb-cli.exe','spacetimedb-standalone.exe')) { | |
| $path = Join-Path $targetDir $exe | |
| Write-Host "Signing $exe..." | |
| & signtool.exe sign /sha1 $thumbprint /tr http://timestamp.digicert.com /td SHA256 /fd SHA256 $path | |
| if ($LASTEXITCODE -ne 0) { throw "Signing failed for $exe (exit code $LASTEXITCODE)" } | |
| Write-Host "$exe signed successfully" | |
| } | |
| - name: Verify signatures | |
| if: ${{ runner.os == 'Windows' && startsWith(github.ref, 'refs/tags/') }} | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| $targetDir = Join-Path $env:GITHUB_WORKSPACE 'target\x86_64-pc-windows-msvc\release' | |
| foreach ($exe in @('spacetimedb-update.exe','spacetimedb-cli.exe','spacetimedb-standalone.exe')) { | |
| $path = Join-Path $targetDir $exe | |
| & signtool.exe verify /v /pa $path | |
| if ($LASTEXITCODE -ne 0) { throw "Signature verification failed for $exe" } | |
| } | |
| - name: Package (unix) | |
| if: ${{ runner.os != 'Windows' }} | |
| shell: bash | |
| run: | | |
| mkdir build | |
| cd target/${{matrix.target}}/release | |
| cp spacetimedb-update ../../../build/spacetimedb-update-${{matrix.target}} | |
| tar -czf ../../../build/spacetime-${{matrix.target}}.tar.gz spacetimedb-{cli,standalone} | |
| - name: Package (windows) | |
| if: ${{ runner.os == 'Windows' }} | |
| shell: bash | |
| run: | | |
| mkdir build | |
| cd target/${{matrix.target}}/release | |
| cp spacetimedb-update.exe ../../../build/spacetimedb-update-${{matrix.target}}.exe | |
| 7z a ../../../build/spacetime-${{matrix.target}}.zip spacetimedb-cli.exe spacetimedb-standalone.exe | |
| - name: Extract branch name | |
| shell: bash | |
| run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT | |
| id: extract_branch | |
| - name: Upload to DO Spaces | |
| uses: shallwefootball/s3-upload-action@master | |
| with: | |
| aws_key_id: ${{ secrets.AWS_KEY_ID }} | |
| aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY}} | |
| aws_bucket: ${{ vars.AWS_BUCKET }} | |
| source_dir: build | |
| endpoint: https://nyc3.digitaloceanspaces.com | |
| destination_dir: ${{ steps.extract_branch.outputs.branch }} |