Lightweight Rust service that provides stable redirect URLs to the latest release artifacts from Forgejo and other hosting platforms.
Find a file
^x3ro e4d1d98d43
All checks were successful
Build and Publish / build (push) Successful in 8m12s
Revert "🐛 FIX: Set buildx driver-opts network=host to fix Docker Hub access"
This reverts commit ac405617c9.
2026-04-20 22:37:10 +02:00
.claude 👌 IMPROVE: Add Claude hooks for doc-update checking 2026-04-19 23:21:03 +02:00
.forgejo/workflows Revert "🐛 FIX: Set buildx driver-opts network=host to fix Docker Hub access" 2026-04-20 22:37:10 +02:00
src 👌 IMPROVE: Rename project to release-router 2026-04-19 23:45:49 +02:00
.env.example 📦 NEW: Implement Rust + Axum URL redirect service 2026-04-19 21:30:03 +02:00
.envrc 📦 NEW: Implement Rust + Axum URL redirect service 2026-04-19 21:30:03 +02:00
.gitignore 📦 NEW: Implement Rust + Axum URL redirect service 2026-04-19 21:30:03 +02:00
.markdownlint.json 👌 IMPROVE: Add markdownlint and fix all markdown lint errors 2026-04-19 22:57:39 +02:00
Cargo.lock 👌 IMPROVE: Switch to rustls and scratch container for minimal image 2026-04-20 00:05:23 +02:00
Cargo.toml 👌 IMPROVE: Switch to rustls and scratch container for minimal image 2026-04-20 00:05:23 +02:00
CLAUDE.md 👌 IMPROVE: Switch builder to rust:alpine for faster CI builds 2026-04-20 00:28:54 +02:00
docker-compose.yml 👌 IMPROVE: Rename project to release-router 2026-04-19 23:45:49 +02:00
Dockerfile 👌 IMPROVE: Switch builder to rust:alpine for faster CI builds 2026-04-20 00:28:54 +02:00
flake.lock 👌 IMPROVE: Rewrite flake to use flake-parts and flake-compat 2026-04-19 21:51:48 +02:00
flake.nix 👌 IMPROVE: Rename project to release-router 2026-04-19 23:45:49 +02:00
justfile 👌 IMPROVE: Add build-docker just recipe 2026-04-19 23:20:53 +02:00
README.md 👌 IMPROVE: Rename project to release-router 2026-04-19 23:45:49 +02:00
shell.nix 👌 IMPROVE: Rewrite flake to use flake-parts and flake-compat 2026-04-19 21:51:48 +02:00

release-router

A lightweight Rust web service for generating redirect URLs to release artifacts from various sources (Forgejo, GitHub, etc.).

Features

  • Strategy-based architecture: Easily extensible for different redirect sources
  • Forgejo support: Redirect to latest release artifacts from Forgejo/Gitea instances
  • Fast and lightweight: Built with Rust and Axum
  • Docker deployment: Simple containerized deployment

Quick Start

Local Development

This project uses a Nix flake for a reproducible development environment. Nix is the only prerequisite.

  1. Clone and configure:

    git clone <your-repo-url>
    cd release-router
    cp .env.example .env
    # Edit .env and set FORGEJO_INSTANCE_URL
    
  2. Enter the dev shell:

    nix develop      # flake-aware Nix
    # or
    nix-shell        # legacy nix-shell (via flake-compat)
    

    If you have direnv with nix-direnv installed, the shell loads automatically:

    direnv allow
    
  3. Run locally:

    just run
    

    The service will start on http://localhost:8000. Use just watch to automatically restart on file changes.

Docker Deployment

  1. Configure environment:

    cp .env.example .env
    # Edit .env and set FORGEJO_INSTANCE_URL
    
  2. Start with Docker Compose:

    docker-compose up -d
    
  3. View logs:

    docker-compose logs -f releases
    

Usage

Forgejo Strategy

The Forgejo strategy allows you to redirect to release artifacts from Forgejo/Gitea instances.

URL Format: /<strategy>/<sub-strategy>/<path>

Forgejo Release Artifacts:

/forgejo/release/<user>/<repo>/latest/<artifact-name>

Example:

# Redirect to the latest release artifact from Codeberg
curl -L https://your-domain.example/forgejo/release/forgejo/forgejo/latest/forgejo-7.0.0-linux-amd64

This will:

  1. Query the Forgejo API for the latest release of forgejo/forgejo
  2. Find the artifact named forgejo-7.0.0-linux-amd64 in the release assets
  3. Redirect (HTTP 302) to the actual download URL

Configuration

Configuration is done via environment variables or a .env file:

Variable Required Default Description
FORGEJO_INSTANCE_URL Yes - Base URL of your Forgejo instance (e.g., https://codeberg.org)
HOST No 0.0.0.0 Host to bind to
PORT No 8000 Port to listen on
RUST_LOG No info Log level (trace, debug, info, warn, error)

Reverse Proxy Setup

Caddy

Add this to your Caddyfile:

your-domain.example {
    reverse_proxy localhost:8000
}

Nginx

server {
    listen 80;
    server_name your-domain.example;

    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Development

Project Structure

src/
├── main.rs              # Entry point and Axum router setup
├── routes.rs            # HTTP route handlers
├── config.rs            # Configuration from environment
├── error.rs             # Error types and HTTP responses
└── strategies/
    ├── mod.rs           # Module exports
    ├── traits.rs        # Strategy trait definition
    ├── registry.rs      # Strategy registry
    └── forgejo/
        ├── mod.rs       # Forgejo strategy implementation
        └── client.rs    # Forgejo API client

Building

Enter the dev shell first, then use just or cargo directly:

just build          # debug build
just run            # run the service
just watch          # run with auto-restart on file changes

cargo build --release   # release build
cargo test              # run tests
cargo check             # type-check without building

To build the Nix package (uses Crane, produces a reproducible binary):

nix build
./result/bin/release-router

Adding a New Strategy

See CLAUDE.md for detailed instructions on adding new strategies.

Error Handling

The service returns appropriate HTTP status codes:

  • 200/302: Successful redirect
  • 400: Invalid path format
  • 404: Strategy not found, release not found, or artifact not found
  • 500: Server error (API failures, configuration errors)

Error messages are returned in plain text in the response body.

License

MIT