CI/CD and Release Process
July 3, 2026 · View on GitHub
GitHub Actions workflows
Two workflows live in .github/workflows/.
ci.yml — build, lint, test, container E2E
| Job | Command | Gates on |
|---|---|---|
| Check | cd src && cargo check --workspace | compile errors |
| Format | cd src && cargo fmt --all -- --check | rustfmt drift (fails on any diff) |
| Clippy | cd src && cargo clippy --workspace | errors only — style warnings are shown but do not fail CI (see the note in the job) |
| Test | cd src && cargo test --workspace | any failing test |
| Docker Build | builds Dockerfile.builder → extracts binaries → builds Dockerfile.core + per-NF Dockerfile.nf | image build failures (needs the sibling nextgsim checkout) |
| Docker E2E | brings up the 5GC stack (mongodb, nrf, ausf/udm/udr/pcf/nssf/bsf, amf/smf/upf) and health-checks NRF/AMF | startup / health failures |
| Docker E2E (EPC) | brings up the 4G EPC stack from docker-compose-epc.yml and inspects hss/pcrf/sgwc/sgwu/mme | startup / health failures |
Docker jobs are opt-in.
docker-build(and the dependentdocker-e2e/docker-e2e-epc) run only on manualworkflow_dispatch(Actions tab → Run workflow), not on push/PR — they recompile both workspaces in a container and need a cross-repo checkout, so they are too heavy/fragile for every commit. The fast gate (Check/Format/Clippy/Test) protects every push/PR.
Test/Clippy depend on Check; the two Docker E2E jobs depend on Docker Build.
The Test job runs cargo test --workspace at the runner's default parallelism. Tests
that touch process-global NF state (a <nf>_context_init or std::env::set_var) must serialize
on their crate's test_support::CONTEXT_GUARD, or they race and flake here — see
docker/rust/CI.md and the per-crate test guards.
The richer matched-sim data-plane E2E (registration + PDU session + GTP-U ping) is not run by
ci.yml; it is the one-command docker/rust/e2e.sh (documented in docker/rust/CI.md).
pages.yml — documentation site
Deploys docs/ to GitHub Pages (runs docs/scripts/update-api-docs.sh, uploads docs/).
Triggered only when a GitHub release is published (on: release: [published]) so the site
tracks the last release, plus workflow_dispatch for a manual re-deploy — it does not redeploy
on every docs/** push.
Branch triggers
Both workflows run on the default release branch main and on the development branch
initial_commit:
on:
push: { branches: [initial_commit, main] }
pull_request: { branches: [initial_commit, main] }
(ci.yml on push + PR to either branch. pages.yml is not branch-triggered — it deploys the
docs site when a release is published; see below.)
Local pre-push gate (mirror of CI)
Run from src/ in both repos before pushing:
cargo fmt --all -- --check # Format
cargo check --workspace # Check
cargo clippy --workspace # Clippy (errors only)
cargo test --workspace # Test
Optionally the full data-plane E2E: cd docker/rust && ./e2e.sh.
Cutting a release
- Ensure
main(or the release branch) is green in CI and the matched-sim E2E passes (docker/rust/e2e.sh→ 84/84). - Bump the workspace version in
src/Cargo.toml([workspace.package] version) if used, and per-crate versions as needed. Current:0.1.0. - Move the
## [Unreleased]section ofCHANGELOG.mdunder a dated## [X.Y.Z]heading; add a fresh emptyUnreleased. - Commit (
Signed-off-by: Murat Parlakisik <parlakisik@gmail.com>), tagX.Y.Z, push the tag. - Create the GitHub release from the tag, pasting the CHANGELOG section as the release notes:
gh release create X.Y.Z --repo NextgCoreLab/nextgcore --title "NextGCore X.Y.Z" --notes-file <(...). Publishing the release firespages.yml, which deploys the docs site for this version.
Honesty in release notes: keep the validation caveat — spec-text + golden-vector + strict-peer
- matched-sim E2E, not TTCN-certified or third-party-interop tested. 6G/Rel-20 items are research prototypes (no frozen stage-3 spec).