Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(oci): apply system files and apt packages#10373

Merged
jdx merged 1 commit into
mainfrom
feat/oci-system-files
Jun 13, 2026
Merged

feat(oci): apply system files and apt packages#10373
jdx merged 1 commit into
mainfrom
feat/oci-system-files

Conversation

@jdx

@jdx jdx commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • bake project-scoped [system.files] into mise oci images as a dedicated annotated OCI layer
  • support project-scoped apt: [system.packages] natively by unpacking the base image into a temp rootfs, calling host apt-get against that rootfs, and emitting the filesystem diff as an OCI package layer
  • reconstruct apt rootfs inputs from gzip, zstd, or uncompressed OCI layers while applying OCI whiteouts, and emit whiteouts for package-layer deletions
  • keep --include-global behavior aligned with existing OCI scoping, and reject [system.defaults] for OCI images

Tests

  • cargo fmt
  • cargo check
  • cargo build
  • shellcheck e2e/oci/test_oci_build_slow
  • git diff --check
  • mise run test:e2e e2e/oci/test_oci_build_slow
  • live smoke: mise oci build --from debian:bookworm-slim --no-mise with [system.packages] "apt:hello" = "latest"

This PR was generated by an AI coding assistant.

Summary by CodeRabbit

  • New Features

    • OCI builds now include dedicated system file and apt-based system package layers; the builder accepts injected system files/packages.
  • Bug Fixes

    • Builds now fail early when unsupported [system.defaults] are present.
  • Documentation

    • Clarified OCI layer ordering, how system.files (copy/template/symlink) are materialized, ~/→/root/ mapping, apt-only package support, and that [system.defaults]/bootstrap aren’t executed.
  • Tests

    • Added e2e tests covering system.files materialization and apt-based package failure cases.

Note

Medium Risk
Adds a large apt-in-rootfs path that shells out to apt-get and mutates unpacked base filesystems; behavior depends on host tools and network for real Debian bases, though scope is limited to OCI image output rather than host system install.

Overview
mise oci build now applies declarative [system.files] and apt: [system.packages] from the same project-scoped config as tools (optional --include-global), parallel to mise bootstrap / mise system install but without running [system.defaults] or bootstrap tasks.

[system.files] become a separate annotated layer (dev.mise.system.files). Copy and template modes write real file content; symlink modes are materialized as contents so paths are not tied to the checkout. ~/ targets land under /root/.

[system.packages] (apt only for now) unpack base image layers into a temp rootfs (gzip/zstd/tar, with whiteout handling), run host apt-get / dpkg against that root, strip apt caches, diff before/after (including whiteouts for removals), and add one dev.mise.system.packages=apt layer. Non-apt managers and scratch without /etc/apt fail with clear errors.

The OCI builder and layer helpers gain with_system_*, build_layer_from_files_and_dirs, and metadata-preserving tar builds for package diffs. Docs and slow e2e cover file/template layers and the apt-on-scratch failure path.

Reviewed by Cursor Bugbot for commit c6ab69b. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds OCI build support for project-scoped [system.files] and apt-based [system.packages] by implementing package-layer and files-layer construction, wiring both into the OCI Builder and CLI (with config validation), refactoring config aggregation, updating deterministic layer emission, and adding tests and docs.

Changes

OCI system layers

