Skip to content

ci: adopt release-please for automated releases#149

Open
jlav wants to merge 1 commit into
mainfrom
jl/release-please-setup
Open

ci: adopt release-please for automated releases#149
jlav wants to merge 1 commit into
mainfrom
jl/release-please-setup

Conversation

@jlav

@jlav jlav commented Jun 3, 2026

Copy link
Copy Markdown
Member

What this does

Migrates the automation repo from the manual prepare-release flow to
release-please, consuming the
centralized reusable workflows from
OpenHands/release-actions
(the same automation that repo uses to release itself).

This is a migration, not a greenfield add — the repo already had a homegrown
release system (manual prepare-release.yml → tag → pypi-release.yml +
tag-image.yml) and used PEP 440 alpha versioning (1.0.0a5).

Requirements (as requested)

  1. Exact labels from release-actions. .github/release.yml is copied verbatim,
    so changelog grouping uses the same type: feat / type: fix / … labels. The
    type: labels and released: X.Y.Z labels are created/applied by the reusable
    pr-title.yml / release-please.yml workflows — nothing reinvented here.

  2. Embedded versions auto-updated. release-please-config.json extra-files
    bumps every place a version is embedded, all to one repo version:

    File Mechanism
    pyproject.toml [project].version native python release-type
    uv.lock (root pkg) toml $.package[?(@.name.value=='openhands-automation')].version
    frontend/package.json json $.version
    frontend/package-lock.json json $.version + $.packages[''].version
    openhands/automation/__init__.py generic (# x-release-please-version)
    openhands/automation/app.py (FastAPI version=) generic (# x-release-please-version)

    The lock files are included specifically so the release PR's own CI
    (uv sync --frozen, npm ci) stays green. Each updater was verified locally
    against the real files with release-please 17.x — every one changes only the
    intended line(s) (e.g. transitive 0.1.0 deps in package-lock.json are left
    untouched).

  3. Docker publish on tag, tagged. Handled by the existing, untouched
    ghcr-build.yml (builds sha-<commit> on the release merge) + tag-image.yml
    (on tag push, aliases that image to 1.0.0 / 1.0 / 1 / latest). Because
    release-please creates the tag with a GitHub App token, the tag-push event
    triggers these workflows (the default GITHUB_TOKEN would not).

  4. No simple type, no version.txt. Uses release-type: python plus the
    extra-files updaters above.

Decisions (confirmed before implementing)

  • Stable 1.0.0 baseline. 1.0.0a5 isn't valid SemVer; release-please is
    SemVer-based and emits PEP-440-incompatible prereleases. So all version refs are
    set to 1.0.0 and the manifest is seeded at 1.0.0; future releases are
    1.0.1 / 1.1.0 / 2.0.0 from conventional commits. last-release-sha is
    pinned to the current main HEAD so the first release only considers post-baseline
    commits (no 1.0.0 tag exists to anchor on, and tagging now would trigger a
    publish).
  • Replaced prepare-release.yml; kept the publishers. pypi-release.yml and
    tag-image.yml are unchanged — release-please's tag drives them.
  • Unified frontend version. frontend/package.json (was decoupled at 0.1.0)
    now tracks the single repo version.

Tags are bare (include-v-in-tag: false) to match the repo's existing tag
history (1.0.0a5) and avoid a redundant v1.0.0 image tag from tag-image.yml.

Security note on pr.yml

pr.yml uses pull_request_target (so title lint/label works on fork PRs). It is
safe by the release-actions design and stays safe only because: it never checks
out or runs PR code
(reads the title from the event payload only), and it does
not pass secrets: inherit (runs on GITHUB_TOKEN alone). Both invariants are
documented inline.

Prerequisites (one-time, org/repo settings — not in this PR)

  • Org secrets RELEASE_APP_ID / RELEASE_APP_PRIVATE_KEY (the GitHub App
    release-please mints its token from). Without them the release workflow fails by
    design — there is no GITHUB_TOKEN fallback.
  • Squash-merge configured with PR_TITLE as the commit title, so the title
    release-please reads is the conventional one.

Verification

  • All six updaters run locally against the actual files → only intended lines change.
  • uv lock --check passes after the bump; YAML passes the repo's yamlfmt
    pre-commit hook (idempotent); ruff/pycodestyle/pyright pass on the edited Python.
  • release-please-config.json / manifest are valid JSON; all extra-files paths exist.

Replace the manual prepare-release workflow with release-please, consumed
from OpenHands/release-actions' reusable workflows.

- Add release.yml / pr.yml caller workflows (uses: OpenHands/release-actions@main)
- Add release-please-config.json + .release-please-manifest.json (seed 1.0.0)
- Add .github/release.yml with the exact `type:` labels from release-actions
- extra-files bump every embedded version: pyproject.toml, uv.lock,
  frontend/package.json, frontend/package-lock.json,
  openhands/automation/__init__.py, openhands/automation/app.py
- Set the 1.0.0 stable baseline (was 1.0.0a5; __init__/app.py/frontend were 0.1.0)
- Remove prepare-release.yml (superseded); keep pypi-release.yml + tag-image.yml,
  which the release-please tag triggers to publish PyPI + Docker images
- Update AGENTS.md release procedure
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown

Coverage

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown

🚀 Deploy Preview PR Created/Updated

A deploy preview has been created/updated for this PR.

Deploy PR: https://github.com/OpenHands/deploy/pull/4490
Automation SHA: 7188d894c20e51bb948a06081b7b6cbdd61e5eb3
Last updated: Jun 03, 2026, 09:57:38 AM ET

Once the deploy PR's CI passes, the automation service will be deployed to the feature environment.

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.

2 participants