Skip to content

Ship prebuilt binaries and a --tunnel flag for easy local runs#19

Open
aterga wants to merge 3 commits into
mainfrom
arshavir/sweet-hawking-ecjla5
Open

Ship prebuilt binaries and a --tunnel flag for easy local runs#19
aterga wants to merge 3 commits into
mainfrom
arshavir/sweet-hawking-ecjla5

Conversation

@aterga

@aterga aterga commented Jun 26, 2026

Copy link
Copy Markdown
Owner

What & why

Makes the server downloadable and runnable with as few dependencies and as little compile time as possible — collapsing this:

git clone https://github.com/aterga/imcp2 && cd imcp2
cloudflared tunnel --url http://localhost:8000            # copy the printed URL
PUBLIC_URL="https://<name>.trycloudflare.com" cargo run   # restart with it set

into this:

curl -fsSL https://github.com/aterga/imcp2/releases/latest/download/imcp-$(uname -s)-$(uname -m).tar.gz | tar xz
./imcp --tunnel

No clone, no Rust toolchain, no compile, no copy-paste, no restart.

Changes

1. Prebuilt binaries via GitHub Releases (.github/workflows/release.yml)

  • On every v* tag, builds a self-contained binary for linux x86_64/arm64 and macOS x86_64/arm64, packages each as imcp-<uname -s>-<uname -m>.tar.gz + .sha256, and attaches them to a draft release for review. Also runs on workflow_dispatch (artifacts only, no release).
  • The binary is already fully self-contained — the only static assets (Candid cheat sheets + HTML pages) are baked in at compile time via include_str!, so each asset is just one executable.
  • Built natively per target (no cross-compiling): the rustls crypto backend (aws-lc-sys) needs cmake/clang and resists cross/musl builds, so native runners are the reliable path. Linux gnu binaries target glibc 2.35+ (Ubuntu 22.04 runner); the Dockerfile remains the option for older distros.

2. --tunnel flag (src/tunnel.rs, src/main.rs)

  • The server spawns cloudflared tunnel --url http://localhost:<port>, scrapes the https://<name>.trycloudflare.com URL from its output, and sets PUBLIC_URL from it before anything reads PUBLIC_URL (allowed_hosts() and auth::base_url()).
  • cloudflared is kept alive (kill_on_drop) for the server's lifetime; its stderr is drained so the tunnel never stalls. A missing binary produces a clear install hint instead of a stack trace. If PUBLIC_URL is already set, --tunnel is a no-op.
  • Adds --help / --version while wiring up arg parsing.

3. README

  • Documents the download-a-binary flow and the --tunnel one-liner.

Testing

  • cargo check --locked --all-targets and cargo build --locked — clean (only the pre-existing tool_router dead-code warning).
  • cargo test tunnel:: — 5 URL-extraction unit tests pass.
  • Manual: --help, --version, unknown-flag (exit 2), and --tunnel with cloudflared absent (clean install-hint error) all verified.

Note: the release workflow itself can only be exercised by pushing a v* tag / running it from the Actions tab — it hasn't run in CI yet.

🤖 Generated with Claude Code


Generated by Claude Code

Make the server downloadable-and-runnable without a Rust toolchain or the
manual cloudflared dance.

- release.yml: on each v* tag, natively build a self-contained binary for
  linux x86_64/arm64 and macOS x86_64/arm64 and attach a tarball per
  platform to a draft GitHub Release. Built natively per target because the
  rustls crypto backend (aws-lc-sys) needs cmake/clang and resists
  cross/musl builds. The binary already bundles all assets via include_str!,
  so each asset is just one executable.

- --tunnel flag: the server spawns cloudflared, scrapes the
  https://<name>.trycloudflare.com URL it prints, and sets PUBLIC_URL from
  it before anything reads PUBLIC_URL — collapsing "run cloudflared, copy
  the URL, restart with PUBLIC_URL set" into one command. cloudflared is
  kept alive (kill_on_drop) for the server's lifetime; a missing binary
  yields a clear install hint. Adds --help/--version too.

- README: document the download-a-binary flow and the --tunnel one-liner.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Toatr3FXLddEs5y37QXXE8

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a smoother “download-and-run” story for the server by (1) publishing prebuilt release binaries and (2) introducing a --tunnel flag that auto-provisions a Cloudflare quick tunnel and derives PUBLIC_URL during startup.

Changes:

  • Add --tunnel, --help, and --version CLI handling; implement Cloudflare quick-tunnel spawning + URL scraping.
  • Add a GitHub Actions release workflow that builds and packages per-platform tarballs + SHA256 files for GitHub Releases.
  • Update README to document the prebuilt-binary flow and the --tunnel one-liner; expand Tokio features needed for process IO/timeouts.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/tunnel.rs New module to spawn cloudflared, drain logs, and extract the trycloudflare.com URL with tests.
src/main.rs Adds basic CLI parsing and wires --tunnel into startup before PUBLIC_URL is read.
README.md Documents downloading release tarballs and using --tunnel for a public URL.
Cargo.toml Expands Tokio feature set to support tokio::process, IO, timeouts, and channels.
.github/workflows/release.yml New workflow to build/package/upload per-platform release artifacts and create/update a draft GitHub Release.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml Outdated
Comment thread README.md Outdated
- Pin actions/upload-artifact and actions/download-artifact to commit SHAs
  (with version comments), matching the repo's supply-chain hardening
  convention already applied to actions/checkout.
- Build with an explicit --target ${{ matrix.target }} (each runner's native
  triple) and package from target/<triple>/release, making the per-platform
  intent explicit and the output path deterministic; matrix.target is no
  longer unused.
- README: include the .tar.gz suffix in the example asset names so they
  match the documented naming and copy/paste cleanly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Toatr3FXLddEs5y37QXXE8
@aterga aterga marked this pull request as ready for review June 27, 2026 12:38
Copilot AI review requested due to automatic review settings June 27, 2026 12:38

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Comment thread src/main.rs
Comment thread src/tunnel.rs
Comment thread src/tunnel.rs
Comment thread src/main.rs Outdated
Comment thread src/tunnel.rs
The help text said "./oauth-clients.json" while auth.rs defaults to
"oauth-clients.json" (no ./). Make the documented default verbatim so it
greps cleanly against the code.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Toatr3FXLddEs5y37QXXE8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants