diff --git a/.github/workflows/release-pypi.yml b/.github/workflows/release-pypi.yml index e03c792..893f2d2 100644 --- a/.github/workflows/release-pypi.yml +++ b/.github/workflows/release-pypi.yml @@ -1,14 +1,12 @@ name: publish-pypi on: - release: - types: [published] push: tags: - "v*" permissions: - contents: read + contents: write jobs: build: @@ -52,9 +50,58 @@ jobs: - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@release/v1 - publish-mcp-registry: + create-github-release: runs-on: ubuntu-latest needs: publish-pypi + steps: + - uses: actions/checkout@v7 + + - name: Extract changelog section + env: + RELEASE_TAG: ${{ github.ref_name }} + run: | + python - <<'PY' + from pathlib import Path + import os + + tag = os.environ["RELEASE_TAG"] + version = tag.removeprefix("v") + changelog = Path("CHANGELOG.md").read_text(encoding="utf-8").splitlines() + + start = None + end = None + heading = f"## {version} - " + for index, line in enumerate(changelog): + if line.startswith(heading): + start = index + continue + if start is not None and line.startswith("## "): + end = index + break + + if start is None: + raise SystemExit( + f"Could not find CHANGELOG.md section for version {version}." + ) + + if end is None: + end = len(changelog) + + section = "\n".join(changelog[start:end]).strip() + "\n" + Path("release-notes.md").write_text(section, encoding="utf-8") + PY + + - name: Create GitHub release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.ref_name }} + name: ${{ github.ref_name }} + body_path: release-notes.md + generate_release_notes: false + + publish-mcp-registry: + runs-on: ubuntu-latest + needs: create-github-release permissions: id-token: write # required for GitHub OIDC authentication with MCP Registry contents: read diff --git a/AGENTS.md b/AGENTS.md index c059470..f01d92c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -148,9 +148,32 @@ not part of `check` itself so the default gate stays fast. ## Release -1. Bump version in `pyproject.toml`, `src/deep_agentic_core_mcp/__init__.py`, and `CHANGELOG.md` -2. Commit: `git commit -am "release: vX.Y.Z"` -3. Tag: create an annotated `vX.Y.Z` tag and use the latest `CHANGELOG.md` - release section as the tag description -4. Push: `git push origin main --tags` -5. Create a GitHub Release — the workflow publishes to PyPI and the MCP Registry +Two phases, split by the merge to `main` — bumping happens before, and the +tag-driven release automation happens after. + +**1. Pre-release (on the feature branch, before merge):** Bump version in +`pyproject.toml`, `src/deep_agentic_core_mcp/__init__.py`, and +`CHANGELOG.md` (a dated release section under `[Unreleased]`). Commit as +part of the branch's normal history; goes in with the rest of the PR. + +**2. Release (on `main`, once that branch has merged):** + +1. Pull the merge commit on `main`. +2. Tag: create an annotated `vX.Y.Z` tag pointing at the merge commit, + using the `CHANGELOG.md` release section for that version as the tag + message: + `git tag -a vX.Y.Z -F --cleanup=verbatim`. + `--cleanup=verbatim` is required — git's default cleanup silently strips + lines starting with `#`, which would eat the changelog's `###` headers. +3. Push the tag: `git push origin vX.Y.Z`. + +That tag push is the release trigger. `release-pypi.yml` runs automatically +from the same tag and does all of the following: + +- publishes the package to PyPI via Trusted Publishing (OIDC) +- creates the GitHub Release object for `vX.Y.Z` +- publishes the server to the MCP Registry + +The GitHub Release title is the tag name, and its body is copied from the +matching `CHANGELOG.md` section so the changelog, tag, PyPI release, +GitHub Releases page, and MCP Registry publish all stay aligned. diff --git a/ROADMAP.md b/ROADMAP.md index 56dc6a6..6927fa0 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -328,6 +328,10 @@ Goals: - surface incident, evaluation, and readiness evidence through one interface - expose a high-level control surface for the main developer questions: what happened, what changed, what failed, and is this workflow ready +- define the first Control Tower integration path once + `agenticops-control-tower` ships a real control API, starting with + read-only operator queries and keeping authorization-sensitive write + operations out of scope until audit/auth boundaries are clear Possible tools: @@ -335,6 +339,18 @@ Possible tools: - `core.export_report` - `core.incident_summary` - `core.release_check` +- `control_tower.list_agents` +- `control_tower.list_unhealthy_agents` +- `control_tower.capability_summary` + +Control Tower integration notes: + +- `deep-agentic-core-mcp` should connect to `agenticops-control-tower` as a + control-plane connector, not reimplement control-plane logic locally +- first scope should mirror `agenticops-control-tower`'s planned MCP + connector direction: inventory, health, version, and posture queries +- write-capable Control Tower actions should come only after the sibling + package exposes stable authorization and audit semantics ## Phase 5: Publishing and Adoption