Skip to content

Conversation

JakeSCahill
Copy link
Contributor

@JakeSCahill JakeSCahill commented Oct 2, 2025

This PR introduces a new CLI command bundle-openapi that automates the generation of complete OpenAPI 3.1 specification files from Redpanda protocol buffer definitions. This tool addresses the need for up-to-date OpenAPI documentation that can be automatically generated and maintained as part of our CI/CD pipeline.

The new CLI tool automates the entire process of:

  • Cloning the Redpanda repository at any specific git tag/version
  • Running buf generate to create OpenAPI fragments from protobuf definitions
  • Bundling multiple OpenAPI fragments into complete, valid OpenAPI 3.1 documents
  • Post-processing to add proper metadata, versioning, and structure

🛠️ Key Features

  • CLI command interface
    # Generate admin API documentation for a specific version
    doc-tools generate bundle-openapi --surface admin --tag v25.1.1
    # Use admin major version for info.version field
    doc-tools generate bundle-openapi --surface admin --tag v25.1.1 --use-admin-major-version

Example

An example of the bundled spec is here: https://github.com/redpanda-data/docs-extensions-and-macros/pull/134/files/38b6a24d493557bee2d7af0ecca4200922645704#diff-8e633cd03c898beb85637f6ce113c5f325bd2e700f36c8109ad2929e6215c231

Testing

  1. Install dependencies:

    npm install
  2. Link the package for local testing:

    npm link
  3. Install CLI dependencies:

    brew install buf
  4. Test OpenAPI bundling functionality:

    # Test admin API bundling
    doc-tools generate bundle-openapi --surface admin --tag dev --use-admin-major-version

    You should get a bundled spec file inside the admin/ directory.

2025-10-03_15-47-53.mp4

erates OpenAPI spec files from proto files
Copy link

netlify bot commented Oct 2, 2025

Deploy Preview for docs-extensions-and-macros ready!

Name Link
🔨 Latest commit 375a2f2
🔍 Latest deploy log https://app.netlify.com/projects/docs-extensions-and-macros/deploys/68dfa86a04cee50008c4a260
😎 Deploy Preview https://deploy-preview-134--docs-extensions-and-macros.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Contributor

coderabbitai bot commented Oct 2, 2025

📝 Walkthrough

Walkthrough

  • Adds a new OpenAPI bundling tool (tools/bundle-openapi.js) with tag normalization, bundler detection, fragment discovery, entrypoint creation, bundling, and post-processing; exposes a CLI and exports for testing.
  • Extends doc-tools CLI (bin/doc-tools.js) with a new automation subcommand bundle-openapi; imports Option; duplicate command block present.
  • Introduces comprehensive Jest tests for the bundling tool with mocks and temp filesystem scaffolding.
  • Adds a new OpenAPI 3.1 spec file for Redpanda Admin API v2 (admin/redpanda-admin-api.yaml) with schemas and POST endpoints.
  • Updates package.json: version bump, new scripts, and dependencies (@redocly/cli, yargs).
  • Overhauls cli-utils/install-test-dependencies.sh to install/verify required tooling, including OpenAPI bundlers and rpk.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Developer
  participant DT as doc-tools (CLI)
  participant BO as bundle-openapi.js
  participant Git as Git Repo
  participant Buf as buf
  participant FS as FS (temp/out)
  participant B as Bundler (redocly|swagger-cli)

  Dev->>DT: doc-tools generate bundle-openapi --tag --surface [...]
  DT->>BO: bundleOpenAPI(options)
  BO->>Git: clone repo@tag to tempDir
  BO->>Buf: buf generate (protos -> OpenAPI fragments)
  BO->>FS: discover fragments by surface (admin/connect)
  BO->>FS: create entrypoint (merge fragments if needed)
  BO->>BO: detectBundler()
  BO->>B: runBundler(entrypoint -> bundled.yaml)
  B-->>BO: bundled file
  BO->>FS: postProcessBundle (normalize metadata, sort keys)
  BO-->>DT: paths to outputs
  DT-->>Dev: Completed
  note over BO,B: Handles timeouts, missing bundler, and cleanup