Layer / File(s) Summary
System packages implementation
src/oci/mod.rs, src/oci/packages.rs
New oci::packages module implements apt-based package installation into a temp rootfs, snapshots before/after install, computes a filesystem diff, and builds an OCI package layer when changes exist.
System files implementation and Builder wiring
src/oci/builder.rs
Builder adds system_files and system_packages fields and with_* methods; build() inserts optional system-packages and system-files phases, writes layer blobs with annotations (dev.mise.system.packages=apt, dev.mise.system.files=true), and includes helpers to materialize FileRequest entries (collect sources, render templates, validate/normalize targets, compute modes).
Layer utilities: deterministic directory emission
src/oci/layer.rs
build_layer_from_files_and_dirs accepts an explicit dirs list and deterministically emits parent and directory entries before files, de-duplicating emissions.
System config aggregation helpers
src/system/files.rs, src/system/mod.rs
Extracted files_from_config_files and packages_from_config_files to aggregate across config maps (global→local ordering); render_template made public for reuse.
CLI validation and builder integration
src/cli/oci/common.rs
perform_build now rejects unsupported [system.defaults], aggregates system files/packages from the appropriate config-map set, and passes them into the Builder before building.
E2E tests and docs
e2e/oci/test_oci_build_slow, docs/dev-tools/mise-oci.md
Adds tests verifying [system.files] dedicated layer (copy + template rendering) and a negative test for packages on --from scratch; docs updated to describe new layer ordering, symlink/template handling, ~//root/ mapping, and limitations (apt-only, no [system.defaults]/bootstrap).

Sequence Diagram

sequenceDiagram
  participant CLI as OCI Build CLI
  participant Validator as reject_unsupported_system_defaults
  participant Aggregator as files_from_config_files / packages_from_config_files
  participant Builder as OCI Builder
  participant PackagesPhase as oci::packages::build_system_packages_layer
  participant FilesPhase as build_system_files_layer
  participant ImageLayout as ImageLayout

  CLI->>Validator: validate loaded configs
  Validator-->>CLI: error if `[system.defaults]` present
  CLI->>Aggregator: aggregate [system.files]/[system.packages]
  Aggregator-->>CLI: Vec<FileRequest>/Vec<ManagerPackages>
  CLI->>Builder: with_system_files(...) / with_system_packages(...)
  Builder->>PackagesPhase: build_system_packages_layer(layout, base_layers, managers, owner, arch)
  PackagesPhase->>ImageLayout: write package layer blob + annotation
  Builder->>FilesPhase: build_system_files_layer(requests, ...)
  FilesPhase->>ImageLayout: write files layer blob + annotation
  ImageLayout-->>Builder: layer descriptor/digest
Loading

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs:

  • jdx/mise#10365: Related work on declarative [system.files] support; this PR threads refactored aggregation and template visibility into OCI builder.
  • jdx/mise#10075: Modifies OCI layer-building APIs and tar ownership behavior used by this change.

"I nibble bytes and stitch each file,
Into a layer, tidy and compile.
Symlinks fixed and templates baked,
Paths placed under root, no link left naked.
A rabbit's patch — build snug and styled. 🐰"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(oci): apply system files and apt packages' clearly and directly summarizes the main changes: adding support for system files and apt packages in OCI image building.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread src/oci/builder.rs
@greptile-apps

greptile-apps Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR extends mise oci build to materialise declarative [system.files] entries (copy/template/symlink-each) and apt:-prefixed [system.packages] entries into dedicated OCI layers, and rejects [system.defaults] at build time. The apt path unpacks the pulled base image into a temporary rootfs, runs host apt-get with a custom Dir= configuration, diffs the filesystem, and emits the changes as a gzip layer.

  • src/oci/packages.rs (new): full apt rootfs unpack → install → diff → layer pipeline, including OCI whiteout handling and gzip/zstd/tar layer sniffing.
  • src/oci/builder.rs: adds with_system_files / with_system_packages builder methods and inserts system-package layer (step 3) and system-files layer (step 5) into the existing build sequence.
  • src/oci/layer.rs: adds build_layer_from_dir_preserve_metadata and build_layer_from_files_and_dirs; refactors collect_sorted_entries to carry per-entry owner so metadata-preserving paths work correctly.

Confidence Score: 4/5

Safe to merge for the common case (fresh apt install with no deletions); the whiteout parent-directory mode issue only manifests when apt removes files whose parent directory has non-default permissions.

