Skip to content

[ci] Render an upstream baseline copy of the spec in proposal repos - #2229

Merged
tlively merged 1 commit into
WebAssembly:mainfrom
kmiller68:upstream-baseline-ci
Sep 1, 2026
Merged

[ci] Render an upstream baseline copy of the spec in proposal repos#2229
tlively merged 1 commit into
WebAssembly:mainfrom
kmiller68:upstream-baseline-ci

Conversation

@kmiller68

Copy link
Copy Markdown
Contributor

Proposal repos are plain forks of WebAssembly/spec, so their published webassembly.github.io// site has no rendered copy of the unmodified spec to compare against. The proposals often also lag behind the upstream spec so a direct comparison between the rendered specs is full of false differences. A reviewer who wants to see what a proposal actually does to the spec text has to build upstream themselves, or read source diffs, which is particularly awkward for parts of the spec which are generated in the output. e.g. typeset rules, tables, appendices, etc.

With this change a fork also renders every document at the commit where it diverged from its parent repo, and publishes the result under webassembly.github.io//upstream with the same layout as the main site. This will allow us to link to W3C's spec diff service and view a formatted and searchable comparison with a single URL. e.g.

https://services.w3.org/htmldiff?doc1=https://webassembly.github.io//upstream/core/bikeshed/&doc2=https://webassembly.github.io//core/bikeshed/

The baseline is chosen by a new resolve-baseline job, which asks the gh API for the repository's parent, fetches the parent's main, and takes git merge-base. For most proposals which sync by merging upstream, this resolves to the most recent sync point. When running on WebAssembly/spec, a fork with no changes of its own, or when the parent cannot be determined / fetched, the job short-circuits and no upstream copy is generated.

The commit upstream was rendered from is recorded at /upstream/baseline-sha and compared on the next run. When the shas match, the upstream variant is dropped from the build matrix and the published copy is carried over instead of being rendered again. This saves a decent amount of CI time for most (non-downstreaming) commits.

@kmiller68

Copy link
Copy Markdown
Contributor Author

For help with reviewing here are two CI runs:

Published output from the two current runs:

After writing this I also realized that gh-pages is actually a git repo itself. So in theory there are historical renderings from the merge-base. That said, there are a few reasons I uploaded this anyway:

  1. https://raw.githubusercontent.com/WebAssembly/spec/dbde29a3e/js-api/index.html is served as text rather than html and services.w3.org won't process it.
  2. Historical builds of the spec could have different versions of rendering tools.
  3. Not every commit deploys so champions would have to find the most recent deployment when downstreaming.

@kmiller68

Copy link
Copy Markdown
Contributor Author

One other decision I made is to use FETCH_HEAD rather than hardcoding WebAssembly/spec as the upstream source. For most proposals these are the same but for ones dependent on another proposal they might depend on a different proposal. e.g. shared everything, which depends on threads (I assume anyway). I'm open to hardcoding WebAssembly/spec if folks think that's a better choice though.

@kmiller68

Copy link
Copy Markdown
Contributor Author

@rossberg @tlively Do either of you want to review this? it seems like you two have touch this file the most recently.

@tlively tlively left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! I will definitely use this.

Comment thread .github/workflows/ci-spec.yml Outdated
Comment on lines +339 to +345
mv _upstream/core-rendered-upstream _output/upstream/core
mv _upstream/js-api-rendered-upstream _output/upstream/js-api
mv _upstream/web-api-rendered-upstream _output/upstream/web-api
mv _upstream/code-metadata-rendered-upstream _output/upstream/metadata/code
mv _upstream/legacy-exceptions-core-rendered-upstream _output/upstream/legacy/exceptions/core
mv _upstream/legacy-exceptions-js-api-rendered-upstream _output/upstream/legacy/exceptions/js-api
mv _upstream/versions-rendered-upstream _output/upstream/versions

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid listing out all these directories so we can't accidentally forget to add new directories in the future?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a consequence of how the upload-artifact works. I changed it so each job stages it's build artifacts appropriately. Although that feels like something the Makefiles should be doing but those seem somewhat bit-rotted so it probably makes more sense to do that in a different PR.