Loading
sequenceDiagram
  autonumber
  actor Dev as Developer
  participant Tests as Jest
  participant BO as bundle-openapi.js (exports)

  Tests->>BO: normalizeTag/getMajorMinor/sortObjectKeys
  Tests->>BO: detectBundler (mocked child_process)
  Tests->>BO: createEntrypoint/postProcessBundle (temp FS)
  Tests-->>Dev: Assertions on outputs and errors
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Suggested reviewers

  • paulohtb6
  • Feediver1
  • mihaitodor

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The pull request introduces functionality and extensive test infrastructure beyond the linked issue’s scope, such as support for the connect API surface, duplicate command blocks in doc-tools, and broad refactoring of the dependency installation script that are unrelated to automating Admin API v2 spec generation. These additions go beyond the requirements of DOC-1705, potentially increasing review and maintenance overhead. They would be more appropriate in separate, focused pull requests. Please isolate or remove unrelated features such as the connect surface support, duplicate doc-tools command definitions, and extensive installer script changes, or split them into distinct pull requests so this one remains focused solely on automating Admin API v2 spec generation.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly summarizes the core change of adding a CLI command that generates OpenAPI spec files from protobuf sources and aligns with the pull request objectives. It is specific, concise, and directly reflects the main functionality introduced. A reviewer can understand the primary change without needing to inspect the individual file modifications.
Linked Issues Check ✅ Passed The pull request fulfills the objectives of DOC-1705 by automating the generation of the Admin API v2 OpenAPI specification from protobuf definitions, including cloning the repository, running buf generate, bundling fragments, and post-processing the output. It provides a CLI interface with requisite options for tag specification and admin major version usage. All core coding requirements from the linked issue are met through the new tool and supporting utilities.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed The pull request description clearly outlines the addition of a new CLI command bundle-openapi, describes its purpose, usage examples, and testing steps, and directly relates to the changes in the diff which introduce the bundling tool and associated code. It is specific to the content of the PR and explains how the new functionality integrates into the existing tooling. Therefore, the description is on-topic and sufficiently informative for a pre-merge check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch DOC-1705

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 and usage tips.

coderabbitai bot added a commit that referenced this pull request Oct 2, 2025
Docstrings generation was requested by @JakeSCahill.

* #134 (comment)

The following files were modified:

* `cli-utils/install-test-dependencies.sh`
* `tools/bundle-openapi.js`
Copy link
Contributor

coderabbitai bot commented Oct 2, 2025

Note

Generated docstrings for this pull request at #135

Docstrings generation was requested by @JakeSCahill.

* #134 (comment)

The following files were modified:

* `cli-utils/install-test-dependencies.sh`
* `tools/bundle-openapi.js`

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@JakeSCahill JakeSCahill requested a review from kbatuigas October 2, 2025 09:44
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b6a549a and 38b6a24.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • __tests__/tools/bundle-openapi.test.js (1 hunks)
  • admin/redpanda-admin-api.yaml (1 hunks)
  • bin/doc-tools.js (2 hunks)
  • cli-utils/install-test-dependencies.sh (1 hunks)
  • package.json (3 hunks)
  • tools/bundle-openapi.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
__tests__/tools/bundle-openapi.test.js (1)
tools/bundle-openapi.js (9)
  • fs (3-3)
  • require (5-5)
  • require (762-762)
  • path (4-4)
  • bundler (691-691)
  • commonDir (204-204)
  • options (475-475)
  • options (581-581)
  • normalized (37-37)
tools/bundle-openapi.js (2)
bin/doc-tools.js (11)
  • require (3-3)
  • require (5-5)
  • require (10-10)
  • require (12-12)
  • require (13-13)
  • require (15-15)
  • require (16-19)
  • require (853-853)
  • require (1349-1349)
  • require (1561-1561)
  • require (1568-1568)
__tests__/tools/bundle-openapi.test.js (2)
  • require (4-4)
  • require (10-19)
bin/doc-tools.js (2)
tools/bundle-openapi.js (4)
  • require (5-5)
  • require (762-762)
  • options (475-475)
  • options (581-581)
__tests__/tools/bundle-openapi.test.js (2)
  • require (4-4)
  • require (10-19)
cli-utils/install-test-dependencies.sh (3)
tools/docusaurus-to-antora-conversion-scripts/pre-process-markdown.js (2)
  • command (35-35)
  • pandoc (3-3)
bin/doc-tools.js (1)
  • make (1080-1122)
extensions/archive-attachments.js (1)
  • tar (5-5)
🪛 Checkov (3.2.334)
admin/redpanda-admin-api.yaml

[high] 1-1582: Ensure that the global security field has rules defined

(CKV_OPENAPI_4)


[high] 1-1582: Ensure that security operations is not empty.

(CKV_OPENAPI_5)


[medium] 41-46: Ensure that arrays have a maximum number of items

(CKV_OPENAPI_21)

🪛 Shellcheck (0.11.0)
cli-utils/install-test-dependencies.sh

[warning] 27-27: Declare and assign separately to avoid masking return values.

(SC2155)

Comment on lines 1 to 20
components:
schemas:
connect-protocol-version:
const: 1
description: Define the version of the Connect protocol
enum:
- 1
title: Connect-Protocol-Version
type: number
connect-timeout-header:
description: Define the timeout, in ms
title: Connect-Timeout-Ms
type: number
connect.error:
additionalProperties: true
description: "Error type returned by Connect: https://connectrpc.com/docs/go/errors/#http-representation"
properties:
code:
description: The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].
enum:
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 2, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add security schemes and requirements.

The bundle omits components.securitySchemes and a corresponding security requirement, so every operation is documented as publicly accessible. The Admin API isn’t open—in practice it requires authenticated access (TLS client certs, HTTP basic/SASL credentials, etc.). Client code generated from this spec will therefore skip auth entirely. Please declare the appropriate security scheme(s) in components.securitySchemes and apply them globally (or per operation) so the contract matches the real service.

🧰 Tools
🪛 Checkov (3.2.334)

[high] 1-1582: Ensure that the global security field has rules defined

(CKV_OPENAPI_4)


[high] 1-1582: Ensure that security operations is not empty.

(CKV_OPENAPI_5)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link

Choose a reason for hiding this comment

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

