Skip to content

Import GitHub label synchronization CLI#6

Open
leynos wants to merge 12 commits into
mainfrom
import-initial-script
Open

Import GitHub label synchronization CLI#6
leynos wants to merge 12 commits into
mainfrom
import-initial-script

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented May 25, 2026

Summary

This branch replaces the generated package stub with a working GitHub label synchronization tool. It imports the Axinite label bootstrap behaviour into a Python package, exposes a Cyclopts console entrypoint, uses github3.py for GitHub API access, and makes label names, colours and descriptions configurable through TOML.

No issue, roadmap task, or execplan is linked to this branch.

Review walkthrough

Validation

  • make check-fmt: passed
  • make typecheck: passed
  • make lint: passed
  • make test: passed, 16 passed
  • coderabbit review --agent: passed, findings: 0

Notes

  • The branch uses Betamax for the GitHub API mutation test because the required label create/update flow is covered reliably by a GitHub-shaped local HTTP fixture recorded through github3.py.
  • The package keeps label synchronization additive: labels omitted from TOML are not deleted from GitHub.

Replace the package stub with a Cyclopts CLI that loads TOML label
configuration, applies the imported Axinite default labels when no labels are
configured, and synchronises labels through github3.py instead of shelling out
to `gh`.

Add unit, pytest-bdd, and Betamax-backed github3.py coverage for parsing,
create/update behaviour, error paths, CLI wiring, and HTTP request flow. Update
the users' guide and keep Markdown files formatted so the repository gates pass.
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @leynos, you have reached your weekly rate limit of 2500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b34c43ab-883a-4952-b8b7-881eaf973dca

📥 Commits

Reviewing files that changed from the base of the PR and between 5d0733a and 88366e7.

📒 Files selected for processing (3)
  • AGENTS.md
  • docs/contents.md
  • docs/repository-layout.md

Overview

This pull request replaces the generated package stub with a fully functional GitHub label synchronization tool. It imports the Axinite label bootstrap behaviour into a Python package, exposes a Cyclopts-based CLI entrypoint, integrates github3.py for GitHub API access, and makes label names, colours and descriptions configurable through TOML. Label synchronization is kept additive—labels omitted from configuration are not deleted.

Core Implementation

Configuration & Defaults (create_labels/config.py, create_labels/defaults.py):

  • Introduces LabelConfig and LabelSpec dataclasses with built-in normalisation (colour formatting, description trimming, name validation)
  • Implements TOML parsing via load_config() with validation for duplicate label names, malformed colours, and repository specifications
  • Defines DEFAULT_LABELS containing 47 imported Axinite labels covering size buckets, risk levels, code scope categories, workflow exceptions, and contributor tiers

Synchronization Engine (create_labels/sync.py):

  • Defines GitHubRepository and GitHubLabel protocols as abstraction boundaries
  • Implements sync_labels() with per-label create/update logic and normalisation of remote label fields (colour case and leading #, description whitespace) for idempotent comparisons
  • Returns LabelSyncResult tuples tracking action outcomes ("created", "updated", "unchanged")

GitHub Integration (create_labels/github.py):

  • Implements sync_repository_labels() with precedence-based resolution: explicit arguments, then TOML config, then environment variables
  • Validates repository coordinates and authentication tokens; raises GitHubError for missing/malformed inputs
  • Adapts github3.py behaviour via _GitHubRepositoryAdapter for URL-encoded label lookup

CLI Entrypoint (create_labels/cli.py):

  • Exposes Cyclopts main() command accepting --config, --repository, --token, and --api-url options
  • Parses repository arguments in owner/name format; loads configuration with appropriate defaults
  • Prints synchronization results as "{action}: {name}" lines; wires stable script entrypoint via run()

Package API (create_labels/__init__.py):

  • Re-exports label-focused public API: DEFAULT_LABELS, LabelConfig, LabelSpec, RepositorySpec, load_config, LabelSyncResult, sync_labels
  • Removes previous Rust optional-loading and hello stub exports

Testing

Unit Tests (tests/test_config.py, tests/test_sync.py, tests/test_github.py, tests/test_cli.py):

  • Validates configuration parsing, colour/description normalisation, and duplicate label detection
  • Tests label create/update/unchanged paths with realistic field normalisation scenarios
  • Covers CLI argument parsing, malformed input rejection, and environment variable handling
  • Includes error-path coverage for missing repositories, invalid credentials, and repository lookup failures

Behaviour Tests (tests/features/synchronise_labels.feature, tests/steps/test_synchronise_labels.py):

  • Gherkin-based scenario: existing label update and missing label creation under a given configuration
  • pytest-bdd step implementations using FakeRepository/FakeLabel test doubles from tests/test_helpers.py

Integration Tests (tests/test_github_betamax.py):

  • Betamax-backed HTTP recording/playback for github3.py request/response cycles
  • Minimal mock LabelApiHandler serving GitHub-shaped repository and label endpoints
  • Asserts correct request paths (URL-encoded label names) and return values under real client-library interaction

Documentation

Users' Guide (docs/users-guide.md):

  • Installation, configuration precedence (CLI args → TOML → environment), authentication and API endpoint selection
  • TOML label schema and GitHub colour normalisation rules
  • Clarifies that labels omitted from configuration are retained and default label behaviour

Developers' Guide (docs/developers-guide.md):

  • Module layer architecture and data flow from CLI through config parsing to label synchronization
  • Label normalisation rules and remote label comparison semantics
  • Three-tier testing strategy (unit, BDD, Betamax HTTP) and local validation workflow

Reference & Index (docs/contents.md, docs/repository-layout.md):

  • Documentation index linking to core guides and standards
  • Repository structure guidance for maintainers

AGENTS.md Updates:

  • Strengthened documentation maintenance guidance: reference ADRs for requirements, update users' guide for user-facing changes, document interfaces in developers' guide
  • Expanded "New Functionality" testing checklist with specific tools and coverage types

Configuration

Runtime Dependencies (pyproject.toml):

  • Added cyclopts (CLI framework) and github3.py (GitHub API client)

Development Dependencies:

  • Added pytest-bdd, simulacat (for pytest-bdd fixture support), betamax>=0.9.0 (HTTP recording)

Console Script:

  • Mapped create-labels command to create_labels.cli:run

Related Issues

Open issues for out-of-scope work include property testing with Hypothesis (#7), snapshot testing for CLI output (#8), and structured logging/observability (#9). The implementation addresses blocking feedback from automated review: normalisation of remote label fields for idempotent synchronization and realistic GitHub response handling are now in place, with corresponding unit and integration test coverage.

Walkthrough

Implement a create‑labels CLI: parse TOML into typed configs with defaults, compute effective labels, sync with GitHub via github3.py, add a Cyclopts CLI and packaging entrypoint, and provide unit, BDD and Betamax integration tests plus user/developer documentation.

Changes

Label Configuration and Synchronisation System

Layer / File(s) Summary
Configuration Schema and Validation
create_labels/config.py
RepositorySpec, LabelSpec, LabelConfig, load_config and parse_config parse and validate TOML; normalise colours to 6‑hex uppercase, trim strings, enforce required fields and reject duplicate labels.
Default labels
create_labels/defaults.py
Export DEFAULT_LABELS tuple of LabelSpec entries used when no TOML [[labels]] are provided.
Label Synchronisation Core Logic
create_labels/sync.py
Define GitHubLabel/GitHubRepository Protocols and sync_labels that creates missing labels, updates out‑of‑date labels, returns LabelSyncResult including "unchanged", and normalises existing label fields for idempotent comparisons.
GitHub API Integration
create_labels/github.py
Resolve repository/token/api_url (args → config → env), authenticate via github3.py (support custom base_url), fetch repository and call sync_labels via an adapter; raise GitHubError on missing inputs or repository not found.
CLI Entry Point and Packaging
create_labels/cli.py, create_labels/__init__.py, pyproject.toml, tests/test_cli.py
Add Cyclopts CLI (app, main, run), repository argument parsing and validation, re‑export public API from package root, declare console script and runtime/dev dependencies, and add CLI tests verifying wiring and output.
Test doubles and unit tests
tests/test_helpers.py, tests/test_sync.py, tests/test_config.py, tests/test_cli.py
Provide FakeLabel/FakeRepository fakes and unit tests for create/update/unchanged paths, normalisation, URL‑encoding lookup semantics, CLI behaviour, and failure modes (create returns None, update returns False).
Betamax integration and HTTP fixture
tests/test_github_betamax.py, tests/fixtures/repository_payload.json
Add integration test that runs a mock GitHub API server, records requests with Betamax, and asserts expected URL‑encoded PATCH/POST requests for update/create flows.
Behavioural Specification
tests/features/synchronise_labels.feature, tests/steps/test_synchronise_labels.py
BDD feature and pytest‑bdd steps that assert existing labels are updated and missing labels are created using the FakeRepository fixture.
Documentation and small edits
docs/users-guide.md, docs/developers-guide.md, docs/contents.md, docs/repository-layout.md, docs/scripting-standards.md, AGENTS.md, README.md
Add Users' Guide and developers' guide, populate docs index and repository layout, rewrap shebang guidance, expand AGENTS.md maintenance/testing guidance, and rewrite README for the create-labels tool.

Sequence Diagram (high-level sync flow)

sequenceDiagram
  participant User
  participant CLI as create_labels.cli
  participant Adapter as create_labels.github
  participant GitHub as GitHub API
  User->>CLI: invoke `main()` with options (config/repository/token/api_url)
  CLI->>CLI: load TOML or use defaults -> LabelConfig
  CLI->>Adapter: call `sync_repository_labels(config, repository, token, api_url)`
  Adapter->>GitHub: authenticate (github3) and fetch repository
  Adapter->>GitHub: GET /repos/{owner}/{repo}/labels/{urlencoded_name} (lookup)
  Adapter->>GitHub: POST /repos/{owner}/{repo}/labels (create) or PATCH /repos/{owner}/{repo}/labels/{urlencoded_name} (update)
  Adapter-->>CLI: return `LabelSyncResult` tuple
  CLI->>User: print "action: name" lines
Loading

"From hello‑to‑labels reborn,
TOML read and colours shorn.
Fake repos record the play,
Adapter pings the GitHub way.
Tests assert the sync today. 🎯"


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 6 warnings)

Check name Status Explanation Resolution
Security And Privacy ❌ Error docs/users-guide.md contains example token ghp_example using real GitHub token format, violating the requirement that test credentials be clearly fake. Replace ghp_example with an obviously fake token (e.g., fake_token_for_example) in docs/users-guide.md.
Docstring Coverage ⚠️ Warning Docstring coverage is 73.42% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
User-Facing Documentation ⚠️ Warning Programmatic API declared for library consumers but no documentation provided. Users-guide and README focus solely on CLI usage, not the public exports. Document the programmatic API in users-guide or create a library usage guide covering imports, LabelConfig, sync_labels, and embedding examples.
Testing (Unit And Behavioural) ⚠️ Warning BDD tests violate requirements: Gherkin scenario describes user workflow but steps test internal sync_labels() with mocks, duplicating unit test coverage instead of testing functional boundaries. Rewrite BDD to test functional boundary: CLI workflow with TOML config and GitHub API mocking, or use Betamax integration. Remove duplicate test_sync.py coverage.
Testing (Property / Proof) ⚠️ Warning PR introduces invariants (label normalisation, colour formatting, sync idempotency) requiring property tests per AGENTS.md, but Hypothesis tests were deferred as out-of-scope per PR objectives. Add Hypothesis property tests for label normalisation invariants: colour format, name/description trimming, sync idempotency across varied inputs, and URL encoding symmetry.
Testing (Compile-Time / Ui) ⚠️ Warning CLI output lacks snapshot testing. AGENTS.md requires syrupy snapshots for text output; tests use hardcoded string assertions instead. Add syrupy to dev dependencies and implement snapshot tests in tests/test_cli.py for CLI output formatting using assert_text_snapshot().
Observability ⚠️ Warning Operational code lacks observability: no logging at decision points (API calls, auth, repo lookup), no metrics for latency/error rates, no tracing across network boundaries, no alerts. Add structured logging in github.py and sync.py; implement metrics for throughput and error rates; add tracing context for API calls; define actionable alerts for auth and repository failures.
✅ Passed checks (13 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and directly summarises the main purpose of this changeset: importing (implementing) a GitHub label synchronisation CLI tool to replace the generated package stub.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, covering the summary, review walkthrough with specific file references, validation results, and implementation notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Testing (Overall) ✅ Passed Tests are substantive: unit tests cover normalisation, validation, error handling; BDD validates end-to-end flow; integration test uses real github3.py. All three PR blocking issues resolved.
Developer Documentation ✅ Passed Developers' guide documents new APIs (config, sync, github, cli), architecture, data flow, normalization, and testing strategy. No roadmap or execplan exists requiring updates.
Module-Level Documentation ✅ Passed All 13 Python modules carry clear module-level docstrings explaining purpose, utility and relationships to other components, as required by the custom check.
Unit Architecture ✅ Passed Clear separation of query and command paths, explicit error handling, injectable dependencies, immutable data structures, proper test boundaries, and no hidden global state.
Domain Architecture ✅ Passed sync.py is pure domain; config.py translates I/O to ConfigError; github.py adapts github3.py cleanly; cli.py wires layers. Domain models avoid vendor types and environment variables.
Performance And Resource Use ✅ Passed All loops are O(N), memory bounded by design (immutable tuples, ~7KB defaults, TOML-sized configs), I/O intentional and per-label as expected, no unnecessary cloning or async blocking.
Concurrency And State ✅ Passed Production code is single-threaded. Test state protected by threading.Lock. Frozen dataclasses prevent mutation. Proper task cleanup with try/finally. Environment isolation via monkeypatch.
Architectural Complexity And Maintainability ✅ Passed Clean layering with no cycles, justified abstractions enabling isolated testing, config layer enforces invariants, explicit composition, clear maintenance story.
Rust Compiler Lint Integrity ✅ Passed This PR is a Python project with no Rust code; the Rust-specific lint check does not apply.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch import-initial-script

Comment @coderabbitai help to get the list of available commands and usage tips.

@leynos leynos marked this pull request as ready for review May 25, 2026 14:38
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 25f7ac11b0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread create_labels/sync.py Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
tests/test_config.py (1)

33-85: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add a regression test for slash-only github.api_url.

Cover the api_url = "/" case and assert ConfigError so the normalisation edge case does not regress.

🧪 Proposed test
+def test_parse_config_rejects_api_url_empty_after_normalisation() -> None:
+    """Reject API URLs that normalise to an empty string."""
+    with pytest.raises(ConfigError, match="must not be empty after normalisation"):
+        parse_config({"github": {"api_url": "/"}})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_config.py` around lines 33 - 85, Add a regression test that
ensures a slash-only github.api_url (" / ") is rejected: create a new test
(similar to
test_load_config_parses_repository_api_url_and_optional_label_fields) that
writes a TOML with [github] api_url = "/" (or call parse_config with {"github":
{"api_url": "/"}}) and assert it raises ConfigError; reference parse_config and
load_config in the test and assert ConfigError to ensure the API URL
normalization edge-case is covered.
tests/test_sync.py (1)

39-78: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Collapse mirrored failure-path tests into a parameterized test.

Replace the duplicated failure scaffolding with @pytest.mark.parametrize and vary patched callable plus expected error message.

As per coding guidelines: "Replace duplicate tests with @pytest.mark.parametrize".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_sync.py` around lines 39 - 78, Combine the two nearly identical
tests into one parameterized test that calls sync_labels with the same LabelSpec
but varies the patched callable and expected error message; create a single test
(e.g., test_sync_labels_failure_paths) decorated with `@pytest.mark.parametrize`
supplying tuples like ("create_label", lambda... returning None, "GitHub did not
return a label after creating 'risk: low'") and ("update", lambda... returning
False, "GitHub rejected update for label 'risk: low'"), use
make_fake_repository/make_fake_label to produce the repository and existing
label as needed, monkeypatch.setattr on either repository.create_label or
existing.update depending on the parameter, and assert
pytest.raises(RuntimeError, match=expected_message) when calling sync_labels
with LabelSpec("risk: low", "4CAF50", "Low-risk change").
create_labels/github.py (1)

114-145: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add NumPy-style one-line docstrings to private helpers.

Document _login, _repository_from_env, and _effective_labels with single-line summaries to keep helper intent explicit and maintainable.

♻️ Proposed fix
 def _login(token: str | None, api_url: str | None) -> github3.GitHub:
+    """Authenticate with GitHub using a token and optional API base URL."""
     resolved_token = token or os.environ.get("GITHUB_TOKEN")
@@
 def _repository_from_env() -> RepositorySpec | None:
+    """Parse ``GITHUB_REPOSITORY`` into a ``RepositorySpec`` when present."""
     raw_repository = os.environ.get("GITHUB_REPOSITORY")
@@
 def _effective_labels(labels: cabc.Sequence[LabelSpec]) -> tuple[LabelSpec, ...]:
+    """Return configured labels, or defaults when no labels are configured."""
     if labels:
         return tuple(labels)
     return DEFAULT_LABELS

As per coding guidelines "Docstrings must follow the numpy style guide. Use a single-line summary for private functions and methods, and full structured docs for all public interfaces."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@create_labels/github.py` around lines 114 - 145, Add NumPy-style single-line
docstrings to the three private helper functions to state their intent: add a
one-line summary docstring for _login(token: str | None, api_url: str | None)
explaining it resolves token/api URL and returns a GitHub client; for
_repository_from_env() explaining it parses GITHUB_REPOSITORY into a
RepositorySpec or returns None; and for _effective_labels(labels:
cabc.Sequence[LabelSpec]) explaining it returns the provided labels as a tuple
or the DEFAULT_LABELS; place each docstring immediately under the def line
following numpy single-line convention.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@create_labels/config.py`:
- Around line 35-85: Update the public class docstrings to full NumPy style:
replace the summary-only docstrings for ConfigError, RepositorySpec, LabelSpec,
and LabelConfig with structured docstrings containing "Parameters" (or
"Attributes" for dataclasses) and "Raises" where applicable; include types and
brief descriptions for RepositorySpec.owner, RepositorySpec.name,
RepositorySpec.full_name (describe it's a property returning "owner/name"),
LabelSpec.name, LabelSpec.color, LabelSpec.description and describe that
LabelSpec.__post_init__ normalises values and may raise ConfigError for empty
names or invalid colours, and document LabelConfig.repository,
LabelConfig.labels, and LabelConfig.api_url. Ensure wording follows NumPy style
and keep private/internal methods single-line only.
- Around line 170-174: The current code validates raw_api_url before trimming
trailing slashes, allowing inputs like "/" to become empty and be returned as
valid; update the logic in create_labels/config.py to first normalize the input
(normalized = raw_api_url.strip().rstrip("/")), then validate that normalized is
a non-empty string (raise ConfigError with the existing message if not) and
finally return normalized; reference the raw_api_url variable, the returned
value, and the ConfigError raised.

In `@create_labels/sync.py`:
- Around line 114-117: The existing code always calls existing_label.update(...)
which causes unnecessary API writes; change sync logic in the block that
currently calls existing_label.update to first compare existing_label's current
name/color/description to the desired label.name, label.color, and
label.description and if they are identical return LabelSyncResult(label.name,
"unchanged") without calling existing_label.update, otherwise proceed to call
existing_label.update and keep the existing RuntimeError-on-failure behavior.

In `@docs/users-guide.md`:
- Line 48: Replace the word "normalised" with the Oxford/en-GB-oxendict spelling
"normalized" in the sentence that reads "may include a leading `#`; they are
normalised to the six-character hex form" so it becomes "may include a leading
`#`; they are normalized to the six-character hex form".

In `@pyproject.toml`:
- Line 25: Replace the floating VCS dependency string "simulacat @
git+https://github.com/leynos/simulacat" with an immutable ref (a specific tag
or commit SHA) so builds are reproducible; update the pyproject.toml entry for
simulacat to include the chosen tag or full commit hash in the VCS URL (e.g.,
using @<tag-or-sha>) and ensure the package identifier remains "simulacat" so
the resolver picks the pinned ref.

In `@tests/steps/test_synchronise_labels.py`:
- Around line 85-89: The two bare assertions in the test should include
descriptive messages to aid debugging: update the assertion that checks for
LabelSpec(name, _HIGH_RISK_COLOR, _HIGH_RISK_DESC) in
label_sync_context["repository"].created to include a message like "expected
created labels to contain {name} with correct color/desc" and update the
assertion that LabelSyncResult(name, "created") in label_sync_context["results"]
to include a message like "expected label sync results to include created result
for {name}"; modify the test assertions referencing LabelSpec,
label_sync_context, and LabelSyncResult accordingly so failures print those
explanatory messages.
- Around line 75-76: Tests use bare assertions at the two checks for
label.updates and label_sync_context results; update both assertions to include
descriptive messages: for the first assertion about label.updates (comparing to
[LabelSpec(name, _LOW_RISK_COLOR, _LOW_RISK_DESC)]) add a message explaining
expected updates (e.g., expected low-risk LabelSpec for name), and for the
second assertion that LabelSyncResult(name, "updated") is in
label_sync_context["results"] add a message clarifying the expected sync result;
locate these in tests/steps/test_synchronise_labels.py referencing
label.updates, LabelSpec, _LOW_RISK_COLOR, _LOW_RISK_DESC, LabelSyncResult and
label_sync_context to modify the assert statements to use the form assert
<condition>, "<descriptive message>".

---

Outside diff comments:
In `@create_labels/github.py`:
- Around line 114-145: Add NumPy-style single-line docstrings to the three
private helper functions to state their intent: add a one-line summary docstring
for _login(token: str | None, api_url: str | None) explaining it resolves
token/api URL and returns a GitHub client; for _repository_from_env() explaining
it parses GITHUB_REPOSITORY into a RepositorySpec or returns None; and for
_effective_labels(labels: cabc.Sequence[LabelSpec]) explaining it returns the
provided labels as a tuple or the DEFAULT_LABELS; place each docstring
immediately under the def line following numpy single-line convention.

In `@tests/test_config.py`:
- Around line 33-85: Add a regression test that ensures a slash-only
github.api_url (" / ") is rejected: create a new test (similar to
test_load_config_parses_repository_api_url_and_optional_label_fields) that
writes a TOML with [github] api_url = "/" (or call parse_config with {"github":
{"api_url": "/"}}) and assert it raises ConfigError; reference parse_config and
load_config in the test and assert ConfigError to ensure the API URL
normalization edge-case is covered.

In `@tests/test_sync.py`:
- Around line 39-78: Combine the two nearly identical tests into one
parameterized test that calls sync_labels with the same LabelSpec but varies the
patched callable and expected error message; create a single test (e.g.,
test_sync_labels_failure_paths) decorated with `@pytest.mark.parametrize`
supplying tuples like ("create_label", lambda... returning None, "GitHub did not
return a label after creating 'risk: low'") and ("update", lambda... returning
False, "GitHub rejected update for label 'risk: low'"), use
make_fake_repository/make_fake_label to produce the repository and existing
label as needed, monkeypatch.setattr on either repository.create_label or
existing.update depending on the parameter, and assert
pytest.raises(RuntimeError, match=expected_message) when calling sync_labels
with LabelSpec("risk: low", "4CAF50", "Low-risk change").
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 32929be9-f086-460e-a315-f2153de477be

📥 Commits

Reviewing files that changed from the base of the PR and between 18c6337 and 25f7ac1.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (21)
  • AGENTS.md
  • README.md
  • create_labels/__init__.py
  • create_labels/cli.py
  • create_labels/config.py
  • create_labels/defaults.py
  • create_labels/github.py
  • create_labels/pure.py
  • create_labels/sync.py
  • docs/scripting-standards.md
  • docs/users-guide.md
  • pyproject.toml
  • tests/features/synchronise_labels.feature
  • tests/fixtures/repository_payload.json
  • tests/steps/test_synchronise_labels.py
  • tests/test_cli.py
  • tests/test_config.py
  • tests/test_github_betamax.py
  • tests/test_helpers.py
  • tests/test_stub.py
  • tests/test_sync.py
💤 Files with no reviewable changes (4)
  • README.md
  • tests/test_stub.py
  • AGENTS.md
  • create_labels/pure.py

Comment thread create_labels/config.py
Comment thread create_labels/config.py Outdated
Comment thread create_labels/sync.py
Comment thread docs/users-guide.md Outdated
Comment thread pyproject.toml Outdated
Comment thread tests/steps/test_synchronise_labels.py Outdated
Comment thread tests/steps/test_synchronise_labels.py Outdated
leynos added 2 commits May 25, 2026 16:35
Reject slash-only GitHub API URLs after normalization and skip
GitHub label updates when existing metadata already matches the desired
configuration.

Pin the `simulacat` development dependency to an immutable revision,
expand public configuration docstrings, and tighten regression coverage
for the reviewed sync and parsing paths.
Quote label names before calling `repository.label` so slash-containing
names are sent as a single path segment to github3.py. Keep create and
update payload names unchanged.

Add regression coverage for `scope: channel/cli` and teach the fake
repository to resolve encoded lookup path segments.
@coderabbitai coderabbitai Bot added the Roadmap label May 25, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@create_labels/sync.py`:
- Around line 118-126: Normalize the remote label fields before comparing so the
equality check is idempotent: for existing_label.color remove any leading '#'
and uppercase it (so it matches LabelSpec's uppercase hex) and for
existing_label.description convert null to None and otherwise strip() whitespace
(preserving None when GitHub returns null) then build existing_values from these
normalized values and compare to desired_values; update the equality check
around existing_label, label and LabelSyncResult so unchanged is returned only
when normalized fields match.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: bf779d3b-df3d-4060-8088-1b8ee71ed1f8

📥 Commits

Reviewing files that changed from the base of the PR and between 25f7ac1 and 42ace0f.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • create_labels/config.py
  • create_labels/github.py
  • create_labels/sync.py
  • docs/users-guide.md
  • pyproject.toml
  • tests/steps/test_synchronise_labels.py
  • tests/test_config.py
  • tests/test_sync.py

Comment thread create_labels/sync.py
leynos added 2 commits May 25, 2026 19:39
Normalize GitHub label colour and description fields before comparing
them with `LabelSpec` values. This keeps repeated sync runs idempotent
when GitHub returns lowercase colours, leading `#`, or padded
descriptions.

Add regression coverage for the unchanged path so those formatting
differences do not trigger redundant updates.
Document `--config` usage and add a developers guide for the package
boundaries, data flow, normalization rules, and local workflow.

Extend regression coverage for null GitHub descriptions, GitHub adapter
error paths, and all CLI sync result actions. Add private helper
docstrings so package docstring coverage includes internal boundaries.

Guard the Betamax request recorder with a lock because the mock server
records requests from its own thread.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@create_labels/sync.py`:
- Line 107: The private docstring that currently reads "Synchronise one label
and return its action." should use the Oxford -ize spelling; change
"Synchronise" to "Synchronize" so the docstring becomes "Synchronize one label
and return its action." Update the triple-quoted docstring string (the one
containing that exact sentence) in create_labels/sync.py accordingly to match
project docstyle.

In `@docs/developers-guide.md`:
- Line 3: Update the wording in docs/developers-guide.md by replacing the
British-spelled word "summarises" with the Oxford -ize variant "summarizes" on
the line that currently reads "This guide summarises the package structure,
internal boundaries, and local".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 488cae34-7245-48fe-9df8-bd9a462ff6b7

📥 Commits

Reviewing files that changed from the base of the PR and between 5d4d0df and e8710f0.

📒 Files selected for processing (8)
  • create_labels/config.py
  • create_labels/sync.py
  • docs/developers-guide.md
  • docs/users-guide.md
  • tests/test_cli.py
  • tests/test_github.py
  • tests/test_github_betamax.py
  • tests/test_sync.py

Comment thread create_labels/sync.py Outdated
Comment thread docs/developers-guide.md Outdated
Add standalone `dependencies`, `github-actions`, and `cargo` labels to
the default label set so repositories receive those common automation
and package-management labels without custom TOML.

Update the default-label regression test to assert the expanded count and
the three new label specs explicitly.
@leynos
Copy link
Copy Markdown
Owner Author

leynos commented May 25, 2026

@coderabbitai Have the following failed checks now been resolved?

If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures.

Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already.

❌ Failed checks (2 errors, 11 warnings)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error Vacuous test: unchanged label test uses exact-match values, passes without normalization. sync.py doesn't normalise existing_label fields before comparison per review comment. Normalise existing_label colour and description before comparison. Add tests with realistic GitHub formats (lowercase colours, null descriptions).
Unit Architecture ❌ Error Label field comparison in sync.py fails to normalise existing remote fields (colour case, description whitespace) before equality check, violating idempotency: queries must be side-effect-free. Normalise existing_label.color (uppercase) and description (strip whitespace) in _sync_label before line 119-126 comparison to ensure unchanged labels are correctly identified.
Docstring Coverage ⚠️ Warning Docstring coverage is 68.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
User-Facing Documentation ⚠️ Warning The --config CLI parameter is not documented in docs/users-guide.md, forcing users to discover it via --help or source code. Document the --config parameter in docs/users-guide.md with an example showing how to pass a TOML file path. Note that defaults apply when omitted.
Developer Documentation ⚠️ Warning docs/developers-guide.md does not exist. PR introduces new APIs (LabelConfig, LabelSpec, sync_labels, load_config) and architectural boundaries requiring developer documentation. Create docs/developers-guide.md documenting the package architecture, module organisation, data flow, internal APIs, and development procedures.
Testing (Unit And Behavioural) ⚠️ Warning No test verifies "unchanged" when remote label color differs only by case or description by whitespace; sync.py doesn't normalize existing_label fields before equality check, breaking idempotency. Add tests for "unchanged" when remote label differs only by normalisation (case/whitespace); add github.py GitHubError tests and CLI error cases.
Testing (Property / Proof) ⚠️ Warning Normalization invariants (colour to uppercase, description trimming) are enforced in LabelSpec but sync doesn't verify idempotency with denormalised GitHub values, flagged in review. Introduce property tests with hypothesis to verify sync_labels returns "unchanged" for any colour/description variants matching after normalisation, ensuring idempotency.
Testing (Compile-Time / Ui) ⚠️ Warning CLI outputs structured text results without snapshot testing. Literal string assertions exist but only cover one result type; no snapshots for all three (created/updated/unchanged). Implement snapshot testing for CLI output using Syrupy or Insta. Cover all three result types with stable serialization and explicit nondeterministic field redaction.
Domain Architecture ⚠️ Warning sync.py compares raw GitHub label data with normalized LabelSpec without normalizing colour/description, breaking idempotency and domain separation. Normalise existing_label.color (.upper()) and existing_label.description (.strip()) before equality check in _sync_label (lines 119-126) to match domain invariants.
Observability ⚠️ Warning PR adds operational behaviour (GitHub API mutations, config loading, network I/O) without logging, metrics, tracing, or structured error context needed to diagnose failures in production. Add debug/info logging at decision points; include operation context (repo, label count, HTTP status); capture metrics for API failures and latency; use structured exceptions with diagnostic fields.
Performance And Resource Use ⚠️ Warning Colour and description values are compared without normalisation before the idempotency check, breaking sync on every run since GitHub returns lowercase hex and null descriptions. Normalise existing_label.color and existing_label.description before line 125 equality check in create_labels/sync.py, matching LabelSpec's normalisation logic.
Concurrency And State ⚠️ Warning Unguarded shared mutable requests list in test accessed by concurrent threads; sync code doesn't normalise remote label fields before comparison, breaking idempotency. Add thread lock to guard requests list in test; normalise existing_label.color.upper() and description whitespace before equality check in _sync_label.
Architectural Complexity And Maintainability ⚠️ Warning Architecture is sound: well-layered, justified abstractions, no cycles. However, sync.py fails to normalize remote fields before comparison, breaking idempotency per review comments. Normalise existing_label.color.upper() and description.strip() in _sync_label() before equality comparison to maintain idempotency with GitHub's API responses.

Update the reviewed sync helper docstring and developers guide wording
to use the project style-guide -ize spelling.
@coderabbitai

This comment was marked as resolved.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented May 26, 2026

@coderabbitai Please investigate the cause of the following issue using codegraph exploration and research, identify a fix and provide an AI coding agent prompt for the fix:

============================= test session starts ==============================
platform linux -- Python 3.14.5, pytest-9.0.3, pluggy-1.6.0 -- /home/runner/work/create-labels/create-labels/.venv-coverage/bin/python
cachedir: .pytest_cache
rootdir: /home/runner/work/create-labels/create-labels
configfile: pyproject.toml
plugins: xdist-3.8.0, slipcover-1.0.18, betamax-0.9.0, timeout-2.4.0, simulacat-0.1.0, bdd-8.1.0
timeout: 30.0s
timeout method: signal
timeout func_only: False
collecting ... collected 27 items

tests/steps/test_synchronise_labels.py::test_create_and_update_configured_labels PASSED [  3%]
tests/test_cli.py::test_main_loads_config_and_prints_sync_results PASSED [  7%]
tests/test_cli.py::test_main_prints_each_sync_result_action[result0-created: risk: low\n] PASSED [ 11%]
tests/test_cli.py::test_main_prints_each_sync_result_action[result1-updated: risk: medium\n] PASSED [ 14%]
tests/test_cli.py::test_main_prints_each_sync_result_action[result2-unchanged: risk: high\n] PASSED [ 18%]
tests/test_cli.py::test_main_rejects_malformed_repository[] PASSED       [ 22%]
tests/test_cli.py::test_main_rejects_malformed_repository[owner] PASSED  [ 25%]
tests/test_cli.py::test_main_rejects_malformed_repository[owner/] PASSED [ 29%]
tests/test_cli.py::test_main_rejects_malformed_repository[/name] PASSED  [ 33%]
tests/test_cli.py::test_main_rejects_malformed_repository[owner/name/extra] PASSED [ 37%]
tests/test_config.py::test_default_labels_import_original_shell_script_set PASSED [ 40%]
tests/test_config.py::test_load_config_parses_repository_api_url_and_optional_label_fields PASSED [ 44%]
tests/test_config.py::test_config_rejects_slash_only_api_url PASSED      [ 48%]
tests/test_config.py::test_parse_config_rejects_duplicate_labels PASSED  [ 51%]
tests/test_config.py::test_parse_config_rejects_malformed_colours PASSED [ 55%]
tests/test_github.py::test_sync_repository_labels_requires_repository FAILED [ 59%]
tests/test_github.py::test_sync_repository_labels_rejects_malformed_environment_repository PASSED [ 62%]
tests/test_github.py::test_sync_repository_labels_requires_token PASSED  [ 66%]
tests/test_github_betamax.py::test_sync_labels_uses_github3_requests_recorded_by_betamax PASSED [ 70%]
tests/test_sync.py::test_sync_labels_creates_missing_labels PASSED       [ 74%]
tests/test_sync.py::test_sync_labels_updates_existing_labels PASSED      [ 77%]
tests/test_sync.py::test_sync_labels_leaves_matching_existing_labels_unchanged PASSED [ 81%]
tests/test_sync.py::test_sync_labels_normalizes_existing_label_fields_before_comparison PASSED [ 85%]
tests/test_sync.py::test_sync_labels_preserves_null_descriptions_when_comparing PASSED [ 88%]
tests/test_sync.py::test_sync_labels_url_encodes_names_for_lookup PASSED [ 92%]
tests/test_sync.py::test_sync_labels_failure_paths[create_label-GitHub did not return a label after creating 'risk: low'] PASSED [ 96%]
tests/test_sync.py::test_sync_labels_failure_paths[update-GitHub rejected update for label 'risk: low'] PASSED [100%]

=================================== FAILURES ===================================
_______________ test_sync_repository_labels_requires_repository ________________

    def test_sync_repository_labels_requires_repository() -> None:
        """Repository coordinates must come from CLI, config, or environment."""
        auth_value = "sample-auth-value"
    
        with pytest.raises(GitHubError, match="Repository must be provided"):
>           sync_repository_labels(
                config=LabelConfig(None, ()),
                repository=None,
                token=auth_value,
                api_url=None,
            )

tests/test_github.py:16: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
create_labels/github.py:102: in sync_repository_labels
    github_repository = github.repository(
.venv-coverage/lib/python3.14/site-packages/github3/github.py:2103: in repository
    json = self._json(self._get(url), 200)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <GitHub [token samp...]>, response = <Response [401]>
expected_status_code = 200, include_cache_info = True

    def _json(self, response, expected_status_code, include_cache_info=True):
        ret = None
        if response is None:
            return None
    
        actual_status_code = response.status_code
        if actual_status_code != expected_status_code:
            if actual_status_code >= 400:
>               raise exceptions.error_for(response)
E               github3.exceptions.AuthenticationFailed: 401 Bad credentials

.venv-coverage/lib/python3.14/site-packages/github3/models.py:161: AuthenticationFailed
=============================== warnings summary ===============================
.venv-coverage/lib/python3.14/site-packages/_pytest/config/__init__.py:1309
  /home/runner/work/create-labels/create-labels/.venv-coverage/lib/python3.14/site-packages/_pytest/config/__init__.py:1309: PytestAssertRewriteWarning: Module already imported so cannot be rewritten; slipcover
    self._mark_plugins_for_rewrite(hook, disable_autoload)

tests/test_github_betamax.py::test_sync_labels_uses_github3_requests_recorded_by_betamax
  /home/runner/work/create-labels/create-labels/.venv-coverage/lib/python3.14/site-packages/betamax/adapter.py:105: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
    now = datetime.utcnow()

tests/test_github_betamax.py::test_sync_labels_uses_github3_requests_recorded_by_betamax
tests/test_github_betamax.py::test_sync_labels_uses_github3_requests_recorded_by_betamax
tests/test_github_betamax.py::test_sync_labels_uses_github3_requests_recorded_by_betamax
tests/test_github_betamax.py::test_sync_labels_uses_github3_requests_recorded_by_betamax
tests/test_github_betamax.py::test_sync_labels_uses_github3_requests_recorded_by_betamax
  /home/runner/work/create-labels/create-labels/.venv-coverage/lib/python3.14/site-packages/betamax/util.py:166: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
    stamp = datetime.utcnow().isoformat()

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED tests/test_github.py::test_sync_repository_labels_requires_repository - github3.exceptions.AuthenticationFailed: 401 Bad credentials
=================== 1 failed, 26 passed, 7 warnings in 1.08s ===================

@coderabbitai

This comment was marked as resolved.

leynos added 4 commits May 26, 2026 11:44
Move github3-specific label lookup handling into the GitHub adapter so
the sync module depends only on its repository protocol.

Snapshot Betamax-recorded requests under the request lock before assertions
and expand the package README and public API module documentation.
Guard the shared Betamax request list with the requested private class
lock and snapshot recorded requests under that lock before assertions.
Document the expected validation layers for new features, including
`pytest`, `pytest-bdd`, snapshots, end-to-end tests, property tests, and
proof-backed contractual logic where appropriate.

Clarify where design decisions, user-facing changes, and internal
interfaces or practices should be documented.
Ensure the missing-repository test removes `GITHUB_REPOSITORY` so GitHub
Actions does not bypass the guard by injecting repository coordinates.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@create_labels/__init__.py`:
- Around line 4-7: The module docstring currently uses British -ise spelling
"synchronisation"; update the docstring to use Oxford -ize spelling by replacing
"synchronisation" with "synchronization" in the public API sentence that
mentions create_labels.sync, and ensure any other occurrences in this docstring
follow the -ize/-yse/-our conventions (e.g., change "synchronisation function"
to "synchronization function" while keeping references to create_labels.config
and create_labels.defaults unchanged).

In `@create_labels/sync.py`:
- Line 13: Update the module-level example sentence that currently reads
"Synchronise two labels against a repository-like object::" to use Oxford -ize
spelling by replacing "Synchronise" with "Synchronize" (i.e., change the
top-level docstring/comment string so it reads "Synchronize two labels against a
repository-like object::"); locate the module-level docstring or top-of-file
comment in the create_labels sync module and make this single-word substitution.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 57de80ef-37ae-4b02-96d3-bdb40352284c

📥 Commits

Reviewing files that changed from the base of the PR and between c6d2e31 and 5d0733a.

📒 Files selected for processing (8)
  • AGENTS.md
  • README.md
  • create_labels/__init__.py
  • create_labels/github.py
  • create_labels/sync.py
  • tests/test_github.py
  • tests/test_github_betamax.py
  • tests/test_sync.py

Comment thread create_labels/__init__.py
Comment on lines +4 to 7
re-exports typed configuration values from ``create_labels.config``, the
imported default label set from ``create_labels.defaults``, and the pure label
synchronisation function and result type from ``create_labels.sync``.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use Oxford -ize spelling in the module docstring.

Replace synchronisation with synchronization in the public API description.

Triage: [type:spelling] [type:docstyle]

📝 Proposed fix
-... and the pure label synchronisation function and result type from ``create_labels.sync``.
+... and the pure label synchronization function and result type from ``create_labels.sync``.

As per coding guidelines: "**/*.py: Comments and docs must follow en-GB-oxendict (-ize / -yse / -our) spelling and grammar."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
re-exports typed configuration values from ``create_labels.config``, the
imported default label set from ``create_labels.defaults``, and the pure label
synchronisation function and result type from ``create_labels.sync``.
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``.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@create_labels/__init__.py` around lines 4 - 7, The module docstring currently
uses British -ise spelling "synchronisation"; update the docstring to use Oxford
-ize spelling by replacing "synchronisation" with "synchronization" in the
public API sentence that mentions create_labels.sync, and ensure any other
occurrences in this docstring follow the -ize/-yse/-our conventions (e.g.,
change "synchronisation function" to "synchronization function" while keeping
references to create_labels.config and create_labels.defaults unchanged).

Comment thread create_labels/sync.py

Example
-------
Synchronise two labels against a repository-like object::
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use Oxford -ize spelling in the module example sentence.

Replace Synchronise with Synchronize.

Triage: [type:spelling] [type:docstyle]

📝 Proposed fix
-Synchronise two labels against a repository-like object::
+Synchronize two labels against a repository-like object::

As per coding guidelines: "**/*.py: Comments and docs must follow en-GB-oxendict (-ize / -yse / -our) spelling and grammar."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Synchronise two labels against a repository-like object::
Synchronize two labels against a repository-like object::
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@create_labels/sync.py` at line 13, Update the module-level example sentence
that currently reads "Synchronise two labels against a repository-like object::"
to use Oxford -ize spelling by replacing "Synchronise" with "Synchronize" (i.e.,
change the top-level docstring/comment string so it reads "Synchronize two
labels against a repository-like object::"); locate the module-level docstring
or top-of-file comment in the create_labels sync module and make this
single-word substitution.

Add a documentation contents page and repository layout reference so
maintainers have clear entrypoints for project guides and source-tree
orientation.

Reference both documents from `AGENTS.md` as the starting point for
documentation and repository context.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant