Skip to content

Conversation

@UdjinM6
Copy link

@UdjinM6 UdjinM6 commented Dec 17, 2025

Issue being fixed or feature implemented

Add ctcache to cache clang-tidy analysis results, reducing time spent in "Run linters" step from 33-34 minutes to 3-4 minutes in the best case scenarios.

What was done?

  • Download ctcache in contrib/containers/ci/ci.Dockerfile and patch it to work correctly
  • Add new steps in .github/workflows/build-src.yml to save/restore ctcache cache (for linux64_multiprocess, save on pushes to default branch only)
  • Adjust ci/dash/lint-tidy.sh to configure ctcache, force run-clang-tidy to use it
  • Add manual cache cleanup in ci/dash/lint-tidy.sh since ctcache doesn't have a way to set internal limits like ccache does

How Has This Been Tested?

Run, check "Run linters" step in linux64_multiprocess-build job.
develop, no ctcache: 31m 43s
develop*, empty cache: 0% hits, 33m 19s
develop*, second run, using cache: 100% hits, 3m 27s
New branch*, merged #6947 (chainlock, evo): 96.5% hits, 5m 13s
New branch*, merged #7056 (chainlock, instantsend, llmq, etc): 59.3%, 19m 50s
New branch*, merged #7005 (wallet, utils): 40.9% hits, 25m 49s

* with this patch merged into develop

Breaking Changes

n/a

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation
  • I have assigned this pull request to a milestone (for repository code-owners and collaborators only)

@UdjinM6 UdjinM6 added this to the 23.1 milestone Dec 17, 2025
@github-actions
Copy link

github-actions bot commented Dec 17, 2025

✅ No Merge Conflicts Detected

This PR currently has no conflicts with other open PRs.

@coderabbitai
Copy link

coderabbitai bot commented Dec 17, 2025

Walkthrough

Adds ctcache support for caching clang-tidy results in CI. The workflow (.github/workflows/build-src.yml) restores and saves a ctcache cache on linux64_multiprocess runs (save only on pushes to the default branch). ci/dash/lint-tidy.sh initializes and validates ctcache and clang-tidy, zeroes and reports per-run ctcache stats, invokes clang-tidy via a ctcache wrapper, enforces size/age-based cleanup, and expands iwyu_tool.py inputs. contrib/containers/ci/ci.Dockerfile fetches ctcache helpers at a pinned commit and creates /cache/ctcache. ci/test/00_setup_env.sh adds CTCACHE_DIR and CTCACHE_MAXSIZE_MB defaults.

Sequence Diagram(s)

mermaid
sequenceDiagram
autonumber
participant GH as GitHub Actions
participant Runner as CI Runner
participant Cache as Actions Cache
participant Script as lint-tidy.sh
participant CTWrap as ctcache wrapper
Note over GH,Runner: Workflow conditioned on linux64_multiprocess
GH->>Cache: Restore ctcache (conditional)
GH->>Runner: start lint job
Runner->>Script: execute lint-tidy.sh
Script->>Script: export CTCACHE_DIR/CTCACHE_MAXSIZE_MB; ensure /cache/ctcache exists
Script->>Script: validate clang-tidy in PATH and ctcache helpers
Script->>CTWrap: invoke clang-tidy via -clang-tidy-binary (ctcache wrapper)
CTWrap-->>Script: cached or fresh lint output
Script->>Script: zero per-run stats; tee output to tmp.tidy-out.txt
Script->>Script: show ctcache stats; report cache size
Script->>Script: cleanup_ctcache (age + size pruning)
Runner->>Cache: Save ctcache (conditional; only on default-branch push)

