Le Change
Fast Git change detection with deploy matrix generation.
Rust core library with a CLI binary, GitHub Action, and Python bindings.
Features
- Diff two commits and list changed files by type (added, modified, deleted, renamed)
- Glob pattern filtering and exclusion
- Dynamic group discovery via
files_group_bytemplates (e.g.stacks/{group}/**) - Deploy matrix JSON output for GitHub Actions
strategy.matrix - Workflow failure tracking with per-run or per-job granularity
- Concurrent workflow detection with deadlock-safe priority ordering
- Ancestor directory file association for monorepo layouts
- Vanished-file detection: files added then removed within a PR (invisible to endpoint diffs) surface as
action: destroymatrix entries with the commit to reconstruct them from - Static musl binaries for Linux (zero runtime dependencies)
GitHub Action
jobs:
detect:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.changes.outputs.matrix }}
has_changes: ${{ steps.changes.outputs.has_changes }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: lituus-io/le-change@v1
id: changes
with:
files: 'stacks/**/*.yaml'
files_group_by: 'stacks/{group}/**'
deploy:
needs: detect
if: needs.detect.outputs.has_changes == 'true'
strategy:
matrix: ${{ fromJson(needs.detect.outputs.matrix) }}
runs-on: ubuntu-latest
steps:
- run: echo "Deploying ${{ matrix.stack }}"
Action Inputs
| Input | Default | Description |
|---|---|---|
files |
Glob patterns to include (comma-separated) | |
files_ignore |
Glob patterns to exclude | |
files_group_by |
Group discovery template (e.g. stacks/{group}/**) |
|
files_group_by_key |
name |
Group key mode: name, path, or hash |
files_ancestor_lookup_depth |
0 |
Ancestor directory lookup depth (max 3) |
track_workflow_failures |
false |
Enable workflow failure tracking |
failure_tracking_level |
run |
Tracking granularity: run or job |
wait_for_active_workflows |
false |
Wait for concurrent overlapping workflows |
workflow_max_wait_seconds |
300 |
Max wait time in seconds |
workflow_name_filter |
Glob pattern to filter workflow names | |
deploy_matrix_include_reason |
false |
Add action/reason to matrix entries |
deploy_matrix_include_concurrency |
false |
Add concurrency info to matrix entries |
detect_vanished |
false |
Detect files added then removed within the PR history (needs fetch-depth: 0) |
vanished_max_commits |
500 |
Max commits the vanished walk visits (0 = unlimited) |
deleted_to_destroy |
false |
Emit action: destroy matrix entries for fully-deleted groups |
token |
github.token |
GitHub token for API access |
base_sha |
Override base commit SHA | |
sha |
Override head commit SHA |
Action Outputs
| Output | Description |
|---|---|
matrix |
Deploy matrix JSON for fromJson() |
has_changes |
true if any deployable changes detected |
any_changed |
true if any files changed |
changed_files |
Space-separated changed file paths |
changed_files_count |
Number of changed files |
added_files |
Space-separated added file paths |
modified_files |
Space-separated modified file paths |
deleted_files |
Space-separated deleted file paths |
deploy_decisions |
JSON array of per-group deploy decisions |
files_to_rebuild |
Files needing rebuild |
files_to_skip |
Files safe to skip |
diagnostics |
JSON array of diagnostic messages |
vanished_files |
Space-separated files added then removed within the PR history |
vanished |
JSON array of {path, last_seen_sha} for vanished files |
CLI
lechange detect \
--files 'stacks/**/*.yaml' \
--files-group-by 'stacks/{group}/**' \
--base-sha abc123 \
--sha def456 \
--output-format json
All options accept environment variables with LECHANGE_ prefix (e.g. LECHANGE_FILES).
Exit codes: 0 = changes detected, 1 = error, 2 = no changes.
Python
pip install lechange
from lechange import ChangeDetector, Config
detector = ChangeDetector(".")
config = Config(
files=["src/**/*.py"],
files_group_by="src/{group}/**",
base_sha="abc123",
sha="def456",
)
result = detector.get_changed_files(config)
print(result.all_changed_files)
print(result.deploy_matrix)
print(result.has_deployable_groups)
Development
cargo test -p le-change # Core library tests
cargo test -p lechange-cli # CLI tests
cargo build --release -p lechange-cli # Release binary
License
Copyright (c) 2024-2026 Lituus-io. All rights reserved.
AGPL-3.0-or-later. Commercial license available — contact spicyzhug@gmail.com.
Metadata
Release files for lechange 0.3.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| lechange-0.3.2-cp38-abi3-win_amd64.whl | CPython 3.8 | abi3 | Windows x86-64 | Details for lechange-0.3.2-cp38-abi3-win_amd64.whl |
| lechange-0.3.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ x86-64 | Details for lechange-0.3.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
| lechange-0.3.2-cp38-abi3-macosx_11_0_arm64.whl | CPython 3.8 | abi3 | macOS 11.0+ ARM64 | Details for lechange-0.3.2-cp38-abi3-macosx_11_0_arm64.whl |
Total release size: 9.3 MB
Release files / lechange-0.3.2-cp38-abi3-win_amd64.whl
| Download URL | lechange-0.3.2-cp38-abi3-win_amd64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.8 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
0802b620ba92c6a595ad31ae226fb5529d3fac4696efe326dd16504051d34eb0
|
|
BLAKE2b-256 checksum How to use checksums |
03380320a0e350618c688aa1631e4b028fbcd1bdea24b672f162e16c1d97dc67
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / lechange-0.3.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | lechange-0.3.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 3.3 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
21573f804680cec56714c3f44a6ff0ad51ae8d044fedd494ae77bf618ed54a9d
|
|
BLAKE2b-256 checksum How to use checksums |
1b22c62d7f8eef1977748d44419e83ee537da78043628f20ee11d3b5a15b5b83
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / lechange-0.3.2-cp38-abi3-macosx_11_0_arm64.whl
| Download URL | lechange-0.3.2-cp38-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.9 MB |
| Tags | CPython 3.8 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
7277daa4871e1f5419b590131523371bbf2a872715e1470ed1331c451dab3458
|
|
BLAKE2b-256 checksum How to use checksums |
c7ac24461d600dbfe58882035d7f5c3e7a9a9a69d2eb9440937ff41cf1eeef9e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Security for lechange 0.3.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.