You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Packaged docs repos assemble the release asset by hand. AbsaOSS/knowledge-base-docs-example/.github/workflows/pack.yml validates the manifest with an inline Python snippet, greps the HTML for the headless attribute, runs tar -czf dist.tar.gz dist/ marketplace.json and uploads through softprops/action-gh-release. Every new docs repo copies that file, and every contract change (the rename in #74, a new required field, a tightened check) has to be chased across N repositories by hand. The reusable validate-doc-app.yml workflow does not help: it assumes npm run build -- --headless, which the Python example cannot run, and it is not what the example uses.
Single-page docs already have this solved: actions/publish-single-page-docs owns validation, packing and upload, and a consuming repo only passes inputs. Packaged sites need the same.
Proposal
actions/publish-docs
A composite action for repos that build their own headless site. The repo keeps its build (mkdocs, Starlight, anything); the action owns everything after it.
- uses: AbsaOSS/knowledge-base/actions/publish-docs@v1with:
manifest: kb-docs.json # default; repo rootdist: dist # default; the headless build output for the single app in the manifestrelease-tag: ${{ github.ref_name }} # default: triggering release, else latest
Steps:
Validate kb-docs.json against contract/kb-docs.schema.json, vendored inside the action (the action is checked out at a ref, so the schema is always the one matching that ref, with no runtime fetch). Report every problem at once, naming the field and the fix, like the single-page action does.
Verify the built output: dist/<entryPoint> exists; every HTML file carries the headless attribute; no root-relative href/src/action; no <base>; every pages[].path exists; warn on inline <script> (the KB hoists them, but the repo should know). This absorbs and retires .github/workflows/validate-doc-app.yml.
Upload to the release with gh release upload --clobber, same fallback logic as the single-page action (triggering release → releases/latest → most recent release → fail with an actionable message).
A manifest may declare more than one app; then dist is a directory holding one subdirectory per slug. Single app + dist/ is just the common case.
Shared internals
Validation, packing, upload and notify are the same for both actions. Move them into actions/lib/ (manifest.js, verify-html.js, pack.js, release.js, notify.js) and have actions/publish-single-page-docs render markdown into the staging layout and then call the same library. A remote uses: checks out the whole repository, so a composite action may reference ${{ github.action_path }}/../lib. One pinned dependency tree in actions/package.json; the per-action package.json goes away.
actions/publish-single-page-docs changes accordingly: it emits kb-docs.json (kbVersion, apps[]) and kb-docs.tar.gz, and its bundle.json goes away. The composite input surface stays the same, plus the two notify inputs.
Versioning the actions
Consuming repos should pin @v1, not @master. Add a floating v1 tag (moved by a release workflow in this repo) and document that a breaking contract change means v2. The contract's kbVersion and the action's major version move together.
Self-test and CI
Extend the existing publish-single-page-docs self-test job into an actions job that runs both actions' self-tests: a sample packaged site fixture and a sample markdown set, both producing a tarball that the knowledge base build then consumes (prebuilt) so the two ends of the contract are exercised in one CI run. Parse all action.yml manifests as today (#39).
Scope
actions/lib/ with manifest validation, HTML verification, deterministic packing, release upload, repository_dispatch notify
actions/publish-single-page-docs refactored onto the library; emits the unified manifest and asset name
.github/workflows/validate-doc-app.yml deleted; contract/HEADLESS_RULES.md "Required: GitHub Release artifact" section rewritten around the action
v1 floating tag + a small release-actions.yml workflow that moves it on tag push
CI: both self-tests, plus a knowledge-base build consuming both outputs
Migrate AbsaOSS/knowledge-base-docs-example: marketplace.json → kb-docs.json, pack.yml reduced to build + uses: AbsaOSS/knowledge-base/actions/publish-docs@v1; scripts/pack.sh / pack.py keep the local --headless build but stop tarring; README.md updated. Publish a new release so the KB's optional sibling entry and the vendored fixture come from the real action.
Notes
The action never builds the site. Toolchains differ per repo; the contract is about the output.
Part of #73. Depends on #74.
Problem
Packaged docs repos assemble the release asset by hand.
AbsaOSS/knowledge-base-docs-example/.github/workflows/pack.ymlvalidates the manifest with an inline Python snippet, greps the HTML for the headless attribute, runstar -czf dist.tar.gz dist/ marketplace.jsonand uploads throughsoftprops/action-gh-release. Every new docs repo copies that file, and every contract change (the rename in #74, a new required field, a tightened check) has to be chased across N repositories by hand. The reusablevalidate-doc-app.ymlworkflow does not help: it assumesnpm run build -- --headless, which the Python example cannot run, and it is not what the example uses.Single-page docs already have this solved:
actions/publish-single-page-docsowns validation, packing and upload, and a consuming repo only passes inputs. Packaged sites need the same.Proposal
actions/publish-docsA composite action for repos that build their own headless site. The repo keeps its build (mkdocs, Starlight, anything); the action owns everything after it.
Steps:
kb-docs.jsonagainstcontract/kb-docs.schema.json, vendored inside the action (the action is checked out at a ref, so the schema is always the one matching that ref, with no runtime fetch). Report every problem at once, naming the field and the fix, like the single-page action does.dist/<entryPoint>exists; every HTML file carries the headless attribute; no root-relativehref/src/action; no<base>; everypages[].pathexists; warn on inline<script>(the KB hoists them, but the repo should know). This absorbs and retires.github/workflows/validate-doc-app.yml.kb-docs.tar.gzin the Contract v1: rename dist.tar.gz to kb-docs.tar.gz and unify marketplace.json + bundle.json into kb-docs.json #74 layout:kb-docs.jsonat the root,dist/renamed to<slug>/. Deterministic member order and mtimes so identical input produces identical bytes.gh release upload --clobber, same fallback logic as the single-page action (triggering release →releases/latest→ most recent release → fail with an actionable message).notify-repoandnotify-tokenset, firerepository_dispatchkb-docs-publishedat the deployment repo with{ repo, tag, slugs }as the payload, so Deployment: reusable build-image workflow, --strict registry mode, and the private deployment repo definition #78 can rebuild on publish. Skipped silently when unset.Outputs:
slugs,count,artifact,release-tag.A
manifestmay declare more than one app; thendistis a directory holding one subdirectory per slug. Single app +dist/is just the common case.Shared internals
Validation, packing, upload and notify are the same for both actions. Move them into
actions/lib/(manifest.js,verify-html.js,pack.js,release.js,notify.js) and haveactions/publish-single-page-docsrender markdown into the staging layout and then call the same library. A remoteuses:checks out the whole repository, so a composite action may reference${{ github.action_path }}/../lib. One pinned dependency tree inactions/package.json; the per-actionpackage.jsongoes away.actions/publish-single-page-docschanges accordingly: it emitskb-docs.json(kbVersion,apps[]) andkb-docs.tar.gz, and itsbundle.jsongoes away. The composite input surface stays the same, plus the two notify inputs.Versioning the actions
Consuming repos should pin
@v1, not@master. Add a floatingv1tag (moved by a release workflow in this repo) and document that a breaking contract change meansv2. The contract'skbVersionand the action's major version move together.Self-test and CI
Extend the existing
publish-single-page-docsself-test job into anactionsjob that runs both actions' self-tests: a sample packaged site fixture and a sample markdown set, both producing a tarball that the knowledge base build then consumes (prebuilt) so the two ends of the contract are exercised in one CI run. Parse allaction.ymlmanifests as today (#39).Scope
actions/lib/with manifest validation, HTML verification, deterministic packing, release upload,repository_dispatchnotifyactions/publish-docs/action.yml+src/index.js+README.mdactions/publish-single-page-docsrefactored onto the library; emits the unified manifest and asset name.github/workflows/validate-doc-app.ymldeleted;contract/HEADLESS_RULES.md"Required: GitHub Release artifact" section rewritten around the actionv1floating tag + a smallrelease-actions.ymlworkflow that moves it on tag pushAbsaOSS/knowledge-base-docs-example:marketplace.json→kb-docs.json,pack.ymlreduced to build +uses: AbsaOSS/knowledge-base/actions/publish-docs@v1;scripts/pack.sh/pack.pykeep the local--headlessbuild but stop tarring;README.mdupdated. Publish a new release so the KB'soptionalsibling entry and the vendored fixture come from the real action.Notes
env:, not${{ }}insiderun:blocks (Hardening: publish-single-page-docs interpolates step outputs directly into a run: block #55).