Skip to content

fix: require Dylint and repair core cache hydration#996

Merged
zackees merged 1 commit into
mainfrom
fix/994-995-dylint-core-cache
Jul 7, 2026
Merged

fix: require Dylint and repair core cache hydration#996
zackees merged 1 commit into
mainfrom
fix/994-995-dylint-core-cache

Conversation

@zackees

@zackees zackees commented Jul 7, 2026

Copy link
Copy Markdown
Member

Summary

  • Enabled and verified Dylint as a strict required status check for main via branch protection, without adding Dylint to ./lint.
  • Documented the separate Dylint gate in .github/workflows/dylint.yml so local lint stays rustfmt + clippy only.
  • Made framework core artifact cache keys independent of project checkout basename/path by adding a project-normalized artifact-cache signature path.
  • Hydrate cached core .o/.d payloads while regenerating destination .cmdhash files from the hydrating project's compiler signature.

Validation

  • GitHub branch protection: required_status_checks.strict=true, contexts=[Dylint], checks=[{context:Dylint, app_id:15368}]; repository rulesets remain empty.
  • git diff --check
  • uv run --no-project python ci/render_workflows.py --check
  • Docker helper image rebuilt locally from the ~/dev/soldr fast-rebuild pattern with soldr 0.8.0, Rust/Cargo 1.94.1, persistent /target, Cargo, Rustup, and soldr cache volumes.
  • docker exec -w /src clud-docker-build-soldr-ee1b6073b8ae soldr --version -> soldr 0.8.0
  • docker exec -w /src clud-docker-build-soldr-ee1b6073b8ae sh -lc 'SOLDR_COMPILE_REPLY_TIMEOUT_SECS=180 soldr cargo test -p fbuild-build framework_core_cache -- --nocapture'
  • docker exec -w /src clud-docker-build-soldr-ee1b6073b8ae sh -lc 'SOLDR_COMPILE_REPLY_TIMEOUT_SECS=180 soldr cargo test -p fbuild-build test_artifact_cache_signature_ignores_project_directory_name -- --nocapture'
  • docker exec -w /src clud-docker-build-soldr-ee1b6073b8ae sh -lc 'SOLDR_COMPILE_REPLY_TIMEOUT_SECS=180 soldr cargo test -p fbuild-build rebuild_signature_matches_write_path_with_unflags -- --nocapture'
  • docker exec -w /src clud-docker-build-soldr-ee1b6073b8ae sh -lc 'soldr cargo fmt --all -- --check'
  • docker exec -w /src clud-docker-build-soldr-ee1b6073b8ae sh -lc 'SOLDR_COMPILE_REPLY_TIMEOUT_SECS=180 soldr cargo clippy -p fbuild-build --all-targets -- -D warnings'

Notes

Closes #994.
Closes #995.

Summary by CodeRabbit

  • New Features

    • Improved build caching so cached artifacts can be reused more reliably across different project folder names and checkout paths.
  • Bug Fixes

    • Fixed cache key generation to better match the active toolchain, source type, and project-specific flags.
    • Updated framework cache hydration to refresh build metadata after copying cached objects, reducing unnecessary rebuilds.
    • Improved compiler handling for multiple embedded targets to keep cache behavior consistent during rebuilds.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a project-independent artifact_cache_signature method to the Compiler trait and its ch32v/esp32/renesas implementations, refactors signature hashing with a pluggable path normalizer, updates FrameworkCoreCache key computation and hydrate to refresh cmdhash files using the compiler, wires the new hydrate signature through orchestrator/pipeline call sites, and updates Dylint workflow comments.

Changes

Artifact cache signature and core cache hydrate refresh

