Skip to content

discussion: release & CI ownership — manual releases since 0.1.7 throttle iteration #37

Description

@ch-liuzhide

Context

For an OSS framework, release friction is a direct throttle on how fast improvements reach users. Since 0.1.7 the project has shipped via a fully manual process: the automated release-PR flow (release-please) was removed because the org cannot grant CI the permission to create/merge PRs. A release now means hand-editing four version files plus the changelog, with no guard against a partial bump. This is an organizational + process decision — we need to pick a release-ownership and automation boundary, not just patch a script.

This issue is a discussion to decide that boundary. It maps to D7 in the capability-gap roadmap.

Current state

  • release-please automation is gone. There is no .github/workflows/release-please.yml (only ci.yml, publish.yml, deploy-pages.yml, docs-pr.yml remain in .github/workflows/). A .release-please-manifest.json file still exists at the repo root pinning {".": "0.1.7"}, but nothing consumes it automatically anymore.
  • Publishing is triggered by a version change on main, not by a tag or release PR. See .github/workflows/publish.yml:3-7on: push: branches: [main] filtered to paths: ['pyproject.toml']. The check-version job (.github/workflows/publish.yml:18-49) extracts the version from pyproject.toml and skips if that version already exists on PyPI; the tag job (.github/workflows/publish.yml:124-138) creates v<version> after publish.
  • PyPI publishing already uses Trusted Publishing / OIDC (no API token). See .github/workflows/publish.yml:9-11 (id-token: write) and the publish step at .github/workflows/publish.yml:119-122 (pypa/gh-action-pypi-publish@release/v1, "Uses Trusted Publisher — no API token needed"). So option (3) below is largely already in place — the open question is confirming/hardening it, not introducing it.
  • A release requires bumping four version files by hand, plus the changelog. This is documented inline in CHANGELOG.md:8-15, which instructs the maintainer to bump the version in:
    • pyproject.toml:7version = "0.1.7" (the trigger file)
    • src/hebb/__init__.py:45__version__ = "0.1.7"
    • .release-please-manifest.json{".": "0.1.7"}
    • .claude-plugin/plugin.json:3"version": "0.1.7"
    • and add a dated section to CHANGELOG.md (currently ## [0.1.7] - 2026-06-08, CHANGELOG.md:16).
  • There is no release helper today. scripts/ contains only install.sh; there is no Makefile and no make release / release script. The bump is entirely manual, with no tooling to keep the four files in lockstep or to fail if one drifts.

Proposed approach (decide one direction)

  1. Restore automated release PRs — ask the org to grant a scoped token or install a GitHub App with PR create/merge permission, then reinstate a release-please-style workflow that opens/merges the version-bump PR. Removes manual bumping entirely but depends on an org-level permission grant that was previously denied.
  2. Maintainer-run one-command release script — a make release (or scripts/release.py / hebb-dev release) that performs the four-file bump + changelog stamp + git tag in one step, with a check that fails if any of the four version strings disagree. Reduces manual error without needing any CI PR permission; publish.yml still ships on the resulting pyproject.toml change to main. Lowest-dependency option.
  3. Confirm / harden Trusted Publishing (OIDC) — Trusted Publishing is already wired in publish.yml; ratify it as the supported path, document the PyPI publisher config, and ensure no fallback API token is ever needed. Pairs with either (1) or (2).

These are not mutually exclusive: (2) + (3) is a fully self-serve maintainer path with no org dependency; (1) + (3) is the fully-automated path if the permission can be obtained.

Acceptance criteria

  • A decision is recorded on the release-ownership + automation approach (option 1, 2, 3, or a stated combination).
  • If a scripted path is chosen, a single-command release exists that bumps all four version files (pyproject.toml, src/hebb/__init__.py, .release-please-manifest.json, .claude-plugin/plugin.json) and stamps CHANGELOG.md from one input version.
  • A consistency guard fails the release (or CI) if the four version strings ever disagree.
  • The Trusted Publishing / OIDC path in publish.yml is confirmed as the supported publish mechanism and documented (no API token fallback).
  • If the org-token / GitHub App route is pursued, the required permission scope is identified and the request tracked.

Scope / out of scope

  • In scope: the release-ownership decision, the manual-bump error surface, and the one-command release path.
  • Out of scope: the test/build matrix in ci.yml and publish.yml (these already re-run before publish, publish.yml:51-108); changes to the SemVer policy or the publish trigger (version change on main) unless a chosen option requires it.

References

  • .github/workflows/publish.yml — publish trigger, OIDC/Trusted Publishing, tagging.
  • .github/workflows/ci.yml — existing test/lint/e2e/model/docker gates.
  • CHANGELOG.md (header at lines 8-15) — the documented manual four-file bump procedure.
  • reports/audit/core-system-audit-2026-06-07.md
  • reports/audit/newuser-experience-audit-2026-06-08.md
  • reports/design/capability-gap-roadmap-2026-06-11.md (D7)

Filed from the capability-gap roadmap (reports/design/capability-gap-roadmap-2026-06-11.md).

Metadata

Metadata

Assignees

No one assigned

    Labels

    github_actionsPull requests that update GitHub Actions codeneeds-discussionDirection/architecture decision needed before scheduling

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions