Skip to content

auto merge all PRs from upstream #7

Description

@milahu

so i heard you want to maintain this fork ; )

here is a script to merge all the pull requests from upstream

Details
#! /usr/bin/env bash

# bash script to automatically merge pull-requests
# form the abandoned upstream repo to this active fork

# author: milahu, license: MIT
# https://github.com/avryhof/speech_recognition/issues/7

set -e

upstream_repo_name=speech_recognition
upstream_repo_owner=Uberi
this_repo_owner=avryhof
upstream_main_branch=master
this_main_branch=$upstream_main_branch
committer_main_branch=$upstream_main_branch
committer_repo_owner=milahu # need write access to this fork
# git remote add milahu https://milahu:__password__@github.com/milahu/speech_recognition

echo "getting open pulls from https://github.com/$upstream_repo_owner/$upstream_repo_name/pulls"

#pulls_state=all
pulls_state=open # default

merge_upstream_main_branch=true
if $merge_upstream_main_branch; then
  echo "merging main branch from upstream"
  (
    set -x
    git remote add "$upstream_repo_owner" "https://github.com/$upstream_repo_owner/$upstream_repo_name" || true
    git fetch "$upstream_repo_owner" "$upstream_main_branch"
    git checkout "$this_main_branch"
  )
  rev_short=$(git rev-parse --short "$upstream_repo_owner/$upstream_main_branch")
  branch_name="merge-$upstream_repo_owner-$upstream_main_branch-$rev_short"
  if (set -x; git branch "$branch_name")
  then
    (set -x; git switch "$branch_name")
    # use "git merge" to preserve commit hashes
    if (set -x; git merge "$upstream_repo_owner/$upstream_main_branch" -m "merge branch $upstream_repo_owner/$upstream_main_branch")
    then
      #git rebase "$upstream_repo_owner/$upstream_main_branch"
      (set -x; git push "$committer_repo_owner")
      echo "create PR at $upstream_repo_owner/$upstream_repo_name: https://github.com/$committer_repo_owner/$upstream_repo_name/pull/new/$branch_name"
      echo "create PR at $committer_repo_owner/$upstream_repo_name: https://github.com/$committer_repo_owner/$upstream_repo_name/compare/$committer_main_branch...$committer_repo_owner:$branch_name"
      (set -x; git checkout "$this_main_branch")
      echo "done main branch"
    else
      (set -x; git merge --abort)
      echo "failed to auto-merge main branch -> skip"
    fi
    echo "hit enter to continue"
    read
  else
    echo "branch $branch_name exists -> skip merging main branch"
  fi
fi

[ ! -e pulls.json ] && curl -o pulls.json "https://api.github.com/repos/$upstream_repo_owner/$upstream_repo_name/pulls?state=$pulls_state"

clean_name() {
  echo "$1" | sed -E 's/[ \t]+/-/g; s/[^a-zA-Z0-9_-]//g;'
}

num_pulls=$(<pulls.json jq length)
last_index=$((num_pulls - 1))
echo "found $num_pulls open pulls"

#for ((i = 0; i < num_pulls; i++))
#for ((i = 6; i < num_pulls; i++))
for ((i = 0; i < 6; i++))
do
  echo "pull index $i of $last_index"
  json="$(<pulls.json jq ".[$i]")"
  number="$(<<<"$json" jq -r .number)"
  title="$(<<<"$json" jq -r .title)"
  author="$(<<<"$json" jq -r .user.login)"
  head_repo_name="$(<<<"$json" jq -r .head.repo.name)"
  head_repo_owner="$(<<<"$json" jq -r .head.repo.owner.login)"
  head_ref="$(<<<"$json" jq -r .head.ref)"
  head_sha="$(<<<"$json" jq -r .head.sha)"
  base_sha="$(<<<"$json" jq -r .base.sha)"
  base_ref="$(<<<"$json" jq -r .base.ref)"
  echo "original PR: https://github.com/$upstream_repo_owner/$upstream_repo_name/pull/$number"
  echo "title: $title"
  echo "author: $author"
  echo "head_repo_name: $head_repo_name"
  echo "head_repo_owner: $head_repo_owner"
  echo "head_ref: $head_ref"
  echo "head_sha: $head_sha"
  echo "base_sha: $base_sha"

  if [[ "$(<<<"$json" jq -r .head.repo)" == "null" ]]
  then
    echo "FIXME head branch was deleted? -> skip PR"
    # example https://github.com/Uberi/speech_recognition/pull/554
    echo "hit enter to continue"
    read
    continue
  fi

  title_clean=$(clean_name "$title")
  author_clean=$(clean_name "$author")

  # check if this PR was already merged
  # TODO check harder. commit hash may be different
  if [ -n "$(git branch "$this_main_branch" --contains "$head_sha" 2>/dev/null)" ]
  then
    echo "PR $number was already merged -> skip"
    continue
  fi

  # TODO check if this PR was already requested

  (
    set -x

    git fetch "$upstream_repo_owner" "$base_ref"

    git remote add "$head_repo_owner" "https://github.com/$head_repo_owner/$head_repo_name" || true
    git fetch "$head_repo_owner" "$head_ref"

    #git checkout "$head_sha"
    git checkout "$this_main_branch"
  )

  rev_short="${head_sha:0:7}"
  branch_name="merge-$upstream_repo_owner-pr$number-$rev_short-$title_clean-by-$author_clean"

  if (set -x; git branch "$branch_name")
  then

    (set -x; git switch "$branch_name")

    # use "git merge" to preserve commit hashes
    if (set -x; git merge "$head_repo_owner/$head_ref" -m "merge branch $head_repo_owner/$head_ref")
    then
      #git rebase "$upstream_repo_owner/$upstream_main_branch"
      (set -x; git push "$committer_repo_owner")
      echo "create PR at $this_repo_owner/$upstream_repo_name: https://github.com/$committer_repo_owner/$upstream_repo_name/pull/new/$branch_name"
      echo "create PR at $committer_repo_owner/$upstream_repo_name: https://github.com/$committer_repo_owner/$upstream_repo_name/compare/$committer_main_branch...$committer_repo_owner:$branch_name"
      echo "original PR: https://github.com/$upstream_repo_owner/$upstream_repo_name/pull/$number"
      (set -x; git checkout "$this_main_branch")
      echo "done PR $number"
    else
      (set -x; git merge --abort)
      echo "failed to auto-merge PR $number -> skip"
    fi
    echo "hit enter to continue"
    read
  else
    echo "branch $branch_name exists -> skip merging PR $number"
  fi

done

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions