Skip to content

Add azpysdk changelog command group wrapping Chronus#46016

Draft
Copilot wants to merge 8 commits intomainfrom
copilot/azpysdk-add-chronus-capabilities
Draft

Add azpysdk changelog command group wrapping Chronus#46016
Copilot wants to merge 8 commits intomainfrom
copilot/azpysdk-add-chronus-capabilities

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 31, 2026

Integrates Chronus changelog management into the azpysdk CLI so developers don't need to use npx chronus directly.

New subcommands

Command Delegates to Purpose
azpysdk changelog add [package] npx chronus add Add a change entry (interactive or non-interactive)
azpysdk changelog verify npx chronus verify Check modified packages have entries
azpysdk changelog create npx chronus changelog Generate CHANGELOG.md from entries
azpysdk changelog status npx chronus status Show pending changes / version bumps

Commands work from both the repository root and from within a package directory. When running azpysdk changelog add from inside a package folder (e.g. sdk/storage/azure-storage-blob), the package path is detected automatically and passed to chronus. An explicit package argument always takes precedence.

The add subcommand supports --kind (-k) and --message (-m) flags for non-interactive use, including tagging entries as breaking changes. Valid kinds: breaking, feature, deprecation, fix, dependencies, internal. If omitted, chronus falls back to its interactive prompts.

Changes

  • azpysdk/changelog.py — New changelog Check subclass. Runs npx chronus <cmd> from repo root with inherited stdio for interactive prompts. Auto-detects package path from CWD when inside an sdk/<service>/<package> directory. Supports --kind and --message flags on add for non-interactive change entry creation (e.g. breaking changes). Errors clearly when Node.js/npx is missing.
  • azpysdk/main.py — Import and register the changelog command.
  • tests/test_changelog_commands.py — 41 tests covering parser structure, correct argument passthrough, --kind/--message flag forwarding, CWD-based package detection, repo-root cwd, exit code propagation, and npx-missing error handling.
# Example usage — from repo root
azpysdk changelog add sdk/storage/azure-storage-blob
azpysdk changelog add --kind breaking -m "Removed deprecated API"
azpysdk changelog add sdk/core/azure-core -k feature -m "Added new endpoint"
azpysdk changelog verify
azpysdk changelog create

# Example usage — from inside a package directory
cd sdk/storage/azure-storage-blob
azpysdk changelog add    # auto-detects the package
azpysdk changelog add -k fix -m "Fixed upload bug"

Copilot AI linked an issue Mar 31, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Add chronus capabilities to azpysdk Add azpysdk changelog command group wrapping Chronus Mar 31, 2026
Copilot AI requested a review from l0lawrence March 31, 2026 16:26

Wraps Chronus CLI commands (add, verify, create, status) so they can be
invoked through the ``azpysdk`` CLI. Unlike most checks that operate on
individual packages, changelog commands run at the **repository root**
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot I dont think they have to run at the repo root we should make it work at the root or in the pkg folder

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated in c506c82. azpysdk changelog add now auto-detects the package when CWD is inside a package directory (e.g. sdk/storage/azure-storage-blob or any subdirectory). An explicit package argument still takes precedence. Chronus itself always runs from the repo root since it needs .chronus/config.yaml.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 31, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • scanning-api.github.com
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node /home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps /home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from l0lawrence March 31, 2026 16:46
@l0lawrence
Copy link
Copy Markdown
Member

This should also support breaking changes — e.g. a --breaking flag on azpysdk changelog add or a way to tag entries as breaking so Chronus generates the appropriate changelog section and version bump.

@l0lawrence
Copy link
Copy Markdown
Member

This should also support breaking changes — e.g. a --breaking flag on azpysdk changelog add or a way to tag entries as breaking so Chronus generates the appropriate changelog section and version bump.

@copilot

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 7, 2026

This should also support breaking changes — e.g. a --breaking flag on azpysdk changelog add or a way to tag entries as breaking so Chronus generates the appropriate changelog section and versi...

