Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions docs/operator-docs-versioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ published just because their Website PR is merged. The local command
`npm run preview:operator-source` is explicitly labeled as an unpublished
authoring preview.

Netlify deploy previews make these edits reviewable before release: the
editable source appears at the ordinary, unversioned Operator URLs, with an
"Upcoming Operator documentation preview — not published" notice. Browser
search includes the editable source, and the documentation assistant is hidden
on these pages because it uses published documentation. Registered release
URLs remain mounted from their frozen snapshots. For example, while
preparing v1.2.0, inspect the roadmap at
`<deploy-preview-url>/docs/krkn-operator/releases/`; the page at
`<deploy-preview-url>/docs/krkn-operator/versions/v1.1.0/releases/` continues
to show the captured v1.1.0 roadmap. Production builds do not enable this
preview mode: source pages stay hidden and unversioned links redirect to the
newest published stable snapshot.

Previously shared unversioned URLs keep working through generated redirect
pages that send readers to the corresponding article in the newest published
stable snapshot, or its overview if the article is unavailable. Those pages
Expand Down Expand Up @@ -127,5 +140,6 @@ NETLIFY=false LINK_CHECK_SOFT_FAIL=0 npm run check:links

A raw `hugo` command bypasses snapshot preparation and integrity checks. The
`preview:operator-source` command is only for authors to inspect unpublished
source; use a production build or Website PR preview to check what readers
will see.
source locally. In a Website PR deploy preview, use unversioned Operator URLs
to review pending source edits and versioned URLs to verify archived releases.
Use a production build to check what public readers will see.
3 changes: 2 additions & 1 deletion layouts/_partials/hooks/body-end.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<!-- Include Krkn Documentation Chatbot -->
{{- $operatorDocs := partial "operator-docs/context.html" . -}}
{{- if not $operatorDocs.isOlder }}
{{- $operatorSourcePreview := and .Site.Params.operator_docs_authoring_preview (strings.HasPrefix .RelPermalink "/docs/krkn-operator/") (not $operatorDocs.enabled) -}}
{{- if and (not $operatorDocs.isOlder) (not $operatorSourcePreview) }}
{{ partial "chatbot.html" . }}
{{- end }}
{{- if $operatorDocs.enabled }}
Expand Down
5 changes: 3 additions & 2 deletions layouts/_td-content-after-header.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{{- $context := partial "operator-docs/context.html" . -}}
{{- if $context.enabled }}
{{ partial "operator-docs/banner.html" $context }}
{{- else if .Site.Params.operator_docs_authoring_preview }}
{{- else if and .Site.Params.operator_docs_authoring_preview (strings.HasPrefix .RelPermalink "/docs/krkn-operator/") (not (strings.HasPrefix .RelPermalink "/docs/krkn-operator/versions/")) }}
<aside class="krkn-operator-docs-authoring-banner" aria-label="Authoring preview">
Authoring preview — not published documentation.
Upcoming Operator documentation preview — not published.
The versioned release pages remain frozen, and the documentation assistant is disabled on draft pages.
</aside>
{{- end -}}
1 change: 1 addition & 0 deletions netlify.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ command = "npm install && npm run build:preview && node scripts/post-build.js"

[context.deploy-preview.environment]
HUGO_VERSION = "0.146.0"
OPERATOR_DOCS_DEPLOY_PREVIEW = "1"

# Function-specific settings
[functions]
Expand Down
16 changes: 12 additions & 4 deletions scripts/hugo-with-operator-docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,24 +60,32 @@ async function main() {
throw new Error(`Hugo binary not found at ${hugoBin}`);
}
const authoringPreview = process.env.OPERATOR_DOCS_AUTHORING_PREVIEW === '1';
const deployPreview = process.env.OPERATOR_DOCS_DEPLOY_PREVIEW === '1';
const registry = authoringPreview ? null : readRegistry(repoRoot);
const prepared = authoringPreview
? { enabled: false }
: prepareHugoInputs(repoRoot, registry);
: prepareHugoInputs(repoRoot, registry, {
includeAuthoringSourcePreview: deployPreview,
});
const generatedConfig = prepared.hugoConfigPath
? `hugo.yaml,${path.relative(repoRoot, prepared.hugoConfigPath)}`
: null;
const hugoArgs = authoringPreview
? ['--config', 'hugo.yaml,config/operator-docs-authoring.yaml', ...args]
: prepared.enabled
? ['--config', `hugo.yaml,${path.relative(repoRoot, prepared.hugoConfigPath)}`, ...args]
: generatedConfig
? ['--config', generatedConfig, ...args]
: args;
if (authoringPreview) {
console.log('Authoring preview — not published documentation.');
} else if (deployPreview) {
console.log('Deploy preview — upcoming Operator docs are shown at unversioned URLs; release snapshots remain frozen.');
}
const exitCode = await runHugo(hugoArgs);
if (exitCode !== 0) {
process.exitCode = exitCode;
return;
}
if (isStaticBuild(args) && prepared.enabled) {
if (isStaticBuild(args) && prepared.enabled && !deployPreview) {
finalizeRedirects(repoRoot, registry, path.join(repoRoot, 'public'));
}
}
Expand Down
70 changes: 51 additions & 19 deletions scripts/lib/operator-docs-hugo.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,44 +241,74 @@ function writeRedirectPages(repoRoot, redirects) {
);
}

