From 87ad4f4ab4544bc31fd1fc6f26f70b8e638d0865 Mon Sep 17 00:00:00 2001 From: David Hyrule Date: Mon, 29 Jun 2026 03:59:40 +0200 Subject: [PATCH] chore: add release workflow + distribution/adoption doc release.yml builds sdist+wheel and publishes a GitHub Release on v* tags. docs/distribution.md lays out how loops adopt agent-core as a real (always-on) dependency: uv git source pin (recommended), Release wheel, hosted index, or making the repo public; with the per-loop reversible path and the CI-auth tradeoff. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/release.yml | 32 ++++++++++++++++++ docs/distribution.md | 62 +++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 .github/workflows/release.yml create mode 100644 docs/distribution.md diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..93713eb --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,32 @@ +name: release + +on: + push: + tags: ["v*"] + +permissions: + contents: write + +jobs: + build-release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Install uv + run: curl -LsSf https://astral.sh/uv/install.sh | sh + - name: Build sdist + wheel + run: ~/.local/bin/uv build + - name: Verify version matches tag + run: | + test -f "dist/agent_core-${GITHUB_REF_NAME#v}-py3-none-any.whl" \ + || (echo "wheel version does not match tag ${GITHUB_REF_NAME}" && ls dist && exit 1) + - name: Publish GitHub Release with artifacts + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release create "${GITHUB_REF_NAME}" dist/* \ + --title "agent-core ${GITHUB_REF_NAME}" \ + --notes "Built from ${GITHUB_SHA}. Install: see docs/distribution.md." diff --git a/docs/distribution.md b/docs/distribution.md new file mode 100644 index 0000000..4e4f58b --- /dev/null +++ b/docs/distribution.md @@ -0,0 +1,62 @@ +# Distributing agent-core (making emission always-on) + +Today the loops emit agent-core records **optionally**: they import `agent_core` via +`importlib` only when `HYRULE_*_AGENT_CORE_TRACE` is set, and `agent-core` is **not** a +declared dependency. That means zero CI/auth changes, but emission is off until both the +flag and the package are present. + +To make emission **always-on**, a loop must declare `agent-core` as a real dependency. The +only real obstacle is **auth**: `AS215932/agent-core` is private, so any consumer (and its +CI) must be able to fetch it. The options below trade off effort vs. infra. + +## The release artifact + +`.github/workflows/release.yml` builds an sdist + wheel and publishes a **GitHub Release** +on any `v*` tag (e.g. `v0.1.0`). This gives every version a versioned, downloadable +artifact without standing up a server. + +## Adoption options (pick one) + +### A. uv git source pin — *recommended first step* +In a loop's `pyproject.toml`: +```toml +dependencies = ["agent-core"] + +[tool.uv.sources] +agent-core = { git = "https://github.com/AS215932/agent-core", tag = "v0.1.0" } +``` +- Pros: no index server; version-pinned; reproducible via `uv.lock`. +- Cons: private repo → CI must authenticate the git fetch. On the **self-hosted + `hyrule-public-pr` runners** this is a GitHub App/token with **read-only** access to + `agent-core`; on GitHub-hosted runners (e.g. knowledge `validate`) it needs a secret + (a fine-grained PAT or App token) exposed to `uv`. + +### B. GitHub Release wheel + `--find-links` +Install the published wheel directly: +``` +uv pip install --find-links https://github.com/AS215932/agent-core/releases/download/v0.1.0 agent-core +``` +- Same private-repo auth requirement as A; less reproducible than a locked git source. + +### C. Hosted private index (pypiserver / devpi) on internal infra +A real PyPI-compatible index behind the AS215932 network. +- Pros: the "always-on internal index" model; clean `index-url`. +- Cons: provisioning + hosting + auth + CI network access. Defer unless several private + packages need it. + +### D. Make `agent-core` public — *simplest if acceptable* +`agent-core` contains only generic framework contracts and adapters — **no secrets, no +infra topology** (fixtures use placeholder hosts). Making the repo public removes the auth +problem entirely; options A/B then need no tokens, and a future PyPI publish becomes trivial. +- Decision for the owner: is publishing the framework scaffolding publicly acceptable? + +## Recommendation + +1. Tag `v0.1.0` now (this PR adds the release workflow) so a versioned artifact exists. +2. Keep loops on **optional** emission until a distribution choice is made. +3. Choose **D (public)** if acceptable — then adopt **A (uv git source)** in each loop with + zero CI-auth work. Otherwise adopt **A** with a read-only deploy token. Revisit **C** + only when multiple private packages justify an index. + +Adoption is per-loop and reversible: flip a loop to a hard dependency in its own PR, run its +gate, and the flag-gated emission becomes always-on for that loop.