Repository navigation
Development
wildfirebill edited this page Jul 20, 2026
·
1 revision
Guide for building, testing, and contributing to hub2lab.
- Node.js ≥ 20
- npm
- Git
git clone https://github.com/wildfirebill-docker/hub2lab.git
cd hub2lab
npm install| 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) |
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
tsconfig.json targets Node.js 22 with:
- Target: ES2022
- Module: NodeNext
- Strict mode enabled
- Output to
dist/directory
| 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 |
| Package | Purpose |
|---|---|
typescript |
TypeScript compiler |
tsx |
TypeScript execution with hot-reload |
@types/express |
Express type definitions |
@types/node |
Node.js type definitions |
- 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
npm run buildThe compiled output goes to dist/. Run it with:
npm startcp .env.example .env
cp mapping.example.json mapping.jsonEdit .env with your development tokens.
npm run devcurl http://localhost:3000/healthngrok http 3000Copy the ngrok URL and configure it in GitHub/GitLab webhook settings.
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- Fork the repository
- Create a feature branch:
git checkout -b feat/my-feature - Make your changes
- Ensure
npm run lintpasses (no type errors) - Ensure
npm run buildsucceeds - Commit with a descriptive message
- Push and open a Pull Request
Use conventional commits:
feat: add support for GitLab merge request eventsfix: handle empty commit list on tag pushesdocs: update mapping guidechore: bump dependenciesrefactor: extract mirror logic to separate module