Skip to content

feat: optimized py_image_layer#960

Open
thesayyn wants to merge 1 commit intomainfrom
claude/review-pr-942-gZbpc
Open

feat: optimized py_image_layer#960
thesayyn wants to merge 1 commit intomainfrom
claude/review-pr-942-gZbpc

Conversation

@thesayyn
Copy link
Copy Markdown
Member

@thesayyn thesayyn commented May 1, 2026

Optimized py_image_layer creation with maximal action sharing

Changes are visible to end-users: yes

  • Searched for relevant documentation and updated as needed: yes
  • Breaking change (forces users to change their own code or config): yes
  • Suggested release notes appear below: yes

New public api of py_image_layer is quite different than the previous one.

Test plan

  • Covered by existing test cases
  • New test cases added

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 1, 2026

CLA assistant check
All committers have signed the CLA.

@jbedard
Copy link
Copy Markdown
Member

jbedard commented May 1, 2026

Please dont spam like this lol 🙏

@thesayyn thesayyn force-pushed the claude/review-pr-942-gZbpc branch from 0fa9da8 to 46ea075 Compare May 1, 2026 21:27
@aspect-workflows
Copy link
Copy Markdown

aspect-workflows Bot commented May 1, 2026

Bazel 8 (Test)

All tests were cache hits

123 tests (100.0%) were fully cached saving 60s.


Bazel 9 (Test)

All tests were cache hits

122 tests (100.0%) were fully cached saving 1m 5s.


Bazel 8 (Test)

e2e

All tests were cache hits

67 tests (100.0%) were fully cached saving 1m 15s.


Bazel 9 (Test)

e2e

All tests were cache hits

60 tests (100.0%) were fully cached saving 1m 11s.


Bazel 8 (Test)

examples/uv_pip_compile

All tests were cache hits

1 test (100.0%) was fully cached saving 444ms.


Buildifier

@thesayyn thesayyn force-pushed the claude/review-pr-942-gZbpc branch from 276dde4 to 5f158ff Compare May 5, 2026 03:15
@thesayyn thesayyn changed the base branch from new_layering to main May 5, 2026 03:18
@thesayyn thesayyn marked this pull request as ready for review May 5, 2026 17:56
@thesayyn thesayyn changed the title Address PR #942 review comments + buildifier fix feat: optimized py_image_layer May 5, 2026
@thesayyn thesayyn requested review from jbedard and xangcastle May 5, 2026 17:59
Rewrite py_image_layer with analysis-time grouped OCI layers and
globally-shared pip tars via two propagated aspects:

- _layer_aspect propagates through deps/data/actual; pip per-package
  tars are declared at the pip target's namespace so they action-share
  across every rule using that package. First-party PyInfo targets
  matched by layer_tier.groups are captured for per-group tarring at
  the binary.
- _merge_aspect runs only on the binary, reads pip_packages closure,
  buckets install_dirs by merge_group, and emits one bsdtar action per
  group from raw install_dirs (single pass, no intermediates).

A new layer_tier rule carries grouping + compression as LayerTierInfo;
aspects read it via a //py:layer_tier label_flag so users can switch
tiers globally with --//py:layer_tier=//path:custom_tier or pin one
per rule via the layer_tier attr. A Python validation action surfaces
layer_tier(groups=...) suggestions when the squashed pip layer or
individual packages exceed thresholds, or the OCI 127-layer limit is
breached.

Sharing model:
- Solo whole-group + subpath-split pip tars: action-shared across
  every rule using that package (declared at the pip target's
  namespace).
- Multi-member merged tars: per-binary action, deterministic content
  (canonical mtree, fixed bsdtar options) so remote CAS / OCI registry
  dedupes by digest.
- First-party grouped tars: per-binary, one tar per group, collected
  from matched py_library targets in the binary's dep closure.
- Ungrouped pip packages: squashed by the rule into one per-rule tar.
- Optional dedicated interpreter layer when layer_tier.interpreter_group
  is set; the tar is declared at the py toolchain target's namespace
  so it action-shares across every py_image_layer using that toolchain
  config.

Other:
- normalize_label tolerates both Bazel 8 (`+`) and Bazel 9 (`~`)
  module-extension separators by anchoring on the stable `whl_install__`
  substring instead of the full prefix.
- Pull runfiles.repo_mapping_manifest into the binary's source layer
  and special-case its short_path so it lands at
  `./app.runfiles/_repo_mapping`.
- The validator binary uses rules_py's own py_binary rule (no
  @rules_python load needed at the BUILD level).
- Two container_structure_tests that exec the launcher are gated off
  on Bazel 9 — Bazel 9 stages bzlmod-canonical repo names in the
  runfiles tree, so the runfiles.bash bootstrap can't find
  `bazel_tools/tools/bash/runfiles/runfiles.bash` by apparent name.
  Same gate the existing listing tests use via
  `bazel_features.rules.merkle_cache_v2`.
@thesayyn thesayyn force-pushed the claude/review-pr-942-gZbpc branch from 8128424 to 2dca728 Compare May 5, 2026 18:00
@jbedard
Copy link
Copy Markdown
Member

jbedard commented May 5, 2026

@codex

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2dca728046

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +318 to +320
return [_LayerInfo(
source_files = depset(transitive = transitive_source),
pip_packages = depset(
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Drop pip transitive sources from the default layer

When a target has OutputGroupInfo.install_dir, it is already represented as a pip package layer via pip_packages, but this return still propagates transitive_source from its deps into the binary's default source layer. For pip targets whose internal deps expose the install tree, the same wheel files end up in both the dedicated pip tar and the default tar (the updated my_app_layers_listing.yaml shows the colorama install path in layer 0 and again in the default layer), which defeats the layer split and bloats images. These install-dir targets should stop forwarding source files, or otherwise filter those files before they reach info.source_files.

Useful? React with 👍 / 👎.

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