PR-A CR-r2 fixes (2 bucket-(a) findings from 7-agent confirmation round).
A4: Tighten publish-job `if:` so `needs.build.result == 'skipped'` is only honored when
the event is `workflow_call` (the intentional skip for the reusable workflow callee).
Previously, a `pull_request: closed` event on a release branch where the PR was closed
WITHOUT merging would cause the build job to skip (its own merged-true guard), then the
publish job's permissive `if:` would still run it — a phantom publish from an unmerged
release PR.
A5: Every post-publish step's custom `if:` overrode the default implicit `success()`
check, meaning a failure in `Publish to npm` or the `Verify version` guard would not
prevent downstream steps (tag push, GitHub Release create) from running. Prepended
`success() && ` to all post-publish step `if:` conditions to restore the implicit gate.
Spec: https://www.notion.so/36d3aa381852811ba10ad1bcd228d6d8
PR-A CR-r1 fixes (4 of 4 actionable findings from 7-agent CR + 1 cheap defense-in-depth).
A1: post-publish steps (Configure git user, Check for pre-existing tags, Create and push
git tag, Create GitHub Release) now gate on `inputs.dry-run != true && mode != 'prerelease'`
instead of just `mode`. On dry-run + stable, VERSION was empty so TAG="v" garbage was
pushed; this prevents that.
A2: Add explicit Verify-publish-step-emitted-version guard between Publish to npm and the
post-publish chain. Fails loud if publish-release.ts (or any inputs.publish-script
override) forgets to emit `version` to GITHUB_OUTPUT.
A3: Replace the single unconditional Release summary with three gated variants (stable,
prerelease, dry-run) so the summary no longer claims "Release Published" on dry-run or
prerelease.
B3: inputs.publish-script and steps.meta.outputs.scope now flow through env to the shell
(reduces injection surface even though caller is in-repo today).
Spec: https://www.notion.so/36d3aa381852811ba10ad1bcd228d6d8
prerelease.yml cannot register as a second npm trusted publisher (npm allows
exactly one per package; all 16 monorepo-scoped packages bind to
publish-release.yml). Refactor publish-release.yml to also support
workflow_call so prerelease.yml can invoke it as a reusable workflow — OIDC's
job_workflow_ref claim points at the callee, so the existing trust record
covers both flows.
This PR (PR-A) adds the workflow_call trigger, input schema, meta step for
scope+mode resolution, build-job gating to skip on workflow_call, publish-job
if: override for skipped-needs, post-publish step gating on
mode != prerelease, NOTION_API_KEY gating on stable mode, and the
publish-script input for the TS file selection.
Also adds a dry-run input on workflow_dispatch so PR-A can be verified
post-merge via a sacrificial release branch without an actual publish.
Spec: https://www.notion.so/36d3aa381852811ba10ad1bcd228d6d8
Customer block (Ben Taylor, #engr): @copilotkit/react-core canary with
suffix=thread-id-propagation.
PR-B (prerelease.yml caller conversion) follows.
upload-artifact's path filters are post-walk: even with !**/node_modules/**
exclusions, the action still descends into every node_modules and stats
every file (~6M for this monorepo with pnpm's .pnpm/ symlink farm) before
applying negations. That enumeration is the actual bottleneck — the
Upload workspace step runs 10+ minutes even with the filters added in
#5044.
Replace the filtered upload with: rm -rf the heavy dirs (node_modules,
.nx, .turbo, .next), tar the workspace into a single file, upload that.
Publish job tar -xzf's it after download and continues unchanged. Single-
file upload skips upload-artifact's per-file overhead entirely.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The prerelease workflow has been OOMing on Upload workspace since the
build/publish split in 770759a4be. The artifact upload enumerates
~6M files (root + per-package node_modules with pnpm symlinks all
materialized, plus build caches) and actions/upload-artifact builds
the full manifest in memory before streaming, blowing past the 4GB
Node heap limit.
publish-release.yml already had the working pattern: exclude
node_modules/.next/.turbo/.nx and re-run pnpm install --frozen-lockfile
in the publish job. Port it over so prerelease publishes succeed
again.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Zizmor's ref-version-mismatch audit flags the existing `# v1` comment
because the hash 5f3b3c2e5a00f0093de47f657aeaefcedff27d18 is the
v1.17.0 tag, not the v1 head. Update the trailing comment to match.
No behavior change — the SHA pin is what governs which commit Actions
fetches. This just keeps zizmor green so unrelated showcase-wiring PRs
don't trip on a pre-existing pin annotation.
Three companion workflows duplicate the showcase_build.yml service registry
and were missed in the initial wiring commit. Bring them in sync:
- .github/workflows/showcase_build_check.yml: add ms_agent_harness_dotnet
to the paths-filter and the ALL_SERVICES matrix (mirror of the
production build matrix, used for pre-merge Docker build verification).
- .github/workflows/showcase_deploy.yml: add ms-agent-harness-dotnet to
the workflow_dispatch options and the verification ALL_SERVICES with
railway_id 6343d7f9-6c3f-4c8d-9a6e-79f03d2f1e37 and /api/health.
- .github/workflows/showcase_keep-alive.yml: add ms-agent-harness-dotnet
to the keep-alive ping matrix.
Brings the Microsoft Agent Harness (.NET) integration live on the
showcase Railway project. Integration code itself landed in PR #4982.
Changes:
- Railway service `showcase-ms-agent-harness-dotnet` created
(id 6343d7f9-6c3f-4c8d-9a6e-79f03d2f1e37) with the public domain
showcase-ms-agent-harness-dotnet-production.up.railway.app, image
source ghcr.io/copilotkit/showcase-ms-agent-harness-dotnet:latest,
healthcheck /api/health, and env vars cloned from the sibling
showcase-ms-agent-dotnet service.
- .github/workflows/showcase_build.yml: add ms-agent-harness-dotnet to
workflow_dispatch options, paths-filter, and the ALL_SERVICES matrix
(mirroring the ms-agent-dotnet sibling entry).
- showcase/integrations/ms-agent-harness-dotnet/manifest.yaml: flip
deployed: false -> true so the dashboard surfaces the integration
once the image is live.
Skips test-and-check-packages pre-commit hook locally because
@copilotkit/web-inspector:test has a pre-existing failure on main
(window.localStorage.clear telemetry test setup) unrelated to these
YAML-only changes.
publish-release.ts now checks npm for each package before publishing
and skips versions that already exist. Makes publish idempotent —
safe to retry after partial failures. Removes the publish-remaining
one-shot workflow that's no longer needed.
Packages without repository.url fail npm OIDC provenance verification.
Adds the field to agentcore-runner, core, sqlite-runner, voice, and
web-inspector. Includes a one-shot workflow to publish the 14 remaining
v1.57.4 packages (a2ui-renderer already published via OIDC).
Replace pnpm publish with pnpm pack + npx npm@11.15.0 publish to
enable OIDC authentication. Set NODE_AUTH_TOKEN='' to prevent the
expired secret from blocking OIDC. Removes test workflow.
Without --bare, claude -p launches MCP servers defined in the project-level
.mcp.json before the model loads. A PR replacing .mcp.json with a malicious
entry gets an attacker-controlled subprocess launched on the CI runner —
same RCE surface as a SessionStart hook.
This repo already has .mcp.json committed (nx-mcp). Removing it before the
social copy generator runs is safe: the workflow's --allowedTools already
restricts Claude to specific read/diff tools and MCP servers are not needed
for social copy generation.
Call-site enumeration: rm -f is self-contained, no callers.
Extends the security fix to also cover .claude/settings.local.json, which
Claude Code reads with equal authority to settings.json. A PR author can
force-commit a gitignored file, so the .gitignore entry does not protect
against this vector.
Also moves the removal step to immediately after Checkout (before any other
step runs in the checked-out workspace), rather than after Install Claude Code.
Claude is not invoked during the intermediate steps, but this ordering is
strictly more defensive and prevents any future step insertions from reopening
the window.
Call-site enumeration: rm -f has no callers; step is self-contained YAML.
- Switch STORE_PATH from $GITHUB_ENV to $GITHUB_OUTPUT (step-scoped,
per GitHub Actions security hardening guide)
- Narrow hashFiles glob from '**/pnpm-lock.yaml' to 'pnpm-lock.yaml'
(root-only, avoids spurious cache busts from docs/examples lockfiles)
- Reword comment to show ABI mismatch is symmetric across all versions
- Document that actions/cache is equally fork-safe (GitHub platform guarantee)
pnpm rebuild better-sqlite3 was a no-op — pnpm treats the arg as a
workspace package name and exits silently when none matches.
Root fix: replace setup-node's built-in cache: "pnpm" (whose key omits
the Node.js version) with a manual actions/cache step that includes
matrix.node-version in the key. Each Node version gets its own pnpm
store, so the ABI-137 better-sqlite3 binary cached from a Node 24 job
can no longer be served to Node 20 (needs ABI 115) or Node 22 (needs
ABI 127) jobs.
The pnpm store cache key used by setup-node does not include the Node.js
version, so a cache entry written by a Node 24 job contains an ABI-137
better-sqlite3 binary. When Node 20 (ABI 115) or Node 22 (ABI 127) jobs
restore from the same cache key they get the wrong binary and all
sqlite-runner tests fail with "Module did not self-register".
Adding `pnpm rebuild better-sqlite3` after install re-runs prebuild-install
for the active Node version, downloading the correct prebuilt binary and
overwriting whatever ABI was in the restored cache.
Root cause first appeared after the setup-node v4→v6 and pnpm/action-setup
v4→v6 bumps (May 15, PRs #4857/#4858) reset the cold cache, allowing a
Node 24 binary to poison the shared store entry.
The release/publish workflow's build job uploads the entire workspace
as an artifact for the publish job to download. With node_modules and
build caches included, this monorepo produces ~6.4M files, which OOMs
upload-artifact's Node process at its 4GB heap limit during
enumeration:
FATAL ERROR: Ineffective mark-compacts near heap limit
Allocation failed - JavaScript heap out of memory
Excluding node_modules, .next, .turbo, and .nx cuts the file count by
orders of magnitude. The publish job runs `pnpm install --frozen-lockfile`
after download to restore node_modules deterministically from
pnpm-lock.yaml (carried in the artifact), so the publish step still
runs against exactly the resolved dependency tree the build job used.
Fixes the upload step that hung for 12+ minutes and then OOM'd when
the workflow_dispatch trigger added in #4808 was first exercised.
## Summary
Adds a `workflow_dispatch` trigger to
`.github/workflows/publish-release.yml` so the release/publish workflow
can be manually retriggered against the latest commit on `main`.
This is the escape hatch for the current edge case: a release failed
mid-flight, `main` already has the bumped versions, but nothing was
published and the normal PR-merge trigger can't fire again without a
fresh release PR.
## What this covers
✅ Failures **before** the `Publish to npm` step succeeded:
- Build errors
- Infrastructure blips (runner crash, OIDC token issue, npm registry
hiccup)
- Pre-publish workflow bugs (e.g. the `git config --local` issue fixed
in #4874)
## What this does NOT cover
❌ Failures **after** `Publish to npm` succeeded:
- If npm publish ran but tag push or GitHub Release creation failed,
dispatching this workflow will fail at `Publish to npm` with an `already
published` error.
- The `Check for pre-existing tags` step will also block retries where
the tag was pushed but later steps failed.
For those cases: finish the release by hand using `release-notes.md`
from the merged release PR — manually create the git tag at the publish
commit and create the GitHub Release. Don't dispatch.
Both the in-file YAML comment above `workflow_dispatch:` and the
dispatch form's `scope` input description spell this out so operators
see it before triggering.
## Change
Minimal: 33 insertions, 7 deletions in one workflow file.
- New `workflow_dispatch` trigger with a required `scope` choice input
(`monorepo` | `angular`)
- `if` condition widened to also accept `workflow_dispatch` runs
- Scope-extraction step now uses `inputs.scope` when present, falls back
to the existing PR-branch parsing otherwise
- YAML comment above the trigger documents the coverage limits
The normal PR-merge trigger and the entire downstream publish pipeline
are unchanged.
## Test plan
- [ ] Merge to main
- [ ] Actions → "release / publish" → "Run workflow" → pick scope →
confirm publish proceeds against current main versions
- [ ] Confirm a normal release-PR merge still triggers and behaves
identically
- [ ] Confirm dispatch against a state where npm publish already
succeeded fails fast at "Publish to npm" (does not corrupt anything)
## Summary
Shell-docs is becoming the canonical authoring source for CopilotKit
documentation on the upcoming cutover. The existing
\`showcase_docs-sync.yml\` workflow auto-syncs from
\`docs/content/docs/\` down to \`showcase/shell-docs/src/content/docs/\`
on every push to main that touches the upstream tree — which would
clobber edits made directly in \`showcase/shell-docs/\` after cutover.
This PR disables the push trigger on
\`.github/workflows/showcase_docs-sync.yml\` and keeps
\`workflow_dispatch\` for manual re-run if the cutover is reverted.
## Files changed
- \`.github/workflows/showcase_docs-sync.yml\` — 5 lines
## Test plan
- [ ] Confirm the workflow no longer fires on pushes to main that touch
\`docs/content/docs/**\` or \`docs/snippets/**\`
- [ ] Confirm \`workflow_dispatch\` still allows manual runs from the
Actions UI
The format job's "Commit formatting fixes" step previously fed the raw
`git diff --name-only` output into `git add`. If a tracked-but-gitignored
path (e.g. a build artifact) appeared in the diff, `git add` refused the
ignored path and aborted the step, so the auto-fix commit never landed
on the PR branch. PRs could then merge with formatting violations still
present, leaving main red on the post-merge push-scope check.
Stage only the paths listed in `.pr-format-files.existing.txt` — the
same scoped set the formatter operates on — so unrelated diffs in the
working tree can't poison the commit.
Adds a manual workflow_dispatch trigger so the release/publish workflow
can be re-run against the latest commit on main when the normal flow
(merge a release/publish/* PR) is unavailable — e.g. after a failed
release that already bumped versions on main but did not publish.
Scope of coverage:
- Covers failures BEFORE the "Publish to npm" step succeeds (build
errors, infra blips, git config bugs).
- Does NOT cover post-npm-publish failures: if npm publish already
succeeded but a later step failed, the dispatch retry will fail at
"Publish to npm" with "already published", and the
"Check for pre-existing tags" step will block retries where the tag
was pushed. Those cases need manual remediation using release-notes.md
from the merged release PR.
Both the in-file YAML comment and the dispatch form's scope input
description spell this out so operators see it before triggering.
git config --global persists user.name/email beyond the job into the
runner environment. Changed to --local so credentials are scoped to
the checkout directory only.
Upstream release notes contain @username references that trigger GitHub
notifications when posted as PR comments. Strip mention-prefix @ from
standalone mentions while preserving @scope/pkg, email@domain, and
action@version patterns.
ClosesCopilotKit/aimock#216
zizmor-action inputs use hyphens (min-severity, advanced-security),
not underscores. The wrong names were silently ignored, causing the
action to default to SARIF upload mode which fails without
security-events: write permission.