The apt diff pipeline contains a correctness gap in write_whiteout/materialize_diff: parent directories are created with default umask mode, and when those directories are unchanged between snapshots they land in the package layer with wrong permissions. The primary install-only use case does not trigger this, but upgrade or conflict-resolution runs that delete files would silently corrupt directory modes.

src/oci/packages.rs — specifically write_whiteout and materialize_diff

Important Files Changed

Filename Overview
src/oci/packages.rs New file: implements apt-based package layer via host apt-get against an unpacked rootfs. Contains a correctness issue where whiteout helper creates parent dirs in diff_dir with default umask-derived mode, potentially overriding base-image directory permissions in the emitted layer.
src/oci/builder.rs Adds system-package and system-files layer slots (steps 3 and 5) into the existing build pipeline; layer sequencing and annotation logic looks correct.
src/oci/layer.rs Adds build_layer_from_dir_preserve_metadata and build_layer_from_files_and_dirs; adds owner per-Entry so metadata-preserving paths don't share the global owner. Logic is sound.
src/cli/oci/common.rs Adds reject_unsupported_system_defaults guard and wires system_files/system_packages into both the --include-global and project-scoped paths; logic is symmetric and correct.
src/system/files.rs Refactors files_from_config into files_from_config_files accepting a ConfigMap, and exposes render_template; clean split with no logic changes.
src/system/mod.rs Extracts packages_from_config_files helper analogous to the files refactor; logic is preserved correctly.
e2e/oci/test_oci_build_slow Adds e2e tests for system.files materialization and a failure-path test for apt on scratch; coverage looks appropriate.
docs/dev-tools/mise-oci.md Documentation updates accurately reflect new system.packages / system.files behavior and limitations.

Reviews (9): Last reviewed commit: "feat(oci): apply system config to images" | Re-trigger Greptile

Comment thread src/oci/builder.rs
Comment thread src/oci/builder.rs Outdated
Comment thread src/cli/oci/common.rs
Comment thread src/oci/builder.rs

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🧹 Nitpick comments (2)
docs/dev-tools/mise-oci.md (1)

208-227: ⚡ Quick win

Consider documenting the --include-global flag's effect on [system.files].

The documentation states that "project-scoped [system.files] entries" are baked (line 210), which is the default behavior. However, based on the implementation in src/cli/oci/common.rs (lines 52-73), the --include-global flag changes this scoping to include global config files as well.

Adding a sentence mentioning that --include-global opts into baking global [system.files] would help users understand the complete scoping behavior.

📝 Suggested addition

Consider adding after line 212:

