6.6 KiB
Contributing to Asepharyana Hub
Table of Contents
- Prerequisites
- Local Setup
- Development Workflow
- Project Structure
- Coding Standards
- Commit Message Format
- Pull Request Process
- Adding a New Service
Prerequisites
- Git with LFS support
- Node.js >= 22.11.0 (via
.node-versionor.nvmrc) - Bun >= 1.3.11 (package manager)
- Rust >= 1.89.0 (for Rust services)
- Docker and Docker Compose (for shared infrastructure)
Local Setup
1. Clone the Repository
git clone https://github.com/asepharyana/asepharyana-hub.git
cd asepharyana-hub
2. Initialize Submodules
This hub repo uses Git submodules for all application services:
git submodule update --init --recursive
This checks out all submodules at the pinned commit (not main). The submodules and their remotes are:
| Path | Remote |
|---|---|
apps/elysia |
asepharyana/asepharyana-hub-elysia |
apps/scraper |
asepharyana/asepharyana-hub-scraper |
apps/react |
asepharyana/asepharyana-hub-react |
apps/rust-auth |
asepharyana/asepharyana-hub-rust-auth |
3. Install Dependencies per Service
Install dependencies for TypeScript/Bun services:
cd apps/elysia && bun install && cd ../..
cd apps/react && npm install && cd ../..
4. Start Shared Infrastructure
Start shared services (Redis) via Docker Compose:
docker compose -f infra/compose/shared.yml up -d
5. Configure Environment
Copy the example environment file and adjust as needed:
cp .env.example .env
Key variables to configure:
| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection (Tailscale IP to imrnes VPS) |
REDIS_URL |
Redis connection (redis://localhost:6379 for local) |
JWT_SECRET |
JWT signing secret |
GITHUB_TOKEN |
GitHub personal access token |
Development Workflow
Running Services
Rust API (rust-auth):
cd apps/rust-auth
cargo run
Elysia API (elysia):
cd apps/elysia
bun run dev
React Frontend (react):
cd apps/react
npm run dev
API Documentation
- Rust OpenAPI:
http://localhost:4091/docs - Elysia Swagger:
http://localhost:4092/docs - Elysia AsyncAPI:
http://localhost:4092/docs-ws
Coding Standards
Linting
- ESLint with
@antfu/eslint-configfor TypeScript/JavaScript - Cargo Clippy for Rust
Run linting:
# TypeScript/JavaScript
eslint . --no-error-on-unmatched-pattern
# Rust specific
cd apps/rust-auth && cargo clippy -- -D warnings
Formatting
- Prettier for TypeScript/JavaScript/Markdown (config in
.prettierrc)- Single quotes, 100 print width, 2-space indent, trailing commas
- Cargo fmt for Rust
- EditorConfig for general formatting (
.editorconfig)
# Prettier
prettier --write .
# Rust
cd apps/rust-auth && cargo fmt
Rust Configuration
Rust services use edition 2024 with stable toolchain (nightly features may be used).
Commit Message Format
This project enforces Conventional Commits for all commit messages.
Format
<type>(<scope>): <description>
[optional body]
[optional footer]
Types
| Type | Usage |
|---|---|
feat |
A new feature |
fix |
A bug fix |
chore |
Maintenance, config, tooling changes |
docs |
Documentation only changes |
refactor |
Code change that neither fixes a bug nor adds a feature |
test |
Adding or updating tests |
ci |
CI/CD configuration and scripts |
style |
Formatting, missing semicolons, etc. (no production change) |
perf |
Performance improvement |
Examples
feat(rust-auth): add OAuth2 Google login flow
fix(elysia): handle null JWT payload in auth middleware
chore: update eslint config to v10
docs: add API endpoint documentation for scraper
refactor(react): extract Header component from App
test(elysia): add unit tests for rate limiter
ci: migrate to CodeQL v3
Scopes
Common scopes: rust-auth, elysia, react, scraper, infra, ci, deps
Pull Request Process
-
Create a branch from
mainwith a descriptive name:feat/my-featurefix/issue-descriptionchore/update-config
-
Make your changes following the coding standards above.
-
Run checks locally before pushing:
cd apps/react && npx tsc --noEmit eslint . --no-error-on-unmatched-pattern -
Push and open a PR against
main. CI will automatically run:- Lint — ESLint across changed TypeScript files
- TypeCheck — TypeScript compilation check
- Security — CodeQL analysis (weekly schedule + PRs)
-
Docker Build Pipeline triggers on pushes to
mainwhenapps/**changes:- Detects which services changed
- Builds Docker images for only those services
- Pushes to GHCR with
latestandsha-<short>tags - Updates compose manifests to use the new SHA tags
-
Deployment Pipeline triggers after a successful Docker build:
- SSHes into the VPS (
orange, Tailscale IP100.96.248.86) - Pulls updated Docker images
- Recreates only the changed containers
- All services share the
app-shared-netDocker network
- SSHes into the VPS (
-
Merge after CI passes and you have at least one approval (if applicable). Use squash merge to keep history clean.
Adding a New Service
See docs/add-new-app.md for the complete step-by-step guide. In summary:
- Create the app in
apps/<name> - Add it as a Git submodule in
.gitmodules - Register it in
infra/compose/<name>.yml - Add a Dockerfile at
infra/docker/<name>.Dockerfile - Add Traefik routing config in
infra/traefik/dynamic/apps.yaml - Add CI entries in
.github/workflows/docker-build-push.yml - Add compose file to the deploy script in
deploy-docker.yml - Add any required GitHub secrets for the service