Update HCR fixture for watch rebuilds #2438
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: Codetracer CI | ||
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
| pull_request: | ||
| permissions: | ||
| contents: read | ||
| id-token: write | ||
| jobs: | ||
| windows-bootstrap-smoke: | ||
| runs-on: windows-latest | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| - name: Validate env.sh syntax | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| test -f env.sh | ||
| bash -n env.sh | ||
| - name: Validate PowerShell parser | ||
| shell: pwsh | ||
| run: | | ||
| $scriptPaths = @( | ||
| "env.ps1", | ||
| "non-nix-build/windows/toolchain-utils.ps1", | ||
| "non-nix-build/windows/ensure-rust.ps1", | ||
| "non-nix-build/windows/ensure-just.ps1", | ||
| "non-nix-build/windows/ensure-nextest.ps1", | ||
| "non-nix-build/windows/ensure-node.ps1", | ||
| "non-nix-build/windows/ensure-uv.ps1", | ||
| "non-nix-build/windows/ensure-nim.ps1", | ||
| "non-nix-build/windows/ensure-capnp.ps1", | ||
| "non-nix-build/windows/ensure-tup.ps1", | ||
| "non-nix-build/windows/ensure-ct-remote.ps1", | ||
| "non-nix-build/windows/ensure-nargo.ps1", | ||
| "non-nix-build/windows/ensure-ttd.ps1", | ||
| "non-nix-build/windows/validate-toolchain-versions.ps1", | ||
| "non-nix-build/windows/validate-env-path-entries.ps1" | ||
| ) | ||
| foreach ($scriptPath in $scriptPaths) { | ||
| if (-not (Test-Path -LiteralPath $scriptPath)) { | ||
| throw "Missing required file: $scriptPath" | ||
| } | ||
| $parseErrors = $null | ||
| [void][System.Management.Automation.Language.Parser]::ParseFile( | ||
| $scriptPath, | ||
| [ref]$null, | ||
| [ref]$parseErrors | ||
| ) | ||
| if ($parseErrors.Count -gt 0) { | ||
| $parseErrors | ForEach-Object { Write-Error "${scriptPath}: $($_.Message)" } | ||
| throw "PowerShell parser reported one or more errors." | ||
| } | ||
| } | ||
| - name: Validate toolchain-versions.env | ||
| shell: pwsh | ||
| run: | | ||
| pwsh -File non-nix-build/windows/validate-toolchain-versions.ps1 | ||
| - name: Validate env.ps1 PATH helper | ||
| shell: pwsh | ||
| run: | | ||
| pwsh -File non-nix-build/windows/validate-env-path-entries.ps1 | ||
| - name: Validate arm64 mode routing smoke checks | ||
| shell: pwsh | ||
| run: | | ||
| $windowsDir = "non-nix-build/windows" | ||
| function Invoke-BootstrapProbe { | ||
| param( | ||
| [Parameter(Mandatory = $true)][string]$Name, | ||
| [Parameter(Mandatory = $true)][hashtable]$Env, | ||
| [Parameter(Mandatory = $true)][scriptblock]$Action, | ||
| [Parameter(Mandatory = $true)][string[]]$RequiredPatterns, | ||
| [string[]]$ForbiddenPatterns = @() | ||
| ) | ||
| $installRoot = Join-Path $env:RUNNER_TEMP ("codetracer-bootstrap-routing-" + $Name) | ||
| if (Test-Path -LiteralPath $installRoot) { | ||
| Remove-Item -LiteralPath $installRoot -Recurse -Force | ||
| } | ||
| New-Item -ItemType Directory -Path $installRoot -Force | Out-Null | ||
| $savedPath = $env:PATH | ||
| $savedArchOverride = $env:WINDOWS_DIY_ARCH_OVERRIDE | ||
| $savedEnv = @{} | ||
| foreach ($envKey in $Env.Keys) { | ||
| $savedEnv[$envKey] = [Environment]::GetEnvironmentVariable($envKey) | ||
| [Environment]::SetEnvironmentVariable($envKey, [string]$Env[$envKey]) | ||
| } | ||
| [Environment]::SetEnvironmentVariable("WINDOWS_DIY_ARCH_OVERRIDE", "arm64") | ||
| $env:PATH = "$env:SystemRoot\System32;$env:SystemRoot" | ||
| $probeOutput = @() | ||
| try { | ||
| $probeSucceeded = $true | ||
| $probeOutput = & $Action $installRoot 2>&1 | ||
| } catch { | ||
| $probeSucceeded = $false | ||
| $probeOutput = @($probeOutput) + $_.Exception.Message + ($_ | Out-String -Width 10000) | ||
| } finally { | ||
| $env:PATH = $savedPath | ||
| [Environment]::SetEnvironmentVariable("WINDOWS_DIY_ARCH_OVERRIDE", $savedArchOverride) | ||
| foreach ($envKey in $Env.Keys) { | ||
| [Environment]::SetEnvironmentVariable($envKey, $savedEnv[$envKey]) | ||
| } | ||
| } | ||
| $probeText = ($probeOutput | Out-String -Width 10000) | ||
| if ($probeSucceeded) { | ||
| throw "Probe '$Name' unexpectedly succeeded. Expected a fast-fail source-route assertion." | ||
| } | ||
| foreach ($pattern in $RequiredPatterns) { | ||
| if ($probeText -notmatch $pattern) { | ||
| throw "Probe '$Name' output is missing required pattern '$pattern'." | ||
| } | ||
| } | ||
| foreach ($pattern in $ForbiddenPatterns) { | ||
| if ($probeText -match $pattern) { | ||
| throw "Probe '$Name' output matched forbidden pattern '$pattern'." | ||
| } | ||
| } | ||
| } | ||
| # Load shared modules | ||
| . "$windowsDir/toolchain-utils.ps1" | ||
| . "$windowsDir/ensure-nim.ps1" | ||
| . "$windowsDir/ensure-capnp.ps1" | ||
| . "$windowsDir/ensure-ct-remote.ps1" | ||
| # Parse toolchain versions | ||
| $toolchainPath = Join-Path $windowsDir "toolchain-versions.env" | ||
| $toolchain = @{} | ||
| foreach ($line in Get-Content -LiteralPath $toolchainPath) { | ||
| if ($line -match '^\s*#' -or [string]::IsNullOrWhiteSpace($line)) { continue } | ||
| if ($line -notmatch '^\s*([A-Za-z_][A-Za-z0-9_]*)=(.*)$') { continue } | ||
| $name = $matches[1] | ||
| $value = $matches[2].Trim() | ||
| if ($value.StartsWith('"') -and $value.EndsWith('"') -and $value.Length -ge 2) { | ||
| $value = $value.Substring(1, $value.Length - 2) | ||
| } | ||
| $toolchain[$name] = $value | ||
| } | ||
| Invoke-BootstrapProbe ` | ||
| -Name "nim-auto-arm64-source-first" ` | ||
| -Env @{ | ||
| "NIM_WINDOWS_SOURCE_MODE" = "auto" | ||
| } ` | ||
| -Action { | ||
| param($installRoot) | ||
| $arch = Get-WindowsArch | ||
| Ensure-Nim -Root $installRoot -Arch $arch -Toolchain $toolchain | ||
| } ` | ||
| -RequiredPatterns @( | ||
| "NIM_WINDOWS_SOURCE_MODE=auto attempted Nim source bootstrap on 'arm64' and failed:", | ||
| "Prebuilt fallback is x64-only" | ||
| ) ` | ||
| -ForbiddenPatterns @( | ||
| "Falling back to pinned prebuilt asset", | ||
| "NIM_WINDOWS_SOURCE_MODE=prebuilt" | ||
| ) | ||
| Invoke-BootstrapProbe ` | ||
| -Name "capnp-auto-arm64-source-route" ` | ||
| -Env @{ | ||
| "CAPNP_WINDOWS_SOURCE_MODE" = "auto" | ||
| } ` | ||
| -Action { | ||
| param($installRoot) | ||
| $arch = Get-WindowsArch | ||
| Ensure-Capnp -Root $installRoot -Arch $arch -Toolchain $toolchain | ||
| } ` | ||
| -RequiredPatterns @( | ||
| "git is required for source bootstrap but was not found on PATH" | ||
| ) ` | ||
| -ForbiddenPatterns @( | ||
| "capnproto-c\\+\\+-win32-" | ||
| ) | ||
| Invoke-BootstrapProbe ` | ||
| -Name "ct-remote-auto-arm64-local-route" ` | ||
| -Env @{ | ||
| "CT_REMOTE_WINDOWS_SOURCE_MODE" = "auto" | ||
| "CT_REMOTE_WINDOWS_SOURCE_REPO" = (Join-Path $env:RUNNER_TEMP "codetracer-ci-missing-routes") | ||
| } ` | ||
| -Action { | ||
| param($installRoot) | ||
| $arch = Get-WindowsArch | ||
| Ensure-CtRemote -Root $installRoot -Arch $arch -Toolchain $toolchain -WindowsDir $windowsDir | ||
| } ` | ||
| -RequiredPatterns @( | ||
| "CT_REMOTE_WINDOWS_SOURCE_MODE=auto on 'arm64' requires local source project", | ||
| "Pinned download is x64-only" | ||
| ) ` | ||
| -ForbiddenPatterns @( | ||
| "Installing ct-remote from pinned download", | ||
| "Falling back to pinned download" | ||
| ) | ||
| windows-named-pipe-tests: | ||
| runs-on: windows-latest | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| - name: Install Rust toolchain | ||
| uses: dtolnay/rust-toolchain@stable | ||
| - name: Run Windows named-pipe transport tests | ||
| working-directory: src/tui | ||
| shell: pwsh | ||
| run: cargo test --bin simple-tui windows_named_pipe -- --nocapture | ||
| windows-rust-components: | ||
| runs-on: windows-latest | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Install Rust toolchain | ||
| uses: dtolnay/rust-toolchain@stable | ||
| with: | ||
| components: clippy | ||
| - name: Install capnproto | ||
| shell: pwsh | ||
| run: choco install capnproto -y | ||
| - name: Generate tree-sitter-nim parser | ||
| shell: pwsh | ||
| run: | | ||
| npm install -g tree-sitter-cli | ||
| cd libs/tree-sitter-nim | ||
| tree-sitter generate | ||
| - name: Build db-backend | ||
| working-directory: src/db-backend | ||
| shell: bash | ||
| run: cargo build | ||
| - name: Test db-backend | ||
| working-directory: src/db-backend | ||
| shell: bash | ||
| run: cargo test | ||
| - name: Build backend-manager | ||
| working-directory: src/backend-manager | ||
| shell: bash | ||
| run: cargo build | ||
| - name: Build tui | ||
| working-directory: src/tui | ||
| shell: bash | ||
| run: cargo build | ||
| - name: Clippy db-backend | ||
| working-directory: src/db-backend | ||
| shell: bash | ||
| run: cargo clippy --all-targets -- -D warnings | ||
| - name: Clippy backend-manager | ||
| working-directory: src/backend-manager | ||
| shell: bash | ||
| run: cargo clippy --all-targets -- -D warnings | ||
| - name: Clippy tui | ||
| working-directory: src/tui | ||
| shell: bash | ||
| run: cargo clippy --all-targets -- -D warnings | ||
| - name: Test tui named pipe | ||
| working-directory: src/tui | ||
| shell: bash | ||
| run: cargo test --bin simple-tui windows_named_pipe | ||
| # Headless DAP test suite on Windows using MCR backend. | ||
| # Installs all dependencies via env.ps1, builds ct-mcr from the | ||
| # codetracer-native-recorder sibling, then runs the Rust DAP integration tests. | ||
| windows-headless-test: | ||
| runs-on: windows-latest | ||
| name: test (headless DAP, Windows) | ||
| needs: | ||
| - windows-rust-components | ||
| steps: | ||
| - name: Generate CI token | ||
| id: app-token | ||
| uses: actions/create-github-app-token@v1 | ||
| with: | ||
| app-id: ${{ vars.CI_TOKEN_PROVIDER_APP_ID }} | ||
| private-key: ${{ secrets.CI_TOKEN_PROVIDER_PRIVATE_KEY }} | ||
| owner: metacraft-labs | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ steps.app-token.outputs.token }} | ||
| - name: Resolve codetracer-native-recorder ref | ||
| id: resolve-mcr-ref | ||
| shell: bash | ||
| run: | | ||
| PINS=".github/sibling-pins" | ||
| REF="main" | ||
| if [ -f "${PINS}" ]; then | ||
| PIN_REF="$(grep '^codetracer-native-recorder ' "${PINS}" | cut -d' ' -f2)" || true | ||
| [ -n "${PIN_REF}" ] && REF="${PIN_REF}" | ||
| fi | ||
| echo "ref=${REF}" >> "$GITHUB_OUTPUT" | ||
| - name: Clone codetracer-native-recorder | ||
| uses: metacraft-labs/metacraft-github-actions/clone-repo@main | ||
| with: | ||
| repo: metacraft-labs/codetracer-native-recorder | ||
| ref: ${{ steps.resolve-mcr-ref.outputs.ref }} | ||
| path: ${{ github.workspace }}/../codetracer-native-recorder | ||
| gh-token: ${{ steps.app-token.outputs.token }} | ||
| submodules: 'true' | ||
| - name: Bootstrap Windows dev environment | ||
| shell: pwsh | ||
| env: | ||
| WINDOWS_DIY_ENSURE_TTD: "false" | ||
| run: | | ||
| . .\env.ps1 | ||
| # Export PATH and key env vars for subsequent steps | ||
| $env:PATH -split ';' | ForEach-Object { | ||
| if ($_ -ne '') { Add-Content -Path $env:GITHUB_PATH -Value $_ } | ||
| } | ||
| @( | ||
| "GCC_DIR", "GO_DIR", "GOROOT", "ZSTD_DIR", "CARGO_HOME", | ||
| "RUSTUP_HOME", "CC", "CXX", "CT_NIM_CC_FLAGS", "NIM1", | ||
| "CAPNP_DIR", "WINDOWS_DIY_SHIMS_DIR", "WINDOWS_DIY_INSTALL_ROOT", | ||
| "CODETRACER_REPO_ROOT_PATH", "CODETRACER_PREFIX", | ||
| "CODETRACER_E2E_CT_PATH" | ||
| ) | ForEach-Object { | ||
| $val = [Environment]::GetEnvironmentVariable($_, "Process") | ||
| if ($val) { Add-Content -Path $env:GITHUB_ENV -Value "$_=$val" } | ||
| } | ||
| - name: Install Nim dependencies | ||
| shell: bash | ||
| run: nimble install results stew -y | ||
| - name: Build ct-mcr.exe | ||
| shell: bash | ||
| run: | | ||
| cd "${{ github.workspace }}/../codetracer-native-recorder/ct_cli" | ||
| nim c --cc:vcc \ | ||
| --path:../ct_time_model/src --path:../ct_events/src \ | ||
| --path:../ct_ringbuf/src --path:../ct_runtime/src \ | ||
| --path:../ct_recorder/src --path:../ct_replayer/src \ | ||
| --path:../ct_debugserver/src --path:../ct_trace_store/src \ | ||
| --path:../ct_interpose/src --path:../ct_instrument/src \ | ||
| --path:../ct_snapshot/src --path:../ct_sync/src \ | ||
| -o:ct_mcr.exe src/ct_cli.nim | ||
| - name: Build ct_interpose.dll | ||
| shell: bash | ||
| run: | | ||
| cd "${{ github.workspace }}/../codetracer-native-recorder" | ||
| nim c --app:lib --cc:vcc --mm:orc \ | ||
| -o:ct_interpose/ct_interpose.dll \ | ||
| ct_interpose/src/ct_interpose/library_init_windows.nim | ||
| - name: Build db-backend | ||
| working-directory: src/db-backend | ||
| shell: bash | ||
| run: cargo build --release | ||
| - name: Build backend-manager | ||
| working-directory: src/backend-manager | ||
| shell: bash | ||
| run: cargo build --release | ||
| - name: Run headless DAP tests (MCR backend) | ||
| shell: bash | ||
| env: | ||
| CODETRACER_CT_MCR_CMD: ${{ github.workspace }}/../codetracer-native-recorder/ct_cli/ct_mcr.exe | ||
| CODETRACER_ALLOW_GRACEFUL_TEST_SKIPPING: "false" | ||
| CODETRACER_USE_GCC: "1" | ||
| CODETRACER_GDB_CMD: gdb | ||
| CODETRACER_GCC_CMD: gcc | ||
| CODETRACER_GPP_CMD: g++ | ||
| working-directory: src/db-backend | ||
| run: | | ||
| cargo nextest run --release --test '*' \ | ||
| -E 'test(~dap) and not test(~bash_flow) and not test(~zsh_flow) and not test(~javascript_flow)' | ||
| lint-bash: | ||
| runs-on: [self-hosted, nixos] | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Install Nix | ||
| uses: ./.github/actions/setup-nix | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - run: "nix develop .#devShells.x86_64-linux.default -c ./ci/lint/bash.sh" | ||
| lint-nim: | ||
| runs-on: [self-hosted, nixos] | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Install Nix | ||
| uses: ./.github/actions/setup-nix | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - run: "nix develop .#devShells.x86_64-linux.default -c ./ci/lint/nim.sh" | ||
| lint-nix: | ||
| runs-on: [self-hosted, nixos] | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Install Nix | ||
| uses: ./.github/actions/setup-nix | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - run: "nix develop .#devShells.x86_64-linux.default -c ./ci/lint/nix.sh" | ||
| lint-rust: | ||
| runs-on: [self-hosted, nixos] | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Install Nix | ||
| uses: ./.github/actions/setup-nix | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - run: "nix develop .#devShells.x86_64-linux.default -c ./ci/lint/rust.sh" | ||
| reprobuild-macos-smoke: | ||
| runs-on: [self-hosted, darwin, nix-darwin, aarch64-darwin] | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Install Nix | ||
| uses: ./.github/actions/setup-nix | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Run Reprobuild macOS smoke | ||
| run: nix develop . --command just test-reprobuild-macos-smoke | ||
| push-gpg-public-key: | ||
| runs-on: [self-hosted, nixos] | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: "Import GPG key for signing commits" | ||
| id: import-gpg | ||
| uses: crazy-max/ghaction-import-gpg@v6 | ||
| with: | ||
| gpg_private_key: ${{ secrets.CODETRACER_AUR_GPG_PRIVATE_KEY }} | ||
| passphrase: ${{ secrets.CODETRACER_AUR_GPG_PRIVATE_KEY_PASS }} | ||
| git_config_global: true | ||
| git_user_signingkey: true | ||
| git_commit_gpgsign: true | ||
| - name: "Upload public key" | ||
| env: | ||
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY_ID }} | ||
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY }} | ||
| run: | | ||
| nix develop .#devShells.x86_64-linux.default --command gpg --armor --export > CodeTracer.pub.asc | ||
| nix develop .#devShells.x86_64-linux.default --command aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp CodeTracer.pub.asc s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/CodeTracer.pub.asc | ||
| push-install-script: | ||
| runs-on: [self-hosted, nixos] | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Upload script | ||
| env: | ||
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY_ID }} | ||
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY }} | ||
| run: | | ||
| nix develop .#devShells.x86_64-linux.default --command aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp install-on-distributions.sh s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/install.sh | ||
| dev-build: | ||
| runs-on: [self-hosted, nixos] | ||
| needs: | ||
| - lint-bash | ||
| - lint-nim | ||
| - lint-nix | ||
| - lint-rust | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Install Nix | ||
| uses: ./.github/actions/setup-nix | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - run: "nix develop .#devShells.x86_64-linux.default --command ./ci/build/dev.sh" | ||
| nix-build: | ||
| runs-on: [self-hosted, nixos] | ||
| needs: | ||
| - lint-bash | ||
| - lint-nim | ||
| - lint-nix | ||
| - lint-rust | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Install Nix | ||
| uses: ./.github/actions/setup-nix | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - run: "nix develop .#devShells.x86_64-linux.default --command ./ci/build/nix.sh" | ||
| build-python-packages: | ||
| needs: | ||
| - lint-bash | ||
| - lint-nim | ||
| - lint-nix | ||
| - lint-rust | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| include: | ||
| - name: linux-amd64 | ||
| runner: ubuntu-latest | ||
| target_os: linux | ||
| arch: amd64 | ||
| plat_name: manylinux_2_17_x86_64 | ||
| # - name: linux-arm64 | ||
| # runner: ubuntu-22.04-arm64 | ||
| # target_os: linux | ||
| # arch: arm64 | ||
| # plat_name: manylinux_2_17_aarch64 | ||
| - name: macos-amd64 | ||
| runner: macos-15-intel | ||
| target_os: macos | ||
| arch: amd64 | ||
| plat_name: macosx_10_9_x86_64 | ||
| - name: macos-arm64 | ||
| runner: macos-14 | ||
| target_os: macos | ||
| arch: arm64 | ||
| plat_name: macosx_11_0_arm64 | ||
| runs-on: ${{ matrix.runner }} | ||
| steps: | ||
| - name: Check out repository | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: 'true' | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Set up Python | ||
| uses: actions/setup-python@v6 | ||
| with: | ||
| python-version: '3.11' | ||
| - name: Install Python build backend | ||
| run: python -m pip install --upgrade build | ||
| - name: Install nim | ||
| run: | | ||
| set -euo pipefail | ||
| wget https://nim-lang.org/download/nim-2.2.6.tar.xz | ||
| tar xf nim-2.2.6.tar.xz | ||
| pushd nim-2.2.6 | ||
| sh build.sh | ||
| bin/nim c koch | ||
| ./koch boot -d:release | ||
| export PATH="$(pwd)/bin:${PATH}" | ||
| popd | ||
| - name: Get sqlite | ||
| run: | | ||
| set -euo pipefail | ||
| wget https://sqlite.org/2025/sqlite-amalgamation-3500400.zip | ||
| unzip sqlite-amalgamation-3500400.zip | ||
| cp sqlite-amalgamation-3500400/sqlite3.c . | ||
| - name: Install libssl and libbpf (Linux) | ||
| if: ${{ matrix.target_os == 'linux' }} | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y libssl-dev libbpf-dev libelf-dev | ||
| - name: Install libssl (MacOS) | ||
| if: ${{ matrix.target_os == 'macos' }} | ||
| run: | | ||
| git clone https://github.com/openssl/openssl | ||
| pushd openssl | ||
| git checkout openssl-3.5.4 | ||
| ./Configure --prefix=$(pwd)/../openssl-res | ||
| make -j$(sysctl -n hw.ncpu) | ||
| make install_sw | ||
| popd | ||
| - name: Install zlib (Linux) | ||
| if: ${{ matrix.target_os == 'linux' }} | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y zlib1g-dev | ||
| - name: Install zlib (MacOS) | ||
| if: ${{ matrix.target_os == 'macos' }} | ||
| run: | | ||
| wget https://zlib.net/zlib-1.3.2.tar.gz | ||
| tar xf zlib-1.3.2.tar.gz | ||
| pushd zlib-1.3.2 | ||
| ./configure --static --prefix=$(pwd)/../zlib-res | ||
| make -j$(sysctl -n hw.ncpu) | ||
| make install | ||
| popd | ||
| - name: Build codetracer binaries (Linux) | ||
| if: ${{ matrix.target_os == 'linux' }} | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| TARGET_DIR="build-python/src/ct/bin/${{ matrix.target_os }}-${{ matrix.arch }}" | ||
| mkdir -p "${TARGET_DIR}" | ||
| ./nim-2.2.6/bin/nim -d:release \ | ||
| --d:asyncBackend=asyncdispatch \ | ||
| --dynlibOverride:std -d:staticStd \ | ||
| --mm:refc --hints:on --warnings:off \ | ||
| --boundChecks:on \ | ||
| -d:useOpenssl3 \ | ||
| -d:ssl \ | ||
| -d:chronicles_sinks=json -d:chronicles_line_numbers=true \ | ||
| -d:chronicles_timestamps=UnixTime \ | ||
| -d:ctTest -d:testing --hint"[XDeclaredButNotUsed]":off \ | ||
| -d:builtWithNix \ | ||
| -d:ctEntrypoint \ | ||
| -d:pythonPackage \ | ||
| -d:libcPath=libc \ | ||
| -d:pathToNodeModules=../node_modules \ | ||
| --nimcache:nimcache \ | ||
| -d:staticSqlite \ | ||
| -d:useLibzipSrc \ | ||
| --passL:"-Wl,-Bstatic -L/usr/lib/x86_64-linux-gnu -l:libz.a -Wl,-Bdynamic" \ | ||
| --dynlibOverride:ssl --dynlibOverride:crypto \ | ||
| --passL:"-Wl,-Bstatic -L/usr/lib/x86_64-linux-gnu -l:libssl.a -l:libcrypto.a -Wl,-Bdynamic" \ | ||
| --out:"${TARGET_DIR}/ct" c ./src/ct/codetracer.nim | ||
| ./nim-2.2.6/bin/nim \ | ||
| -d:release -d:asyncBackend=asyncdispatch \ | ||
| --mm:refc --hints:off --warnings:off \ | ||
| --debugInfo --lineDir:on \ | ||
| --boundChecks:on --stacktrace:on --linetrace:on \ | ||
| -d:chronicles_sinks=json -d:chronicles_line_numbers=true \ | ||
| -d:chronicles_timestamps=UnixTime \ | ||
| -d:ssl \ | ||
| -d:ctTest -d:testing --hint"[XDeclaredButNotUsed]":off \ | ||
| -d:libcPath=libc \ | ||
| -d:builtWithNix \ | ||
| -d:ctEntrypoint \ | ||
| -d:pythonPackage \ | ||
| --nimcache:nimcache \ | ||
| -d:staticSqlite \ | ||
| -d:useLibzipSrc \ | ||
| --passL:"-Wl,-Bstatic -L/usr/lib/x86_64-linux-gnu -l:libz.a -Wl,-Bdynamic" \ | ||
| --dynlibOverride:ssl --dynlibOverride:crypto \ | ||
| --passL:"-Wl,-Bstatic -L/usr/lib/x86_64-linux-gnu -l:libssl.a -l:libcrypto.a -Wl,-Bdynamic" \ | ||
| --out:"${TARGET_DIR}/db-backend-record" c ./src/ct/db_backend_record.nim | ||
| ./build-python/scripts/download_ct_remote.sh \ | ||
| "${{ matrix.target_os }}" \ | ||
| "${{ matrix.arch }}" \ | ||
| "${TARGET_DIR}" | ||
| - name: Build codetracer binaries (MacOS) | ||
| if: ${{ matrix.target_os == 'macos' }} | ||
| run: | | ||
| set -euo pipefail | ||
| TARGET_DIR="build-python/src/ct/bin/${{ matrix.target_os }}-${{ matrix.arch }}" | ||
| mkdir -p "${TARGET_DIR}" | ||
| ./nim-2.2.6/bin/nim -d:release \ | ||
| --d:asyncBackend=asyncdispatch \ | ||
| --dynlibOverride:std -d:staticStd \ | ||
| --mm:refc --hints:on --warnings:off \ | ||
| --boundChecks:on \ | ||
| -d:useOpenssl3 \ | ||
| -d:ssl \ | ||
| -d:chronicles_sinks=json -d:chronicles_line_numbers=true \ | ||
| -d:chronicles_timestamps=UnixTime \ | ||
| -d:ctTest -d:testing --hint"[XDeclaredButNotUsed]":off \ | ||
| -d:builtWithNix \ | ||
| -d:ctEntrypoint \ | ||
| -d:pythonPackage \ | ||
| -d:libcPath=libc \ | ||
| -d:pathToNodeModules=../node_modules \ | ||
| --nimcache:nimcache \ | ||
| -d:staticSqlite \ | ||
| -d:useLibzipSrc \ | ||
| --passL:"$(pwd)/zlib-res/lib/libz.a" \ | ||
| --dynlibOverride:ssl --dynlibOverride:crypto \ | ||
| --passL:"$(pwd)/openssl-res/lib/libssl.a $(pwd)/openssl-res/lib/libcrypto.a" \ | ||
| --out:"${TARGET_DIR}/ct" c ./src/ct/codetracer.nim | ||
| ./nim-2.2.6/bin/nim \ | ||
| -d:release -d:asyncBackend=asyncdispatch \ | ||
| --mm:refc --hints:off --warnings:off \ | ||
| --debugInfo --lineDir:on \ | ||
| --boundChecks:on --stacktrace:on --linetrace:on \ | ||
| -d:chronicles_sinks=json -d:chronicles_line_numbers=true \ | ||
| -d:chronicles_timestamps=UnixTime \ | ||
| -d:ssl \ | ||
| -d:ctTest -d:testing --hint"[XDeclaredButNotUsed]":off \ | ||
| -d:libcPath=libc \ | ||
| -d:builtWithNix \ | ||
| -d:ctEntrypoint \ | ||
| -d:pythonPackage \ | ||
| --nimcache:nimcache \ | ||
| -d:staticSqlite \ | ||
| -d:useLibzipSrc \ | ||
| --passL:"$(pwd)/zlib-res/lib/libz.a" \ | ||
| --dynlibOverride:ssl --dynlibOverride:crypto \ | ||
| --passL:"$(pwd)/openssl-res/lib/libssl.a $(pwd)/openssl-res/lib/libcrypto.a" \ | ||
| --out:"${TARGET_DIR}/db-backend-record" c ./src/ct/db_backend_record.nim | ||
| ./build-python/scripts/download_ct_remote.sh \ | ||
| "${{ matrix.target_os }}" \ | ||
| "${{ matrix.arch }}" \ | ||
| "${TARGET_DIR}" | ||
| - name: Build wheel | ||
| run: | | ||
| set -euo pipefail | ||
| pushd build-python | ||
| python -m build --wheel -C--build-option=--plat-name=${{ matrix.plat_name }} | ||
| popd | ||
| - name: Upload distributions | ||
| uses: actions/upload-artifact@v5 | ||
| with: | ||
| name: python-dist-${{ matrix.name }} | ||
| path: build-python/dist/*.whl | ||
| if-no-files-found: error | ||
| appimage-build: | ||
| runs-on: [self-hosted, nixos] | ||
| needs: | ||
| - lint-bash | ||
| - lint-nim | ||
| - lint-nix | ||
| - lint-rust | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Install Nix | ||
| uses: ./.github/actions/setup-nix | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: "Import GPG key for signing commits" | ||
| id: import-gpg | ||
| uses: crazy-max/ghaction-import-gpg@v6 | ||
| with: | ||
| gpg_private_key: ${{ secrets.CODETRACER_AUR_GPG_PRIVATE_KEY }} | ||
| passphrase: ${{ secrets.CODETRACER_AUR_GPG_PRIVATE_KEY_PASS }} | ||
| git_config_global: true | ||
| git_user_signingkey: true | ||
| git_commit_gpgsign: true | ||
| - name: Build | ||
| run: "nix develop .#devShells.x86_64-linux.default --command ./ci/build/appimage.sh" | ||
| - name: Upload artifact | ||
| env: | ||
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY_ID }} | ||
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY }} | ||
| run: | | ||
| nix develop .#devShells.x86_64-linux.default --command gpg --armor --detach-sign CodeTracer.AppImage | ||
| nix develop .#devShells.x86_64-linux.default --command aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp CodeTracer.AppImage s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/CodeTracer-${{ github.ref_name }}-amd64.AppImage | ||
| nix develop .#devShells.x86_64-linux.default --command aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp CodeTracer.AppImage.asc s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/CodeTracer-${{ github.ref_name }}-amd64.AppImage.asc | ||
| dmg-build: | ||
| runs-on: macos-latest | ||
| needs: | ||
| - lint-bash | ||
| - lint-nim | ||
| - lint-nix | ||
| - lint-rust | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: "Import GPG key for signing commits" | ||
| id: import-gpg | ||
| uses: crazy-max/ghaction-import-gpg@v6 | ||
| with: | ||
| gpg_private_key: ${{ secrets.CODETRACER_AUR_GPG_PRIVATE_KEY }} | ||
| passphrase: ${{ secrets.CODETRACER_AUR_GPG_PRIVATE_KEY_PASS }} | ||
| git_config_global: true | ||
| git_user_signingkey: true | ||
| git_commit_gpgsign: true | ||
| - name: Set up Rust toolchain | ||
| uses: dtolnay/rust-toolchain@stable | ||
| - name: Build | ||
| run: ./ci/build/dmg.sh | ||
| - name: Install AWS CLI | ||
| run: brew install awscli | ||
| - name: Upload artifact | ||
| env: | ||
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY_ID }} | ||
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY }} | ||
| run: | | ||
| gpg --armor --detach-sign non-nix-build/CodeTracer.dmg | ||
| # for now apply workaround from https://community.cloudflare.com/t/an-error-occurred-internalerror-when-calling-the-putobject-operation/764905/11: | ||
| # adding `--checksum-algorithm CRC32` | ||
| aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp ./non-nix-build/CodeTracer.dmg s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/CodeTracer-${{ github.ref_name }}-arm64.dmg --checksum-algorithm CRC32 | ||
| aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp ./non-nix-build/CodeTracer.dmg.asc s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/CodeTracer-${{ github.ref_name }}-arm64.dmg.asc --checksum-algorithm CRC32 | ||
| dmg-lib-check: | ||
| runs-on: macos-latest | ||
| needs: | ||
| - dmg-build | ||
| steps: | ||
| - name: Install AWS CLI | ||
| run: brew install awscli | ||
| - name: Install 7zip | ||
| run: brew install sevenzip | ||
| - name: Download artifact | ||
| env: | ||
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY_ID }} | ||
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY }} | ||
| run: | | ||
| aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/CodeTracer-${{ github.ref_name }}-arm64.dmg ./CodeTracer.dmg | ||
| - name: Extract dmg | ||
| env: | ||
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY_ID }} | ||
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY }} | ||
| run: | | ||
| 7zz x ./CodeTracer.dmg | ||
| - name: Check if ct starts | ||
| env: | ||
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY_ID }} | ||
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY }} | ||
| run: | | ||
| ./CodeTracer/CodeTracer.app/Contents/MacOS/bin/ct --version | ||
| appimage-lib-check: | ||
| runs-on: ubuntu-latest | ||
| needs: | ||
| - appimage-build | ||
| steps: | ||
| - name: Install AWS CLI | ||
| if: ${{ startsWith(github.ref, 'refs/tags/') && !github.event['codetracer-ci'] }} | ||
| run: sudo snap install aws-cli --classic | ||
| - name: Install FUSE | ||
| run: sudo apt-get install -y fuse libfuse2 | ||
| - name: Download artifact | ||
| env: | ||
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY_ID }} | ||
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY }} | ||
| run: | | ||
| aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/CodeTracer-${{ github.ref_name }}-amd64.AppImage ./CodeTracer.AppImage | ||
| - name: Check if ct starts | ||
| env: | ||
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY_ID }} | ||
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY }} | ||
| run: | | ||
| chmod +x ./CodeTracer.AppImage | ||
| ./CodeTracer.AppImage --version | ||
| test-non-gui: | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| include: | ||
| - platform: nixos | ||
| runner: [self-hosted, nixos] | ||
| - platform: macos | ||
| runner: macos-latest | ||
| runs-on: ${{ matrix.runner }} | ||
| # macOS tests are new and may have pre-existing failures; don't block PRs | ||
| continue-on-error: ${{ matrix.platform == 'macos' }} | ||
| needs: | ||
| - lint-bash | ||
| - lint-nim | ||
| - lint-nix | ||
| - lint-rust | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| # --- NixOS setup --- | ||
| - name: Install Nix | ||
| if: matrix.platform == 'nixos' | ||
| uses: ./.github/actions/setup-nix | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| # --- macOS setup --- | ||
| - name: Install just (macOS) | ||
| if: matrix.platform == 'macos' | ||
| run: brew install just | ||
| - name: Set up Python 3.12 (macOS) | ||
| if: matrix.platform == 'macos' | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: '3.12' | ||
| - name: Set up Rust toolchain (macOS) | ||
| if: matrix.platform == 'macos' | ||
| uses: dtolnay/rust-toolchain@stable | ||
| - name: Install cargo-nextest (macOS) | ||
| if: matrix.platform == 'macos' | ||
| run: curl -LsSf https://get.nexte.st/latest/mac | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin | ||
| - name: Build (non-nix) | ||
| if: matrix.platform == 'macos' | ||
| run: ./non-nix-build/build.sh | ||
| - name: Clone python-recorder (macOS) | ||
| if: matrix.platform == 'macos' | ||
| uses: metacraft-labs/metacraft-github-actions/clone-repo@main | ||
| with: | ||
| repo: metacraft-labs/codetracer-python-recorder | ||
| ref: main | ||
| path: ${{ github.workspace }}/../codetracer-python-recorder | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Clone ruby-recorder (macOS) | ||
| if: matrix.platform == 'macos' | ||
| uses: metacraft-labs/metacraft-github-actions/clone-repo@main | ||
| with: | ||
| repo: metacraft-labs/codetracer-ruby-recorder | ||
| ref: main | ||
| path: ${{ github.workspace }}/../codetracer-ruby-recorder | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| # Runs all Rust tests including flow integration tests for all languages. | ||
| # WASM flow tests skip automatically if wazero or wasm32-wasip1 target | ||
| # are not available. Stylus flow tests are #[ignore] and need a devnode. | ||
| # Cross-repo tests (rr) run in the separate test-ui-tests-rr job. | ||
| - name: Run tests | ||
| run: ./ci/test/non-gui.sh | ||
| env: | ||
| CODETRACER_CI_PLATFORM: ${{ matrix.platform }} | ||
| test-ui-tests: | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| include: | ||
| - platform: nixos | ||
| runner: [self-hosted, nixos] | ||
| - platform: macos | ||
| runner: macos-latest | ||
| runs-on: ${{ matrix.runner }} | ||
| # macOS tests are new and may have pre-existing failures; don't block PRs | ||
| continue-on-error: ${{ matrix.platform == 'macos' }} | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| # --- NixOS setup --- | ||
| - name: Install Nix | ||
| if: matrix.platform == 'nixos' | ||
| uses: ./.github/actions/setup-nix | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Build CodeTracer (nix) | ||
| if: matrix.platform == 'nixos' | ||
| run: nix build --print-build-logs '.?submodules=1#codetracer' --override-input codetracer-trace-format path:./libs/codetracer-trace-format | ||
| # --- macOS setup --- | ||
| - name: Install just (macOS) | ||
| if: matrix.platform == 'macos' | ||
| run: brew install just | ||
| - name: Set up Python 3.12 (macOS) | ||
| if: matrix.platform == 'macos' | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: '3.12' | ||
| - name: Set up Rust toolchain (macOS) | ||
| if: matrix.platform == 'macos' | ||
| uses: dtolnay/rust-toolchain@stable | ||
| - name: Build CodeTracer (non-nix) | ||
| if: matrix.platform == 'macos' | ||
| run: ./non-nix-build/build.sh | ||
| - name: Clone python-recorder (macOS) | ||
| if: matrix.platform == 'macos' | ||
| uses: metacraft-labs/metacraft-github-actions/clone-repo@main | ||
| with: | ||
| repo: metacraft-labs/codetracer-python-recorder | ||
| ref: main | ||
| path: ${{ github.workspace }}/../codetracer-python-recorder | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Clone ruby-recorder (macOS) | ||
| if: matrix.platform == 'macos' | ||
| uses: metacraft-labs/metacraft-github-actions/clone-repo@main | ||
| with: | ||
| repo: metacraft-labs/codetracer-ruby-recorder | ||
| ref: main | ||
| path: ${{ github.workspace }}/../codetracer-ruby-recorder | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Run TypeScript Playwright UI tests (DB-based only) | ||
| run: ./ci/test/ui-tests-db.sh | ||
| env: | ||
| CODETRACER_CI_PLATFORM: ${{ matrix.platform }} | ||
| CODETRACER_DB_TESTS_ONLY: "1" | ||
| test-ui-tests-rr: | ||
| runs-on: [self-hosted, nixos] | ||
| timeout-minutes: 120 | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Install Nix | ||
| uses: ./.github/actions/setup-nix | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Build CodeTracer | ||
| run: nix build --print-build-logs '.?submodules=1#codetracer' --override-input codetracer-trace-format path:./libs/codetracer-trace-format | ||
| - name: Setup rr-backend | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| run: ./ci/setup-rr-backend.sh | ||
| - name: Run TypeScript Playwright UI tests (RR-based only) | ||
| env: | ||
| CODETRACER_E2E_CT_PATH: ${{ github.workspace }}/result/bin/ct | ||
| CODETRACER_RR_BACKEND_PATH: ${{ github.workspace }}/../codetracer-native-backend | ||
| CODETRACER_RR_BACKEND_PRESENT: "1" | ||
| CODETRACER_RR_TESTS_ONLY: "1" | ||
| PLAYWRIGHT_GLOBAL_TIMEOUT: "10800000" | ||
| run: "nix develop .#devShells.x86_64-linux.default --command just test-gui" | ||
| - name: Upload test artifacts | ||
| if: failure() | ||
| uses: actions/upload-artifact@v5 | ||
| with: | ||
| name: ui-tests-rr-artifacts | ||
| path: | | ||
| tsc-ui-tests/test-results/ | ||
| tsc-ui-tests/playwright-report/ | ||
| retention-days: 14 | ||
| if-no-files-found: ignore | ||
| visual-replay-regression-gate: | ||
| runs-on: [self-hosted, nixos] | ||
| timeout-minutes: 180 | ||
| steps: | ||
| - name: Checkout CodeTracer | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Install Nix | ||
| uses: ./.github/actions/setup-nix | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Resolve codetracer-visual-replay ref | ||
| id: visual-replay-ref | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| PINS=".github/sibling-pins" | ||
| if [[ ! -f "$PINS" ]]; then | ||
| echo "Missing $PINS" >&2 | ||
| exit 1 | ||
| fi | ||
| REF="$(awk '$1 == "codetracer-visual-replay" { print $2; exit }' "$PINS")" | ||
| if [[ -z "$REF" ]]; then | ||
| echo "Missing codetracer-visual-replay pin in $PINS" >&2 | ||
| exit 1 | ||
| fi | ||
| echo "ref=$REF" >> "$GITHUB_OUTPUT" | ||
| echo "Resolved codetracer-visual-replay ref: $REF" | ||
| - name: Clone codetracer-visual-replay | ||
| uses: metacraft-labs/metacraft-github-actions/clone-repo@main | ||
| with: | ||
| repo: metacraft-labs/codetracer-visual-replay | ||
| ref: ${{ steps.visual-replay-ref.outputs.ref }} | ||
| path: ${{ github.workspace }}/../codetracer-visual-replay | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Restore codetracer-visual-replay sibling pins | ||
| shell: bash | ||
| env: | ||
| TOKEN: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| run: | | ||
| set -euo pipefail | ||
| PINS="${{ github.workspace }}/../codetracer-visual-replay/.github/sibling-pins" | ||
| if [[ ! -f "$PINS" ]]; then | ||
| echo "Missing visual replay sibling pins: $PINS" >&2 | ||
| exit 1 | ||
| fi | ||
| for required in \ | ||
| codetracer-native-backend \ | ||
| codetracer-native-recorder \ | ||
| codetracer-native-test-programs \ | ||
| codetracer-visual-replay-fixtures; do | ||
| if ! awk -v repo="$required" '$1 == repo { found = 1 } END { exit found ? 0 : 1 }' "$PINS"; then | ||
| echo "Missing required visual replay sibling pin: $required" >&2 | ||
| exit 1 | ||
| fi | ||
| done | ||
| while IFS=' ' read -r name sha branch; do | ||
| [[ -z "$name" ]] && continue | ||
| dest="${{ github.workspace }}/../${name}" | ||
| echo "Restoring ${name}@${sha}" | ||
| rm -rf "$dest" | ||
| git clone --no-checkout --filter=blob:none \ | ||
| "https://x-access-token:${TOKEN}@github.com/metacraft-labs/${name}.git" \ | ||
| "$dest" | ||
| git -C "$dest" fetch --depth 1 origin "$sha" | ||
| git -C "$dest" checkout --detach "$sha" | ||
| echo "${name}: $(git -C "$dest" rev-parse HEAD)" | ||
| if [[ "$(git -C "$dest" rev-parse HEAD)" != "$sha" ]]; then | ||
| echo "${name} did not restore to pinned SHA ${sha}" >&2 | ||
| exit 1 | ||
| fi | ||
| done < "$PINS" | ||
| - name: Run visual replay regression gate | ||
| env: | ||
| CODETRACER_VISUAL_REPLAY_REPO_PATH: ${{ github.workspace }}/../codetracer-visual-replay | ||
| PLAYWRIGHT_GLOBAL_TIMEOUT: "10800000" | ||
| run: | | ||
| nix develop .#devShells.x86_64-linux.default --command just test-visual-replay-gate | ||
| - name: Upload visual replay artifacts | ||
| if: failure() | ||
| uses: actions/upload-artifact@v5 | ||
| with: | ||
| name: visual-replay-regression-artifacts | ||
| path: | | ||
| src/tests/gui/test-results/ | ||
| src/tests/gui/playwright-report/ | ||
| src/tests/gui/test-stats/ | ||
| storybook/storybook-static/ | ||
| storybook/dist/ | ||
| ../codetracer-visual-replay/tests/output/ | ||
| ../codetracer-visual-replay/bench-results/ | ||
| /tmp/*_diff.rgba | ||
| /tmp/*_sw.rgba | ||
| /tmp/*_hw.rgba | ||
| retention-days: 14 | ||
| if-no-files-found: ignore | ||
| publish-pypi: | ||
| needs: | ||
| - build-python-packages | ||
| - test-non-gui | ||
| - test-ui-tests | ||
| - create-release | ||
| if: startsWith(github.ref, 'refs/tags/') | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Download built distributions | ||
| uses: actions/download-artifact@v6 | ||
| with: | ||
| path: dist | ||
| merge-multiple: true | ||
| - name: Publish to TestPyPI | ||
| uses: pypa/gh-action-pypi-publish@release/v1 | ||
| with: | ||
| packages_dir: dist | ||
| repository-url: https://test.pypi.org/legacy/ | ||
| - name: Publish to PyPI | ||
| uses: pypa/gh-action-pypi-publish@release/v1 | ||
| with: | ||
| packages_dir: dist | ||
| push-to-cachix: | ||
| runs-on: [self-hosted, nixos] | ||
| needs: | ||
| - test-non-gui | ||
| - test-ui-tests | ||
| - appimage-lib-check | ||
| - dmg-lib-check | ||
| if: "github.ref == 'refs/heads/main' && ${{ !github.event.codetracer-ci }}" | ||
|
Check warning on line 1339 in .github/workflows/codetracer.yml
|
||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Install Nix | ||
| uses: ./.github/actions/setup-nix | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - run: "nix develop .#devShells.x86_64-linux.default --command ./ci/deploy/build-nix-and-push-to-cachix.sh" | ||
| build-and-deploy-docs: | ||
| runs-on: [self-hosted, nixos] | ||
| needs: [push-to-cachix] | ||
| if: ${{ github.ref == 'refs/heads/main' && !github.event['codetracer-ci'] }} | ||
| permissions: | ||
| contents: "write" | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Install Nix | ||
| uses: ./.github/actions/setup-nix | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| gh-token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - run: | | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| git config init.defaultBranch main | ||
| git remote set-url origin https://x-access-token:${{ secrets.CODETRACER_PUSH_GITHUB_TOKEN }}@github.com/metacraft-labs/codetracer | ||
| nix develop .#devShells.x86_64-linux.default --command ./ci/deploy/docs.sh | ||
| push-tag: | ||
| runs-on: [ self-hosted, nixos ] | ||
| needs: [ dev-build, nix-build, appimage-build, dmg-build ] | ||
| permissions: | ||
| contents: "write" | ||
| outputs: | ||
| tag: ${{ steps.tag.outputs.tag }} | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| submodules: recursive | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Install Nix | ||
| uses: metacraft-labs/nixos-modules/.github/install-nix@main | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| - name: Configure Nix for private repos | ||
| run: | | ||
| mkdir -p ~/.config/nix | ||
| echo "access-tokens = github.com=${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }}" >> ~/.config/nix/nix.conf | ||
| git config --global url."https://x-access-token:${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }}@github.com/".insteadOf "git@github.com:" | ||
| git config --global url."https://x-access-token:${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }}@github.com/".insteadOf "ssh://git@github.com/" | ||
| git config --global url."https://x-access-token:${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }}@github.com/".insteadOf "https://github.com/" | ||
| - name: Create tag | ||
| if: ${{ github.ref == 'refs/heads/main' }} | ||
| id: tag | ||
| run: | | ||
| YEAR=$(bash -c 'grep "CodeTracerYear\*" src/ct/version.nim | sed "s/.*CodeTracerYear\* = //g"') | ||
| MONTH=$(bash -c "printf '%02d' \$(grep \"CodeTracerMonth\*\" src/ct/version.nim | sed \"s/.*CodeTracerMonth\* = //g\")") | ||
| BUILD=$(bash -c 'grep "CodeTracerBuild\*" src/ct/version.nim | sed "s/.*CodeTracerBuild\* = //g"') | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| git config init.defaultBranch main | ||
| git remote set-url origin https://x-access-token:${{ secrets.CODETRACER_PUSH_GITHUB_TOKEN }}@github.com/metacraft-labs/codetracer | ||
| git tag -a "$YEAR.$MONTH.$BUILD" -m "Release $YEAR.$MONTH.$BUILD" || echo "Tag already exists" | ||
| (git push origin "$YEAR.$MONTH.$BUILD" && echo "tag=$YEAR.$MONTH.$BUILD" >> $GITHUB_OUTPUT) || echo "Tag already exists" | ||
| create-release: | ||
| runs-on: [ self-hosted, nixos ] | ||
| needs: [ push-tag ] | ||
| if: ${{ ((startsWith(github.ref, 'refs/tags/') && !contains(github.ref_name, '-')) || needs.push-tag.outputs.tag != '') && !github.event['codetracer-ci'] }} | ||
| permissions: | ||
| contents: "write" | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| token: ${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }} | ||
| - name: Install Nix | ||
| uses: metacraft-labs/nixos-modules/.github/install-nix@main | ||
| with: | ||
| cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} | ||
| cachix-cache: ${{ vars.CACHIX_CACHE }} | ||
| trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }} | ||
| substituters: ${{ vars.SUBSTITUTERS }} | ||
| - name: Configure Nix for private repos | ||
| run: | | ||
| mkdir -p ~/.config/nix | ||
| echo "access-tokens = github.com=${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }}" >> ~/.config/nix/nix.conf | ||
| git config --global url."https://x-access-token:${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }}@github.com/".insteadOf "git@github.com:" | ||
| git config --global url."https://x-access-token:${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }}@github.com/".insteadOf "ssh://git@github.com/" | ||
| git config --global url."https://x-access-token:${{ secrets.GH_READ_METACRAFT_PRIVATE_REPOS }}@github.com/".insteadOf "https://github.com/" | ||
| - name: "Import GPG key for signing commits" | ||
| id: import-gpg | ||
| uses: crazy-max/ghaction-import-gpg@v6 | ||
| with: | ||
| gpg_private_key: ${{ secrets.CODETRACER_AUR_GPG_PRIVATE_KEY }} | ||
| passphrase: ${{ secrets.CODETRACER_AUR_GPG_PRIVATE_KEY_PASS }} | ||
| git_config_global: true | ||
| git_user_signingkey: true | ||
| git_commit_gpgsign: true | ||
| - name: Create resource tarball | ||
| run: | | ||
| nix develop .#devShells.x86_64-linux.default --command bash -c "tar cfJ resources.tar.xz resources/" | ||
| nix develop .#devShells.x86_64-linux.default --command bash -c "gpg --detach-sign resources.tar.xz" | ||
| - name: Upload latest | ||
| env: | ||
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY_ID }} | ||
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_CODETRACER_BUCKET_ACCESS_KEY }} | ||
| run: | | ||
| nix develop .#devShells.x86_64-linux.default --command wget "https://downloads.codetracer.com/CodeTracer-main-arm64.dmg" | ||
| nix develop .#devShells.x86_64-linux.default --command wget "https://downloads.codetracer.com/CodeTracer-main-arm64.dmg.asc" | ||
| nix develop .#devShells.x86_64-linux.default --command wget "https://downloads.codetracer.com/CodeTracer-main-amd64.AppImage" | ||
| nix develop .#devShells.x86_64-linux.default --command wget "https://downloads.codetracer.com/CodeTracer-main-amd64.AppImage.asc" | ||
| nix develop .#devShells.x86_64-linux.default --command aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp CodeTracer-main-arm64.dmg s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/CodeTracer-${{ needs.push-tag.outputs.tag }}-arm64.dmg --checksum-algorithm CRC32 | ||
| nix develop .#devShells.x86_64-linux.default --command aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp CodeTracer-main-arm64.dmg.asc s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/CodeTracer-${{ needs.push-tag.outputs.tag }}-arm64.dmg.asc --checksum-algorithm CRC32 | ||
| nix develop .#devShells.x86_64-linux.default --command aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp CodeTracer-main-amd64.AppImage s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/CodeTracer-${{ needs.push-tag.outputs.tag }}-amd64.AppImage --checksum-algorithm CRC32 | ||
| nix develop .#devShells.x86_64-linux.default --command aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp CodeTracer-main-amd64.AppImage.asc s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/CodeTracer-${{ needs.push-tag.outputs.tag }}-amd64.AppImage.asc --checksum-algorithm CRC32 | ||
| nix develop .#devShells.x86_64-linux.default --command aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp CodeTracer-main-arm64.dmg s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/CodeTracer-latest-arm64.dmg --checksum-algorithm CRC32 | ||
| nix develop .#devShells.x86_64-linux.default --command aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp CodeTracer-main-arm64.dmg.asc s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/CodeTracer-latest-arm64.dmg.asc --checksum-algorithm CRC32 | ||
| nix develop .#devShells.x86_64-linux.default --command aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp CodeTracer-main-amd64.AppImage s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/CodeTracer-latest-amd64.AppImage --checksum-algorithm CRC32 | ||
| nix develop .#devShells.x86_64-linux.default --command aws --endpoint-url=${{ secrets.R2_CODETRACER_BUCKET_S3_ENDPOINT }} s3 cp CodeTracer-main-amd64.AppImage.asc s3://${{ vars.R2_CODETRACER_BUCKET_NAME }}/CodeTracer-latest-amd64.AppImage.asc --checksum-algorithm CRC32 | ||
| - name: Get changelog text | ||
| id: changelog | ||
| run: | | ||
| nix develop .#devShells.x86_64-linux.default --command bash -c "awk '/^## /{if (p) exit; p=1} p' CHANGELOG.md > release_changelog.md" | ||
| echo "\ | ||
| We're actively working on multiple exciting features, which are not fully released yet. Stay tuned! | ||
| Available downloads: | ||
| <a href="https://downloads.codetracer.com/CodeTracer-${{ needs.push-tag.outputs.tag }}-arm64.dmg"><img width="75px" height="100px" src="https://upload.wikimedia.org/wikipedia/commons/1/1b/Apple_logo_grey.svg"></a> | ||
| <a href="https://deb.codetracer.com/"><img width="100px" height="100px" src="https://upload.wikimedia.org/wikipedia/commons/9/9e/UbuntuCoF.svg"></a> | ||
| <a href="https://deb.codetracer.com/"><img width="100px" height="100px" src="https://upload.wikimedia.org/wikipedia/commons/6/66/Openlogo-debianV2.svg"></a> | ||
| <a href="https://rpm.codetracer.com/"><img width="100px" height="100px" src="https://upload.wikimedia.org/wikipedia/commons/d/d8/Red_Hat_logo.svg"></a> | ||
| <a href="https://rpm.codetracer.com/"><img width="100px" height="100px" src="https://upload.wikimedia.org/wikipedia/commons/3/3f/Fedora_logo.svg"></a> | ||
| <a href="https://github.com/metacraft-labs/metacraft-overlay"><img width="100px" height="100px" src="https://upload.wikimedia.org/wikipedia/commons/4/48/Gentoo_Linux_logo_matte.svg"></a> | ||
| <a href="https://aur.archlinux.org/packages/codetracer"><img width="100px" height="100px" src="https://upload.wikimedia.org/wikipedia/commons/1/13/Arch_Linux_%22Crystal%22_icon.svg"></a> | ||
| <a href="https://downloads.codetracer.com/CodeTracer-${{ needs.push-tag.outputs.tag }}-amd64.AppImage"><img width="100px" height="100px" src="https://upload.wikimedia.org/wikipedia/commons/7/73/App-image-logo.svg"></a> | ||
| Key signatures: | ||
| [](https://downloads.codetracer.com/CodeTracer-${{ needs.push-tag.outputs.tag }}-arm64.dmg.asc) | ||
| [](https://downloads.codetracer.com/CodeTracer-${{ needs.push-tag.outputs.tag }}-amd64.AppImage.asc) | ||
| [](https://downloads.codetracer.com/CodeTracer.pub.asc)" >> release_changelog.md | ||
| - name: Create Release | ||
| uses: softprops/action-gh-release@v2 | ||
| with: | ||
| body_path: "release_changelog.md" | ||
| draft: true | ||
| prerelease: false | ||
| files: | | ||
| resources.tar.xz | ||
| resources.tar.xz.asc | ||
| generate_release_notes: false | ||
| tag_name: "${{ needs.push-tag.outputs.tag }}" | ||