By default, only project-scoped files are baked. Use `--include-global` to also include `[system.files]` from global configs.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/dev-tools/mise-oci.md` around lines 208 - 227, Update the docs section
that describes `[system.files]` in OCI images to mention the `--include-global`
flag: note that by default only project-scoped `[system.files]` entries are
baked into the image, and adding `--include-global` (as handled in
src/cli/oci/common.rs) opts into also including global `[system.files]` entries;
reference the flag name `--include-global` and the scope change so users know it
alters which config sources are baked.
e2e/oci/test_oci_build_slow (1)

103-124: ⚡ Quick win

Test coverage looks good; consider verifying copy mode content.

The test correctly verifies that the system files layer exists with the proper annotation, contains the expected file paths, and that template rendering works.

For more thorough coverage, you could also verify that the copy mode file contains the expected content, similar to how line 123 verifies the template output:

assert_contains "tar -xOzf ./out-files/blobs/sha256/$files_layer etc/profile.d/project.sh" "PROJECT_READY=1"

This would confirm that copy mode actually transfers file content, not just creates empty entries.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/oci/test_oci_build_slow` around lines 103 - 124, Add an assertion that
verifies the "copy" mode file actually contains the expected content: after
computing mf_files and files_layer (variables mf_files and files_layer), call
assert_contains with a tar -xOzf extraction of etc/profile.d/project.sh from
./out-files/blobs/sha256/$files_layer and check for "PROJECT_READY=1" (similar
to the existing template check for root/.config/app/config.toml) so the test
covers both template and copy modes using the existing assert_contains helper.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/cli/oci/common.rs`:
- Around line 117-131: The current gate only checks numeric counts (packages,
defaults) so present-but-empty system sections slip through; update the loop
over config_files to also track presence of any system section (e.g., a boolean
like has_system_section set when cf.system_config() is Some(_)), keep packages
and defaults counts for the error message, and change the conditional from if
packages > 0 || defaults > 0 to if has_system_section || packages > 0 ||
defaults > 0 so any declared [system] sections (even empty) are rejected;
reference variables: config_files, cf.system_config(), packages, defaults, and
the final if check.

In `@src/oci/builder.rs`:
- Around line 654-657: The WalkDir loop filters entries with
entry.file_type().is_file(), which silently drops symlinks; change the condition
to accept file OR symlink (e.g., entry.file_type().is_file() ||
entry.file_type().is_symlink()) when iterating
walkdir::WalkDir::new(&req.source).sort_by_file_name(); for entries that are
symlinks, call std::fs::read_link(entry.path()) to capture the link target and
emit a symlink entry into the OCI layer (preserve link target and metadata)
instead of trying to copy file contents, so symlinked files are materialized
consistently with src/system/files.rs.

---

Nitpick comments:
In `@docs/dev-tools/mise-oci.md`:
- Around line 208-227: Update the docs section that describes `[system.files]`
in OCI images to mention the `--include-global` flag: note that by default only
project-scoped `[system.files]` entries are baked into the image, and adding
`--include-global` (as handled in src/cli/oci/common.rs) opts into also
including global `[system.files]` entries; reference the flag name
`--include-global` and the scope change so users know it alters which config
sources are baked.

In `@e2e/oci/test_oci_build_slow`:
- Around line 103-124: Add an assertion that verifies the "copy" mode file
actually contains the expected content: after computing mf_files and files_layer
(variables mf_files and files_layer), call assert_contains with a tar -xOzf
extraction of etc/profile.d/project.sh from
./out-files/blobs/sha256/$files_layer and check for "PROJECT_READY=1" (similar
to the existing template check for root/.config/app/config.toml) so the test
covers both template and copy modes using the existing assert_contains helper.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3493c5c7-57c9-4cbc-b297-804d9d820c7a

📥 Commits

Reviewing files that changed from the base of the PR and between 5393223 and eb30f73.

📒 Files selected for processing (6)
  • docs/dev-tools/mise-oci.md
  • e2e/oci/test_oci_build_slow
  • src/cli/oci/common.rs
  • src/oci/builder.rs
  • src/oci/layer.rs
  • src/system/files.rs

Comment thread src/cli/oci/common.rs Outdated
Comment on lines +117 to +131
let mut packages = 0usize;
let mut defaults = 0usize;
for cf in config_files.values() {
let Some(system) = cf.system_config() else {
continue;
};
packages += system.packages.len();
defaults += system
.defaults
.values()
.map(|v| v.as_table().map_or(1, |t| t.len()))
.sum::<usize>();
}

if packages > 0 || defaults > 0 {

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Reject unsupported system sections by presence, not only non-zero entry counts.

Line 131 gates on packages > 0 || defaults > 0. Present-but-empty tables can leave both counts as zero, letting unsupported [system.packages] / [system.defaults] configs pass unexpectedly. Use section presence (is_empty) for the gate, and keep counts only for the error message.

Suggested patch
 fn reject_unsupported_system_config(config_files: &ConfigMap) -> Result<()> {
     let mut packages = 0usize;
     let mut defaults = 0usize;
+    let mut has_packages = false;
+    let mut has_defaults = false;
     for cf in config_files.values() {
         let Some(system) = cf.system_config() else {
             continue;
         };
+        has_packages |= !system.packages.is_empty();
+        has_defaults |= !system.defaults.is_empty();
         packages += system.packages.len();
         defaults += system
             .defaults
             .values()
             .map(|v| v.as_table().map_or(1, |t| t.len()))
             .sum::<usize>();
     }
 
-    if packages > 0 || defaults > 0 {
+    if has_packages || has_defaults {
         bail!(
             "mise oci does not yet support [system.packages] or [system.defaults] \
              (found {packages} package entrie(s), {defaults} default entrie(s)). \
              [system.files] entries are baked into the image; install OS packages \
              in the base image for now."
         );
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let mut packages = 0usize;
let mut defaults = 0usize;
for cf in config_files.values() {
let Some(system) = cf.system_config() else {
continue;
};
packages += system.packages.len();
defaults += system
.defaults
.values()
.map(|v| v.as_table().map_or(1, |t| t.len()))
.sum::<usize>();
}
if packages > 0 || defaults > 0 {
let mut packages = 0usize;
let mut defaults = 0usize;
let mut has_packages = false;
let mut has_defaults = false;
for cf in config_files.values() {
let Some(system) = cf.system_config() else {
continue;
};
has_packages |= !system.packages.is_empty();
has_defaults |= !system.defaults.is_empty();
packages += system.packages.len();
defaults += system
.defaults
.values()
.map(|v| v.as_table().map_or(1, |t| t.len()))
.sum::<usize>();
}
if has_packages || has_defaults {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cli/oci/common.rs` around lines 117 - 131, The current gate only checks
numeric counts (packages, defaults) so present-but-empty system sections slip
through; update the loop over config_files to also track presence of any system
section (e.g., a boolean like has_system_section set when cf.system_config() is
Some(_)), keep packages and defaults counts for the error message, and change
the conditional from if packages > 0 || defaults > 0 to if has_system_section ||
packages > 0 || defaults > 0 so any declared [system] sections (even empty) are
rejected; reference variables: config_files, cf.system_config(), packages,
defaults, and the final if check.

