Skip to content

Commit

Permalink
auto-backport: update init configuration
Browse files Browse the repository at this point in the history
Based on all changes done in scylla-pkg, updating machine-image for
recent auto-backport working version

(cherry picked from commit 69ca65f)
  • Loading branch information
yaronkaikov committed Nov 24, 2024
1 parent 99a3617 commit 1c24567
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 28 deletions.
53 changes: 27 additions & 26 deletions .github/scripts/auto-backport.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
from git import Repo, GitCommandError

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
try:
github_token = os.environ["GITHUB_TOKEN"]
except KeyError:
print("Please set the 'GITHUB_TOKEN' environment variable")
sys.exit(1)


def is_pull_request():
Expand Down Expand Up @@ -57,7 +62,7 @@ def get_pr_commits(repo, pr, stable_branch, start_commit=None):
commits = []
if pr.merged:
merge_commit = repo.get_commit(pr.merge_commit_sha)
if len(merge_commit.parents) > 1: # Check if this merge commit include multiple commits
if len(merge_commit.parents) > 1: # Check if this merge commit includes multiple commits
commits.append(pr.merge_commit_sha)
else:
if start_commit:
Expand All @@ -67,13 +72,13 @@ def get_pr_commits(repo, pr, stable_branch, start_commit=None):
for commit in pr.get_commits():
for promoted_commit in promoted_commits:
commit_title = commit.commit.message.splitlines()[0]
# In Scylla-pkg and scylla-dtest for example, we don't create a merge commit for a PR with multiple commits,
# according to the GitHub API, the last commit will be the merge commit which is not what we need when backporting (we need all the commits).
# In Scylla-pkg and scylla-dtest, for example,
# we don't create a merge commit for a PR with multiple commits,
# according to the GitHub API, the last commit will be the merge commit,
# which is not what we need when backporting (we need all the commits).
# So here, we are validating the correct SHA for each commit so we can cherry-pick
if promoted_commit.commit.message.startswith(commit_title):
commits.append(promoted_commit.sha)
else:
commits.append(start_commit)

elif pr.state == 'closed':
events = pr.get_issue_events()
Expand All @@ -83,15 +88,16 @@ def get_pr_commits(repo, pr, stable_branch, start_commit=None):
return commits


def backport(repo, pr, version, commits, backport_base_branch):
def backport(repo, pr, version, commits, backport_base_branch, user):
with (tempfile.TemporaryDirectory() as local_repo_path):
try:
new_branch_name = f'backport/{pr.number}/to-{version}'
backport_pr_title = f'[Backport {version}] {pr.title}'
repo_local = Repo.clone_from(f'https://github.com/{repo.full_name}.git', local_repo_path, branch=backport_base_branch)
repo_local = Repo.clone_from(f'https://{user.login}:{github_token}@github.com/{repo.full_name}.git', local_repo_path, branch=backport_base_branch)
repo_local.git.checkout(b=new_branch_name)
fork_repo = pr.user.get_repo(repo.full_name.split('/')[1])
repo_local.create_remote('fork', fork_repo.clone_url)
fork_repo_url = f'https://{user.login}:{github_token}@github.com/{fork_repo.full_name}.git'
repo_local.create_remote('fork', fork_repo_url)
remote = 'origin'
is_draft = False
for commit in commits:
Expand All @@ -110,46 +116,39 @@ def backport(repo, pr, version, commits, backport_base_branch):
logging.warning(f"GitCommandError: {e}")


def get_prs_from_commits(repo, commits):
for sha1 in commits:
commit = repo.get_commit(sha1.sha)
for parent in commit.parents:
prs = repo.get_pulls(state="closed", head=parent.sha)
if prs:
yield prs[0]
break


def main():
args = parse_args()
base_branch = args.base_branch.split('/')[2]
promoted_label = 'promoted-to-master'
repo_name = args.repo
if 'scylla-enterprise' in args.repo:
promoted_label = 'promoted-to-enterprise'
if args.repo in ('scylladb/scylla', 'scylladb/scylla-enterprise'):
stable_branch = base_branch
backport_branch = 'branch-'
if args.repo == 'scylladb/scylla-enterprise':
promoted_label = 'promoted-to-enterprise'
else:
backport_branch = f'{base_branch}-'
if base_branch == 'next':
backport_branch = 'next-'
if base_branch in ('master', 'next'):
stable_branch = 'master'
elif base_branch in ('enterprise', 'next-enterprise'):
stable_branch = 'enterprise'
else:
stable_branch = base_branch.replace('next', 'branch')

github_token = os.getenv("BACKPORT_GITHUB_TOKEN")
backport_label_pattern = re.compile(r'backport/\d+\.\d+$')

g = Github(github_token)
repo = g.get_repo(repo_name)
user = g.get_user()
closed_prs = []
start_commit = None

if args.commits:
start_commit, end_commit = args.commits.split('..')
commits = repo.compare(start_commit, end_commit).commits
prs = get_prs_from_commits(repo, commits)
closed_prs = list(prs)
for commit in commits:
for pr in commit.get_pulls():
closed_prs.append(pr)
if args.pull_request:
start_commit = args.head_commit
pr = repo.get_pull(args.pull_request)
Expand All @@ -159,15 +158,17 @@ def main():
labels = [label.name for label in pr.labels]
backport_labels = [label for label in labels if backport_label_pattern.match(label)]
if promoted_label not in labels:
print(f'no {promoted_label} label: {pr.number}')
continue
if not backport_labels:
print(f'no backport label: {pr.number}')
continue
commits = get_pr_commits(repo, pr, stable_branch, start_commit)
logging.info(f"Found PR #{pr.number} with commit {commits} and the following labels: {backport_labels}")
for backport_label in backport_labels:
version = backport_label.replace('backport/', '')
backport_base_branch = backport_label.replace('backport/', backport_branch)
backport(repo, pr, version, commits, backport_base_branch)
backport(repo, pr, version, commits, backport_base_branch, user)


if __name__ == "__main__":
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/add-label-when-promoted.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,18 @@ jobs:
ref: ${{ env.DEFAULT_BRANCH }}
token: ${{ secrets.AUTO_BACKPORT_TOKEN }}
fetch-depth: 0 # Fetch all history for all tags and branches
- name: Set up Git identity
run: |
git config --global user.name "GitHub Action"
git config --global user.email "[email protected]"
- name: Install dependencies
run: sudo apt-get install -y python3-github python3-git
- name: Run python script
if: github.event_name == 'push'
env:
GITHUB_TOKEN: ${{ secrets.AUTO_BACKPORT_TOKEN }}
run: python .github/scripts/search_commits.py --commits ${{ github.event.before }}..${{ github.sha }} --repository ${{ github.repository }} --ref ${{ github.ref }}
- name: Run auto-backport.py whe promotion completed
- name: Run auto-backport.py when promotion completed
if: github.event_name == 'push'
env:
GITHUB_TOKEN: ${{ secrets.AUTO_BACKPORT_TOKEN }}
Expand All @@ -63,4 +67,4 @@ jobs:
if: github.event_name == 'pull_request_target' && steps.check_label.outputs.backport_label == 'true' && (github.event.pull_request.state == 'closed' && github.event.pull_request.merged == true)
env:
GITHUB_TOKEN: ${{ secrets.AUTO_BACKPORT_TOKEN }}
run: python .github/scripts/auto-backport.py --repo ${{ github.repository }} --base-branch ${{ github.ref }} --pull-request ${{ github.event.pull_request.number }} --head-commit ${{ github.sha }}
run: python .github/scripts/auto-backport.py --repo ${{ github.repository }} --base-branch ${{ github.ref }} --pull-request ${{ github.event.pull_request.number }} --head-commit ${{ github.event.pull_request.base.sha }}

0 comments on commit 1c24567

Please sign in to comment.