There is no option for this (I also don't know anything about openapi format). Do we have this for other generated proto files?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess we might need to add overlays with the security schema? https://learn.openapis.org/specification/security.html

Choose a reason for hiding this comment

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

Cloud has it, but this was custom: https://github.com/redpanda-data/cloudv2/blob/dev/tools/openapi-converter/main.go#L302

The overlay option also works for me

@JakeSCahill JakeSCahill requested a review from rockwotj October 2, 2025 09:53
@kbatuigas
Copy link

kbatuigas commented Oct 2, 2025

From following the instructions

  • Is it ok if I already have buf installed, but not through Homebrew?
    This is what I get when I try to run brew install buf
      $ brew install buf
    ==> Auto-updating Homebrew...
    Adjust how often this is run with `$HOMEBREW_AUTO_UPDATE_SECS` or disable with
    `$HOMEBREW_NO_AUTO_UPDATE=1`. Hide these hints with `$HOMEBREW_NO_ENV_HINTS=1` (see `man brew`).
    ==> Auto-updated Homebrew!
    Updated 3 taps (redpanda-data/tap, homebrew/core and homebrew/cask).
    ==> New Formulae
    cagent: Agent Builder and Runtime by Docker Engineering
    mcp-grafana: MCP server for Grafana
    mlx-lm: Run LLMs with MLX
    playwright-mcp: MCP server for Playwright
    portable-libffi: Portable Foreign Function Interface library
    portable-libxcrypt: Extended crypt library for descrypt, md5crypt, bcrypt, and others
    portable-libyaml: YAML Parser
    portable-openssl: Cryptography and SSL/TLS Toolkit
    portable-ruby: Powerful, clean, object-oriented scripting language
    portable-zlib: General-purpose lossless data-compression library
    salesforce-mcp: MCP Server for interacting with Salesforce instances
    
    You have 7 outdated formulae installed.
    
    Error: buf was installed from the bufbuild/buf tap
    but you are trying to install it from the homebrew/core tap.
    Formulae with the same name from different taps cannot be installed at the same time.
    
    To install this version, you must first uninstall the existing formula:
      brew uninstall buf
    Then you can install the desired version:
      brew install buf
    
  • I get an error in step 4, does it have to do with my buf installation?
    $ doc-tools install-test-dependencies
    /bin/sh: /Users/kat/Documents/rp/rp-docs/docs-extensions-and-macros/cli-utils/install-test-dependencies.sh: Permission denied
    

fwiw I checked out this branch and ran the commands but maybe I shouldn't have done that for testing

@rockwotj
Copy link

rockwotj commented Oct 2, 2025

From following the instructions

* Is it ok if I already have buf installed, but not through Homebrew?
  This is what I get when I try to run brew install buf
  ```
    $ brew install buf
  ==> Auto-updating Homebrew...
  Adjust how often this is run with `$HOMEBREW_AUTO_UPDATE_SECS` or disable with
  `$HOMEBREW_NO_AUTO_UPDATE=1`. Hide these hints with `$HOMEBREW_NO_ENV_HINTS=1` (see `man brew`).
  ==> Auto-updated Homebrew!
  Updated 3 taps (redpanda-data/tap, homebrew/core and homebrew/cask).
  ==> New Formulae
  cagent: Agent Builder and Runtime by Docker Engineering
  mcp-grafana: MCP server for Grafana
  mlx-lm: Run LLMs with MLX
  playwright-mcp: MCP server for Playwright
  portable-libffi: Portable Foreign Function Interface library
  portable-libxcrypt: Extended crypt library for descrypt, md5crypt, bcrypt, and others
  portable-libyaml: YAML Parser
  portable-openssl: Cryptography and SSL/TLS Toolkit
  portable-ruby: Powerful, clean, object-oriented scripting language
  portable-zlib: General-purpose lossless data-compression library
  salesforce-mcp: MCP Server for interacting with Salesforce instances
  
  You have 7 outdated formulae installed.
  
  Error: buf was installed from the bufbuild/buf tap
  but you are trying to install it from the homebrew/core tap.
  Formulae with the same name from different taps cannot be installed at the same time.
  
  To install this version, you must first uninstall the existing formula:
    brew uninstall buf
  Then you can install the desired version:
    brew install buf
  ```

* I get an error in step 4, does it have to do with my buf installation?
  ```
  $ doc-tools install-test-dependencies
  /bin/sh: /Users/kat/Documents/rp/rp-docs/docs-extensions-and-macros/cli-utils/install-test-dependencies.sh: Permission denied
  ```

fwiw I checked out this branch and ran the commands but maybe I shouldn't have done that for testing

Might be better to install via npm, then there should be no additional setup as I think it will be on the path for npm scripts: https://buf.build/docs/cli/installation/#npm

Copy link

@rockwotj rockwotj left a comment

Choose a reason for hiding this comment

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

LGTM

@JakeSCahill
Copy link
Contributor Author

Might be better to install via npm, then there should be no additional setup as I think it will be on the path for npm scripts: https://buf.build/docs/cli/installation/#npm

Oh nice. I didn't realise there was an npm package. Thanks!

@JakeSCahill
Copy link
Contributor Author

JakeSCahill commented Oct 3, 2025

From following the instructions

  • Is it ok if I already have buf installed, but not through Homebrew?
    This is what I get when I try to run brew install buf
      $ brew install buf
    ==> Auto-updating Homebrew...
    Adjust how often this is run with `$HOMEBREW_AUTO_UPDATE_SECS` or disable with
    `$HOMEBREW_NO_AUTO_UPDATE=1`. Hide these hints with `$HOMEBREW_NO_ENV_HINTS=1` (see `man brew`).
    ==> Auto-updated Homebrew!
    Updated 3 taps (redpanda-data/tap, homebrew/core and homebrew/cask).
    ==> New Formulae
    cagent: Agent Builder and Runtime by Docker Engineering
    mcp-grafana: MCP server for Grafana
    mlx-lm: Run LLMs with MLX
    playwright-mcp: MCP server for Playwright
    portable-libffi: Portable Foreign Function Interface library
    portable-libxcrypt: Extended crypt library for descrypt, md5crypt, bcrypt, and others
    portable-libyaml: YAML Parser
    portable-openssl: Cryptography and SSL/TLS Toolkit
    portable-ruby: Powerful, clean, object-oriented scripting language
    portable-zlib: General-purpose lossless data-compression library
    salesforce-mcp: MCP Server for interacting with Salesforce instances
    
    You have 7 outdated formulae installed.
    
    Error: buf was installed from the bufbuild/buf tap
    but you are trying to install it from the homebrew/core tap.
    Formulae with the same name from different taps cannot be installed at the same time.
    
    To install this version, you must first uninstall the existing formula:
      brew uninstall buf
    Then you can install the desired version:
      brew install buf
    
  • I get an error in step 4, does it have to do with my buf installation?
    $ doc-tools install-test-dependencies
    /bin/sh: /Users/kat/Documents/rp/rp-docs/docs-extensions-and-macros/cli-utils/install-test-dependencies.sh: Permission denied
    

fwiw I checked out this branch and ran the commands but maybe I shouldn't have done that for testing

That's all fine. I'll add as an npm module. The error is about file execution permissions. I'll update. You don't actually need to call that command.

@JakeSCahill JakeSCahill requested a review from micheleRP October 3, 2025 12:29
Copy link

@micheleRP micheleRP left a comment

Choose a reason for hiding this comment

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

lgtm

@JakeSCahill JakeSCahill merged commit f3f1a6d into main Oct 3, 2025
17 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.

4 participants