feat: automate versioned CLI command documentation scaffolding and changelog engine#43
Conversation
Updated the changelog workflow to push changes to a feature branch instead of the default branch.
Updated the changelog workflow to include staging and committing of docs.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
Note
|
| Layer / File(s) | Summary |
|---|---|
Triggers and checkout .github/workflows/changelog.yml |
Workflow triggers on release events and v*.*.* tag pushes, sets job concurrency and contents: write permission, and checks out the default branch with full history. |
Changelog action configuration .github/workflows/changelog.yml |
Runs mikepenz/release-changelog-builder-action with category-to-label mappings (Features/Fixes/Improvements/Documentation) and forwards GITHUB_TOKEN to obtain changelog output. |
Docs scaffold and README generation .github/workflows/changelog.yml |
Computes VERSION from the ref name, copies .github/docs-template (including dotfiles) or builds a fallback docs/${VERSION} structure, injects **Version:** ${VERSION} into Markdown files missing it, and writes docs/${VERSION}/README.md with header, published date, and changelog content (combined from $CHANGELOG and action output). |
Commit and push docs changes .github/workflows/changelog.yml |
Configures the Actions bot git identity, stages docs/, exits if no changes, otherwise commits with [skip ci] and pushes the updates to the default branch. |
sequenceDiagram
participant GitHub as GitHub Events
participant Workflow as Changelog Workflow
participant Builder as release-changelog-builder
participant FS as Repository Filesystem
participant Git as Git Push
GitHub->>Workflow: release published / tag push (v*.*.*)
Workflow->>Builder: run changelog builder (with categories)
Builder-->>Workflow: generated changelog text
Workflow->>FS: create docs/${VERSION} (copy template or fallback)
Workflow->>FS: inject **Version:** ${VERSION} into Markdown files
Workflow->>FS: write docs/${VERSION}/README.md (changelog + metadata)
Workflow->>Git: commit and push docs/ to default branch
🎯 3 (Moderate) | ⏱️ ~20 minutes
Poem
📦 A tag flies by, the changelog wakes,
Templates copied, and version marks placed,
README filled with notes of release,
A bot signs off, the docs find their peace,
Versions preserved, history embraced.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | The title accurately summarizes the main change: automating versioned CLI documentation scaffolding and changelog generation via a new GitHub Actions workflow. |
| Docstring Coverage | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. |
| Linked Issues check | ✅ Passed | Check skipped because no linked issues were found for this pull request. |
| Out of Scope Changes check | ✅ Passed | Check skipped because no linked issues were found for this pull request. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing Touches
🧪 Generate unit tests (beta)
- Create PR with unit tests
Comment @coderabbitai help to get the list of available commands and usage tips.
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 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 @.github/workflows/changelog.yml:
- Around line 11-12: The generate-changelog job lacks explicit token permissions
for repo writes; update the workflow to request the required permission by
adding a permissions block that grants contents: write (e.g., add "permissions:
contents: write" at the job or workflow level) so the job (generate-changelog)
can push changes using the GITHUB_TOKEN; ensure the permissions block is placed
alongside the job definition and not nested inside a step.
- Around line 46-48: The cp command fails when TEMPLATE_DIR exists but is empty;
change the step to only run cp when the glob matches entries—e.g., test for
entries with compgen -G "$TEMPLATE_DIR"/* (or use a for loop with bash nullglob)
and only then run cp -r "$TEMPLATE_DIR"/* "$TARGET_DIR"/; this keeps the
existing variables TEMPLATE_DIR and TARGET_DIR and ensures the job does not
abort when the template directory is empty.
- Around line 56-57: The fallback directory creation currently uses TARGET_DIR
with subdirs "config", "runner", "docker", "kubernetes", "monitoring" which
doesn't match the documented template contract; update the mkdir -p invocation
that uses TARGET_DIR so it creates "config", "health", "logs", "show", and
"watch" (i.e., mkdir -p "$TARGET_DIR/config" "$TARGET_DIR/health"
"$TARGET_DIR/logs" "$TARGET_DIR/show" "$TARGET_DIR/watch") to ensure the
fallback layout matches the PR-specified template contract and produces
consistent versioned docs.
- Around line 77-80: Before running the git commit/push steps, detect whether
there are any staged changes under the docs path and skip the commit/push if
none exist: add a pre-check (e.g., using a staged-diff check like `git diff
--cached` or `git status --porcelain` scoped to docs/) and only run `git commit
-m "..."` and `git push origin HEAD:${{ github.event.repository.default_branch
}}` when that check finds changes; if no changes, log/echo a message and exit
successfully so the workflow does not fail.
- Around line 50-53: The current find ... -exec sh -c block appends the version
footer unconditionally, causing duplicates; update that shell snippet (the sh -c
executed by find that references TARGET_DIR and VERSION and uses echo) to first
detect and remove or skip existing version footers before appending: for each
file, check for an existing footer matching the version block (e.g., a trailing
"\n---\n**Version:** <VERSION>" or any "\n---\n**Version:**" block) using
grep/sed/awk, remove the old footer if present (or skip appending when it
already matches VERSION), and only then append the new footer with echo —
implement this inside the same sh -c block so the operation is idempotent across
runs.
- Line 65: The workflow currently injects the generated changelog into a shell
command via echo -e "${{ steps.github_release.outputs.changelog }}" >>
"$VERSION_README", which risks command injection from changelog content; replace
this with a safe write that treats the changelog as data (not evaluated shell
input) — e.g., call a tool that accepts the changelog as a single argument
(printf with a %s format) or append using a quoted/heredoc literal so the
variable is not interpreted by the shell, or use a GitHub Action that writes
file content directly; update the step replacing the echo invocation with one of
these safe write methods to ensure the changelog is not executed.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 1609d36c-812e-4ca4-b768-abede105bf73
⛔ Files ignored due to path filters (10)
.github/docs-template/README.mdis excluded by none and included by none.github/docs-template/config/README.mdis excluded by none and included by none.github/docs-template/health/README.mdis excluded by none and included by none.github/docs-template/logs/README.mdis excluded by none and included by none.github/docs-template/show/README.mdis excluded by none and included by none.github/docs-template/watch/README.mdis excluded by none and included by noneREADME.mdis excluded by none and included by nonedocs/changelogs/v1.1.3.mdis excluded by none and included by nonedocs/changelogs/v1.2.0.mdis excluded by none and included by nonedocs/changelogs/v1.2.1.mdis excluded by none and included by none
📒 Files selected for processing (1)
.github/workflows/changelog.yml
|
2 bots showing errors is an already existing issue and is unrelated to my PR. In the failure log, .github/scripts/bot-on-pr-open.cjs failed with a MODULE_NOT_FOUND error because it failed to import ./helpers. This looks like an existing issue with the PR-opening bot script on the upstream repository, and is totally unrelated to the documentation scaffolding changes introduced in this patch. The core Auto Changelog & Versioned Docs workflow itself is verified and ready for review! |
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 @.github/workflows/changelog.yml:
- Around line 49-62: The script has two shell syntax errors: fix the
array-length check by replacing the invalid `${\`#template_items\`[@]}` with the
correct parameter expansion `${`#template_items`[@]}` when testing template_items,
and remove the duplicated trailing "' _ {} +" so the find -exec block ends with
a single properly quoted exec invocation (i.e., keep only one ' _ {} + after the
sh -c block); ensure the inner sh -c quoting around "$VERSION" remains intact
and the for-loop block is closed exactly once.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 6d00d9f7-7f13-49e9-8b92-0e0595565f94
📒 Files selected for processing (1)
.github/workflows/changelog.yml
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
.github/workflows/changelog.yml (2)
70-73:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winWrite changelog content safely (no shell interpolation).
Line [73] injects
${{ steps.github_release.outputs.changelog }}directly into the shell script. Treat changelog text as data via an env var +printf. Also, Line [72] currently references$CHANGELOGwithout defining it in this step.Suggested patch
- name: Scaffold Versioned CLI Documentation System + env: + CHANGELOG: ${{ steps.github_release.outputs.changelog }} run: | @@ echo -e "# KDM CLI Documentation - ${VERSION}\n" > "$VERSION_README" echo -e "Published on: $(date +'%Y-%m-%d')\n" >> "$VERSION_README" printf '%s\n' "$CHANGELOG" >> "$VERSION_README" - echo -e "${{ steps.github_release.outputs.changelog }}" >> "$VERSION_README" printf '\n---\n**Version Information:** %s\n' "$VERSION" >> "$VERSION_README"🤖 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/changelog.yml around lines 70 - 73, The step writes changelog content unsafely by interpolating ${{ steps.github_release.outputs.changelog }} directly into the shell and using an undefined $CHANGELOG; fix it by exporting the release changelog into an environment variable (e.g. CHANGELOG) from the workflow step that runs the script or by setting CHANGELOG="$(echo "${{ steps.github_release.outputs.changelog }}")" before writing the file, then use printf '%s\n' "$CHANGELOG" >> "$VERSION_README" (and echo other static lines) so all changelog content is treated as data and not subject to shell interpolation; update usages of VERSION_README and CHANGELOG in the step accordingly.
51-62:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winFix broken Bash syntax in the template-copy block.
Line [51] uses invalid array-length expansion, and Line [62] has a stray duplicated
find -execterminator. This will break the run step before scaffolding completes.Suggested patch
shopt -s dotglob nullglob template_items=("$TEMPLATE_DIR"/*) - if [ ${`#template_items`[@]} -gt 0 ]; then + if [ ${`#template_items`[@]} -gt 0 ]; then cp -r "${template_items[@]}" "$TARGET_DIR"/ fi # 3. Recursively inject the mandatory Version string into every markdown file copied find "$TARGET_DIR" -type f -name "*.md" -exec sh -c ' for file; do if ! grep -Fq "**Version:** '"$VERSION"'" "$file"; then printf "\n---\n**Version:** %s\n" "'"$VERSION"'" >> "$file" fi done ' _ {} + - ' _ {} +🤖 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/changelog.yml around lines 51 - 62, The template-copy block has broken Bash syntax: replace the invalid array-length expression `${\`#template_items\`[@]}` with the correct `${`#template_items`[@]}` when checking template_items, and remove the stray duplicated terminator "' _ {} +" at the end of the find -exec invocation so the single find "$TARGET_DIR" -type f -name "*.md" -exec sh -c '... ' _ {} + form is preserved; ensure variables referenced inside the sh -c script (VERSION, file) remain properly quoted as in the existing block.
🤖 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 @.github/workflows/changelog.yml:
- Line 24: Replace the mutable tag used in the workflow step that currently
reads uses: mikepenz/release-changelog-builder-action@v4 with the action pinned
to its full commit SHA; locate the workflow step referencing
mikepenz/release-changelog-builder-action and update the tag to the specific
commit SHA (e.g., @<full-commit-sha>) so the action is immutable and cannot be
changed by upstream tag updates.
- Around line 3-8: Add a top-level GitHub Actions concurrency stanza to
serialize runs for the same version: add a concurrency block (at workflow root)
with group set to an expression that resolves to the tag/version for both
events, e.g. group: "changelog-${{ github.event.release.tag_name || github.ref
}}" and set cancel-in-progress: false so runs queue instead of cancelling; this
ensures the release (release.published) and push (tags v*.*.*) triggers for the
same version cannot run concurrently and will be serialized.
---
Duplicate comments:
In @.github/workflows/changelog.yml:
- Around line 70-73: The step writes changelog content unsafely by interpolating
${{ steps.github_release.outputs.changelog }} directly into the shell and using
an undefined $CHANGELOG; fix it by exporting the release changelog into an
environment variable (e.g. CHANGELOG) from the workflow step that runs the
script or by setting CHANGELOG="$(echo "${{
steps.github_release.outputs.changelog }}")" before writing the file, then use
printf '%s\n' "$CHANGELOG" >> "$VERSION_README" (and echo other static lines) so
all changelog content is treated as data and not subject to shell interpolation;
update usages of VERSION_README and CHANGELOG in the step accordingly.
- Around line 51-62: The template-copy block has broken Bash syntax: replace the
invalid array-length expression `${\`#template_items\`[@]}` with the correct
`${`#template_items`[@]}` when checking template_items, and remove the stray
duplicated terminator "' _ {} +" at the end of the find -exec invocation so the
single find "$TARGET_DIR" -type f -name "*.md" -exec sh -c '... ' _ {} + form is
preserved; ensure variables referenced inside the sh -c script (VERSION, file)
remain properly quoted as in the existing block.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 028e8d0d-eca1-4abc-89df-94e7c1350d2d
📒 Files selected for processing (1)
.github/workflows/changelog.yml
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (1)
.github/workflows/changelog.yml (1)
57-57:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winBash syntax error: backticks inside parameter expansion are invalid.
This issue was previously flagged and remains unresolved. The expression
${#template_items[@]}uses backticks around#template_items, which is invalid bash syntax. Backticks trigger command substitution and cannot be nested within${}parameter expansion.🐛 Proposed fix
- if [ ${`#template_items`[@]} -gt 0 ]; then + if [ ${`#template_items`[@]} -gt 0 ]; then🤖 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/changelog.yml at line 57, The bash condition is using invalid backticks inside parameter expansion `${\`#template_items\`[@]}`; replace it with the correct parameter expansion and quoting: use `if [ "${`#template_items`[@]}" -gt 0 ]; then` (i.e., remove backticks, put `#template_items` directly inside `${}` and quote the expansion) so the test correctly checks the array length of `template_items`.
🤖 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 @.github/workflows/changelog.yml:
- Around line 77-78: The step writes an undefined $CHANGELOG and reintroduces a
shell-injection vector by using echo with the raw GitHub Actions output
(steps.github_release.outputs.changelog); fix by adding CHANGELOG to the step's
env and removing the vulnerable echo line, and update the safe append to use the
defined env variable (CHANGELOG) with a non-evaluating writer (e.g., printf) to
append to VERSION_README so the changelog content is not passed through the
shell for execution.
- Line 10: Remove the spurious leading space before the YAML top-level key
"jobs:" so it is a top-level mapping (i.e., ensure "jobs:" has no preceding
indentation), which will restore valid workflow structure and allow the parser
to recognize the jobs mapping correctly.
- Around line 28-30: Replace the placeholder action ref in the GitHub Action
step that uses mikepenz/release-changelog-builder-action (the line starting with
"uses: mikepenz/release-changelog-builder-action@<full_commit_sha>") with the
actual v4 commit SHA by changing the reference to
"`@32e3c96f29a6532607f638797455e9e98cfc703d`"; ensure the "uses:" value exactly
matches
mikepenz/release-changelog-builder-action@32e3c96f29a6532607f638797455e9e98cfc703d
so the workflow runs against the known v4 commit.
---
Duplicate comments:
In @.github/workflows/changelog.yml:
- Line 57: The bash condition is using invalid backticks inside parameter
expansion `${\`#template_items\`[@]}`; replace it with the correct parameter
expansion and quoting: use `if [ "${`#template_items`[@]}" -gt 0 ]; then` (i.e.,
remove backticks, put `#template_items` directly inside `${}` and quote the
expansion) so the test correctly checks the array length of `template_items`.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: c1233e3d-8e95-494e-aea7-f15fceac3563
📒 Files selected for processing (1)
.github/workflows/changelog.yml
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Updated changelog action to use specific commit SHA.
|
Resolved all errors and suggestions by CodeRabbit ready to merge |
|
@Yuvraj-Sarathe After this PR is merged, we would love to add you as a CODEOWNER for this workflow. This will allow you to handle its future maintenance and review any upcoming changes.Let us know if you're ready for this! |
I will be more than willing to play the role of that alongside trying to solve more issues. However, we must first decide what we actually aim to do with this workflow. I am referring to this: #43 (comment) |
|
Let's get on the same page about the architecture before we start writing any code. We need to make a decision on how to deal with the current PR. Depending on how we want to structure the automated docs, we will either merge this as a baseline, edit, or close it all together and start fresh. Here is the proposed design to keep a flat file structure within the Proposed StructureWe automate generation of versioned markdown files (like We have two options to implement the main Option 1: My SuggestionThe
# Documentation (Latest: v1.2.1)
[Embedded content of v1.2.1.md]
---
## Version History
* [v1.2.1](v1.2.1.md)
* [v1.0.0](v1.0.0.md)
Option 2: Index Based ApproachThe
# Project Documentation
Select a version to view its documentation:
* [](v1.2.1.md) (Latest)
* [](v1.0.0.md)
Note: Individual version files (like How to Proceed with this PR
Let me know which option you prefer so I can configure the automation tracking accordingly. |
Yes option 1 looks good rn i will merge it as is we can follow this architecture flow in new pr |
|
@Yuvraj-Sarathe reopen the pr as i will merge it make you codeowner of it then our decided new approach will be implemented on a new pr |
Issue fixed
Issue #30
📝 Description
This PR introduces a fully automated, CI/CD-driven documentation management framework. It shifts the burden of manually creating changelogs and version-specific directory trees away from core developers and delegates it completely to a high-performance GitHub Actions pipeline.
Instead of maintaining a massive, monolithic root-level
CHANGELOG.mdfile (which is prone to nasty merge conflicts during parallel feature development), this automation dynamically scaffolds isolated versioned workspaces (e.g.,docs/v2.1.2/) directly on release events.🛠️ What This PR Actually Does
1. The Scaffolding Pipeline (
.github/workflows/changelog.yml)We built a durable shell automation script that intercepts official repository releases and tag pushes (
v*.*.*). The runner completely bypasses standard pipeline failures likedetached HEADstates ornon-fast-forwardpush blocks by explicitly aligning its workspace tracking pointers to the default branch before compiling code.2. Master Blueprint System (
.github/docs-template/)We initialized a centralized blueprint layout that perfectly mirrors the recently adopted structure seen in the
v1.2.1tracking directory. It includes the mandatory subdirectories:config/health/logs/show/watch/3. Automated Lifecycle & Metadata Injection
Every time a new version tag is launched, the bot executes the following internal runtime sequence:
docs/v2.1.3/)..github/docs-template/into the new version directory.Version: vX.X.Xpayload right to the bottom of the document footer automatically.mikepenz/release-changelog-builder-actionengine, categorizes them according to Conventional Commits rules, and outputs them as the rootREADME.mdfor that specific version folder.📂 Target Project Directory Layout After A Release Run
Once this automation executes for a hypothetical
v2.1.3release, thedocs/folder structure scales perfectly without human configuration:⚙️ How to Maintain & Update Command Docs (For Developers)
As the CLI tool evolves, updating the baseline documentation for new features is straightforward:
.github/docs-template/..github/docs-template/.GitHub isolates permissions for third-party security actions. To ensure this automation functions without throwing execution code errors, the repository maintainer must complete these two administrative configurations manually:
1. Enable Read/Write Permissions for the Workflow Token
By default, GitHub blocks background actions from committing code back to your branch. You must give the system write access:
2. Backfill Existing Content Inside the Master Template
The master template (
.github/docs-template/) currently contains the clean folder structures matchingv1.2.1alongside empty placeholder files.docs/v1.2.1/folder right into the corresponding paths inside.github/docs-template/.Summary by CodeRabbit