Comment thread .github/workflows/ci-spec.yml Outdated
Comment on lines +68 to +69
published=$(gh api "repos/$REPOSITORY/contents/$BASELINE_STAMP?ref=gh-pages" \
--jq .content 2>/dev/null | base64 -d | tr -d '[:space:]') || published=''

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/kmiller68/spec/actions/runs/31828913256/job/94859702501 logs "base64: invalid input" here. Is that expected?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it probably should abort early. Fixed, I don't think it was harmful though.

@kmiller68
kmiller68 force-pushed the upstream-baseline-ci branch from 57538a8 to c6be319 Compare September 1, 2026 12:38
Proposal repos are plain forks of `WebAssembly/spec`, so their published
webassembly.github.io/<proposal>/ site has no rendered copy of the
unmodified spec to compare against. The proposals often also lag behind
the upstream spec so a direct comparison between the rendered specs is
full of false differences. A reviewer who wants to see what a proposal
actually does to the spec text has to build upstream themselves, or read
source diffs, which is particularly awkward for parts of the spec which
are generated in the output. e.g. typeset rules, tables, appendices, etc.

With this change a fork also renders every document at the commit where
it diverged from its parent repo, and publishes the result under
webassembly.github.io/<proposal>/upstream with the same layout as the
main site. This will allow us to link to W3C's spec diff service and
view a formatted and searchable comparison with a single URL. e.g.

https://services.w3.org/htmldiff?doc1=https://webassembly.github.io/<proposal>/upstream/core/bikeshed/&doc2=https://webassembly.github.io/<proposal>/core/bikeshed/

The baseline is chosen by a new resolve-baseline job, which asks the `gh`
API for the repository's parent, fetches the parent's main, and takes
`git merge-base`. For most proposals which sync by merging upstream,
this resolves to the most recent sync point. When running on
`WebAssembly/spec`, a fork with no changes of its own, or when the
parent cannot be determined / fetched, the job short-circuits and no
upstream copy is generated.

Each build job stages its render at the final path it occupies on the
site. This lets the publish job merge every artifact into one tree
instead of mapping each one to a destination. Adding a document no
longer requires touching the publish job. It feels like this should be
the Makefile's job but I'll leave that to another PR.

The commit upstream was rendered from is recorded at
/upstream/baseline-sha and compared on the next run. When the shas match,
the upstream variant is dropped from the build matrix and the published
copy is carried over instead of being rendered again. This saves a
decent amount of CI time for most (non-downstreaming) commits.
@kmiller68
kmiller68 force-pushed the upstream-baseline-ci branch from c6be319 to e1bbb24 Compare September 1, 2026 12:40

@rossberg rossberg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, that looks super useful, even though I can't pretend to understand the git fu.

(Would there be a way to also rewrite local links to send you to the respective file diff instead of a 503? Then it would work for the non-Bikeshed version.)

@kmiller68

Copy link
Copy Markdown
Contributor Author

CI runs for the latest PR:

# Scenario Run Result
1 No /upstream on the site yet 33130922877 17 jobs; both variants render; stamp written
2 Merge-base matches the stamp 33132330301 10 jobs; upstream variant dropped from the matrix; published copy carried over; stamp untouched
3 Merge-base moved 33134774643 17 jobs; re-rendered; stamp updated to the new sha

@kmiller68

Copy link
Copy Markdown
Contributor Author

(Would there be a way to also rewrite local links to send you to the respective file diff instead of a 503? Then it would work for the non-Bikeshed version.)

In theory yes, I think we'd want to do that globally though and have a webassembly.github.io/<proposal>/diff link for it.

@kmiller68

Copy link
Copy Markdown
Contributor Author

Actually for the multi-page version it might be kinda weird since this is just flowing through a diff tool. I think we'd end up with every link being a diff, which would drown the diff in noise. Links would probably have to be something the diff tool itself knows about. Maybe worth a feature request to https://github.com/w3c/htmldiff-ui once we know what we want.

@kmiller68

Copy link
Copy Markdown
Contributor Author

I don't think I have the power to merge so if someone could do it for me that would be appreciated.

@tlively
tlively merged commit 06272d1 into WebAssembly:main Sep 1, 2026
11 checks passed
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.

3 participants