Skip to content

Parameterize reference generation by target collection#326

Open
miharp wants to merge 1 commit into
OpenVoxProject:masterfrom
miharp:docs/issue-325-reference-pinning
Open

Parameterize reference generation by target collection#326
miharp wants to merge 1 commit into
OpenVoxProject:masterfrom
miharp:docs/issue-325-reference-pinning

Conversation

@miharp

@miharp miharp commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

What

Make the reference generators able to build into an arbitrary target collection,
rather than always writing into the current stable collection. This is the first
step toward versioned docs (frozen historical versions + a new major line).

Why

Today each generator hardcodes its output dir (_<product>_latest, or
_openbolt_5x for OpenBolt) and emits canonical URLs at load time, so every build
lands in the current stable collection. To freeze _openvox_8x and build a new
_openvox_9x from a different upstream tag, builds need to target a specific
collection and emit URLs that match that version.

Changes

  • Add PuppetReferences.url_base_for to map a collection dir to its published URL
    base (e.g. _openvox_9x/openvox/9.x), splitting on the last underscore so
    hyphenated product names (openvox-server) stay intact.
  • Thread a collection: argument through build_puppet_references /
    build_facter_references / build_openbolt_references into every generator,
    replacing the load-time OUTPUT_DIR constants with instance-level paths derived
    from the target collection.
  • Fix an existing OpenFact bug: core_facts and facter_cli stamped
    /openvox/latest canonicals while writing into _openfact_*; they now derive the
    correct /openfact/... base.
  • Localize intra-product body links. Generated pages embedded /<product>/latest/
    links (e.g. via the static type preamble), which would leak a frozen version's
    pages back to latest. Add Reference#localize_links, which rewrites only the
    target product's own /latest/ doc links to the version base, applied in the type
    and functions generators. Cross-product links (a different product's /latest/)
    are left to follow latest per the repo's linking policy, and it's a no-op when
    building the latest collection.
  • Key the strings cache per collection. strings.json generation was memoized
    with a single global flag while its path is now per collection; building more than
    one collection in one process would skip generation and read a missing/stale file.
    Memoize by output path instead.
  • Rakefile accepts COLLECTION=<dir> alongside VERSION=, defaulting per product
    to the prior hardcoded targets so CI behavior is unchanged.

An explicit VERSION already bypasses the prerelease filter (newest_release is
only consulted when no VERSION is given), so a frozen version can be built from a
prerelease tag — no change needed there.

Validation

Ran real end-to-end builds (not just unit checks):

  • references:openfact VERSION=5.6.1 COLLECTION=_openfact_5x → files land in
    _openfact_5x, canonical /openfact/5.x/....
  • references:openfact VERSION=5.6.1 (no COLLECTION) → _openfact_latest,
    canonical /openfact/latest/... (back-compat preserved + bug fixed).
  • references:openvox VERSION=9.0.0-alpha1 COLLECTION=_openvox_9x → all five
    generators ran; man/, types/, types_strings/ subdirs and the intermediate
    JSON (strings.json, type.json, …) all routed into _openvox_9x; every
    canonical is /openvox/9.x/... (0 stale /openvox/latest canonicals);
    built_from_commit matches the 9.0.0-alpha1 tag, confirming the prerelease build.
  • references:openvox VERSION=8.28.0 COLLECTION=_openvox_8x → the three type-preamble
    links resolve to /openvox/8.x in both type.md (root) and types/overview.md
    (subdir), and zero intra-product /openvox/latest/ links remain in the build.
  • localize_links unit-checked: rewrites the own product's /latest/, preserves a
    different product's /latest/ (cross-product) and external puppet.com/.../latest
    links, and is a no-op for the latest collection.
  • rubocop clean; library loads; all generator classes instantiate with the
    expected output dir and URL base.

Scope

This is the generator capability only. The references:all task that reads a
_data/versions.yml pin table, the cutover runbook, and the version selector are
follow-ups.

Part of #325.

@miharp miharp requested a review from a team as a code owner June 10, 2026 13:39
@miharp miharp marked this pull request as draft June 10, 2026 14:53
The reference generators hardcoded their output dir (_<product>_latest, or
_openbolt_5x for OpenBolt) and emitted canonical/body URLs at load time, so every
build wrote into the current stable collection and linked to /latest. To support
frozen historical docs and a new major version, builds must be able to target an
arbitrary collection and emit URLs that match that version.

- Add PuppetReferences.url_base_for to map a collection dir to its published URL
  base (e.g. _openvox_9x -> /openvox/9.x), splitting on the last underscore so
  hyphenated product names stay intact.
- Thread a collection: argument through build_puppet_references /
  build_facter_references / build_openbolt_references into every generator,
  replacing the load-time OUTPUT_DIR constants with instance-level paths derived
  from the target collection.
- Add Reference#localize_links to rewrite the target product's own /latest/ doc
  links to the version base (e.g. /openvox/8.x), applied in the type and functions
  generators. Cross-product links (a different product's /latest/) follow latest
  per the repo's linking policy; it is a no-op when building the latest collection.
- Key the Strings JSON memoization by output path rather than a single global
  flag, so building more than one collection in one process generates each
  strings.json instead of skipping and reading a missing/stale file.
- Fix an existing OpenFact bug: core_facts and facter_cli stamped /openvox/latest
  canonicals while writing into _openfact_*; they now derive the correct
  /openfact/... base.
- Rakefile accepts COLLECTION=<dir> alongside VERSION=, defaulting per product to
  the prior hardcoded targets so CI behavior is unchanged.
- Document the COLLECTION flag in CONTRIBUTING.

An explicit VERSION already bypasses the prerelease filter (newest_release is only
consulted when no VERSION is given), so a frozen version can be built from a
prerelease tag.

Verified with real end-to-end builds: OpenFact 5.6.1 into _openfact_5x and the
default _openfact_latest; OpenVox 9.0.0-alpha1 into _openvox_9x (all generators,
subdirs and intermediate JSON routed correctly, version-pinned canonicals); and
OpenVox 8.28.0 into _openvox_8x confirming the type-preamble links resolve to
/openvox/8.x with zero intra-product /openvox/latest links remaining.

Part of OpenVoxProject#325.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Signed-off-by: Michael Harp <[email protected]>
@miharp miharp force-pushed the docs/issue-325-reference-pinning branch from ea906a5 to 4df6da6 Compare June 10, 2026 15:08
@miharp miharp marked this pull request as ready for review June 10, 2026 15:21
def initialize(*)
@latest = '/openvox/latest/man'
super
@latest = "#{@latest}/man"

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.

do we still need the initialize?

@latest = '/openvox/latest/yard'
super
@latest = "#{@latest}/yard"
end

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.

do we still need this? initialize was removed in other files.

Comment thread lib/puppet_references.rb
end

def self.build_openbolt_references(commit)
def self.build_openbolt_references(commit, collection: '_openbolt_5x')

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.

why do we have a different pattern here? all other generator use _latest instead of a version.

Comment thread Rakefile
require 'puppet_references'
PuppetReferences.build_openbolt_references(ENV.fetch('VERSION', nil))
PuppetReferences.build_openbolt_references(ENV.fetch('VERSION', nil), collection: ENV.fetch('COLLECTION', '_openbolt_5x'))
end

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.

same here. all other use latest.

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.

2 participants