anvilsign in

collin/anvil

1[workspace]
2resolver = "2"
3members = [
4 "crates/*",
5 "vendor/gitserver-core",
6]
7
8[workspace.package]
9version = "0.0.0"
10edition = "2024"
11license = "MIT OR Apache-2.0"
12repository = "https://github.com/richardscollin/anvil"
13rust-version = "1.98.0"
14
15[workspace.lints.clippy]
16# One version of a crate per tree, or say why not. Duplicates are usually a
17# dependency mid-upgrade (two `digest` generations, two `base64`s) — each one
18# is dead weight in the static musl binary and a type that does not unify
19# across the seam. Unavoidable ones go in `allowed-duplicate-crates` in
20# clippy.toml, with a reason, so the list is the record of what we are waiting
21# on rather than an ambient warning everyone learns to scroll past.
22multiple_crate_versions = "warn"
23
24[workspace.dependencies]
25# Internal crates
26anvil-core = { path = "crates/anvil-core" }
27anvil-ci = { path = "crates/anvil-ci" }
28anvil-docker = { path = "crates/anvil-docker" }
29anvil-job = { path = "crates/anvil-job" }
30anvil-agent = { path = "crates/anvil-agent" }
31anvil-git = { path = "crates/anvil-git" }
32anvil-web = { path = "crates/anvil-web" }
33anvil-ssh = { path = "crates/anvil-ssh" }
34
35# Repo secrets (docs/secrets.md): sealed to users' ssh-ed25519 keys with
36# X25519 + HKDF-SHA256 + AES-256-GCM. AES-GCM rather than ChaCha20-Poly1305
37# because the *browser* is the encryptor and WebCrypto has no ChaCha.
38# Both track whatever russh is on, because cargo unifies each onto a single
39# version tree-wide: these used to be `=`-pinned to pre-releases for that
40# reason, and russh 0.63 moving to the final releases is what let the pins go.
41# Bumping either ahead of russh puts them back. X25519 comes from
42# `MontgomeryPoint::mul_clamped` rather than the x25519-dalek wrapper, which
43# would want its own curve25519-dalek.
44
45# HTTP client for the CD deploy webhook. No TLS feature on purpose: the deploy
46# receiver is host-local plaintext HTTP, and enabling rustls would drag in
47# aws-lc-rs and break the musl cross-compile (see the russh note below).
48# TLS via rustls with the *ring* provider only (`-no-provider` + an explicit
49# rustls/ring dep): aws-lc-rs needs cmake and breaks the zig musl
50# cross-compile, ring does not. anvil-git installs the provider at use time.
51# Used for the CD deploy webhook (anvil-ci) and HTTPS push mirroring
52# (anvil-git).
53# Native (system) roots rather than the bundled webpki set: `anvild secret`
54# talks to whatever anvil you self-host, including one behind a private or
55# local CA — portless's `.localhost` certificates being the everyday case. The
56# deploy image installs ca-certificates, so the server side is unaffected.
57# reqwest 0.13 folded the old `rustls-tls-native-roots-no-provider` into
58# `rustls-no-provider`, which verifies against the platform trust store —
59# same intent, one feature.
60
61# Used directly only for idempotent schema shims on existing databases; the
62# version tracks what toasty-driver-sqlite already pulls in.
63
64# `anvild secret` prompts for an ssh key passphrase / an account password.
65
66# RS256 verification of OIDC id tokens (docs/oidc.md). ring rather than a JWT
67# crate: it is already in the tree under rustls, cross-compiles to static musl
68# (aws-lc-rs, which the maintained JWT crates default to, needs cmake and does
69# not), and one signature check over `header.payload` is all we need.
70
71# `regex-onig` (C Oniguruma regex engine) over the pure-Rust `regex-fancy`:
72# several times faster on large files, and zig's cc cross-compiles the C just
73# fine for the static musl build (verified via deploy/build.sh's toolchain).
74# Spelled out rather than taking the `default-onig` bundle, which also turns on
75# `plist-load` and `yaml-load` — those are for building a SyntaxSet/ThemeSet
76# out of .sublime-syntax / .tmTheme files at runtime, and ui.rs only ever calls
77# `load_defaults_newlines`/`load_defaults`, which read the baked-in bincode
78# dumps (`dump-load`, still on). Dropping them takes plist, quick-xml,
79# yaml-rust and linked-hash-map out of the tree.
80
81# ssh — use the `ring` crypto backend instead of the default `aws-lc-rs`:
82# ring is far cheaper to compile (no cmake/perl) and cross-compiles cleanly
83# (zigbuild/musl), which matters for building images for the low-RAM VPS.
84
85# ssh-key parsing/fingerprinting, shared by anvil-core (storage) and anvil-ssh
86# (auth). Pinned to match russh's transitive ssh-key so fingerprints agree.
87
88# The features we actually use, rather than `full`. Nothing here spawns a
89# child process or installs a signal handler — the design rule is that the
90# product never shells out, and the `Command::new("git")` calls in the tree are
91# all test fixtures using `std::process` — so `process` and `signal` were
92# paying for `signal-hook-registry` and `errno` and a chunk of tokio's own
93# compile for nothing. Add a feature back the moment something needs it.
94
95# Both configuration languages anvil reads: the operator's `anvil.toml` and the
96# repository's `.anvil/ci.toml`. Pipelines used to be YAML, which meant a
97# serde_yaml — the archived dtolnay one, unmaintained since 2024 — in the tree
98# to parse one file per CI run. Making them TOML retired that parser and left
99# users one syntax to learn instead of two.
100
101aes-gcm = { version = "0.11.1" }
102anyhow = { version = "1.0.104" }
103argon2 = { version = "0.6.0-rc.8", features = ["rand_core"] }
104async-trait = { version = "0.1.92" }
105axum = { version = "0.8.9", features = ["ws"] }
106axum-extra = { version = "0.12.6", features = ["cookie"] }
107base64 = { version = "0.22.1" }
108bollard = { version = "0.21.1" }
109clap = { version = "4.6.6", features = ["derive"] }
110curve25519-dalek = { version = "5.0.0" }
111flate2 = { version = "1.1.9" }
112futures-util = { version = "0.3.34" }
113gitserver-core = { path = "vendor/gitserver-core" }
114gix = { version = "0.87.1", default-features = false, features = ["sha1", "max-performance-safe", "revision"] }
115gix-pack = { version = "0.74.2", features = ["sha1"] }
116hmac = { version = "0.13.0" }
117lru = { version = "0.18.2" }
118maud = { version = "0.27.0", features = ["axum"] }
119pulldown-cmark = { version = "0.13.4", default-features = false, features = ["html"] }
120rand = { version = "0.10.2" }
121reqwest = { version = "0.13.4", default-features = false, features = ["form", "json", "rustls-no-provider"] }
122ring = { version = "0.17.14" }
123rpassword = { version = "7.5.4" }
124rusqlite = { version = "0.40.2" }
125russh = { version = "0.63.1", default-features = false, features = ["flate2", "ring", "rsa"] }
126rustls = { version = "0.23.43", default-features = false, features = ["ring", "logging", "std", "tls12"] }
127serde = { version = "1.0.229", features = ["derive"] }
128serde_json = { version = "1.0.151" }
129sha2 = { version = "0.11.0" }
130similar = { version = "3.2.0" }
131ssh-key = { version = "0.7.0-rc.11" }
132syntect = { version = "5.3.0", default-features = false, features = ["default-syntaxes", "default-themes", "html", "regex-onig"] }
133tar = { version = "0.4.46" }
134thiserror = { version = "2.0.20" }
135time = { version = "0.3.55", features = ["serde", "formatting"] }
136toasty = { version = "0.10.0", features = ["sqlite"] }
137tokio = { version = "1.53.1", features = ["fs", "io-util", "macros", "net", "rt-multi-thread", "sync", "time"] }
138tokio-util = { version = "0.7.19", features = ["io"] }
139toml = { version = "1.1.4" }
140tower = { version = "0.5.3" }
141tracing = { version = "0.1.44" }
142tracing-subscriber = { version = "0.3.23", features = ["env-filter"] }