ci: harden cache, timeouts and retries across CI and release (#328)
Hardens both workflows after the R-on-ubuntu job repeatedly hit the 20-minute job cap and was cancelled (no R-package cache + no retry + a slow source build). Each item below maps to the requested checklist. ### CI (`ci.yml`) - **Timeouts 20 → 30 min** on every job (backstop only; real jobs finish well under). - **R dependencies cached**: replace the manual `install.packages(testthat/knitr)` with `r-lib/actions/setup-r-dependencies` — restores a cached R library and pulls **RSPM binaries** instead of compiling from source (the slow/flaky path that blew the cap). This is the actual root-cause fix. - **NuGet cache** for the C# job (`~/.nuget/packages`, keyed on the project files). - **Retry** the network installs that had none — `npm ci`, `dotnet test`, `mvn install` — via `nick-fields/retry` (2–3 attempts, backoff). On top of the existing env-level retries (`CARGO_NET_RETRY`, `npm_config_fetch_retries`, `PIP_RETRIES`) and the setup-* CDN-flake retries. - **Go stays `cache: false`** on purpose: the module has no `go.sum` / external deps, so there is nothing to cache (enabling it would only warn). ### Release (`release.yml`) - **Per-job timeouts** added (there were none — only GitHub's 6h default): **45 min**, higher than CI's 30 because the wheel/build jobs compile from source incl. **vendored OpenSSL** and must not be killed mid-build. - **wasm-publish** gets a `Swatinem/rust-cache` like the other Rust-build jobs. - **Retry** the no-retry network installs (`npm ci` ×2, `dotnet pack`). The actual publish/deploy steps are left alone — they are already idempotent (skip-existing / skip-duplicate), so re-running the job is the safe recovery. ### R binding download (`bindings/r/configure[.win]`) - A freshly cut release can 404 for 1–2 min while assets propagate, which broke the C ABI download (`cannot open URL … 404`). Add a `wickra_download` retry helper (6 × 20s ≈ 2 min backoff) for both the release-asset and wasm-source downloads. Note: the CI R job builds the C ABI **locally** (`WICKRA_*_DIR`), so it never downloads — this fix covers the real-world r-universe / end-user build. This PR's own CI exercises the CI changes (the reworked R job, caches, retries, timeouts) before merge; the release-only changes are validated on the next tag.
This commit is contained in:
+69
-24
@@ -34,7 +34,7 @@ jobs:
|
||||
rust:
|
||||
name: Rust ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -105,7 +105,7 @@ jobs:
|
||||
examples-smoke:
|
||||
name: Examples (syntax smoke)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
@@ -195,7 +195,7 @@ jobs:
|
||||
clippy-bindings:
|
||||
name: Clippy bindings
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
@@ -279,7 +279,7 @@ jobs:
|
||||
msrv:
|
||||
name: ${{ matrix.name }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -328,7 +328,7 @@ jobs:
|
||||
coverage:
|
||||
name: Coverage
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
@@ -370,7 +370,7 @@ jobs:
|
||||
supply-chain:
|
||||
name: Supply-chain (cargo-deny)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
@@ -389,7 +389,7 @@ jobs:
|
||||
fuzz-smoke:
|
||||
name: Fuzz (smoke)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
@@ -443,7 +443,7 @@ jobs:
|
||||
python:
|
||||
name: Python ${{ matrix.python-version }} on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -525,7 +525,7 @@ jobs:
|
||||
wasm:
|
||||
name: WASM build
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
@@ -575,7 +575,7 @@ jobs:
|
||||
node:
|
||||
name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -622,9 +622,17 @@ jobs:
|
||||
cache: npm
|
||||
cache-dependency-path: bindings/node/package-lock.json
|
||||
|
||||
# npm's own fetch-retry (npm_config_fetch_retries) rides out per-request
|
||||
# blips; wrap the whole `npm ci` once more so a longer registry hiccup
|
||||
# retries the install instead of failing the job.
|
||||
- name: Install Node dependencies
|
||||
working-directory: bindings/node
|
||||
run: npm ci
|
||||
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
retry_wait_seconds: 20
|
||||
command: cd bindings/node && npm ci
|
||||
shell: bash
|
||||
|
||||
- name: Build native module
|
||||
working-directory: bindings/node
|
||||
@@ -649,7 +657,7 @@ jobs:
|
||||
c-abi:
|
||||
name: C ABI on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -705,7 +713,7 @@ jobs:
|
||||
csharp:
|
||||
name: C# on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -723,6 +731,19 @@ jobs:
|
||||
continue-on-error: true # cache is an optimisation; never block on a stuck/slow restore
|
||||
timeout-minutes: 6
|
||||
|
||||
# Cache the restored NuGet packages so dotnet test/build resolve from the
|
||||
# local store instead of hitting nuget.org every run. No packages.lock.json
|
||||
# exists, so key on the project files; never block the job on a slow restore.
|
||||
- name: Cache NuGet packages
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
continue-on-error: true
|
||||
timeout-minutes: 6
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-nuget-
|
||||
|
||||
# The binding links against the C ABI hub at runtime; build it first so the
|
||||
# DllImportResolver finds target/release/wickra.{dll,so,dylib}. .NET 8 SDK is
|
||||
# preinstalled on the GitHub runners, so no setup-dotnet step is needed.
|
||||
@@ -732,8 +753,17 @@ jobs:
|
||||
- name: .NET info
|
||||
run: dotnet --info
|
||||
|
||||
# dotnet test restores from nuget.org first; retry so a transient restore
|
||||
# blip retries instead of failing the job (the cached packages above make
|
||||
# the retry cheap).
|
||||
- name: Test the C# binding
|
||||
run: dotnet test bindings/csharp/Wickra.Tests/Wickra.Tests.csproj -c Release
|
||||
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||
with:
|
||||
timeout_minutes: 15
|
||||
max_attempts: 2
|
||||
retry_wait_seconds: 20
|
||||
command: dotnet test bindings/csharp/Wickra.Tests/Wickra.Tests.csproj -c Release
|
||||
shell: bash
|
||||
|
||||
- name: Build the C# examples
|
||||
shell: bash
|
||||
@@ -756,7 +786,7 @@ jobs:
|
||||
go:
|
||||
name: Go on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -879,7 +909,7 @@ jobs:
|
||||
r:
|
||||
name: R on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -912,10 +942,17 @@ jobs:
|
||||
r-version: "release"
|
||||
use-public-rspm: true
|
||||
|
||||
# Use the repos configured by setup-r (use-public-rspm) so Linux installs
|
||||
# binary packages — building testthat's deps from source is slow and flaky.
|
||||
- name: Install test dependency
|
||||
run: Rscript -e 'install.packages("testthat")'
|
||||
# Install the R dependencies via setup-r-dependencies: it restores a cached
|
||||
# package library (actions/cache) and pulls RSPM *binaries* instead of
|
||||
# compiling testthat / knitr and their deps from source — the slow, flaky
|
||||
# path that previously blew past the job timeout on the ubuntu runner.
|
||||
- name: Install R dependencies (cached binaries)
|
||||
uses: r-lib/actions/setup-r-dependencies@a51a8012b0aab7c32ef9d19bf54da93f3254335e # v2
|
||||
with:
|
||||
working-directory: bindings/r
|
||||
extra-packages: |
|
||||
any::testthat
|
||||
any::knitr
|
||||
|
||||
- name: Install and test the R binding
|
||||
shell: bash
|
||||
@@ -938,8 +975,8 @@ jobs:
|
||||
# CRAN (with pandoc); this job only INSTALLs, so execute the vignette's R
|
||||
# chunks here (knit, no pandoc needed) to catch a broken example before it
|
||||
# reaches the published build.
|
||||
# knitr is installed by the cached setup-r-dependencies step above.
|
||||
run: |
|
||||
Rscript -e 'install.packages("knitr", repos = Sys.getenv("RSPM", unset = "https://cloud.r-project.org"))'
|
||||
Rscript -e 'knitr::knit("bindings/r/vignettes/getting-started.Rmd", output = tempfile(fileext = ".md"), quiet = TRUE); cat("vignette code OK\n")'
|
||||
|
||||
- name: Run the offline R examples
|
||||
@@ -961,7 +998,7 @@ jobs:
|
||||
java:
|
||||
name: Java on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -1016,8 +1053,16 @@ jobs:
|
||||
|
||||
# `install` runs the archetype test suite (the real FFI boundary check) and
|
||||
# installs the binding to the local repo so the examples can resolve it.
|
||||
# Maven resolves plugins/deps from the network on a cache miss; retry so a
|
||||
# transient Central blip retries instead of failing the job.
|
||||
- name: Test and install the Java binding
|
||||
run: mvn -B -f bindings/java install
|
||||
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||
with:
|
||||
timeout_minutes: 20
|
||||
max_attempts: 2
|
||||
retry_wait_seconds: 20
|
||||
command: mvn -B -f bindings/java install
|
||||
shell: bash
|
||||
|
||||
- name: Build the Java examples
|
||||
run: mvn -B -f examples/java compile
|
||||
|
||||
@@ -36,6 +36,7 @@ jobs:
|
||||
# --------------------------------------------------------------------------
|
||||
cargo-publish:
|
||||
name: Publish to crates.io
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
runs-on: ubuntu-latest
|
||||
# The publish jobs run with long-lived registry tokens. Binding them to a
|
||||
# protected GitHub environment lets the org require a reviewer to approve
|
||||
@@ -139,6 +140,7 @@ jobs:
|
||||
# --------------------------------------------------------------------------
|
||||
python-wheels:
|
||||
name: Build wheels (${{ matrix.target }}/${{ matrix.manylinux }} on ${{ matrix.os }})
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -209,6 +211,7 @@ jobs:
|
||||
|
||||
python-sdist:
|
||||
name: Build Python sdist
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
@@ -228,6 +231,7 @@ jobs:
|
||||
|
||||
python-publish:
|
||||
name: Publish to PyPI
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: [python-wheels, python-sdist]
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
@@ -251,6 +255,7 @@ jobs:
|
||||
# --------------------------------------------------------------------------
|
||||
node-build:
|
||||
name: Node build (${{ matrix.target }})
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -296,8 +301,13 @@ jobs:
|
||||
timeout-minutes: 6
|
||||
|
||||
- name: Install Node deps
|
||||
working-directory: bindings/node
|
||||
run: npm ci
|
||||
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
retry_wait_seconds: 20
|
||||
command: cd bindings/node && npm ci
|
||||
shell: bash
|
||||
|
||||
- name: Build native module
|
||||
working-directory: bindings/node
|
||||
@@ -312,6 +322,7 @@ jobs:
|
||||
|
||||
node-publish:
|
||||
name: Publish to npm
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: node-build
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
@@ -351,8 +362,13 @@ jobs:
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
- name: Install Node deps
|
||||
working-directory: bindings/node
|
||||
run: npm ci
|
||||
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
retry_wait_seconds: 20
|
||||
command: cd bindings/node && npm ci
|
||||
shell: bash
|
||||
|
||||
- name: Download all platform binaries
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
@@ -484,6 +500,7 @@ jobs:
|
||||
# which requires the `id-token: write` permission set at the job level.
|
||||
wasm-publish:
|
||||
name: Publish wickra-wasm to npm
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
# `id-token: write` lets npm publish embed a Sigstore provenance
|
||||
@@ -523,6 +540,10 @@ jobs:
|
||||
with:
|
||||
targets: wasm32-unknown-unknown
|
||||
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
continue-on-error: true # cache is an optimisation; never block on a stuck/slow restore
|
||||
timeout-minutes: 6
|
||||
|
||||
- name: Install wasm-pack (latest, via prebuilt binary)
|
||||
# See the matching note in ci.yml: jetli's default installs an old
|
||||
# 0.10.x wasm-pack whose build subcommand rejects --features.
|
||||
@@ -590,6 +611,7 @@ jobs:
|
||||
# --------------------------------------------------------------------------
|
||||
c-abi-build:
|
||||
name: C ABI library (${{ matrix.target }})
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -645,6 +667,7 @@ jobs:
|
||||
# workflow release.yml) exchanges the GitHub OIDC token for a short-lived key.
|
||||
csharp-publish:
|
||||
name: Publish to NuGet
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: c-abi-build
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
@@ -689,11 +712,18 @@ jobs:
|
||||
echo "staged ${RID[$target]}:"; ls -l "$dest"
|
||||
done
|
||||
|
||||
# dotnet pack restores from nuget.org first; retry so a transient restore
|
||||
# blip retries instead of failing the release.
|
||||
- name: Pack
|
||||
shell: bash
|
||||
run: |
|
||||
version="${GITHUB_REF_NAME#v}"
|
||||
dotnet pack bindings/csharp/Wickra/Wickra.csproj -c Release -p:Version="$version" -o nupkg
|
||||
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||
with:
|
||||
timeout_minutes: 15
|
||||
max_attempts: 2
|
||||
retry_wait_seconds: 20
|
||||
shell: bash
|
||||
command: |
|
||||
version="${GITHUB_REF_NAME#v}"
|
||||
dotnet pack bindings/csharp/Wickra/Wickra.csproj -c Release -p:Version="$version" -o nupkg
|
||||
|
||||
# Exchange the GitHub OIDC token for a short-lived (~1h) NuGet API key.
|
||||
# 'user' is the nuget.org profile name (the package owner), not an email.
|
||||
@@ -728,6 +758,7 @@ jobs:
|
||||
# match the release tag (kept in sync by the version-bump checklist).
|
||||
java-publish:
|
||||
name: Publish to Maven Central
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: c-abi-build
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
@@ -799,6 +830,7 @@ jobs:
|
||||
# derived artifact, so its bot commit is intentionally unsigned.
|
||||
go-mirror:
|
||||
name: Mirror the Go module to wickra-go
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: c-abi-build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -882,6 +914,7 @@ jobs:
|
||||
|
||||
github-release:
|
||||
name: Attach assets to the draft GitHub Release
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: [cargo-publish, python-publish, node-publish, wasm-publish, c-abi-build]
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
@@ -1007,6 +1040,7 @@ jobs:
|
||||
# --------------------------------------------------------------------------
|
||||
attestations:
|
||||
name: Attest build provenance
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: [cargo-publish, python-wheels, python-sdist, github-release]
|
||||
runs-on: ubuntu-latest
|
||||
# Signed SLSA build-provenance attestations for the published crates and
|
||||
@@ -1090,6 +1124,7 @@ jobs:
|
||||
# --------------------------------------------------------------------------
|
||||
publish-release:
|
||||
name: Publish the GitHub Release
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: [github-release, attestations]
|
||||
if: always() && needs.github-release.result == 'success'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
Vendored
+22
-4
@@ -14,6 +14,26 @@ set -e
|
||||
inc=""
|
||||
lib=""
|
||||
|
||||
# A freshly-cut GitHub release can briefly return 404 while its assets propagate
|
||||
# across the CDN, and a transient network blip should not fail the build either.
|
||||
# Retry base R's download.file with a backoff (~2 min total) instead of giving up
|
||||
# on the first miss.
|
||||
wickra_download() {
|
||||
_url="$1"
|
||||
_dest="$2"
|
||||
_attempt=1
|
||||
while [ "${_attempt}" -le 6 ]; do
|
||||
if "${R_HOME}/bin/Rscript" -e "download.file('${_url}', '${_dest}', mode = 'wb', quiet = TRUE)"; then
|
||||
return 0
|
||||
fi
|
||||
echo "wickra: download attempt ${_attempt}/6 failed (${_url}); the release asset may still be propagating — retrying in 20s..."
|
||||
sleep 20
|
||||
_attempt=$((_attempt + 1))
|
||||
done
|
||||
echo "wickra: failed to download ${_url} after 6 attempts"
|
||||
return 1
|
||||
}
|
||||
|
||||
# WebAssembly (r-universe / webR): there is no prebuilt wasm C ABI to download,
|
||||
# but the build image ships cargo (/usr/local/cargo/bin) and emscripten
|
||||
# (EMSDK on PATH), so build the C ABI staticlib from source for
|
||||
@@ -26,8 +46,7 @@ if [ "$(uname -s)" = "Emscripten" ]; then
|
||||
echo "wickra: building C ABI from source for wasm32-unknown-emscripten (v${version})"
|
||||
build=$(mktemp -d)
|
||||
url="https://github.com/wickra-lib/wickra/archive/refs/tags/v${version}.tar.gz"
|
||||
"${R_HOME}/bin/Rscript" -e "download.file('${url}', '${build}/src.tar.gz', mode = 'wb', quiet = TRUE)" \
|
||||
|| { echo "wickra: failed to download source ${url}"; exit 1; }
|
||||
wickra_download "${url}" "${build}/src.tar.gz" || exit 1
|
||||
"${R_HOME}/bin/Rscript" -e "untar('${build}/src.tar.gz', exdir = '${build}')"
|
||||
root="${build}/wickra-${version}"
|
||||
rustup target add wasm32-unknown-emscripten 2>/dev/null || true
|
||||
@@ -73,8 +92,7 @@ else
|
||||
esac
|
||||
url="https://github.com/wickra-lib/wickra/releases/download/v${version}/wickra-c-${triple}.tar.gz"
|
||||
echo "wickra: downloading C ABI ${triple} for v${version}"
|
||||
"${R_HOME}/bin/Rscript" -e "download.file('${url}', 'src/wickra-c.tar.gz', mode = 'wb', quiet = TRUE)" \
|
||||
|| { echo "wickra: failed to download ${url}"; exit 1; }
|
||||
wickra_download "${url}" "src/wickra-c.tar.gz" || exit 1
|
||||
"${R_HOME}/bin/Rscript" -e "untar('src/wickra-c.tar.gz', exdir = 'src/wickra-c')"
|
||||
inc="src/wickra-c/wickra-c-${triple}/include"
|
||||
lib="src/wickra-c/wickra-c-${triple}/lib"
|
||||
|
||||
@@ -10,6 +10,26 @@
|
||||
# WICKRA_LIB_DIR to build against a locally built C ABI instead (dev override).
|
||||
set -e
|
||||
|
||||
# A freshly-cut GitHub release can briefly return 404 while its assets propagate
|
||||
# across the CDN, and a transient network blip should not fail the build either.
|
||||
# Retry base R's download.file with a backoff (~2 min total) instead of giving up
|
||||
# on the first miss.
|
||||
wickra_download() {
|
||||
_url="$1"
|
||||
_dest="$2"
|
||||
_attempt=1
|
||||
while [ "${_attempt}" -le 6 ]; do
|
||||
if "${R_HOME}/bin/Rscript" -e "download.file('${_url}', '${_dest}', mode = 'wb', quiet = TRUE)"; then
|
||||
return 0
|
||||
fi
|
||||
echo "wickra: download attempt ${_attempt}/6 failed (${_url}); the release asset may still be propagating — retrying in 20s..."
|
||||
sleep 20
|
||||
_attempt=$((_attempt + 1))
|
||||
done
|
||||
echo "wickra: failed to download ${_url} after 6 attempts"
|
||||
return 1
|
||||
}
|
||||
|
||||
if [ -n "${WICKRA_INCLUDE_DIR}" ] && [ -n "${WICKRA_LIB_DIR}" ]; then
|
||||
echo "wickra: using C ABI from WICKRA_INCLUDE_DIR / WICKRA_LIB_DIR (dev override)"
|
||||
inc="${WICKRA_INCLUDE_DIR}"
|
||||
@@ -24,8 +44,7 @@ else
|
||||
esac
|
||||
url="https://github.com/wickra-lib/wickra/releases/download/v${version}/wickra-c-${triple}.tar.gz"
|
||||
echo "wickra: downloading C ABI ${triple} for v${version}"
|
||||
"${R_HOME}/bin/Rscript" -e "download.file('${url}', 'src/wickra-c.tar.gz', mode = 'wb', quiet = TRUE)" \
|
||||
|| { echo "wickra: failed to download ${url}"; exit 1; }
|
||||
wickra_download "${url}" "src/wickra-c.tar.gz" || exit 1
|
||||
"${R_HOME}/bin/Rscript" -e "untar('src/wickra-c.tar.gz', exdir = 'src/wickra-c')"
|
||||
inc="src/wickra-c/wickra-c-${triple}/include"
|
||||
lib="src/wickra-c/wickra-c-${triple}/lib"
|
||||
|
||||
Reference in New Issue
Block a user