Skip to content

feat(parser): optional pj.parser_runtime.v1 diagnostics service #542

feat(parser): optional pj.parser_runtime.v1 diagnostics service

feat(parser): optional pj.parser_runtime.v1 diagnostics service #542

Workflow file for this run

name: Windows CI
on:
push:
branches: [main]
pull_request:
branches: [main]
types: [opened, synchronize, reopened, ready_for_review]
workflow_dispatch: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
if: github.event.pull_request.draft == false
runs-on: windows-latest
permissions:
contents: read
packages: write # push/pull the Conan cache OCI artifact on ghcr.io
steps:
- uses: actions/checkout@v4
- uses: conan-io/setup-conan@v1
with:
# We back the cache via ghcr.io/oras instead of actions/cache (which
# has a 10 GB per-repo soft cap and 7-day eviction). ghcr.io public
# repos: unlimited storage and bandwidth; tags survive forever.
cache_packages: false
- name: Setup oras (OCI Registry As Storage)
# Primary install path. continue-on-error so a 5xx on the github.com
# release CDN doesn't kill CI — we have a fallback below, and worst
# case we degrade to "no cache this run" (build still completes).
id: setup_oras
uses: oras-project/setup-oras@v1
continue-on-error: true
- name: Setup oras (manual download fallback)
# Only fires if setup-oras failed. No truly-independent CDN exists
# for the oras binary on Windows runners, so we re-download from the
# same release URL but with longer exponential backoff (5 retries vs
# setup-oras's 2). Helps with brief 5xx blips that exceed the action's
# built-in retry budget.
id: setup_oras_fallback
if: steps.setup_oras.outcome == 'failure'
continue-on-error: true
shell: pwsh
run: |
$version = "1.3.0"
$url = "https://github.com/oras-project/oras/releases/download/v$version/oras_${version}_windows_amd64.zip"
$zip = Join-Path $env:RUNNER_TEMP "oras.zip"
$installDir = Join-Path $env:RUNNER_TEMP "oras-bin"
New-Item -ItemType Directory -Force -Path $installDir | Out-Null
$attempts = 0
while ($attempts -lt 5) {
try {
Invoke-WebRequest -Uri $url -OutFile $zip -UseBasicParsing
break
} catch {
$attempts++
if ($attempts -ge 5) { throw }
$delay = [math]::Pow(2, $attempts) * 5
Write-Host "Download attempt $attempts failed: $_. Retry in ${delay}s..."
Start-Sleep -Seconds $delay
}
}
Expand-Archive -Path $zip -DestinationPath $installDir -Force
"$installDir" | Out-File -FilePath $env:GITHUB_PATH -Append
& "$installDir\oras.exe" version
- name: Compute Conan cache tag
id: conan_cache
shell: pwsh
run: |
$hash = (Get-FileHash conanfile.py -Algorithm SHA256).Hash.Substring(0, 16).ToLower()
$owner = "${{ github.repository_owner }}".ToLower()
$tag = "ghcr.io/$owner/plotjuggler-core-conan-cache:windows-msvc-$hash"
$mainTag = "ghcr.io/$owner/plotjuggler-core-conan-cache:windows-msvc-main"
"tag=$tag" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
"main_tag=$mainTag" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
Write-Host "Cache tag: $tag"
Write-Host "Main fallback cache tag: $mainTag"
- name: Login to ghcr.io
# Required for both pull (private packages) and push. GITHUB_TOKEN is
# auto-provisioned and scoped to this repo's packages. Skip if neither
# oras install path succeeded — graceful degradation to no-cache build.
if: github.repository_owner == 'PlotJuggler' && (steps.setup_oras.outcome == 'success' || steps.setup_oras_fallback.outcome == 'success')
shell: pwsh
env:
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
$env:GHCR_TOKEN | oras login ghcr.io -u $env:GITHUB_ACTOR --password-stdin
- name: Restore Conan cache from ghcr.io
if: github.repository_owner == 'PlotJuggler' && (steps.setup_oras.outcome == 'success' || steps.setup_oras_fallback.outcome == 'success')
shell: pwsh
run: |
$exactTag = "${{ steps.conan_cache.outputs.tag }}"
$mainTag = "${{ steps.conan_cache.outputs.main_tag }}"
$pullDir = Join-Path $env:RUNNER_TEMP "conan-cache-pull"
New-Item -ItemType Directory -Force -Path $pullDir | Out-Null
$tarball = Join-Path $pullDir "conan-cache.tar.zst"
foreach ($tag in @($exactTag, $mainTag)) {
Remove-Item $tarball -Force -ErrorAction SilentlyContinue
Write-Host "Trying Conan cache: $tag"
Push-Location $pullDir
try {
oras pull $tag 2>&1 | Out-Host
$pulled = $LASTEXITCODE
} finally {
Pop-Location
}
if ($pulled -eq 0 -and (Test-Path $tarball)) {
Write-Host "Cache HIT: extracting $tarball"
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.conan2" | Out-Null
tar --zstd -xf $tarball -C $env:USERPROFILE
"CONAN_CACHE_HIT=1" | Out-File -FilePath $env:GITHUB_ENV -Append
"CONAN_CACHE_HIT_TAG=$tag" | Out-File -FilePath $env:GITHUB_ENV -Append
if ($tag -eq $exactTag) {
"CONAN_CACHE_EXACT_HIT=1" | Out-File -FilePath $env:GITHUB_ENV -Append
}
$global:LASTEXITCODE = 0
exit 0
}
Write-Host "Cache MISS for $tag"
}
# Reset exit code so a missing tag doesn't fail the step
$global:LASTEXITCODE = 0
- name: Install sccache
uses: mozilla-actions/sccache-action@v0.0.9
- name: Conan install
run: >
conan install . --output-folder=build --build=missing
-s build_type=Release -s compiler.cppstd=20
-o "plotjuggler_sdk/*:with_tests=True"
- name: Save Conan cache to ghcr.io
# Only push from the canonical repo on real pushes (forks lack write
# access to ghcr.io packages). Skip on exact cache HIT — the tag content
# is already up to date, no point re-uploading the same bytes. Skip if
# neither oras install path succeeded (graceful degradation).
if: github.event_name == 'push' && github.repository == 'PlotJuggler/plotjuggler_sdk' && env.CONAN_CACHE_EXACT_HIT != '1' && (steps.setup_oras.outcome == 'success' || steps.setup_oras_fallback.outcome == 'success')
shell: pwsh
run: |
$tag = "${{ steps.conan_cache.outputs.tag }}"
$tarball = Join-Path $env:RUNNER_TEMP "conan-cache.tar.zst"
# Trim build trees before packing so the uploaded artifact only
# contains the package binaries consumers actually need.
conan cache clean "*" --build --source --temp
Write-Host "Packing ~/.conan2 -> $tarball"
tar --zstd -cf $tarball -C $env:USERPROFILE .conan2
$size = (Get-Item $tarball).Length / 1MB
Write-Host ("Compressed cache size: {0:N1} MB" -f $size)
Push-Location $env:RUNNER_TEMP
try {
oras push $tag "conan-cache.tar.zst:application/vnd.oci.image.layer.v1.tar+zstd"
if ($env:GITHUB_REF_NAME -eq "main") {
oras push "${{ steps.conan_cache.outputs.main_tag }}" "conan-cache.tar.zst:application/vnd.oci.image.layer.v1.tar+zstd"
}
} finally {
Pop-Location
}
- name: Configure
run: >
cmake -S . -B build
-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/build/conan_toolchain.cmake
-DCMAKE_C_COMPILER_LAUNCHER=sccache
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
- name: Build
run: cmake --build build --config Release
- name: Test
run: ctest --test-dir build --build-config Release --output-on-failure