Script-driven code changes with automated merge requests
Project description
repoactive - Script-driven code changes with automated merge requests
Warning: This project is in an early stage of development. Use at your own risk.
repoactive runs your scripts against a git repository and keeps the
corresponding merge requests up to date. You write the scripts that produce
the code changes; repoactive handles the rest - branches, commits, and the
full MR lifecycle.
How it works
You configure one or more jobs, each with a script (any shell command or
executable) that modifies the repository's working tree. repoactive runs
each script, captures the resulting diff, and then:
- opens a new merge request if one does not already exist for that job, or
- updates the existing merge request branch if the diff has changed.
Branches and MR descriptions are managed automatically - the only code you need to write is the script that produces the change.
[your script] → diff → repoactive → branch → git push → merge request
↑
(create or update)
repoactivecreates a new commit on top of the base branch or on top of other repoactive managed branches.- It runs the job's script against the working tree.
- If the script produced a diff, it pushes the branch and creates or updates the merge request.
- If the script produced no diff, the branch is reset to the base and pushed without opening or updating an MR.
Use cases
- Keeping generated files (API clients, protobuf bindings, lock files) in sync with their sources
- Applying organization-wide refactors or policy changes across many repositories
- Automating any periodic code transformation that should go through a review process
Configuration
repoactive is configured via .repoactive.toml in the repository root (or
passed via --config).
[job-defaults]
# Prefix prepended to job.name to form the branch name
branch_prefix = "repoactive/"
# Prefix prepended to every MR/PR title (set to "" to disable)
mr_title_prefix = "[repoactive] "
# Prefix prepended to every commit title (set to "" to disable)
commit_title_prefix = "[repoactive] "
# Labels applied to every MR/PR unless overridden per job
labels = ["repoactive"]
[[job]]
# Unique identifier - branch name is always <branch_prefix><name>
name = "regenerate-api-client"
# Script run in the repo working directory; non-zero exit = failure
command = "python scripts/regen_api.py"
# MR/PR title
title = "api: regenerate API client"
# Optional: MR description
description = "Automated regeneration of the API client from the OpenAPI spec."
# Optional: extra labels (merged with job-defaults.labels)
labels = ["automated", "api"]
# Optional: target branch (default: repo default branch)
base_branch = "main"
# Optional: open the MR/PR as a draft (default: false)
draft = false
# Optional: create an MR/PR for this job (default: true). Set to false to
# push the branch without opening an MR/PR.
create_mr = true
# Optional: append the job's command and its output to the commit message
# (default: true). Set to false to keep the commit message clean.
output_in_commit = true
[[job]]
name = "sync-license-headers"
command = "./scripts/add_license_headers.sh"
title = "sync license headers"
[[job]]
name = "integration-tests-update"
command = "./scripts/update_integration_tests.py"
title = "tests: update integration tests"
# Optional: run this job on top of the merged output of the listed jobs
depends_on = ["regenerate-api-client", "sync-license-headers"]
For public GitHub.com or GitLab.com repositories no platform declaration is
needed — repoactive detects the remote URL automatically. To use a
self-hosted instance, add a [[platform]] section:
[[platform]]
# Base URL of the platform instance
url = "https://gitlab.example.com"
# Name of the env var holding the API token
token_env = "GITLAB_TOKEN"
# type must be either "github" or "gitlab"
type = "gitlab"
The branch for each job is always job-defaults.branch_prefix + job.name.
Secrets are kept out of the config file by referencing environment variable
names rather than inline values.
When depends_on is set, repoactive starts the job's script from a
working tree that has all listed dependency branches merged together, rather
than from the plain base branch. The resulting MR branch will therefore
include both the dependency jobs and the new job on top. Links to the parent
MRs are automatically added to the MR description.
Usage
# Print the installed version and exit
repoactive --version
repoactive run [OPTIONS] [JOBS]...
Run all configured jobs (or a named subset - dependencies are auto-included):
# Run all jobs
repoactive run
# Run specific jobs
repoactive run regenerate-api-client sync-license-headers
# Run jobs locally without pushing branches or creating MRs
repoactive run --local
# Enable debug logging
repoactive run --debug
| Option | Short | Description |
|---|---|---|
--config PATH |
-c |
Config file (default: .repoactive.toml) |
--repo PATH |
-r |
jj repository path (default: .) |
--local |
Skip pushing branches and MR creation | |
--debug |
-d |
Enable debug logging |
Validating configuration
repoactive validate-config [OPTIONS]
Check that a config file is syntactically and semantically valid without running any jobs:
# Validate the default .repoactive.toml
repoactive validate-config
# Validate a specific config file
repoactive validate-config --config myconfig.toml
# Validate a merged config (same merging rules as `run`)
repoactive validate-config --config base.toml --config override.toml
On success the command prints Config OK: N job(s) defined. and exits with
code 0. On failure it prints the validation error to stderr and exits with
code 1.
Validation checks include unknown keys, missing required fields, invalid
depends_on references, and circular job dependencies.
| Option | Short | Description |
|---|---|---|
--config PATH |
-c |
Config file (default: .repoactive.toml); repeat to merge |
Requirements
- Python 3.11 or later
- jj (Jujutsu) -
repoactiveuses jj to manage branches and commits in the target repository - A GitLab or GitHub API token exposed via the environment variable named in
platform.token_env
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file repoactive-0.0.4.tar.gz.
File metadata
- Download URL: repoactive-0.0.4.tar.gz
- Upload date:
- Size: 22.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b71e4831f85b1a7a6777558323d1800d0cb5460a2367b21a5973c3897542d7a
|
|
| MD5 |
9b40bdd68b3b945e6e745495f746ccc0
|
|
| BLAKE2b-256 |
6e8c350af9688b10c41819256e22f7b6ffb9b84a7b6ab40aa9e74abb6d1ee6fa
|
Provenance
The following attestation bundles were made for repoactive-0.0.4.tar.gz:
Publisher:
publish.yml on schmir/repoactive
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
repoactive-0.0.4.tar.gz -
Subject digest:
6b71e4831f85b1a7a6777558323d1800d0cb5460a2367b21a5973c3897542d7a - Sigstore transparency entry: 1784731224
- Sigstore integration time:
-
Permalink:
schmir/repoactive@f2b047a5f1a429a26733a9a277c1fcd47258e194 -
Branch / Tag:
refs/tags/v0.0.4 - Owner: https://github.com/schmir
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f2b047a5f1a429a26733a9a277c1fcd47258e194 -
Trigger Event:
push
-
Statement type:
File details
Details for the file repoactive-0.0.4-py3-none-any.whl.
File metadata
- Download URL: repoactive-0.0.4-py3-none-any.whl
- Upload date:
- Size: 26.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4e2429cd47f97d1200c22341917b82266bf36eab74df85674c78b34f001cbdb
|
|
| MD5 |
c9b45343a394874a01ede203b514ba92
|
|
| BLAKE2b-256 |
f9d9689cd52ba02a73f31ec5f48763bebd2811c9ba20293a55810b4b99184ce0
|
Provenance
The following attestation bundles were made for repoactive-0.0.4-py3-none-any.whl:
Publisher:
publish.yml on schmir/repoactive
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
repoactive-0.0.4-py3-none-any.whl -
Subject digest:
f4e2429cd47f97d1200c22341917b82266bf36eab74df85674c78b34f001cbdb - Sigstore transparency entry: 1784731437
- Sigstore integration time:
-
Permalink:
schmir/repoactive@f2b047a5f1a429a26733a9a277c1fcd47258e194 -
Branch / Tag:
refs/tags/v0.0.4 - Owner: https://github.com/schmir
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f2b047a5f1a429a26733a9a277c1fcd47258e194 -
Trigger Event:
push
-
Statement type: