Skip to main content

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|shell github:brokenpip3/ansel

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 repositories
  • ansel sync --dry-run: Preview changes without making any modifications
  • ansel sync --plan: interactive mode to review and confirm each change
  • ansel builtins: list available hooks and template variables
  • ansel repos: overview of configured repositories
  • ansel 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 (if gh_cli is set true) with this flow:

    • gh auth status
    • gh 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ansel_cli-0.2.1.tar.gz (21.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ansel_cli-0.2.1-py3-none-any.whl (27.5 kB view details)

Uploaded Python 3

File details

Details for the file ansel_cli-0.2.1.tar.gz.

File metadata

  • Download URL: ansel_cli-0.2.1.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

Hashes for ansel_cli-0.2.1.tar.gz
Algorithm Hash digest
SHA256 2a318828020be7c7025766c51e5da36bbd9f8a6451a24add5efc0fc45664e805
MD5 9eec9ec0b16d1d132f6796235d9a77d2
BLAKE2b-256 36d7c6c2f2388db8117533287b7c2a193bc8ac9bda9c056cc649072c5c699024

See more details on using hashes here.

Provenance

The following attestation bundles were made for ansel_cli-0.2.1.tar.gz:

Publisher: publish.yaml on brokenpip3/ansel

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ansel_cli-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: ansel_cli-0.2.1-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

Hashes for ansel_cli-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 19641c5219c190b61e290a4cfb0990aec392b563b5a99ab25d9118d114e56266
MD5 fa875cb1eaaaacd1197fd67c316892e4
BLAKE2b-256 b04f035226ed32e46584b4d50be4d88de80c813dda83ef8919dd8b82b8619290

See more details on using hashes here.

Provenance

The following attestation bundles were made for ansel_cli-0.2.1-py3-none-any.whl:

Publisher: publish.yaml on brokenpip3/ansel

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page