From dc101d36d238ecb4e3d9473397b51a83a052c8c4 Mon Sep 17 00:00:00 2001 From: Deep-Sixed <281237415+Deep-Sixed@users.noreply.github.com> Date: Tue, 8 Sep 2026 22:47:27 -0400 Subject: [PATCH 1/4] Bump package version to 0.1.1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index cbdb313..1b613d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "contextmesh-graph" -version = "0.1.0" +version = "0.1.1" description = "A typed context graph for AI agents: provenance, assumptions, and answers that walk a path you can read." readme = "README.md" requires-python = ">=3.9" From e3164bac400103e671ccf2148ef16ec6232b037c Mon Sep 17 00:00:00 2001 From: Deep-Sixed <281237415+Deep-Sixed@users.noreply.github.com> Date: Tue, 8 Sep 2026 22:47:42 -0400 Subject: [PATCH 2/4] Add PyPI trusted publishing workflow --- .github/workflows/publish.yml | 83 +++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..3c63c3f --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,83 @@ +name: Publish to PyPI + +on: + release: + types: [published] + +permissions: + contents: read + +jobs: + build: + name: Build release distributions + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Verify release tag matches package metadata + run: | + python - <<'PY' + import os + from pathlib import Path + import tomllib + + project = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8"))["project"] + expected_name = "contextmesh-graph" + expected_tag = f"v{project['version']}" + actual_tag = os.environ["GITHUB_REF_NAME"] + + assert project["name"] == expected_name, (project["name"], expected_name) + assert os.environ["GITHUB_REF_TYPE"] == "tag", os.environ["GITHUB_REF_TYPE"] + assert actual_tag == expected_tag, (actual_tag, expected_tag) + print(f"release identity: {project['name']} {project['version']} from {actual_tag}") + PY + + - name: Build and check wheel and sdist + run: | + python -m pip install --upgrade pip + python -m pip install build twine + python -m build + python -m twine check dist/* + python - <<'PY' + from pathlib import Path + + wheels = list(Path("dist").glob("*.whl")) + sdists = list(Path("dist").glob("*.tar.gz")) + assert len(wheels) == 1, wheels + assert len(sdists) == 1, sdists + assert wheels[0].name.startswith("contextmesh_graph-0.1.1-"), wheels[0] + assert sdists[0].name == "contextmesh_graph-0.1.1.tar.gz", sdists[0] + print(wheels[0]) + print(sdists[0]) + PY + + - name: Upload release distributions + uses: actions/upload-artifact@v4 + with: + name: pypi-dist + path: dist/ + if-no-files-found: error + + publish: + name: Publish release to PyPI + needs: build + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/project/contextmesh-graph/ + permissions: + contents: read + id-token: write + steps: + - name: Retrieve release distributions + uses: actions/download-artifact@v4 + with: + name: pypi-dist + path: dist/ + + - name: Publish release distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 From 9cb1637dfb499d6cd4ad77160c22b88ec0296829 Mon Sep 17 00:00:00 2001 From: Deep-Sixed <281237415+Deep-Sixed@users.noreply.github.com> Date: Tue, 8 Sep 2026 22:47:52 -0400 Subject: [PATCH 3/4] Prepare v0.1.1 release notes --- RELEASE_NOTES.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 1f2cb90..b61ab1d 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,26 @@ +# ContextMesh v0.1.1 + +`v0.1.1` is a release-engineering patch for the first PyPI publication of ContextMesh. +Runtime graph, persistence, MCP authority, and LLM behavior are unchanged from `v0.1.0`. + +## Changed + +- The PyPI distribution is `contextmesh-graph` because the `contextmesh` distribution name is already owned by an unrelated project. +- The Python import namespace remains `contextmesh`. +- The console scripts remain `contextmesh` and `contextmesh-mcp`. +- PyPI publication uses GitHub Actions Trusted Publishing through OIDC; no long-lived PyPI API token is stored in the repository. +- Publication is triggered only by a published GitHub release whose tag exactly matches the package version. + +## Install + +```bash +pip install contextmesh-graph +pip install 'contextmesh-graph[mcp]' +``` + +The core distribution supports Python 3.9+ with no runtime dependencies. The optional MCP +extra requires Python 3.10+. + # ContextMesh v0.1.0 `v0.1.0` is the first public technical release of ContextMesh. It is intentionally not @@ -16,8 +39,8 @@ a 1.0 stability claim. ## Release boundary The core package supports Python 3.9+ with no runtime dependencies. The optional MCP -extra requires Python 3.10+ and is installed with `contextmesh[mcp]`. The stdio MCP +extra requires Python 3.10+ and is installed with `contextmesh-graph[mcp]`. The stdio MCP server is a single-session-per-process deployment model, not a shared multi-tenant service. -Package publication remains a separate explicit gate. +Package publication was a separate explicit gate and is opened by the `v0.1.1` release. From dcc01eef7e1f7670f7fb03c0ca47f6ee20f3ee25 Mon Sep 17 00:00:00 2001 From: Deep-Sixed <281237415+Deep-Sixed@users.noreply.github.com> Date: Tue, 8 Sep 2026 22:48:31 -0400 Subject: [PATCH 4/4] Make publish artifact checks version-aware --- .github/workflows/publish.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3c63c3f..afdbd13 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -44,13 +44,15 @@ jobs: python -m twine check dist/* python - <<'PY' from pathlib import Path + import tomllib + version = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8"))["project"]["version"] wheels = list(Path("dist").glob("*.whl")) sdists = list(Path("dist").glob("*.tar.gz")) assert len(wheels) == 1, wheels assert len(sdists) == 1, sdists - assert wheels[0].name.startswith("contextmesh_graph-0.1.1-"), wheels[0] - assert sdists[0].name == "contextmesh_graph-0.1.1.tar.gz", sdists[0] + assert wheels[0].name.startswith(f"contextmesh_graph-{version}-"), wheels[0] + assert sdists[0].name == f"contextmesh_graph-{version}.tar.gz", sdists[0] print(wheels[0]) print(sdists[0]) PY