mermaid
sequenceDiagram
autonumber
participant DockerBuild as Dockerfile build
participant GitRemote as Remote repo (pinned commit)
participant Image as CI image
DockerBuild->>GitRemote: fetch ctcache scripts at pinned commit
DockerBuild->>DockerBuild: apply sed edits; chmod +x launcher
DockerBuild->>Image: create /cache/ctcache directory in final layer

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • .github/workflows/build-src.yml: verify conditional expressions for restore/save, cache key composition, and default-branch save guard.
  • ci/dash/lint-tidy.sh: review ctcache initialization/validation, wrapper invocation (-clang-tidy-binary usage), zeroing/stats reporting, cleanup_ctcache logic (7-day deletion + oldest ~20% pruning), and expanded iwyu_tool.py invocation.
  • contrib/containers/ci/ci.Dockerfile: confirm pinned commit reference, sed edits to helper, launcher permissions, and /cache/ctcache creation.
  • ci/test/00_setup_env.sh: confirm CTCACHE_DIR and CTCACHE_MAXSIZE_MB defaults and interactions with existing CACHE_DIR.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: integrating ctcache for clang-tidy result caching in CI, which aligns with the changeset's primary objective and file modifications.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining the feature being implemented, changes made, testing results, and lack of breaking changes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c310c7 and 040ac27.

