Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
48 changes: 48 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
# Jobs:
# e2e-opsm — offline E2E suite (runs on every push/PR)
# runtime-api — runtime version API integration tests (external_api tag, no downloads)
# live-download — full runtime install pipeline, incl. nickel plugin
# evaluation (workflow_dispatch only, see below)
#
# :live_download tests (full tool installs ~10-50MB) are workflow_dispatch only
# to avoid burning bandwidth on every commit; run manually when validating
Expand Down Expand Up @@ -88,3 +90,49 @@ jobs:
--include external_api \
--exclude live_download \
--trace
live-download:
name: Runtime — live install (workflow_dispatch only)
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install Rust toolchain (to build nickel)
uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
with:
toolchain: '1.97.0'
- name: Cache cargo-installed tools
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2
with:
key: nickel-lang-cli-1.16.0
- name: Install nickel
# Pinned to opsm.toml [runtime] — see docs/TOOLCHAIN.adoc. Manager.install
# (opsm_ex/lib/opsm/runtime/manager.ex) shells out to the `nickel` binary
# to evaluate runtime/core/*.ncl plugin definitions; without it every
# install fails with {:error, {:nickel_not_installed, tool}}.
run: cargo install nickel-lang-cli --version 1.16.0 --locked
- name: Setup Erlang/Elixir
uses: erlef/setup-beam@54075bcc5e249e4758d363f27d099f55d843f124 # v1.24.1
with:
# Versions derive from opsm.toml [runtime] via .tool-versions
# (generated by `just toolchain-sync` — see docs/TOOLCHAIN.adoc)
version-file: '.tool-versions'
version-type: 'strict'
- name: Restore Mix cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v4
with:
path: |
opsm_ex/deps
opsm_ex/_build
key: ${{ runner.os }}-mix-${{ hashFiles('opsm_ex/mix.lock') }}
- name: Install dependencies
run: cd opsm_ex && mix deps.get
- name: Compile
run: cd opsm_ex && mix compile --warnings-as-errors
- name: Run live-download runtime install tests (full zig install via Manager.install)
run: |
cd opsm_ex && mix test test/opsm/runtime/integration_test.exs \
--include external_api \
--include live_download \
--trace
151 changes: 130 additions & 21 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@
# opsm.toml [runtime] — drift is gated by `just toolchain-check`.
# Scanner images (trivy/semgrep/trufflehog) deliberately float: their
# detection databases need to stay fresh, so pinning them is worse.
#
# There is no root mix.exs or Cargo.toml — mix.exs lives in opsm_ex/, and
# the estate's Rust code is nine independent first-party crates (the
# ratatui TUI, two Elixir NIFs, and six microservices under services/).
# `exists: mix.exs` / `exists: Cargo.toml` at repo root never matched
# either, so every mix-*/cargo-* job below was permanently dormant.
# mix-* jobs now target opsm_ex/ directly; cargo-* jobs loop over
# $RUST_CRATE_DIRS. Keep that variable and each job's `rules: exists:`
# list in sync when a crate is added or removed — `rules: exists:` needs
# literal paths, it does not expand CI variables.

