-
Notifications
You must be signed in to change notification settings - Fork 0
185 lines (165 loc) · 7.86 KB
/
Copy pathwindows-ci.yml
File metadata and controls
185 lines (165 loc) · 7.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
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