diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..25f7bdc --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,52 @@ +{ + "name": "Template Rust Development", + "image": "mcr.microsoft.com/devcontainers/rust:1-bookworm", + + "features": { + "ghcr.io/devcontainers/features/rust:1": { + "version": "latest", + "profile": "default" + }, + "ghcr.io/devcontainers/features/git:1": {}, + "ghcr.io/devcontainers/features/github-cli:1": {} + }, + + "customizations": { + "vscode": { + "extensions": [ + "rust-lang.rust-analyzer", + "vadimcn.vscode-lldb", + "serayuzgur.crates", + "tamasfe.even-better-toml", + "usernamehw.errorlens", + "ms-vscode.makefile-tools" + ], + "settings": { + "rust-analyzer.checkOnSave.command": "clippy", + "rust-analyzer.cargo.features": "all", + "editor.formatOnSave": true, + "editor.defaultFormatter": "rust-lang.rust-analyzer", + "[rust]": { + "editor.defaultFormatter": "rust-lang.rust-analyzer" + } + } + } + }, + + "postCreateCommand": "cargo build", + + "remoteEnv": { + "RUST_BACKTRACE": "1", + "DATABASE_URL": "todo.db" + }, + + "mounts": [ + "source=${localWorkspaceFolder}/data,target=/workspaces/${localWorkspaceFolderBasename}/data,type=bind,consistency=cached" + ], + + "forwardPorts": [], + + "portsAttributes": {}, + + "remoteUser": "vscode" +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..6a3927d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,35 @@ +# Build artifacts +target/ +*.db +*.db-* + +# Git +.git/ +.gitignore + +# IDE +.vscode/ +.idea/ + +# CI/CD +.github/ + +# Documentation +*.md +docs/ + +# Nix +*.nix +.envrc + +# Devcontainer +.devcontainer/ + +# Docker +Dockerfile +docker-compose.yml +.dockerignore + +# Misc +.env +.env.* diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..43e1f57 --- /dev/null +++ b/.envrc @@ -0,0 +1,8 @@ +# Automatically use Nix flakes when entering this directory +# Install direnv and run: direnv allow + +use flake + +# Optional: Set additional environment variables +# export DATABASE_URL="todo.db" +# export RUST_BACKTRACE="1" diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..610a47f --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,47 @@ +name: Docker Build + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +permissions: + contents: read + +jobs: + docker-build: + name: Docker Build Test + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: false + tags: template-rust:test + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Test Docker image + run: | + docker run --rm template-rust:test --version || echo "Application does not support --version flag" + docker run --rm template-rust:test --help + + docker-compose: + name: Docker Compose Validation + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + + - name: Validate docker-compose.yml + run: docker compose config > /dev/null diff --git a/.gitignore b/.gitignore index d5cf02f..d6d18ac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,31 @@ +# Rust build artifacts /target +Cargo.lock.bak + +# Database files *.db *.db-* +*.sqlite +*.sqlite3 + +# Environment files .env +.env.* +!.envrc + +# macOS .DS_Store + +# IDE +.idea/ +*.swp +*.swo +*~ + +# Docker data +data/ + +# Nix +result +result-* +.direnv/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1f5deb1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,58 @@ +# Multi-stage build for minimal final image +FROM rust:1.83-slim AS builder + +# Install build dependencies +RUN apt-get update && apt-get install -y \ + pkg-config \ + libssl-dev \ + && rm -rf /var/lib/apt/lists/* + +# Create a new empty project +WORKDIR /app + +# Copy manifests +COPY Cargo.toml Cargo.lock ./ + +# Copy source code +COPY src ./src +COPY examples ./examples +COPY tests ./tests + +# Build the application in release mode +RUN cargo build --release + +# Runtime stage +FROM debian:bookworm-slim + +# Install runtime dependencies +RUN apt-get update && apt-get install -y \ + ca-certificates \ + libssl3 \ + && rm -rf /var/lib/apt/lists/* + +# Create a non-root user +RUN useradd -m -u 1000 appuser + +WORKDIR /app + +# Copy the binary from builder +COPY --from=builder /app/target/release/template-rust /usr/local/bin/template-rust + +# Change ownership +RUN chown -R appuser:appuser /app + +# Switch to non-root user +USER appuser + +# Set default database path +ENV DATABASE_URL=/app/data/todo.db + +# Create data directory +RUN mkdir -p /app/data + +# Expose any necessary ports (if needed for future web features) +# EXPOSE 8080 + +# Set the default command +ENTRYPOINT ["template-rust"] +CMD ["--help"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b1d32e6 --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +.PHONY: help build test clean docker-build docker-run docker-compose-up docker-compose-down + +help: ## Show this help message + @echo 'Usage: make [target]' + @echo '' + @echo 'Available targets:' + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-20s\033[0m %s\n", $$1, $$2}' + +build: ## Build the project in debug mode + cargo build + +build-release: ## Build the project in release mode + cargo build --release + +test: ## Run all tests + cargo test + +test-verbose: ## Run tests with verbose output + cargo test -- --nocapture + +clippy: ## Run clippy linter + cargo clippy -- -D warnings + +fmt: ## Format code + cargo fmt + +fmt-check: ## Check code formatting + cargo fmt --all -- --check + +clean: ## Clean build artifacts + cargo clean + +docker-build: ## Build Docker image + docker build -t template-rust:latest . + +docker-run: ## Run Docker container in TUI mode + docker run --rm -it -v $(PWD)/data:/app/data template-rust:latest tui + +docker-compose-up: ## Start services with docker-compose + docker compose up + +docker-compose-down: ## Stop services with docker-compose + docker compose down + +docker-compose-dev: ## Start development service with docker-compose + docker compose up dev + +all: fmt clippy test build ## Run format, clippy, test, and build diff --git a/README.md b/README.md index d290316..3ff0164 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,14 @@ A Rust project template featuring a todo application with SQLite database and te - 🚀 CI/CD with GitHub Actions - 📦 Cross-platform releases - 🔒 Security auditing +- 🐳 Docker and Docker Compose support +- ❄️ Nix flakes for reproducible environments +- 📦 Devcontainer configuration for GitHub Codespaces ## Installation +> **💡 Quick Start**: See [SETUP.md](SETUP.md) for detailed setup instructions using Docker, Nix, Codespaces, or local development. + ### From Source ```bash @@ -26,6 +31,33 @@ cargo build --release Download the latest binary from the [Releases](https://github.com/pnstack/template-rust/releases) page. +### With Docker + +```bash +# Build the image +docker build -t template-rust:latest . + +# Run with interactive TUI +docker run --rm -it -v $(pwd)/data:/app/data template-rust:latest tui + +# Or use Docker Compose +docker compose up +``` + +### With Nix + +```bash +# Enter development environment +nix develop + +# Or run directly +nix run +``` + +### With GitHub Codespaces + +Click the "Code" button on GitHub and select "Create codespace on main" - everything is pre-configured! + ## Usage ### Command Line Interface @@ -93,15 +125,28 @@ template-rust/ ## Development +> **📚 Full Setup Guide**: See [SETUP.md](SETUP.md) for comprehensive development environment setup instructions. + ### Prerequisites -- Rust 1.70 or later -- SQLite3 +Choose your preferred development method: + +- **Local**: Rust 1.70 or later, SQLite3 +- **Docker**: Docker 20.10+ and Docker Compose +- **Nix**: Nix package manager with flakes enabled +- **Codespaces**: Just a GitHub account! ### Building ```bash +# Local cargo build + +# Docker +docker compose up --build + +# Nix +nix build ``` ### Running Tests @@ -122,6 +167,15 @@ cargo clippy -- -D warnings cargo fmt ``` +### Development Environments + +The project provides multiple development environment options: + +- **Docker Compose**: `docker compose up dev` - Containerized development with live code mounting +- **Nix Flakes**: `nix develop` - Reproducible environment with all dependencies +- **Devcontainer**: Open in VS Code or GitHub Codespaces - Fully configured IDE +- **Traditional**: Local Rust installation with cargo + ## Database The application uses SQLite for persistence. By default, it creates a `todo.db` file in the current directory. You can specify a different database path: @@ -140,9 +194,12 @@ For testing with in-memory database: The project includes comprehensive GitHub Actions workflows: -- **CI**: Build, test, lint, and format checks on multiple platforms -- **Security**: Weekly security audits with `cargo audit` -- **Release**: Automated binary releases for Linux, macOS, and Windows +- **CI** (`ci.yml`): Build, test, lint, and format checks on multiple platforms (Linux, macOS, Windows) +- **Security** (`security.yml`): Weekly security audits with `cargo audit` +- **Release** (`release.yml`): Automated binary releases for Linux, macOS, and Windows on version tags +- **Docker** (`docker.yml`): Docker image build testing and docker-compose validation + +All workflows run automatically on push and pull requests to ensure code quality and security. ## Contributing diff --git a/SETUP.md b/SETUP.md new file mode 100644 index 0000000..f02542f --- /dev/null +++ b/SETUP.md @@ -0,0 +1,455 @@ +# Setup Guide + +This guide will help you set up the development environment for template-rust using various methods. + +## Table of Contents + +- [Prerequisites](#prerequisites) +- [Quick Start](#quick-start) +- [Setup Methods](#setup-methods) + - [Local Development](#local-development) + - [Docker](#docker) + - [Docker Compose](#docker-compose) + - [Nix](#nix) + - [GitHub Codespaces / Devcontainer](#github-codespaces--devcontainer) +- [Building the Project](#building-the-project) +- [Running Tests](#running-tests) +- [Common Issues](#common-issues) + +## Prerequisites + +Choose one of the following setup methods based on your preference: + +- **Local Development**: Rust 1.70+, SQLite3 +- **Docker**: Docker 20.10+ and Docker Compose (optional) +- **Nix**: Nix package manager with flakes enabled +- **Codespaces**: GitHub account (no local setup required) + +## Quick Start + +The fastest way to get started depends on your environment: + +```bash +# Local development +cargo run -- --help + +# Docker +docker compose up + +# Nix (with flakes) +nix develop +cargo run + +# GitHub Codespaces +# Just open the repository in Codespaces - everything is preconfigured! +``` + +## Setup Methods + +### Local Development + +#### Installation + +1. **Install Rust** (if not already installed): + ```bash + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + source $HOME/.cargo/env + ``` + +2. **Install SQLite** (if not already installed): + + - **Ubuntu/Debian**: + ```bash + sudo apt-get update + sudo apt-get install sqlite3 libsqlite3-dev + ``` + + - **macOS**: + ```bash + brew install sqlite + ``` + + - **Windows**: + Download from [SQLite Download Page](https://www.sqlite.org/download.html) + +3. **Clone and build**: + ```bash + git clone https://github.com/pnstack/template-rust.git + cd template-rust + cargo build --release + ``` + +4. **Run the application**: + ```bash + cargo run -- --help + ``` + +#### Development Tools + +Install additional development tools: + +```bash +# Format checker +rustup component add rustfmt + +# Linter +rustup component add clippy + +# IDE support +rustup component add rust-analyzer +``` + +### Docker + +#### Building and Running + +1. **Build the Docker image**: + ```bash + docker build -t template-rust:latest . + ``` + +2. **Run the container**: + ```bash + # Run with help + docker run --rm template-rust:latest --help + + # Run TUI mode (interactive) + docker run --rm -it -v $(pwd)/data:/app/data template-rust:latest tui + + # Run CLI commands + docker run --rm -v $(pwd)/data:/app/data template-rust:latest list + ``` + +3. **Persist data**: + + The container stores data in `/app/data`. Mount a volume to persist data: + ```bash + mkdir -p data + docker run --rm -it -v $(pwd)/data:/app/data template-rust:latest tui + ``` + +### Docker Compose + +Docker Compose simplifies multi-service development and provides predefined configurations. + +#### Running with Docker Compose + +1. **Start the application**: + ```bash + docker compose up template-rust + ``` + +2. **Start in development mode**: + ```bash + # Development mode with live code mounting + docker compose up dev + ``` + +3. **Build and run**: + ```bash + docker compose up --build + ``` + +4. **Run in detached mode**: + ```bash + docker compose up -d + ``` + +5. **Stop services**: + ```bash + docker compose down + ``` + +#### Development Workflow + +The `dev` service in docker-compose.yml provides: +- Live code mounting for rapid development +- Cargo cache for faster builds +- Interactive terminal access + +```bash +# Enter development container +docker compose run --rm dev bash + +# Inside container +cargo build +cargo test +cargo run -- tui +``` + +### Nix + +Nix provides reproducible development environments across different systems. + +#### Using Nix Flakes (Recommended) + +1. **Enable flakes** (if not already enabled): + ```bash + mkdir -p ~/.config/nix + echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf + ``` + +2. **Enter development environment**: + ```bash + nix develop + ``` + + This provides: + - Rust toolchain with rust-analyzer + - All build dependencies + - Development tools + +3. **Build the project**: + ```bash + nix build + ``` + +4. **Run the application**: + ```bash + nix run + ``` + +#### Using Traditional Nix Shell + +If you prefer not to use flakes: + +```bash +nix-shell +``` + +This provides the same development environment using `shell.nix`. + +#### Direnv Integration (Optional) + +For automatic environment activation: + +1. **Install direnv**: + ```bash + # Via Nix + nix-env -iA nixpkgs.direnv + + # Via package manager + # Ubuntu/Debian: sudo apt install direnv + # macOS: brew install direnv + ``` + +2. **Configure direnv**: + ```bash + # Add to ~/.bashrc or ~/.zshrc + eval "$(direnv hook bash)" # or zsh + ``` + +3. **Create .envrc**: + ```bash + echo "use flake" > .envrc + direnv allow + ``` + +Now the environment activates automatically when you enter the directory! + +### GitHub Codespaces / Devcontainer + +The easiest way to get started with zero local setup. + +#### Using GitHub Codespaces + +1. **Open in Codespaces**: + - Navigate to the repository on GitHub + - Click "Code" → "Codespaces" → "Create codespace on main" + - Wait for the environment to build (first time only) + +2. **Start developing**: + - All tools are pre-installed + - VS Code with Rust extensions ready + - Project automatically builds on creation + +#### Using Local Devcontainer + +If you have Docker and VS Code locally: + +1. **Install prerequisites**: + - Docker Desktop + - VS Code + - "Dev Containers" extension for VS Code + +2. **Open in container**: + - Open the repository in VS Code + - Press `F1` → "Dev Containers: Reopen in Container" + - Wait for container to build + +3. **Start developing**: + - Integrated terminal has all tools + - Extensions auto-installed + - Same environment as Codespaces + +## Building the Project + +### Development Build + +```bash +cargo build +``` + +### Release Build (Optimized) + +```bash +cargo build --release +``` + +The binary will be in `target/release/template-rust`. + +### Checking Code Without Building + +```bash +cargo check +``` + +## Running Tests + +### All Tests + +```bash +cargo test +``` + +### Specific Test + +```bash +cargo test test_name +``` + +### With Output + +```bash +cargo test -- --nocapture +``` + +### Integration Tests Only + +```bash +cargo test --test integration_tests +``` + +## Code Quality + +### Format Code + +```bash +cargo fmt +``` + +### Check Formatting + +```bash +cargo fmt --check +``` + +### Run Linter + +```bash +cargo clippy +``` + +### Run Linter (Strict) + +```bash +cargo clippy -- -D warnings +``` + +## Common Issues + +### Issue: SQLite not found + +**Solution**: Install SQLite development libraries + +```bash +# Ubuntu/Debian +sudo apt-get install libsqlite3-dev + +# macOS +brew install sqlite + +# Nix +nix develop # Automatically provides SQLite +``` + +### Issue: OpenSSL not found + +**Solution**: Install OpenSSL development libraries + +```bash +# Ubuntu/Debian +sudo apt-get install libssl-dev pkg-config + +# macOS +brew install openssl +export PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig" + +# Nix +nix develop # Automatically provides OpenSSL +``` + +### Issue: Cargo is slow on first build + +**Solution**: This is normal - Cargo downloads and compiles all dependencies on first build. Subsequent builds are much faster due to caching. + +For Docker users, the multi-stage build and layer caching help reduce rebuild times. + +### Issue: Permission denied in Docker + +**Solution**: The container runs as non-root user. Ensure mounted volumes have appropriate permissions: + +```bash +mkdir -p data +chmod 777 data # Or use appropriate user/group ownership +``` + +### Issue: Database locked + +**Solution**: Close any other instances of the application accessing the same database file, or use a different database path: + +```bash +./template-rust --database another.db tui +``` + +## Environment Variables + +The application supports the following environment variables: + +- `DATABASE_URL`: Path to the SQLite database file (default: `todo.db`) +- `RUST_BACKTRACE`: Set to `1` or `full` for detailed error traces +- `RUST_LOG`: Set log level (e.g., `debug`, `info`, `warn`, `error`) + +Example: + +```bash +export DATABASE_URL=":memory:" # Use in-memory database +export RUST_BACKTRACE=1 # Enable backtraces +cargo run +``` + +## Next Steps + +After setting up your environment: + +1. Read the [README.md](README.md) for usage instructions +2. Explore the [examples/](examples/) directory +3. Check the [tests/](tests/) directory for test examples +4. Review the [CI/CD workflows](.github/workflows/) to understand the automation + +## Getting Help + +If you encounter issues: + +1. Check this guide's [Common Issues](#common-issues) section +2. Search existing [GitHub Issues](https://github.com/pnstack/template-rust/issues) +3. Open a new issue with: + - Your setup method (Local/Docker/Nix/Codespaces) + - Operating system and version + - Rust version (`rustc --version`) + - Complete error message + - Steps to reproduce + +## Contributing + +See [README.md](README.md#contributing) for contribution guidelines. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b547d2b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,46 @@ +services: + template-rust: + build: + context: . + dockerfile: Dockerfile + image: template-rust:latest + container_name: template-rust-app + volumes: + # Mount data directory for persistent storage + - ./data:/app/data + environment: + # Override database path if needed + - DATABASE_URL=/app/data/todo.db + # Uncomment if you add a web server + # ports: + # - "8080:8080" + stdin_open: true + tty: true + # Override entrypoint for interactive TUI mode + entrypoint: ["template-rust"] + command: ["tui"] + restart: unless-stopped + + # Development service with live code mounting + dev: + build: + context: . + dockerfile: Dockerfile + target: builder + image: template-rust:dev + container_name: template-rust-dev + volumes: + - .:/app + - cargo-cache:/usr/local/cargo/registry + - target-cache:/app/target + working_dir: /app + environment: + - DATABASE_URL=/app/todo.db + - RUST_BACKTRACE=1 + stdin_open: true + tty: true + command: ["cargo", "run", "--", "tui"] + +volumes: + cargo-cache: + target-cache: diff --git a/docs/CI-CD.md b/docs/CI-CD.md new file mode 100644 index 0000000..7e0556a --- /dev/null +++ b/docs/CI-CD.md @@ -0,0 +1,342 @@ +# CI/CD Documentation + +This document describes the Continuous Integration and Continuous Deployment (CI/CD) workflows configured for this project. + +## Overview + +The project uses GitHub Actions for automated testing, building, and releasing. All workflows are located in `.github/workflows/`. + +## Workflows + +### 1. CI Workflow (`ci.yml`) + +**Triggers:** +- Push to `main` branch +- Pull requests to `main` branch + +**Jobs:** + +#### Test +- Runs on: Ubuntu Latest +- Steps: + 1. Checkout code + 2. Install Rust stable + 3. Cache dependencies (Cargo registry, git, and target directory) + 4. Run `cargo test --verbose` + +#### Clippy (Linter) +- Runs on: Ubuntu Latest +- Steps: + 1. Checkout code + 2. Install Rust stable with clippy component + 3. Cache dependencies + 4. Run `cargo clippy -- -D warnings` (fails on any warnings) + +#### Rustfmt (Code Formatting) +- Runs on: Ubuntu Latest +- Steps: + 1. Checkout code + 2. Install Rust stable with rustfmt component + 3. Run `cargo fmt --all -- --check` (fails if code is not formatted) + +#### Build +- Runs on: Matrix of OS (Ubuntu, Windows, macOS) +- Steps: + 1. Checkout code + 2. Install Rust stable + 3. Cache dependencies + 4. Run `cargo build --verbose --release` + +**Purpose:** Ensures code quality, passes tests, follows formatting standards, and builds successfully on all target platforms. + +### 2. Security Workflow (`security.yml`) + +**Triggers:** +- Weekly schedule (Sunday at 00:00 UTC) +- Push to `main` branch +- Pull requests to `main` branch + +**Jobs:** + +#### Security Audit +- Runs on: Ubuntu Latest +- Steps: + 1. Checkout code + 2. Install Rust stable + 3. Install `cargo-audit` + 4. Cache dependencies + 5. Run `cargo audit` to check for security vulnerabilities in dependencies + +**Purpose:** Regularly scans dependencies for known security vulnerabilities and alerts on any issues. + +### 3. Release Workflow (`release.yml`) + +**Triggers:** +- Push of tags matching `v*.*.*` (e.g., `v0.1.0`, `v1.2.3`) + +**Jobs:** + +#### Build and Release +- Runs on: Matrix of OS and targets +- Targets: + - Linux: `x86_64-unknown-linux-gnu` + - Windows: `x86_64-pc-windows-msvc` + - macOS: `x86_64-apple-darwin` +- Steps: + 1. Checkout code + 2. Install Rust stable with target + 3. Cache dependencies (per target) + 4. Build release binary: `cargo build --release --target ` + 5. Upload artifact with platform-specific name + +#### Create Release +- Depends on: build-and-release +- Runs on: Ubuntu Latest +- Steps: + 1. Checkout code + 2. Download all artifacts + 3. Create GitHub release with: + - All platform binaries + - Auto-generated release notes + - Tag information + +**Purpose:** Automatically builds and publishes release binaries for all supported platforms when a version tag is pushed. + +**Usage:** +```bash +# Create a release +git tag -a v0.1.0 -m "Release version 0.1.0" +git push origin v0.1.0 + +# The workflow will automatically: +# 1. Build binaries for Linux, macOS, and Windows +# 2. Create a GitHub release +# 3. Upload binaries as release assets +``` + +### 4. Docker Workflow (`docker.yml`) + +**Triggers:** +- Push to `main` branch +- Pull requests to `main` branch + +**Jobs:** + +#### Docker Build Test +- Runs on: Ubuntu Latest +- Steps: + 1. Checkout code + 2. Set up Docker Buildx + 3. Build Docker image with cache + 4. Test Docker image (run help command) + +**Purpose:** Ensures Docker image builds successfully and can run basic commands. + +#### Docker Compose Validation +- Runs on: Ubuntu Latest +- Steps: + 1. Checkout code + 2. Validate `docker-compose.yml` syntax + +**Purpose:** Ensures docker-compose configuration is valid. + +## Caching Strategy + +All workflows use GitHub Actions caching to speed up builds: + +```yaml +path: | + ~/.cargo/registry + ~/.cargo/git + target +key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} +``` + +This caches: +- Cargo package registry +- Git repositories of dependencies +- Build artifacts + +The cache is invalidated when `Cargo.lock` changes (i.e., when dependencies are updated). + +## Branch Protection + +To ensure code quality, consider enabling branch protection rules for `main`: + +1. **Require pull request reviews**: At least 1 approval +2. **Require status checks**: All CI jobs must pass +3. **Require branches to be up to date**: Prevent merge conflicts +4. **Require linear history**: Keep history clean + +## Adding New Workflows + +### Example: Add a Coverage Workflow + +Create `.github/workflows/coverage.yml`: + +```yaml +name: Coverage + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + coverage: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Install tarpaulin + run: cargo install cargo-tarpaulin + + - name: Generate coverage + run: cargo tarpaulin --out Xml + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 + with: + files: ./cobertura.xml +``` + +## Best Practices + +### 1. Keep Workflows Fast +- Use caching extensively +- Run jobs in parallel when possible +- Use matrix builds for multiple platforms + +### 2. Fail Fast +- Use `-- -D warnings` for clippy to catch issues early +- Run format checks before heavy builds +- Use `--check` flags for validation-only steps + +### 3. Security +- Never commit secrets to workflows +- Use GitHub Secrets for sensitive data +- Regularly update dependencies with security patches +- Use `cargo audit` to catch vulnerabilities + +### 4. Versioning +- Use semantic versioning (SemVer) for releases +- Document breaking changes in release notes +- Test thoroughly before tagging releases + +### 5. Documentation +- Update release notes automatically +- Keep workflow documentation current +- Document any manual release steps + +## Troubleshooting + +### Build Failures + +**Problem:** Build fails on specific platform + +**Solution:** +1. Check the workflow logs for the specific error +2. Test locally on that platform if possible +3. Check for platform-specific dependencies +4. Review recent changes that might affect that platform + +### Cache Issues + +**Problem:** Builds are slower than expected + +**Solution:** +1. Check if cache is being hit (look for "Cache restored" in logs) +2. Verify cache key includes `Cargo.lock` hash +3. Clear cache if corrupted (manually delete in GitHub UI) + +### Release Failures + +**Problem:** Release workflow fails to create release + +**Solution:** +1. Verify tag follows `v*.*.*` format +2. Check `GITHUB_TOKEN` permissions +3. Ensure all build jobs completed successfully +4. Verify artifact names match expected patterns + +### Security Audit Failures + +**Problem:** `cargo audit` finds vulnerabilities + +**Solution:** +1. Review the security advisory +2. Update affected dependencies: `cargo update` +3. If no fix available, consider: + - Finding alternative dependency + - Waiting for upstream fix + - Documenting known issue + +## Monitoring + +### Workflow Status + +Monitor workflow runs: +- GitHub repository → Actions tab +- View logs for failed runs +- Check timing to optimize performance + +### Notifications + +Enable notifications for: +- Failed workflow runs on main branch +- Security vulnerabilities +- Failed releases + +Configure in: GitHub Settings → Notifications + +## Local Testing + +Before pushing, test locally: + +```bash +# Run all checks +make all + +# Or individually +cargo fmt --check +cargo clippy -- -D warnings +cargo test +cargo build --release + +# Test Docker +docker build -t template-rust:test . +docker run --rm template-rust:test --help + +# Validate docker-compose +docker compose config +``` + +## Future Improvements + +Consider adding: + +1. **Code Coverage**: Track test coverage with codecov or coveralls +2. **Benchmarking**: Automated performance regression testing +3. **Deploy to Registry**: Publish Docker images to GitHub Container Registry +4. **Nightly Builds**: Test against Rust nightly to catch future issues +5. **Dependency Updates**: Automated PRs for dependency updates (Dependabot) +6. **Documentation Deployment**: Auto-deploy docs to GitHub Pages + +## Resources + +- [GitHub Actions Documentation](https://docs.github.com/en/actions) +- [Rust CI/CD Guide](https://doc.rust-lang.org/cargo/guide/continuous-integration.html) +- [Actions for Rust](https://github.com/actions-rs) +- [Semantic Versioning](https://semver.org/) + +## Questions or Issues + +If you have questions about the CI/CD setup: +1. Check this documentation +2. Review workflow files in `.github/workflows/` +3. Check workflow run logs for details +4. Open an issue for discussion diff --git a/docs/QUICK-START.md b/docs/QUICK-START.md new file mode 100644 index 0000000..3cbbb10 --- /dev/null +++ b/docs/QUICK-START.md @@ -0,0 +1,215 @@ +# Quick Start Guide + +Choose your preferred development method and get started in minutes! + +## 🚀 Fastest Methods + +### GitHub Codespaces (Zero Setup!) +1. Click "Code" → "Codespaces" → "Create codespace on main" +2. Wait ~2 minutes for setup +3. Start coding! + +**Best for:** Trying the project, contributing without local setup + +--- + +### Docker Compose (Simple) +```bash +git clone https://github.com/pnstack/template-rust.git +cd template-rust +docker compose up +``` + +**Best for:** Quick testing, isolated environments + +--- + +### Nix (Reproducible) +```bash +git clone https://github.com/pnstack/template-rust.git +cd template-rust +nix develop +cargo run +``` + +**Best for:** Guaranteed reproducible builds, NixOS users + +--- + +### Local Development (Traditional) +```bash +# Install Rust +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + +# Clone and build +git clone https://github.com/pnstack/template-rust.git +cd template-rust +cargo build --release +``` + +**Best for:** Full control, native performance + +--- + +## 📋 Common Commands + +### Using Make (Recommended) +```bash +make help # Show all available commands +make build # Build debug version +make test # Run tests +make clippy # Run linter +make fmt # Format code +make all # Format, lint, test, and build +``` + +### Using Cargo +```bash +cargo build # Debug build +cargo build --release # Optimized build +cargo test # Run tests +cargo clippy -- -D warnings # Lint +cargo fmt # Format +``` + +### Using Docker +```bash +docker build -t template-rust . # Build image +docker run --rm template-rust --help # Show help +docker run --rm -it template-rust tui # Interactive TUI +``` + +### Using Docker Compose +```bash +docker compose up # Start app +docker compose up dev # Development mode +docker compose down # Stop services +``` + +--- + +## 🎯 First Steps After Setup + +1. **Run the application:** + ```bash + cargo run -- --help + ``` + +2. **Try the TUI:** + ```bash + cargo run -- tui + ``` + +3. **Add a todo:** + ```bash + cargo run -- add "My first task" + ``` + +4. **List todos:** + ```bash + cargo run -- list + ``` + +5. **Run tests:** + ```bash + cargo test + ``` + +--- + +## 🔍 Need More Details? + +- **Full setup instructions:** [SETUP.md](../SETUP.md) +- **Usage examples:** [README.md](../README.md) +- **CI/CD info:** [CI-CD.md](CI-CD.md) + +--- + +## ❓ Troubleshooting + +### "SQLite not found" +```bash +# Ubuntu/Debian +sudo apt-get install libsqlite3-dev + +# macOS +brew install sqlite + +# Nix/Codespaces - Already included! +``` + +### "OpenSSL not found" +```bash +# Ubuntu/Debian +sudo apt-get install libssl-dev pkg-config + +# macOS +brew install openssl + +# Nix/Codespaces - Already included! +``` + +### "Slow first build" +This is normal! Cargo compiles all dependencies on first build. +Subsequent builds are much faster (seconds instead of minutes). + +### Docker permission issues +```bash +# Create data directory with proper permissions +mkdir -p data +chmod 777 data +``` + +--- + +## 🎓 Learning Resources + +### Rust Basics +- [The Rust Book](https://doc.rust-lang.org/book/) +- [Rust by Example](https://doc.rust-lang.org/rust-by-example/) + +### Project-Specific +- Explore [src/](../src/) for code organization +- Check [tests/](../tests/) for testing examples +- Read [examples/](../examples/) for usage patterns + +### Development Tools +- [Cargo Book](https://doc.rust-lang.org/cargo/) +- [Clippy Lints](https://rust-lang.github.io/rust-clippy/) +- [Rustfmt Configuration](https://rust-lang.github.io/rustfmt/) + +--- + +## 💡 Tips + +1. **Use rust-analyzer**: Best IDE support for Rust +2. **Run clippy often**: Catches bugs early +3. **Format before commit**: `cargo fmt` or `make fmt` +4. **Test frequently**: `cargo test` or `make test` +5. **Use `--release` for production**: Much faster + +--- + +## 🤝 Contributing + +Ready to contribute? + +1. Fork the repository +2. Create a branch: `git checkout -b feature/my-feature` +3. Make changes +4. Test: `make all` +5. Commit: `git commit -m "Add feature"` +6. Push: `git push origin feature/my-feature` +7. Open a Pull Request + +--- + +## 📞 Getting Help + +- 📖 Read the [full docs](../README.md) +- 🐛 [Open an issue](https://github.com/pnstack/template-rust/issues) +- 💬 Check [existing issues](https://github.com/pnstack/template-rust/issues?q=is%3Aissue) + +--- + +**Happy coding! 🦀** diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..43ce105 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,94 @@ +# Documentation + +Welcome to the template-rust documentation! + +## 📚 Available Documentation + +### Getting Started +- **[Quick Start Guide](QUICK-START.md)** - Get up and running in minutes with your preferred method + +### Setup & Configuration +- **[Setup Guide](../SETUP.md)** - Comprehensive setup instructions for all environments + - Local development + - Docker & Docker Compose + - Nix & Nix Flakes + - GitHub Codespaces & Devcontainer + +### Development +- **[CI/CD Documentation](CI-CD.md)** - Complete guide to our GitHub Actions workflows + - CI workflow (build, test, lint) + - Security auditing + - Release automation + - Docker builds + +### Usage +- **[Main README](../README.md)** - Project overview, features, and usage examples + +## 🎯 Quick Links + +### For Contributors +1. [QUICK-START.md](QUICK-START.md) - Choose your setup method +2. [../SETUP.md](../SETUP.md) - Detailed environment setup +3. [CI-CD.md](CI-CD.md) - Understand our automated workflows + +### For Users +1. [../README.md](../README.md) - Learn how to use the application +2. [QUICK-START.md](QUICK-START.md) - Quick reference for common tasks + +### For Maintainers +1. [CI-CD.md](CI-CD.md) - Managing workflows and releases +2. [../SETUP.md](../SETUP.md) - Supporting different development environments + +## 🔧 Configuration Files Reference + +### Docker +- `/Dockerfile` - Multi-stage Docker build +- `/docker-compose.yml` - Development and production services +- `/.dockerignore` - Build optimization + +### Nix +- `/flake.nix` - Nix flakes configuration +- `/shell.nix` - Traditional Nix shell +- `/.envrc` - Direnv integration + +### Development Environment +- `/.devcontainer/devcontainer.json` - VS Code devcontainer config +- `/Makefile` - Common development commands + +### CI/CD +- `/.github/workflows/ci.yml` - Build, test, lint +- `/.github/workflows/security.yml` - Security audits +- `/.github/workflows/release.yml` - Automated releases +- `/.github/workflows/docker.yml` - Docker builds + +## 📖 Documentation Standards + +When contributing documentation: + +1. **Be Clear**: Use simple language and examples +2. **Be Concise**: Respect the reader's time +3. **Be Complete**: Cover edge cases and troubleshooting +4. **Use Examples**: Show, don't just tell +5. **Keep Updated**: Update docs when code changes + +## 🤝 Contributing to Docs + +Found an issue or want to improve the documentation? + +1. Check if there's an [existing issue](https://github.com/pnstack/template-rust/issues) +2. Open a new issue describing the problem +3. Submit a PR with improvements + +Good documentation helps everyone! 🎉 + +## 📞 Questions? + +If you can't find what you're looking for: + +1. Check all documentation files listed above +2. Search [existing issues](https://github.com/pnstack/template-rust/issues) +3. Open a [new issue](https://github.com/pnstack/template-rust/issues/new) with your question + +--- + +**Thank you for reading! 🦀** diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..3807ffd --- /dev/null +++ b/flake.nix @@ -0,0 +1,87 @@ +{ + description = "Template Rust - A Rust template with todo app example"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + rust-overlay.url = "github:oxalica/rust-overlay"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, rust-overlay, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let + overlays = [ (import rust-overlay) ]; + pkgs = import nixpkgs { + inherit system overlays; + }; + + rustToolchain = pkgs.rust-bin.stable.latest.default.override { + extensions = [ "rust-src" "rust-analyzer" ]; + }; + + nativeBuildInputs = with pkgs; [ + rustToolchain + pkg-config + ]; + + buildInputs = with pkgs; [ + openssl + sqlite + ] ++ lib.optionals stdenv.isDarwin [ + darwin.apple_sdk.frameworks.Security + darwin.apple_sdk.frameworks.SystemConfiguration + ]; + + in + { + # Development shell + devShells.default = pkgs.mkShell { + inherit buildInputs nativeBuildInputs; + + shellHook = '' + echo "🦀 Rust development environment" + echo "Rust version: $(rustc --version)" + echo "" + echo "Available commands:" + echo " cargo build - Build the project" + echo " cargo test - Run tests" + echo " cargo run - Run the application" + echo " cargo clippy - Run linter" + echo " cargo fmt - Format code" + echo "" + ''; + + # Environment variables + RUST_BACKTRACE = "1"; + DATABASE_URL = "todo.db"; + }; + + # Package definition + packages.default = pkgs.rustPlatform.buildRustPackage { + pname = "template-rust"; + version = "0.1.0"; + + src = ./.; + + cargoLock = { + lockFile = ./Cargo.lock; + }; + + inherit nativeBuildInputs buildInputs; + + meta = with pkgs.lib; { + description = "A Rust template with todo app example using SQLite and TUI"; + homepage = "https://github.com/pnstack/template-rust"; + license = with licenses; [ mit asl20 ]; + maintainers = [ ]; + }; + }; + + # App definition for easy running + apps.default = { + type = "app"; + program = "${self.packages.${system}.default}/bin/template-rust"; + }; + } + ); +} diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..3638b23 --- /dev/null +++ b/shell.nix @@ -0,0 +1,36 @@ +{ pkgs ? import { } }: + +pkgs.mkShell { + buildInputs = with pkgs; [ + # Rust toolchain + rustc + cargo + rustfmt + rust-analyzer + clippy + + # Build dependencies + pkg-config + openssl + sqlite + + # Additional development tools + git + ] ++ lib.optionals stdenv.isDarwin [ + # macOS specific dependencies + darwin.apple_sdk.frameworks.Security + darwin.apple_sdk.frameworks.SystemConfiguration + ]; + + shellHook = '' + echo "🦀 Rust development environment (shell.nix)" + echo "Rust version: $(rustc --version)" + echo "" + echo "To use flakes instead, run: nix develop" + echo "" + ''; + + # Environment variables + RUST_BACKTRACE = "1"; + DATABASE_URL = "todo.db"; +}