Comment thread src/oci/builder.rs
@github-actions

github-actions Bot commented Jun 13, 2026

Copy link
Copy Markdown

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.5 x -- echo 18.2 ± 0.7 17.2 23.5 1.00
mise x -- echo 19.0 ± 2.1 17.5 51.5 1.04 ± 0.12

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.5 env 18.0 ± 0.6 16.8 22.2 1.00
mise env 18.6 ± 0.7 17.5 23.7 1.03 ± 0.06

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.5 hook-env 18.8 ± 0.7 17.5 23.6 1.00
mise hook-env 19.4 ± 0.7 18.2 23.7 1.03 ± 0.05

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.5 ls 15.1 ± 0.6 13.9 19.3 1.00
mise ls 15.8 ± 0.7 14.6 20.3 1.04 ± 0.06

xtasks/test/perf

Command mise-2026.6.5 mise Variance
install (cached) 134ms 135ms +0%
ls (cached) 59ms 60ms -1%
bin-paths (cached) 64ms 65ms -1%
task-ls (cached) 125ms 129ms -3%

@jdx jdx force-pushed the feat/oci-system-files branch from eb30f73 to e162a8a Compare June 13, 2026 02:36
@jdx jdx changed the title feat(oci): bake system files into images feat(oci): apply system config to images Jun 13, 2026
@jdx jdx changed the title feat(oci): apply system config to images feat(oci): apply system files and apt packages Jun 13, 2026
Comment thread src/oci/builder.rs
Comment thread src/oci/packages.rs

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/oci/packages.rs`:
- Around line 122-131: The current unpack_base_layers function blindly
gunzip-unpacks each blob which misses non-gzip compressed layers and OCI
whiteout semantics; update unpack_base_layers (and related
ImageLayout/Descriptor handling) to detect and support the actual compression
(gzip, zstd, uncompressed) when creating the decoder, stream-extract the tar
content into rootfs while applying OCI whiteout rules (treat .wh.<name> as
delete, .wh..wh..opq as opaque directory that removes existing entries), and
ensure file deletions and directory metadata follow OCI diff semantics so the
reconstructed temp rootfs matches how the runtime would assemble base_layers.
- Around line 325-337: materialize_diff currently only copies entries from the
after snapshot and thus drops deletions; update materialize_diff to also iterate
the keys in before that are missing from after and emit OCI whiteouts into
diff_dir: for each removed file/path create a whiteout file named
".wh.<basename>" in the parent directory inside diff_dir, and for removed
directories emit the opaque marker ".wh..wh..opq" in the parent directory as
appropriate; use existing helpers (snapshot, same_entry, copy_entry) and ensure
the whiteout files are created with create_dir_all and appropriate metadata so
the produced layer correctly represents deletions and directory opaqueness when
applied.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b4fb629e-a9f1-4361-a7a5-6d5ec07ca406

📥 Commits

Reviewing files that changed from the base of the PR and between eb30f73 and e162a8a.

📒 Files selected for processing (9)
  • docs/dev-tools/mise-oci.md
  • e2e/oci/test_oci_build_slow
  • src/cli/oci/common.rs
  • src/oci/builder.rs
  • src/oci/layer.rs
  • src/oci/mod.rs
  • src/oci/packages.rs
  • src/system/files.rs
  • src/system/mod.rs
✅ Files skipped from review due to trivial changes (2)
  • src/oci/mod.rs
  • docs/dev-tools/mise-oci.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/system/files.rs
  • src/cli/oci/common.rs
  • src/oci/layer.rs

Comment thread src/oci/packages.rs Outdated
Comment thread src/oci/packages.rs
@jdx jdx force-pushed the feat/oci-system-files branch 2 times, most recently from d6b857d to 45302bd Compare June 13, 2026 03:09

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (1)
src/oci/packages.rs (1)

504-512: 💤 Low value

Add error context for symlink creation.

If symlink() fails, the error message won't indicate which path was being processed. This makes debugging harder when package installation creates many symlinks.

🔧 Suggested improvement
         FsEntryKind::Symlink { target } => {
             #[cfg(unix)]
-            symlink(target, &dst)?;
+            symlink(target, &dst)
+                .wrap_err_with(|| format!("creating symlink {} -> {}", dst.display(), target.display()))?;
             #[cfg(not(unix))]
             {
                 let _ = target;
                 bail!("OCI apt package layers with symlinks require a unix host");
             }
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/oci/packages.rs` around lines 504 - 512, When creating symlinks in the
FsEntryKind::Symlink { target } arm, wrap the symlink(...) call so any I/O error
is annotated with context including the destination and target paths (e.g., use
anyhow::Context or map_err to attach a message referencing dst and target)
instead of propagating the raw error; update the symlink(target, &dst)? usage to
symlink(target, &dst).with_context(|| format!("failed to create symlink {:?} ->
{:?}", &dst, &target))? (or equivalent) so failures identify which path was
being processed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/oci/packages.rs`:
- Around line 504-512: When creating symlinks in the FsEntryKind::Symlink {
target } arm, wrap the symlink(...) call so any I/O error is annotated with
context including the destination and target paths (e.g., use anyhow::Context or
map_err to attach a message referencing dst and target) instead of propagating
the raw error; update the symlink(target, &dst)? usage to symlink(target,
&dst).with_context(|| format!("failed to create symlink {:?} -> {:?}", &dst,
&target))? (or equivalent) so failures identify which path was being processed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 56eeff56-7f4e-457d-b722-2be50038f3a1

📥 Commits

Reviewing files that changed from the base of the PR and between d6b857d and 45302bd.

📒 Files selected for processing (9)
  • docs/dev-tools/mise-oci.md
  • e2e/oci/test_oci_build_slow
  • src/cli/oci/common.rs
  • src/oci/builder.rs
  • src/oci/layer.rs
  • src/oci/mod.rs
  • src/oci/packages.rs
  • src/system/files.rs
  • src/system/mod.rs
✅ Files skipped from review due to trivial changes (1)
  • docs/dev-tools/mise-oci.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/system/mod.rs
  • src/oci/layer.rs
  • e2e/oci/test_oci_build_slow
  • src/system/files.rs
  • src/cli/oci/common.rs
  • src/oci/builder.rs

@jdx jdx force-pushed the feat/oci-system-files branch from 45302bd to cabe154 Compare June 13, 2026 03:20
Comment thread src/oci/builder.rs Outdated

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@e2e/oci/test_oci_build_slow`:
- Around line 108-124: The test is flaky because it relies on ambient MISE_ENV
while asserting "tool=dev"; make it hermetic by setting MISE_ENV explicitly for
the test run or by rendering a fixed value into the template: ensure the
invocation that renders the template sets MISE_ENV=dev (or change the template
line tool={{env.MISE_ENV | default(value="dev")}} to emit a literal "dev") so
the assertion that checks for "tool=dev" (and the template source reference
app.tmpl / mise.toml render) will always match; update the test to export/inline
MISE_ENV=dev before the template rendering or change the template to a static
value so assertions remain stable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f6cac2e5-72e8-4159-ac19-d7a4cd2bb1ab

📥 Commits

Reviewing files that changed from the base of the PR and between 45302bd and cabe154.

📒 Files selected for processing (9)
  • docs/dev-tools/mise-oci.md
  • e2e/oci/test_oci_build_slow
  • src/cli/oci/common.rs
  • src/oci/builder.rs
  • src/oci/layer.rs
  • src/oci/mod.rs
  • src/oci/packages.rs
  • src/system/files.rs
  • src/system/mod.rs
✅ Files skipped from review due to trivial changes (1)
  • docs/dev-tools/mise-oci.md
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/oci/mod.rs
  • src/system/mod.rs
  • src/oci/layer.rs
  • src/cli/oci/common.rs
  • src/system/files.rs
  • src/oci/builder.rs
  • src/oci/packages.rs

Comment thread e2e/oci/test_oci_build_slow
Comment thread src/oci/packages.rs
@jdx jdx force-pushed the feat/oci-system-files branch 2 times, most recently from 249feb4 to 46b6139 Compare June 13, 2026 03:37
Comment thread src/oci/packages.rs Outdated
@jdx jdx force-pushed the feat/oci-system-files branch from 46b6139 to c797b62 Compare June 13, 2026 03:48
Comment thread src/oci/packages.rs
@jdx jdx force-pushed the feat/oci-system-files branch from c797b62 to 7b5bb1d Compare June 13, 2026 03:54
Comment thread src/oci/packages.rs Outdated
@jdx jdx force-pushed the feat/oci-system-files branch from 7b5bb1d to 4ded72a Compare June 13, 2026 04:01
Comment thread src/oci/packages.rs Outdated
@jdx jdx force-pushed the feat/oci-system-files branch from 4ded72a to 5565b91 Compare June 13, 2026 04:06
Comment thread src/oci/builder.rs Outdated
@jdx jdx force-pushed the feat/oci-system-files branch from 5565b91 to 1fd2519 Compare June 13, 2026 04:10

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1fd2519. Configure here.

Comment thread src/oci/layer.rs Outdated
@jdx jdx force-pushed the feat/oci-system-files branch from 1fd2519 to e0b1e01 Compare June 13, 2026 04:14
@jdx jdx force-pushed the feat/oci-system-files branch from e0b1e01 to c6ab69b Compare June 13, 2026 04:21
@jdx jdx enabled auto-merge (squash) June 13, 2026 04:32
@jdx jdx merged commit 3f2ae78 into main Jun 13, 2026
35 checks passed
@jdx jdx deleted the feat/oci-system-files branch June 13, 2026 04:37
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.

1 participant