Skip to main content

git-epic

A Python CLI for our epic-based Git workflow, with no runtime Python dependencies. Git discovers the git-epic executable automatically, so commands use git epic ….

Install

Requires Python 3.11+, Git 2.31+, and glab. Authenticate once with your GitLab host:

glab auth login --hostname gitlab.wonderbeauties.com

After the first PyPI release, install with pipx:

pipx install git-epic
pipx ensurepath
git epic -h

For local development before publication:

pipx install .
pipx ensurepath
git epic -h

If ensurepath changes your PATH, open a new terminal. Upgrade with pipx upgrade git-epic. The package is not yet published; pipx install . works from a local checkout today.

Commands

Use git epic -h for CLI help. Git reserves git epic --help for a system manual page; this MVP does not install one. Direct invocation also supports git-epic --help.

Command Behavior
git epic init Write shared .git-epic.json; defaults to production, origin, and GitLab.
git epic start <name> Fetch production; create and switch to local epic/<name>.
git epic task start <name> From an epic, fetch and fast-forward remote epic changes if possible; create task/<epic>/<name>.
git epic task submit Push committed task changes; create or return its parent epic MR. Publish the local parent epic if it is not yet on the remote.
git epic sync From an epic, fetch and merge production. Push the result yourself or with release.
git epic status Fetch; show current task/epic, labelled local/remote epic drift, related open MRs (including task MRs when on an epic), and their latest reported CI status.
git epic release Push committed epic changes; create or return an MR targeting production. Never merges or deploys.

GitLab calls PRs merge requests (MRs). Submission commands also push new commits when returning an existing MR; they do not create a duplicate.

Names are single segments: letters, numbers, dots, underscores, and hyphens, starting with a letter or number. Git's branch-name restrictions also apply.

For repositories using a different production branch or remote:

git epic init --production main --remote origin
git add .git-epic.json
git commit -m "Configure git-epic"
git push

Commit this file on production before creating epics so all branches and teammates inherit it. It contains no credentials. Existing configuration is never overwritten; edit the file to change settings. An initial production commit must already exist on the remote; init does not bootstrap an empty application repository.

Typical workflow

git epic start checkout
git epic task start payment
# Implement and commit your task.
git epic task submit
# Review, CI, and merge the task MR in GitLab.
git switch epic/checkout
# Bring merged tasks into the local epic.
git fetch origin
git merge --ff-only origin/epic/checkout
git epic sync
git push origin epic/checkout
# Deploy OTF and obtain QA approval through the existing team process.
git epic release
# Review, required CI, and merge in GitLab; CI/CD deploys production.

OTF deployment and QA approval are external to this CLI. Approval belongs to an exact commit/build. If the candidate or production changes, update and revalidate before merging. release refuses an epic that is behind current production, but the hosting platform/CI must also enforce release checks at merge time. The CLI does not record or verify QA approval.

Git behavior

  • Branch and submission operations require a clean working tree and no unfinished merge/rebase/cherry-pick/revert. status allows uncommitted changes.
  • Fetch updates remote-tracking refs. No command force-pushes, resets, deletes a branch, merges an MR, or deploys.
  • start creates a local epic. Submission publishes branches with ordinary pushes; non-fast-forward pushes are rejected rather than overwriting teammates' work.
  • task start stops if local and remote epic histories have diverged. Reconcile the epic using Git before retrying. release similarly requires your local epic to include remote epic work before a push can succeed.
  • If sync conflicts, resolve and commit, or use git merge --abort.
  • An MR/API failure after a push leaves the branch published; retry the command.
  • GitLab authentication is managed by glab, and Git authentication by Git.

Development and release

python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e '.[dev]'
ruff check .
ruff format --check .
python -m unittest discover -s tests -v
python -m build
python -m twine check --strict dist/*.whl dist/*.tar.gz

Tests create temporary local Git repositories and a fake glab; they never create real MRs or touch production. GitLab API behavior is delegated to the installed glab. CI checks Python 3.11 and 3.14, builds a wheel and source distribution, validates metadata with Twine, and smoke-tests the installed wheel via Git.

Publish to PyPI

Local publication helper

From a clean, committed checkout with a configured Git upstream, run:

./publish.sh

The helper uses uv to prompt for a PEP 440 version (press Enter to keep the current version for the first release), update the version and README release-tag examples, run tests, clean and build distributions, validate with Twine, upload to PyPI, and commit/push the release changes. Set PYPI_API_TOKEN or TWINE_PASSWORD in your shell; otherwise Twine prompts for authentication. It does not create a release tag or trigger the CI publication job.

GitLab CI publication

The distribution name is git-epic, import package is git_epic, and CLI entry point is git-epic. Version is defined once in src/git_epic/__init__.py.

  1. Create a PyPI account and an API token. For the first release, a token with account scope is needed; after creating the project, use a project-scoped token.
  2. In GitLab CI/CD variables, add PYPI_API_TOKEN as a masked, protected variable. Protect the release tag pattern (v*) so tagged jobs can access it.
  3. Update the version, then push a matching tag, for example v0.1.0.
  4. After verification and build jobs pass, manually run publish:pypi.

The job uploads only the validated wheel and source distribution from the build job. A release tag must match the package version. PyPI does not allow reusing an uploaded version: use a new version for subsequent releases.

An optional publish:testpypi job uses TESTPYPI_API_TOKEN and the separate TestPyPI registry. TestPyPI accounts and tokens are independent of PyPI. A test installation uses pipx install --index-url https://test.pypi.org/simple/ git-epic.

For a manual upload of locally built, validated distributions:

export TWINE_USERNAME=__token__
# Set TWINE_PASSWORD to your PyPI API token in your shell.
python -m twine upload --non-interactive dist/*.whl dist/*.tar.gz

Credentials are supplied by the shell or CI, never stored in project files. PyPI Trusted Publishing currently supports GitLab.com, not this self-managed GitLab host, so the release jobs use API tokens. Package-name availability is determined by PyPI at upload time. A public PyPI release includes the source code even when the GitLab repository is private.

Metadata

Release files for git-epic 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for git-epic 0.1.0
File Size Uploaded
git_epic-0.1.0.tar.gz 20.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for git-epic 0.1.0
File Interpreter ABI Platform
git_epic-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 32.5 kB

Release files / git_epic-0.1.0.tar.gz

Download URL git_epic-0.1.0.tar.gz
Size 20.1 kB
Tags Source
SHA-256 checksum
How to use checksums
628162de276db2f96129bfe09cec3a552da2ee95d2b27f11548220dbeeca3fe5
BLAKE2b-256 checksum
How to use checksums
77f80b472f9e98d93705d6eb9ed2dd8ad02d97f22d02c0f2b71bf7a8ddbb351a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.14

Release files / git_epic-0.1.0-py3-none-any.whl

Download URL git_epic-0.1.0-py3-none-any.whl
Size 12.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
80629c6b8d4080658a92d562f6e76a5b748fab7e79036eb9cf51301f65c350c4
BLAKE2b-256 checksum
How to use checksums
57078183e27c2055159535741213ed0e8cf25bedf96b279a97150beb6363a5c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.14

Release history Release notifications | RSS feed

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page