Skip to content

Let the generator build from a local, unpublished release zip, so a release can be link-checked before it ships #106

Description

@wmdietl

The Checker Framework's release scripts should be able to link-check the site
before a release is published, not after. Today they cannot, because the
generator can only build the site from releases that already exist on GitHub.
That is the one thing standing between us and a real pre-release gate; see
eisop/checker-framework#2111 for the other half.

Why this is small

The GitHub API is used only to discover the newest zip and its metadata. In
EisopSiteGenerator.main, the releases list comes from
https://api.github.com/repos/eisop/checker-framework/releases, and the
per-release loop then works entirely on a local file: it needs
LatestAssetsData.get("name") (the zip's filename, which carries the version)
and the downloaded zip itself. Everything downstream is local file manipulation
-- extract, lift docs/{examples,manual,tutorial} and docs/CHANGELOG.md to
the release root, move checker/dist/checker-javadoc.jar to api/ and unpack
it as api/checker-javadoc, copy tutorial/CFLogo.png up, then copy the newest
release's subtrees to cf/.

So the API is an input source, not a dependency threaded through the pipeline.

Wanted

1. --local-release <zip> -- substitute that file for the newest entry from
the releases API. The version and date come from the zip's filename and the run.
Everything else, including the archive list of previous releases, keeps using
the API.

2. --only-latest -- build just the newest release's folder and the cf/
top level, skipping the archive. A full run downloads 29 CF and 28 AFU zips,
roughly 890 MB; a pre-release gate that slow will not be run. This overlaps with
#105 section B, which is about not extracting what the site never serves anyway.

These compose with the dry_run input from #104:

flag means
--local-release this release does not exist on GitHub yet
dry_run do not commit the site
both full site, unpublished release as newest, written nowhere

The Checker Framework's release_build.py builds
checker-framework-<version>.zip into its interm directory (line 285) well
before release_push.py pushes anything, so that zip is exactly what gets
passed in. A failure aborts the release with no tag pushed, no GitHub release,
and no site touched.

Why not part of #104

#104 packages the templates and publishes the site from Actions. Its consumer is
the publish workflow; this feature's consumer is the Checker Framework's release
script, in another repository. #104 is worth merging on its own rather than
growing.

Worth knowing

  • The archive page stays API-driven, so cf/releases/releases.html lists one
    fewer release during a pre-release check. Harmless, but do not treat it as a
    bug.
  • AFU ordering. getAFU() reads the annotation-tools releases API, and the
    front page links the AFU zip. If AFU has not been released yet, the check
    reports a 404 that is expected. Either keep releasing AFU first, or allow a
    suppression for that one URL -- narrow, unlike the blanket
    checkerframework.org suppression the Checker Framework's link checker
    carries today, which silences a domain we do not publish to.
  • Both depths must be checked. The shipped front page is served as
    /cf/index.html and as /cf/<release>/index.html, and its links are mixed
    relative/absolute precisely because of that. Checking only one depth proves
    nothing about the other. The reasoning is in a comment at the top of
    docs/checker-framework-webpage.html in the Checker Framework repository.

Verifying

Serve the generator's output and check both depths, e.g.

python3 -m http.server 8000 --directory <gh-pages working copy> &
lychee http://localhost:8000/cf/index.html http://localhost:8000/cf/<release>/index.html

Because the local root is the site root, /cf/... and /afu/... resolve exactly
as they will live, and the zip download link works too -- the generator moves the
zip into cf/. That is what the Checker Framework's unused DEV_SITE_DIR was
reaching for.

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions