Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
239f031
Test/CI - TEST - Streamline the full test battery and cache package i…
matt-pharr Oct 26, 2026
65939a4
KineticForces/CI - BUGFIX - Close periodic torque samples and pin Jul…
matt-pharr Oct 26, 2026
ea32a0c
Repo - MINOR - Merge develop into the test suite overhaul
matt-pharr Oct 26, 2026
0f2c7ba
CI - PERF - Gate test groups on shared precompilation
matt-pharr Oct 26, 2026
7474acd
CI - BUGFIX - Stabilize the compiled package cache fingerprint
matt-pharr Oct 26, 2026
cf1246f
Merge branch 'develop' into test/streamline-suite
matt-pharr Oct 26, 2026
a817894
CI - PERF - Run the test workflow on self-hosted Linux
matt-pharr Oct 26, 2026
c086890
CI - PERF - Cache self-hosted Julia depots on local disk
matt-pharr Oct 26, 2026
f8049ab
CI - BUGFIX - Restore read-only Julia artifacts safely
matt-pharr Oct 26, 2026
b1d1062
CI - MINOR - Restore GitHub-hosted test runners
matt-pharr Oct 26, 2026
685c52c
CI - MINOR - Merge develop and use slim runners for metadata
matt-pharr Oct 26, 2026
0664f93
CI - BUGFIX - Hand compiled test environments through artifacts
matt-pharr Oct 27, 2026
773cb05
Repo - MINOR - Merge develop into the streamlined test suite
matt-pharr Oct 27, 2026
2f9b654
Test - TEST - Expect analytic grid refinement to match the deck
matt-pharr Oct 27, 2026
fa1b61a
Repo - MINOR - Merge current develop and adapt replay checks
matt-pharr Oct 27, 2026
c63aafb
CI - PERF - Prefer warm caches with an artifact fallback
matt-pharr Oct 27, 2026
cd731f5
CI - FEATURE - Validate merge-queue candidates
matt-pharr Oct 27, 2026
49e67d4
Repo - MINOR - Merge develop and register SLAYER transport tests
matt-pharr Oct 27, 2026
4ed1f1f
Merge branch 'develop' into test/streamline-suite
matt-pharr Oct 27, 2026
b544b97
CI - PERF - Measure deferred solver compilation and balance test groups
matt-pharr Oct 28, 2026
24218ff
Repo - MINOR - Merge develop and register new solver and replay tests
matt-pharr Oct 28, 2026
8f57276
CI - PERF - Restore solver workload after warm timing comparison
matt-pharr Oct 28, 2026
9fd6366
Repo - MINOR - Merge develop before final CI review
matt-pharr Oct 28, 2026
7f5f17a
Merge branch 'develop' into test/streamline-suite
matt-pharr Oct 28, 2026
cb5c8fb
Merge branch 'develop' into test/streamline-suite
matt-pharr Oct 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
303 changes: 303 additions & 0 deletions .github/workflows/julia-test-version.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
name: Test one Julia version

on:
workflow_call:
inputs:
version:
required: true
type: string

permissions:
contents: read

jobs:
precompile:
name: Precompile ${{ inputs.version }}
runs-on: ubuntu-latest
timeout-minutes: 30
outputs:
julia-version: ${{ steps.julia.outputs.julia-version }}
depot-key: ${{ steps.cache-keys.outputs.depot }}
gpec-key: ${{ steps.cache-keys.outputs.gpec }}
local-cache: ${{ steps.cache-keys.outputs.local }}
env:
GPEC_LOCAL_CACHE_DIR: ${{ vars.GPEC_LOCAL_CACHE_DIR }}
JULIA_CPU_TARGET: 'generic'
JULIA_NUM_THREADS: '2'
OPENBLAS_NUM_THREADS: '1'
DEPOT_PATHS: |
~/.julia/artifacts
~/.julia/packages
~/.julia/registries
~/.julia/compiled
~/.julia/scratchspaces
~/.julia/logs

steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Fingerprint tracked package inputs
id: inputs
shell: bash
run: |
set -euo pipefail
fingerprint=$(
git ls-files -z -- Project.toml 'ci/manifests/Manifest-v*.toml' src |
sort -z |
while IFS= read -r -d '' file; do
sha256sum "$file" | cut -d ' ' -f 1 | xxd -r -p
done |
sha256sum | cut -d ' ' -f 1
)
echo "gpec=$fingerprint" >> "$GITHUB_OUTPUT"
echo "Tracked package fingerprint: $fingerprint"

- name: Set up Julia
id: julia
uses: julia-actions/setup-julia@v2
with:
version: ${{ inputs.version }}

- name: Select cache keys and storage
id: cache-keys
env:
DEPOT_KEY: julia-depot-v3-generic-aot-ubuntu-latest-${{ runner.arch }}-${{ inputs.version }}-${{ steps.julia.outputs.julia-version }}-${{ hashFiles('Project.toml', 'ci/manifests/Manifest-v*.toml') }}
GPEC_KEY: gpec-images-v5-generic-aot-o2-bounds-yes-${{ runner.os }}-${{ runner.arch }}-${{ steps.julia.outputs.julia-version }}-${{ steps.inputs.outputs.gpec }}
RUNNER_ENVIRONMENT: ${{ runner.environment }}
run: |
echo "depot=$DEPOT_KEY" >> "$GITHUB_OUTPUT"
echo "gpec=$GPEC_KEY" >> "$GITHUB_OUTPUT"
if [ "$RUNNER_ENVIRONMENT" = self-hosted ] && [ -n "$GPEC_LOCAL_CACHE_DIR" ]; then
echo "local=true" >> "$GITHUB_OUTPUT"
else
echo "local=false" >> "$GITHUB_OUTPUT"
fi

- name: Restore the local Julia snapshot
if: steps.cache-keys.outputs.local == 'true'
run: bash ci/local-julia-cache.sh restore "$CACHE_KEY"
env:
CACHE_KEY: ${{ steps.cache-keys.outputs.gpec }}

# The prefix identifies compatible dependencies; a unique write key avoids stale reservations.
- name: Restore the Julia depot
id: depot
if: steps.cache-keys.outputs.local != 'true'
uses: actions/cache/restore@v4
with:
path: ${{ env.DEPOT_PATHS }}
key: ${{ steps.cache-keys.outputs.depot }}-${{ github.run_id }}-${{ github.run_attempt }}
restore-keys: |
${{ steps.cache-keys.outputs.depot }}
julia-depot-v3-generic-aot-ubuntu-latest-${{ runner.arch }}-${{ inputs.version }}-${{ steps.julia.outputs.julia-version }}-
julia-depot-v3-generic-aot-ubuntu-latest-${{ runner.arch }}-${{ inputs.version }}-
julia-depot-v4-generic-jit-ubuntu-latest-${{ runner.arch }}-${{ inputs.version }}-${{ steps.julia.outputs.julia-version }}-

# The dependency cache is immutable and intentionally independent of src/. Layer
# a small source-keyed package cache over it so source changes can refresh GPEC
# without uploading another copy of the entire depot. Test-only PR updates reuse it.
- name: Restore GPEC compilation
id: gpec-cache
if: steps.cache-keys.outputs.local != 'true'
uses: actions/cache/restore@v4
with:
path: ~/.julia/compiled/v*/GeneralizedPerturbedEquilibrium
key: ${{ steps.cache-keys.outputs.gpec }}-${{ github.run_id }}-${{ github.run_attempt }}
restore-keys: ${{ steps.cache-keys.outputs.gpec }}

- name: Pin the CI dependency set
run: |
set -euo pipefail

minor=$(julia -e 'print(VERSION.major, ".", VERSION.minor)')
pinned="ci/manifests/Manifest-v${minor}.toml"

if [ ! -f "$pinned" ]; then
echo "::warning::No pinned dependency set for Julia ${minor}; resolving fresh. Generate one with 'julia +${minor} ci/manifests/update.jl'."
exit 0
fi

cp "$pinned" Manifest.toml
echo "Pinned dependency set: ${pinned}"

recorded=$(cat ci/manifests/project.sha256)
actual=$(shasum -a 256 Project.toml | cut -d ' ' -f 1)
if [ "$recorded" != "$actual" ]; then
echo "::warning::Project.toml has changed since the pinned dependency sets were generated, so ${pinned} may be stale. Regenerate with ci/manifests/update.jl."
fi

- name: Instantiate pinned dependencies
env:
JULIA_PKG_PRECOMPILE_AUTO: '0'
run: julia --project=. -e 'using Pkg; Pkg.instantiate()'

# Coverage instrumentation is off: nothing consumes the .cov files (they are
# gitignored and never uploaded), and instrumenting slows compute-heavy
# numerical code noticeably. Set coverage: true and add a Codecov upload
# step together if coverage reporting is ever wanted.
- name: Check the production precompile workload
run: julia --check-bounds=yes --depwarn=yes --project=. -e 'using Pkg; Pkg.precompile(; strict=true); using GeneralizedPerturbedEquilibrium'

- name: Save GPEC compilation
timeout-minutes: 3
continue-on-error: true
if: success() && steps.cache-keys.outputs.local != 'true' && !startsWith(steps.gpec-cache.outputs.cache-matched-key, steps.cache-keys.outputs.gpec)
uses: actions/cache/save@v4
with:
path: ~/.julia/compiled/v*/GeneralizedPerturbedEquilibrium
key: ${{ steps.gpec-cache.outputs.cache-primary-key }}

# Refresh missing or incompatible dependency snapshots; reuse a matching prefix unchanged.
- name: Prune the depot before caching
if: success() && steps.cache-keys.outputs.local != 'true' && !startsWith(steps.depot.outputs.cache-matched-key, steps.cache-keys.outputs.depot)
run: julia --project=. -e 'using Pkg; Pkg.gc()'

- name: Save the Julia depot
timeout-minutes: 3
continue-on-error: true
if: success() && steps.cache-keys.outputs.local != 'true' && !startsWith(steps.depot.outputs.cache-matched-key, steps.cache-keys.outputs.depot)
uses: actions/cache/save@v4
with:
path: ${{ env.DEPOT_PATHS }}
key: ${{ steps.depot.outputs.cache-primary-key }}

- name: Publish the local Julia snapshot
if: steps.cache-keys.outputs.local == 'true'
run: bash ci/local-julia-cache.sh save "$CACHE_KEY"
env:
CACHE_KEY: ${{ steps.cache-keys.outputs.gpec }}

# Caches are optional acceleration; this artifact is the required job handoff.
- name: Package the compiled test environment
if: steps.cache-keys.outputs.local != 'true'
run: |
set -euo pipefail
handoff="$RUNNER_TEMP/julia-test-environment"
mkdir -p "$handoff"
cp Manifest.toml "$handoff/Manifest.toml"
entries=()
for path in artifacts packages registries compiled scratchspaces logs; do
if [ -d "$HOME/.julia/$path" ]; then
entries+=(".julia/$path")
fi
done
tar -cf - -C "$HOME" "${entries[@]}" | zstd -T2 -3 -f -o "$handoff/depot.tar.zst"

- name: Share the compiled test environment
if: steps.cache-keys.outputs.local != 'true'
uses: actions/upload-artifact@v4
with:
name: julia-test-environment-${{ inputs.version }}
path: ${{ runner.temp }}/julia-test-environment/
compression-level: 0
retention-days: 1
overwrite: true
if-no-files-found: error

- name: Share the resolved dependency set
if: steps.cache-keys.outputs.local != 'true'
uses: actions/upload-artifact@v4
with:
name: julia-test-manifest-${{ inputs.version }}
path: Manifest.toml
retention-days: 1
overwrite: true
if-no-files-found: error

test:
name: ${{ matrix.group }}
needs: precompile
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
group: [core, api, errorfields]
env:
GPEC_LOCAL_CACHE_DIR: ${{ vars.GPEC_LOCAL_CACHE_DIR }}
JULIA_CPU_TARGET: 'generic'
JULIA_NUM_THREADS: '2'
OPENBLAS_NUM_THREADS: '1'
GPEC_TEST_GROUP: ${{ matrix.group }}
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Set up the precompiled Julia version
uses: julia-actions/setup-julia@v2
with:
version: ${{ needs.precompile.outputs.julia-version }}

- name: Try the compatible dependency cache
id: test-depot
if: needs.precompile.outputs.local-cache != 'true'
timeout-minutes: 2
continue-on-error: true
uses: actions/cache/restore@v4
with:
path: |
~/.julia/artifacts
~/.julia/packages
~/.julia/registries
~/.julia/compiled
~/.julia/scratchspaces
~/.julia/logs
key: ${{ needs.precompile.outputs.depot-key }}
restore-keys: ${{ needs.precompile.outputs.depot-key }}

- name: Try the matching GPEC image
id: test-gpec
if: needs.precompile.outputs.local-cache != 'true' && steps.test-depot.outcome == 'success' && steps.test-depot.outputs.cache-matched-key != ''
timeout-minutes: 2
continue-on-error: true
uses: actions/cache/restore@v4
with:
path: ~/.julia/compiled/v*/GeneralizedPerturbedEquilibrium
key: ${{ needs.precompile.outputs.gpec-key }}
restore-keys: ${{ needs.precompile.outputs.gpec-key }}

- name: Select the environment handoff
id: handoff
if: needs.precompile.outputs.local-cache != 'true'
env:
USE_ARTIFACT: ${{ steps.test-depot.outcome != 'success' || steps.test-depot.outputs.cache-matched-key == '' || steps.test-gpec.outcome != 'success' || steps.test-gpec.outputs.cache-matched-key == '' }}
run: echo "artifact=$USE_ARTIFACT" >> "$GITHUB_OUTPUT"

- name: Restore the resolved dependency set
if: needs.precompile.outputs.local-cache != 'true'
uses: actions/download-artifact@v4
with:
name: julia-test-manifest-${{ inputs.version }}

- name: Download the compiled test environment
if: steps.handoff.outputs.artifact == 'true'
uses: actions/download-artifact@v4
with:
name: julia-test-environment-${{ inputs.version }}
path: ${{ runner.temp }}/julia-test-environment/

- name: Restore the compiled test environment
if: steps.handoff.outputs.artifact == 'true'
run: |
set -euo pipefail
handoff="$RUNNER_TEMP/julia-test-environment"
depot=$(mktemp -d "$RUNNER_TEMP/julia-test-depot.XXXXXXXX")
zstd -dc "$handoff/depot.tar.zst" | tar -xf - -C "$depot"
echo "JULIA_DEPOT_PATH=$depot/.julia:" >> "$GITHUB_ENV"
cp "$handoff/Manifest.toml" Manifest.toml

- name: Restore the local precompiled snapshot
if: needs.precompile.outputs.local-cache == 'true'
run: bash ci/local-julia-cache.sh require "$CACHE_KEY"
env:
CACHE_KEY: ${{ needs.precompile.outputs.gpec-key }}

# Level 1 can reuse the higher-optimization production package images.
- name: Run tests
uses: julia-actions/julia-runtest@v1
with:
coverage: false
check_bounds: 'yes'
optimize: '1'
allow_reresolve: false
8 changes: 7 additions & 1 deletion .github/workflows/make_docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:
tags:
- '*'
pull_request:
merge_group:
types: [checks_requested]

concurrency:
# Skip intermediate builds: always.
Expand All @@ -28,6 +30,10 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v6

- name: Disable the solver precompile workload
run: |
printf '[GeneralizedPerturbedEquilibrium]\nprecompile_workload = false\n' > docs/LocalPreferences.toml

- name: Set up Julia
uses: julia-actions/setup-julia@v2
with:
Expand All @@ -39,7 +45,7 @@ jobs:
- name: Prepare docs environment (develop local package, then instantiate)
run: julia --project=docs -e 'using Pkg; Pkg.activate("docs"); Pkg.develop(PackageSpec(path=".")); Pkg.instantiate(update_registry=false)'

- name: Build and deploy documentation
- name: Build documentation
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: julia --project=docs docs/make.jl
4 changes: 2 additions & 2 deletions .github/workflows/pr-conventions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ permissions:
jobs:
validate:
name: Title and release note
runs-on: ubuntu-latest
runs-on: ubuntu-slim
steps:
- uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -102,7 +102,7 @@ jobs:

metadata:
name: Label and metadata
runs-on: ubuntu-latest
runs-on: ubuntu-slim
# Forked PRs get a read-only token, so these steps cannot run there.
if: github.event.pull_request.head.repo.full_name == github.repository
permissions:
Expand Down
Loading
Loading