function writeHugoConfig(repoRoot, defaultTag, registry) {
function writeHugoConfig(repoRoot, defaultTag, registry, options = {}) {
const configPath = path.join(repoRoot, CACHE_ROOT, 'hugo.yaml');
const releaseRecords = sortReleasesNewest(registry);
const releaseTags = releaseRecords.map((release) => release.tag);
const includeAuthoringSourcePreview = options.includeAuthoringSourcePreview === true;
const mounts = [
{
source: 'content/en',
target: 'content',
excludeFiles: ['docs/krkn-operator/**'],
},
{
source: 'content/en/docs/krkn-operator/versions',
target: 'content/docs/krkn-operator/versions',
},
{
source: `${CACHE_ROOT}/redirects`,
target: 'content/docs/krkn-operator',
},
];
if (includeAuthoringSourcePreview) {
mounts.push(
{
source: 'content/en/docs/krkn-operator',
target: 'content/docs/krkn-operator',
excludeFiles: ['versions/**'],
},
{
source: 'content/en/docs/krkn-operator/versions',
target: 'content/docs/krkn-operator/versions',
}
);
} else {
mounts.push(
{
source: 'content/en/docs/krkn-operator/versions',
target: 'content/docs/krkn-operator/versions',
},
{
source: `${CACHE_ROOT}/redirects`,
target: 'content/docs/krkn-operator',
}
);
}
const config = {
module: {
mounts,
},
params: {
operator_docs_default_tag: defaultTag,
operator_docs_release_tags: releaseTags,
operator_docs_release_records: releaseRecords,
...(defaultTag ? {
operator_docs_default_tag: defaultTag,
operator_docs_release_tags: releaseTags,
operator_docs_release_records: releaseRecords,
} : {}),
...(includeAuthoringSourcePreview ? { operator_docs_authoring_preview: true } : {}),
Comment thread
qodo-code-review[bot] marked this conversation as resolved.
},
};
if (registry.releases.length > 0) config.module = { mounts };
fs.writeFileSync(configPath, YAML.stringify(config));
return configPath;
}

function prepareHugoInputs(repoRoot, registry = readRegistry(repoRoot)) {
function prepareHugoInputs(repoRoot, registry = readRegistry(repoRoot), options = {}) {
validateRegistry(registry);
removeGeneratedCache(repoRoot);
const includeAuthoringSourcePreview = options.includeAuthoringSourcePreview === true;
const enabled = registry.releases.length > 0;
if (!enabled) {
if (includeAuthoringSourcePreview) {
fs.mkdirSync(path.join(repoRoot, CACHE_ROOT), { recursive: true });
const hugoConfigPath = writeHugoConfig(repoRoot, null, registry, options);
return {
enabled: false,
versionTag: null,
defaultRelease: null,
hugoConfigPath,
redirects: [],
};
}
return {
enabled: false,
versionTag: null,
Expand All @@ -291,10 +321,12 @@ function prepareHugoInputs(repoRoot, registry = readRegistry(repoRoot)) {
validateSnapshots(repoRoot, registry);
const defaultRelease = selectDefaultRelease(registry);
const releasePages = collectReleasePages(repoRoot, registry.releases);
const redirects = buildRedirects(repoRoot, defaultRelease, releasePages);
const redirects = includeAuthoringSourcePreview
? []
: buildRedirects(repoRoot, defaultRelease, releasePages);
fs.mkdirSync(path.join(repoRoot, CACHE_ROOT), { recursive: true });
writeRedirectPages(repoRoot, redirects);
const hugoConfigPath = writeHugoConfig(repoRoot, defaultRelease.tag, registry);
if (!includeAuthoringSourcePreview) writeRedirectPages(repoRoot, redirects);
const hugoConfigPath = writeHugoConfig(repoRoot, defaultRelease.tag, registry, options);
return {
enabled: true,
versionTag: defaultRelease.tag,
Expand Down
40 changes: 40 additions & 0 deletions scripts/tests/operator-docs-hugo.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,46 @@ test('prepared builds only mount releases in the registry', () => {
assert.equal(fs.existsSync(path.join(repoRoot, '.cache/operator-docs/preview-test-snapshot')), false);
});

test('deploy previews expose editable Operator source while keeping registered snapshots', () => {
const { repoRoot } = setupRepo();
const registry = readRegistry(repoRoot);
const result = prepareHugoInputs(repoRoot, registry, {
includeAuthoringSourcePreview: true,
});
const config = YAML.parse(fs.readFileSync(result.hugoConfigPath, 'utf8'));

assert.equal(result.enabled, true);
assert.deepEqual(result.redirects, []);
assert.equal(config.params.operator_docs_authoring_preview, true);
assert.deepEqual(config.params.operator_docs_release_tags, ['v1.1.0', 'v1.0.0']);
assert.ok(config.module.mounts.some((mount) =>
mount.source === 'content/en/docs/krkn-operator' &&
mount.target === 'content/docs/krkn-operator' &&
mount.excludeFiles.includes('versions/**')
));
assert.ok(config.module.mounts.some((mount) =>
mount.source === 'content/en/docs/krkn-operator/versions' &&
mount.target === 'content/docs/krkn-operator/versions'
));
assert.ok(!config.module.mounts.some((mount) => mount.source === '.cache/operator-docs/redirects'));
assert.equal(fs.existsSync(path.join(repoRoot, '.cache/operator-docs/redirects')), false);
});

test('empty-registry deploy previews still enable the unpublished-source notice', () => {
const repoRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'operator-docs-preview-empty-'));
fs.mkdirSync(path.join(repoRoot, 'data'), { recursive: true });
fs.writeFileSync(path.join(repoRoot, 'data/operator_doc_versions.yaml'), 'schema_version: 1\nreleases: []\n');

const result = prepareHugoInputs(repoRoot, readRegistry(repoRoot), {
includeAuthoringSourcePreview: true,
});

assert.ok(result.hugoConfigPath);
const config = YAML.parse(fs.readFileSync(result.hugoConfigPath, 'utf8'));
assert.equal(config.params.operator_docs_authoring_preview, true);
assert.equal(config.module, undefined);
});

test('final redirects append exact temporary rules and preserve existing API rules', () => {
const { repoRoot } = setupRepo();
prepareHugoInputs(repoRoot, readRegistry(repoRoot));
Expand Down
Loading
Loading