diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..c7902f5 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,63 @@ +# Changelog + +All notable changes to Expose will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +--- + +## [Unreleased] + +### Planned for v0.2.0 +- ngrok provider support +- Custom subdomains +- HTTPS support + +--- + +## [0.1.2] - 2025-11-10 + +### Added +- Config management commands (`config list`, `config get`) +- Service layer with thread-safe tunnel management +- `--version` flag with commit and build date metadata + +### Changed +- Improved error messages for tunnel lifecycle +- Better context cancellation handling + +### Fixed +- Race conditions in Service.Start() +- Graceful shutdown on Ctrl+C + +--- + +## [0.1.1] - 2025-11-09 + +### Added +- LocalTunnel provider integration +- 6 unit tests for Service layer (75%+ coverage) +- Provider interface for extensibility + +### Changed +- Refactored tunnel command to use Service layer +- Separated CLI logic from business logic + +--- + +## [0.1.0] - 2025-11-07 + +### Added +- Initial release +- `expose init` - Create `.expose.yml` config +- `expose tunnel` - Start local reverse proxy +- Cobra CLI framework +- GitHub Actions CI/CD (test.yml) +- Basic test coverage (tunnel package) + +--- + +[0.1.2]: https://github.com/kernelshard/expose/releases/tag/v0.1.2 +[0.1.1]: https://github.com/kernelshard/expose/releases/tag/v0.1.1 +[0.1.0]: https://github.com/kernelshard/expose/releases/tag/v0.1.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..1eefcc4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,167 @@ +# Contributing to Expose + +Thanks for your interest in contributing! This guide will help you get started. + +--- + +## Development Setup + +### Prerequisites +- Go 1.23+ +- Git + +### Clone and Build + +``` +git clone https://github.com/kernelshard/expose.git +cd expose +go mod download +go build -o expose ./cmd/expose +./expose --version +``` + +--- + +## Workflow + +### Branch Strategy + +1. **Always branch from `develop`** (not `main`) + ``` + git checkout develop + git pull origin develop + git checkout -b feature/your-feature-name + ``` + +2. **Branch naming:** + - Features: `feat/add-ngrok-provider` + - Fixes: `fix/config-load-error` + - Docs: `docs/update-readme` + - Tests: `test/add-provider-tests` + +3. **Create PR to `develop`** (not `main`) + - Base branch: `develop` + - Title: Use commit prefix (`feat:`, `fix:`, `docs:`, `test:`) + - Description: Reference issue number, explain changes + +4. **After merge:** We merge `develop` → `main` only for releases + +--- + +## Code Standards + +### Commit Messages + +Follow [Conventional Commits](https://www.conventionalcommits.org/): + +``` +feat: add ngrok provider support +fix: resolve config file not found error +docs: update installation instructions +test: add tunnel service tests +``` + +### Testing Requirements + +- ✅ Write tests for new features +- ✅ Minimum **75% coverage** +- ✅ Run with race detector: `go test -race ./...` +- ✅ Use table-driven tests for multiple cases + +**Example:** + +``` +func TestConfigLoad(t *testing.T) { + tests := []struct { + name string + config string + wantErr bool + }{ + {"valid config", "port: 3000", false}, + {"invalid yaml", "port:", true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // test body + }) + } +} +``` + +### Code Style + +- Run `go fmt` before committing +- Follow [Effective Go](https://golang.org/doc/effective_go) +- Keep CLI layer thin (delegate to service layer) +- Export struct fields only when needed (YAML marshaling) +- Return errors early + +**File organization:** + +``` +internal/ +├── cli/ # Cobra commands (newXXXCmd() factory pattern) +├── config/ # Config CRUD operations +├── provider/ # Provider implementations +├── tunnel/ # Service layer (business logic) +└── version/ # Version metadata +``` + +--- + +## Running Tests + +``` +# All tests with race detector +go test ./... -v -race -cover + +# Specific package coverage +go test ./internal/config -cover +go test ./internal/tunnel -cover + +# Coverage report +go test ./... -coverprofile=coverage.out +go tool cover -html=coverage.out +``` + +--- + +## Testing Locally + +``` +# Build +go build -o expose ./cmd/expose + +# Run tunnel +./expose tunnel + +# Test with HTTP server +python3 -m http.server 3000 # Terminal 1 +./expose tunnel # Terminal 2 +curl # Terminal 3 +``` + +--- + +## Pull Request Checklist + +Before submitting: + +- [ ] Tests pass: `go test ./... -race -cover` +- [ ] Code formatted: `go fmt ./...` +- [ ] Coverage ≥ 75% +- [ ] Commit messages follow convention +- [ ] PR description includes issue reference +- [ ] Branch is up to date with `develop` + +--- + +## Need Help? + +- **Issues:** [github.com/kernelshard/expose/issues](https://github.com/kernelshard/expose/issues) +- **Discussions:** Comment on relevant issue + +--- + +**Made with ❤️ by contributors like you.** diff --git a/README.md b/README.md index 794d109..cfc3029 100644 --- a/README.md +++ b/README.md @@ -1,159 +1,224 @@ -# expose +# 🚀 Expose [![Tests](https://github.com/kernelshard/expose/actions/workflows/test.yml/badge.svg)](https://github.com/kernelshard/expose/actions/workflows/test.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/kernelshard/expose)](https://goreportcard.com/report/github.com/kernelshard/expose) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/kernelshard/expose/blob/main/LICENSE) -> Expose localhost to the internet. Minimal. Fast. Open Source. +> Minimal CLI tool to expose your local dev server to the internet -**expose** is a lightweight Golang CLI that makes sharing your local development server effortless. +**Expose** lets you share your `localhost` with the world — perfect for testing webhooks, demoing work, or debugging on mobile devices. Built as a lightweight alternative to ngrok, powered by LocalTunnel. ## ✨ Features -- 🚀 **One Command**: Expose your local server instantly -- ⚙️ **Zero Config**: Works out of the box with sensible defaults -- 🔒 **Privacy First**: Self-hostable, no vendor lock-in -- 🎯 **Minimal**: Single binary, no runtime dependencies +- 🌐 **Instant public URLs** — Share localhost with one command +- ⚡ **Zero signup** — No accounts, no registration required +- � **Config management** — Save port settings per project +- 📦 **Single binary** — No Node.js, Python, or runtime dependencies +- 🧪 **Production-tested** — 75%+ test coverage, CI/CD pipeline -## 📦 Installation - -``` -# Clone the repository -git clone https://github.com/kernelshard/expose.git -cd expose +--- -# Build -go build -o expose cmd/expose/main.go +## 🚀 Quick Start -# Optional: Install globally +```bash +# Install go install github.com/kernelshard/expose/cmd/expose@latest -``` -## 🚀 Quick Start - -``` -# 1. Initialize configuration +# Initialize config expose init -# 2. Expose your local server +# Start tunnel expose tunnel - -# 3. Access via http://localhost:8080 ``` -## 📖 Usage +--- -### Version +## 📦 Installation -Check the version of expose: +### Using Go Install +```bash +go install github.com/kernelshard/expose/cmd/expose@latest ``` -expose --version -# expose version v0.1.1 (commit: 4784595, built: 2025-11-07) + +### From Source + +```bash +git clone https://github.com/kernelshard/expose.git +cd expose +go build -o expose ./cmd/expose +./expose --version ``` -### Initialize Project +--- -Create a `.expose.yml` configuration file: +## 📖 Usage -``` -expose init -``` +### Initialize Configuration -This generates: +```bash +$ expose init +✓ Config created: .expose.yml ``` -project: my-app -default_port: 3000 + +Creates `.expose.yml` in current directory: + +```yaml +project: expose +port: 3000 ``` -### Expose Local Server +### Start Tunnel -Start exposing your local development server: +```bash +# Use config port +$ expose tunnel +✓ Tunnel (LocalTunnel) started for localhost:3000 +✓ Public URL: https://quick-mammals-sing.loca.lt +✓ Forwarding to http://localhost:3000 +✓ Provider: LocalTunnel +✓ Press Ctrl+C to stop +# Override port +$ expose tunnel --port 8080 ``` -# Use default port from config -expose tunnel -# Specify custom port -expose tunnel --port 8080 -``` +### Manage Configuration -## ⚙️ Configuration +```bash +# List all config values +$ expose config list +project: expose +port: 3000 -Edit `.expose.yml` to customize settings: +# Get specific value +$ expose config get port +3000 +$ expose config get project +expose ``` -project: "my-awesome-app" -default_port: 3000 -``` -## 🏗️ Architecture +--- + +## ✅ Tested Locally +```bash +$ expose --version +expose version v0.1.2 (commit: d30c483, built: 2025-11-10) + +$ expose init +✓ Config created: .expose.yml (project: expose, port: 3000) + +$ python3 -m http.server 3000 & +Serving HTTP on 0.0.0.0 port 3000... + +$ expose tunnel +🚀 Tunnel[LocalTunnel] started for localhost:3000 +✓ Public URL: https://ripe-garlics-add.loca.lt +✓ Forwarding to: http://localhost:3000 +✓ Provider: LocalTunnel +Press Ctrl+C to stop + +$ curl https://ripe-garlics-add.loca.lt +... # Works! ``` + +**Tested on:** Go 1.23, macOS 14, Ubuntu 22.04 + +--- + +## 🏗 Architecture + +```text expose/ -├── cmd/expose/ # CLI entry point -└── internal/ - ├── cli/ # Command implementations - ├── config/ # Configuration management - ├── env/ # Environment handling - ├── git/ # Git integration - ├── preview/ # Preview functionality - ├── state/ # State management - └── tunnel/ # Tunnel management +├── cmd/expose/ # CLI entry point +├── internal/ +│ ├── cli/ # Cobra commands (thin layer) +│ ├── config/ # YAML config management +│ ├── provider/ # Tunnel provider interface +│ ├── tunnel/ # Service layer (business logic) +│ └── version/ # Version metadata +└── .expose.yml # User config (add to .gitignore per project) ``` -**Design Principles:** -- Idiomatic Go code -- Clean architecture -- Minimal dependencies -- Easy to contribute +**Design principles:** +- **Interface-driven** — `Provider` interface supports multiple tunnel backends +- **Clean separation** — CLI → Service → Provider (no circular deps) +- **Testable** — Real file tests, injectable service layer + +--- -## 🛠️ Development +## ⚠️ Known Limitations -``` -# Install dependencies +- **LocalTunnel only** — ngrok/Cloudflare support planned for v0.2.0 +- **One tunnel per process** — Each `expose tunnel` command runs independently (can run multiple on different ports) +- **No persistence** — Public URLs change on restart +- **CLI-only** — No web UI or dashboard yet + +See [GitHub Issues](https://github.com/kernelshard/expose/issues) for roadmap. + +--- + +## 🧪 Development + +### Prerequisites +- Go 1.23+ +- Git + +### Setup + +```bash +git clone https://github.com/kernelshard/expose.git +cd expose go mod download +``` -# Run locally -go run cmd/expose/main.go init +### Run Tests -# Build -go build -o expose cmd/expose/main.go +```bash +# Run all tests with race detector +go test ./... -v -race -cover -# Format code -go fmt ./... +# Check coverage for specific packages +go test ./internal/config -cover +go test ./internal/tunnel -cover ``` -## 🗺️ Roadmap +### Build -- [x] Basic tunnel functionality -- [ ] Localtunnel/ngrok-style public URLs -- [ ] Branch-aware environment switching -- [ ] PR preview environments -- [ ] Custom tunnel server support +```bash +go build -o expose ./cmd/expose +./expose --version +``` -## 🤝 Contributing +### Run Locally -Contributions welcome! This project follows: -- Standard Go conventions -- Commit message format: `type: description` -- Clean, tested, documented code +```bash +# Without installing +go run cmd/expose/main.go tunnel -### Contributors +# Test with live server +python3 -m http.server 3000 # Terminal 1 +./expose tunnel # Terminal 2 +``` -- **Samiul Sk** - Project creator and maintainer +--- -*Want to contribute? See our [contributing guidelines](CONTRIBUTING.md) (coming soon)* +## 🤝 Contributing -## 📝 License +Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for: +- Development workflow +- Branch strategy +- Testing requirements +- Code style guidelines -MIT License - see [LICENSE](LICENSE) for details. +--- -## 🙏 Acknowledgments +## 📝 License -Built with: -- [Cobra](https://github.com/spf13/cobra) - CLI framework -- Go standard library - Minimal and powerful +MIT License - see [LICENSE](LICENSE) for details. --- -**Status:** Early development - contributions welcome! +**Made with ❤️ by [@kernelshard](https://github.com/kernelshard)**