Skip to content

fix(workflows): publish-on-tag hardening + umbrella support#54

Open
jadb wants to merge 5 commits into
mainfrom
fix/publish-on-tag-fixes
Open

fix(workflows): publish-on-tag hardening + umbrella support#54
jadb wants to merge 5 commits into
mainfrom
fix/publish-on-tag-fixes

Conversation

@jadb

@jadb jadb commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Hardens publish-on-tag.yml for the failure modes seen during the
first multi-component publish runs in hop-top/poly-cite and adds
the docs / ADR coverage to keep follow-on adopters from re-hitting
the same edges.

publish-on-tag.yml

  • Umbrella / meta-component tags now skip cleanly. parse.lookup
    used to hard-fail with ::error::Unknown component when a tag's
    component prefix had no entry in the caller's ecosystems map.
    release-please umbrella bumps (the . root in a separate-PRs
    manifest, e.g. poly-cite/v0.1.0) hit this path by design and
    reddened otherwise-clean release runs. Replaced with a
    ::notice:: + empty outputs; every downstream job (publish-ts,
    publish-py, publish-rs, mirror, publish-php) now gates on
    needs.parse.outputs.ecosystem != '' so the workflow finishes
    green with all publish jobs marked skipped.

  • publish-php no longer reds out when Packagist credentials
    aren't forwarded.
    PACKAGIST_USERNAME / PACKAGIST_TOKEN are
    already declared in the workflow_call secrets: block, but a
    caller that hadn't wired them got ::error::… must be provided

    • exit 1. Switched to ::notice:: + exit 0 — "no credentials"
      means "don't notify Packagist," not "fail the release." Hard-fail
      belongs in the preflight, not the publish path. (secrets.*
      cannot appear in job-level if:, so the gate stays in the step
      body.)

release-please.yml

  • workflow_dispatch: {} added so the bot's standing PRs can be
    rebuilt against current main on demand after sibling-PR conflicts
    force a rebase. Previously required a no-op commit to main.

Docs (SKILL.md, references/quick-start.md)

  • New SKILL.md sections: Umbrella / meta-component tags,
    Bootstrap-mirror gotcha (two safe shapes — empty mirror or
    pre-populated via git subtree split at the tag's source commit
    — plus recovery on non-fast-forward and rationale for not
    defaulting to --force-push), and Re-runs use the tag's
    workflow snapshot, not main
    (with the two recovery paths:
    delete + recreate tag, or cut a new patch tag).
  • Caller templates (SKILL.md TL; DR + references/quick-start.md)
    now show workflow_dispatch: {} on the caller publish.yml,
    with a caveat comment about snapshot semantics so adopters know
    the trade-off up front.
  • Three new rows in the "find your intent" table.

docs/adr/0001-release-please-rebase-automation.md

  • ADR proposing how to handle the O(N²) manifest-conflict
    cascade under release-please-action separate-pull-requests: true.
    Four options considered (upstream native rebase — no flag exists
    today; local release-please-rebase.yml reusable; single-PR mode
    — regresses per-component review; community auto-rebase actions
    — can't resolve manifest semantics). Decision: file upstream AND
    scope the reusable in parallel; retire the reusable when upstream
    lands a fix. Implementation out of scope — separate task.

Test plan

  • actionlint .github/workflows/*.yml passes locally.
  • python3 -c "import yaml; yaml.safe_load(open('.github/workflows/publish-on-tag.yml'))" succeeds.
  • Dispatch a synthetic umbrella tag (<name>/v0.0.1 with no ecosystems entry) on a sandbox caller repo; expect the workflow to finish green with every publish job skipped.
  • Dispatch a php tag from a caller that has NOT wired PACKAGIST_USERNAME / PACKAGIST_TOKEN; expect publish-php to finish with the ::notice:: and the run to be green overall.
  • Trigger release-please.yml via gh workflow run release-please.yml --ref main and confirm the bot PRs are rebuilt.
  • Confirm the caller publish.yml example in references/quick-start.md is copy-paste-safe (no leftover comment-only lines, valid YAML).

Notes

  • One of the original tasks in scope (forward RELEASE_BOT_* secrets
    • gate the notify-vanity job) was already retired in commit
      e775e3b (docs(skill): vanity-URL resolver + retire #50's notify-vanity mechanism #52) when the notify-vanity job was removed; the secrets
      are no longer referenced anywhere in publish-on-tag.yml. Vanity-
      URL resolution now lives in the hop-top/hop.top Cloudflare
      Worker + homebrew-tap overrides per
      references/concepts/vanity-imports.md. That task was closed as
      N/A; no publish-on-tag.yml change shipped for it here.

jadb added 5 commits May 28, 2026 13:14
…s skip

parse.lookup: replace hard-fail on missing ecosystem entry with
::notice:: + empty outputs. Umbrella / meta-component tags
(release-please . root, e.g. poly-cite, poly-uri) finish green with
every downstream job skipped via the empty ecosystem output.

Downstream guards: publish-ts, publish-py, publish-rs, mirror,
publish-php all gated on needs.parse.outputs.ecosystem != ''
alongside their existing ecosystem-equality / mirror conditions.

publish-php: missing PACKAGIST_USERNAME or PACKAGIST_TOKEN now
::notice:: + exit 0 instead of ::error:: + exit 1. A php-tag
pipeline still publishes the mirror; "no credentials" means "don't
notify Packagist," not "fail the release." Hard-fail belongs in
the preflight, not the publish path. (secrets.* cannot appear in
job-level if: — the gate stays in the step body.)
Re-running release-please after sibling-PR conflicts force a rebase
previously required a noop commit to main. workflow_dispatch lets the
bot's standing PRs be rebuilt against current main on demand.
…s, dispatch trigger

SKILL.md additions:

- Umbrella / meta-component tags — explains the new graceful-skip
  contract (release-please . root, e.g. poly-cite/v0.1.0 finishes
  green with every publish job skipped via empty ecosystem output).
- Bootstrap-mirror gotcha — two safe shapes (empty repo OR pre-
  populated via git subtree split at the tag's source commit);
  recovery path on non-fast-forward; rationale for not defaulting
  to force-push.
- Re-runs use the tag's workflow snapshot — re-stating + linking
  the mental-model concept page. Two recovery paths: delete +
  recreate tag, or cut a new patch tag.

Caller templates (SKILL.md TL;DR + references/quick-start.md):

- Add workflow_dispatch: {} to publish.yml example with caveat
  comment about snapshot semantics so adopters know the
  trade-off up front.

Find-your-intent table: three new rows for the above sections.
ADR 0001 — proposed design for resolving the manifest-conflict
cascade under release-please-action separate-pull-requests mode.

Four options considered: upstream native rebase (no flag exists
today), local release-please-rebase.yml reusable, single-PR mode
(regresses per-component review ergonomics), community auto-rebase
actions (can't resolve manifest merge semantics).

Decision: pursue upstream report AND local reusable in parallel;
retire the reusable when upstream lands a native fix. Implementation
out of scope — separate task.

Pointer added under SKILL.md "See also".
…agist no-creds

common-pitfalls.md: new row for umbrella graceful-skip linking
SKILL.md § Umbrella / meta-component tags; enrich existing
snapshot-rerun row with SKILL.md § Re-runs and concepts/mental-model
§ Snapshot semantics cross-links.

php.md: new "Packagist credentials missing" section + table row
documenting the publish-php clean-skip on absent PACKAGIST_USERNAME
/ PACKAGIST_TOKEN; cross-links the umbrella graceful-skip design.
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.

1 participant