Skip to content

Share realm sync deployment tracking through a composite action - #6920

Merged
habdelra merged 2 commits into
mainfrom
cs-14258-realm-sync-workflows-copy-the-same-deployment-tracking-shell
Oct 22, 2026
Merged

habdelra merged 2 commits into
mainfrom
cs-14258-realm-sync-workflows-copy-the-same-deployment-tracking-shell

Conversation

@habdelra

@habdelra habdelra commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Important

Merge order: #6915 has merged; this PR targets main.

  • boxel-catalog's sync-to-workspace.yml and deploy-production.yml move onto these actions in CS-14261. That catalog PR merges after this one, because it calls the actions at @main.

What this changes

Three workflows sync a git-sourced realm with boxel realm push --changed-since, and each carried its own copy of the shell around the push. This PR moves that shell into two composite actions under .github/actions/realm-deployment/:

  • start finds the revisions the realm may hold, builds the push arguments, and records an in-progress GitHub deployment. It fails before doing any of that when boxel isn't on PATH. Its push arguments come from the CLI's --help, so a missing CLI would otherwise look like an old one.
    • Revisions: it walks the environment's recorded deployments back to the newest success, and keeps that revision plus every newer one. With no success, or a revision the checkout's history doesn't reach, the push sends every file.
    • Push arguments: one --changed-since per revision, plus --no-realm-events, each only when boxel realm push --help lists it. The caller splices the push-args output into its push with read -ra.
    • For the production catalog deploy: known-revision takes the revision catalog-deploy-check.ts reports. That revision stands in for a successful deployment. require-revisions fails before anything is recorded when the push would send every file.
    • Other inputs: ref, payload, description and repository-path cover the rest of what the catalog deploys record.
  • finish marks the deployment success or failure from the push step's outcome. Composite actions can't run a post step, so this is its own action. The caller runs it with if: always().

sync-workspace.yml uses both actions as $/.github/actions/realm-deployment/{start,finish}. That form resolves them in cardstack/boxel at the revision of the workflow the caller runs. A ./ path would resolve against the caller's checkout, and @main would ignore a caller's pin. Its concurrency group, checkout, CLI install, profile setup and reporting stay the same.

The logic lives in start.sh, so it can be tested on its own. start.test.sh runs it against a scratch git repository, with gh and boxel stubbed. The cases cover the success walk, duplicate SHAs, no success, a revision outside the history, a failed listing, a known revision, an older CLI, a missing CLI, and both require-revisions refusals. The path-gated Realm Deployment Self-Test workflow runs it and shellcheck.

Behavior differences from the inline copies

  • A failed deployment listing logs a warning before falling back to a full push. The inline loop fell back without a warning.
  • The notices are titled <environment> realm sync.

Test plan

  • bash .github/actions/realm-deployment/start.test.sh: 12 cases pass. Removing the loop's break on success makes one of them fail.
  • shellcheck and prettier on the changed files. actionlint 1.7.12 doesn't recognize $/ yet, and nothing in CI runs it.
  • Realm Deployment Self-Test and YAML Lint on this PR.
  • After merge, the next boxel-skills or boxel-home staging sync records a staging deployment. Its log shows the revisions and the --changed-since arguments, and the deployment finishes success.

🤖 Generated with Claude Code

sync-workspace.yml, and boxel-catalog's staging and production deploys,
each carried their own copy of the shell that finds the revisions a realm
may hold, records the GitHub deployment, and builds the `boxel realm push`
arguments. The copies had started to drift.

realm-deployment/start finds the revisions (with an optional known
revision and a require-revisions guard for the production catalog),
builds the --changed-since / --no-realm-events arguments from the CLI's
--help, and records an in-progress deployment. realm-deployment/finish
marks it success or failure. Composite actions have no post step, so the
finish is its own action.

sync-workspace.yml uses both by name at @main, since a reusable workflow
resolves `./` actions against the caller's checkout. start.sh is tested
against stubbed gh and boxel and a scratch repo, run by a path-gated
self-test workflow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-22T14:49:46.444256Z 0730d41 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0730d413d3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/sync-workspace.yml Outdated
env:
ENVIRONMENT: ${{ steps.baseline.outputs.environment }}
WORKSPACE_URL: ${{ steps.baseline.outputs.environment == 'production' && inputs.production-workspace-url || inputs.staging-workspace-url }}
uses: cardstack/boxel/.github/actions/realm-deployment/start@main

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Resolve the action from the reusable workflow revision

