Skip to content

Commit c4bbb8a

Browse files
authored
ci: parallelize and strengthen package validation (#721)
#### Overview Improve CI throughput and artifact confidence by parallelizing independent work, unifying matrices, and adding musl and downstream package validation. - [x] I confirm this contribution is my own work, or I have the right to submit it under this project's license. - [x] I searched existing issues and open pull requests, and this does not duplicate existing work. #### Details - Run language workflows, checks, license validation, packaging, and tests in parallel where dependencies allow. - Enable fail-fast consistently and consolidate repeated platform matrices and installer checks. - Scope caches by platform target, including distinct glibc and musl cache keys. - Test Rust core, Python, and Node on musl for amd64 and ARM64. - Run musl Rust tests through the same `just --set ci true test-rust` path as native platforms, including locked nextest execution and JUnit output. - Install the centrally pinned `uv`, `just`, and `cargo-nextest` versions inside the musllinux runtime; retain the existing musl coverage exclusion. - Make the shared `just` helpers honor an explicit `UV_PYTHON` interpreter so PyO3 uses Alpine's shared Python instead of another interpreter bundled in the musllinux image. - Add downstream smoke validation for Python wheels/source packages and Rust CLI artifacts. - Use `npm ci` and Cargo/Maturin locked dependency resolution in musl validation paths. - Infer musl behavior from the platform name instead of maintaining a separate matrix boolean. Validation: - `uv run pre-commit run --all-files` - Targeted GitHub Actions/actionlint and workflow matrix contract checks - YAML parsing, `just` recipe dry-run, and `git diff --check` - Verified pinned `uv`, `just`, and `cargo-nextest` downloads for x86_64 and ARM64 musl - Verified a missing explicit `UV_PYTHON` fails immediately and a valid explicit interpreter completes `just build-rust` - Exercised the shared locked nextest path locally: 3,842 tests passed; eight FFI tests observed a personal ancestor `.nemo-relay/plugins.toml` and failed their clean-environment assertions - Maturin locked-option checks, Node script syntax validation, and locked Cargo metadata validation Docker is unavailable locally, so the complete musllinux container paths will run in GitHub Actions. #### Where should the reviewer start? Start with `.github/workflows/ci.yaml` for the top-level dependency graph, then review `.github/workflows/ci_rust.yml` and the shared Python resolver in `justfile` for the unified native/musl Rust test entrypoint. #### Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to) - Relates to: none ## Summary by CodeRabbit - **New Features** - Added automated validation for Linux, macOS, Windows, and musllinux package builds. - Added smoke tests for native packages, musllinux wheels, source distributions, plugin SDK wheels, and compiled artifacts. - Added checks confirming packaged CLI versions match expected releases. - **Bug Fixes** - Improved cross-platform installer and package testing, including Windows PowerShell validation. - Strengthened failure handling so test failures are detected promptly. - **Chores** - Improved package reproducibility by honoring locked dependencies during builds. - Improved Python interpreter selection through optional environment configuration. Authors: - Will Killian (https://github.com/willkill07) Approvers: - Eric Evans II (https://github.com/ericevans-nv) URL: #721
1 parent 9a3443d commit c4bbb8a

9 files changed

Lines changed: 563 additions & 433 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,11 @@ jobs:
125125

126126
ci_license_diff:
127127
name: License Diff
128-
needs: [prepare, ci_changes, ci_check]
128+
needs: [prepare, ci_changes]
129129
uses: ./.github/workflows/ci_license_diff.yml
130130
if: >-
131131
${{
132132
needs.prepare.outputs.is_pr == 'true'
133-
&& needs.ci_check.result == 'success'
134133
&& needs.ci_changes.outputs.run_dependencies == 'true'
135134
}}
136135
permissions:
@@ -142,9 +141,9 @@ jobs:
142141

143142
ci_rust:
144143
name: Rust
145-
needs: [prepare, ci_changes, ci_check]
144+
needs: [prepare, ci_changes]
146145
uses: ./.github/workflows/ci_rust.yml
147-
if: ${{ needs.ci_check.result == 'success' && needs.ci_changes.outputs.run_rust == 'true' }}
146+
if: ${{ needs.ci_changes.outputs.run_rust == 'true' }}
148147
permissions:
149148
contents: read
150149
secrets:
@@ -154,19 +153,19 @@ jobs:
154153

155154
ci_go:
156155
name: Go
157-
needs: [prepare, ci_changes, ci_check]
156+
needs: [prepare, ci_changes]
158157
uses: ./.github/workflows/ci_go.yml
159-
if: ${{ needs.ci_check.result == 'success' && needs.ci_changes.outputs.run_go == 'true' }}
158+
if: ${{ needs.ci_changes.outputs.run_go == 'true' }}
160159
permissions:
161160
contents: read
162161
secrets:
163162
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
164163

165164
ci_node:
166165
name: Node.js
167-
needs: [prepare, ci_changes, ci_check]
166+
needs: [prepare, ci_changes]
168167
uses: ./.github/workflows/ci_node.yml
169-
if: ${{ needs.ci_check.result == 'success' && needs.ci_changes.outputs.run_node == 'true' }}
168+
if: ${{ needs.ci_changes.outputs.run_node == 'true' }}
170169
permissions:
171170
contents: read
172171
secrets:
@@ -179,17 +178,17 @@ jobs:
179178

180179
ci_python:
181180
name: Python
182-
needs: [prepare, ci_changes, ci_check]
181+
needs: [prepare, ci_changes]
183182
uses: ./.github/workflows/ci_python.yml
184-
if: ${{ needs.ci_check.result == 'success' && ( needs.ci_changes.outputs.run_python == 'true' || needs.ci_changes.outputs.run_python_integration_langchain == 'true' ) }}
183+
if: ${{ needs.ci_changes.outputs.run_python == 'true' || needs.ci_changes.outputs.run_python_integration_langchain == 'true' }}
185184
permissions:
186185
contents: read
187186
secrets:
188187
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
189188
with:
190189
ref_type: ${{ github.ref_type }}
191190
ref_name: ${{ github.ref_name }}
192-
run_package: ${{ ( needs.ci_changes.outputs.run_python == 'true' || needs.ci_changes.outputs.run_python_integration_langchain == 'true' ) }}
191+
run_package: ${{ needs.ci_changes.outputs.run_python_package == 'true' }}
193192
run_integration_langchain: ${{ needs.ci_changes.outputs.run_python_integration_langchain == 'true' }}
194193

195194
ci_required:

.github/workflows/ci_check.yml

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,27 @@ jobs:
4444
runs-on: ${{ matrix.runner }}
4545
timeout-minutes: 10
4646
strategy:
47-
fail-fast: false
47+
fail-fast: true
4848
matrix:
4949
include:
5050
- platform: linux-x86_64
5151
runner: ubuntu-latest
52+
shell: sh
5253
run_mock_tests: true
5354
- platform: linux-arm64
5455
runner: ubuntu-24.04-arm
56+
shell: sh
5557
run_mock_tests: false
5658
- platform: macos-arm64
5759
runner: macos-15
60+
shell: sh
5861
run_mock_tests: false
62+
- platform: windows-x86_64
63+
runner: windows-2022
64+
shell: pwsh
65+
- platform: windows-ARM64
66+
runner: windows-11-arm
67+
shell: pwsh
5968
permissions:
6069
contents: read
6170

@@ -66,41 +75,22 @@ jobs:
6675
persist-credentials: false
6776

6877
- name: Validate installer
78+
if: ${{ matrix.shell == 'sh' }}
6979
run: |
7080
sh -n install.sh
7181
sh -n scripts/test-install.sh
7282
sh -n scripts/test-install-mocks.sh
7383
7484
- name: Run live installer tests
85+
if: ${{ matrix.shell == 'sh' }}
7586
run: sh scripts/test-install.sh
7687

7788
- name: Run mock-only installer tests
78-
if: ${{ matrix.run_mock_tests }}
89+
if: ${{ matrix.shell == 'sh' && matrix.run_mock_tests }}
7990
run: sh scripts/test-install-mocks.sh
8091

81-
install-script-windows:
82-
name: Install script (Windows ${{ matrix.architecture }})
83-
if: ${{ inputs.run_installer }}
84-
runs-on: ${{ matrix.runner }}
85-
timeout-minutes: 10
86-
strategy:
87-
fail-fast: false
88-
matrix:
89-
include:
90-
- architecture: x86_64
91-
runner: windows-2022
92-
- architecture: ARM64
93-
runner: windows-11-arm
94-
permissions:
95-
contents: read
96-
97-
steps:
98-
- name: Checkout
99-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
100-
with:
101-
persist-credentials: false
102-
10392
- name: Validate PowerShell installer syntax
93+
if: ${{ matrix.shell == 'pwsh' }}
10494
shell: pwsh
10595
run: |
10696
$scripts = @('install.ps1', 'scripts/test-install.ps1')
@@ -116,6 +106,7 @@ jobs:
116106
}
117107
118108
- name: Run PowerShell installer tests
109+
if: ${{ matrix.shell == 'pwsh' }}
119110
shell: pwsh
120111
run: ./scripts/test-install.ps1
121112

@@ -164,7 +155,7 @@ jobs:
164155

165156
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
166157
with:
167-
shared-key: nemo-relay-rust-${{ runner.os }}-${{ runner.arch }}-${{ steps.ci-config.outputs.rust_version }}
158+
shared-key: nemo-relay-rust-linux-amd64-${{ steps.ci-config.outputs.rust_version }}
168159
workspaces: . -> target
169160
cache-all-crates: true
170161
cache-bin: false

.github/workflows/ci_go.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,10 @@ jobs:
2525
name: Test (${{ matrix.platform }})
2626
runs-on: ${{ matrix.runner }}
2727
timeout-minutes: 30
28-
continue-on-error: ${{ startsWith(matrix.platform, 'windows') }}
2928
permissions:
3029
contents: read
3130
strategy:
32-
fail-fast: false
31+
fail-fast: true
3332
matrix:
3433
include:
3534
- platform: linux-amd64
@@ -62,7 +61,7 @@ jobs:
6261

6362
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
6463
with:
65-
shared-key: nemo-relay-rust-${{ runner.os }}-${{ runner.arch }}-${{ steps.ci-config.outputs.rust_version }}
64+
shared-key: nemo-relay-rust-${{ matrix.platform }}-${{ steps.ci-config.outputs.rust_version }}
6665
workspaces: . -> target
6766
cache-all-crates: true
6867
cache-bin: false

0 commit comments

Comments
 (0)