Skip to content

feat: add CI workflow to auto-update CLI docs (#31)#167

Open
boxcee-interview wants to merge 2 commits into
crossplane:mainfrom
boxcee-interview:fix/issue-31-auto-update-cli-docs
Open

feat: add CI workflow to auto-update CLI docs (#31)#167
boxcee-interview wants to merge 2 commits into
crossplane:mainfrom
boxcee-interview:fix/issue-31-auto-update-cli-docs

Conversation

@boxcee-interview

Copy link
Copy Markdown

Closes #31

Adds a GitHub Actions workflow that automatically updates CLI command reference documentation in the crossplane/docs repository.

Changes

  • New .github/workflows/update-docs.yml workflow triggered on push to main and on release tags
  • Builds the CLI via Nix, runs crossplane generate-docs, then creates a PR to crossplane/docs via peter-evans/create-pull-request

How to Test

Requires a DOCS_WRITE_TOKEN secret with write access to crossplane/docs repo. The workflow will create a PR to that repo when triggered on push to main or a new tag.

Signed-off-by: Moritz Schmitz von Hülst <mschmitzvonhuelst@gmail.com>
@boxcee-interview boxcee-interview requested review from a team, jcogilvie and tampakrap as code owners June 28, 2026 23:29
@boxcee-interview boxcee-interview requested review from bobh66 and removed request for a team June 28, 2026 23:29
@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This workflow now runs on version tag pushes, builds the CLI with Nix, generates the command reference, writes it into the docs repo under a versioned path, and opens or updates a pull request only when the generated docs differ.

Changes

Version-tagged CLI Docs Automation

Layer / File(s) Summary
Triggers and permissions
.github/workflows/update-docs.yml
Sets the workflow to run on v* tag pushes, adds concurrency cancellation, and configures workflow/job GitHub token permissions.
Build CLI and generate docs
.github/workflows/update-docs.yml
Checks out the repo, installs Nix, configures Cachix, builds the crossplane binary, and generates generated-docs/command-reference.md.
Checkout docs repo and derive target path
.github/workflows/update-docs.yml
Checks out crossplane/docs into docs/ and computes content/cli/<minor-version> from the pushed tag.
Sync docs and open PR
.github/workflows/update-docs.yml
Copies the generated markdown into the docs repo, detects changes with git status, sets docs-changed=true, and conditionally opens or updates a PR on auto/update-cli-docs.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • crossplane/cli#106: Adds the same Nix-based CLI doc generation and auto-PR flow targeting content/cli/master in the docs repo.
  • crossplane/cli#120: Shares the same PR branch name (auto/update-cli-docs) used for docs-update automation.
  • crossplane/cli#121: Adjusts commit metadata for docs PR commits in the same GitHub Actions automation area.

Suggested reviewers

  • jcogilvie
  • tampakrap
  • phisco
  • jbw976
🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The workflow no longer triggers on main, so it misses the issue's required content/master updates. Add a main-branch trigger or equivalent CI path that updates content/master/ when help changes merge.
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is descriptive, under 72 characters, and matches the new CLI docs update workflow.
Description check ✅ Passed The description is related to the workflow that auto-updates CLI docs via CI.
Out of Scope Changes check ✅ Passed The changes stay focused on the docs-update workflow, PR creation, and supporting run logic.
Breaking Changes ✅ Passed Only .github/workflows/update-docs.yml changed; no apis/** or cmd/** files were modified, so no public fields/flags or behavior changes.
Feature Gate Requirement ✅ Passed Only a GitHub Actions workflow was added; no apis/** or runtime feature code changed, so no feature-flag gate is needed.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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/update-docs.yml:
- Around line 14-18: The update-docs workflow can have overlapping runs writing
to the shared auto/update-cli-docs branch, which can cause out-of-order docs
updates. Add workflow-level serialization in update-docs and/or make the PR
branch name unique per target directory before the branch is reused, so only one
run of the update-docs job can write at a time and the generated docs PR stays
current.
- Around line 60-67: The docs change detection in the Update Docs step misses
newly created untracked files, so first-time release docs can be skipped. Update
the gate in the Update Docs workflow to use a status check that includes
untracked files, or stage the generated docs before checking, so the
`docs-changed` flag is set when `command-reference.md` is newly added. Use the
`Update Docs` step and its `git diff --quiet` check as the location to adjust.
🪄 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: CHILL

Plan: Pro

Run ID: 9ba7c8c3-3946-4d7d-85f8-97b202caf5d1

📥 Commits

Reviewing files that changed from the base of the PR and between 86f5f7a and 1b8069c.

📒 Files selected for processing (1)
  • .github/workflows/update-docs.yml

Comment thread .github/workflows/update-docs.yml
Comment thread .github/workflows/update-docs.yml

@adamwg adamwg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for taking a look at this!

We already have automated docs updates working on the main branch as part of the Validate Docs job in the ci workflow. No objection to centralizing the updates if we can have a single workflow handle both releases and main updates, but we shouldn't do it twice.

For releases, I think we shouldn't update docs until the release has been promoted to the stable channel. It might make sense to attach the docs update to the promote workflow.

Comment thread .github/workflows/update-docs.yml Outdated
Comment on lines +53 to +55
VERSION="${GITHUB_REF#refs/tags/}"
DIR_NAME="${VERSION#v}"
echo "dir=content/cli/${DIR_NAME}" >> "$GITHUB_OUTPUT"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Note that the docs are versioned per minor version, not for each patch. The tag will be (e.g.) v2.4.1, so this logic needs to strip the patch portion to make the directory name v2.4.

@boxcee-interview

Copy link
Copy Markdown
Author

Addressed review feedback:

  • Removed main branch trigger — the job already handles docs updates on main pushes, so this workflow now triggers only on release tags.
  • Added concurrency group — prevents overlapping runs from writing to the same branch simultaneously.
  • Fixed version directory naming — strip patch version so → (per your inline comment about minor-version directory structure).
  • Fixed untracked file detection — switched from to so newly created release docs aren't silently skipped.

Regarding the promote workflow question: happy to discuss whether attaching the docs update to the promote workflow makes more sense. For now, keeping the tag-triggered workflow as a first pass.

@boxcee-interview

Copy link
Copy Markdown
Author

Addressed review feedback:

  • Removed main branch trigger — the ci.yml validate-docs job already handles docs updates on main pushes, so this workflow now triggers only on release tags.
  • Added concurrency group — prevents overlapping runs from writing to the same branch simultaneously.
  • Fixed version directory naming — strip patch version so v2.4.1 → content/cli/2.4 (per your inline comment about minor-version directory structure).
  • Fixed untracked file detection — switched from git diff --quiet to git status --porcelain so newly created release docs are not silently skipped.

Regarding the promote workflow question: happy to discuss whether attaching the docs update to the promote workflow makes more sense. For now, keeping the tag-triggered workflow as a first pass.

- Remove main branch trigger (docs already updated via ci workflow)
- Add concurrency group to prevent overlapping runs
- Strip patch version from directory name (v2.4.1 -> v2.4)
- Use git status --porcelain to detect untracked new files

Signed-off-by: Moritz Schmitz von Hülst <mschmitzvonhuelst@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/update-docs.yml (1)

57-64: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

git status --porcelain switch correctly catches new files now — thanks for the fix!

This resolves the earlier issue where git diff --quiet missed newly created command-reference.md files for first-time releases.

One smaller note while we're in here: static analysis flags lines 59-60 for template injection, since ${{ steps.target.outputs.dir }} is interpolated directly into the run: block rather than passed through an env: var. Since dir is derived from the pushed tag name (which requires write access to create), the practical risk is low, but it's still cheap insurance to route it through an env var so a stray shell metacharacter in a tag name can't be expanded as code. Want to apply this pattern?

Suggested fix
       - name: Update Docs
+        env:
+          TARGET_DIR: ${{ steps.target.outputs.dir }}
         run: |
-          mkdir -p docs/${{ steps.target.outputs.dir }}
-          cp generated-docs/command-reference.md docs/${{ steps.target.outputs.dir }}/command-reference.md
+          mkdir -p "docs/${TARGET_DIR}"
+          cp generated-docs/command-reference.md "docs/${TARGET_DIR}/command-reference.md"
           cd docs
           if [[ -n "$(git status --porcelain --untracked-files=all)" ]]; then
             echo "docs-changed=true" >> "$GITHUB_ENV"
           fi
🤖 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/update-docs.yml around lines 57 - 64, The Update Docs step
in the workflow interpolates steps.target.outputs.dir directly inside the run
script, which triggers template-injection concerns. Move that value into an env
variable for the Update Docs job and reference the env var in the mkdir/cp
commands so the shell never expands the raw expression inline. Keep the existing
logic in the Update Docs step and only change how dir is passed into the script.

Source: Linters/SAST tools

🤖 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/update-docs.yml:
- Around line 13-15: The workflow concurrency setting in update-docs should not
cancel in-flight runs for different release tags. Update the concurrency block
in the docs generation workflow so the static update-cli-docs group still
serializes runs, but cancel-in-progress is set to false to queue later tags
instead of dropping earlier versioned docs jobs.

---

Nitpick comments:
In @.github/workflows/update-docs.yml:
- Around line 57-64: The Update Docs step in the workflow interpolates
steps.target.outputs.dir directly inside the run script, which triggers
template-injection concerns. Move that value into an env variable for the Update
Docs job and reference the env var in the mkdir/cp commands so the shell never
expands the raw expression inline. Keep the existing logic in the Update Docs
step and only change how dir is passed into the script.
🪄 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: CHILL

Plan: Pro

Run ID: e8014e48-f664-4599-811f-f396bb003e9a

📥 Commits

Reviewing files that changed from the base of the PR and between 1b8069c and 8a487fe.

📒 Files selected for processing (1)
  • .github/workflows/update-docs.yml

Comment on lines +13 to +15
concurrency:
group: update-cli-docs
cancel-in-progress: true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Nice fix on the concurrency group — one follow-up on cancel-in-progress.

Glad to see the concurrency group land here, it directly addresses the overlapping-writes concern from the earlier review. One thing worth double-checking: with a static group: update-cli-docs and cancel-in-progress: true, if a second tag (e.g. v2.5.0) is pushed while the v2.4.0 run is still mid-flight, the in-progress v2.4.0 run gets cancelled rather than queued. That means the content/cli/2.4 docs PR would silently never get generated for that release. Would cancel-in-progress: false (queue instead of cancel) be safer here, since each run targets a different version directory and none of them are truly redundant?

Suggested tweak
   update-docs:
     concurrency:
       group: update-cli-docs
-      cancel-in-progress: true
+      cancel-in-progress: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
concurrency:
group: update-cli-docs
cancel-in-progress: true
concurrency:
group: update-cli-docs
cancel-in-progress: false
🤖 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/update-docs.yml around lines 13 - 15, The workflow
concurrency setting in update-docs should not cancel in-flight runs for
different release tags. Update the concurrency block in the docs generation
workflow so the static update-cli-docs group still serializes runs, but
cancel-in-progress is set to false to queue later tags instead of dropping
earlier versioned docs jobs.

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.

Automatically update the command reference docs from CI

2 participants