Skip to content

ISLE verifier: update GitHub cache from publish-artifacts workflow as well. - #15083

Merged
alexcrichton merged 1 commit into
bytecodealliance:mainfrom
cfallin:isle-veri-cache-s3
Nov 3, 2026
Merged

alexcrichton merged 1 commit into
bytecodealliance:mainfrom
cfallin:isle-veri-cache-s3

Conversation

@cfallin

@cfallin cfallin commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

We previously had a workflow where we published the updated cache only from CI runs in main.yml, but because of branch scoping combined with our use of the merge queue, runs on "main" actually ran on a merge-queue temporary branch and thus did not update the cache contents in a location available for other runs. The main-scoped content was updated only by our once-per-night full CI run on main.

This commit updates publish-artifacts.yml to add a job to the flow that does run on main, after merge, on every merge: it fetches the artifact from the build we just did and publishes it to the GitHub cache. This way, cache updates from all changes that are merged will be immediately available to subsequent CI runs.

@cfallin
cfallin requested review from a team as code owners October 29, 2026 23:45
@cfallin
cfallin requested review from fitzgen and removed request for a team October 29, 2026 23:45
@cfallin

cfallin commented Oct 29, 2026

Copy link
Copy Markdown
Member Author

(I've created the appropriate secrets in this repo pointing to the S3 bucket that I created for testing -- let's see if this works!)

@github-actions github-actions Bot added cranelift Issues related to the Cranelift code generator isle Related to the ISLE domain-specific language labels Oct 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Subscribe to Label Action

cc @avanhatt, @cfallin, @fitzgen, @mmcloughlin

Details This issue or pull request has been labeled: "cranelift", "isle"

Thus the following users have been cc'd because of the following labels:

  • avanhatt: isle
  • cfallin: isle
  • fitzgen: isle
  • mmcloughlin: isle

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

