mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-26 03:12:16 -04:00
[9.20] chg: ci: Various autorebase improvements
- Rewrite cherry-pick references during autorebases - Fix autorebase error reporting - Limit post-push pipelines for autorebased branches - Only autorebase when there is anything to rebase - Conflate missing commit reference notifications - Support autorebasing backported security MRs Backport of MR !12024 Merge branch 'backport-michal/autorebase-improvements-9.20' into 'bind-9.20' See merge request isc-projects/bind9!12069
This commit is contained in:
commit
29a132b5d0
2 changed files with 64 additions and 38 deletions
|
|
@ -340,8 +340,8 @@ stages:
|
|||
.rule_source_all: &rule_source_all
|
||||
- if: '$CI_PIPELINE_SOURCE =~ /^(api|merge_request_event|pipeline|schedule|trigger|web)$/ && $REBASE_ONLY != "1"'
|
||||
|
||||
.rule_private_security_branch: &rule_private_security_branch
|
||||
- if: '$CI_COMMIT_BRANCH =~ /^security-(main|bind-9\.[1-9][0-9])$/ && $CI_PROJECT_PATH == "isc-private/bind9" && $REBASE_ONLY != "1"'
|
||||
.rule_branch_after_autorebase: &rule_branch_after_autorebase
|
||||
- if: '$CI_PIPELINE_SOURCE == "push" && $AUTOREBASED == "1"'
|
||||
|
||||
.api-pipelines-schedules-tags-triggers-web-triggering-rules: &api_pipelines_schedules_tags_triggers_web_triggering_rules
|
||||
rules:
|
||||
|
|
@ -351,7 +351,7 @@ stages:
|
|||
.default-triggering-rules_list: &default_triggering_rules_list
|
||||
- *rule_tag
|
||||
- *rule_source_all
|
||||
- *rule_private_security_branch
|
||||
- *rule_branch_after_autorebase
|
||||
|
||||
.default-triggering-rules: &default_triggering_rules
|
||||
rules:
|
||||
|
|
@ -363,7 +363,7 @@ stages:
|
|||
- *rule_mr_manual
|
||||
- *rule_tag
|
||||
- *rule_source_other_than_mr
|
||||
- *rule_private_security_branch
|
||||
- *rule_branch_after_autorebase
|
||||
|
||||
.shell-triggering-rules: &shell_triggering_rules
|
||||
rules:
|
||||
|
|
@ -371,7 +371,7 @@ stages:
|
|||
- *rule_mr_manual
|
||||
- *rule_tag
|
||||
- *rule_source_other_than_mr
|
||||
- *rule_private_security_branch
|
||||
- *rule_branch_after_autorebase
|
||||
|
||||
.python-triggering-rules: &python_triggering_rules
|
||||
rules:
|
||||
|
|
@ -379,7 +379,7 @@ stages:
|
|||
- *rule_mr_manual
|
||||
- *rule_tag
|
||||
- *rule_source_other_than_mr
|
||||
- *rule_private_security_branch
|
||||
- *rule_branch_after_autorebase
|
||||
|
||||
.extra-system-tests-triggering-rules: &extra_system_tests_triggering_rules
|
||||
rules:
|
||||
|
|
@ -789,7 +789,7 @@ clang-format:
|
|||
- *rule_mr_manual
|
||||
- *rule_tag
|
||||
- *rule_source_other_than_mr
|
||||
- *rule_private_security_branch
|
||||
- *rule_branch_after_autorebase
|
||||
script:
|
||||
- if [ -r .clang-format ]; then "${CLANG_FORMAT}" -i -style=file $(git ls-files '*.c' '*.h'); fi
|
||||
- git diff > clang-format.patch
|
||||
|
|
@ -931,7 +931,7 @@ coccinelle:
|
|||
- *rule_mr_manual
|
||||
- *rule_tag
|
||||
- *rule_source_other_than_mr
|
||||
- *rule_private_security_branch
|
||||
- *rule_branch_after_autorebase
|
||||
script:
|
||||
- util/check-cocci.sh
|
||||
- if test "$(git status --porcelain | grep -Ev '\?\?' | wc -l)" -gt "0"; then git status --short; exit 1; fi
|
||||
|
|
@ -2598,7 +2598,7 @@ stress-test-child-pipeline:
|
|||
allow_failure: true
|
||||
- *rule_tag
|
||||
- if: '$CI_PIPELINE_SOURCE =~ /^(api|pipeline|schedule|trigger|web)$/ && $REBASE_ONLY != "1"'
|
||||
- *rule_private_security_branch
|
||||
- *rule_branch_after_autorebase
|
||||
trigger:
|
||||
include:
|
||||
- artifact: stress-test-configs.yml
|
||||
|
|
@ -2723,27 +2723,35 @@ merged-metadata:
|
|||
script:
|
||||
# CI job token is not sufficient for push operations
|
||||
- git remote get-url origin | sed -e "s/gitlab-ci-token:${CI_JOB_TOKEN}/oauth2:${BIND_TEAM_WRITE_TOKEN}/" | xargs git remote set-url --push origin
|
||||
- git remote add base-project "https://oauth2:${BIND_TEAM_API_TOKEN}@gitlab.isc.org/${BASE_PROJECT}.git"
|
||||
- git fetch --depth=1000 base-project "${BASE_COMMIT}"
|
||||
- git rebase --rebase-merges "${BASE_COMMIT}"
|
||||
- git remote add base-project "${CI_SERVER_URL}/${BASE_PROJECT}.git"
|
||||
- git fetch --depth="${GIT_DEPTH}" base-project "${BASE_COMMIT}"
|
||||
# If this branch has no changes compared to its base branch yet, there is nothing to rebase;
|
||||
# push the new revision anyway to trigger any potential downstream autorebases.
|
||||
- if [ -z "$(git log --max-count=1 "${BASE_COMMIT}..")" ]; then git push origin "${BASE_COMMIT}:${CI_COMMIT_REF_NAME}"; exit 0; fi
|
||||
- *git_clone_bind9-qa
|
||||
- >
|
||||
"$CI_PROJECT_DIR"/bind9-qa/releng/rebase.py ${REWRITE_CHERRY_PICKS_FROM:+--rewrite-cherry-picks-from ${REWRITE_CHERRY_PICKS_FROM}} --base-project "${BASE_PROJECT}" "${BASE_COMMIT}"
|
||||
- autoreconf -fi
|
||||
- *configure
|
||||
- make -j${BUILD_PARALLEL_JOBS:-1} V=1
|
||||
- git range-diff --color=always "${BASE_COMMIT}" "${CI_COMMIT_SHA}" HEAD
|
||||
- if ! git push --force-with-lease origin "HEAD:${CI_COMMIT_REF_NAME}"; then touch .git-push-failed; exit 1; fi
|
||||
- if ! git push --force-with-lease -o ci.variable="AUTOREBASED=1" origin "HEAD:${CI_COMMIT_REF_NAME}"; then touch .git-push-failed; exit 1; fi
|
||||
after_script:
|
||||
- if [ "${CI_JOB_STATUS}" = "success" ]; then exit 0; fi
|
||||
- OLDEST_MERGE_COMMIT="$(git log --reverse --merges --pretty=%H "${CI_COMMIT_SHA}..${BASE_COMMIT}" | head -1)"
|
||||
- read -r OLDEST_MERGE_REQUEST_PROJECT OLDEST_MERGE_REQUEST_ID < <(git log --max-count=1 "${OLDEST_MERGE_COMMIT}" | sed -nE 's|^\s*See merge request ([a-z-]+/bind9)!([0-9]+).*|\1 \2|p' | head -1)
|
||||
- if [ "${CI_JOB_STATUS}" = "success" ] || [ "${CI_PIPELINE_SOURCE}" = "merge_request_event" ]; then exit 0; fi
|
||||
- |
|
||||
REASON_DETAILS=""
|
||||
if git rebase --abort; then
|
||||
# Rebase failed; try applying recent commits from the base branch on top of the branch being rebased to determine which one introduces conflicts
|
||||
git rebase --rebase-merges "${CI_COMMIT_SHA}" "${BASE_COMMIT}" || true
|
||||
CONFLICT_COMMIT="$(git status | sed -nE 's/^\s*(pick|merge -C) ([0-9a-f]+).*/\2/p' | head -1 | git rev-list -n 1 --stdin)"
|
||||
CONFLICT_COMMIT="$(git rev-parse REBASE_HEAD)"
|
||||
CONFLICT_COMMIT_AUTHOR="$(git log --max-count=1 --pretty="@%al" "${CONFLICT_COMMIT}")"
|
||||
CONFLICT_COMMIT_MERGE="$(git log --reverse --merges --pretty="%H" "${CONFLICT_COMMIT}..${BASE_COMMIT}" | head -1)"
|
||||
read -r CONFLICT_COMMIT_MERGE_REQUEST_PROJECT CONFLICT_COMMIT_MERGE_REQUEST_ID < <(git log --max-count=1 "${CONFLICT_COMMIT_MERGE}" | sed -n -E 's|^\s*See merge request ([a-z-]+/bind9)!([0-9]+).*|\1 \2|p' | head -1)
|
||||
REASON="merge conflict introduced by a change in the base branch"
|
||||
REASON_DETAILS="${REASON_DETAILS}\n**First bad commit**: [${CONFLICT_COMMIT}](https://gitlab.isc.org/${CONFLICT_COMMIT_MERGE_REQUEST_PROJECT}/-/commit/${CONFLICT_COMMIT}) (authored by ${CONFLICT_COMMIT_AUTHOR})"
|
||||
REASON_DETAILS="${REASON_DETAILS}\n**First bad merge request**: https://gitlab.isc.org/${CONFLICT_COMMIT_MERGE_REQUEST_PROJECT}/-/merge_requests/${CONFLICT_COMMIT_MERGE_REQUEST_ID}"
|
||||
else
|
||||
# Rebase did not fail; most likely, this is a build failure, or the job was canceled
|
||||
CONFLICT_COMMIT="${OLDEST_MERGE_COMMIT}"
|
||||
if [ "${CI_JOB_STATUS}" = "failed" ]; then
|
||||
if [ -f ".git-push-failed" ]; then
|
||||
REASON="branch was updated during rebase"
|
||||
|
|
@ -2754,15 +2762,27 @@ merged-metadata:
|
|||
REASON="job was canceled"
|
||||
fi
|
||||
fi
|
||||
CONFLICT_COMMIT_AUTHOR="$(git log --max-count=1 --pretty="@%al" "${CONFLICT_COMMIT}")"
|
||||
MSG="#### :rotating_light: Autorebase error for branch \`${CI_COMMIT_REF_NAME}\` :rotating_light:"
|
||||
MSG="${MSG}\n**Job**: ${CI_JOB_URL}"
|
||||
MSG="${MSG}\n**Reason**: ${REASON}"
|
||||
MSG="${MSG}\n**First bad commit**: [${CONFLICT_COMMIT}](https://gitlab.isc.org/${OLDEST_MERGE_REQUEST_PROJECT}/-/commit/${CONFLICT_COMMIT}) (authored by ${CONFLICT_COMMIT_AUTHOR})"
|
||||
MSG="${MSG}\n**First bad merge request**: https://gitlab.isc.org/${OLDEST_MERGE_REQUEST_PROJECT}/-/merge_requests/${OLDEST_MERGE_REQUEST_ID}"
|
||||
MSG="${MSG}${REASON_DETAILS}"
|
||||
- |
|
||||
curl -s -o /dev/null -X POST -H content-type:application/json -d '{"channel":"bind-9-team", "text": "'"${MSG}"'" }' "${MATTERMOST_WEBHOOK_URL}"
|
||||
|
||||
autorebase-merge-request:
|
||||
<<: *autorebase
|
||||
stage: quick-checks
|
||||
resource_group: null
|
||||
before_script:
|
||||
- git fetch --depth="${GIT_DEPTH}" origin "${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}" "${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}"
|
||||
- export BASE_PROJECT="isc-private/bind9"
|
||||
- export BASE_COMMIT="$(git rev-parse "origin/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}")"
|
||||
- export REWRITE_CHERRY_PICKS_FROM="security-main"
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE == "isc-private" && $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^security-(bind-9\.[0-9]+)$/'
|
||||
when: manual
|
||||
allow_failure: true
|
||||
|
||||
autorebase-trigger-security:
|
||||
<<: *autorebase_common
|
||||
rules:
|
||||
|
|
@ -2773,6 +2793,7 @@ autorebase-trigger-security:
|
|||
REBASE_ONLY: 1
|
||||
BASE_PROJECT: isc-projects/bind9
|
||||
BASE_COMMIT: "${CI_COMMIT_SHA}"
|
||||
REWRITE_CHERRY_PICKS_FROM: security-main
|
||||
trigger:
|
||||
project: isc-private/bind9
|
||||
branch: "security-${CI_COMMIT_BRANCH}"
|
||||
|
|
|
|||
|
|
@ -281,25 +281,30 @@ if is_backport:
|
|||
else: # check for commit IDs once original MR is merged
|
||||
original_mr_commits = list(original_mr.commits(all=True))
|
||||
backport_mr_commits = list(mr.commits(all=True))
|
||||
for orig_commit in original_mr_commits:
|
||||
for backport_commit in backport_mr_commits:
|
||||
if orig_commit.id in backport_commit.message:
|
||||
break
|
||||
missing_commits = []
|
||||
for orig_id in (o.id for o in original_mr_commits):
|
||||
if not any(b for b in backport_mr_commits if orig_id in b.message):
|
||||
missing_commits.append(orig_id)
|
||||
if missing_commits:
|
||||
msg = (
|
||||
f"The following commits from original MR !{original_mr_id} "
|
||||
"are not referenced in any of the backport commits:"
|
||||
)
|
||||
msg += "<ul>"
|
||||
msg += "".join(f"<li>{orig_id}</li>" for orig_id in missing_commits)
|
||||
msg += "</ul>"
|
||||
if not is_full_backport:
|
||||
message(msg)
|
||||
else:
|
||||
msg = (
|
||||
f"Commit {orig_commit.id} from original MR !{original_mr_id} "
|
||||
"is not referenced in any of the backport commits."
|
||||
if target_branch.startswith("security-"):
|
||||
msg += ":bulb: Try running the `autorebase-merge-request` job. "
|
||||
msg += (
|
||||
"Please use `-x` when cherry-picking to include "
|
||||
"the full original commit ID. Alternatively, use the "
|
||||
"`Backport::Partial` label if not all original "
|
||||
"commits are meant to be backported."
|
||||
)
|
||||
if not is_full_backport:
|
||||
message(msg)
|
||||
else:
|
||||
msg += (
|
||||
" Please use `-x` when cherry-picking to include "
|
||||
"the full original commit ID. Alternately, use the "
|
||||
"`Backport::Partial` label if not all original "
|
||||
"commits are meant to be backported."
|
||||
)
|
||||
fail(msg)
|
||||
fail(msg)
|
||||
else:
|
||||
if not version_labels:
|
||||
fail(
|
||||
|
|
|
|||
Loading…
Reference in a new issue