Layer / File(s) Summary
Shared signature normalization helper
crates/fbuild-build/src/compiler.rs, crates/fbuild-build/src/compiler_tests.rs
Adds Compiler::artifact_cache_signature, refactors build_rebuild_signature into a normalizer-based helper, adds build_rebuild_signature_for_project and normalize_signature_value_for_project, and tests project-directory-name independence.
Per-chip signature implementations
crates/fbuild-build/src/ch32v/ch32v_compiler.rs, crates/fbuild-build/src/esp32/esp32_compiler.rs, crates/fbuild-build/src/renesas/renesas_compiler.rs
Adds artifact_cache_signature to Ch32v, Esp32, and Renesas compilers, selecting C/C++ flags and appending framework-specific suppression flags.
Core cache key uses new signature
crates/fbuild-build/src/framework_core_cache.rs
Updates core_cache_key to normalize absolute source paths and call artifact_cache_signature(project_dir, ...); updates tests to pass project_dir and adds a project-directory-independence test.
Hydrate refreshes cmdhash
crates/fbuild-build/src/framework_core_cache.rs
Rewrites hydrate to accept compiler/sources/flags, refactors copy_artifacts into ArtifactCopyOutcome with include_cmdhash, and adds refresh_command_hashes.
Wire hydrate call sites
crates/fbuild-build/src/esp32/orchestrator/build.rs, crates/fbuild-build/src/pipeline/sequential.rs
Updates orchestrator and sequential pipeline hydrate calls to pass compiler, sources, and overlay.

Dylint workflow comments

Layer / File(s) Summary
Comment clarifications
.github/workflows/dylint.yml
Updates header and retry-loop comments explaining required-status-check rationale and toolchain-alias retry logic; no logic changes.

Estimated code review effort: 4 (Complex) | ~50 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SequentialPipeline
  participant Esp32Orchestrator
  participant FrameworkCoreCache
  participant Compiler
  SequentialPipeline->>FrameworkCoreCache: hydrate(core_build_dir, compiler, core_and_variant sources, user_overlay)
  Esp32Orchestrator->>FrameworkCoreCache: hydrate(core_build_dir, compiler, all_core_sources, user_overlay)
  FrameworkCoreCache->>FrameworkCoreCache: copy_artifacts(include_cmdhash=false)
  FrameworkCoreCache->>Compiler: artifact_cache_signature(project_dir, source, extra_flags)
  Compiler-->>FrameworkCoreCache: signature
  FrameworkCoreCache->>FrameworkCoreCache: refresh_command_hashes(copied_objects)
Loading

Possibly related PRs

  • FastLED/fbuild#965: Introduces the path_arg_for_compile_cwd helper that the new artifact_cache_signature/project normalization path depends on for checkout-stable signatures.
  • FastLED/fbuild#975: Also modifies compiler.rs signature hashing to consistently handle build_unflags() across the shared build_rebuild_signature* logic and related compiler overrides.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive The cache-hydration changes appear to satisfy #995, but the exact required-Dylint branch-protection setup for #994 isn't visible here, so full compliance can't be verified. Provide the branch-protection or ruleset evidence for the exact Dylint required check, and confirm the outcome is linked back to #939 and #992.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly names the two main changes: Dylint enforcement and core-cache hydration repair.
Out of Scope Changes check ✅ Passed The diff stays within Dylint workflow commentary and core-cache/artifact-hydration fixes, with no unrelated changes apparent.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/994-995-dylint-core-cache

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (2)
crates/fbuild-build/src/compiler.rs (1)

527-536: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Minor duplication between the two normalizer functions.

normalize_signature_value_for_project repeats the empty/absolute-path checks from normalize_signature_value before diverging only in the "under project_dir" branch. Could be collapsed into one function parameterized by an optional project_dir, but not urgent.

Also applies to: 538-557

🤖 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 `@crates/fbuild-build/src/compiler.rs` around lines 527 - 536, The two
signature normalizer paths duplicate the same empty-string and absolute-path
checks, so refactor the logic in normalize_signature_value and
normalize_signature_value_for_project to share a single common flow. Keep the
existing behavior, but extract the shared pre-checks into one helper or
parameterize normalize_signature_value with an optional project_dir so the
project-specific branch only handles the under-project-dir case.
crates/fbuild-build/src/ch32v/ch32v_compiler.rs (1)

228-264: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Extract shared flag-selection/suppression logic to avoid 3-way drift.

artifact_cache_signature duplicates the extension dispatch and framework-suppression-flag augmentation already in rebuild_signature (Lines 194-226), which itself must already mirror compile_one's suppression logic per the comment above it. That's now 3 call sites (compile_one, rebuild_signature, artifact_cache_signature) that must be kept manually in sync per chip file, and the pattern is repeated identically across ch32v/esp32/renesas compilers — 6 places total.

Consider extracting a helper like fn signature_inputs(&self, source, extra_flags) -> (&Path, Vec<String>, Vec<String>) returning (compiler_path, flags, effective_extra), then have both rebuild_signature and artifact_cache_signature call it and just pick the builder function.

