Take a local project to a CI artifact¶
This tutorial prepares a working Incan project for reproducible artifact delivery. The local gate is executable with the prepared 0.5 release envelope; the hosted runner stops at source verification until public 0.5 packaging installs that same envelope.
- LockFreeze dependency resolution
- GateMatch the local CI commands
- ReportDiscover the artifact
- HandoffSeparate shipped CI from packaging preview
Step 1: create the lock authority¶
From the project root, resolve dependencies and commit the result with the manifest:
incan lock
git add incan.toml incan.lock
incan.lock is the reproducibility authority for --locked commands. Regenerate it intentionally after dependency changes; do not let CI silently resolve a different graph.
Step 2: run the local gate¶
Run the same checks CI will enforce:
incan fmt --check .
incan test --locked
mkdir -p target
incan build src/main.incn --locked --report json --report-output target/build-report.json
Use --frozen only when the runner already has every required dependency cached. --locked prevents resolution drift while still allowing a clean runner to fetch the committed dependency graph.
Step 3: read the compiler-owned artifact path¶
The build report records emitted artifacts as structured rows. Select the existing binary instead of assuming a generated Cargo directory:
jq -r '.artifacts[] | select(.kind == "binary" and .exists == true) | .path' \
target/build-report.json
The report schema is the tooling contract. Generated Rust paths remain inspectable implementation output rather than a stable ABI.
Step 4: add the hosted source-check lane¶
The repository composite action currently installs a compiler binary from the selected Incan source ref. It does not install the prepared 0.5 release Loaf envelope used by the local gate above. Keep the hosted lane within that smaller contract instead of publishing a workflow that is expected to fail at native execution.
Create .github/workflows/incan.yml and pin the action to the accepted Incan commit SHA:
name: Incan
on:
push:
branches: [main]
pull_request:
env:
INCAN_NO_BANNER: 1
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Install Incan
uses: encero-systems/incan/.github/actions/install-incan@<accepted-commit-sha>
- name: Verify source contracts
run: |
incan --version
incan fmt --check .
incan check src/main.incn --format json
Do not replace the placeholder with @main: a moving compiler ref is not a reproducible delivery authority. When public 0.5 packaging installs the finite release envelope, extend this lane with the same locked test/build/report commands already verified locally and retain the report-selected artifact. Until then, the local build report proves the artifact path while hosted CI proves source and formatting contracts.
You now have a release-envelope executable local gate, a compiler-owned artifact path, and a hosted lane that stays within the installer contract actually available today. The missing hosted envelope is visible instead of hidden behind a workflow that cannot succeed.