📒 Files selected for processing (1)
  • contrib/containers/ci/ci.Dockerfile (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • contrib/containers/ci/ci.Dockerfile
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: arm-linux-gnueabihf / Build depends
  • GitHub Check: x86_64-apple-darwin / Build depends
  • GitHub Check: x86_64-w64-mingw32 / Build depends
  • GitHub Check: x86_64-pc-linux-gnu / Build depends
  • GitHub Check: x86_64-pc-linux-gnu_multiprocess / Build depends
  • GitHub Check: x86_64-pc-linux-gnu_nowallet / Build depends
  • GitHub Check: Lint / Run linters

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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
ci/dash/lint-tidy.sh (1)

26-26: LGTM with observation on hardcoded path.

The clang-tidy invocation correctly uses the ctcache wrapper via -clang-tidy-binary=/usr/local/bin/clang-tidy-cache. The hardcoded path matches the Dockerfile installation, but consider whether this should be more flexible (e.g., using a variable or which command).

If you want to make the path more maintainable, consider:

+CLANG_TIDY_CACHE="/usr/local/bin/clang-tidy-cache"
+
 cd "${BASE_ROOT_DIR}/build-ci/dashcore-${BUILD_TARGET}/src"

-if ! ( run-clang-tidy -clang-tidy-binary=/usr/local/bin/clang-tidy-cache -quiet "${MAKEJOBS}" | tee tmp.tidy-out.txt ); then
+if ! ( run-clang-tidy -clang-tidy-binary="${CLANG_TIDY_CACHE}" -quiet "${MAKEJOBS}" | tee tmp.tidy-out.txt ); then
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea73b83 and 9d434ce.

📒 Files selected for processing (3)
  • .github/workflows/build-src.yml (2 hunks)
  • ci/dash/lint-tidy.sh (1 hunks)
  • contrib/containers/ci/ci.Dockerfile (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
{guix-build*,releases,**/guix-build*,releases/**,.github/**,depends/**,ci/**,contrib/**,doc/**}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not make changes to build system files (guix-build*), release artifacts, or avoid changes to .github, depends, ci, contrib, and doc directories unless specifically prompted

Files:

  • ci/dash/lint-tidy.sh
  • .github/workflows/build-src.yml
  • contrib/containers/ci/ci.Dockerfile
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: arm-linux-gnueabihf / Build depends
  • GitHub Check: x86_64-apple-darwin / Build depends
  • GitHub Check: x86_64-pc-linux-gnu_nowallet / Build depends
  • GitHub Check: x86_64-pc-linux-gnu / Build depends
  • GitHub Check: x86_64-pc-linux-gnu_multiprocess / Build depends
  • GitHub Check: x86_64-w64-mingw32 / Build depends
  • GitHub Check: Lint / Run linters
🔇 Additional comments (9)
.github/workflows/build-src.yml (2)

114-123: LGTM!

The ctcache restore logic is correctly structured, following the same pattern as ccache. The cache key incorporates the Dockerfile and dependencies hashes to ensure proper invalidation when the build environment changes, and the restore-keys allow efficient cache reuse across commits.


132-142: LGTM!

The ctcache save step correctly restricts cache persistence to pushes on the default branch, preventing cache pollution from PR branches. The path and key structure are consistent with the restore step.

contrib/containers/ci/ci.Dockerfile (2)

83-89: LGTM!

The ctcache directory is created consistently with the existing cache directory structure, and ownership is properly assigned to the non-privileged user.


68-81: The pinned commit and patches are still necessary.

The Dockerfile correctly pins ctcache to commit e33c063ca6e52b48bcefbc45d46d8c150ffa81ca and applies two necessary patches:

  1. Line 77-78: Fixes return shlex.split(command["arguments"][0]) to return the list directly, since command["arguments"] is already a list
  2. Line 79-80: Changes digest format from {i:x} to {i:02x} for zero-padded hex formatting

Both patches remain necessary—the upstream code in both the pinned commit and main branch still contains the unpatched code. No fixes have been integrated upstream as of the commit date (2025-09-02). The pinning strategy is appropriate given these unresolved issues.

ci/dash/lint-tidy.sh (5)

14-19: LGTM!

The ctcache environment setup correctly exports the necessary variables, and the cache directory path is consistent with the workflow configuration and Dockerfile. The mkdir -p safely handles the case where the directory already exists.


21-22: LGTM with minor observation.

The zero-stats call correctly resets statistics before the run. The || true prevents script failure if the statistics feature is unavailable, which is appropriate for a non-critical operation.


32-36: LGTM!

The ctcache statistics display provides useful diagnostics with appropriate error handling. The combination of du -sh and --show-stats gives both size and hit rate information.


53-53: LGTM!

The divider line properly closes the ctcache statistics section, maintaining clean output formatting.


37-52: Add defensive checks for cache size retrieval.

The cache management logic is generally sound, but if du -sm fails (e.g., permissions issue, directory not found), CACHE_SIZE_MB will be empty, causing the comparison on Line 40 to fail silently. This could allow unbounded cache growth.

Apply this diff to add defensive checks:

 # Limit cache size (ctcache has no built-in size management)
 CTCACHE_MAXSIZE_MB=50
 CACHE_SIZE_MB=$(du -sm "${CTCACHE_DIR}" 2>/dev/null | cut -f1)
+if [ -z "${CACHE_SIZE_MB}" ]; then
+  echo "Warning: Unable to determine cache size, skipping cleanup"
+  CACHE_SIZE_MB=0
+fi
 if [ "${CACHE_SIZE_MB}" -gt "${CTCACHE_MAXSIZE_MB}" ]; then
   echo "Cache size ${CACHE_SIZE_MB}MB exceeds limit ${CTCACHE_MAXSIZE_MB}MB, cleaning old entries..."
   # Remove files older than 7 days, or if still too large, oldest 20% of files
   find "${CTCACHE_DIR}" -type f -mtime +7 -delete 2>/dev/null || true
   CACHE_SIZE_MB=$(du -sm "${CTCACHE_DIR}" 2>/dev/null | cut -f1)
+  if [ -z "${CACHE_SIZE_MB}" ]; then
+    CACHE_SIZE_MB=0
+  fi
   if [ "${CACHE_SIZE_MB}" -gt "${CTCACHE_MAXSIZE_MB}" ]; then

Likely an incorrect or invalid review comment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
ci/dash/lint-tidy.sh (3)

14-19: Consider verifying clang-tidy availability explicitly.

The which clang-tidy command will cause the script to exit (due to set -e) if clang-tidy is not in PATH, but without a clear error message. While the fail-fast behavior is acceptable for CI, consider adding an explicit check with a descriptive error message for easier debugging.

Example improvement:

+# Verify clang-tidy is available
+if ! command -v clang-tidy >/dev/null 2>&1; then
+  echo "Error: clang-tidy not found in PATH"
+  exit 1
+fi
+
 # Setup ctcache for clang-tidy result caching
 export CTCACHE_DIR="/cache/ctcache"
 export CTCACHE_SAVE_OUTPUT=1
 CTCACHE_CLANG_TIDY=$(which clang-tidy)
 export CTCACHE_CLANG_TIDY
 mkdir -p "${CTCACHE_DIR}"

21-25: Verify ctcache installation before use.

The hardcoded paths to ctcache binaries are not verified before use. If ctcache is not properly installed (e.g., missing from the Docker image), the script will fail at Line 29 with an unclear error when run-clang-tidy cannot find the binary.

Add verification:

 CLANG_TIDY_CACHE="/usr/local/bin/clang-tidy-cache"
 CLANG_TIDY_CACHE_PY="/usr/local/bin/src/ctcache/clang_tidy_cache.py"
+
+# Verify ctcache is installed
+if [ ! -x "${CLANG_TIDY_CACHE}" ]; then
+  echo "Error: ctcache binary not found at ${CLANG_TIDY_CACHE}"
+  exit 1
+fi
+if [ ! -f "${CLANG_TIDY_CACHE_PY}" ]; then
+  echo "Warning: ctcache Python script not found at ${CLANG_TIDY_CACHE_PY}, statistics will be unavailable"
+fi
 
 # Zero stats before run to get accurate statistics for this run only
 python3 "${CLANG_TIDY_CACHE_PY}" --zero-stats 2>&1 || true

49-52: Consider using null-terminated strings for maximum robustness.

The current file removal pipeline works correctly, but using null-terminated strings would be more robust against unusual filenames (newlines, etc.) and is a best practice for shell scripts processing file paths.

Optional improvement:

     FILE_COUNT=$(find "${CTCACHE_DIR}" -type f | wc -l)
     REMOVE_COUNT=$((FILE_COUNT / 5))
-    find "${CTCACHE_DIR}" -type f -printf '%T+ %p\n' | sort | head -n "${REMOVE_COUNT}" | cut -d' ' -f2- | xargs rm -f 2>/dev/null || true
+    find "${CTCACHE_DIR}" -type f -printf '%T+ %p\0' | sort -z | head -z -n "${REMOVE_COUNT}" | cut -z -d' ' -f2- | xargs -0 rm -f 2>/dev/null || true
     echo "Removed ${REMOVE_COUNT} oldest cache entries"

Note: This uses null-terminated strings throughout the pipeline for safer file path handling.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9d434ce and e176501.

📒 Files selected for processing (1)
  • ci/dash/lint-tidy.sh (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
{guix-build*,releases,**/guix-build*,releases/**,.github/**,depends/**,ci/**,contrib/**,doc/**}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not make changes to build system files (guix-build*), release artifacts, or avoid changes to .github, depends, ci, contrib, and doc directories unless specifically prompted

Files:

  • ci/dash/lint-tidy.sh
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: win64-build / Build source
  • GitHub Check: mac-build / Build source
  • GitHub Check: linux64_tsan-build / Build source
  • GitHub Check: arm-linux-build / Build source
  • GitHub Check: linux64-build / Build source
  • GitHub Check: linux64_ubsan-build / Build source
  • GitHub Check: linux64_sqlite-build / Build source
  • GitHub Check: linux64_fuzz-build / Build source
  • GitHub Check: linux64_nowallet-build / Build source
  • GitHub Check: Lint / Run linters
🔇 Additional comments (4)
ci/dash/lint-tidy.sh (4)

29-29: LGTM: ctcache integration in run-clang-tidy.

The modification correctly integrates ctcache by using the -clang-tidy-binary flag while preserving the existing error handling and output capture logic.


35-38: LGTM: Statistics display.

The statistics display provides useful debugging information and correctly handles potential failures with fallback messages.


40-55: Note: GNU find dependency.

The cache cleanup logic uses find -printf, which is specific to GNU findutils and may not work on BSD systems. Since this script runs in a controlled Docker CI environment (likely GNU/Linux), this is acceptable. However, if portability becomes a concern, consider using find -exec stat as an alternative.

The cleanup logic assumes GNU find. Verify that the CI Docker image uses GNU coreutils:

#!/bin/bash
# Verify GNU find is available in the CI environment
# Expected: GNU find is installed and -printf is supported

# Check if we can inspect the Dockerfile
if [ -f "contrib/containers/ci/ci.Dockerfile" ]; then
  echo "=== Checking CI Dockerfile for base image ==="
  grep -E "^FROM" contrib/containers/ci/ci.Dockerfile
  echo ""
fi

# Check if there's documentation about the CI environment
echo "=== Checking for CI documentation ==="
fd -t f "README" ci/ contrib/containers/ 2>/dev/null | head -5

42-43: Add safety check for cache size calculation.

If the cache directory doesn't exist or du fails, CACHE_SIZE_MB will be an empty string, causing the integer comparison at Line 43 to fail with "integer expression expected" error.

Apply this diff to add a safety check:

 # Limit cache size (ctcache has no built-in size management)
 CTCACHE_MAXSIZE_MB=50
 CACHE_SIZE_MB=$(du -sm "${CTCACHE_DIR}" 2>/dev/null | cut -f1)
+# Default to 0 if du fails or returns empty
+CACHE_SIZE_MB=${CACHE_SIZE_MB:-0}
 if [ "${CACHE_SIZE_MB}" -gt "${CTCACHE_MAXSIZE_MB}" ]; then

Likely an incorrect or invalid review comment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
ci/dash/lint-tidy.sh (1)

20-25: Consider using command -v for consistency.

Line 23 uses which clang-tidy while line 15 uses command -v clang-tidy. For consistency and modern shell best practices, consider using command -v here as well.

Apply this diff to improve consistency:

-CTCACHE_CLANG_TIDY=$(which clang-tidy)
+CTCACHE_CLANG_TIDY=$(command -v clang-tidy)
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e176501 and f9d5ccce4b84ec1d206a664ce0471bf73269cbfb.

📒 Files selected for processing (1)
  • ci/dash/lint-tidy.sh (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
{guix-build*,releases,**/guix-build*,releases/**,.github/**,depends/**,ci/**,contrib/**,doc/**}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not make changes to build system files (guix-build*), release artifacts, or avoid changes to .github, depends, ci, contrib, and doc directories unless specifically prompted

Files:

  • ci/dash/lint-tidy.sh
🔇 Additional comments (4)
ci/dash/lint-tidy.sh (4)

14-18: LGTM!

The clang-tidy availability check is correctly implemented using command -v with proper error handling.


27-38: LGTM!

The ctcache path definitions and validation checks are properly implemented with appropriate error handling.


40-41: LGTM!

Appropriate use of || true to prevent stats initialization failures from blocking the build.


45-45: LGTM!

The clang-tidy invocation correctly uses the ctcache binary while preserving existing flags and parallel execution.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
ci/dash/lint-tidy.sh (1)

64-67: Optional: File-count-based cleanup may not optimize cache size.

The cleanup removes 20% of files by count, but cache files can vary significantly in size. If the cache contains many small files and a few large ones, removing 20% by count might not free sufficient space to bring the cache under the size limit.

Consider a size-aware cleanup strategy that removes files until the target size is reached:

# Alternative: Remove oldest files until size target is met
TARGET_SIZE_MB=$((CTCACHE_MAXSIZE_MB * 80 / 100))  # Target 80% of max
find "${CTCACHE_DIR}" -type f -printf '%T+ %s %p\0' | sort -z | while IFS=' ' read -r -d $'\0' timestamp size path; do
  if [ "${CACHE_SIZE_MB}" -le "${TARGET_SIZE_MB}" ]; then
    break
  fi
  rm -f "$path" 2>/dev/null || true
  CACHE_SIZE_MB=$(du -sm "${CTCACHE_DIR}" 2>/dev/null | cut -f1)
done

However, the current count-based approach is simpler and may be sufficient for relatively uniform cache file sizes.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f9d5ccce4b84ec1d206a664ce0471bf73269cbfb and e08360b.

📒 Files selected for processing (1)
  • ci/dash/lint-tidy.sh (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
{guix-build*,releases,**/guix-build*,releases/**,.github/**,depends/**,ci/**,contrib/**,doc/**}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not make changes to build system files (guix-build*), release artifacts, or avoid changes to .github, depends, ci, contrib, and doc directories unless specifically prompted

Files:

  • ci/dash/lint-tidy.sh
🔇 Additional comments (8)
ci/dash/lint-tidy.sh (8)

14-18: LGTM! Clear error handling for missing clang-tidy.

The availability check provides a clear, early failure message if clang-tidy is not found. Using command -v is the standard approach for checking command availability in shell scripts.


20-26: LGTM! ctcache environment setup is appropriate for CI.

The hardcoded /cache/ctcache path is acceptable in this CI-specific context and matches the Docker container structure defined in the Dockerfile. The environment variables are correctly exported for ctcache to use.


27-28: LGTM! Binary paths match Dockerfile installation.

The hardcoded paths correspond to the ctcache installation locations defined in contrib/containers/ci/ci.Dockerfile. While tightly coupled, this is appropriate for a CI-specific script.


30-38: LGTM! Proper validation of ctcache installation.

The checks ensure that the ctcache components installed by the Dockerfile are present before attempting to use them, providing clear error messages for debugging if the installation is incomplete.


40-41: LGTM! Appropriate handling of statistics reset.

Zeroing statistics before the run ensures accurate per-run metrics. The || true prevents the script from failing if stats reset fails, which is acceptable for non-critical cache statistics.


45-45: LGTM! Correct integration of ctcache wrapper.

The -clang-tidy-binary flag correctly redirects run-clang-tidy to use the ctcache wrapper, enabling result caching while preserving all existing behavior including error handling and output redirection.


51-55: LGTM! Clear reporting of ctcache statistics.

The statistics reporting provides useful visibility into cache performance. Using || true for error suppression is appropriate here since cache statistics are non-critical to the linting process.


69-72: LGTM! Appropriate final reporting of cache state.

The final cache size display provides useful feedback on the effectiveness of the cleanup operations.

UdjinM6 and others added 6 commits December 19, 2025 23:14
Adds ctcache to cache clang-tidy analysis results, significantly reducing
CI time for subsequent runs. Unchanged files serve results from cache while
only modified files get re-analyzed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Move CTCACHE_DIR and CTCACHE_MAXSIZE_MB to ci/test/00_setup_env.sh
- Use command -v instead of hardcoded paths for clang-tidy and clang-tidy-cache
- Store clang-tidy location in CLANG_TIDY_BIN variable for reuse
- Extract cache cleanup logic into cleanup_ctcache() function
- Convert CTCACHE_COMMIT to ARG variable in Dockerfile

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
ci/dash/lint-tidy.sh (2)

14-35: Consider refining the cache cleanup strategy.

The current cleanup logic removes files older than 7 days, then removes the oldest 20% if still over the limit. This approach has some limitations:

  1. Size-agnostic removal: Removes 20% of files by count, not by size. A few large, rarely-used entries might be more suitable for eviction than many small, frequently-used entries.
  2. No post-cleanup verification: Doesn't verify that cleanup actually brought the cache under the limit.
  3. Aggressive eviction: Removing 20% at once might evict recently useful entries, reducing hit rates.

Consider a more granular approach: remove files in smaller batches (e.g., 5-10% at a time) until under the limit, or prioritize removal by size-to-age ratio.

🔎 Example: Iterative cleanup until under limit
 cleanup_ctcache() {
   local cache_dir=$1
   local max_size_mb=$2
   local cache_size_mb
 
   cache_size_mb=$(du -sm "${cache_dir}" 2>/dev/null | cut -f1)
   if [ "${cache_size_mb}" -gt "${max_size_mb}" ]; then
     echo "Cache size ${cache_size_mb}MB exceeds limit ${max_size_mb}MB, cleaning old entries..."
     # Remove files older than 7 days, or if still too large, oldest 20% of files
     find "${cache_dir}" -type f -mtime +7 -delete 2>/dev/null || true
     cache_size_mb=$(du -sm "${cache_dir}" 2>/dev/null | cut -f1)
-    if [ "${cache_size_mb}" -gt "${max_size_mb}" ]; then
+    while [ "${cache_size_mb}" -gt "${max_size_mb}" ]; do
       local file_count remove_count
       file_count=$(find "${cache_dir}" -type f | wc -l)
-      remove_count=$((file_count / 5))
+      remove_count=$((file_count / 10))  # Remove 10% at a time instead of 20%
+      if [ "${remove_count}" -eq 0 ]; then
+        echo "Warning: Cannot reduce cache size further"
+        break
+      fi
       find "${cache_dir}" -type f -printf '%T+ %p\0' | sort -z | head -z -n "${remove_count}" | cut -z -d' ' -f2- | xargs -0 rm -f 2>/dev/null || true
       echo "Attempted to remove ${remove_count} oldest cache entries"
-    fi
+      cache_size_mb=$(du -sm "${cache_dir}" 2>/dev/null | cut -f1)
+    done
     echo "Cache size after cleanup: $(du -sh "${cache_dir}" 2>/dev/null | cut -f1)"
   fi
 }

73-80: Consider logging suppressed errors for debugging.

The statistics and cleanup commands suppress errors with || true and 2>&1 || true, which prevents CI failures but may hide real issues (e.g., permission problems, corrupted cache). Consider capturing and logging these errors for debugging while still allowing the script to continue.

🔎 Example: Log errors while continuing
 echo "=== ctcache statistics ==="
-du -sh "${CTCACHE_DIR}" 2>/dev/null || echo "Cache directory not found"
-python3 "${CLANG_TIDY_CACHE_PY}" --show-stats 2>&1 || true
+if ! du -sh "${CTCACHE_DIR}" 2>&1; then
+  echo "Warning: Failed to check cache directory size"
+fi
+if ! python3 "${CLANG_TIDY_CACHE_PY}" --show-stats 2>&1; then
+  echo "Warning: Failed to retrieve cache statistics"
+fi
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 70930fb and 28577db.

📒 Files selected for processing (4)
  • .github/workflows/build-src.yml (1 hunks)
  • ci/dash/lint-tidy.sh (1 hunks)
  • ci/test/00_setup_env.sh (1 hunks)
  • contrib/containers/ci/ci.Dockerfile (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • contrib/containers/ci/ci.Dockerfile
  • .github/workflows/build-src.yml
🧰 Additional context used
📓 Path-based instructions (1)
{guix-build*,releases,**/guix-build*,releases/**,.github/**,depends/**,ci/**,contrib/**,doc/**}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not make changes to build system files (guix-build*), release artifacts, or avoid changes to .github, depends, ci, contrib, and doc directories unless specifically prompted

Files:

  • ci/test/00_setup_env.sh
  • ci/dash/lint-tidy.sh
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: x86_64-pc-linux-gnu / Build depends
  • GitHub Check: x86_64-pc-linux-gnu_multiprocess / Build depends
  • GitHub Check: Lint / Run linters
🔇 Additional comments (3)
ci/dash/lint-tidy.sh (2)

37-42: LGTM!

The clang-tidy verification correctly uses command -v, stores the result in a variable for reuse (addressing previous feedback), and provides clear error handling.


67-67: LGTM!

The clang-tidy invocation correctly uses the ctcache wrapper via -clang-tidy-binary="${CLANG_TIDY_CACHE}" while preserving the quiet mode and parallelism settings.

ci/test/00_setup_env.sh (1)

64-66: The review comment references PR objectives and specific cache hit metrics that cannot be verified in the codebase or git history. Additionally, the underlying assumption about cache size requirements is contradicted by ctcache documentation, which states that storage needs are minimal since ctcache only stores hashes by default. The codebase already implements automatic cache cleanup logic (removing files older than 7 days, or oldest 20% if size exceeds limit), indicating the maintainers are aware of size constraints.

Likely an incorrect or invalid review comment.

Instead of hardcoding the Python script path, derive it from the
clang-tidy-cache wrapper location using the same logic the wrapper
itself uses. This improves portability if ctcache is installed in
a different location.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
ci/dash/lint-tidy.sh (1)

20-21: Consider defensive handling for empty cache size.

If du -sm fails (e.g., directory doesn't exist or is inaccessible), cache_size_mb will be an empty string. Line 21's integer comparison will then fail with "integer expression expected" and cause the script to exit due to set -eo pipefail.

While the directory is created on line 47 before cleanup_ctcache is called, adding a default value improves robustness.

🔎 Optional defensive fix
-  cache_size_mb=$(du -sm "${cache_dir}" 2>/dev/null | cut -f1)
+  cache_size_mb=$(du -sm "${cache_dir}" 2>/dev/null | cut -f1)
+  cache_size_mb=${cache_size_mb:-0}
   if [ "${cache_size_mb}" -gt "${max_size_mb}" ]; then

This ensures cache_size_mb defaults to 0 if empty, preventing comparison errors.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 28577db and 7c310c7.

📒 Files selected for processing (1)
  • ci/dash/lint-tidy.sh (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
{guix-build*,releases,**/guix-build*,releases/**,.github/**,depends/**,ci/**,contrib/**,doc/**}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not make changes to build system files (guix-build*), release artifacts, or avoid changes to .github, depends, ci, contrib, and doc directories unless specifically prompted

Files:

  • ci/dash/lint-tidy.sh
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: arm-linux-build / Build source
  • GitHub Check: linux64-build / Build source
  • GitHub Check: linux64_sqlite-build / Build source
  • GitHub Check: linux64_fuzz-build / Build source
  • GitHub Check: linux64_ubsan-build / Build source
  • GitHub Check: mac-build / Build source
  • GitHub Check: linux64_nowallet-build / Build source
  • GitHub Check: win64-build / Build source
  • GitHub Check: linux64_tsan-build / Build source
  • GitHub Check: Lint / Run linters
🔇 Additional comments (3)
ci/dash/lint-tidy.sh (3)

37-62: LGTM: Robust validation and setup.

The clang-tidy and ctcache verification logic is well-implemented:

  • Uses command -v for binary discovery
  • Stores binary paths in variables for reuse
  • Provides clear error messages when required tools are missing
  • Derives the Python script path from the wrapper location (matching ctcache's own logic)
  • Creates cache directory with mkdir -p for safety

All past review concerns have been addressed.


64-73: LGTM: Correct ctcache integration.

The stats zeroing and clang-tidy execution are properly implemented:

  • Stats are zeroed before the run to isolate per-run metrics (with || true for resilience)
  • run-clang-tidy correctly uses the ctcache wrapper via -clang-tidy-binary
  • Output is captured for error reporting
  • Error handling shows context with grep -C5

75-82: LGTM: Comprehensive reporting and cleanup.

The statistics reporting and cache management are well-implemented:

  • Clear section delimiters for CI log readability
  • Defensive error handling (|| true, || echo) for resilience
  • Cache cleanup enforces size limits (ctcache lacks built-in size management, as noted)
  • Uses environment variables (CTCACHE_DIR, CTCACHE_MAXSIZE_MB) configured in ci/test/00_setup_env.sh

kwvg
kwvg previously approved these changes Dec 20, 2025
Copy link
Collaborator

@kwvg kwvg left a comment

Choose a reason for hiding this comment

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

utACK 7c310c7

@UdjinM6
Copy link
Author

UdjinM6 commented Dec 21, 2025

Both my fixes were merged into upstream, we no longer have to patch it manually. Added 040ac27.

CI: https://github.com/UdjinM6/dash/actions/runs/20409759062

@UdjinM6 UdjinM6 requested a review from kwvg December 21, 2025 15:10
Copy link
Collaborator

@kwvg kwvg left a comment

Choose a reason for hiding this comment

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

utACK 040ac27

Copy link
Member

@PastaPastaPasta PastaPastaPasta left a comment

Choose a reason for hiding this comment

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

utACK 040ac27

@PastaPastaPasta PastaPastaPasta merged commit e9321d2 into dashpay:develop Dec 23, 2025
39 of 42 checks passed
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