Skip to content

Allow module extensions to persist facts in the lockfile#26198

Closed
fmeum wants to merge 13 commits intobazelbuild:masterfrom
fmeum:24777-facts
Closed

Allow module extensions to persist facts in the lockfile#26198
fmeum wants to merge 13 commits intobazelbuild:masterfrom
fmeum:24777-facts

Conversation

@fmeum
Copy link
Copy Markdown
Collaborator

@fmeum fmeum commented May 31, 2025

RELNOTES[NEW]: Module extensions can store a JSON-like Starlark object in module_ctx.extension_metadata(facts = ...) and retrieve it back in future evaluations of the extension via module_ctx.facts without any invalidation taking place.

See bazel-contrib/rules_go#4393 for a real-world application of this new feature.

Fixes #24777

@fmeum fmeum force-pushed the 24777-facts branch 2 times, most recently from 0e22b0c to 4584973 Compare June 4, 2025 16:00
@fmeum fmeum force-pushed the 24777-facts branch 2 times, most recently from 5cb1682 to d68881c Compare June 12, 2025 15:49
@fmeum fmeum force-pushed the 24777-facts branch 6 times, most recently from 0acf750 to 00c53b2 Compare July 8, 2025 14:56
@fmeum fmeum changed the title WIP: Allow module extensions to persist facts in the lockfile Allow module extensions to persist facts in the lockfile Jul 8, 2025
@fmeum fmeum marked this pull request as ready for review July 8, 2025 15:55
@github-actions github-actions bot added team-ExternalDeps External dependency handling, remote repositiories, WORKSPACE file. awaiting-review PR is awaiting review from an assigned reviewer labels Jul 8, 2025
@fmeum
Copy link
Copy Markdown
Collaborator Author

fmeum commented Jul 8, 2025

I will add freeform docs after the first review round.

@fmeum
Copy link
Copy Markdown
Collaborator Author

fmeum commented Jul 8, 2025

@bazel-io fork 8.4.0

fmeum added a commit to bazel-contrib/rules_go that referenced this pull request Jul 8, 2025
**What type of PR is this?**

Feature

**What does this PR do? Why is it needed?**

This moves the download of the "all versions" JSON, which can't hit the
repository cache, from each individual `go_download_sdk` into the module
extension. If the current version of Bazel supports facts, this
information will also be persisted in the lockfile, allowing for truly
airgapped builds assuming an up-to-date download (formerly repository)
cache.

See bazelbuild/bazel#26198 for the PR that adds
facts support to Bazel.

**Which issues(s) does this PR fix?**

Fixes #3945 

**Other notes for review**
Copy link
Copy Markdown
Member

@meteorcloudy meteorcloudy left a comment

Choose a reason for hiding this comment

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

Looks great! But please wait also for @Wyverald 's review.

I have only one question about when old facts are going to be deleted so that the lockfile won't grow forever. IIUC, the module extension will always pass new facts via extension_metadata which should refresh the lockfile, right?

throw new SingleExtensionEvalFunctionException(
ExternalDepsException.withMessage(
Code.BAD_LOCKFILE,
"The module extension '%s' has changed its facts: %s != %s",
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.

Should we also recommend what the solution could be?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good point, done!

@fmeum
Copy link
Copy Markdown
Collaborator Author

fmeum commented Jul 9, 2025

I have only one question about when old facts are going to be deleted so that the lockfile won't grow forever. IIUC, the module extension will always pass new facts via extension_metadata which should refresh the lockfile, right?

I did miss this. I now added logic that deletes facts for extensions that are no longer used, mirroring what we already do for module extension entries.

@fmeum fmeum requested a review from meteorcloudy July 9, 2025 11:41
@fmeum
Copy link
Copy Markdown
Collaborator Author

fmeum commented Jul 21, 2025

@Wyverald Friendly ping

@aignas
Copy link
Copy Markdown

aignas commented Aug 21, 2025

Is there still any chance for this to make into the 8.4 release?

@thesayyn
Copy link
Copy Markdown
Contributor

thesayyn commented Sep 3, 2025

I'd benefit from this api immensely and would prevent me from inventing my own lock file for rules_distroless.

@fmeum
Copy link
Copy Markdown
Collaborator Author

fmeum commented Oct 7, 2025

@Wyverald Addressed the comments and also wrote some long-form docs

Copy link
Copy Markdown
Member

@Wyverald Wyverald left a comment

Choose a reason for hiding this comment

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

hmm, basically all shell integration tests started failing with some MODULE.bazel syntax error. Could you please take a look?

@fmeum fmeum requested a review from Wyverald October 10, 2025 20:00
Copy link
Copy Markdown
Member

@Wyverald Wyverald left a comment

Choose a reason for hiding this comment

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

looks like tests are going to pass this time. great!

@Wyverald Wyverald added awaiting-PR-merge PR has been approved by a reviewer and is ready to be merge internally and removed awaiting-review PR is awaiting review from an assigned reviewer labels Oct 10, 2025
@aignas
Copy link
Copy Markdown

aignas commented Oct 11, 2025

As a rule author I want to leverage this feature but I also want to support multiple version of bazel. What is the expectation of the behaviour here?

  • rules_python includes a lock file generated with bazel 8.5
  • The users setup detects the facts and automagically works on 8.5 without querying the internet.
  • The user updates to bazel 9
  • Are the facts persisted, or will we get network traffic, because rules_python extensions will be re-evaluated?

@fmeum
Copy link
Copy Markdown
Collaborator Author

fmeum commented Oct 11, 2025

Both 8.5.0 and current master will be on the same lockfile version after this change, so flags should be preserved between them. I haven't tested this yet, but that is the intended behavior.

@fmeum
Copy link
Copy Markdown
Collaborator Author

fmeum commented Oct 11, 2025

I think I misunderstood your setup: What does it mean for rules_python to include a lockfile generated by Bazel? Any MODULE.bazel.lock files in deps are currently ignored. Users would see network requests on the first fetch, with the results then persisted in their own lockfile.

@aignas
Copy link
Copy Markdown

aignas commented Oct 11, 2025

OK, thanks for confirming this.

@github-actions github-actions bot removed the awaiting-PR-merge PR has been approved by a reviewer and is ready to be merge internally label Oct 15, 2025
fmeum added a commit to fmeum/bazel that referenced this pull request Oct 16, 2025
RELNOTES[NEW]: Module extensions can store a JSON-like Starlark object in `module_ctx.extension_metadata(facts = ...)` and retrieve it back in future evaluations of the extension via `module_ctx.facts` without any invalidation taking place.

See bazel-contrib/rules_go#4393 for a real-world application of this new feature.

Fixes bazelbuild#24777

Closes bazelbuild#26198.

PiperOrigin-RevId: 819640644
Change-Id: I281503c9d4d0e60f46b57e9a231c3d2a4658d486
(cherry picked from commit 330dc9f)
fmeum added a commit to fmeum/bazel that referenced this pull request Oct 16, 2025
RELNOTES[NEW]: Module extensions can store a JSON-like Starlark object in `module_ctx.extension_metadata(facts = ...)` and retrieve it back in future evaluations of the extension via `module_ctx.facts` without any invalidation taking place.

See bazel-contrib/rules_go#4393 for a real-world application of this new feature.

Fixes bazelbuild#24777

Closes bazelbuild#26198.

PiperOrigin-RevId: 819640644
Change-Id: I281503c9d4d0e60f46b57e9a231c3d2a4658d486
(cherry picked from commit 330dc9f)
meteorcloudy pushed a commit that referenced this pull request Oct 16, 2025
)

RELNOTES[NEW]: Module extensions can store a JSON-like Starlark object
in `module_ctx.extension_metadata(facts = ...)` and retrieve it back in
future evaluations of the extension via `module_ctx.facts` without any
invalidation taking place.

See bazel-contrib/rules_go#4393 for a real-world
application of this new feature.

Fixes #24777

Closes #26198.

PiperOrigin-RevId: 819640644
Change-Id: I281503c9d4d0e60f46b57e9a231c3d2a4658d486 
(cherry picked from commit 330dc9f)
fmeum added a commit to fmeum/bazel that referenced this pull request Oct 18, 2025
RELNOTES[NEW]: Module extensions can store a JSON-like Starlark object in `module_ctx.extension_metadata(facts = ...)` and retrieve it back in future evaluations of the extension via `module_ctx.facts` without any invalidation taking place.

See bazel-contrib/rules_go#4393 for a real-world application of this new feature.

Fixes bazelbuild#24777

Closes bazelbuild#26198.

PiperOrigin-RevId: 819640644
Change-Id: I281503c9d4d0e60f46b57e9a231c3d2a4658d486
@fmeum fmeum deleted the 24777-facts branch October 23, 2025 09:55
fmeum added a commit to bazel-contrib/rules_go that referenced this pull request Nov 3, 2025
)

**What type of PR is this?**

Feature

**What does this PR do? Why is it needed?**

This moves the download of the "all versions" JSON, which can't hit the
repository cache, from each individual `go_download_sdk` into the module
extension. If the current version of Bazel supports facts, this
information will also be persisted in the lockfile, allowing for truly
airgapped builds assuming an up-to-date download (formerly repository)
cache.

This is a reland of #4393 with the following improvements:
* Adapted to the more limited facts API that actually got merged.
* Prefetching of SDK hashes is now performed on a best-effort basis so
that otherwise airgapped builds that provide SDK hashes do not result in
failures.

See bazelbuild/bazel#26198 for the PR that added
facts support to Bazel.

**Which issues(s) does this PR fix?**

Fixes #3945 

**Other notes for review**

You can verify that this works by running `bazel mod show_repo
@go_default_sdk` in the BCR test repo.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

team-ExternalDeps External dependency handling, remote repositiories, WORKSPACE file.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Persistent storage for module extension evaluation.

7 participants