Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
84c7865
feat: init cargo workspace with rust nix flake
karol-broda Jan 11, 2026
9376171
feat(core): add tunnel id, message protocol, and api key types
karol-broda Jan 12, 2026
f336be0
feat(db): add migrations for users, api keys, and tunnel sessions
karol-broda Jan 12, 2026
4a43e58
feat(server): add axum skeleton with db layer, api routes, and clap cli
karol-broda Jan 25, 2026
77d842c
chore: update gitignore for rust
karol-broda Jan 25, 2026
4fc45b2
style: clean up comments and use named constants
karol-broda Jan 26, 2026
a87fe75
feat(tunnel): add tunnel manager, active tunnel, and stats
karol-broda Feb 15, 2026
7e94657
feat(ws): add websocket upgrade handler for tunnel clients
karol-broda Feb 16, 2026
ecf579d
feat(proxy): add subdomain router and forwarding headers
karol-broda Mar 8, 2026
7821caa
feat(server): wire tunnel engine into app state and routes
karol-broda Mar 8, 2026
9fd7fdf
feat(client): add tunnel client with websocket, forwarding, and cli
karol-broda Apr 5, 2026
11c6544
fix: resolve build errors in server and client
karol-broda Apr 5, 2026
d57361e
fix: use ipnetwork for inet columns and suppress dead code warnings
karol-broda Apr 6, 2026
fc8e699
chore: remove go source code in favor of rust rewrite
karol-broda May 2, 2026
fe17d96
chore: track Cargo.lock for reproducible builds
karol-broda May 2, 2026
bec50fe
feat(server): add automatic TLS with ACME certificate management
karol-broda May 2, 2026
d9d9481
feat(protocol): replace websocket tunneling with quic
karol-broda May 3, 2026
0a6d27c
refactor: use workspace deps, remove unused crates, and clean up core
karol-broda May 3, 2026
b3816d8
chore(ci): remove github workflows
karol-broda May 3, 2026
be54028
refactor: enable strict clippy lints and replace unwrap/expect with
karol-broda May 3, 2026
3aec4d9
refactor(server): introduce store abstraction layer and extract tls/quic
karol-broda May 8, 2026
caae1de
feat(server): add API key auth middleware for key management endpoints
karol-broda May 9, 2026
22b7257
feat(client): add startup banner, spinner, and colored access log for…
karol-broda May 10, 2026
c2f95db
fix(server): route tunnel subdomain requests to proxy before matching…
karol-broda May 10, 2026
c0a8d1e
style: apply rustfmt formatting
karol-broda May 10, 2026
89d453e
refactor(server): split provider fields from users into accounts table
karol-broda May 10, 2026
6fb4c0d
feat(server): add scope based permissions to api keys
karol-broda May 10, 2026
c9037e0
feat(server): authenticate quic tunnel connections and record sessions
karol-broda May 10, 2026
0991424
feat(server): add oauth login with github and generic provider support
karol-broda May 10, 2026
624f04c
refactor(client): replace inlet config with named context system
karol-broda May 10, 2026
6b8ab69
feat(client): add login, keys, status, and whoami commands
karol-broda May 10, 2026
1890324
wip: add turso backend, teams, and user/session management
karol-broda May 10, 2026
8465fc6
refactor(client): reorganize into cmd/ and tunnel/ modules, remove
karol-broda May 11, 2026
5487ba0
feat(nix): add flake-parts packaging, OCI containers, NixOS/Home Manager
karol-broda May 11, 2026
c7d9696
feat(ci): add GitHub Actions workflows, versioning, and cargo-deny
karol-broda May 11, 2026
663f15e
docs: add roadmap and remove stale Go-era files
karol-broda May 11, 2026
22168dd
feat(server): add OpenAPI spec generation with utoipa and Scalar UI
karol-broda May 12, 2026
340fb44
docs: rebuild site with new content and remove stale Go-era pages
karol-broda May 12, 2026
8738a10
fix(deny): replace rustls-pemfile with rustls-pki-types and ignore
karol-broda May 12, 2026
adcdbc3
feat(ci): add ci devshell and cache Rust build artifacts
karol-broda May 12, 2026
2059279
feat(ci): move clippy and fmt checks from nix derivations to direct
karol-broda May 12, 2026
c1c912d
fix(lint): resolve clippy warnings and formatting across workspace
karol-broda May 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
271 changes: 36 additions & 235 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,252 +1,53 @@
name: 🚀 CI Pipeline
name: CI

on:
push:
branches: [ master ]
branches: [master]
pull_request:
branches: [ master ]
workflow_dispatch:

env:
GO_VERSION: '1.21'
CACHE_VERSION: v1
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
quality:
name: 🔍 code quality
check:
name: Nix Check
runs-on: ubuntu-latest
steps:
- name: 📥 checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: 🔧 setup go environment
uses: actions/setup-go@v5
with:
go-version-file: go.work
cache: false

- name: 📦 cache dependencies
uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ env.CACHE_VERSION }}-${{ runner.os }}-go-${{ hashFiles('**/go.sum', '**/go.work.sum') }}
restore-keys: |
${{ env.CACHE_VERSION }}-${{ runner.os }}-go-

- name: 📋 download dependencies
run: make deps

- name: 🎨 check code formatting
run: |
echo "🔍 Checking code formatting..."
make fmt
if [ -n "$(git status --porcelain)" ]; then
echo "❌ Code is not formatted properly"
echo "📋 Here are the formatting issues:"
git diff
exit 1
fi
echo "✅ Code formatting is correct"

- name: 🔎 run linter
run: |
echo "🔍 Running linter checks..."
make lint
echo "✅ Linting completed successfully"

- name: 🛡️ security scan
uses: securego/gosec@master
with:
args: '-fmt sarif -out gosec.sarif ./...'
continue-on-error: true

- name: 📊 upload security scan results
uses: github/codeql-action/upload-sarif@v2
if: always()
with:
sarif_file: gosec.sarif
continue-on-error: true
- uses: actions/checkout@v6
- uses: DeterminateSystems/nix-installer-action@v22
with:
extra-conf: accept-flake-config = true
- uses: DeterminateSystems/magic-nix-cache-action@v13
- run: nix flake check

test:
name: 🧪 Test Suite
name: Test
runs-on: ubuntu-latest
needs: [quality]
steps:
- name: 📥 checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: 🔧 setup go environment
uses: actions/setup-go@v5
with:
go-version-file: go.work
cache: false

- name: 📦 cache dependencies
uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ env.CACHE_VERSION }}-${{ runner.os }}-go-${{ hashFiles('**/go.sum', '**/go.work.sum') }}
restore-keys: |
${{ env.CACHE_VERSION }}-${{ runner.os }}-go-

- name: 📋 download dependencies
run: make deps

- name: 🏃 run tests
run: |
echo "🧪 Running test suite..."
make test
echo "✅ Tests completed successfully"

- name: 📊 generate coverage report
run: |
echo "📊 Generating coverage reports for all modules..."
coverage_files=""

for dir in $(find . -name "go.mod" -not -path "./go.work*" -exec dirname {} \; | sort); do
module_name=$(basename "$dir")
echo "🔍 Processing module: $module_name (in $dir)"

(cd "$dir" && go test -v -coverprofile="coverage-${module_name}.out" ./...)

if [ -f "$dir/coverage-${module_name}.out" ]; then
echo "✅ Coverage generated for $module_name"
coverage_files="$coverage_files $dir/coverage-${module_name}.out"
fi
done

echo "📋 Coverage files generated: $coverage_files"

- name: 📈 upload coverage reports
uses: actions/upload-artifact@v4
if: always()
with:
name: coverage-reports
path: "**/coverage-*.out"
retention-days: 30

build:
name: 🏗️ Build (${{ matrix.goos }}/${{ matrix.goarch }})
- uses: actions/checkout@v6
- uses: DeterminateSystems/nix-installer-action@v22
with:
extra-conf: accept-flake-config = true
- uses: DeterminateSystems/magic-nix-cache-action@v13
- uses: nicknovitski/nix-develop@v1
with:
arguments: .#ci
- uses: Swatinem/rust-cache@v2
- run: cargo fmt --check
- run: cargo clippy --all-targets -- -D warnings
- run: cargo nextest run --workspace --exclude funnel-e2e
- run: cargo test --doc --workspace

deny:
name: Deny (${{ matrix.check }})
runs-on: ubuntu-latest
needs: [quality, test]
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
name: "🐧 Linux AMD64"
- goos: linux
goarch: arm64
name: "🐧 Linux ARM64"
- goos: darwin
goarch: amd64
name: "🍎 macOS Intel"
- goos: darwin
goarch: arm64
name: "🍎 macOS Apple Silicon"
- goos: windows
goarch: amd64
name: "🪟 Windows AMD64"
steps:
- name: 📥 checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: 🔧 setup go environment
uses: actions/setup-go@v5
with:
go-version-file: go.work
cache: false