Added in f63e08c. azpysdk changelog add now supports --kind (-k) and --message (-m) flags that forward directly to chronus's native options. Valid kinds are: breaking, feature, deprecation, fix, dependencies, internal.

Examples:

azpysdk changelog add --kind breaking -m "Removed deprecated API"
azpysdk changelog add sdk/core/azure-core -k feature -m "Added new endpoint"

If --kind or --message are omitted, chronus falls back to its interactive prompts as before.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • registry.npmjs.org
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/_temp/ghcca-node/node/bin/npx --no chronus add --help (dns block)
  • timotheeguerin.github.io
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node /home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps /home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@l0lawrence
Copy link
Copy Markdown
Member

@copilot There are several issues to fix in this PR:

1. Read _CHANGE_KINDS from .chronus/config.yaml instead of hardcoding

In eng/tools/azure-sdk-tools/azpysdk/changelog.py, the _CHANGE_KINDS list is hardcoded and will silently diverge from .chronus/config.yaml. Instead, read the change kinds dynamically from the config file at module load time (with the hardcoded list as a fallback). Use pyyaml (already available in the repo) to parse .chronus/config.yaml and extract the keys from changeKinds. Add a helper function like:

def _load_change_kinds() -> List[str]:
    config_path = os.path.join(REPO_ROOT, ".chronus", "config.yaml")
    try:
        import yaml
        with open(config_path) as f:
            config = yaml.safe_load(f)
        kinds = list(config.get("changeKinds", {}).keys())
        if kinds:
            return kinds
    except Exception:
        pass
    return ["breaking", "feature", "deprecation", "fix", "dependencies", "internal"]

Then use _CHANGE_KINDS = _load_change_kinds() and add a test that validates the loaded kinds match what's in the config file.

2. Don't auto-install in non-TTY/CI without explicit opt-in

In _ensure_chronus_installed, the current code automatically runs npm install when stdin is not a TTY (CI environments). This is surprising and slow. Instead, require an explicit opt-in via the AZPYSDK_AUTO_INSTALL environment variable. Change the non-interactive branch to:

if not sys.stdin.isatty():
    if not os.environ.get("AZPYSDK_AUTO_INSTALL"):
        logger.error(
            "Chronus is not installed and running in non-interactive mode.\n"
            "Set AZPYSDK_AUTO_INSTALL=1 to allow automatic installation, or run:\n\n"
            f"    cd {REPO_ROOT}\n"
            "    npm install\n"
        )
        raise SystemExit(1)
    logger.info("AZPYSDK_AUTO_INSTALL set - running 'npm install' automatically.")

Update the corresponding tests to check for the env var behavior.

3. Use args.package directly instead of getattr

In _run_add, replace getattr(args, "package", None) with args.package since add_argument always sets the attribute. Same for args.kind and args.message. The getattr pattern is misleading - it suggests the attribute might not exist.

4. Avoid storing parser as private attr on Namespace

In _no_subcommand, accessing args._changelog_parser relies on a private attribute stashed on the Namespace. Instead, store the parser reference as an instance attribute on the changelog class itself (e.g. self._parser = p) and reference self._parser.print_help() in _no_subcommand.

Please make all four fixes and update the tests accordingly.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 7, 2026

@copilot There are several issues to fix in this PR:

1. Read _CHANGE_KINDS from .chronus/config.yaml instead of hardcoding...

All four fixes applied in 358c1c6:

  1. Dynamic change kinds_load_change_kinds() reads .chronus/config.yaml via pyyaml at module load, falls back to _FALLBACK_CHANGE_KINDS if config is missing or unparseable. New test validates loaded kinds match the config file.

  2. AZPYSDK_AUTO_INSTALL gate — Non-interactive mode now exits with an actionable error unless AZPYSDK_AUTO_INSTALL=1 is set. Two new tests cover both paths.

  3. Direct attribute access — Replaced getattr(args, "package", None) etc. with args.package, args.kind, args.message.

  4. Parser on instanceself._parser stores the parser reference; _no_subcommand uses self._parser.print_help() instead of args._changelog_parser.

