Skip to content

Auto-tag fork on upstream sync so update check + Docker pipeline pick up new releases #36

@Du7chManiac

Description

@Du7chManiac

Background

PR for #34's branch (claude/update-fork-check-nkEdN) implements Option B for the fork update check: the release-tag path now only considers v* tags that origin actually publishes. When origin has no v* tags (the current state of TheCouchCoder-com/hermes-webui), the check falls through to a branch-tip comparison — so every merge to master surfaces as "1 update available".

That restores the workflow the maintainer relied on before the upstream _check_repo_release path was added, but it leaves two soft costs in place:

  • The version badge still shows commit-derived describes (e.g. v0.51.127-3-g<sha>) between releases — fine, but less informative than a real semver.
  • GHCR Docker images are only built when v* tags are pushed (.github/workflows/release.yml fires on tags: ['v*']), so source-installed users get updates per merge but Docker users have to wait for a manual release cut.

This issue tracks layering Option A on top of Option B: auto-tag the fork whenever a sync-with-upstream PR merges into master, so the existing release pipeline fires automatically and the version badge stays meaningful.

Proposed approach

  1. Extend .github/workflows/sync-upstream.yml (which already creates sync/upstream-<tag> branches and opens PRs after each upstream tag) with a follow-up job that, after the sync PR is merged into master, pushes a matching tag to the fork.

  2. Tag-naming strategy (open question):

    • Option A1 — mirror upstream verbatim: tag fork's master as v0.51.128 when we sync upstream v0.51.128. Simplest; matches what the version badge already shows via git describe. Risk: a fork's v0.51.128 and upstream's v0.51.128 point at different SHAs (the fork's tag is on the merge commit, not on upstream's tagged commit), so an operator can't tell at a glance which build they're running.
    • Option A2 — append +fork.N: tag as v0.51.128+fork.0 initially, then v0.51.128+fork.1 if we cut a fork-only patch on top. Disambiguates fork vs upstream builds. Requires teaching the version-sort logic to handle the +fork.N suffix correctly.
    • Option A3 — pure fork semver: tag as v1.0.0, v1.0.1, etc., disconnected from upstream's numbers. Cleanest namespace separation but loses the "synced with upstream v0.51.128" signal that's useful in changelog notes.
  3. The trigger needs to handle fork-only PRs too. If only sync PRs auto-tag, fork-only changes between syncs ship without a release. Options:

    • Auto-tag every PR merge to master (high CI cost — Docker build per PR).
    • Auto-tag on a release: true label or PR title prefix.
    • Auto-tag only on sync-with-upstream PRs; cut fork-only releases manually per the existing CLAUDE.md "Cutting a release" procedure.
  4. CHANGELOG.md automation: if we auto-tag on sync, the changelog entry needs to be stamped by the workflow rather than by hand. Either reuse the per-release stamp commit pattern (see d84f8b2 Stamp CHANGELOG for v0.51.127) or rely entirely on the auto-generated release notes from softprops/action-gh-release.

Open questions

  • Tag-naming (A1 / A2 / A3)?
  • Auto-tag scope (every merge / sync-only / labeled)?
  • CHANGELOG automation (stamped commit / generated notes only)?
  • CI budget — Docker multi-arch builds take ~5–10 min each; sync cadence is currently roughly daily during active upstream development.

Acceptance criteria

  • A merge to master from a sync/upstream-* branch (matching the sync-upstream workflow's naming) produces a pushed tag and a GHCR image without manual intervention.
  • The update check (post-PR for fix(updates): refresh version badge dynamically + surface unavailable update check #34) reports the new fork release as "available" within the 30-minute cache TTL.
  • The version badge displays the new release tag exactly (no commit-suffix describe).
  • The maintainer can still cut a release manually via git tag vX.Y.Z && git push origin vX.Y.Z for fork-only work; the auto-tag job does not interfere.

Dependencies

Blocked-by-companion: the PR for branch claude/update-fork-check-nkEdN (Option B). Option A is meaningful only once the check falls through cleanly on a fork with no release tags.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions