Skip to content

Conversation

@rpardini
Copy link
Member

@rpardini rpardini commented Jan 9, 2026

  • 🌱 so patches-to-git filtering is actually useful

Summary by CodeRabbit

  • Bug Fixes
    • Failed patch applications now generate warning-level log messages instead of info messages
    • Unsuccessful patch files are automatically removed from disk after failed application
    • Parent directories of failed patches are automatically cleaned up

✏️ Tip: You can customize this high-level summary in your review settings.

- so patches-to-git filtering is actually useful
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 9, 2026

📝 Walkthrough

Walkthrough

The patching module now logs failed or unrewritten patches at warning level instead of info and deletes their corresponding patch files from disk as cleanup.

Changes

Cohort / File(s) Summary
Patch failure handling
lib/tools/patching.py
Changed log severity from info to warning for failed/unrewritten patches; added os.remove() call to delete patch file paths from disk after patch application

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A patch that fails now gets the axe,
Its warnings loud, no quiet tracks,
We clean the files and warn with care,
Failed attempts just disappear! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: deleting empty patch files during rewrite operations in the patching module.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
  • 📝 Generate docstrings

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.

@github-actions github-actions bot added the 02 Milestone: First quarter release label Jan 9, 2026
@rpardini rpardini marked this pull request as ready for review January 9, 2026 18:24
@github-actions github-actions bot added size/small PR with less then 50 lines Needs review Seeking for review Framework Framework components labels Jan 9, 2026
Copy link
Contributor

@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

🤖 Fix all issues with AI agents
In @lib/tools/patching.py:
- Around line 377-381: The loop over FAILED_PATCHES may call
os.remove(failed_patch.parent.full_file_path()) multiple times for the same file
and has no error handling; change the logic to collect unique parent paths (use
failed_patch.parent.full_file_path() or a set of parent identifiers) and iterate
once per unique path, call log.warning once per path (including the failing
patch counters if desired), and wrap os.remove(...) in a try/except that catches
OSError/FileNotFoundError to log an error via log.exception or log.error instead
of letting the script crash.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a61ff23 and fc25c17.

📒 Files selected for processing (1)
  • lib/tools/patching.py
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: EvilOlaf
Repo: armbian/build PR: 8968
File: patch/u-boot/u-boot-sunxi/arm64-dts-sun50i-h6-orangepi.dtsi-Rollback-r_rsb-to-r_i2c.patch:36-36
Timestamp: 2025-11-20T18:20:11.985Z
Learning: The rewrite-patches tool (REWRITE_PATCHES=yes) in the Armbian build system can inadvertently introduce semantic changes when the u-boot/kernel git base revision differs from expected state. The tool applies patches, commits them, and re-exports them using git format-patch, which can cause the re-exported patch to reflect the base revision's state rather than preserving the original patch intent. This is particularly problematic for device tree changes like interrupt specifications. The tool currently lacks validation mechanisms to detect such semantic drift, and affected patches must be manually corrected after rewriting.
Learnt from: igorpecovnik
Repo: armbian/build PR: 8705
File: .github/workflows/rewrite-kernel-configs.yml:96-169
Timestamp: 2025-10-03T11:42:46.660Z
Learning: In the Armbian build repository's kernel config rewrite workflow (.github/workflows/rewrite-kernel-configs.yml), deletion of kernel config files does not need to be handled. The workflow intentionally only captures ACMR (added/copied/modified/renamed) changes and does not need to propagate deletions to the aggregator.
Learnt from: amazingfate
Repo: armbian/build PR: 8619
File: config/sources/families/rockchip.conf:65-72
Timestamp: 2025-09-14T11:37:35.089Z
Learning: In the Armbian build system, patch directories referenced in BOOTPATCHDIR and KERNELPATCHDIR configurations can be non-existent without causing build failures. Empty patch directories are also ignored by git, so missing patch directories should not be flagged as errors during code review.
Learnt from: EvilOlaf
Repo: armbian/build PR: 0
File: :0-0
Timestamp: 2025-12-17T05:09:02.306Z
Learning: In the Armbian build system, kernel patches (e.g., in patch/kernel/archive/sunxi-6.18/patches.armbian/) contain device tree overlays and other code that have existed for years and are maintained/ported across kernel versions. When reviewing PRs that modify these patch files, focus on the actual changes being made (e.g., Makefile fixes, new additions) rather than reviewing the entire existing content within the patch as if it were new code. The patch file contents are existing, stable code unless explicitly modified in the PR diff.
Learnt from: igorpecovnik
Repo: armbian/build PR: 8705
File: .github/workflows/rewrite-kernel-configs.yml:217-220
Timestamp: 2025-10-04T17:59:19.369Z
Learning: In the Armbian build repository's kernel config rewrite workflow (.github/workflows/rewrite-kernel-configs.yml), the workflow is designed to rewrite existing kernel configs only. New/untracked files can be safely ignored, so using `git diff --quiet` (which ignores untracked files) is the correct approach for detecting changes rather than `git status --porcelain`.
Learnt from: leggewie
Repo: armbian/build PR: 0
File: :0-0
Timestamp: 2025-08-29T18:44:47.732Z
Learning: When creating GitHub issues for code improvements in the Armbian build project, include the relevant patches/diffs in the issue description or open a PR directly instead of just describing the changes. This makes it more efficient for the assignee to handle the improvements.
Learnt from: EvilOlaf
Repo: armbian/build PR: 8428
File: config/boards/lckfb-taishanpi.csc:5-9
Timestamp: 2025-07-25T03:51:50.830Z
Learning: When reviewing PRs in the Armbian build system, U-Boot defconfig files and patches may be added as part of the PR changes but might not be visible in the current repository clone state during review. It's important to check the actual PR file changes directly via GitHub API (https://api.github.com/repos/armbian/build/pulls/{pr_number}/files) to get the complete picture of what files are being added or modified, especially for U-Boot patches that will be applied during the build process.
Learnt from: rpardini
Repo: armbian/build PR: 9180
File: patch/kernel/archive/sm8250-6.18/0000.patching_config.yaml:4-8
Timestamp: 2026-01-07T18:21:35.944Z
Learning: In Armbian patch/kernel/archive/**/0000.patching_config.yaml files, the version metadata fields (name, branch, last-known-good-tag, kind, type) under the "info stuff" comment are not used by the patching scripts. When reviewing these files, do not suggest updating or fixing these metadata fields. Instead, suggest removing them entirely as they serve no functional purpose.
Learnt from: EvilOlaf
Repo: armbian/build PR: 9096
File: patch/kernel/archive/sunxi-6.18/patches.armbian/arm64-dts-sun50i-h616-add-overlays.patch:4-5
Timestamp: 2025-12-17T15:46:22.709Z
Learning: In Armbian kernel patches, when patches are renamed or reorganized, the old Subject line may be intentionally preserved in the patch header (as a second Subject line) for archival/historical purposes to document the previous patch name. This is an Armbian-specific practice for tracking patch evolution and should not be flagged as an error when the maintainer has intentionally included it for documentation.

Comment on lines 377 to +381
for failed_patch in FAILED_PATCHES:
log.info(
f"Consider removing {failed_patch.parent.full_file_path()}(:{failed_patch.counter}); "
f"it was not applied successfully.")
log.warning(
f"Removing {failed_patch.parent.full_file_path()}(:{failed_patch.counter}); "
f" it failed to apply/was not rewritten.")
os.remove(failed_patch.parent.full_file_path())
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Duplicate file deletion attempts will crash the script.

This code will attempt to delete the same patch file multiple times if that file contains multiple patches (mbox format) that both fail to apply or weren't rewritten. The second os.remove() call will raise a FileNotFoundError, terminating the script.

Additionally, there's no error handling around os.remove(), so any deletion failure (permissions, file locked, etc.) will also crash the script.

🐛 Proposed fix: deduplicate parent files and add error handling
 		FAILED_PATCHES = [one_patch for one_patch in VALID_PATCHES if (not one_patch.applied_ok) or (one_patch.rewritten_patch is None)]
+		# Deduplicate parent files to avoid attempting to delete the same file multiple times
+		failed_patch_files_to_delete = set()
 		for failed_patch in FAILED_PATCHES:
-			log.warning(
-				f"Removing {failed_patch.parent.full_file_path()}(:{failed_patch.counter}); "
-				f" it failed to apply/was not rewritten.")
-			os.remove(failed_patch.parent.full_file_path())
+			failed_patch_files_to_delete.add(failed_patch.parent.full_file_path())
+		
+		for patch_file_path in failed_patch_files_to_delete:
+			log.warning(f"Removing {patch_file_path}; it failed to apply/was not rewritten.")
+			try:
+				os.remove(patch_file_path)
+			except FileNotFoundError:
+				log.debug(f"File {patch_file_path} already removed.")
+			except OSError as e:
+				log.error(f"Failed to remove {patch_file_path}: {e}")
📝 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
for failed_patch in FAILED_PATCHES:
log.info(
f"Consider removing {failed_patch.parent.full_file_path()}(:{failed_patch.counter}); "
f"it was not applied successfully.")
log.warning(
f"Removing {failed_patch.parent.full_file_path()}(:{failed_patch.counter}); "
f" it failed to apply/was not rewritten.")
os.remove(failed_patch.parent.full_file_path())
FAILED_PATCHES = [one_patch for one_patch in VALID_PATCHES if (not one_patch.applied_ok) or (one_patch.rewritten_patch is None)]
# Deduplicate parent files to avoid attempting to delete the same file multiple times
failed_patch_files_to_delete = set()
for failed_patch in FAILED_PATCHES:
failed_patch_files_to_delete.add(failed_patch.parent.full_file_path())
for patch_file_path in failed_patch_files_to_delete:
log.warning(f"Removing {patch_file_path}; it failed to apply/was not rewritten.")
try:
os.remove(patch_file_path)
except FileNotFoundError:
log.debug(f"File {patch_file_path} already removed.")
except OSError as e:
log.error(f"Failed to remove {patch_file_path}: {e}")
🤖 Prompt for AI Agents
In @lib/tools/patching.py around lines 377 - 381, The loop over FAILED_PATCHES
may call os.remove(failed_patch.parent.full_file_path()) multiple times for the
same file and has no error handling; change the logic to collect unique parent
paths (use failed_patch.parent.full_file_path() or a set of parent identifiers)
and iterate once per unique path, call log.warning once per path (including the
failing patch counters if desired), and wrap os.remove(...) in a try/except that
catches OSError/FileNotFoundError to log an error via log.exception or log.error
instead of letting the script crash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

02 Milestone: First quarter release Framework Framework components Needs review Seeking for review size/small PR with less then 50 lines

Development

Successfully merging this pull request may close these issues.

1 participant