v0.10.0: TOML config files + adoption polish - #44
Merged
Conversation
Adds `--config <PATH>` to `rusnel server` and `rusnel client` so
non-trivial deployments don't need 200-character ExecStart lines, and
ships the project hygiene + release infrastructure that lets the
project actually be discovered and adopted.
### TOML config support
- `--config <PATH>` on both subcommands. TOML schema mirrors the CLI
flags one-for-one (snake_case) under `[server]` / `[client]`
sections; a single file can hold both.
- Precedence: explicit CLI flag > config file > built-in default.
Detection of "explicit-on-CLI" uses `ArgMatches::value_source`
(same pattern ripgrep / bat use).
- TLS-mode group is atomic: any TLS-mode flag on the CLI causes all
of the file's TLS-mode keys to be ignored, so there's no ambiguity
when overriding e.g. `tls_self_signed = true` with explicit
`--tls-cert/--tls-key`.
- Unknown keys are rejected (`#[serde(deny_unknown_fields)]`) so
typos surface as parse errors instead of silently no-opping.
- Positional `<server>` / `<remote>...` can come from either the
file or the CLI; CLI wins when both are present.
- 6 unit tests for parsing + 6 end-to-end tests that spawn the real
binary and assert the config file actually drives it.
- Annotated example at `examples/rusnel.toml` covering every key.
### Release infrastructure
- `.github/workflows/release.yml` — on `v*` tag push, builds
prebuilt binaries for x86_64/aarch64 Linux (gnu + musl), macOS
(Intel + Apple Silicon), and Windows x86_64, attaches sha256
checksums to a GitHub Release, and pushes a multi-arch
(amd64 + arm64) Docker image to GHCR tagged `:vX.Y.Z`, `:X.Y`,
`:latest`.
- `Dockerfile` (multi-stage, musl builder → distroless runtime;
~10 MB final image, runs as non-root) + `.dockerignore`.
### README + positioning
- New tagline + "Why Rusnel?" comparison table vs chisel / frp /
`ssh -L`.
- Concrete numbers near the top: 779.55 Mbps vs chisel's 377.42
(2.07x), p99 latency 0.463 ms vs 2.005 ms (4.3x better),
pulled from `benchmark/iperf/results/loopback/results.json`.
- 60-second quickstart, expanded Features list surfacing
previously-hidden selling points (`stdio:`, `RUSNEL_EMBED_*`,
`rusnel ctl`, JSON logs, SOCKS5-proxy chaining, Happy Eyeballs).
- New "Configuration file" section documenting the schema + the
TLS-mode override rule.
- Docker install subsection (with the `:8080/udp` reminder
everyone forgets about QUIC).
### Project hygiene
- `ROADMAP.md` extracted from the old `## TODO` README section so
the README stays focused.
- `CONTRIBUTING.md` (CI requirements, version-bump rule,
`clippy::unwrap_used` convention).
- `SECURITY.md` (private disclosure, scope, hardening notes).
- `.github/ISSUE_TEMPLATE/{bug_report,feature_request,config}.yml`
routing security issues to private reporting and questions to
Discussions.
- `.github/PULL_REQUEST_TEMPLATE.md` with the version-bump checklist.
- `docs/launch-post.md` with launch drafts for HN / r/rust /
r/selfhosted / lobste.rs and an awesome-list submission checklist.
Co-authored-by: Cursor <cursoragent@cursor.com>
Per review feedback: - Remove CONTRIBUTING.md, SECURITY.md, and docs/launch-post.md. - Restore the original `## Features` bullet list verbatim instead of the rewritten one. - Drop the README's footer Contributing section that linked to the removed docs. - Update the bug-report issue template to point at GitHub's private vulnerability reporting URL directly instead of the deleted SECURITY.md. Co-authored-by: Cursor <cursoragent@cursor.com>
- Remove `## Why Rusnel?` comparison table and `### Numbers` table.
- Replace the multi-line tagline blockquote and the "punches through
NAT…" paragraph with the original one-line `## Description`.
- Shorten `Quickstart` heading (drop the "60 seconds" suffix) and
remove the trailing pitch sentence.
- Delete `.github/ISSUE_TEMPLATE/{bug_report,feature_request,config}.yml`
per review feedback.
Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two distinct buckets of work that landed together because they share a version bump (CI requires one per PR):
1. TOML config files (
--config <PATH>)rusnel serverandrusnel clientboth gain a--config <PATH>flag pointing at a TOML file with[server]and/or[client]sections. Schema mirrors the CLI flags one-for-one (snake_case); a single file can hold both sections.ArgMatches::value_source(same approach ripgrep / bat use).--insecure/--tls-self-signed/--tls-cert/--tls-key/--tls-caon the server, equivalents on the client) causes all of the file's TLS-mode keys to be ignored — no ambiguous mixing of e.g.tls_self_signed = truewith--tls-cert.#[serde(deny_unknown_fields)]) so typos surface as parse errors.<server>/<remote>...can be supplied by the file when omitted from the CLI; CLI wins when both are present.src/config_file.rscover parsing happy-path + every error mode (typos, invalid enum values, empty file).tests/config_file.rsspawn the actual binary and verify the file drives it (including CLI override of file values).examples/rusnel.toml.2. Release + adoption infrastructure
.github/workflows/release.yml: onv*tag push, builds prebuilt binaries for x86_64/aarch64 Linux (gnu + musl), macOS (Intel + Apple Silicon), Windows x86_64, attaches sha256 checksums to a GitHub Release, and pushes a multi-arch (amd64 + arm64) Docker image to GHCR tagged:vX.Y.Z,:X.Y,:latest.Dockerfile(multi-stage musl builder → distroless runtime, ~10 MB image, runs as non-root) +.dockerignore.ssh -L, concrete benchmark numbers near the top (2.07x throughput vs chisel, 4.3x better p99 latency, pulled from existingbenchmark/iperf/results/loopback/results.json), 60-second quickstart, expanded Features list surfacing previously-hidden bits (stdio:,RUSNEL_EMBED_*,rusnel ctl, JSON logs, Happy Eyeballs), Configuration-file section, Docker subsection.ROADMAP.md: extracted from the old README## TODOso the README stays focused.CONTRIBUTING.md+SECURITY.md: project hygiene that infosec users specifically look for..github/ISSUE_TEMPLATE/{bug_report,feature_request,config}.yml+.github/PULL_REQUEST_TEMPLATE.md: structured reporting that routes security issues to private disclosure and the version-bump checklist into the PR form.docs/launch-post.md: drafts for HN / r/rust / r/selfhosted / lobste.rs and an awesome-list submission checklist (private to the repo, not user-visible from the README).Notable design choices
mod config_fileinmain.rs-only, not exported from the library) because it's tightly coupled to the CLI shape, not to any library API.tests/config_file.rsexercises it through the real binary instead of through library symbols.Args::parse_from(...)totry_get_matches_from + from_arg_matchesso we can readvalue_sourcefor the merge logic. Same struct, same parser, just one more layer of indirection.tls_self_signed = true, you pass--tls-certto override, butresolve_server_tlspicks self-signed first and ignores your cert). The atomic rule means the CLI's TLS choice is total whenever it's specified.Stats
cargo fmt --all -- --checkclean,cargo clippy --all -- -D warningsclean.Made with Cursor