Development workflow
Maintaining a2c-pre-commit-hooks as a shared Python + pre-commit hook repository.
Branches
| Branch | Role |
|---|---|
develop | Day-to-day commits and merge requests |
master | Stable branch — fast-forwarded from develop when ready |
Setup
git clone git@gitlab-ai:libesys/ai-workflows/a2c-pre-commit-hooks.git
cd a2c-pre-commit-hooks
git checkout develop
./scripts/setup-dev.sh
Windows (PowerShell):
.\scripts\setup-dev.ps1
The setup scripts install editable dev + validate extras (including a2c-cli from PyPI),
register pre-commit hooks, and on Windows run scripts/fix-git-ssl.ps1 first so Git HTTPS
(pre-commit hook downloads) uses the Windows certificate store.
Manual setup
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\Activate.ps1
pip install -e ".[dev,validate]"
pre-commit install
pre-commit install --hook-type merge-commit
Windows Git HTTPS / SSL
On Windows, setup-dev.ps1 runs scripts/fix-git-ssl.ps1 first so pre-commit can download hook
repos from GitHub. If HTTPS Git fails elsewhere, run that script once:
.\scripts\fix-git-ssl.ps1
Common cause: a stale global http.sslcainfo pointing at a deleted project venv
certifi/cacert.pem. The fix sets http.sslBackend=schannel (Windows certificate store) and
removes that override. Do not point global Git SSL settings at per-project venv paths.
Local checks
# Lint (same as CI pre-commit job — ruff hooks)
pre-commit run --all-files
# Unit + integration tests (integration requires a2c-cli from .[validate])
pytest -q
# Integration only
pytest -q -m integration
# Release version check (before tagging)
python scripts/verify_release_version.py v0.2.0
# Dogfood check-changelog on staged files
pre-commit run check-changelog
Note: CI installs .[dev,validate] and runs all tests, including integration
tests that call real a2c validate via the hook and the a2c console script. The
unit job publishes coverage parsed from pytest output (see Coverage badge
below).
Coverage badge
Coverage comes from the unit job (coverage: '/TOTAL.*\s+(\d+%)$/' in .gitlab-ci.yml).
Configure a project badge on master using GitLab supported
placeholders so the URL stays portable
across forks and group-level reuse.
Settings → General → Badges → Add badge
| Field | Value |
|---|---|
| Name | Coverage |
| Link | https://gitlab.com/%{project_path}/-/commits/master |
| Badge image URL | https://gitlab.com/%{project_path}/badges/master/coverage.svg |
On a self-hosted GitLab instance, replace https://gitlab.com with your instance URL (or use
%{gitlab_server} only for non-hostname parts — see GitLab docs).
Placeholders used:
| Placeholder | Role |
|---|---|
%{project_path} | Full project path (libesys/ai-workflows/a2c-pre-commit-hooks) |
master | Stable branch (literal ref name — not a placeholder) |
Other useful placeholders for badges on this project:
| Placeholder | Example use |
|---|---|
%{default_branch} | Use instead of master if the GitLab default branch changes |
%{commit_sha} | Link to a specific commit on the default branch |
%{latest_tag} | Latest release tag in custom badge URLs |
Pipeline status badge (optional, same pattern on master):
| Field | Value |
|---|---|
| Name | Pipeline |
| Link | https://gitlab.com/%{project_path}/-/commits/master |
| Badge image URL | https://gitlab.com/%{project_path}/badges/master/pipeline.svg |
The badge shows coverage from the latest successful pipeline on master where the unit
job reported a percentage. If the badge is empty, confirm master has a green pipeline and inspect
the unit job log for a TOTAL … XX% line from pytest-cov.
For markdown outside GitLab badge settings (e.g. this repo's README.md), use resolved URLs:
[](https://gitlab.com/libesys/ai-workflows/a2c-pre-commit-hooks/-/commits/master)
[](https://gitlab.com/libesys/ai-workflows/a2c-pre-commit-hooks/-/commits/master)
Commit conventions
Use Conventional Commits where practical:
feat(hooks): ...— new hook or behaviorfix(check-changelog): ...— bug fixdocs: ...— documentationchore(release): ...— release bump commits frombump_release.py
This repository dogfoods check-changelog: stage CHANGELOG.md when you stage other files.
Project structure
src/a2c_pre_commit_hooks/
├── __init__.py # __version__
├── git_staging.py # Git index helpers (mockable in tests)
├── check_changelog.py # Pure validation logic
└── hooks/
└── check_changelog.py # CLI entry point (pre-commit entry)
Keep hook logic separate from CLI and git I/O so tests stay fast and deterministic.
CI overview
| Job | Stage | Purpose |
|---|---|---|
pre-commit | lint | .pre-commit-config.yaml on all files (git installed when missing) |
unit | test | pytest with coverage |
release:verify | release | Tag pipelines only — version match + hook smoke |
Tag pipelines — see release-pipeline.md.
Adding a new hook
See adding-hooks.md.
Landing on master
When develop is green:
git checkout master
git pull origin master
git merge --ff-only origin/develop
git push origin master