When a consumer pins this reusable workflow to a tag or commit SHA, this reference still downloads the action from the mutable main branch; the matching finish step does the same. Future action changes can therefore alter or break supposedly pinned production syncs, and workflows run from another revision do not exercise their corresponding action implementation. GitHub documents the $/path/to/action self-reference as resolving against the repository and commit containing the workflow, so both composite-action references should use that form.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] Fixed in 54d8c29. Both steps now use $/.github/actions/realm-deployment/{start,finish}. That resolves them in cardstack/boxel at the revision of sync-workspace.yml the caller runs, so a caller that pins the workflow to a tag or SHA gets the actions from that same revision.

@habdelra habdelra left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] This review checked two things. First, whether start/finish keep sync-workspace.yml's behavior. Second, whether their inputs can carry boxel-catalog's staging sync and production deploy: the from baseline as known-revision, ref/payload, the catalog/ checkout as repository-path, and the full-push refusal as require-revisions. It did not run the actions on a runner. The remote @main resolution is left to the post-merge item already in the test plan.

No blocking issues. The inputs can carry both catalog callers' semantics. One non-blocking ask: start.sh misbehaves when it runs before the CLI install, and both catalog workflows currently run in that order.

  1. Fail fast when boxel isn't on PATH instead of treating it as an old CLI. See the comment on push_help in start.sh.

Comment on lines +66 to +68
# A boxel-cli that doesn't list an option rejects it, so each one is passed
# only when `realm push --help` lists it.
push_help=$(boxel realm push --help 2>&1 || true)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] When boxel isn't on PATH, this probe treats it as an old CLI. push-args comes out empty and the step still succeeds, so a staging sync sends every file, with a notice that blames the CLI version. Under require-revisions, the refusal reads "No revision to compare against", which isn't the real cause either. I ran start.sh with boxel missing from PATH: it exits 0 with push-args= empty, and with REQUIRE_REVISIONS=true it exits 1 with that error.

The only thing guarding this is the "after … the boxel-cli install" line in start/action.yml. Both catalog workflows, sync-to-workspace.yml and deploy-production.yml, record their deployment before their Install Boxel CLI step. A step-for-step move onto this action lands right here: staging re-sends the whole catalog, and production refuses with a misleading message.

Please fail fast at the top of start.sh, before anything is listed or recorded:

command -v boxel > /dev/null || {
  echo "::error title=$title::boxel isn't on PATH. Run realm-deployment/start after installing @cardstack/boxel-cli."
  exit 1
}

Please also add a start.test.sh case that removes the boxel stub. (Checking the exit status of --help wouldn't work here: it would turn the intended old-CLI fallback into a failure.)

Regression in the new action. Non-blocking: sync-workspace.yml already installs the CLI before start.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] Fixed in 54d8c29. start.sh now checks command -v boxel before it lists or records anything. A missing CLI fails the step with "boxel isn't on PATH. Run realm-deployment/start after installing @cardstack/boxel-cli." It no longer falls through to the older-CLI path. start.test.sh has a case that runs it on a PATH with no boxel and expects exit 1 with that error.

start.sh reads the push arguments from `boxel realm push --help`, so a
missing CLI looked like an old one and the push would send every file.
It now fails before listing or recording anything, with a test case.

sync-workspace.yml references the actions as `$/.github/actions/...`,
which resolves them at the revision of the reusable workflow the caller
runs, so a caller pinned to a tag or SHA gets the matching actions
rather than main's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@habdelra

Copy link
Copy Markdown
Contributor Author

[Claude Code 🤖] Thanks for the review. The one finding, failing fast when boxel isn't on PATH, is fixed in 54d8c29. The reply is in its thread.

@habdelra
habdelra requested a review from a team October 22, 2026 14:54
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Host Test Results

    1 files      1 suites   1h 29m 28s ⏱️
5 843 tests 5 832 ✅ 11 💤 0 ❌
5 858 runs  5 847 ✅ 11 💤 0 ❌

Results for commit 54d8c29.

Realm Server Test Results

    1 files    361 suites   1h 51m 23s ⏱️
6 005 tests 6 005 ✅ 0 💤 0 ❌
6 068 runs  6 068 ✅ 0 💤 0 ❌

Results for commit 54d8c29.

@habdelra
habdelra changed the base branch from cs-14191-sync-workspace-no-realm-events to main October 22, 2026 17:17
@habdelra
habdelra merged commit c060fce into main Oct 22, 2026
96 of 98 checks passed
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