don't leave crumbs in the woods
Project description
Ansel
Ansel is a minimalistic CLI tool designed to manage boilerplate and shared configuration across multiple git repositories.
https://github.com/user-attachments/assets/8e95268e-8aa7-4742-b7f6-b8d08ec183e2
It declaratively propagates updates and removes manual friction by automating the full workflow: cloning repos locally, applying templates, executing hooks on a new branch, committing, pushing, and opening the PR page in your browser.
Why?
Have you ever had to update a github action workflow across 20 repositories? Or 200?
Or maybe you needed to add a couple of new files to all your microservices, but each one needs to be filled with different variables?
I do, and it's a nightmare of copy-pasting, manual PRs, and the constant fear of missing one repository. Or even worse, a bunch of ad hoc scripts, one per each use case.
That's why I built Ansel for my needs, and I will be happy if it can save you from the same pain.
Core Features
- Template propagation: render and sync jinja2 templates (new and existing)
- Variable substitution: use variables in templates and patches, values can also be defined dynamically with a command
- Structural patching: update yaml and toml files (or generic regex) while preserving comments and indentation (hopefully XD)
- Hooks: run custom scripts or built-ins (like pre-commit) per repository inside the repo context
Check all the options and features in the complete example here.
Installation
- With pip:
pip install ansel-cli
- With Nix:
nix run github:brokenpip3/ansel/0.2.2
Quick Start
Create an ansel.yaml where you want to execute the synchronization, for example:
general:
commit_message: "chore(ansel): update {{ template_name }} in {{ repo_name }}"
repositories:
- brokenpip3/* # automatically find all repos in the brokenpip3 github org
- other-org/other-repo # specific repo, set the url, group, default branch and more
templates:
- .github/dependabot.yml # just render and sync the template inside the templates dir
- fix-nix-install: # more complex patch with variables and operations
type: patch
include: [".github/workflows/*.y*ml"]
vars:
foobar: "hello world"
# start any var with !cmd to execute a command and use the output as the variable:
nix_install_new_ver_hash: "!cmd git ls-remote https://github.com/NixOS/nix-installer-action|head -n 1|awk '{print $1}'"
operations:
- engine: yaml
where:
uses: "DeterminateSystems/nix-installer-action*"
update:
uses: "NixOS/nix-installer-action@{{ nix_install_new_ver_hash }}"
- engine: yaml
where:
uses: "DeterminateSystems/magic-nix-cache-action@*"
delete: true # delete the step if it exists
Run the synchronization:
ansel sync
Usage
ansel sync: automated propagation to all matched repositoriesansel sync --dry-run: Preview changes without making any modificationsansel sync --plan: interactive mode to review and confirm each changeansel builtins: list available hooks and template variablesansel repos: overview of configured repositoriesansel templates: overview of configured templates and patches
Notes
-
This project does not use any github token env because the author believes that any software that requires a permanent gh token is probably a bad software (strong words from an old man - cit). The gh repos are scanned via the public api and since there is no other way to also scan the private repos, the tool will use
gh(ifgh_cliis set true) with this flow:gh auth statusgh login- <scanning, patching, syncing, cooking, painting>
gh logout(don't worry, if you are already logged in 'cause you use gh all the time, it will not log you out)
-
This project was built with the assistance of an llm. Every line of code was meticulously reviewed, tested, and approved by a human who is now questioning their life choices. No robots were harmed during development, though several were forced to explain yaml indentation logic until they questioned their own existence.
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 ansel_cli-0.2.2.tar.gz.
File metadata
- Download URL: ansel_cli-0.2.2.tar.gz
- Upload date:
- Size: 21.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3817dc481c32d238ff8bd2cee25d336e5171e392dd1a00396efb813b543c450b
|
|
| MD5 |
4c7707903128229ee1548245f90188d4
|
|
| BLAKE2b-256 |
6f64b76bbb9b82e41d0e41a9032f2f97c1525c9a26950f5a5b235808321dc10c
|
Provenance
The following attestation bundles were made for ansel_cli-0.2.2.tar.gz:
Publisher:
publish.yaml on brokenpip3/ansel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ansel_cli-0.2.2.tar.gz -
Subject digest:
3817dc481c32d238ff8bd2cee25d336e5171e392dd1a00396efb813b543c450b - Sigstore transparency entry: 1194384051
- Sigstore integration time:
-
Permalink:
brokenpip3/ansel@0344ec691f0ee692acb3b858efc23dc92094bbe7 -
Branch / Tag:
refs/tags/0.2.2 - Owner: https://github.com/brokenpip3
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@0344ec691f0ee692acb3b858efc23dc92094bbe7 -
Trigger Event:
release
-
Statement type:
File details
Details for the file ansel_cli-0.2.2-py3-none-any.whl.
File metadata
- Download URL: ansel_cli-0.2.2-py3-none-any.whl
- Upload date:
- Size: 27.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
420a2c5607cc27613a0f4bc8d945ec9b15baaf64396725e2e99bddf5896f290a
|
|
| MD5 |
54be84b00b70fc866f8be78a45feb185
|
|
| BLAKE2b-256 |
dc79e1629132dcbc2218c5d0ae9fe00f084eb37db716c815a9c1bfd170c5e92b
|
Provenance
The following attestation bundles were made for ansel_cli-0.2.2-py3-none-any.whl:
Publisher:
publish.yaml on brokenpip3/ansel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ansel_cli-0.2.2-py3-none-any.whl -
Subject digest:
420a2c5607cc27613a0f4bc8d945ec9b15baaf64396725e2e99bddf5896f290a - Sigstore transparency entry: 1194384124
- Sigstore integration time:
-
Permalink:
brokenpip3/ansel@0344ec691f0ee692acb3b858efc23dc92094bbe7 -
Branch / Tag:
refs/tags/0.2.2 - Owner: https://github.com/brokenpip3
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@0344ec691f0ee692acb3b858efc23dc92094bbe7 -
Trigger Event:
release
-
Statement type: