Skip to content

Commit cc095fe

Browse files
Merge pull request #28 from Harsh-Microsoft/grp-depbot-security-pr
refactor: Enhance conflict resolution strategy in Dependabot PR workf…
2 parents e970a25 + 0c3d99a commit cc095fe

File tree

1 file changed

+48
-52
lines changed

1 file changed

+48
-52
lines changed

.github/workflows/group-dependabot-security-updates.yml

Lines changed: 48 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -192,73 +192,69 @@ jobs:
192192
echo "✅ Successfully applied PR #$number without conflicts."
193193
applied_pr_numbers+=($number)
194194
else
195-
echo "❌ Conflict found with PR #$number. Attempting 'merge and regenerate' strategy."
195+
echo "❌ Conflict found with PR #$number. Attempting 'Smart Apply' strategy."
196196
197197
manifest_files_conflicted=$(git diff --name-only --diff-filter=U | grep -E "package.json|requirements.txt|pyproject.toml" || true)
198198
199199
if [ -n "$manifest_files_conflicted" ]; then
200-
resolution_failed=false
201-
for manifest_file in $manifest_files_conflicted; do
202-
echo "Attempting to resolve conflict in manifest file: $manifest_file"
203-
204-
git show :1:"$manifest_file" > base.txt
205-
git show :2:"$manifest_file" > ours.txt
206-
git show :3:"$manifest_file" > theirs.txt
207-
208-
# Use --theirs to automatically resolve line-level conflicts by taking the incoming change
209-
if git merge-file --theirs -p ours.txt base.txt theirs.txt > "$manifest_file"; then
210-
echo "Successfully merged $manifest_file using 'theirs' strategy."
211-
git add "$manifest_file"
212-
else
213-
echo "❌ Even with --theirs, could not merge $manifest_file. Aborting."
214-
resolution_failed=true
215-
break
216-
fi
217-
done
218-
219-
if [ "$resolution_failed" = true ]; then
220-
git cherry-pick --abort
221-
continue
222-
fi
223-
200+
echo "Conflict is in a known manifest. Proceeding with resolution."
201+
202+
# First, reset all conflicted manifest files to our current version.
203+
# This resolves the content conflict and gives us a clean slate to apply changes to.
204+
git checkout --ours $manifest_files_conflicted
205+
206+
# Now, intelligently apply the dependency changes from the incoming PR.
224207
case "$group_name" in
225208
frontend)
226-
# Find the package.json that was conflicted to determine the directory.
227-
# We assume only one package.json gets conflicted per cherry-pick for a single project.
228209
pkg_json_path=$(echo "$manifest_files_conflicted" | grep "package.json" | head -n1)
229-
if [ -n "$pkg_json_path" ]; then
230-
project_dir=$(dirname "$pkg_json_path")
231-
echo "Regenerating lockfile in directory: $project_dir"
232-
233-
# If a yarn.lock file exists in that directory, we treat it as a yarn project.
210+
project_dir=$(dirname "$pkg_json_path")
211+
212+
echo "Extracting dependencies from incoming PR for $pkg_json_path"
213+
# Extract dependencies from the incoming commit's package.json into a temporary file.
214+
git show FETCH_HEAD:"$pkg_json_path" | jq -r '.dependencies + .devDependencies | to_entries[] | "\(.key)@\(.value)"' > deps_to_install.txt
215+
216+
if [ -s deps_to_install.txt ]; then
234217
if [ -f "$project_dir/yarn.lock" ]; then
235-
echo "Found yarn.lock, running 'yarn install'."
236-
# Run yarn install from the project's directory
237-
(cd "$project_dir" && yarn install --ignore-scripts)
238-
# Add the regenerated lockfile to resolve its conflict
239-
git add "$project_dir/yarn.lock"
240-
# Otherwise, we fall back to npm.
218+
echo "Using yarn to add/update dependencies in $project_dir..."
219+
# By running `yarn add` for each package, we let yarn handle adding or updating the dependency.
220+
(cd "$project_dir" && xargs -n 1 yarn add < ../deps_to_install.txt)
221+
git add "$project_dir/yarn.lock"
241222
else
242-
echo "No yarn.lock found. Running 'npm install'."
243-
# Run npm install from the project's directory
244-
(cd "$project_dir" && npm install --ignore-scripts)
245-
# Add the regenerated lockfile to resolve its conflict
246-
git add "$project_dir/package-lock.json"
223+
echo "Using npm to install/update dependencies in $project_dir..."
224+
# By running `npm install` for each package, we let npm handle adding or updating the dependency.
225+
(cd "$project_dir" && xargs -n 1 npm install < ../deps_to_install.txt)
226+
git add "$project_dir/package-lock.json"
247227
fi
228+
# Stage the manifest file that npm/yarn updated.
229+
git add "$pkg_json_path"
230+
else
231+
echo "No dependencies found to install."
248232
fi
249233
;;
250234
backend)
251-
# For python, find the requirements file that was conflicted.
252-
req_file_path=$(echo "$manifest_files_conflicted" | grep "requirements.txt" | head -n1)
253-
if [ -n "$req_file_path" ]; then
254-
echo "Running 'pip install' for '$req_file_path' to ensure consistency."
255-
pip install -r "$req_file_path"
256-
# The requirements file itself was already staged in the merge loop.
257-
fi
235+
req_file_path=$(echo "$manifest_files_conflicted" | grep "requirements.txt" | head -n1)
236+
if [ -n "$req_file_path" ]; then
237+
echo "Smart-merging Python requirements for '$req_file_path'"
238+
239+
# Get the incoming version of the requirements file
240+
git show FETCH_HEAD:"$req_file_path" > incoming_reqs.txt
241+
242+
# Merge the two requirements files. The sort command with -u on the key (package name)
243+
# ensures that versions from the incoming file take precedence if a package is in both files.
244+
echo "Merging existing requirements with incoming ones..."
245+
cat incoming_reqs.txt "$req_file_path" | sort -t'=' -k1,1 -u > merged_reqs.txt
246+
mv merged_reqs.txt "$req_file_path"
247+
248+
# Now install from the newly merged file to update the environment
249+
pip install -r "$req_file_path"
250+
251+
# Stage the merged requirements file
252+
git add "$req_file_path"
253+
fi
258254
;;
259255
esac
260-
261-
# Use -c to reuse the original commit message from the PR
256+
257+
# All files should now be resolved and staged. We can commit.
262258
if git commit -C FETCH_HEAD; then
263259
echo "✅ Successfully resolved conflict and applied PR #$number."
264260
applied_pr_numbers+=($number)

0 commit comments

Comments
 (0)