Unified CLI tool for automating merge workflows across Git platforms.
The product solves the same workflow for different providers: Gitea, GitHub, and GitLab, with the ability to add any other providers. The connection process is described in the section "Add A New Provider In Code (Simple)".
Main flow:
- Push the current feature branch to remote.
- Wait for CI/checks for that branch SHA.
- Find an existing PR/MR or create a new one into the target branch.
- Wait until the PR/MR is ready for merge.
- Merge PR/MR.
- Wait for CI/checks on the main branch after merge.
- In watch mode, wait for a new local branch (except main) and repeat the cycle.
If a stage fails for a specific branch, the error is logged, and in watch mode the app continues monitoring next branches. Stop the app with Ctrl+C.
In case of errors persist in flow, recommended usge extended logging for better understanding situation (parameter "log_mode": "extended" in config.json)
- Unified CLI interface for
gitea,github,gitlab. - Unified model for CI/check status processing.
- Continuous watch mode: process new branches until Ctrl+C.
- Dry-run mode for safe flow verification without merge.
- Strict-status mode where success requires explicit CI checks.
- Colored console logs and file logs in
logs/app.log.
- Python 3.12+
uvfor dependency and environment management- Local git repository with a valid
remote - Provider token with permissions to read statuses and merge PR/MR
Install dependencies:
python -m pip install --upgrade pip
python -m pip install uv[all] --upgrade
uv syncBy default, runtime configuration is loaded from config.json in the repository root.
Example configuration:
{
"provider": "gitea",
"base_url": "http://hppiigit:3000",
"repo_path": "C:/Prog/hyper",
"remote": "origin",
"main_branch": "main",
"poll_interval": 10,
"branch_scan_interval": 5,
"timeout_seconds": 1800,
"merge_style": "merge",
"pr_title_prefix": "Auto merge",
"log_mode": "extended",
"dry_run": false,
"watch_branches": true,
"show_check_details": true,
"strict_status": false
}Fields:
provider:gitea,github,gitlabbase_url: provider API base URLowner,repo: repository coordinates (optional) : if not set, the app will try to auto-detect them fromgit remoteinsiderepo_path.repo_path: local repository pathmain_branch: name of the main branch (not required to bemain)merge_style: merge strategy (provider-dependent)log_mode: logging mode (basicorextended)watch_branches: continuous mode until Ctrl+Cbranch_scan_interval: local branch scan interval
You can pass --token directly or use an environment variable.
- Gitea:
GITEA_TOKEN - GitHub:
GITHUB_TOKEN - GitLab:
GITLAB_TOKEN
Examples:
$env:GITEA_TOKEN = "your-token"
uv run python gitea.py --provider gitea --base-url http://hppiigit:3000$env:GITHUB_TOKEN = "your-token"
uv run python gitea.py --provider github --base-url https://api.github.com$env:GITLAB_TOKEN = "your-token"
uv run python gitea.py --provider gitlab --base-url https://gitlab.comYes, you can connect different providers.
For already supported providers (Gitea, GitHub, GitLab), the process is simple:
- Select provider in
config.json:
{
"provider": "github",
"base_url": "https://api.github.com"
}- Set token in an environment variable:
$env:GITHUB_TOKEN = "your-token"- Run the CLI:
uv run python gitea.pyIf needed, pass the same parameters via CLI:
uv run python gitea.py --provider github --base-url https://api.github.com --token your-tokenMinimum required parameters:
providerbase_url- token (
--tokenor provider env variable)
Show all options:
uv run python gitea.py --helpImportant:
--providerselects provider API implementation.--base-urlsets the provider endpoint.--gitea-urlis a compatibility alias for--base-url.--main-branchsets the main branch.--log-modeswitches logging mode (basic/extended).--watch-branchesenables continuous branch monitoring.--no-watch-branchesruns a one-shot cycle for current branch.
If you need a provider that is not supported yet, add it in 4 short steps.
- Create a new adapter class in src/gitea_automation/providers.py implementing
ScmProvider. - Implement 7 methods: commit statuses, PR/MR search, PR/MR create, PR/MR get, readiness, merge, branch SHA.
- Register the adapter in
create_providerfactory in src/gitea_automation/providers.py. - Add provider name to
--providerchoices in src/gitea_automation/cli.py and document token env var in README.
After that, user flow stays the same: provider + base_url + token.
Dry-run does not merge and does not create a new PR/MR.
In this mode:
- Push feature branch.
- Check CI/checks for pushed SHA.
- Search for existing open PR/MR.
Run:
uv run python gitea.py --dry-runBy default, the app runs in watch mode:
- Processes current branch if it is not main.
- Switches to local branch monitoring.
- Automatically starts full workflow when a new branch appears (except main).
- Does not exit after PR/MR and keeps running until Ctrl+C.
Examples:
uv run python gitea.pyuv run python gitea.py --main-branch develop --branch-scan-interval 3One-shot run (without watching):
uv run python gitea.py --no-watch-branches--strict-status requires at least one explicit check/status.
If provider returns success but checks are missing, execution fails.
Run:
uv run python gitea.py --strict-statusDisable:
uv run python gitea.py --no-strict-statusuv run pytest
uv run ruff check .
uv run mypy .extended(default): full diagnostics with detailed technical information.basic: only key events and errors without detailed HTTP diagnostics.- Configure via
log_modefield inconfig.jsonor CLI--log-mode.
Examples:
{
"log_mode": "basic"
}uv run python gitea.py --log-mode basic