Comment thread .github/workflows/main.yml Outdated
runs-on: ubuntu-latest
# Keep the two copies of this condition (here and in the verify step) in
# sync.
environment: ${{ ((github.event_name == 'merge_group' && github.event.merge_group.base_ref == 'refs/heads/main') || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main')) && 'isle-veri-cache-writer' || '' }}

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.

Could this unconditionally set the environment key? My assumption is that PRs already don't get access to secrets, even if this is set

@bjorn3 bjorn3 Oct 30, 2026 •

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.

  1. You can restrict which workflows and branches can access an environment. Setting the environment here unconditionally means that wouldn't be possible as defense in depth.
  2. Each time a workflow runs, this causes an entry in https://github.com/bytecodealliance/wasmtime/deployments and in addition, an event is added to the PR that caused the environment saying that it deployed to the environment. So each time you add a new commit to a PR you did get a rather noisy event that is way bigger than a commit event and persists after force pushes.
noise caused by setting an environment on PR CI

(the PR I took this from has over 30 such events, taking up over half of the total scroll space)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I don't understand much about GitHub environments beyond what I briefly read yesterday, but I did believe that this rule was necessary to ensure that secrets would not leak to PRs; and even if technically not with current scoping rules, I'd prefer to have defense-in-depth.

Reading the page in settings, I see: "They are not passed to workflows that are triggered by a pull request from a fork." That seems to imply (by omission) that secrets are present for PRs from branches within the main repo. I don't want to grant access to the secrets to anyone who has collaborator access on their own unreviewed PRs, so I do think we need an explicit condition here (or at least, that's my reading!).

What do you think?

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.

That seems to imply (by omission) that secrets are present for PRs from branches within the main repo.

I believe so yeah.

so I do think we need an explicit condition here (or at least, that's my reading!).

Yes and you will have to restrict the environment to the main branch (+ branch protection to prevent direct pushes) to prevent a contributor from just modifying the workflow to use the environment on their branch.

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.

PRs from other repos will never get secrets, and by default no new branches are allowed in the Wasmtime repo. In that sense there's no real chance of leakage AFAIK. We've had a PERSONAL_ACCESS_TOKEN secret for quite some time, not in an environment, and that's arguably much more important to protect than access to the s3 bucket.

If the environment were unconditionally configured here then my understanding is we'd go edit the environment settings to conditionally have access to the secret on some branches but not others. Why wouldn't that work to scope this? (or, alternatively, just remove environment here since it may not play well with our repo configuration)

Comment thread .github/workflows/main.yml Outdated
# (anonymous access) otherwise.
AWS_ACCESS_KEY_ID: ${{ secrets.ISLE_VERI_CACHE_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.ISLE_VERI_CACHE_AWS_SECRET_ACCESS_KEY }}
CACHE_MODE: ${{ ((github.event_name == 'merge_group' && github.event.merge_group.base_ref == 'refs/heads/main') || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main')) && 'read-write' || 'read-only' }}

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.

Could CACHE_MODE be inferred based on the presence/absence of the access key and secret access key?

Comment thread cranelift/isle/veri/caching/src/s3.rs Outdated

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.

This file in general is pretty intense -- could this perhaps shell out to the AWS CLI which I believe is installed on github runners instead?

@cfallin cfallin Oct 30, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Sure, I can take a look at this next week! My intent was to make this usable for developers running client-side too, for what it's worth, where I would not necessarily want to require them to install the AWS SDK. With the public-readonly ACL on the bucket, the idea is that folks could let the tool download the cache when the run locally and it should Just Work.

The other options, if not the external CLI tool, seemed to be either a little 400-line handwritten (err, robot-written) S3 client with just the methods we need, or the full AWS Rust SDK (and vet it + deps). I couldn't think of a secret fourth option.

What do you think?

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.

That's the part for me basically, I don't really want an unreviewed S3 client LLM-authored here, and I'd prefer to not have to review it myself. Could aws be used when available and maybe curl when it's not?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

So my thinking on this is: the S3 actions we need are more than just "get a single file with a known name", so curl is not going to lead to a simpler end-state: we will effectively need to write an AWS client still, except instead of using ureq to access the endpoint, we are shelling out to a subprocess with the right verb/URI/request headers/signature/etc and then parsing the result just the same.

Concretely for example: parts of s3.rs implement (i) XML parsing of the result of a list-object request; (ii) request signing, which requires an AWS-specific algorithm and inserts a custom header with the signature, for authorization; (iii) all the setup of other request details for each kind of action. Very little of the file is base-level HTTP stuff that curl would handle, and curl used to implement any cache usage or update (usage requires list-objects) would need all of the above. So we'd have "an S3 client but with more steps".

IMHO if we want to minimize custom logic that we carry ourselves, the right answer is probably to use a real S3 client crate. I haven't quantified exactly what the vetting burden of that is but that'd be the cost, vs. reviewing this code here (or equivalent code that does all the same things but generating curl commandlines). That's probably a better long-term direction if we hope to use S3 from other build infra though, now that I write it out...

Alternately, we redesign the cache so it really is still "a single file" and then decouple all uses of S3 to separate actions run in CI to download and upload; but then we lose the incremental-update benefit, and I think that's important here (otherwise we amplify our S3 PUT cost by ~20x compared to this compact-every-20-times approach, and PUTs are the expensive actions). I imagine that other kinds of caching we might want to do will probably want fine-grained hit/miss/update capabilities rather than "single giant blob we monolithically rebuild" so it seems better to me to push in the direction (i.e. figure out our S3 client approach) of enabling in-band S3 API access from whatever build tools, rather than making all our tooling use a local filesystem than snapshotting the whole thing at the end. At least that's the hypothesis of this PR.

What do you think?

@alexcrichton

Copy link
Copy Markdown
Member

I'll also note that ideally we'd leverage S3-based caching (or just something external) for much more than just ISLE, for example integrating sccache, caching docker images, etc. IMO we should probably replace basically all usage of actions/cache with something that uses S3 instead

…as well.

We previously had a workflow where we published the updated cache only
from CI runs in `main.yml`, but because of branch scoping combined
with our use of the merge queue, runs on "`main`" actually ran on a
merge-queue temporary branch and thus did not update the cache
contents in a location available for other runs. The `main`-scoped
content was updated only by our once-per-night full CI run on `main`.

This commit updates `publish-artifacts.yml` to add a job to the flow
that *does* run on `main`, *after* merge, on every merge: it fetches
the artifact from the build we just did and publishes it to the GitHub
cache. This way, cache updates from all changes that are merged will
be immediately available to subsequent CI runs.
@cfallin
cfallin force-pushed the isle-veri-cache-s3 branch from d21db3b to 8201057 Compare November 3, 2026 23:02
@cfallin

cfallin commented Nov 3, 2026

Copy link
Copy Markdown
Member Author

I talked with @alexcrichton just now and we came upon a much simpler idea: we can solve the proximate issue (once-per-night frequency of updates to cached ISLE verification state) in a much simpler way by moving where the GitHub cache update happens into the on-every-merge publish-artifacts workflow.

We can still potentially use S3 for other caching actions, but it's probably more complexity than we want to accept for now.

I just force-pushed away the S3-related changes here (and will update title/description) and made the yaml-only change; @alexcrichton let me know what you think!

@cfallin cfallin changed the title ISLE verifier cache: rewrite to use an S3 bucket. ISLE verifier: update GitHub cache from publish-artifacts workflow as well. Nov 3, 2026
@alexcrichton
alexcrichton added this pull request to the merge queue Nov 3, 2026
Merged via the queue into bytecodealliance:main with commit d0202d6 Nov 3, 2026
52 checks passed
@alexcrichton

Copy link
Copy Markdown
Member

The full check job in the merge queue failed to restore the cache but the merge queue saved the cache with the key that failed lookup. I believe this is due to #14896 landing since last night when the cache was rebuilt so... I think it's all working?

@cfallin
cfallin deleted the isle-veri-cache-s3 branch November 4, 2026 00:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cranelift Issues related to the Cranelift code generator isle Related to the ISLE domain-specific language

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants