Set up continuous integration for a Vary project using GitHub Actions.
The validate command bundles checks into profiles:
| Profile | Stages | Typical use |
|---|---|---|
fast | analyze, static, tests | Local iteration |
local | analyze, static, tests | Alias for fast |
ci | analyze, static, tests, mutation | Pull request gate |
nightly | analyze, static, tests, mutation, oracle | Scheduled deep run |
Run a profile:
vary validate src/ --profile ci
| Stage | Cost | What it does |
|---|---|---|
analyze | Cheap | Structural checks (dead code, style, lint rules) |
static | Cheap | Type checking and effect analysis |
tests | Cheap | Runs test blocks and test_*.vary/*_test.vary files |
mutation | Medium | Source-level mutation testing, scales with test count |
oracle | Expensive | VAST corpus verification, generates and verifies broad test scenarios |
Cheap stages finish in seconds for most projects. Mutation testing can take minutes. VAST/oracle verification takes longer and is best reserved for nightly or weekly runs.
Runs on every pull request. Uses the ci profile: static analysis, type checking, tests, and mutation testing.
# .github/workflows/vary-pr.yml
name: Vary PR
on:
pull_request:
branches: [main]
jobs:
verify:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
- name: Install Vary
run: |
curl -fsSL https://github.com/ccollicutt/vary/releases/latest/download/install.sh | sh
echo "$HOME/.vary/bin" >> "$GITHUB_PATH"
- name: Validate (CI profile)
run: vary validate src/ --profile ci
- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: ci-artifacts
path: .vary/runs/
What this covers:
| Stage | What it catches |
|---|---|
analyze | Structural lint checks |
static | Type errors, effect violations, service host authority |
tests | All test blocks execute and pass |
mutation | Mutation score meets configured threshold |
Runs the full verification suite including the VAST oracle stage. Schedule it during off-hours.
# .github/workflows/vary-nightly.yml
name: Vary Nightly
on:
schedule:
- cron: '0 3 * * *' # 3 AM UTC daily
workflow_dispatch: # Allow manual trigger
jobs:
verify:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
- name: Install Vary
run: |
curl -fsSL https://github.com/ccollicutt/vary/releases/latest/download/install.sh | sh
echo "$HOME/.vary/bin" >> "$GITHUB_PATH"
- name: Validate (nightly profile)
run: vary validate src/ --profile nightly
- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: nightly-artifacts
path: .vary/runs/
The oracle stage is the addition over PR CI. VAST corpus verification catches correctness issues that unit tests and mutation testing miss.
vary.tomlDefine project-specific profiles:
[profiles.pr-fast]
checks = ["check", "test"]
timeout = 300
[profiles.pr-fast.thresholds]
mutation_score = 60
[profiles.full]
checks = ["check", "test", "mutation", "oracle"]
timeout = 1800
[profiles.full.thresholds]
mutation_score = 80
Then reference them in CI:
vary validate src/ --profile pr-fast
Config profiles override built-in profiles of the same name, so you can customize ci or nightly for your project.
Minimum verification bar for a production Vary application:
| Area | What to configure |
|---|---|
| Project layout | Follow the canonical structure with pure core separated from effectful boundaries |
vary.toml | Define [profiles.ci] and [profiles.nightly] with appropriate thresholds |
| PR gate | Run vary validate --profile ci and block merge on failure |
| Nightly job | Run vary validate --profile nightly with VAST oracle verification |
| Service host authority | Configure [services] in vary.toml if the app makes HTTP calls |
| Effect deny list | Configure [check.effects] to prevent unintended side effects in pure modules |
| Mutation threshold | At least 60% for CI, 80% for nightly |
| Contract preconditions | in {} blocks on public API functions for input validation |
| Test coverage | Both unit tests (test blocks) and integration tests for service boundaries |
Generate a project with these defaults already configured:
vary new my-app --template serious
This scaffolds a project with vary.toml profiles, a GitHub Actions workflow, and the canonical directory structure.