This document describes the CI/CD pipeline and code quality tools used in the vtcode project.
The project uses several GitHub Actions workflows to ensure code quality and automate testing:
Triggers:
- Push to
main(filtered by.rs,.toml,.lock,.yml,.json,.md,scripts/) - Pull requests to
main(same path filters) - Weekly schedule (Monday 5 AM UTC)
- Manual
workflow_dispatch
Jobs:
- Format Check (rustfmt): Ensures code is properly formatted
- Lint Check (clippy): Runs comprehensive linting with
-D warnings - Test: Runs
cargo nextest runon Ubuntu (plus macOS and Windows for PRs) - Benchmarks: Performance regression testing
- Security Audit:
cargo auditfor vulnerable dependencies - Documentation: Builds and tests documentation (
cargo doc)
Triggers:
- Push and PR to
mainon.rs,.toml,.lock,scripts/,.github/workflows/
Jobs:
- Tool Evaluation: Validates built-in tool behavior and safety gateways
- Integration tests: End-to-end tool execution checks
Triggers:
- Manual
workflow_dispatchwith release tag input - Called from
release.ymlon publish
Jobs:
- Build Linux: Compiles
x86_64-unknown-linux-gnu,x86_64-unknown-linux-musl, andaarch64-unknown-linux-gnubinaries - Build Windows: Compiles
x86_64-pc-windows-msvcbinary - Upload Artifacts: Stores compiled binaries + extension-stripped
.sha256sidecars for release
Required release target matrix (enforced by scripts/release.sh):
| Target | Built by | Archive |
|---|---|---|
x86_64-apple-darwin |
local (release.sh) |
.tar.gz |
aarch64-apple-darwin |
local (release.sh) |
.tar.gz |
x86_64-unknown-linux-gnu |
build-linux-windows.yml |
.tar.gz |
x86_64-unknown-linux-musl |
build-linux-windows.yml |
.tar.gz |
aarch64-unknown-linux-gnu |
build-linux-windows.yml |
.tar.gz |
x86_64-pc-windows-msvc |
build-linux-windows.yml |
.zip (required by default) |
release.sh derives a raw compat-vtcode-<v>-<target>.tar.gz.compat executable from
each normal archive. These are the legacy updater compatibility bridge for
v0.141.0-v0.141.4 (see Update System Guide). The
compat- prefix is load-bearing: GitHub returns release assets sorted alphabetically
by name, and the prefix makes the compat asset sort before vtcode-<v>-<target>.tar.gz
so the broken legacy updater picks the raw binary instead of the gzip archive it
cannot extract. The release fails if any required target archive (including
Windows by default) is missing. Set RELEASE_REQUIRE_WINDOWS=false only for an
emergency macOS/Linux rescue when Windows CI is flaky.
Binary size & cold-start optimization:
All release profiles inherit [profile.release] which uses opt-level = "z" (size
optimization) + full LTO + codegen-units = 1. Binary size directly impacts cold-start
time — dyld page-faults loading the Mach-O dominate the first-launch latency.
| Build path | Profile | Extra size flags |
|---|---|---|
macOS local (release.sh) |
release |
-Wl,-dead_strip via CARGO_TARGET_*_RUSTFLAGS |
| Linux CI | release-fast (thin LTO, 4 codegen units) |
-Wl,--gc-sections via RUSTFLAGS |
| Windows CI | release-fast-windows (no LTO, 16 codegen units) |
MSVC /OPT:REF (default) |
release.sh also runs a cold-start spot check (fresh /tmp copy → --version timing)
after the macOS aarch64 build to catch sub-1s regressions before shipping. All build
commands use --locked to ensure the Cargo.lock matches Cargo.toml so the size-optimized
profiles are actually applied.
Triggers:
- Push and PR to
mainon.rs,Cargo.toml,Cargo.lock,coverage.yml
Jobs:
- Code Coverage:
cargo tarpaulinwith XML output - Coverage Report: Uploads to code coverage service
Triggers:
- Manual
workflow_dispatchwith version tag
Jobs:
- Build Binaries: Triggers
build-linux-windows.yml - Create Release: Drafts GitHub Release with changelog
- Publish: Publishes to crates.io and Homebrew
Installation:
rustup component add rustfmtUsage:
# Check formatting
cargo fmt --all -- --check
# Auto-format code
cargo fmt --all
# Print current configuration
cargo fmt --print-config default rustfmt.tomlConfiguration:
Create a rustfmt.toml or .rustfmt.toml file in your project root:
edition = "2021"
max_width = 100
tab_spaces = 4Installation:
rustup component add clippyUsage:
# Run clippy with warnings as errors
cargo clippy -- -D warnings
# Run on specific target
cargo clippy --lib
# Fix clippy suggestions automatically
cargo clippy --fixCommon clippy lints:
clippy::all: Enable all lintsclippy::pedantic: More strict lintsclippy::nursery: Experimental lintsclippy::cargo: Cargo.toml specific lints
The lint migration keeps the actionable marker scan separate from generated or fixture content. Run it from the repository root:
./scripts/first-party-debt-scan.shThe scanner covers first-party src/, crates/, and scripts/ content while
excluding vendored, generated, fixture, template, sample, and task-panel
content. New TODO:, FIXME:, HACK:, or XXX: markers fail the check.
The workspace lint gate also enforces the previously suppressed result, indexing, string-slice, cast, and allow-without-reason lint families:
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo nextest run --locked --workspaceUse the provided development check script to run the same checks locally:
# Run all checks
./scripts/check.sh
# Run specific checks
./scripts/check.sh fmt # Format check
./scripts/check.sh clippy # Clippy check
./scripts/check.sh test # Run tests
./scripts/check.sh build # Build project
./scripts/check.sh docs # Generate docsTo set up the development environment manually:
# Install required components
rustup component add rustfmt clippy
# Install additional tools
cargo install cargo-audit # Security auditing
cargo install cargo-outdated # Dependency checking
cargo install cargo-udeps # Unused dependencies
cargo install cargo-msrv # MSRV checking
cargo install cargo-license # License checking
cargo install cargo-tarpaulin # Code coverageSet up pre-commit hooks to run checks before committing:
# Install pre-commit (if using)
pre-commit install
# Or create .git/hooks/pre-commit manually:
#!/bin/bash
./scripts/check.shAdd to .vscode/settings.json:
{
"rust-analyzer.checkOnSave.command": "clippy",
"editor.formatOnSave": true,
"rust-analyzer.rustfmt.enableRangeFormatting": true
}autocmd BufWritePre *.rs :silent! !cargo fmt -- %:pMost Rust IDEs support rustfmt and clippy:
- IntelliJ/CLion: Built-in Rust plugin
- VS Code: rust-analyzer extension
- Vim: rust.vim plugin
- Emacs: rustic-mode
Configure branch protection rules in GitHub:
- Go to repository Settings → Branches
- Add rule for
main/masterbranch - Require status checks to pass:
fmtclippytestsecurity-audit
Add these badges to your README:
[](https://github.com/yourusername/vtcode/actions/workflows/ci.yml)
[](https://github.com/yourusername/vtcode/actions/workflows/code-quality.yml)rustup component add rustfmt
rustup updatecargo clippy -- -W clippy::allcargo msrv --workspace
cargo msrv --workspace set 1.93.0 # Set specific versioncargo update
cargo outdated
cargo udeps# In workflow
- uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]# Install cargo-audit
cargo install cargo-audit
# Run audit
cargo audit
# Fix vulnerabilities
cargo audit fix# Check licenses (quick overview)
cargo install cargo-license
cargo license --workspace
# Regenerate THIRD-PARTY-NOTICES from Cargo.lock (full automation)
cargo install --locked --features cli cargo-about
scripts/generate-notices.sh # regenerate the file
scripts/generate-notices.sh --check # CI mode: exit 1 if out of dateThe license-notices CI job runs scripts/generate-notices.sh --check on
every PR to catch stale license notices before merge. The file has a manual
header (scripts/templates/third-party-header.txt for in-tree source ports)
and an auto-generated dependency listing (scripts/templates/third-party-notices.hbs
via cargo-about).