Thanks for your interest in contributing to GitProxy! This guide covers everything you need to get a local development environment running, understand the codebase, and submit high-quality pull requests.
For project governance, roles, and voting procedures, see the Governance section on the website.
- Prerequisites
- Getting Started
- Project Structure
- Development Workflow
- Testing
- Code Quality
- Configuration Schema
- Submitting a Pull Request
- Community
We actively support and test against the latest two LTS Node versions, currently 22 and 24. When a new LTS version rolls out (26, 28, etc.), we deprecate the oldest one.
| Tool | Version | Notes |
|---|---|---|
| Node.js | 22.13.1+, or 24.0.0+ | Check with node -v |
| npm | 8+ | Bundled with Node.js |
| Git | Any recent version | Must support HTTP/S |
| Docker & Docker Compose | Any recent version | Required for E2E tests only |
# Fork on GitHub, then clone your fork
git clone https://github.com/<your-username>/git-proxy.git
cd git-proxynpm installThis installs all dependencies for the server, UI, and CLI workspace packages. Husky git hooks are configured automatically via the prepare script.
# Run both the proxy server and the dashboard UI (recommended for development)
npm startThis starts two processes concurrently:
| Process | Command | URL | Description |
|---|---|---|---|
| Proxy server | npm run server |
http://localhost:8000 (proxy) / http://localhost:8080 (API) |
Express server handling git operations |
| Dashboard UI | npm run client |
http://localhost:3000 |
Vite dev server with hot module replacement |
You can also run them independently:
npm run server # Proxy server only
npm run client # Vite UI dev server only# Clone a repo through GitProxy
git clone http://localhost:8000/octocat/Hello-World.gitBy default, GitProxy blocks all pushes. To allow pushes for a specific repo, add it to proxy.config.json. See the Configuration docs for details.
git-proxy/
├── src/
│ ├── proxy/ # Core proxy logic (action chain, processors)
│ ├── service/ # Express app, API routes, authentication (Passport.js)
│ ├── db/ # Database abstraction (MongoDB + NeDB)
│ ├── config/ # Configuration loading and generated types
│ ├── ui/ # React dashboard (Material-UI)
│ ├── plugin.ts # Plugin base classes (PushActionPlugin, PullActionPlugin)
│ └── types/ # Shared TypeScript types
├── test/ # Unit and integration tests (Vitest)
├── tests/e2e/ # End-to-end tests (Vitest + Docker)
├── cypress/ # UI tests (Cypress)
├── localgit/ # Local git server for E2E testing (see localgit/README.md)
├── packages/
│ └── git-proxy-cli/ # CLI package
├── plugins/ # Sample plugin packages
├── website/ # Documentation site (Docusaurus)
├── index.ts # CLI entry point
├── docker-compose.yml # Docker Compose for E2E environment
├── proxy.config.json # Default proxy configuration
├── config.schema.json # JSON Schema for configuration
├── vite.config.ts # Frontend build configuration
├── vitest.config.ts # Unit test configuration
└── vitest.config.e2e.ts # E2E test configuration
- Action chain: Git push/fetch requests flow through a chain of processors in
src/proxy/chain.ts - Plugin system: Extends the action chain with custom logic (see
src/plugin.ts) - Dual database: MongoDB for production state; NeDB for local file-based development (
.data/directory) - Authentication: Passport.js strategies (local, Active Directory, OpenID Connect)
npm run build # Full build: generate config types, build UI, compile TypeScript
npm run build-ts # Compile TypeScript server code to dist/
npm run build-ui # Build React frontend with Vite to build/npm run check-types # Type check everything (server + UI)
npm run check-types:server # Type check server code only (faster)Husky runs the following hooks automatically:
- pre-commit:
lint-stagedruns Prettier on staged files - commit-msg:
@commitlint/clienforces Conventional Commits format
Commit message examples:
feat: add new OIDC authentication strategy
fix: resolve race condition in push processor
docs: update testing guide with Vitest examples
test: add fuzz tests for repo name validation
To understand when your contribution will get merged upstream and published to NPM, see our Releases guide.
GitProxy has three test suites, each serving a different purpose.
Unit and integration tests use Vitest and are located in the test/ directory. These do not require Docker.
npm test # Run all unit tests once
npm run test-watch # Watch mode (re-runs on file changes)
npm run test-shuffle # Randomized execution order (detects test coupling)
npm run test-coverage # Run with coverage reportConfiguration: vitest.config.ts
Test files are organized by module:
test/
├── processors/ # Proxy processor logic
├── db/ # Database operations
├── services/ # API and service tests
├── integration/ # Cross-module integration tests
├── plugin/ # Plugin system tests
├── preReceive/ # Git hook tests
└── fixtures/ # Binary test data for protocol-level tests
Some tests require a real MongoDB instance. These are guarded by the RUN_MONGO_TESTS environment variable and run separately from unit tests.
# Start MongoDB with Docker
docker run -d --name mongodb-test -p 27017:27017 mongo:7
# Run MongoDB integration tests
RUN_MONGO_TESTS=true npm run test:integration
# Cleanup
docker stop mongodb-test && docker rm mongodb-testConfiguration: vitest.config.integration.ts
In CI, RUN_MONGO_TESTS is set automatically in the workflow that runs integration tests.
E2E tests perform real git operations against a Dockerized environment. They use Vitest with a separate config.
Prerequisites: Docker and Docker Compose must be running.
# Run E2E tests (builds containers, runs tests, tears down)
npm run test:e2e
# Watch mode for E2E development
npm run test:e2e:watchConfiguration: vitest.config.e2e.ts
The E2E environment is defined in docker-compose.yml and consists of three services:
| Service | Port | Description |
|---|---|---|
git-proxy |
8000, 8081 | GitProxy application under test |
mongodb |
27017 | MongoDB 7 instance |
git-server |
8443 | Apache-based git HTTP server with test repos (see localgit/) |
All services run in an isolated git-network Docker bridge network.
When developing or debugging E2E tests, you'll often want to keep the containers running between test runs rather than letting the test script tear them down:
# Start all services in the background
docker compose up -d
# Verify all three containers are running
docker compose ps
# Rebuild from scratch (e.g., after changing localgit/ or Dockerfile)
docker compose down -v
docker compose build --no-cache
docker compose up -dThe git server is initialized with two test repos:
| Repository | Path |
|---|---|
test-owner/test-repo.git |
Simple test repo with a README and text file |
e2e-org/sample-repo.git |
Sample project with a README, package.json, and LICENSE |
Two users are pre-configured:
| Username | Password | Purpose |
|---|---|---|
admin |
admin123 |
Full access to all repos |
testuser |
user123 |
Standard user for testing |
# Clone directly from the git server
git clone http://admin:admin123@localhost:8443/test-owner/test-repo.git
# Clone through GitProxy
git clone http://admin:admin123@localhost:8000/test-owner/test-repo.git
# Push a change
cd test-repo
echo "test" > test.txt
git add test.txt
git commit -m "test commit"
git push origin maindocker compose logs -f git-proxy # GitProxy application logs
docker compose logs -f git-server # Apache git server logs
docker compose logs -f mongodb # MongoDB logsIf services won't start or tests fail unexpectedly:
# Check service status
docker compose ps
# View logs for the failing service
docker compose logs git-server
# Nuclear option: tear down everything and rebuild
docker compose down -v
docker compose build --no-cache
docker compose up -dIf MongoDB connections fail:
docker compose exec mongodb mongosh --eval "db.adminCommand('ping')"The git server includes a data capture system that records raw git protocol data for every operation. This is useful for creating binary test fixtures (e.g., PACK files) for unit tests. See localgit/README.md for details on the capture system, PACK extraction tools, and fixture generation workflow.
Cypress tests exercise the dashboard UI end-to-end.
# Start the app first
npm start
# Then, in another terminal:
npm run cypress:open # Interactive test runner (recommended for development)
npm run cypress:run # Headless mode (used in CI)Configuration: cypress.config.js
Cypress tests live in cypress/e2e/ and use custom commands defined in cypress/support/commands.js (e.g., cy.login(username, password)).
Some test files include fuzz tests using fast-check to find edge-case bugs with randomized inputs. These run as part of the regular unit test suite (npm test).
All new code introduced in a PR must have over 80% patch coverage. This is enforced by CodeCov in CI.
# Generate a local coverage report
npm run test-coverageThe coverage report is written to ./coverage/. If your PR is below the threshold, check the CodeCov report on your PR for uncovered lines.
npm run lint # Run ESLint
npm run lint:fix # ESLint with auto-fix
npm run format # Format all files with Prettier
npm run format:check # Check formatting without modifying filesCI runs ESLint, Prettier, and TypeScript type checks on every PR (see .github/workflows/lint.yml).
GitProxy uses a JSON Schema (config.schema.json) to define and validate configuration. When adding or modifying config properties:
- Update
config.schema.jsonwith the new/changed properties - Regenerate TypeScript types:
npm run generate-config-types
- Regenerate the schema reference documentation for the website:
# Requires Python and json-schema-for-humans: # pip install json-schema-for-humans npm run gen-schema-doc
- Check for existing issues: Search open issues before starting work. If none exists, create one describing the change.
- Fork & branch: Create a feature branch from
main(e.g.,feat/my-featureorfix/my-bugfix). - Make your changes: Follow the code style enforced by ESLint and Prettier. Write tests for new functionality.
- Verify locally:
npm run check-types:server # Type check npm test # Unit tests npm run lint # Lint npm run format:check # Formatting
- Commit using Conventional Commits: The commit-msg hook validates this automatically.
- Push & open a PR: Target the
mainbranch. Fill in the PR template and link the relevant issue.
The following checks must pass before a PR can be merged:
- Unit tests: Run across a matrix of the latest 2 Node.js (22, 24) and MongoDB (6.0, 7.0, 8.0) versions on Ubuntu, plus a Windows build
- E2E tests: Docker-based end-to-end tests
- Cypress tests: UI end-to-end tests
- Lint & format: ESLint, Prettier, TypeScript type checks
- Commit lint: Conventional Commits validation
- Coverage: 80%+ patch coverage via CodeCov
- Security: CodeQL analysis, dependency review, OpenSSF Scorecard
All contributors must have a CLA on file with FINOS before PRs can be merged. Review the FINOS contribution requirements and submit the required CLA.
- Slack: #git-proxy on the FINOS Slack workspace
- Mailing list: git-proxy+subscribe@lists.finos.org
- Community meetings: Fortnightly on Mondays at 4PM BST (odd week numbers) via Zoom. Add to Google Calendar.
- Issues: github.com/finos/git-proxy/issues