Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCPBUGS-5537: USHIFT-601 rebase: entrypoint and create_pr.py #1242

Merged
merged 1 commit into from
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
52 changes: 37 additions & 15 deletions scripts/auto-rebase/create_pr.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,55 +15,74 @@
"""

import os
import re
import sys
from git import Repo, PushInfo # GitPython
from github import GithubIntegration, Github, GithubException # pygithub
from git import Repo, PushInfo # GitPython
from github import GithubIntegration, Github, GithubException # pygithub
from pathlib import Path

APP_ID_ENV = "APP_ID"
KEY_ENV = "KEY"
ORG_ENV = "ORG"
REPO_ENV = "REPO"
JOB_NAME_ENV = "JOB_NAME"

BOT_REMOTE_NAME = "bot-creds"
JOB_NAME_REGEXP = "periodic-ci-openshift-microshift-(.+)-periodics-rebase-on-nightlies"


def try_get_env(var_name):
val = os.getenv(var_name)
if val is None or val == "":
sys.exit(f"Env var {var_name} is empty")
return val


def get_expected_base_branch():
return re.search(JOB_NAME_REGEXP, try_get_env(JOB_NAME_ENV)).group(1)


app_id = try_get_env(APP_ID_ENV)
key_path = try_get_env(KEY_ENV)
org = try_get_env(ORG_ENV)
repo = try_get_env(REPO_ENV)
expected_base = get_expected_base_branch()


def commit_str(commit):
return f"{commit.hexsha[:8]} - {commit.summary}"


def create_or_get_pr_url(ghrepo):
prs = ghrepo.get_pulls(base='main', head=f"{org}:{r.active_branch.name}", state="all")
prs = ghrepo.get_pulls(
base=expected_base, head=f"{org}:{r.active_branch.name}", state="all")
if prs.totalCount == 1:
print(f"{prs[0].state.capitalize()} pull request exists already: {prs[0].html_url}")
print(
f"{prs[0].state.capitalize()} pull request exists already: {prs[0].html_url}")
elif prs.totalCount > 1:
print(f"Found several existing PRs for '{r.active_branch.name}': {[(x.state, x.html_url) for x in prs]}")
print(
f"Found several existing PRs for '{r.active_branch.name}': {[(x.state, x.html_url) for x in prs]}")
else:
body = f"{r.active_branch.name}\n\n/label tide/merge-method-squash"
pr = ghrepo.create_pull(title=r.active_branch.name, body=body, base='main', head=r.active_branch.name, maintainer_can_modify=True)
pr = ghrepo.create_pull(title=r.active_branch.name, body=body,
base=expected_base, head=r.active_branch.name, maintainer_can_modify=True)
print(f"Created pull request: {pr.html_url}")


integration = GithubIntegration(app_id, Path(key_path).read_text())
app_installation = integration.get_installation(org, repo)
if app_installation == None:
sys.exit(f"Failed to get app_installation for {org}/{repo}. Response: {app_installation.raw_data}")
installation_access_token = integration.get_access_token(app_installation.id).token
sys.exit(
f"Failed to get app_installation for {org}/{repo}. Response: {app_installation.raw_data}")
installation_access_token = integration.get_access_token(
app_installation.id).token
gh = Github(installation_access_token)
ghrepo = gh.get_repo(f"{org}/{repo}")

r = Repo('.')
if r.active_branch.commit == r.branches["main"].commit:
print(f"There's no new commit on branch {r.active_branch} compared to 'main'.\nLast commit: {r.active_branch.commit.hexsha[:8]} - \n\n{r.active_branch.commit.summary}'")
if r.active_branch.commit == r.branches[expected_base].commit:
print(
f"There's no new commit on branch {r.active_branch} compared to '{expected_base}'.\nLast commit: {r.active_branch.commit.hexsha[:8]} - \n\n{r.active_branch.commit.summary}'")
sys.exit(0)

remote_url = f"https://x-access-token:{installation_access_token}@github.com/{org}/{repo}"
Expand All @@ -77,11 +96,13 @@ def create_or_get_pr_url(ghrepo):
remote.fetch()

# Check if branch with the same name exists in remote
matching_remote_branches = [ ref for ref in remote.refs if BOT_REMOTE_NAME + "/" + r.active_branch.name == ref.name ]
matching_remote_branches = [
ref for ref in remote.refs if BOT_REMOTE_NAME + "/" + r.active_branch.name == ref.name]
if len(matching_remote_branches) == 1:
# Compare local and remote rebase branches by looking at their start on main branch (commit from which they branched off)
merge_base_prev_rebase = r.merge_base("main", matching_remote_branches[0].name)
merge_base_cur_rebase = r.merge_base("main", r.active_branch.name)
# Compare local and remote rebase branches by looking at their start on {expected_base} branch (commit from which they branched off)
merge_base_prev_rebase = r.merge_base(
expected_base, matching_remote_branches[0].name)
merge_base_cur_rebase = r.merge_base(expected_base, r.active_branch.name)
if merge_base_prev_rebase[0] == merge_base_cur_rebase[0]:
print(f"Branch {r.active_branch} already exists on remote and it's up to date.\n\
Branch-off commit: {commit_str(merge_base_cur_rebase[0])}\n")
Expand All @@ -94,7 +115,8 @@ def create_or_get_pr_url(ghrepo):

push_result = remote.push(r.active_branch.name, force=True)
if len(push_result) != 1:
sys.exit(f"Unexpected amount ({len(push_result)}) of items in push_result: {push_result}")
sys.exit(
f"Unexpected amount ({len(push_result)}) of items in push_result: {push_result}")
if push_result[0].flags & PushInfo.ERROR:
sys.exit(f"Pushing branch failed: {push_result[0].summary}")
if push_result[0].flags & PushInfo.FORCED_UPDATE:
Expand Down
31 changes: 31 additions & 0 deletions scripts/auto-rebase/rebase_job_entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/bash

set -o nounset
set -o errexit
set -o pipefail
set -x

echo "Environment:"
printenv

cp /secrets/ci-pull-secret/.dockercfg "$HOME/.pull-secret.json" || {
echo "WARN: Could not copy registry secret file"
}

release_amd64="$(oc get configmap/release-release-images-latest -o yaml \
| yq '.data."release-images-latest.yaml"' \
| jq -r '.metadata.name')"
release_arm64="$(oc get configmap/release-release-images-arm64-latest -o yaml \
| yq '.data."release-images-arm64-latest.yaml"' \
| jq -r '.metadata.name')"

pullspec_release_amd64="registry.ci.openshift.org/ocp/release:${release_amd64}"
pullspec_release_arm64="registry.ci.openshift.org/ocp-arm64/release-arm64:${release_arm64}"

./scripts/auto-rebase/rebase.sh to "${pullspec_release_amd64}" "${pullspec_release_arm64}"

APP_ID=$(cat /secrets/pr-creds/app_id) \
KEY=/secrets/pr-creds/key.pem \
ORG=openshift \
REPO=microshift \
./scripts/auto-rebase/create_pr.py