From 51ba91361facb4d651b4d9b1cf853105dca2b06d Mon Sep 17 00:00:00 2001 From: bradjin8 Date: Fri, 31 Jul 2026 12:31:43 -0400 Subject: [PATCH 01/10] chore: date changelog and prepare v0.1.0 release (#102) Move accumulated [Unreleased] entries into [0.1.0] - 2026-07-31, document the release workflow in CONTRIBUTING.md, and update SECURITY.md for the first tagged pre-release. --- CHANGELOG.md | 23 ++++++++++------------- CONTRIBUTING.md | 15 +++++++++++++++ SECURITY.md | 8 ++++---- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1668306..2b3c296 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.1.0] - 2026-07-31 + +First public pre-release. The CLI package version is `0.1.0` (`cli/pyproject.toml`). + ### Added +- `localci` CLI — analyze, list, run, status, logs, images, cache, and config commands +- Configurable workflow patch pipeline for local act execution +- Docker image management and caching (ccache, Boost, CMake, APT) +- CI: ruff lint/format, mypy strict typecheck, unit tests, and act/Docker integration tests +- Runnable validation example under `examples/` +- README yq disambiguation and per-OS install matrix for [mikefarah/yq](https://github.com/mikefarah/yq) v4+ - `CONTRIBUTING.md` — developer onboarding (setup, tests, lint, pre-commit, PR expectations) - `CHANGELOG.md` — this file - `.github/CODEOWNERS` — maintainer routing for reviews @@ -29,19 +39,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `PriorityJobQueue`: jobs in `WAITING_DEPS` return to `QUEUED` when their dependencies finish. Same-priority `needs` chains were leaving dependents stuck. - `PriorityJobQueue.cancel_all` drops cancelled keys from `_running_keys`. A `READY` job from `next_ready()` no longer counts as running after cancel. -## [0.1.0] - TBD - -Pre-release baseline. The CLI package version is `0.1.0` (`cli/pyproject.toml`). - -### Added - -- `localci` CLI — analyze, list, run, status, logs, images, cache, and config commands -- Configurable workflow patch pipeline for local act execution -- Docker image management and caching (ccache, Boost, CMake, APT) -- CI: ruff lint/format, mypy strict typecheck, unit tests, and act/Docker integration tests -- Runnable validation example under `examples/` -- README yq disambiguation and per-OS install matrix for [mikefarah/yq](https://github.com/mikefarah/yq) v4+ - ### Pre-release stability (before 1.0) This project is in **0.x** pre-release. Until **1.0.0**: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 54eeb2a..0551ac8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -97,6 +97,21 @@ pre-commit run -a 2. Keep changes focused; link related issues in the PR description. 3. Ensure CI is green — lint, typecheck, unit tests, and integration tests must pass. 4. Request review from at least one maintainer. PRs need **at least one approving review** before merge. +5. Update `CHANGELOG.md` for user-visible changes under `## [Unreleased]`. + +## Branching and releases + +- `develop` is the default branch where day-to-day work lands and releases are cut from. +- To cut release `X.Y.Z` when `cli/pyproject.toml` already declares that version: + 1. Move the `## [Unreleased]` entries in [CHANGELOG.md](CHANGELOG.md) under a new + `## [X.Y.Z] - YYYY-MM-DD` heading and update the link references at the bottom. + 2. Merge the changelog update to `develop` via PR; wait for CI to be green. + 3. Publish a GitHub Release for a **new** tag `vX.Y.Z` targeting `develop` — in the UI, + or `gh release create vX.Y.Z --target develop --title vX.Y.Z --notes-file ...`. + `--target develop` only selects the commit when the release *creates* the tag: if + `vX.Y.Z` already exists, GitHub publishes from wherever that tag points. Ensure + `vX.Y.Z` does not yet exist so the release creates it on the merged `develop` commit. + 4. Confirm [`.github/workflows/ci.yml`](.github/workflows/ci.yml) is green on the tagged commit. ## Maintainers diff --git a/SECURITY.md b/SECURITY.md index d9bdd57..4741871 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,13 +2,13 @@ ## Supported Versions -Local CI is in pre-release development. There are no tagged stable releases yet -(`pyproject.toml` declares `0.1.0`, not yet tagged). +| Version | Supported | +| ------- | ------------------ | +| 0.1.x | :white_check_mark: | Security fixes are produced only against the latest commit on the [`develop`](https://github.com/cppalliance/local-ci-test-system/tree/develop) -branch. Once a `v0.1.0` tag is cut, this section will be reformatted as a -semver-style support table. +branch for the current 0.1.x line. ## Reporting a Vulnerability From 11235186fb8c318c3bbc39b2a009efef5b103403 Mon Sep 17 00:00:00 2001 From: bradjin8 Date: Fri, 31 Jul 2026 12:33:53 -0400 Subject: [PATCH 02/10] add: release note --- RELEASE_NOTES_v0.1.0.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 RELEASE_NOTES_v0.1.0.md diff --git a/RELEASE_NOTES_v0.1.0.md b/RELEASE_NOTES_v0.1.0.md new file mode 100644 index 0000000..64ce684 --- /dev/null +++ b/RELEASE_NOTES_v0.1.0.md @@ -0,0 +1,26 @@ +# localci v0.1.0 + +First public pre-release of Local CI — run GitHub Actions workflows locally in Docker via [act](https://github.com/nektos/act). + +## Highlights + +- **`localci` CLI** — analyze, list, run, status, logs, images, cache, and config commands +- **Generic patch profile by default** — stock non-Capy repos run without overrides; `profile: capy` opts into Boost.Capy/B2 workflow patches +- **Docker image management and caching** — ccache, Boost, CMake, and APT layers for fast re-runs +- **Priority-ordered parallel execution** with resource-aware throttling +- **Unsupported-platform honesty** — Windows/macOS matrix jobs fail with an explicit Linux-only message + +## Install + +```bash +cd cli +pip install -e . +``` + +See [README.md](README.md) for prerequisites (Docker, act, mikefarah/yq v4+). + +## Pre-1.0 stability + +This is a **0.x** pre-release. CLI flags, `.localci.yml` schema, and patch-pipeline behavior may change between minor releases. Pin a version and read [CHANGELOG.md](CHANGELOG.md) before upgrading. + +Full changelog: https://github.com/cppalliance/local-ci-test-system/blob/v0.1.0/CHANGELOG.md From dd5d62915d8f07e174ffe6bbd37c83a8bf6fd309 Mon Sep 17 00:00:00 2001 From: bradjin8 Date: Fri, 31 Jul 2026 12:42:26 -0400 Subject: [PATCH 03/10] docs: tighten release checklist in CONTRIBUTING.md --- CONTRIBUTING.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0551ac8..b52c0b1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -104,14 +104,18 @@ pre-commit run -a - `develop` is the default branch where day-to-day work lands and releases are cut from. - To cut release `X.Y.Z` when `cli/pyproject.toml` already declares that version: 1. Move the `## [Unreleased]` entries in [CHANGELOG.md](CHANGELOG.md) under a new - `## [X.Y.Z] - YYYY-MM-DD` heading and update the link references at the bottom. + `## [X.Y.Z] - YYYY-MM-DD` heading, leave `## [Unreleased]` empty, and update + the link references at the bottom. 2. Merge the changelog update to `develop` via PR; wait for CI to be green. 3. Publish a GitHub Release for a **new** tag `vX.Y.Z` targeting `develop` — in the UI, - or `gh release create vX.Y.Z --target develop --title vX.Y.Z --notes-file ...`. + or `gh release create vX.Y.Z --target develop --title vX.Y.Z --notes-file ...` + using the new `## [X.Y.Z]` section as the release notes source. `--target develop` only selects the commit when the release *creates* the tag: if `vX.Y.Z` already exists, GitHub publishes from wherever that tag points. Ensure `vX.Y.Z` does not yet exist so the release creates it on the merged `develop` commit. 4. Confirm [`.github/workflows/ci.yml`](.github/workflows/ci.yml) is green on the tagged commit. + 5. Confirm the `[Unreleased]` and `[X.Y.Z]` compare links at the bottom of + [CHANGELOG.md](CHANGELOG.md) resolve after the new tag is created. ## Maintainers From 6b6a9bd23a46215f01c3acaedf2e5315642607c6 Mon Sep 17 00:00:00 2001 From: bradjin8 Date: Fri, 31 Jul 2026 12:52:18 -0400 Subject: [PATCH 04/10] docs: require tag validation before v0.1.0 release publish --- CONTRIBUTING.md | 16 ++++++++-------- RELEASE_NOTES_v0.1.0.md | 4 ++++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b52c0b1..911a9c6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -107,14 +107,14 @@ pre-commit run -a `## [X.Y.Z] - YYYY-MM-DD` heading, leave `## [Unreleased]` empty, and update the link references at the bottom. 2. Merge the changelog update to `develop` via PR; wait for CI to be green. - 3. Publish a GitHub Release for a **new** tag `vX.Y.Z` targeting `develop` — in the UI, - or `gh release create vX.Y.Z --target develop --title vX.Y.Z --notes-file ...` - using the new `## [X.Y.Z]` section as the release notes source. - `--target develop` only selects the commit when the release *creates* the tag: if - `vX.Y.Z` already exists, GitHub publishes from wherever that tag points. Ensure - `vX.Y.Z` does not yet exist so the release creates it on the merged `develop` commit. - 4. Confirm [`.github/workflows/ci.yml`](.github/workflows/ci.yml) is green on the tagged commit. - 5. Confirm the `[Unreleased]` and `[X.Y.Z]` compare links at the bottom of + 3. Create an annotated tag `vX.Y.Z` on the merged `develop` commit and push it + (`git tag -a vX.Y.Z` then `git push origin vX.Y.Z`). + 4. Validate the tag: confirm `git show vX.Y.Z:CHANGELOG.md` has + `## [X.Y.Z] - YYYY-MM-DD` (not `TBD`) and CI is green on the tagged commit. + 5. Publish the GitHub Release (`gh release create vX.Y.Z --notes-file ...`) using + the new `## [X.Y.Z]` section as the release notes source. If the tag already + exists, GitHub publishes from that commit. + 6. Confirm the `[Unreleased]` and `[X.Y.Z]` compare links at the bottom of [CHANGELOG.md](CHANGELOG.md) resolve after the new tag is created. ## Maintainers diff --git a/RELEASE_NOTES_v0.1.0.md b/RELEASE_NOTES_v0.1.0.md index 64ce684..a6906b7 100644 --- a/RELEASE_NOTES_v0.1.0.md +++ b/RELEASE_NOTES_v0.1.0.md @@ -1,5 +1,9 @@ # localci v0.1.0 + + First public pre-release of Local CI — run GitHub Actions workflows locally in Docker via [act](https://github.com/nektos/act). ## Highlights From 9957327de3624c02887c63e5b008f1eca79100bd Mon Sep 17 00:00:00 2001 From: bradjin8 Date: Fri, 31 Jul 2026 12:59:22 -0400 Subject: [PATCH 05/10] docs: require tag commit match before release publish --- CONTRIBUTING.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 911a9c6..7396587 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -108,12 +108,15 @@ pre-commit run -a the link references at the bottom. 2. Merge the changelog update to `develop` via PR; wait for CI to be green. 3. Create an annotated tag `vX.Y.Z` on the merged `develop` commit and push it - (`git tag -a vX.Y.Z` then `git push origin vX.Y.Z`). + (`git tag -a vX.Y.Z` then `git push origin vX.Y.Z`). If `vX.Y.Z` already + exists, stop and verify `git rev-parse vX.Y.Z` matches the merged release + commit (`git rev-parse develop`); do not publish from a tag that points + elsewhere. 4. Validate the tag: confirm `git show vX.Y.Z:CHANGELOG.md` has `## [X.Y.Z] - YYYY-MM-DD` (not `TBD`) and CI is green on the tagged commit. 5. Publish the GitHub Release (`gh release create vX.Y.Z --notes-file ...`) using - the new `## [X.Y.Z]` section as the release notes source. If the tag already - exists, GitHub publishes from that commit. + the new `## [X.Y.Z]` section as the release notes source, only after steps + 3–4 confirm the tag points to the merged release commit. 6. Confirm the `[Unreleased]` and `[X.Y.Z]` compare links at the bottom of [CHANGELOG.md](CHANGELOG.md) resolve after the new tag is created. From d015c9cfe95047010af4d53161b6ffba77f31b47 Mon Sep 17 00:00:00 2001 From: bradjin8 Date: Fri, 31 Jul 2026 13:54:15 -0400 Subject: [PATCH 06/10] docs: name RELEASE_NOTES artifact and standardize on develop branch --- CONTRIBUTING.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7396587..d5cb2fe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -93,7 +93,7 @@ pre-commit run -a ## Pull requests -1. Branch from `develop` (or `main` for release fixes). +1. Branch from `develop`. 2. Keep changes focused; link related issues in the PR description. 3. Ensure CI is green — lint, typecheck, unit tests, and integration tests must pass. 4. Request review from at least one maintainer. PRs need **at least one approving review** before merge. @@ -106,18 +106,21 @@ pre-commit run -a 1. Move the `## [Unreleased]` entries in [CHANGELOG.md](CHANGELOG.md) under a new `## [X.Y.Z] - YYYY-MM-DD` heading, leave `## [Unreleased]` empty, and update the link references at the bottom. - 2. Merge the changelog update to `develop` via PR; wait for CI to be green. - 3. Create an annotated tag `vX.Y.Z` on the merged `develop` commit and push it + 2. Create `RELEASE_NOTES_vX.Y.Z.md` from the new `## [X.Y.Z]` section (see + [RELEASE_NOTES_v0.1.0.md](RELEASE_NOTES_v0.1.0.md) for the format). + 3. Merge the changelog and release-notes update to `develop` via PR; wait for CI + to be green. + 4. Create an annotated tag `vX.Y.Z` on the merged `develop` commit and push it (`git tag -a vX.Y.Z` then `git push origin vX.Y.Z`). If `vX.Y.Z` already exists, stop and verify `git rev-parse vX.Y.Z` matches the merged release commit (`git rev-parse develop`); do not publish from a tag that points elsewhere. - 4. Validate the tag: confirm `git show vX.Y.Z:CHANGELOG.md` has + 5. Validate the tag: confirm `git show vX.Y.Z:CHANGELOG.md` has `## [X.Y.Z] - YYYY-MM-DD` (not `TBD`) and CI is green on the tagged commit. - 5. Publish the GitHub Release (`gh release create vX.Y.Z --notes-file ...`) using - the new `## [X.Y.Z]` section as the release notes source, only after steps - 3–4 confirm the tag points to the merged release commit. - 6. Confirm the `[Unreleased]` and `[X.Y.Z]` compare links at the bottom of + 6. Publish the GitHub Release + (`gh release create vX.Y.Z --notes-file RELEASE_NOTES_vX.Y.Z.md`) only after + steps 4–5 confirm the tag points to the merged release commit. + 7. Confirm the `[Unreleased]` and `[X.Y.Z]` compare links at the bottom of [CHANGELOG.md](CHANGELOG.md) resolve after the new tag is created. ## Maintainers From 83a06b3197a937a8c879e594e8fc0e35ef0b92c4 Mon Sep 17 00:00:00 2001 From: bradjin8 Date: Fri, 31 Jul 2026 13:56:23 -0400 Subject: [PATCH 07/10] docs: peel tag to commit when verifying release target --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d5cb2fe..ba2ca65 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -112,9 +112,9 @@ pre-commit run -a to be green. 4. Create an annotated tag `vX.Y.Z` on the merged `develop` commit and push it (`git tag -a vX.Y.Z` then `git push origin vX.Y.Z`). If `vX.Y.Z` already - exists, stop and verify `git rev-parse vX.Y.Z` matches the merged release - commit (`git rev-parse develop`); do not publish from a tag that points - elsewhere. + exists, stop and verify `git rev-parse vX.Y.Z^{commit}` matches the merged + release commit (`git rev-parse origin/develop`); do not publish from a tag + that points elsewhere. 5. Validate the tag: confirm `git show vX.Y.Z:CHANGELOG.md` has `## [X.Y.Z] - YYYY-MM-DD` (not `TBD`) and CI is green on the tagged commit. 6. Publish the GitHub Release From 2a41f211f59d5a6f26b9ec15a1fd057a2c8aa6cd Mon Sep 17 00:00:00 2001 From: bradjin8 Date: Fri, 31 Jul 2026 13:57:12 -0400 Subject: [PATCH 08/10] docs: use tagged clone and non-editable install in v0.1.0 release notes --- RELEASE_NOTES_v0.1.0.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/RELEASE_NOTES_v0.1.0.md b/RELEASE_NOTES_v0.1.0.md index a6906b7..e4a2508 100644 --- a/RELEASE_NOTES_v0.1.0.md +++ b/RELEASE_NOTES_v0.1.0.md @@ -17,8 +17,9 @@ First public pre-release of Local CI — run GitHub Actions workflows locally in ## Install ```bash -cd cli -pip install -e . +git clone --branch v0.1.0 https://github.com/cppalliance/local-ci-test-system.git +cd local-ci-test-system/cli +pip install . ``` See [README.md](README.md) for prerequisites (Docker, act, mikefarah/yq v4+). From eaae670cabe78b17d6ce42bbcc3b6f57fc557631 Mon Sep 17 00:00:00 2001 From: bradjin8 Date: Fri, 31 Jul 2026 13:58:08 -0400 Subject: [PATCH 09/10] docs: offer security email unconditionally in SECURITY.md --- SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index 4741871..41070ac 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -14,7 +14,7 @@ branch for the current 0.1.x line. **Please do not open a public GitHub issue for security vulnerabilities.** -Report security issues through **[GitHub private vulnerability reporting](https://github.com/cppalliance/local-ci-test-system/security/advisories/new)** (preferred), or email **will@cppalliance.org** if you do not have a GitHub account. +Report security issues through **[GitHub private vulnerability reporting](https://github.com/cppalliance/local-ci-test-system/security/advisories/new)** or email **will@cppalliance.org**. If you need an encrypted channel, mention this in your initial email and a maintainer will reply with a current PGP key fingerprint or arrange another From 66b98c518a8a3dafc9fb43477740df251705780a Mon Sep 17 00:00:00 2001 From: bradjin8 Date: Fri, 31 Jul 2026 14:04:07 -0400 Subject: [PATCH 10/10] chore: humanize release docs and apply Jannie cleanup Docs: plain-language release notes, active voice in SECURITY, colon instead of em dash in CONTRIBUTING. Code: walk up for image-registry.yml in run flow, share PLATFORM_CLI_MAP, remove unused helpers. --- CONTRIBUTING.md | 2 +- RELEASE_NOTES_v0.1.0.md | 14 +++++++------- SECURITY.md | 4 ++-- cli/localci/cli/list.py | 9 ++------- cli/localci/cli/run/run_flow.py | 18 +++++------------- cli/localci/core/patch_registry.py | 12 ------------ cli/localci/core/workflow.py | 7 +++++++ cli/localci/utils/output.py | 8 -------- cli/localci/utils/paths.py | 28 ---------------------------- 9 files changed, 24 insertions(+), 78 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ba2ca65..88b616b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -95,7 +95,7 @@ pre-commit run -a 1. Branch from `develop`. 2. Keep changes focused; link related issues in the PR description. -3. Ensure CI is green — lint, typecheck, unit tests, and integration tests must pass. +3. Ensure CI is green: lint, typecheck, unit tests, and integration tests must pass. 4. Request review from at least one maintainer. PRs need **at least one approving review** before merge. 5. Update `CHANGELOG.md` for user-visible changes under `## [Unreleased]`. diff --git a/RELEASE_NOTES_v0.1.0.md b/RELEASE_NOTES_v0.1.0.md index e4a2508..c75aa15 100644 --- a/RELEASE_NOTES_v0.1.0.md +++ b/RELEASE_NOTES_v0.1.0.md @@ -4,15 +4,15 @@ CHANGELOG.md at the tag shows ## [0.1.0] - 2026-07-31 (not TBD) and CI is green, then publish with: gh release create v0.1.0 --notes-file RELEASE_NOTES_v0.1.0.md --> -First public pre-release of Local CI — run GitHub Actions workflows locally in Docker via [act](https://github.com/nektos/act). +First public pre-release of Local CI. Run GitHub Actions workflows locally in Docker via [act](https://github.com/nektos/act). ## Highlights -- **`localci` CLI** — analyze, list, run, status, logs, images, cache, and config commands -- **Generic patch profile by default** — stock non-Capy repos run without overrides; `profile: capy` opts into Boost.Capy/B2 workflow patches -- **Docker image management and caching** — ccache, Boost, CMake, and APT layers for fast re-runs -- **Priority-ordered parallel execution** with resource-aware throttling -- **Unsupported-platform honesty** — Windows/macOS matrix jobs fail with an explicit Linux-only message +- `localci` CLI: analyze, list, run, status, logs, images, cache, and config +- Generic patch profile by default; set `profile: capy` for Boost.Capy/B2 workflow patches +- Docker image management and caching (ccache, Boost, CMake, APT) +- Priority-ordered parallel execution with resource limits +- Windows and macOS matrix jobs fail with an explicit Linux-only message instead of running act without an image ## Install @@ -26,6 +26,6 @@ See [README.md](README.md) for prerequisites (Docker, act, mikefarah/yq v4+). ## Pre-1.0 stability -This is a **0.x** pre-release. CLI flags, `.localci.yml` schema, and patch-pipeline behavior may change between minor releases. Pin a version and read [CHANGELOG.md](CHANGELOG.md) before upgrading. +0.x pre-release: CLI flags, `.localci.yml`, and patch steps may change between minors. Pin a version and read [CHANGELOG.md](CHANGELOG.md) before upgrading. Full changelog: https://github.com/cppalliance/local-ci-test-system/blob/v0.1.0/CHANGELOG.md diff --git a/SECURITY.md b/SECURITY.md index 41070ac..b83632c 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -6,9 +6,9 @@ | ------- | ------------------ | | 0.1.x | :white_check_mark: | -Security fixes are produced only against the latest commit on the +Security fixes land only on the latest commit on [`develop`](https://github.com/cppalliance/local-ci-test-system/tree/develop) -branch for the current 0.1.x line. +for the current 0.1.x line. ## Reporting a Vulnerability diff --git a/cli/localci/cli/list.py b/cli/localci/cli/list.py index 795e30a..ee3df86 100644 --- a/cli/localci/cli/list.py +++ b/cli/localci/cli/list.py @@ -12,6 +12,7 @@ import click from localci.core.workflow import ( + PLATFORM_CLI_MAP, CompilerFamily, Platform, WorkflowAnalyzer, @@ -29,12 +30,6 @@ # Helpers # ===================================================================== -_PLATFORM_MAP = { - "linux": Platform.LINUX, - "windows": Platform.WINDOWS, - "macos": Platform.MACOS, -} - _COMPILER_MAP = { "gcc": CompilerFamily.GCC, "clang": CompilerFamily.CLANG, @@ -165,7 +160,7 @@ def list_cmd( entries = wf.all_matrix_entries() if platform != "all": - target = _PLATFORM_MAP.get(platform) + target = PLATFORM_CLI_MAP.get(platform) if target: entries = [e for e in entries if e.platform == target] diff --git a/cli/localci/cli/run/run_flow.py b/cli/localci/cli/run/run_flow.py index 46e4cea..96aa4ff 100644 --- a/cli/localci/cli/run/run_flow.py +++ b/cli/localci/cli/run/run_flow.py @@ -13,15 +13,10 @@ from localci.core.github_token import resolve_github_token, warn_sentinel_github_token from localci.core.models import JobEvent, JobEventType from localci.core.results import ExecutionSummary -from localci.core.workflow import MatrixEntry, Platform, Workflow +from localci.core.workflow import PLATFORM_CLI_MAP, MatrixEntry, Workflow from localci.errors import ActNotFoundError, DockerNotAvailableError, WorkflowError from localci.utils.output import print_error, print_info, print_warning - -_PLATFORM_MAP = { - "linux": Platform.LINUX, - "windows": Platform.WINDOWS, - "macos": Platform.MACOS, -} +from localci.utils.paths import REGISTRY_FILENAME, find_file_upward def execute_run( @@ -73,13 +68,10 @@ def execute_run( return 0 priority_config = container.priority_config_factory(cfg) - registry_candidate = project_dir / "image-registry.yml" - registry_path: Path | None = ( - registry_candidate if registry_candidate.exists() else None - ) + registry_path = find_file_upward(REGISTRY_FILENAME, project_dir) matrix_include, matrix_exclude = _resolve_matrix_filters(options, cfg) - plat_filter = _PLATFORM_MAP.get(options.platform) if options.platform else None + plat_filter = PLATFORM_CLI_MAP.get(options.platform) if options.platform else None compiler_filter = options.compiler.lower() if options.compiler else None selected_set = {(jid, e.index) for jid, e in selected} job_filter_list = list({jid for jid, _ in selected}) @@ -197,7 +189,7 @@ def _filter_matrix_pairs( ) -> list[tuple[str, MatrixEntry]]: selected = list(all_pairs) if platform: - target_plat = _PLATFORM_MAP.get(platform) + target_plat = PLATFORM_CLI_MAP.get(platform) selected = [(jid, e) for jid, e in selected if e.platform == target_plat] compiler_filter = compiler.lower() if compiler else None diff --git a/cli/localci/core/patch_registry.py b/cli/localci/core/patch_registry.py index b3d541e..3581ca5 100644 --- a/cli/localci/core/patch_registry.py +++ b/cli/localci/core/patch_registry.py @@ -14,8 +14,6 @@ from importlib.metadata import entry_points from typing import TYPE_CHECKING -from localci.core.config import PATCH_STEP_NAMES - logger = logging.getLogger(__name__) if TYPE_CHECKING: @@ -38,13 +36,3 @@ def get_patch_step_registry() -> dict[str, type[PatchStep]]: "Failed to load localci.patch_steps entry point %r", ep.name ) return registry - - -def clear_patch_step_registry_cache() -> None: - """Clear the registry cache (for tests that register plugins at runtime).""" - get_patch_step_registry.cache_clear() - - -def is_builtin_patch_step(name: str) -> bool: - """Return True when *name* is a built-in (non-plugin) patch step.""" - return name in PATCH_STEP_NAMES diff --git a/cli/localci/core/workflow.py b/cli/localci/core/workflow.py index 5810da8..d2dfb28 100644 --- a/cli/localci/core/workflow.py +++ b/cli/localci/core/workflow.py @@ -41,6 +41,13 @@ class Platform(Enum): UNKNOWN = "unknown" +PLATFORM_CLI_MAP: dict[str, Platform] = { + "linux": Platform.LINUX, + "windows": Platform.WINDOWS, + "macos": Platform.MACOS, +} + + class CompilerFamily(Enum): """Compiler family classification.""" diff --git a/cli/localci/utils/output.py b/cli/localci/utils/output.py index 8d3cf04..bb1b6ca 100644 --- a/cli/localci/utils/output.py +++ b/cli/localci/utils/output.py @@ -105,11 +105,3 @@ def make_table(*columns: str, title: str | None = None) -> Table: for col in columns: table.add_column(col) return table - - -def print_not_implemented(command: str) -> None: - """Placeholder for commands whose backend is not yet built.""" - print_warning( - f"[muted]{command}[/muted] is not yet implemented. " - "It will be available once the corresponding module is built." - ) diff --git a/cli/localci/utils/paths.py b/cli/localci/utils/paths.py index aca1029..b2fe28b 100644 --- a/cli/localci/utils/paths.py +++ b/cli/localci/utils/paths.py @@ -9,34 +9,6 @@ from pathlib import Path -def resolve_workflow( - path: str | Path | None, config_workflow: Path | None = None -) -> Path: - """Resolve a workflow file path. - - Priority: - 1. Explicit *path* argument from the CLI - 2. ``workflow`` value from the loaded config - 3. Default ``.github/workflows/ci.yml`` - - Raises - ------ - FileNotFoundError - If the resolved path does not exist. - """ - if path is not None: - resolved = Path(path).resolve() - elif config_workflow is not None: - resolved = Path(config_workflow).resolve() - else: - resolved = Path(".github/workflows/ci.yml").resolve() - - if not resolved.is_file(): - raise FileNotFoundError(f"Workflow file not found: {resolved}") - - return resolved - - def ensure_directory(path: Path) -> Path: """Create directory (and parents) if it does not exist, then return it.""" path.mkdir(parents=True, exist_ok=True)