- name: 📦 cache dependencies
uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ env.CACHE_VERSION }}-${{ runner.os }}-go-${{ hashFiles('**/go.sum', '**/go.work.sum') }}
restore-keys: |
${{ env.CACHE_VERSION }}-${{ runner.os }}-go-

- name: 📋 download dependencies
run: make deps

- name: 🔨 build binaries for ${{ matrix.name }}
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
run: |
EXT=""
if [ "$GOOS" = "windows" ]; then
EXT=".exe"
fi

BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
GIT_COMMIT=${GITHUB_SHA::7}
GIT_TAG=${GITHUB_REF#refs/tags/}
VERSION="0.0.1a"

echo "🏗️ Building funnel client for ${{ matrix.name }}..."
GOOS=$GOOS GOARCH=$GOARCH go build \
-ldflags "-X github.com/karol-broda/funnel/version.Version=$VERSION \
-X github.com/karol-broda/funnel/version.BuildDate=$BUILD_DATE \
-X github.com/karol-broda/funnel/version.GitCommit=$GIT_COMMIT \
-X github.com/karol-broda/funnel/version.GitTag=$GIT_TAG \
-s -w" \
-o funnel-$GOOS-$GOARCH$EXT \
./cmd/funnel

echo "🏗️ Building funnel server for ${{ matrix.name }}..."
GOOS=$GOOS GOARCH=$GOARCH go build \
-ldflags "-X github.com/karol-broda/funnel/version.Version=$VERSION \
-X github.com/karol-broda/funnel/version.BuildDate=$BUILD_DATE \
-X github.com/karol-broda/funnel/version.GitCommit=$GIT_COMMIT \
-X github.com/karol-broda/funnel/version.GitTag=$GIT_TAG \
-s -w" \
-o funnel-server-$GOOS-$GOARCH$EXT \
./cmd/server

echo "✅ Build completed successfully for ${{ matrix.name }}"

if [ -f "funnel-$GOOS-$GOARCH$EXT" ] && [ -f "funnel-server-$GOOS-$GOARCH$EXT" ]; then
echo "📦 Binary sizes:"
ls -lh funnel*-$GOOS-$GOARCH$EXT
else
echo "❌ Build verification failed"
exit 1
fi

rm -f funnel-$GOOS-$GOARCH$EXT funnel-server-$GOOS-$GOARCH$EXT

build-summary:
name: 📋 Build Summary
runs-on: ubuntu-latest
needs: [build]
if: always()
check: [advisories, "bans licenses sources"]
continue-on-error: ${{ matrix.check == 'advisories' }}
steps:
- name: 📊 build results summary
run: |
echo "## 🏗️ Build Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Platform | Status |" >> $GITHUB_STEP_SUMMARY
echo "|----------|--------|" >> $GITHUB_STEP_SUMMARY
echo "| 🐧 Linux AMD64 | ${{ needs.build.result == 'success' && '✅ Success' || '❌ Failed' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 🐧 Linux ARM64 | ${{ needs.build.result == 'success' && '✅ Success' || '❌ Failed' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 🍎 macOS Intel | ${{ needs.build.result == 'success' && '✅ Success' || '❌ Failed' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 🍎 macOS Apple Silicon | ${{ needs.build.result == 'success' && '✅ Success' || '❌ Failed' }} |" >> $GITHUB_STEP_SUMMARY
echo "| 🪟 Windows AMD64 | ${{ needs.build.result == 'success' && '✅ Success' || '❌ Failed' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📊 Pipeline Results" >> $GITHUB_STEP_SUMMARY
echo "- 🔍 Code Quality: ${{ needs.quality.result == 'success' && '✅ Passed' || '❌ Failed' }}" >> $GITHUB_STEP_SUMMARY
echo "- 🧪 Tests: ${{ needs.test.result == 'success' && '✅ Passed' || '❌ Failed' }}" >> $GITHUB_STEP_SUMMARY
echo "- 🏗️ Builds: ${{ needs.build.result == 'success' && '✅ All Successful' || '❌ Some Failed' }}" >> $GITHUB_STEP_SUMMARY
- uses: actions/checkout@v6
- uses: EmbarkStudios/cargo-deny-action@v2
with:
command: check ${{ matrix.check }}
Loading
Loading