45 tests passing.

@l0lawrence
Copy link
Copy Markdown
Member

@copilot if the user does not have chronus installed, install it for them and log it

@l0lawrence
Copy link
Copy Markdown
Member

@copilot if the user does not have chronus installed, install it for them and log it

@copilot

l0lawrence pushed a commit that referenced this pull request Apr 22, 2026
…iscovery

Two CI failures on PR #46016:

1. static-analysis (black): changelog.py and test_changelog_commands.py failed 'black --check'. Applied black with the repo's eng/black-pyproject.toml config.

2. verify-azpysdk-checks: the workflow discovers checks by scraping 'azpysdk -h' and invokes each one as 'azpysdk <check> --isolate <package>'. The changelog command group rejects --isolate (it's a developer tool wrapping Chronus, not a per-package check) and exits 2. Filter 'changelog' out of the discovery pipeline, same way 'next-*' checks are already filtered.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI and others added 6 commits April 22, 2026 15:21
Adds `azpysdk changelog {add,verify,create,status}` subcommands that
delegate to `npx chronus` at the repository root, enabling developers
to manage changelogs without leaving the azpysdk CLI.

Agent-Logs-Url: https://github.com/Azure/azure-sdk-for-python/sessions/a188ee1e-f36a-4ca9-be34-654196dd5328

Co-authored-by: l0lawrence <100643745+l0lawrence@users.noreply.github.com>
When running `azpysdk changelog add` from within a package directory
(e.g. sdk/storage/azure-storage-blob), the package path is now detected
automatically and passed to chronus. An explicit package argument still
takes precedence. Chronus itself always runs from the repo root.

Agent-Logs-Url: https://github.com/Azure/azure-sdk-for-python/sessions/758fb61b-770f-40c1-91a6-108220c6a402

Co-authored-by: l0lawrence <100643745+l0lawrence@users.noreply.github.com>
Add --kind (-k) and --message (-m) flags to `azpysdk changelog add`
that forward to chronus's native --kind and --message options. This
lets developers tag entries as breaking (or any other change kind)
non-interactively:

  azpysdk changelog add --kind breaking -m "Removed deprecated API"
  azpysdk changelog add -k feature -m "Added new endpoint"

Valid kinds: breaking, feature, deprecation, fix, dependencies, internal

Also fix _ensure_chronus_installed to skip the interactive prompt
when stdin is not a TTY (non-interactive / CI environments).

Agent-Logs-Url: https://github.com/Azure/azure-sdk-for-python/sessions/aa3dee26-9283-4594-a49f-64fc64d3d995

Co-authored-by: l0lawrence <100643745+l0lawrence@users.noreply.github.com>
…ct attr access, parser on instance

1. Read _CHANGE_KINDS from .chronus/config.yaml via _load_change_kinds()
   with hardcoded fallback when config or pyyaml is unavailable.
2. Non-interactive (CI) mode now requires AZPYSDK_AUTO_INSTALL=1 env var
   before running npm install automatically.
3. Use args.package/args.kind/args.message directly instead of getattr.
4. Store parser reference as self._parser on the changelog class instance
   instead of stashing a private attr on the argparse Namespace.

Agent-Logs-Url: https://github.com/Azure/azure-sdk-for-python/sessions/c9c4bf6e-9283-48b9-9861-00062d368e90

Co-authored-by: l0lawrence <100643745+l0lawrence@users.noreply.github.com>
@l0lawrence l0lawrence force-pushed the copilot/azpysdk-add-chronus-capabilities branch from ee4e1f5 to 2aae69b Compare April 22, 2026 22:23
l0lawrence and others added 2 commits April 23, 2026 08:39
Co-authored-by: Copilot <copilot@github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[azpysdk] add chronus capabilities to azpysdk

2 participants