Add CMS Strapi changelog sync pipeline#1165
Conversation
Introduces prepare/sync/publish tooling that LLM-simplifies English changelog into gitignored staging, pushes comfyui and cloud drafts to Strapi, auto-refreshes published-versions.json on publish, and adds CI workflows plus agent skills.
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
🌐 i18n translation sync reminder@comfyui-wiki English documentation was updated in this PR. Please complete or schedule translation updates for the following files: Japanese (
|
|
Warning Review limit reached
More reviews will be available in 2 minutes and 42 seconds. Learn how PR review limits work. To continue reviewing without waiting, enable usage-based billing in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (18)
📝 WalkthroughWalkthroughA new end-to-end CMS changelog sync pipeline is introduced: TypeScript scripts prepare simplified/translated staging content, sync it to Strapi as drafts, publish reviewed drafts, maintain a published-versions registry, and delete stale drafts. Two GitHub Actions workflows automate sync on push and registry validation on PRs. Agent guides and Cursor skill docs document all workflows. A changelog edit removes the SeedVR2 entry, with ja/ko/zh translations updated accordingly. ChangesCMS Changelog Automation Pipeline
Sequence DiagramssequenceDiagram
rect rgba(70, 130, 180, 0.5)
note over CI,StrapiAPI: Prepare stage (LLM-driven)
CI->>prepare-cms-changelog.ts: pnpm cms:prepare (push trigger)
prepare-cms-changelog.ts->>cms-simplify-en.ts: simplifyEnglish(entries, docsContent)
cms-simplify-en.ts->>TranslateAPI: POST /chat/completions (simplify prompt)
TranslateAPI-->>cms-simplify-en.ts: simplified EN block
cms-simplify-en.ts->>StagingFiles: writeStagingCheckpoint(en/changelog)
prepare-cms-changelog.ts->>cms-staging-translate.ts: translateLocales(enContent)
cms-staging-translate.ts->>TranslateAPI: POST /chat/completions (translate block)
TranslateAPI-->>cms-staging-translate.ts: translated block
cms-staging-translate.ts->>StagingFiles: writeStagingCheckpoint(ja/zh/ko/changelog)
end
rect rgba(60, 179, 113, 0.5)
note over CI,StrapiAPI: Sync stage (Strapi drafts)
CI->>sync-to-strapi.ts: pnpm cms:sync
sync-to-strapi.ts->>StrapiClient: ping(release-notes)
StrapiClient->>StrapiAPI: GET /api/release-notes
StrapiAPI-->>StrapiClient: ok
sync-to-strapi.ts->>StrapiClient: create/update draft (EN locale)
StrapiClient->>StrapiAPI: POST/PUT draft payload
StrapiAPI-->>StrapiClient: draft document
sync-to-strapi.ts->>StrapiClient: create/update draft (ja/zh/ko locale)
StrapiClient->>StrapiAPI: POST/PUT locale draft
StrapiAPI-->>StrapiClient: draft document
end
rect rgba(255, 140, 0, 0.5)
note over CI,StrapiAPI: Publish stage (manual)
CI->>publish-cms-drafts.ts: pnpm cms:publish
publish-cms-drafts.ts->>StrapiClient: publishLocale(documentId, locale)
StrapiClient->>StrapiAPI: PUT status=published
StrapiAPI-->>StrapiClient: published document
publish-cms-drafts.ts->>PublishedVersionsRegistry: writePublishedVersions(merged)
end
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…shes and enhancing descriptions for new features, nodes, and performance improvements across Japanese, Korean, and Chinese versions.
…. Adjusted documentation to reflect changes in CI workflow for clarity.
There was a problem hiding this comment.
Actionable comments posted: 21
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.cursor/skills/cms-changelog-sync/SKILL.md:
- Around line 17-27: The fenced code block at line 17 in the SKILL.md file is
missing a language identifier after the opening triple backticks, which violates
markdownlint rule MD040. Add a language identifier such as `text` or `bash`
immediately after the opening ``` to specify the block's language and resolve
the lint error.
In @.github/scripts/cms/cms-attention.ts:
- Around line 20-22: The catch block that returns an empty object {} is silently
swallowing all errors including malformed JSON and permission issues, preventing
visibility into why attention overrides fail to load. Replace the silent
fallback by logging the error details (error message and context) before
returning, ensuring that parse failures and file access issues are visible for
debugging rather than being hidden from view.
In @.github/scripts/cms/cms-env.ts:
- Line 16: The condition on line 16 uses a falsy check with `!process.env[key]`
which will treat empty strings as missing values and overwrite them. Change this
to an explicit undefined check using `process.env[key] === undefined` instead,
so that intentionally set empty string values in environment variables are
preserved and not overwritten with the default value.
- Line 18: The empty catch block on line 18 is suppressing all errors from
reading the `.env.local` file indiscriminately. Instead of catching all errors
silently, modify the catch block to check if the error code is ENOENT (file not
found) and only ignore that specific error type. For any other error type, log
the error or rethrow it so that configuration loading failures are visible and
debuggable rather than silently ignored.
In @.github/scripts/cms/cms-staging-io.ts:
- Around line 48-53: The readStaging function's catch block swallows all errors
indiscriminately by returning an empty string, which masks real I/O failures
like permission errors or disk issues. Modify the catch block to check if the
caught error is a file-not-found error (ENOENT), and only return an empty string
in that specific case. For all other types of errors, re-throw the error so that
real I/O failures are properly propagated and don't cause invalid data to be
written by the caller.
In @.github/scripts/cms/cms-staging-translate.ts:
- Around line 56-58: In the cms-staging-translate.ts file, when the EN block is
missing and the code logs a skip message in the if (!enBlock) condition, the
skipped counter is not being incremented. Add a line to increment the skipped
variable before the continue statement in the if (!enBlock) block to ensure the
summary statistics accurately reflect the number of skipped entries.
In @.github/scripts/cms/cms-translate-client.ts:
- Around line 39-51: The fetch call in the request to the chat completions
endpoint lacks a timeout mechanism, which can cause the cms:prepare command to
hang indefinitely if the provider stalls. Add an AbortController instance and
set a timeout (typically 30-60 seconds) that will abort the fetch request if it
exceeds the duration. Attach the abort signal to the fetch options and handle
the abort error appropriately to prevent the process from hanging.
In @.github/scripts/cms/cms-versions.ts:
- Around line 17-19: The catch block that returns an empty string "" is silently
swallowing errors, which can mislead callers into thinking there are no changes
when the actual git operation failed. Instead of catching and returning "" in
this catch block, either rethrow the error so it propagates up to the caller or
return a typed failure object that explicitly indicates an error occurred. This
allows callers to properly handle and respond to failures rather than proceeding
with false assumptions about the state of changes.
- Around line 13-16: The function at lines 13-16 uses execSync with shell
command interpolation of the before and after git references, which creates a
shell injection vulnerability. Replace the execSync call with execFileSync,
passing "git" as the command and constructing the arguments as an array
(containing "diff", before, after, "--", and "changelog/index.mdx") instead of
interpolating them into a shell command string. Maintain the same options object
for encoding and cwd.
In @.github/scripts/cms/delete-cms-drafts.ts:
- Around line 82-90: The enIsPublished function is not correctly filtering for
English locale publications. Currently, the publishedVersions Set is created by
filtering only on project but includes all locales, so a version published in
any locale would be considered "EN-published". Fix this by adding a locale check
when constructing the publishedVersions Set to only include entries where the
locale is specifically English (likely e.locale === 'en' or similar), ensuring
that only actual English-published versions are used for the fast-path check in
the enIsPublished function.
In @.github/scripts/cms/published-versions-sync.ts:
- Around line 87-95: The merge operation in mergePublishedEntries on line 88
retains stale entries from the current published registry that are no longer
present in the CMS data (fromCms), preventing the removed detection logic on
line 93 from correctly identifying true deletions. To fix this, modify the merge
strategy to be scoped such that entries present in current.published but absent
from fromCms are properly classified as removed. Ensure the merged result only
contains entries that exist in the current CMS data (fromCms) plus any entries
from current.published that should be retained according to the scoped merge
logic, so that the removed filter correctly identifies entries that have been
deleted from the CMS.
In @.github/scripts/cms/published-versions.schema.json:
- Line 13: The version regex pattern in the "version" property is missing the
end anchor character which allows invalid version suffixes to pass validation.
Add a `$` character at the end of the pattern `^\\d+\\.\\d+\\.\\d+` to make it
`^\\d+\\.\\d+\\.\\d+$`. This ensures the pattern matches the complete version
string strictly without allowing trailing characters like `-beta`, `rc1`, or
other unwanted suffixes.
In @.github/scripts/cms/published-versions.ts:
- Around line 22-25: The loadPublishedVersions function currently casts the
parsed JSON directly to PublishedVersionsFile without validating the actual
structure at runtime, which can cause issues if the file is malformed. Add
runtime validation of the parsed JSON data before the return statement to ensure
it matches the expected PublishedVersionsFile shape. This can be done using a
schema validation library or by manually checking required properties exist with
correct types. Only return the value after confirming it passes validation, so
malformed data is caught at load time rather than causing unexpected behavior
later during publish or sync operations.
In @.github/scripts/cms/set-cms-attention.ts:
- Around line 68-84: The updateAttentionInStrapi function hardcodes field names
"project" and "version" in the filters object instead of using the configured
field names from cms-config. Replace the hardcoded filters object construction
(currently { project, version }) with dynamic field name mapping that uses the
configured project_field and version_field from the cms-config to ensure lookups
work correctly regardless of custom field configurations. Apply the same fix to
the other location mentioned at lines 150-154 where similar hardcoded field name
references appear.
In @.github/scripts/cms/strapi-client.ts:
- Around line 216-218: The publishLocale() function hardcodes the field names as
`["content", "project", "version", "attention"]`, but these should instead
reference the dynamic field mappings from CmsConfig (content_field,
project_field, version_field, attention_field). Replace the hardcoded array with
the corresponding config field values so that if the config field names change,
the published payload will use the correct updated field names and avoid
incomplete or mismatched data being sent.
- Around line 241-243: The delete() method needs a defensive check to prevent
applying the "draft" status value, which causes Strapi 5 to return a 500 error.
Modify the status parameter handling in the delete() method to skip the
this.withStatus() call when opts?.status is "draft", or alternatively, throw an
error with a clear message if a caller attempts to delete with draft status.
This guards against runtime failures while maintaining the existing API contract
that allows the status parameter.
In @.github/scripts/cms/sync-to-strapi.ts:
- Around line 216-227: The registry-first skip check at the
isPublishedInRegistry call can skip tasks before confirming that an English base
document exists in the CMS, which can cause later create actions to fail with an
"English base missing" error. Reorder the validation logic so that the check for
English base document existence in the CMS is performed before applying the
registry-based skip decision, ensuring that registry state is only used to skip
tasks when the necessary prerequisite (English base document) is confirmed to
exist in the CMS. This prevents planning non-EN locale creates without a valid
English base and avoids strand syncs when the registry is stale or drifted.
In @.github/workflows/cms-changelog-sync.yml:
- Around line 3-16: Add a concurrency configuration to the cms-changelog-sync
workflow to prevent multiple sync jobs from running simultaneously on the same
CMS drafts. Insert a `concurrency` block at the workflow level (after the `on`
trigger definition and before the `jobs` section) that specifies a concurrency
group name (such as 'cms-sync') and sets `cancel-in-progress: true` to
automatically cancel any previously running sync jobs when a new push to main
occurs, ensuring serialized execution and preventing race conditions.
- Around line 1-25: The workflow has three security vulnerabilities that need to
be addressed. First, add a permissions block at the workflow level (after the
`on` section and before `jobs`) and specify `contents: read` to follow the
principle of least privilege. Second, pin the `actions/checkout@v4` action on
line 19 from a version tag to a specific commit SHA (e.g., using the format
`actions/checkout@<commit-sha>`) instead of relying on the mutable v4 tag.
Third, pin the `oven-sh/setup-bun@v2` action on line 24 similarly to a specific
commit SHA rather than the version tag. Fourth, add `persist-credentials: false`
to the checkout step's `with` block to prevent the GitHub token from being
persisted on disk. These changes harden the workflow against supply chain
attacks and unauthorized token usage.
In `@AGENTS.md`:
- Around line 17-32: The fenced code block starting at line 17 is missing a
language identifier, which violates markdownlint rule MD040. Add a language tag
(such as `text` or `plaintext`) immediately after the opening triple backticks
to properly identify the code block language and satisfy the linting
requirement.
- Around line 82-88: Fix the ordered-list numbering in the agent rules section
of AGENTS.md. The last item in the list is incorrectly numbered as 5. when it
should be 6., since it follows the items numbered 1 through 5. Update the line
containing "Strapi publish is **manual by default**" to start with 6. instead of
5. to correct the sequence.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 652b0346-409a-489c-9c2c-ec1ec1b02f49
📒 Files selected for processing (42)
.cursor/skills/cms-changelog-sync/SKILL.md.cursor/skills/docs-i18n-review/SKILL.md.cursor/skills/docs-i18n-translate/SKILL.md.env.local.example.github/scripts/cms/README.md.github/scripts/cms/attention-overrides.json.github/scripts/cms/changelog-parse.ts.github/scripts/cms/cms-args.ts.github/scripts/cms/cms-attention.ts.github/scripts/cms/cms-config.json.github/scripts/cms/cms-config.ts.github/scripts/cms/cms-env.ts.github/scripts/cms/cms-simplify-en.ts.github/scripts/cms/cms-simplify-prompt.ts.github/scripts/cms/cms-staging-io.ts.github/scripts/cms/cms-staging-translate.ts.github/scripts/cms/cms-strapi-utils.ts.github/scripts/cms/cms-translate-client.ts.github/scripts/cms/cms-versions.ts.github/scripts/cms/delete-cms-drafts.ts.github/scripts/cms/format-cms-content.ts.github/scripts/cms/prepare-cms-changelog.ts.github/scripts/cms/publish-cms-drafts.ts.github/scripts/cms/published-versions-sync.ts.github/scripts/cms/published-versions.json.github/scripts/cms/published-versions.schema.json.github/scripts/cms/published-versions.ts.github/scripts/cms/set-cms-attention.ts.github/scripts/cms/simplify-changelog.ts.github/scripts/cms/strapi-client.ts.github/scripts/cms/sync-to-strapi.ts.github/scripts/cms/update-published-versions.ts.github/workflows/cms-changelog-sync.yml.github/workflows/cms-published-versions-check.yml.gitignore.mintignoreAGENTS.mdchangelog/index.mdxja/changelog/index.mdxko/changelog/index.mdxpackage.jsonzh/changelog/index.mdx
💤 Files with no reviewable changes (1)
- changelog/index.mdx
| ``` | ||
| changelog/index.mdx ← docs source of truth (do not shorten for CMS) | ||
| │ | ||
| ▼ pnpm cms:prepare:en / cms:prepare | ||
| .github/scripts/cms/staging/ | ||
| en/changelog/index.mdx ← LLM-simplified popup EN | ||
| {zh,ja,ko,fr,ru,es}/… ← translated from simplified EN | ||
| │ | ||
| ▼ pnpm cms:sync | ||
| Strapi CMS (draft only) → manual Publish → published-versions.json | ||
| ``` |
There was a problem hiding this comment.
Specify a language for the top fenced architecture block.
Line 17 opens a fenced block without a language identifier (markdownlint MD040). Use text (or bash if intended) to keep lint green.
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 17-17: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.cursor/skills/cms-changelog-sync/SKILL.md around lines 17 - 27, The fenced
code block at line 17 in the SKILL.md file is missing a language identifier
after the opening triple backticks, which violates markdownlint rule MD040. Add
a language identifier such as `text` or `bash` immediately after the opening ```
to specify the block's language and resolve the lint error.
Source: Linters/SAST tools
| name: CMS Changelog Sync | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
| paths: | ||
| - 'changelog/index.mdx' | ||
| - 'zh/changelog/index.mdx' | ||
| - 'ja/changelog/index.mdx' | ||
| - 'ko/changelog/index.mdx' | ||
| - '.github/scripts/cms/**' | ||
|
|
||
| jobs: | ||
| sync-drafts: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Setup Bun | ||
| uses: oven-sh/setup-bun@v2 | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n .github/workflows/cms-changelog-sync.ymlRepository: Comfy-Org/docs
Length of output: 1852
Don't let unpinned actions take the bun out of your security!
Lines 19 and 24 use unpinned third-party actions (version tags instead of commit SHAs), which creates supply chain risk. The workflow also lacks an explicit permissions block and doesn't prevent token persistence. Add permissions: contents: read, pin actions to commit SHAs, and set persist-credentials: false to stay in the credential clear—these hardening measures take minimal effort and significantly reduce attack surface.
🔐 Suggested hardening patch
name: CMS Changelog Sync
on:
push:
branches:
- main
paths:
- 'changelog/index.mdx'
- 'zh/changelog/index.mdx'
- 'ja/changelog/index.mdx'
- 'ko/changelog/index.mdx'
+permissions:
+ contents: read
+
jobs:
sync-drafts:
runs-on: ubuntu-latest
steps:
- name: Checkout code
- uses: actions/checkout@v4
+ uses: actions/checkout@<PINNED_COMMIT_SHA>
with:
fetch-depth: 0
+ persist-credentials: false
- name: Setup Bun
- uses: oven-sh/setup-bun@v2
+ uses: oven-sh/setup-bun@<PINNED_COMMIT_SHA>🧰 Tools
🪛 zizmor (1.25.2)
[warning] 18-21: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[warning] 1-50: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block
(excessive-permissions)
[error] 19-19: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 24-24: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[info] 15-15: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
[warning] 3-12: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/cms-changelog-sync.yml around lines 1 - 25, The workflow
has three security vulnerabilities that need to be addressed. First, add a
permissions block at the workflow level (after the `on` section and before
`jobs`) and specify `contents: read` to follow the principle of least privilege.
Second, pin the `actions/checkout@v4` action on line 19 from a version tag to a
specific commit SHA (e.g., using the format `actions/checkout@<commit-sha>`)
instead of relying on the mutable v4 tag. Third, pin the `oven-sh/setup-bun@v2`
action on line 24 similarly to a specific commit SHA rather than the version
tag. Fourth, add `persist-credentials: false` to the checkout step's `with`
block to prevent the GitHub token from being persisted on disk. These changes
harden the workflow against supply chain attacks and unauthorized token usage.
Source: Linters/SAST tools
| ``` | ||
| ┌─────────────────────────────────────────────────────────────────┐ | ||
| │ changelog/index.mdx (full English — edit here for releases) │ | ||
| └────────────┬───────────────────────────────┬────────────────────┘ | ||
| │ │ | ||
| ▼ ▼ | ||
| DOCS (Mintlify) CMS (Strapi popup) | ||
| pnpm translate pnpm cms:prepare:en | ||
| → zh/ ja/ ko/ → staging/en/ (gitignored) | ||
| COMMIT to git pnpm cms:prepare → staging/{lang}/ | ||
| pnpm cms:sync → Strapi draft | ||
| │ │ | ||
| ▼ ▼ | ||
| Mintlify site In-app notification | ||
| (full changelog) (3–5 bullets, PR links) | ||
| ``` |
There was a problem hiding this comment.
Add a language tag to the fenced architecture block.
Line 17 starts a fenced block without a language identifier, which fails markdownlint MD040.
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 17-17: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@AGENTS.md` around lines 17 - 32, The fenced code block starting at line 17 is
missing a language identifier, which violates markdownlint rule MD040. Add a
language tag (such as `text` or `plaintext`) immediately after the opening
triple backticks to properly identify the code block language and satisfy the
linting requirement.
Source: Linters/SAST tools
Harden error handling, use CMS as source of truth for sync skips, fix CI to run with bun, and tighten registry validation.
Align registry locale lists and entries with the live CMS published state so the PR registry check passes.
Summary
cms:prepare,cms:sync,cms:publish) to LLM-simplify English changelog into gitignored staging and push comfyui + cloud release-note drafts to Strapi.published-versions.jsonafter publish; supportattentionoverrides andcms:set-attentionfor high-priority popups.AGENTS.md.Note
Restores CMS work after accidental direct push to
main(reverted in 9b93a07).Test plan
CMS_BASE_URL,CMS_API_TOKEN, and translate API keys in.env.localpnpm cms:prepare:en -- --force v0.25.1— verify staging EN + cloud copypnpm cms:preview -- v0.25.1— dry-run shows both projectspnpm cms:sync -- v0.25.1— drafts appear in Strapi for comfyui and cloudpnpm cms:publish -- v0.25.1— live + JSON updatedcms-changelog-syncworkflow