stages:
- security
Expand All @@ -14,11 +24,25 @@ stages:
- build
variables:
CARGO_HOME: ${CI_PROJECT_DIR}/.cargo
# First-party Rust crates only — opsm_ex/deps/** is vendored (Mix deps
# cache), never linted/audited/built as our own code.
RUST_CRATE_DIRS: >-
opsm-ui/tui
opsm_ex/native/opsm_pq_nif
opsm_ex/native/quic_transport
services/checky-monkey
services/oikos
services/palimpsest-license
services/selur
services/svalinn
services/vordr
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- .cargo/
- target/
- "*/target/"
- "*/*/target/"
- "*/*/*/target/"
# ==================
# Security Scanning
# ==================
Expand All @@ -39,32 +63,57 @@ cargo-audit:
stage: security
image: rust:1.97
script:
- cargo install cargo-audit
- cargo audit
- cargo install cargo-audit --locked
- |
for dir in $RUST_CRATE_DIRS; do
echo "== cargo audit: $dir =="
(cd "$dir" && cargo audit)
done
rules:
- exists:
- Cargo.toml
- opsm-ui/tui/Cargo.toml
- opsm_ex/native/opsm_pq_nif/Cargo.toml
- opsm_ex/native/quic_transport/Cargo.toml
- services/checky-monkey/Cargo.toml
- services/oikos/Cargo.toml
- services/palimpsest-license/Cargo.toml
- services/selur/Cargo.toml
- services/svalinn/Cargo.toml
- services/vordr/Cargo.toml
cargo-deny:
stage: security
image: rust:1.97
script:
- cargo install cargo-deny
- cargo deny check
- cargo install cargo-deny --locked
- |
for dir in $RUST_CRATE_DIRS; do
echo "== cargo deny: $dir =="
(cd "$dir" && cargo deny check)
done
rules:
- exists:
- Cargo.toml
- opsm-ui/tui/Cargo.toml
- opsm_ex/native/opsm_pq_nif/Cargo.toml
- opsm_ex/native/quic_transport/Cargo.toml
- services/checky-monkey/Cargo.toml
- services/oikos/Cargo.toml
- services/palimpsest-license/Cargo.toml
- services/selur/Cargo.toml
- services/svalinn/Cargo.toml
- services/vordr/Cargo.toml
allow_failure: true
mix-audit:
stage: security
image: elixir:1.19.5-otp-28
script:
- cd opsm_ex
- mix local.hex --force
- mix archive.install hex mix_audit --force
- mix deps.get
- mix deps.audit
rules:
- exists:
- mix.exs
- opsm_ex/mix.exs
allow_failure: true
# ==================
# Linting
Expand All @@ -74,38 +123,64 @@ rustfmt:
image: rust:1.97
script:
- rustup component add rustfmt
- cargo fmt -- --check
- |
for dir in $RUST_CRATE_DIRS; do
echo "== cargo fmt --check: $dir =="
(cd "$dir" && cargo fmt -- --check)
done
rules:
- exists:
- Cargo.toml
- opsm-ui/tui/Cargo.toml
- opsm_ex/native/opsm_pq_nif/Cargo.toml
- opsm_ex/native/quic_transport/Cargo.toml
- services/checky-monkey/Cargo.toml
- services/oikos/Cargo.toml
- services/palimpsest-license/Cargo.toml
- services/selur/Cargo.toml
- services/svalinn/Cargo.toml
- services/vordr/Cargo.toml
clippy:
stage: lint
image: rust:1.97
script:
- rustup component add clippy
- cargo clippy -- -D warnings
- |
for dir in $RUST_CRATE_DIRS; do
echo "== cargo clippy: $dir =="
(cd "$dir" && cargo clippy -- -D warnings)
done
rules:
- exists:
- Cargo.toml
- opsm-ui/tui/Cargo.toml
- opsm_ex/native/opsm_pq_nif/Cargo.toml
- opsm_ex/native/quic_transport/Cargo.toml
- services/checky-monkey/Cargo.toml
- services/oikos/Cargo.toml
- services/palimpsest-license/Cargo.toml
- services/selur/Cargo.toml
- services/svalinn/Cargo.toml
- services/vordr/Cargo.toml
allow_failure: true
mix-format:
stage: lint
image: elixir:1.19.5-otp-28
script:
- cd opsm_ex
- mix format --check-formatted
rules:
- exists:
- mix.exs
- opsm_ex/mix.exs
credo:
stage: lint
image: elixir:1.19.5-otp-28
script:
- cd opsm_ex
- mix local.hex --force
- mix deps.get
- mix credo --strict
rules:
- exists:
- mix.exs
- opsm_ex/mix.exs
allow_failure: true
# ==================
# Testing
Expand All @@ -114,45 +189,79 @@ cargo-test:
stage: test
image: rust:1.97
script:
- cargo test --all-features
- |
for dir in $RUST_CRATE_DIRS; do
echo "== cargo test: $dir =="
(cd "$dir" && cargo test --all-features)
done
rules:
- exists:
- Cargo.toml
- opsm-ui/tui/Cargo.toml
- opsm_ex/native/opsm_pq_nif/Cargo.toml
- opsm_ex/native/quic_transport/Cargo.toml
- services/checky-monkey/Cargo.toml
- services/oikos/Cargo.toml
- services/palimpsest-license/Cargo.toml
- services/selur/Cargo.toml
- services/svalinn/Cargo.toml
- services/vordr/Cargo.toml
mix-test:
stage: test
image: elixir:1.19.5-otp-28
script:
- cd opsm_ex
- mix local.hex --force
- mix deps.get
- mix test
rules:
- exists:
- mix.exs
- opsm_ex/mix.exs
# ==================
# Build
# ==================
cargo-build:
stage: build
image: rust:1.97
script:
- cargo build --release
- |
for dir in $RUST_CRATE_DIRS; do
echo "== cargo build --release: $dir =="
(cd "$dir" && cargo build --release)
done
artifacts:
paths:
- target/release/
- opsm-ui/tui/target/release/
- opsm_ex/native/opsm_pq_nif/target/release/
- opsm_ex/native/quic_transport/target/release/
- services/checky-monkey/target/release/
- services/oikos/target/release/
- services/palimpsest-license/target/release/
- services/selur/target/release/
- services/svalinn/target/release/
- services/vordr/target/release/
expire_in: 1 week
rules:
- exists:
- Cargo.toml
- opsm-ui/tui/Cargo.toml
- opsm_ex/native/opsm_pq_nif/Cargo.toml
- opsm_ex/native/quic_transport/Cargo.toml
- services/checky-monkey/Cargo.toml
- services/oikos/Cargo.toml
- services/palimpsest-license/Cargo.toml
- services/selur/Cargo.toml
- services/svalinn/Cargo.toml
- services/vordr/Cargo.toml
mix-build:
stage: build
image: elixir:1.19.5-otp-28
script:
- cd opsm_ex
- mix local.hex --force
- mix deps.get
- MIX_ENV=prod mix compile
rules:
- exists:
- mix.exs
- opsm_ex/mix.exs
trufflehog:
stage: security
image: trufflesecurity/trufflehog:latest
Expand Down
Loading
Loading