@redpanda-data/docs-extensions-and-macros 5.31.0 → 5.35.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -446,7 +446,7 @@ const tools = [
446
446
  },
447
447
  surface: {
448
448
  type: 'string',
449
- description: 'Comma-separated surfaces to lint: properties, metrics, rpk, helm, crd, connect (optional, defaults to all)'
449
+ description: `Comma-separated surfaces to lint: ${Object.keys(require('../tools/lint-strings').SURFACES).join(', ')} (optional, defaults to all)`
450
450
  },
451
451
  diff: {
452
452
  type: 'string',
package/bin/doc-tools.js CHANGED
@@ -122,9 +122,9 @@ programCli
122
122
  * - A GitHub token with access to redpanda-data/streaming-enterprise, which is
123
123
  * private. Redpanda releases are published there now, and the old public repo
124
124
  * is frozen, so this command exits rather than report a stale version when it
125
- * has no token. Resolved from GIT_CREDENTIALS, REDPANDA_GITHUB_TOKEN,
126
- * ACTIONS_BOT_TOKEN, GITHUB_TOKEN, VBOT_GITHUB_API_TOKEN, or GH_TOKEN, in
127
- * that priority order
125
+ * has no token. Resolved from REDPANDA_GITHUB_TOKEN, ACTIONS_BOT_TOKEN,
126
+ * GITHUB_TOKEN, VBOT_GITHUB_API_TOKEN, GH_TOKEN, or GIT_CREDENTIALS, in that
127
+ * priority order (an API call, so the git credential is the last resort)
128
128
  */
129
129
  programCli
130
130
  .command('get-redpanda-version')
@@ -1908,7 +1908,7 @@ automation
1908
1908
  *
1909
1909
  * @requirements
1910
1910
  * - GitHub token with access to redpanda-data/cloudv2-infra repository
1911
- * - Token is resolved from GIT_CREDENTIALS, REDPANDA_GITHUB_TOKEN, ACTIONS_BOT_TOKEN, GITHUB_TOKEN, VBOT_GITHUB_API_TOKEN, or GH_TOKEN, in that priority order
1911
+ * - Token is resolved from REDPANDA_GITHUB_TOKEN, ACTIONS_BOT_TOKEN, GITHUB_TOKEN, VBOT_GITHUB_API_TOKEN, GH_TOKEN, or GIT_CREDENTIALS, in that priority order (an API call, so the git credential is the last resort)
1912
1912
  * - Internet connection to access GitHub API
1913
1913
  */
1914
1914
  automation
@@ -1925,7 +1925,7 @@ automation
1925
1925
  .option('--dry-run', 'Print output to stdout instead of writing file')
1926
1926
  .action(async (options, command) => {
1927
1927
  const { generateCloudRegions } = require('../tools/cloud-regions/generate-cloud-regions.js')
1928
- const { getGitHubToken } = require('../cli-utils/github-token')
1928
+ const { getGitHubApiToken } = require('../cli-utils/github-token')
1929
1929
 
1930
1930
  try {
1931
1931
  // The default output path holds the unfiltered table, so a filtered run
@@ -1947,7 +1947,7 @@ automation
1947
1947
  const absOutput = options.dryRun
1948
1948
  ? undefined
1949
1949
  : resolveInsideRepo(repoRoot, options.output, '--output')
1950
- const token = getGitHubToken()
1950
+ const token = getGitHubApiToken()
1951
1951
  if (!token) {
1952
1952
  throw new Error('GitHub token is required to fetch from private cloudv2-infra repo.')
1953
1953
  }
@@ -2622,7 +2622,9 @@ programCli
2622
2622
  .command('lint-strings')
2623
2623
  .description('Lint user-facing doc strings embedded in engineering source code (properties, metrics, ...)')
2624
2624
  .requiredOption('--repo <path>', 'Path to an existing engineering checkout (for example, a local redpanda clone). Nothing is cloned.')
2625
- .option('--surface <list>', 'Comma-separated surfaces to lint (default: all registered). Registered: properties, metrics, rpk, helm, crd, connect')
2625
+ // Read off the registry rather than restated here: a hardcoded list silently
2626
+ // went stale the moment a surface was added.
2627
+ .option('--surface <list>', `Comma-separated surfaces to lint (default: all registered). Registered: ${Object.keys(require('../tools/lint-strings').SURFACES).join(', ')}`)
2626
2628
  .option('--diff <base>', 'Declaration-anchored diff mode: lint only declarations whose full span intersects lines changed in <base>...HEAD')
2627
2629
  .option('--format <format>', 'Output format: human or json', 'human')
2628
2630
  .option('--skip-rules <list>', 'Comma-separated rule ids to skip')
@@ -16,7 +16,8 @@ const DOC_TOOLS_BIN = path.resolve(__dirname, '..', 'doc-tools.js');
16
16
  * Lint user-facing doc strings embedded in engineering source code
17
17
  * @param {Object} args - Arguments
18
18
  * @param {string} args.repo - Path to the engineering checkout (required)
19
- * @param {string} [args.surface] - Comma-separated surfaces (properties, metrics, rpk, helm, crd, connect)
19
+ * @param {string} [args.surface] - Comma-separated surfaces; see the SURFACES
20
+ * registry in tools/lint-strings/index.js for the current list
20
21
  * @param {string} [args.diff] - Base ref for declaration-anchored diff mode
21
22
  * @param {string} [args.skip_rules] - Comma-separated rule ids to skip
22
23
  * @param {string} [args.only_rules] - Comma-separated rule ids to run exclusively
@@ -12,7 +12,7 @@
12
12
 
13
13
  const fs = require('fs')
14
14
  const path = require('path')
15
- const { getGitHubToken } = require('./github-token')
15
+ const { getGitHubApiToken } = require('./github-token')
16
16
 
17
17
  const RAW = 'https://raw.githubusercontent.com'
18
18
 
@@ -62,7 +62,7 @@ async function discardBody (resp) {
62
62
  * check runs on a weekly cron where nobody is watching live.
63
63
  *
64
64
  * @param {object} [deps]
65
- * @param {string|null} [deps.token] - GitHub token (defaults to getGitHubToken())
65
+ * @param {string|null} [deps.token] - GitHub token (defaults to getGitHubApiToken())
66
66
  * @param {Function} [deps.fetchImpl] - fetch implementation (defaults to global fetch)
67
67
  * @param {Function} [deps.warn] - warning sink (defaults to console.warn)
68
68
  * @param {Function} [deps.sleep] - delay implementation, for tests
@@ -72,7 +72,7 @@ async function discardBody (resp) {
72
72
  * check that never ran. Failures without a sourceName throw instead.
73
73
  */
74
74
  function createSourceFetcher (deps = {}) {
75
- const ghToken = deps.token !== undefined ? deps.token : getGitHubToken()
75
+ const ghToken = deps.token !== undefined ? deps.token : getGitHubApiToken()
76
76
  const fetchImpl = deps.fetchImpl || ((...args) => fetch(...args))
77
77
  const warn = deps.warn || ((msg) => console.warn(msg))
78
78
  const sleep = deps.sleep || ((ms) => new Promise((resolve) => setTimeout(resolve, ms)))
@@ -47,9 +47,25 @@ function getTokenFromGitCredentials(credentials = process.env.GIT_CREDENTIALS) {
47
47
  return null;
48
48
  }
49
49
 
50
+ const API_TOKEN_VARS = [
51
+ 'REDPANDA_GITHUB_TOKEN',
52
+ 'ACTIONS_BOT_TOKEN',
53
+ 'GITHUB_TOKEN',
54
+ 'VBOT_GITHUB_API_TOKEN',
55
+ 'GH_TOKEN'
56
+ ];
57
+
58
+ function firstApiTokenVar() {
59
+ for (const name of API_TOKEN_VARS) {
60
+ if (process.env[name]) return process.env[name];
61
+ }
62
+ return null;
63
+ }
64
+
50
65
  /**
51
- * Get GitHub token from environment variables
52
- * Checks multiple common variable names in priority order:
66
+ * Get the GitHub token for git operations (clone, fetch, authenticated URLs).
67
+ *
68
+ * Checks, in priority order:
53
69
  * 1. GIT_CREDENTIALS - Antora's credential store contents (github.com entry)
54
70
  * 2. REDPANDA_GITHUB_TOKEN - Custom Redpanda token
55
71
  * 3. ACTIONS_BOT_TOKEN - GitHub Actions bot token
@@ -57,21 +73,44 @@ function getTokenFromGitCredentials(credentials = process.env.GIT_CREDENTIALS) {
57
73
  * 5. VBOT_GITHUB_API_TOKEN - Legacy bot token
58
74
  * 6. GH_TOKEN - GitHub CLI default
59
75
  *
60
- * Note: this resolver feeds both git clone/fetch auth and GitHub API clients
61
- * (Octokit). Wherever GIT_CREDENTIALS is set (for example, Antora builds on
62
- * Netlify), API calls authenticate with that same token, whose API scopes may
63
- * differ from the token env vars it outranks.
76
+ * GIT_CREDENTIALS wins here on purpose: it is the credential Antora itself
77
+ * clones the content repos with, so anything else that clones in the same
78
+ * build should use the same identity. It is a git credential, not an API
79
+ * one; for REST calls use getGitHubApiToken().
64
80
  *
65
81
  * @returns {string|null} GitHub token or null if not found
66
82
  */
67
83
  function getGitHubToken() {
68
- return getTokenFromGitCredentials() ||
69
- process.env.REDPANDA_GITHUB_TOKEN ||
70
- process.env.ACTIONS_BOT_TOKEN ||
71
- process.env.GITHUB_TOKEN ||
72
- process.env.VBOT_GITHUB_API_TOKEN ||
73
- process.env.GH_TOKEN ||
74
- null;
84
+ return getTokenFromGitCredentials() || firstApiTokenVar();
85
+ }
86
+
87
+ /**
88
+ * Get the GitHub token for REST API calls (Octokit, api.github.com,
89
+ * raw.githubusercontent.com).
90
+ *
91
+ * Same variables as getGitHubToken(), but GIT_CREDENTIALS comes LAST:
92
+ *
93
+ * 1. REDPANDA_GITHUB_TOKEN
94
+ * 2. ACTIONS_BOT_TOKEN
95
+ * 3. GITHUB_TOKEN
96
+ * 4. VBOT_GITHUB_API_TOKEN
97
+ * 5. GH_TOKEN
98
+ * 6. GIT_CREDENTIALS
99
+ *
100
+ * Why the different order: on the Netlify Antora sites GIT_CREDENTIALS holds
101
+ * a token scoped only to cloning the private docs content repos. Letting it
102
+ * outrank REDPANDA_GITHUB_TOKEN meant the release lookup against the private
103
+ * streaming-enterprise repo authenticated with a token that cannot see that
104
+ * repo, got a 404, and every latest-redpanda-* attribute went unset in the
105
+ * production build even though a token with access was sitting right there.
106
+ * An explicitly named API token always beats the git credential; the git
107
+ * credential remains a fallback so a build with only GIT_CREDENTIALS still
108
+ * authenticates.
109
+ *
110
+ * @returns {string|null} GitHub token or null if not found
111
+ */
112
+ function getGitHubApiToken() {
113
+ return firstApiTokenVar() || getTokenFromGitCredentials();
75
114
  }
76
115
 
77
116
  /**
@@ -106,6 +145,7 @@ function hasGitHubToken() {
106
145
 
107
146
  module.exports = {
108
147
  getGitHubToken,
148
+ getGitHubApiToken,
109
149
  getTokenFromGitCredentials,
110
150
  getAuthenticatedGitHubUrl,
111
151
  hasGitHubToken
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const { Octokit } = require('@octokit/rest')
4
- const { getGitHubToken } = require('./github-token')
4
+ const { getGitHubApiToken } = require('./github-token')
5
5
 
6
6
  /**
7
7
  * Shared Octokit client instance for GitHub API access
@@ -14,7 +14,7 @@ const { getGitHubToken } = require('./github-token')
14
14
  */
15
15
 
16
16
  // Get authentication token from environment
17
- const token = getGitHubToken()
17
+ const token = getGitHubApiToken()
18
18
 
19
19
  // Configure Octokit options
20
20
  const octokitOptions = {
@@ -1,6 +1,6 @@
1
1
  const yaml = require('js-yaml');
2
2
  const { spawnSync } = require('child_process');
3
- const { getGitHubToken } = require('./github-token');
3
+ const { getGitHubApiToken } = require('./github-token');
4
4
 
5
5
  const ANTORA_URL = 'https://raw.githubusercontent.com/redpanda-data/docs/main/antora.yml'
6
6
 
@@ -23,7 +23,7 @@ const REJECTED_HINT = ' A GitHub token was sent but rejected, so it may be expir
23
23
  */
24
24
  async function fetchRemoteAntoraVersion(deps = {}) {
25
25
  const fetchImpl = deps.fetchImpl || fetch
26
- const ghToken = 'token' in deps ? deps.token : getGitHubToken()
26
+ const ghToken = 'token' in deps ? deps.token : getGitHubApiToken()
27
27
 
28
28
  let resp = await fetchImpl(ANTORA_URL, ghToken ? { headers: { Authorization: `Bearer ${ghToken}` } } : undefined)
29
29
  const hint = ghToken ? REJECTED_HINT : TOKEN_HINT
@@ -10,10 +10,13 @@ module.exports.register = function ({ config }) {
10
10
  const GetLatestConnectVersion = require('./get-latest-connect');
11
11
  const logger = this.getLogger('set-latest-version-extension');
12
12
 
13
- const { getGitHubToken } = require('../../cli-utils/github-token');
13
+ const { getGitHubApiToken } = require('../../cli-utils/github-token');
14
14
  // Shared with tools/bundle-openapi.js so there is one major.minor derivation.
15
15
  const { toShortVersion } = require('../../cli-utils/version');
16
- const token = getGitHubToken();
16
+ // API token, not the git one: GIT_CREDENTIALS (Antora's clone credential)
17
+ // is only a last resort here, because on Netlify it is scoped to the docs
18
+ // content repos and cannot see streaming-enterprise.
19
+ const token = getGitHubApiToken();
17
20
 
18
21
  if (!token) {
19
22
  // Unauthenticated requests still work for the public repos this
@@ -21,7 +24,7 @@ module.exports.register = function ({ config }) {
21
24
  // version now comes from the private streaming-enterprise repo, whose
22
25
  // API 404s without a token -- the latest-redpanda-* attributes are then
23
26
  // left unset and pages fall back to their antora.yml values.
24
- logger.warn('GitHub token not set (GIT_CREDENTIALS, REDPANDA_GITHUB_TOKEN, GITHUB_TOKEN, or GH_TOKEN). The Redpanda version lookup against the private streaming-enterprise repo will fail and leave latest-redpanda-* attributes unset; other lookups proceed unauthenticated.');
27
+ logger.warn('GitHub token not set (REDPANDA_GITHUB_TOKEN, GITHUB_TOKEN, GH_TOKEN, or GIT_CREDENTIALS). The Redpanda version lookup against the private streaming-enterprise repo will fail and leave latest-redpanda-* attributes unset; other lookups proceed unauthenticated.');
25
28
  }
26
29
 
27
30
  this.on('contentClassified', async ({ contentCatalog }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redpanda-data/docs-extensions-and-macros",
3
- "version": "5.31.0",
3
+ "version": "5.35.1",
4
4
  "description": "Antora extensions and macros developed for Redpanda documentation.",
5
5
  "keywords": [
6
6
  "antora",
@@ -2,7 +2,7 @@
2
2
 
3
3
  const GetLatestRedpandaVersion = require('../extensions/version-fetcher/get-latest-redpanda-version.js');
4
4
  const { getPrereleaseFromAntora } = require('../cli-utils/antora-utils.js');
5
- const { getGitHubToken } = require('../cli-utils/github-token');
5
+ const { getGitHubApiToken } = require('../cli-utils/github-token');
6
6
 
7
7
  /**
8
8
  * Fetches and prints the latest Redpanda version and Docker repository.
@@ -20,7 +20,7 @@ module.exports = async function getRedpandaVersion({ beta = false, fromAntora =
20
20
  const owner = 'redpanda-data';
21
21
  const repo = 'streaming-enterprise';
22
22
 
23
- if (!getGitHubToken()) {
23
+ if (!getGitHubApiToken()) {
24
24
  console.error(`❌ redpanda-data/${repo} is a private repository.`);
25
25
  console.error(' Set GH_TOKEN, REDPANDA_GITHUB_TOKEN, or GITHUB_TOKEN to a token with access.');
26
26
  process.exit(1);
@@ -26,7 +26,21 @@ const SURFACE_ROUTES = [
26
26
  // console) and charts/<name>/values.yaml (connectors).
27
27
  { surface: 'helm', pattern: /^charts\/[^/]+\/(chart\/)?values\.yaml$/ },
28
28
  { surface: 'crd', pattern: /^operator\/api\// },
29
- { surface: 'connect', pattern: /^internal\/impl\// }
29
+ { surface: 'connect', pattern: /^internal\/impl\// },
30
+ // API protos, whose comments and openapiv2 option strings reach readers as
31
+ // OpenAPI descriptions. console holds the data plane and Console APIs under
32
+ // proto/redpanda/api/; cloudv2's control plane lives under proto/public/.
33
+ // Anchored on the api/ segment so cloudv2's proto/descriptors/ tree (private
34
+ // and internal) and every vendored proto/public/**/wellknown/ path stay out.
35
+ { surface: 'api', pattern: /^proto\/(?:redpanda\/api|public\/[^/]+\/redpanda\/api)\/.*\.proto$/ },
36
+ // Admin API v2, in the redpanda/streaming-enterprise repo. A different
37
+ // generator (protoc-gen-connect-openapi) and a third string form; see
38
+ // surfaces/api.js. These two directories are exactly what the api-docs
39
+ // bundler feeds into the published spec (tools/bundle-openapi.js):
40
+ // `admin/internal` and `core/testing` are excluded by that repo's buf.yaml
41
+ // and generate nothing, and `core/rest` generates a fragment that is never
42
+ // bundled, so none of them reach readers.
43
+ { surface: 'api', pattern: /^proto\/redpanda\/core\/(?:admin\/v2|common)\/.*\.proto$/ }
30
44
  ]
31
45
 
32
46
  /**
@@ -0,0 +1,114 @@
1
+ // Copyright 2026 Redpanda Data, Inc.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ //
6
+ // A license header is a leading comment on nothing. It must not attach itself
7
+ // to the first declaration in the file.
8
+
9
+ syntax = "proto3";
10
+
11
+ package redpanda.core.admin.v2;
12
+
13
+ import "proto/redpanda/core/pbgen/rpc.proto";
14
+
15
+ option (pbgen.cpp_namespace) = "proto::fixture";
16
+
17
+ service FixtureService {
18
+ // GetFixture
19
+ //
20
+ // Returns a single fixture.
21
+ rpc GetFixture(GetFixtureRequest) returns (GetFixtureResponse) {
22
+ option (pbgen.rpc) = {
23
+ authz: SUPERUSER
24
+ };
25
+ }
26
+
27
+ // CreateFixture
28
+ //
29
+ // Creates a fixture. The description can run over several comment
30
+ // lines, and the resolved prose joins them.
31
+ //
32
+ // A blank comment line inside the description is a paragraph break and
33
+ // stays part of the description.
34
+ rpc CreateFixture(CreateFixtureRequest)
35
+ returns (CreateFixtureResponse) {
36
+ option (pbgen.rpc) = {
37
+ authz: SUPERUSER
38
+ };
39
+ }
40
+
41
+ // Reports the collapsed case: with no blank line the generator uses this
42
+ // whole comment as BOTH the summary and the description, so the API
43
+ // reference's nav item becomes a paragraph.
44
+ rpc CollapsedFixture(CollapsedFixtureRequest)
45
+ returns (CollapsedFixtureResponse) {
46
+ option (pbgen.rpc) = {
47
+ authz: SUPERUSER
48
+ };
49
+ }
50
+
51
+ // DeleteFixture.
52
+ //
53
+ // Deletes a fixture.
54
+ rpc DeleteFixture(DeleteFixtureRequest) returns (DeleteFixtureResponse) {
55
+ option (pbgen.rpc) = {
56
+ authz: SUPERUSER
57
+ };
58
+ }
59
+
60
+ // ListFixtures
61
+ // over two lines
62
+ //
63
+ // Lists every fixture.
64
+ rpc ListFixtures(ListFixturesRequest) returns (ListFixturesResponse) {
65
+ option (pbgen.rpc) = {
66
+ authz: SUPERUSER
67
+ };
68
+ }
69
+
70
+ // BodylessFixture
71
+ //
72
+ // A body-less rpc opens no block, so it must not swallow the
73
+ // declarations that follow it.
74
+ rpc BodylessFixture(BodylessFixtureRequest) returns (BodylessFixtureResponse);
75
+
76
+ // WatchFixture
77
+ //
78
+ // Confirms the rpc after a body-less one is still found.
79
+ rpc WatchFixture(WatchFixtureRequest) returns (WatchFixtureResponse) {
80
+ option (pbgen.rpc) = {
81
+ authz: SUPERUSER
82
+ };
83
+ }
84
+ }
85
+
86
+ // The request for a single fixture.
87
+ message GetFixtureRequest {
88
+ // The node ID for the fixture. If unset, the broker handling the RPC
89
+ // returns information about itself.
90
+ optional int32 node_id = 1;
91
+
92
+ // Fixture name
93
+ string name = 2;
94
+
95
+ int32 undocumented = 3;
96
+
97
+ // Partition ID
98
+ int32 partition_id = 4;
99
+
100
+ // The protocol versions the fixture supports. See
101
+ // https://kafka.apache.org/protocol.html#protocol_compatibility
102
+ repeated int32 api_versions = 5;
103
+ }
104
+
105
+ // Fixture mode
106
+ //
107
+ // - Not specified
108
+ // - Runs fast
109
+ enum FixtureMode {
110
+ FIXTURE_MODE_UNSPECIFIED = 0;
111
+ // Per-value comments are discarded by protoc-gen-connect-openapi, so they
112
+ // are not extracted and must not be reported as declarations.
113
+ FIXTURE_MODE_FAST = 1;
114
+ }
@@ -0,0 +1,123 @@
1
+ syntax = "proto3";
2
+
3
+ package redpanda.api.fixture.v1;
4
+
5
+ import "google/protobuf/descriptor.proto";
6
+ import "protoc-gen-openapiv2/options/annotations.proto";
7
+
8
+ // Extension fields are wire metadata, never published schema. The field
9
+ // inside this block must not be extracted.
10
+ extend google.protobuf.MethodOptions {
11
+ string fixture_extension = 60002;
12
+ }
13
+
14
+ // FixtureMode selects how the fixture behaves.
15
+ enum FixtureMode {
16
+ FIXTURE_MODE_UNSPECIFIED = 0;
17
+ FIXTURE_MODE_FAST = 1;
18
+ }
19
+
20
+ // A fixture topic.
21
+ message FixtureTopic {
22
+ // A topic-level config key (e.g. `segment.bytes`).
23
+ string name = 1;
24
+
25
+ // Whether the config is read-only, or is dynamic and can be altered.
26
+ bool read_only = 2;
27
+
28
+ // Wrapped option lists must be covered by the declaration span, so a
29
+ // suggestion block can replace the whole statement.
30
+ string wrapped = 3 [
31
+ (buf.validate.field).string.min_len = 1,
32
+ (buf.validate.field).string.max_len = 255
33
+ ];
34
+
35
+ // Sets default_topic_partitions when the topic is created.
36
+ int32 partitions = 4;
37
+
38
+ // A comment can wrap over several lines, and the resolved prose joins them
39
+ // rather than keeping only the first.
40
+ string wrapped_comment = 5;
41
+
42
+ string undocumented = 6;
43
+
44
+ // An openapiv2_field description OVERRIDES this comment, so the comment is
45
+ // dead text and the option's string is what must be linted.
46
+ string option_documented = 9 [
47
+ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
48
+ description: "The string the generator actually publishes."
49
+ example: "\"ignored\""
50
+ }
51
+ ];
52
+
53
+ /*
54
+ * A field documented ONLY by an openapiv2_field option is not an
55
+ * undocumented field. 73 of console's fields are this shape and every one
56
+ * of them used to be reported as having no description.
57
+ *
58
+ * This note is a detached block comment, separated by a blank line, so that
59
+ * option_only genuinely has no leading comment of its own.
60
+ */
61
+
62
+ string option_only = 10 [
63
+ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
64
+ description: "Documented by the option alone."
65
+ }
66
+ ];
67
+
68
+ // A oneof moves the brace depth without opening a message. Matching a bare
69
+ // closing brace here popped FixtureTopic and reported the sibling message
70
+ // below as nested inside it.
71
+ oneof selector {
72
+ // Selects by name.
73
+ string by_name = 7;
74
+ // Selects by id.
75
+ string by_id = 8;
76
+ }
77
+
78
+ // Nested messages are genuinely nested and should report a dotted path.
79
+ message Nested {
80
+ // The nested value.
81
+ string value = 1;
82
+ }
83
+ }
84
+
85
+ // A sibling of FixtureTopic, not a child of it.
86
+ message FixtureSibling {
87
+ // The sibling name.
88
+ string name = 1;
89
+ }
90
+
91
+ service FixtureService {
92
+ rpc CreateFixture(FixtureTopic) returns (FixtureTopic) {
93
+ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
94
+ summary: "Create fixture."
95
+ description: "Create a [fixture](https://docs.redpanda.com/fixture/) with a `{prefix}` path."
96
+ responses: {
97
+ key: "200"
98
+ value: {description: "OK"}
99
+ }
100
+ responses: {
101
+ key: "201"
102
+ value: {description: "Fixture created"}
103
+ }
104
+ };
105
+ }
106
+
107
+ rpc ListFixtures(FixtureTopic) returns (FixtureTopic) {
108
+ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
109
+ summary: "List fixtures"
110
+ description: "Short one"
111
+ };
112
+ }
113
+
114
+ rpc JoinFixtures(FixtureTopic) returns (FixtureTopic) {
115
+ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
116
+ summary: "Join fixtures"
117
+ // Proto concatenates adjacent string literals like C++, so the resolved
118
+ // description is both halves, not just the first.
119
+ description: "Joins two fixtures together "
120
+ "and returns the result."
121
+ };
122
+ }
123
+ }
@@ -28,7 +28,7 @@ This fixture exercises the ` + "`raw` + interpreted + `raw`" + ` concatenation i
28
28
  This heading and the table below are legitimate AsciiDoc:
29
29
 
30
30
  |===
31
- | kafka_key | The record key
31
+ | `+"`kafka_key`"+` | The record key
32
32
  |===
33
33
  `).
34
34
  Fields(fixtureConfigFields()...)
@@ -4,6 +4,7 @@ package v1alpha2
4
4
 
5
5
  import (
6
6
  metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
7
+ "k8s.io/apimachinery/pkg/runtime"
7
8
  )
8
9
 
9
10
  // WidgetSpec defines the configuration of a fixture widget.
@@ -35,6 +36,75 @@ type WidgetReference struct {
35
36
  Version int `json:"version"`
36
37
  }
37
38
 
39
+ // EmptyOnOneLine opens and closes on a single line. Assuming it opened a
40
+ // struct body left the parser inside a type that had already ended, which
41
+ // dropped every declaration below it in the file.
42
+ type EmptyOnOneLine struct{}
43
+
44
+ // ValueSource represents where a value can be pulled from.
45
+ type ValueSource struct {
46
+ // The literal value.
47
+ Value string `json:"value,omitempty"`
48
+ }
49
+
50
+ // UndocumentedType has no doc comment of its own, so a field referencing it
51
+ // has nothing to inherit and genuinely ships blank.
52
+ type undocumentedTypeMarker int
53
+
54
+ type UndocumentedTarget struct {
55
+ // The only field.
56
+ Only string `json:"only,omitempty"`
57
+ }
58
+
59
+ // InlinedValues is +hidefromdoc, but it is embedded with `json:",inline"`
60
+ // below, so crd-ref-docs flattens its fields into the embedding type and
61
+ // publishes every one of them. The marker suppresses this type's own section,
62
+ // not its fields.
63
+ // +hidefromdoc
64
+ type InlinedValues struct {
65
+ ReplicaCount *int32 `json:"replicaCount,omitempty"`
66
+ }
67
+
68
+ // HiddenNotInlined is +hidefromdoc and embedded nowhere, so nothing it
69
+ // declares is ever published.
70
+ // +hidefromdoc
71
+ type HiddenNotInlined struct {
72
+ NeverPublished string `json:"neverPublished,omitempty"`
73
+ }
74
+
75
+ // EmbeddingSpec inlines a hidden type.
76
+ type EmbeddingSpec struct {
77
+ InlinedValues `json:",inline"`
78
+ // The name of the thing.
79
+ Name string `json:"name,omitempty"`
80
+ }
81
+
82
+ // StructuralSpec covers external types that controller-gen publishes with no
83
+ // description of their own.
84
+ type StructuralSpec struct {
85
+ // +optional
86
+ Config *runtime.RawExtension `json:"config,omitempty"`
87
+ // +optional
88
+ Expiration *metav1.Time `json:"expiration,omitempty"`
89
+ }
90
+
91
+ // FallbackSpec covers what an uncommented field actually publishes.
92
+ type FallbackSpec struct {
93
+ // +optional
94
+ Inherited *ValueSource `json:"inherited,omitempty"`
95
+ // +optional
96
+ FromUndocumented *UndocumentedTarget `json:"fromUndocumented,omitempty"`
97
+ // +optional
98
+ Primitive string `json:"primitive,omitempty"`
99
+ // +optional
100
+ SliceOfDocumented []ValueSource `json:"sliceOfDocumented,omitempty"`
101
+ // +optional
102
+ External *metav1.Duration `json:"external,omitempty"`
103
+ // How long to wait before giving up on the widget.
104
+ // +optional
105
+ Both *ValueSource `json:"both,omitempty"`
106
+ }
107
+
38
108
  // WidgetList is ignored via the config's ignoreTypes ('List$').
39
109
  type WidgetList struct {
40
110
  metav1.TypeMeta `json:",inline"`