Skip to content

Development

wildfirebill edited this page Jul 20, 2026 · 1 revision

Development

Guide for building, testing, and contributing to hub2lab.

Prerequisites

  • Node.js ≥ 20
  • npm
  • Git

Setup

git clone https://github.com/wildfirebill-docker/hub2lab.git
cd hub2lab
npm install

Available Scripts

Command Description
npm run build Compile TypeScript → dist/ using tsc
npm start Run the compiled output from dist/
npm run dev Run with hot-reload using tsx watch
npm run lint Type-check without emitting files (tsc --noEmit)

Project Structure

src/
├── index.ts              # Express server entry point
├── types.ts              # Shared type definitions
├── config/
│   ├── index.ts          # Config loader (env vars + mapping file)
│   ├── logger.ts         # Winston logger setup
│   └── mapper.ts         # Org/group ↔ repo resolution
├── github/
│   ├── client.ts         # GitHub API helpers via Octokit
│   └── webhook.ts        # GitHub signature verification & event parsing
├── gitlab/
│   ├── client.ts         # GitLab API helpers via @gitbeaker/rest
│   └── webhook.ts        # GitLab token verification & event parsing
├── handlers/
│   ├── github.ts         # Webhook handlers for GitHub events
│   └── gitlab.ts         # Webhook handlers for GitLab events
└── sync/
    ├── engine.ts         # Event routing dispatcher
    ├── mirror.ts         # Git mirror-based push via simple-git
    └── deletion.ts       # Deletion marker file builders

TypeScript Configuration

tsconfig.json targets Node.js 22 with:

  • Target: ES2022
  • Module: NodeNext
  • Strict mode enabled
  • Output to dist/ directory

Dependencies

Production

Package Purpose
express HTTP server framework
octokit GitHub API client
@gitbeaker/rest GitLab API client
simple-git Local git operations (mirror clone/push)
axios HTTP client (used internally by API libraries)
dotenv Environment variable loading
winston Logging with file rotation

Development

Package Purpose
typescript TypeScript compiler
tsx TypeScript execution with hot-reload
@types/express Express type definitions
@types/node Node.js type definitions

Code Conventions

  • TypeScript strict mode — always use proper types
  • Async/await — all async operations use async/await (no raw promises or callbacks)
  • Logger — use the shared Winston logger instead of console.log
  • Imports — use ESM-style imports (the project uses "module": "NodeNext")
  • Error handling — all webhook handlers wrap async operations in try/catch

Building

npm run build

The compiled output goes to dist/. Run it with:

npm start

Local Testing

1. Set up test config

cp .env.example .env
cp mapping.example.json mapping.json

Edit .env with your development tokens.

2. Start the server

npm run dev

3. Test the health endpoint

curl http://localhost:3000/health

4. Use ngrok for webhook testing

ngrok http 3000

Copy the ngrok URL and configure it in GitHub/GitLab webhook settings.

Docker Build (Local)

docker build -t hub2lab:dev .
docker run -d \
  --name hub2lab-dev \
  -p 3000:3000 \
  -v $(pwd)/.env:/app/.env \
  -v $(pwd)/mapping.json:/app/mapping.json \
  hub2lab:dev

Contribution Workflow

  1. Fork the repository
  2. Create a feature branch: git checkout -b feat/my-feature
  3. Make your changes
  4. Ensure npm run lint passes (no type errors)
  5. Ensure npm run build succeeds
  6. Commit with a descriptive message
  7. Push and open a Pull Request

Commit Conventions

Use conventional commits:

  • feat: add support for GitLab merge request events
  • fix: handle empty commit list on tag pushes
  • docs: update mapping guide
  • chore: bump dependencies
  • refactor: extract mirror logic to separate module

Clone this wiki locally