This document explains how deployments to our VPS infrastructure work across all repositories. It is intended to help contributors understand our branching model, CI/CD pipeline, and repository setup process.
Most of our repositories use two primary branches:
- develop
- master
The develop branch contains ongoing development work and changes that are not yet released to production.
In some repositories, this branch may automatically deploy to a testing or staging environment. For example in TJ-Bot, changes pushed to develop are deployed to a testing server.
This branch should be considered unstable and under active development.
The master branch contains production-ready code that is currently deployed to live environments.
When changes are ready for release:
masteris rebased fromdevelop- Production deployment is triggered after the update
We use Woodpecker CI on our VPS as our continuous integration and deployment engine.
Woodpecker is configured to trigger when changes are merged into either:
developmaster
The behavior depends on repository-specific configuration located in .woodpecker.yml which is stored in the root of each repository.
By design, our Woodpecker pipelines are intentionally minimal and only handle deployment tasks. Typically, pipelines:
- Build container images using Gradle’s jib task
- Push images to our container registry
- Notify Watchtower to restart containers with updated images
We allow multiple GitHub teams to have write access to our repositories. This improves contributor experience by allowing pull requests without requiring repository forks.
However, this model introduces security risks.
If GitHub Actions were used for deployments:
- Any contributor with write access could potentially create or modify workflows
- A malicious or compromised account could expose repository secrets (e.g. registry credentials or Watchtower tokens)
- This could allow attackers to:
- Push malicious container images
- Execute remote code
- Compromise infrastructure
While we trust our contributors, we design our systems with compromise scenarios in mind.
Woodpecker CI was chosen because:
- Secrets are stored and executed outside GitHub
- It reduces attack surface from pull request workflows
- Migration from GitHub Actions was straightforward
- The project is actively maintained and responsive to security issues
- It requires minimal operational overhead
Follow these steps to enable deployments for a repository.
Requirements:
- You must be an organization administrator (Moderator)
Steps:
- Visit: https://woodpecker.togetherjava.org/repos
- Click "Add repository"
- Locate the repository
- Click "Enable"
After enabling the repository, configure required secrets such as:
- Watchtower token
- Docker registry username
- Docker registry password
- Any repository-specific credentials
Secrets are managed inside Woodpecker, not inside GitHub.
Create a .woodpecker.yml file in the repository root directory.
This file defines:
- Build steps
- Image publishing
- Deployment triggers
- Environment-specific behaviour
Pipeline configuration may vary depending on repository requirements.