Skip to content

Commit

Permalink
fix(gha): [SDK-2032] Fix dependabot merger
Browse files Browse the repository at this point in the history
  • Loading branch information
nsingh-branch authored Oct 23, 2023
1 parent 8e353a9 commit 6ad4a9d
Showing 1 changed file with 125 additions and 93 deletions.
218 changes: 125 additions & 93 deletions .github/workflows/dependabot-merger.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
name: Merge Dependabot PRs

on:
schedule:
- cron: "0 9 * * 1" # Run this workflow every Monday at 9:00
Expand All @@ -7,120 +8,151 @@ on:
jobs:
merge:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
with:
ref: master

- name: Authenticate GitHub CLI
run: echo "${{ secrets.DEPENDABOT_MERGER_PAT }}" | gh auth login --with-token

- name: Set Git user identity
run: |
git config user.email "[email protected]"
git config user.name "Dependabot Merger Bot"

- name: Get current date and time
id: datetime
run: echo "date=$(date +'%m-%d-%Y-%H-%M')" >> $GITHUB_OUTPUT

- name: Create new branch based on date and time
run: |
NEW_BRANCH="dependabot-test-${{ steps.datetime.outputs.date }}"
git checkout -b $NEW_BRANCH
git push origin $NEW_BRANCH
- name: Get list of PRs from dependabot
id: pr_list
steps:
- name: Get current on-call
id: on-call
run: |
PR_LIST=$(gh pr list --json number,author,headRefName --jq '.[] | select( .author.is_bot == true and .author.login == "app/dependabot" ) | "\(.number) \(.headRefName)"')
PR_LIST=$(echo "$PR_LIST" | tr -d '\r')
if [ -z "$PR_LIST" ]; then
echo "No PRs from dependabot found."
exit 0
fi
PR_COUNT=$(echo "$PR_LIST" | wc -l)
echo "$PR_COUNT PR's to be merged."
now=$(date -u +%Y-%m-%dT%H:%M:%SZ)
end_time=$(date -u -d '+24 hour' +%Y-%m-%dT%H:%M:%SZ)
oncall=$(curl --request GET \
--url "https://api.pagerduty.com/oncalls?since=$now&until=$end_time&schedule_ids[]=PQLHTOP" \
--header 'Accept: application/vnd.pagerduty+json;version=2' \
--header "Authorization: Token token=${{ secrets.PAGERDUTY_TOKEN }}" \
--header 'Content-Type: application/json' )
engineer_name=$(echo "$oncall" | jq -r '.oncalls[0].user.summary')
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "prs<<$EOF" >> $GITHUB_OUTPUT
echo "$PR_LIST" >> $GITHUB_OUTPUT
echo "$EOF" >> $GITHUB_OUTPUT
declare -A engineer_to_slackid
engineer_to_slackid=(
["Nipun Singh"]="U02AMC70R6E"
["Jagadeesh Karicherla"]="U038BDE0XUZ"
["Gabe De Luna"]="U02MDA0PHK5"
["Ernest Cho"]="UCV77QDSL"
["Nidhi Dixit"]="U02GDFBP88N"
)
slack_id=${engineer_to_slackid["$engineer_name"]}
echo "oncall_slack_id=$slack_id" >> $GITHUB_OUTPUT
- name: Merge PRs into new branch
run: |
NEW_BRANCH="dependabot-test-${{ steps.datetime.outputs.date }}"
git checkout $NEW_BRANCH
PR_LIST="${{ steps.pr_list.outputs.prs }}"
while IFS= read -r line; do
IFS=' ' read -r PR_NUMBER BRANCH_NAME <<< "$line"
echo "Merging PR #$PR_NUMBER from branch $BRANCH_NAME into $NEW_BRANCH..."
git fetch origin $BRANCH_NAME
git merge --no-commit --allow-unrelated-histories --strategy-option=theirs origin/$BRANCH_NAME
echo "Pushing changes to $NEW_BRANCH..."
git commit -m "Merged PR #$PR_NUMBER into $NEW_BRANCH"
git push origin $NEW_BRANCH
done <<< "$PR_LIST"
- name: Create PR
uses: actions/github-script@v6
id: create-pr
with:
script: |
const uniqueBranchName = 'dependabot-combined-prs-' + Date.now().toString();
const pulls = await github.paginate('GET /repos/:owner/:repo/pulls', {
owner: context.repo.owner,
repo: context.repo.repo
});
let branchesAndPRStrings = [];
let baseBranch = null;
let baseBranchSHA = null;
for (const pull of pulls) {
const branch = pull['head']['ref'];
if (branch.startsWith('dependabot/')) {
console.log('Branch matched prefix. Adding to array: ' + branch);
const prString = '#' + pull['number'] + ' ' + pull['title'];
branchesAndPRStrings.push({ branch, prString });
baseBranch = pull['base']['ref'];
baseBranchSHA = pull['base']['sha'];
}
}
if (branchesAndPRStrings.length == 0) {
core.setFailed('There are no open dependabot PRs.');
return;
}
try {
await github.rest.git.createRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: 'refs/heads/' + uniqueBranchName,
sha: baseBranchSHA
});
} catch (error) {
console.log(error);
core.setFailed('Failed to create combined branch');
return;
}
- name: Merge process status
run: |
echo "Merging process completed successfully!"
echo "New branch name: dependabot-test-${{ steps.datetime.outputs.date }}"
let combinedPRs = [];
let mergeFailedPRs = [];
for(const { branch, prString } of branchesAndPRStrings) {
try {
await github.rest.repos.merge({
owner: context.repo.owner,
repo: context.repo.repo,
base: uniqueBranchName,
head: branch,
});
console.log('Merged branch ' + branch);
combinedPRs.push(prString);
} catch (error) {
console.log('Failed to merge branch ' + branch);
mergeFailedPRs.push(prString);
}
}
- name: Generate PR links
id: pr_links
run: |
PR_LIST="${{ steps.pr_list.outputs.prs }}"
PR_LINKS=""
while IFS= read -r line; do
IFS=' ' read -r PR_NUMBER BRANCH_NAME <<< "$line"
PR_URL="https://github.com/${GITHUB_REPOSITORY}/pull/$PR_NUMBER"
PR_LINKS+="\n• <$PR_URL|#${PR_NUMBER}: ${BRANCH_NAME}>"
done <<< "$PR_LIST"
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "pr_links<<$EOF" >> $GITHUB_OUTPUT
echo "$PR_LINKS" >> $GITHUB_OUTPUT
echo "$EOF" >> $GITHUB_OUTPUT
console.log('Creating combined PR');
const combinedPRsString = combinedPRs.join('\n');
let body = '✅ This PR was created by the Merge Dependabot PRs action by combining the following dependabot PRs:\n' + combinedPRsString;
if(mergeFailedPRs.length > 0) {
const mergeFailedPRsString = mergeFailedPRs.join('\n');
body += '\n\n⚠️ The following dependabot PRs were left out due to merge conflicts:\n' + mergeFailedPRsString
}
let response = await github.rest.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: 'Combined Dependabot PR',
head: uniqueBranchName,
base: baseBranch,
body: body
});
console.log('Created combined PR: ' + response.data.html_url);
core.setOutput('pr_url', response.data.html_url);
core.setOutput('pr_list', combinedPRsString);
- name: Post to a Slack channel
uses: slackapi/[email protected]
id: slack
with:
channel-id: "C03RTLRKJQP"
payload: |
{
"blocks": [
"text": "iOS: New Dependabot PR Awaiting Review",
"blocks": [
{
"type": "header",
"text": {
"type": "header",
"text": {
"type": "plain_text",
"text": "⚡️ New iOS Dependabot Testing Branch",
"text":"📱🔧 iOS: New Dependabot PR Awaiting Review",
"emoji": true
}
}
},
{
"type": "section",
"text": {
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Included PRs:*${{ steps.pr_links.outputs.pr_links }}"
}
"text": "*Included PRs:*\n${{ steps.create-pr.outputs.pr_list }}\n\n\nCurrent On-Call: *<${{ steps.on-call.outputs.oncall_slack_id }}>*"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Checkout Test Branch",
"emoji": true
},
"value": "branch-button",
"url": "https://github.com/${{ github.repository }}/tree/dependabot-test-${{ steps.datetime.outputs.date }}",
"action_id": "link-action"
}
]
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": ":github-pull-request-open: View Combined PR",
"emoji": true
},
"value": "pr-button",
"url": "${{ steps.create-pr.outputs.pr_url }}",
"action_id": "link-action",
"style": "primary"
}
]
}
]
}
Expand Down

0 comments on commit 6ad4a9d

Please sign in to comment.