♻️ Sketch of a shared helper
+    fn signature_inputs(&self, source: &Path, extra_flags: &[String]) -> (&Path, Vec<String>, Vec<String>) {
+        let ext = source
+            .extension()
+            .unwrap_or_default()
+            .to_string_lossy()
+            .to_lowercase();
+        let (compiler_path, flags) = match ext.as_str() {
+            "c" | "s" => (self.gcc_path(), self.c_flags()),
+            _ => (self.gxx_path(), self.cpp_flags()),
+        };
+        let extra_owned: Vec<String> = if self.is_framework_source(source) {
+            extra_flags
+                .iter()
+                .cloned()
+                .chain(framework_suppression_flags().iter().map(|s| (*s).to_string()))
+                .collect()
+        } else {
+            extra_flags.to_vec()
+        };
+        (compiler_path, flags, extra_owned)
+    }
+
     fn rebuild_signature(&self, source: &Path, extra_flags: &[String]) -> String {
-        // ...duplicated logic...
+        let (compiler_path, flags, extra_owned) = self.signature_inputs(source, extra_flags);
         crate::compiler::build_rebuild_signature(compiler_path, &flags, &[], &extra_owned, self.build_unflags())
     }
 
     fn artifact_cache_signature(&self, project_dir: &Path, source: &Path, extra_flags: &[String]) -> String {
-        // ...duplicated logic...
+        let (compiler_path, flags, extra_owned) = self.signature_inputs(source, extra_flags);
         crate::compiler::build_rebuild_signature_for_project(project_dir, compiler_path, &flags, &[], &extra_owned, self.build_unflags())
     }
🤖 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 `@crates/fbuild-build/src/ch32v/ch32v_compiler.rs` around lines 228 - 264,
`artifact_cache_signature` repeats the compiler/flag selection and
framework-suppression augmentation already handled in `rebuild_signature`, which
can drift from `compile_one`. Extract the shared logic into a helper on
`Ch32vCompiler` (for example, a signature-input builder) that returns the
compiler path, base flags, and effective extra flags for a source, then have
both `rebuild_signature` and `artifact_cache_signature` call it so the extension
dispatch and framework suppression stay consistent across these paths.
🤖 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 `@crates/fbuild-build/src/ch32v/ch32v_compiler.rs`:
- Around line 228-264: `artifact_cache_signature` repeats the compiler/flag
selection and framework-suppression augmentation already handled in
`rebuild_signature`, which can drift from `compile_one`. Extract the shared
logic into a helper on `Ch32vCompiler` (for example, a signature-input builder)
that returns the compiler path, base flags, and effective extra flags for a
source, then have both `rebuild_signature` and `artifact_cache_signature` call
it so the extension dispatch and framework suppression stay consistent across
these paths.

In `@crates/fbuild-build/src/compiler.rs`:
- Around line 527-536: The two signature normalizer paths duplicate the same
empty-string and absolute-path checks, so refactor the logic in
normalize_signature_value and normalize_signature_value_for_project to share a
single common flow. Keep the existing behavior, but extract the shared
pre-checks into one helper or parameterize normalize_signature_value with an
optional project_dir so the project-specific branch only handles the
under-project-dir case.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ef97e0b7-7d4b-4a1e-9b01-1d38c1b72993

📥 Commits

Reviewing files that changed from the base of the PR and between 56990d0 and b9ab581.

📒 Files selected for processing (9)
  • .github/workflows/dylint.yml
  • crates/fbuild-build/src/ch32v/ch32v_compiler.rs
  • crates/fbuild-build/src/compiler.rs
  • crates/fbuild-build/src/compiler_tests.rs
  • crates/fbuild-build/src/esp32/esp32_compiler.rs
  • crates/fbuild-build/src/esp32/orchestrator/build.rs
  • crates/fbuild-build/src/framework_core_cache.rs
  • crates/fbuild-build/src/pipeline/sequential.rs
  • crates/fbuild-build/src/renesas/renesas_compiler.rs

@zackees
zackees merged commit 74ae4d5 into main Jul 7, 2026
90 of 93 checks passed
@fastled-project-sync fastled-project-sync Bot moved this to Triage in FastLED Tracker Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

perf(build): decide fate of core-cache-hydrate after fw-libs zccache fix ci(dylint): decide and enforce Dylint as a required status check

1 participant