diff --git a/SimLoop/PUBLISHING.md b/SimLoop/PUBLISHING.md index fe2455b..81c6fcf 100644 --- a/SimLoop/PUBLISHING.md +++ b/SimLoop/PUBLISHING.md @@ -59,9 +59,10 @@ except where a row says it was overtaken. | `EnvelopeGuardrails` guardrail names | `withinBound`, `loopTimeUnderBudget` and `safeStopAtEnd` now embed their thresholds in `Guardrail.name()`. Any persisted last-best score from an earlier version will read as a different envelope in `Gate` and must be re-baselined. Non-finite and negative thresholds are now rejected at construction. | | `RunResult.fromRlog` | `RealOutputs/Console` and `RealOutputs/Logger/QueuedCycles` are no longer scoreable, so `keys()` and `frames()` no longer contain them. | -`SimLoop/build.gradle` declares the source version. Installation snippets, the starter, agent guides -and the site footer repeat it. Review all current-version references during a release; keep references -to older tags where they explain compatibility or historical checks. +`SimLoop/build.gradle` declares the source version. The documentation footer is populated from +that value by the `docsSite` Gradle task; it is not repeated in `mkdocs.yml`. Installation snippets, +the starter and agent guides may still contain current-version references. Review those during a release, +and keep references to older tags where they explain compatibility or historical checks. ## Cutting a release @@ -70,10 +71,11 @@ to older tags where they explain compatibility or historical checks. and read by people and agents who have nothing else, so a missing unit is a release defect there in a way it is not in an IDE. 2. **Update the approved version** in `SimLoop/build.gradle` and its current-version references. - Search the root and module READMEs, `SimLoop/docs/`, `SimLoop/mkdocs.yml`, `simloop-starter/` and - `simloop-agents/`. Review each match rather than replacing historical tags blindly. Run - `./gradlew :SimLoop:docsSite`; its version check verifies the footer, and its example check verifies - the first-test snippet. These checks do not replace reviewing installation coordinates. + Search the root and module READMEs, `SimLoop/docs/`, `simloop-starter/` and `simloop-agents/`. + Review each match rather than replacing historical tags blindly. Run + `./gradlew :SimLoop:docsSite`; the generated pages take their footer version directly from Gradle, + and the example check verifies the first-test snippet. These checks do not replace reviewing + installation coordinates. 3. **Verify the artifact locally before anyone can consume it** — the section below says how, and it is the part people skip. 4. **Commit, tag, push the tag.** The tag is the version, e.g. `v0.2.0-alpha.1`. diff --git a/SimLoop/build.gradle b/SimLoop/build.gradle index f9b1b37..9e8b42e 100644 --- a/SimLoop/build.gradle +++ b/SimLoop/build.gradle @@ -374,24 +374,10 @@ tasks.named('check') { // Three tasks rather than one, because each of the three can fail for its own reason and a reader // chasing a red build should be told which one it was. -// Fails if the version in mkdocs.yml and the version in this file have drifted apart. They are not -// linked - `copyright:` in mkdocs.yml is what stamps the footer of every page - and a site claiming one -// version while the jar beside it is another is worse than a site with no version on it at all. The file -// is read while this build script is configured, not while the task runs, so the check survives Gradle's -// configuration cache. -def mkdocsConfigText = file('mkdocs.yml').text -def declaredVersion = project.version.toString() -tasks.register('checkDocsVersion') { - group = 'documentation' - description = 'Fails if mkdocs.yml stamps a different version than this build does.' - doLast { - if (!mkdocsConfigText.contains(declaredVersion)) { - throw new GradleException("mkdocs.yml never mentions version " + declaredVersion - + ", so every page would stamp the wrong one in its footer. Bump the `copyright:` " - + "line in this module's mkdocs.yml to match `version` in its build.gradle.") - } - } -} +// Pass the module's authoritative version to MkDocs. Its !ENV YAML tag resolves the footer +// at build time, so mkdocs.yml never needs a second copy of the release version. +def docsCopyright = "SimLoop ${project.version} · Horizon (FTC 36596) · BSD-3-Clause" + tasks.register('checkDocExamples', Exec) { group = 'documentation' @@ -405,9 +391,10 @@ tasks.register('mkdocsBuild', Exec) { group = 'documentation' description = 'Renders the markdown pages. Needs, in this directory: pip install -r docs-requirements.txt' - dependsOn 'checkDocsVersion', 'checkDocExamples' + dependsOn 'checkDocExamples' workingDir projectDir + environment 'SIMLOOP_DOCS_COPYRIGHT', docsCopyright commandLine 'python', '-m', 'mkdocs', 'build', '-f', 'mkdocs.yml', '--strict' doFirst { diff --git a/SimLoop/mkdocs.yml b/SimLoop/mkdocs.yml index f7a5568..7be7ec2 100644 --- a/SimLoop/mkdocs.yml +++ b/SimLoop/mkdocs.yml @@ -31,12 +31,8 @@ docs_dir: docs # site is never committed by accident. site_dir: build/docs/site -# The version stamp, shown in the footer of every page so a reader always knows what they are looking at. -# -# This is a SECOND place the version is written; `SimLoop/build.gradle` is the authoritative one. They are -# not linked yet, so PUBLISHING.md's release checklist lists this file as a place to bump. Wiring the two -# together is a build change and belongs with the rest of the site build. -copyright: "SimLoop 0.2.0-alpha.2 · Horizon (FTC 36596) · BSD-3-Clause" +# The footer comes from the version in SimLoop/build.gradle, passed by the docsSite Gradle task. +copyright: !ENV SIMLOOP_DOCS_COPYRIGHT theme: name: material