diff --git a/tools/maint/README.md b/tools/maint/README.md new file mode 100644 index 000000000..3df0d2013 --- /dev/null +++ b/tools/maint/README.md @@ -0,0 +1,56 @@ +# Maintenance Tools + +This directory contains automation for managing our **Friendly Fork**. It allows us to integrate community-submitted Pull Requests from the upstream repository into our local development branches. + +## Why this exists + +In firmware development, critical bug fixes or hardware support often exist in the upstream "Pull Request" queue long before they are officially merged. This tool allows us to build an integrated firmware version that includes those necessary patches while remaining syncable with the official source. + +## Usage + +### 1. Prerequisites + +You must have the original repository added as a remote named `upstream`: + +```bash +git remote add upstream https://github.com/meshcore-dev/MeshCore.git +``` + +### 2. Basic Commands + +**Apply specific patches:** +To pull in PR #1338 and PR #1400 from the upstream project: + +```bash +./tools/maint/apply_patches.sh 1338 1400 + +``` + +**Start over (Reset):** +To wipe the integrated branch and reset it to match the official upstream `main` branch exactly: + +```bash +./tools/maint/apply_patches.sh --reset + +``` + +## Traceability + +Every time this script runs, it updates `patch_manifest.log`. This file tracks: + +* The date of the integration. +* The base commit SHA we started from. +* The specific commit SHA of every PR applied. + +**This log is essential for debugging firmware regressions.** If the hardware fails, check the manifest to identify which experimental patch might be the cause. + +--- + +### A Note on Merge Conflicts + +If a PR cannot be applied automatically, the script will abort the merge. You will need to: + +1. Manually merge the PR. +2. Resolve the conflicts in your editor. +3. Commit the result. +4. Manually update the `patch_manifest.log`. diff --git a/tools/maint/apply_patches.sh b/tools/maint/apply_patches.sh new file mode 100755 index 000000000..fcffa751c --- /dev/null +++ b/tools/maint/apply_patches.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# Configuration +UPSTREAM_REMOTE="upstream" +BASE_BRANCH="main" # Change to 'master' if that's what upstream uses +TARGET_BRANCH="main-integrated" +MANIFEST_FILE="tools/maint/patch_manifest.log" + +# Function to reset the branch +reset_to_upstream() { + echo "Warning: This will wipe all local changes on $TARGET_BRANCH." + read -p "Are you sure you want to reset to $UPSTREAM_REMOTE/$BASE_BRANCH? (y/n) " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + git fetch "$UPSTREAM_REMOTE" + git checkout -B "$TARGET_BRANCH" "$UPSTREAM_REMOTE/$BASE_BRANCH" + echo "--- Reset to Upstream: $(date) ---" > "$MANIFEST_FILE" + echo "Base Commit: $(git rev-parse HEAD)" >> "$MANIFEST_FILE" + echo "Reset successful. Branch is now clean." + else + echo "Reset aborted." + fi +} + +# Check for reset flag +if [[ "$1" == "--reset" ]]; then + reset_to_upstream + exit 0 +fi + +# Standard PR application logic +PR_IDS=("$@") +if [ ${#PR_IDS[@]} -eq 0 ]; then + echo "Usage:" + echo " Apply PRs: $0 ..." + echo " Reset: $0 --reset" + exit 1 +fi + +# Ensure target branch exists and is checked out +git checkout -B "$TARGET_BRANCH" + +echo "--- Patch Session: $(date) ---" >> "$MANIFEST_FILE" + +for PR in "${PR_IDS[@]}"; do + echo "--------------------------------------" + echo "Fetching PR #$PR..." + + if git fetch "$UPSTREAM_REMOTE" "pull/$PR/head:PR_TEMP_FETCH"; then + if git merge PR_TEMP_FETCH --no-edit -m "Integrate upstream PR #$PR"; then + echo "Successfully integrated PR #$PR" + echo "PR #$PR SHA: $(git rev-parse PR_TEMP_FETCH)" >> "$MANIFEST_FILE" + else + echo "Conflict in PR #$PR. Aborting merge." + git merge --abort + exit 1 + fi + git branch -D PR_TEMP_FETCH + else + echo "Error: PR #$PR not found." + fi +done + +echo "--------------------------------------" +echo "Done. See $MANIFEST_FILE for details." \ No newline at end of file