forked from SteamWar/SteamWar
@@ -35,29 +35,53 @@ jobs:
|
|||||||
local method="$1"
|
local method="$1"
|
||||||
local path="$2"
|
local path="$2"
|
||||||
local body="${3:-}"
|
local body="${3:-}"
|
||||||
|
local response_file
|
||||||
|
local status
|
||||||
|
|
||||||
|
response_file="$(mktemp)"
|
||||||
|
|
||||||
if [[ -n "$body" ]]; then
|
if [[ -n "$body" ]]; then
|
||||||
curl --fail --silent --show-error \
|
status="$(curl --silent --show-error \
|
||||||
-X "$method" \
|
-X "$method" \
|
||||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||||
-H "Accept: application/json" \
|
-H "Accept: application/json" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
--data "$body" \
|
--data "$body" \
|
||||||
"${GITHUB_API_URL}${path}"
|
--output "$response_file" \
|
||||||
|
--write-out "%{http_code}" \
|
||||||
|
"${GITHUB_API_URL}${path}")"
|
||||||
else
|
else
|
||||||
curl --fail --silent --show-error \
|
status="$(curl --silent --show-error \
|
||||||
-X "$method" \
|
-X "$method" \
|
||||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||||
-H "Accept: application/json" \
|
-H "Accept: application/json" \
|
||||||
"${GITHUB_API_URL}${path}"
|
--output "$response_file" \
|
||||||
|
--write-out "%{http_code}" \
|
||||||
|
"${GITHUB_API_URL}${path}")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "$status" -lt 200 || "$status" -ge 300 ]]; then
|
||||||
|
echo "Gitea API ${method} ${path} failed with HTTP ${status}" >&2
|
||||||
|
cat "$response_file" >&2
|
||||||
|
rm -f "$response_file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat "$response_file"
|
||||||
|
rm -f "$response_file"
|
||||||
}
|
}
|
||||||
|
|
||||||
repo_path="/repos/${GITHUB_REPOSITORY}"
|
repo_path="/repos/${GITHUB_REPOSITORY}"
|
||||||
|
repo_owner="${GITHUB_REPOSITORY%%/*}"
|
||||||
pr_number="$(jq -r '.number' "$GITHUB_EVENT_PATH")"
|
pr_number="$(jq -r '.number' "$GITHUB_EVENT_PATH")"
|
||||||
pr_title="$(jq -r '.pull_request.title // ""' "$GITHUB_EVENT_PATH")"
|
pr_title="$(jq -r '.pull_request.title // ""' "$GITHUB_EVENT_PATH")"
|
||||||
event_commit="$(jq -r '.pull_request.merge_commit_sha // .pull_request.merged_commit_id // .commit_id // env.GITHUB_SHA' "$GITHUB_EVENT_PATH")"
|
event_commit="$(jq -r '.pull_request.merge_commit_sha // .pull_request.merged_commit_id // .commit_id // env.GITHUB_SHA' "$GITHUB_EVENT_PATH")"
|
||||||
|
|
||||||
|
if jq -e '.pull_request.labels[]? | select(.name == "no-backport")' "$GITHUB_EVENT_PATH" >/dev/null; then
|
||||||
|
echo "PR #${pr_number} has label no-backport; skipping automatic backport."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
commoncore_files=()
|
commoncore_files=()
|
||||||
page=1
|
page=1
|
||||||
while true; do
|
while true; do
|
||||||
@@ -113,6 +137,41 @@ jobs:
|
|||||||
git cat-file -e "${commit}^{commit}"
|
git cat-file -e "${commit}^{commit}"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
apply_commoncore_change() {
|
||||||
|
local commit="$1"
|
||||||
|
local parent
|
||||||
|
local patch_file
|
||||||
|
|
||||||
|
if [[ "$(git rev-list --parents -n 1 "$commit" | wc -w)" -gt 2 ]]; then
|
||||||
|
parent="${commit}^1"
|
||||||
|
else
|
||||||
|
parent="${commit}^"
|
||||||
|
fi
|
||||||
|
|
||||||
|
patch_file="$(mktemp)"
|
||||||
|
git diff --binary "$parent" "$commit" -- CommonCore/ > "$patch_file"
|
||||||
|
|
||||||
|
if [[ ! -s "$patch_file" ]]; then
|
||||||
|
echo "Commit ${commit} has no CommonCore/ diff; skipping it."
|
||||||
|
rm -f "$patch_file"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if git apply --reverse --check "$patch_file" >/dev/null 2>&1; then
|
||||||
|
echo "CommonCore/ diff from ${commit} is already present; skipping it."
|
||||||
|
rm -f "$patch_file"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if git apply --3way --index "$patch_file"; then
|
||||||
|
rm -f "$patch_file"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$patch_file"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
mapfile -t version_branches < <(
|
mapfile -t version_branches < <(
|
||||||
git for-each-ref --format='%(refname:short)' refs/remotes/origin/version |
|
git for-each-ref --format='%(refname:short)' refs/remotes/origin/version |
|
||||||
sed 's#^origin/##' |
|
sed 's#^origin/##' |
|
||||||
@@ -142,53 +201,53 @@ jobs:
|
|||||||
git checkout -B "$head_branch" "origin/${target_branch}"
|
git checkout -B "$head_branch" "origin/${target_branch}"
|
||||||
|
|
||||||
for commit in "${source_commits[@]}"; do
|
for commit in "${source_commits[@]}"; do
|
||||||
cherry_pick_args=(-x)
|
if apply_commoncore_change "$commit"; then
|
||||||
if [[ "$(git rev-list --parents -n 1 "$commit" | wc -w)" -gt 2 ]]; then
|
|
||||||
cherry_pick_args=(-x -m 1)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if git cherry-pick "${cherry_pick_args[@]}" "$commit"; then
|
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z "$(git status --porcelain)" ]]; then
|
echo "Failed to apply CommonCore/ diff from ${commit} to ${target_branch}" >&2
|
||||||
echo "Cherry-pick of ${commit} produced no changes; skipping it."
|
exit 1
|
||||||
git cherry-pick --skip || true
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
git cherry-pick --abort || true
|
|
||||||
failures+=("${target_branch}: cherry-pick of ${commit} failed")
|
|
||||||
break
|
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ "${failures[*]:-}" == *"${target_branch}:"* ]]; then
|
if git diff --cached --quiet; then
|
||||||
|
echo "${target_branch} already contains the CommonCore/ change; no PR needed."
|
||||||
git checkout main
|
git checkout main
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if git diff --quiet "origin/${target_branch}" HEAD; then
|
git commit -m "Backport CommonCore changes from #${pr_number}" \
|
||||||
echo "${target_branch} already contains the change; no PR needed."
|
-m "Source PR: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pulls/${pr_number}" \
|
||||||
git checkout main
|
-m "Only CommonCore/ changes are included in this backport."
|
||||||
continue
|
|
||||||
fi
|
git push origin "HEAD:refs/heads/${head_branch}" --force-with-lease
|
||||||
|
|
||||||
if [[ "${#source_commits[@]}" -eq 1 ]]; then
|
if [[ "${#source_commits[@]}" -eq 1 ]]; then
|
||||||
source_text="Source commit: \`${source_commits[0]}\`"
|
source_text="Source commit: \`${source_commits[0]}\`"
|
||||||
else
|
else
|
||||||
source_text="Source commits:"
|
source_text="Source commits:"
|
||||||
for commit in "${source_commits[@]}"; do
|
for commit in "${source_commits[@]}"; do
|
||||||
source_text="${source_text} \`${commit}\`"
|
source_text="${source_text}"$'\n'"- \`${commit}\`"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
description="Automated backport of #${pr_number} to ${target_branch} because the source PR changed CommonCore/. Source PR: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pulls/${pr_number}. ${source_text}. This PR will be merged automatically by the Pull Request Build workflow after a successful build."
|
body="$(cat <<BODY
|
||||||
|
Automated backport of #${pr_number} to \`${target_branch}\` because the source PR changed \`CommonCore/\`.
|
||||||
|
|
||||||
git push \
|
Source PR: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pulls/${pr_number}
|
||||||
-o "topic=${head_branch}" \
|
${source_text}
|
||||||
-o "title=Backport #${pr_number} to ${target_branch}: ${pr_title}" \
|
|
||||||
-o "description=${description}" \
|
This PR will be merged automatically by the Pull Request Build workflow after a successful build.
|
||||||
origin "HEAD:refs/for/${target_branch}"
|
BODY
|
||||||
|
)"
|
||||||
|
|
||||||
|
payload="$(jq -n \
|
||||||
|
--arg base "$target_branch" \
|
||||||
|
--arg head "${repo_owner}:${head_branch}" \
|
||||||
|
--arg title "Backport #${pr_number} to ${target_branch}: ${pr_title}" \
|
||||||
|
--arg body "$body" \
|
||||||
|
'{base: $base, head: $head, title: $title, body: $body}')"
|
||||||
|
|
||||||
|
api POST "${repo_path}/pulls" "$payload" >/dev/null
|
||||||
echo "Created backport PR from ${head_branch} to ${target_branch}."
|
echo "Created backport PR from ${head_branch} to ${target_branch}."
|
||||||
git checkout main
|
git checkout main
|
||||||
done
|
done
|
||||||
|
|||||||
Reference in New Issue
Block a user