Skip to content

fix: chain docker publish from release workflow#116

Merged
jpr5 merged 1 commit intomainfrom
fix/release-docker-publish-chain
Apr 18, 2026
Merged

fix: chain docker publish from release workflow#116
jpr5 merged 1 commit intomainfrom
fix/release-docker-publish-chain

Conversation

@jpr5
Copy link
Copy Markdown
Contributor

@jpr5 jpr5 commented Apr 18, 2026

Bug

publish-release.yml pushes the v* release tag using the default GITHUB_TOKEN. Per GitHub's anti-recursion rule, workflow-created tags pushed with GITHUB_TOKEN do not trigger downstream workflows. As a result, the push: tags: [v*] trigger on publish-docker.yml never fires on automated releases.

Evidence: v1.11.0 through v1.14.3 all published cleanly to npm, but the last successful GHCR publish was for v1.10.0. We only caught this when the v1.14.3 OOM fix never reached the Railway service pulling ghcr.io/copilotkit/aimock:latest.

Fix

After the npm publish step in publish-release.yml succeeds, explicitly invoke publish-docker.yml via gh workflow run publish-docker.yml --ref v$VERSION. Guarded by the same steps.check.outputs.published == 'false' condition, so Docker only builds when npm publish actually happened.

Two supporting changes:

  • Added actions: write to the release job permissions (required to dispatch another workflow).
  • Restored workflow_dispatch: on publish-docker.yml — it was added in 486ccd9 but inadvertently removed in 63aab1e. gh workflow run --ref <TAG> requires workflow_dispatch to be present on the ref being dispatched.

The existing push: tags: v* trigger on publish-docker.yml stays in place as belt-and-suspenders for anyone pushing tags manually from a local clone with a PAT.

Why this option over the alternatives

  • Option A (explicit chain via gh workflow run) — picked. Least invasive, no new secrets, most observable. The dispatch is a discrete named step in the release run, so failures are immediately visible in the log. Doesn't depend on tag-trigger semantics at all.
  • Option B (use a PAT to push the tag): Works, but requires storing and rotating a long-lived secret, and the trigger is implicit (failures look like "Docker workflow just didn't run"). Higher ongoing maintenance.
  • Option C (workflow_call refactor): Strongest coupling but forces us to refactor publish-docker.yml to expose workflow_call alongside push/pull_request/workflow_dispatch, and changes the run topology (nested job vs. separate workflow run). Overkill for what is fundamentally a trigger-chaining bug.

Verification

On the next release after this merges, the release run should show:

  1. npm publish succeeds
  2. Tag v1.x.y is pushed
  3. GitHub Release created
  4. New step: Trigger Docker publish workflow dispatches publish-docker.yml against v1.x.y
  5. publish-docker.yml run appears under Actions with trigger = workflow_dispatch, ref = v1.x.y
  6. ghcr.io/copilotkit/aimock:1.x.y and :latest appear under Packages

A reviewer can also manually confirm the dispatch path right now by running:

gh workflow run publish-docker.yml --ref v1.14.3 --repo CopilotKit/aimock

(Note: another agent is handling v1.14.3 specifically — don't trigger from this PR.)

Local checks

  • pnpm run format:check — clean
  • pnpm run lint — clean
  • pnpm run build — clean
  • pnpm run test — 2461/2461 passing
  • YAML syntax validated on both workflow files

GitHub's anti-recursion rule prevents workflows from triggering other
workflows when acting as GITHUB_TOKEN. publish-release.yml pushes the
release tag with the default token, so the push:tags:v* trigger on
publish-docker.yml never fires. Result: v1.11.0 through v1.14.3 all
published to npm but no Docker image reached GHCR, and the v1.14.3 OOM
fix never made it to the Railway service pulling ghcr.io/copilotkit/aimock:latest.

Fix by explicitly dispatching publish-docker.yml via `gh workflow run
--ref <TAG>` after the npm publish step succeeds. This does not depend
on tag-trigger behavior and is guarded by the same
steps.check.outputs.published == 'false' condition as the publish, so
Docker only builds when npm publish actually happened.

Also restore the workflow_dispatch trigger on publish-docker.yml (added
in 486ccd9, inadvertently removed in 63aab1e); `gh workflow run`
requires workflow_dispatch on the ref being invoked.

The existing push:tags:v* trigger stays as belt-and-suspenders for
anyone pushing tags manually from a local clone with a PAT.

Option chosen: explicit chain over PAT or workflow_call. Least invasive
(no new secrets, no cross-workflow refactor), most observable (the
dispatch shows up as a discrete step in the release run), and the
failure mode is clearly visible in the release workflow log.
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 18, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@copilotkit/aimock@116

commit: a696866

@jpr5 jpr5 merged commit 341490e into main Apr 18, 2026
11 checks passed
@jpr5 jpr5 deleted the fix/release-docker-publish-chain branch April 18, 2026 15:14
jpr5 added a commit that referenced this pull request Apr 18, 2026
## Problem

`gh release create` is invoked without `--latest`, leaving GitHub's
default selector to decide which Release wears the "Latest" badge. When
other Release objects exist (notably the floating `v1` Release that has
tracked the major version), GitHub can race and flip the badge to a
non-semver release unpredictably.

## Fix

Add `--latest` to the `gh release create` invocation in
`publish-release.yml` so every future semver release unambiguously
claims Latest.

```diff
-          gh release create "${TAG}" --generate-notes --title "${TAG}" --verify-tag
+          gh release create "${TAG}" --generate-notes --title "${TAG}" --verify-tag --latest
```

## Notes

- Orthogonal to #116 (Docker publish chain). Independently useful.
- The floating `v1` Release object is being deleted separately as a
one-shot ops action; this PR is **defense in depth** so the badge can
never race again, regardless of what other Release objects exist now or
in the future.
- Single-line YAML change. Format/lint/build/test all pass locally.

**Do not merge. Do not enable auto-merge.**
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