-
Notifications
You must be signed in to change notification settings - Fork 0
Import GitHub label synchronization CLI #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
25f7ac1
Import GitHub label synchronisation CLI
leynos 42ace0f
Address label sync review findings
leynos 38d69df
Encode label names before lookup
leynos 5d4d0df
Normalize existing labels before sync comparison
leynos e8710f0
Address review coverage gaps
leynos 6021353
Add ecosystem default labels
leynos c6d2e31
Use Oxford spelling in review docs
leynos b24926e
Address review architecture and docs
leynos 507cfb4
Use private lock for Betamax request records
leynos 36bb8b5
Expand agent testing guidance
leynos 5d0733a
Clear repository env in GitHub adapter test
leynos 88366e7
Add documentation index and layout guide
leynos 04298c1
Use Oxford -ize spelling in public API docstrings
leynos File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,43 @@ | ||
| # create-labels | ||
|
|
||
| Example package generated from this Copier template. | ||
| `create-labels` creates and updates GitHub repository labels from a TOML | ||
| configuration file or from the built-in df12 label set. It is a small Python | ||
| command-line tool for making label setup repeatable across repositories without | ||
| shelling out to the GitHub CLI. | ||
|
|
||
| ## Why use this? | ||
|
|
||
| - Apply a consistent default label set to new repositories. | ||
| - Keep repository labels in sync from reviewed TOML configuration. | ||
| - Support GitHub Enterprise and local API simulators through `--api-url`. | ||
| - Avoid deleting labels that are outwith the desired configuration. | ||
|
|
||
| ## Quick start | ||
|
|
||
| Install the package, provide a token, and choose a target repository: | ||
|
|
||
| ```bash | ||
| create-labels --repository owner/repo --token "$GITHUB_TOKEN" | ||
| ``` | ||
|
|
||
| To use a TOML configuration file: | ||
|
|
||
| ```bash | ||
| create-labels --config labels.toml --repository owner/repo | ||
| ``` | ||
|
|
||
| When no labels are provided in TOML, the built-in default labels are applied. | ||
|
|
||
| ## Documentation | ||
|
|
||
| Read the [users' guide](docs/users-guide.md) for command-line options, | ||
| configuration format, GitHub Enterprise usage, and local validation commands. | ||
|
|
||
| Read the [developers' guide](docs/developers-guide.md) for package boundaries, | ||
| data flow, normalization rules, and testing strategy. | ||
|
|
||
| ## Compatibility note | ||
|
|
||
| This package is no longer the Copier template placeholder project. The old | ||
| sample `hello` function has been removed; use the `create-labels` console | ||
| script or the public exports from `create_labels` instead. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,19 +1,28 @@ | ||
| """create-labels package.""" | ||
| """Public API for create-labels. | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import importlib | ||
| import typing as typ | ||
| The package root is the stable import boundary for library consumers. It | ||
| re-exports typed configuration values from ``create_labels.config``, the | ||
| imported default label set from ``create_labels.defaults``, and the pure label | ||
| synchronization function and result type from ``create_labels.sync``. | ||
|
|
||
| if typ.TYPE_CHECKING: | ||
| import collections.abc as cabc | ||
| Use these exports when embedding create-labels in tests, scripts, or other | ||
| tools. The submodules keep parsing, default data, GitHub integration, and sync | ||
| decisions separate, while this module provides the small public surface that | ||
| callers should depend on. | ||
| """ | ||
|
|
||
| PACKAGE_NAME = "create_labels" | ||
| from __future__ import annotations | ||
|
|
||
| try: # pragma: no cover - Rust optional | ||
| rust = importlib.import_module(f"._{PACKAGE_NAME}_rs", package=__name__) | ||
| hello = typ.cast("cabc.Callable[[], str]", rust.hello) | ||
| except ModuleNotFoundError: # pragma: no cover - Python fallback | ||
| from .pure import hello | ||
| from .config import LabelConfig, LabelSpec, RepositorySpec, load_config | ||
| from .defaults import DEFAULT_LABELS | ||
| from .sync import LabelSyncResult, sync_labels | ||
|
|
||
| __all__ = ["hello"] | ||
| __all__ = [ | ||
| "DEFAULT_LABELS", | ||
| "LabelConfig", | ||
| "LabelSpec", | ||
| "LabelSyncResult", | ||
| "RepositorySpec", | ||
| "load_config", | ||
| "sync_labels", | ||
| ] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| """Cyclopts command-line interface for create-labels. | ||
|
|
||
| This module provides the console entrypoint that wires together argument | ||
| parsing, TOML configuration loading, github3.py integration, and result | ||
| formatting. ``main`` is the Cyclopts-decorated command used by the | ||
| ``create-labels`` project script. | ||
|
|
||
| Repository resolution prefers ``--repository``, then ``[repository]`` from the | ||
| TOML file, then ``GITHUB_REPOSITORY``. Tokens prefer ``--token`` and then | ||
| ``GITHUB_TOKEN``. API URLs prefer ``--api-url``, then ``github.api_url`` from | ||
| TOML, then ``https://api.github.com``. | ||
|
|
||
| Examples | ||
| -------- | ||
| Apply the imported default labels:: | ||
|
|
||
| create-labels --repository owner/repo | ||
|
|
||
| Apply labels from TOML:: | ||
|
|
||
| create-labels --config labels.toml | ||
|
|
||
| Target GitHub Enterprise or a simulator:: | ||
|
|
||
| create-labels --repository owner/repo --api-url https://github.example/api/v3 | ||
|
|
||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import pathlib | ||
|
|
||
| from cyclopts import App | ||
|
|
||
| from .config import LabelConfig, RepositorySpec, load_config | ||
| from .github import sync_repository_labels | ||
|
|
||
| app: App = App(help="Create or update GitHub repository labels from TOML.") | ||
|
|
||
|
|
||
| @app.default | ||
| def main( | ||
| *, | ||
| config: str | None = None, | ||
| repository: str | None = None, | ||
| token: str | None = None, | ||
| api_url: str | None = None, | ||
| ) -> None: | ||
| """Create or update labels in a GitHub repository. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| config | ||
| TOML configuration path. When omitted, the default imported labels are | ||
| used. | ||
| repository | ||
| Repository in ``owner/name`` form. Overrides ``[repository]`` in the | ||
| TOML file and ``GITHUB_REPOSITORY``. | ||
| token | ||
| GitHub token. When omitted, ``GITHUB_TOKEN`` is used. | ||
| api_url | ||
| GitHub API URL. Use this for GitHub Enterprise or local simulators. | ||
|
|
||
| """ | ||
| label_config = ( | ||
| load_config(pathlib.Path(config)) | ||
| if config is not None | ||
| else LabelConfig(None, ()) | ||
| ) | ||
| results = sync_repository_labels( | ||
| config=label_config, | ||
| repository=_parse_repository_argument(repository), | ||
| token=token, | ||
| api_url=api_url, | ||
| ) | ||
|
|
||
| for result in results: | ||
| print(f"{result.action}: {result.name}") | ||
|
|
||
|
|
||
| def _parse_repository_argument(repository: str | None) -> RepositorySpec | None: | ||
| """Parse an ``owner/name`` repository argument into a RepositorySpec.""" | ||
| if repository is None: | ||
| return None | ||
|
|
||
| owner, separator, name = repository.partition("/") | ||
| if not all((separator, owner, name)) or "/" in name: | ||
| msg = "repository must use the owner/name format" | ||
| raise ValueError(msg) | ||
| return RepositorySpec(owner=owner, name=name) | ||
|
|
||
|
|
||
| def run() -> None: | ||
| """Execute the Cyclopts application. | ||
|
|
||
| This thin wrapper delegates to ``app`` so packaging can expose a stable | ||
| project-script entrypoint. | ||
|
|
||
| Raises | ||
| ------ | ||
| SystemExit | ||
| Raised by Cyclopts when argument parsing or command execution fails. | ||
|
|
||
| """ | ||
| app() |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.