Merge commits to next branch #3142
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Merge commits to next branch | |
on: | |
schedule: | |
- cron: "0 */2 * * 1-5" # Cron timezone is in UTC | |
env: | |
TARGET_BRANCH: next | |
SOURCE_BRANCH: main | |
USERNAME: msfluid-bot | |
EMAIL: [email protected] | |
jobs: | |
check-pr: | |
runs-on: ubuntu-latest | |
if: github.repository_owner == 'microsoft' | |
steps: | |
- run: npm install @octokit/core | |
- name: Check PR exists using octokit | |
uses: actions/github-script@7a5c598405937d486b0331594b5da2b14db670da # pin@v6 | |
id: check-pr-exists | |
with: | |
token: ${{ secrets.BOT_MAIN_NEXT_WORKFLOW_PAT }} | |
script: | | |
const { Octokit } = require("@octokit/core"); | |
const token = `${{ secrets.GITHUB_TOKEN }}`; | |
const octokit = new Octokit({ auth: token }); | |
const response = await octokit.request('GET /repos/{owner}/{repo}/pulls', { | |
owner: 'microsoft', | |
repo: 'FluidFramework' | |
}); | |
console.log("data----", response); | |
console.log("items----", response.data); | |
console.log("length---", response.data.length); | |
for(let i=0; i<response.data.length; i++) { | |
if(response.data[i].title === 'Automation: Main Next Integrate') { | |
return true; | |
} | |
} | |
return false; | |
outputs: | |
EXISTS: ${{ steps.check-pr-exists.outputs.result }} | |
dequeue: | |
runs-on: ubuntu-latest | |
needs: [check-pr] | |
if: needs.check-pr.outputs.EXISTS == 'false' | |
steps: | |
- run: npm install @azure/storage-queue | |
- uses: actions/github-script@7a5c598405937d486b0331594b5da2b14db670da # pin@v6 | |
id: dequeue-message | |
with: | |
script: | | |
const { QueueClient, QueueServiceClient } = require('@azure/storage-queue') | |
const connectionString = `${{ secrets.AZURE_STORAGE_CONNECTION_STRING }}`; | |
const queueName = `${{ secrets.AZURE_QUEUE_NAME }}`; | |
const queueServiceClient = QueueServiceClient.fromConnectionString(connectionString); | |
const queueClient = queueServiceClient.getQueueClient(queueName); | |
// Peek at messages in the queue | |
const peekedMessages = await queueClient.peekMessages({ numberOfMessages: 5 }); | |
let firstMessage; | |
for (i = 0; i < peekedMessages.peekedMessageItems.length; i++) { | |
// Display the peeked message | |
console.log("Peeked message: ", peekedMessages.peekedMessageItems[i].messageText); | |
firstMessage = JSON.parse(peekedMessages.peekedMessageItems[i].messageText); | |
} | |
console.log("sha---", firstMessage.sha); | |
console.log("label---", firstMessage.label); | |
console.log("author---", firstMessage.author); | |
return firstMessage; | |
outputs: | |
LABEL: ${{ fromJSON(steps.dequeue-message.outputs.result).label }} | |
AUTHOR: ${{ fromJSON(steps.dequeue-message.outputs.result).author }} | |
SHA: ${{ fromJSON(steps.dequeue-message.outputs.result).sha }} | |
create-branch: | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write | |
packages: write | |
actions: write | |
checks: write | |
issues: write | |
pull-requests: write | |
statuses: write | |
needs: [dequeue] | |
if: (needs.dequeue.result) == 'success' | |
steps: | |
- name: Git checkout | |
if: ${{needs.dequeue.outputs.LABEL}} == 'queued' | |
uses: actions/checkout@7884fcad6b5d53d10323aee724dc68d8b9096a2e # pin@v2 | |
with: | |
token: ${{ secrets.BOT_MAIN_NEXT_WORKFLOW_PAT }} | |
fetch-depth: "0" | |
- name: Create branch | |
if: ${{needs.dequeue.outputs.LABEL}} == 'queued' | |
run: | | |
git config user.name $USERNAME | |
git config user.email $EMAIL | |
git fetch origin | |
git checkout $SOURCE_BRANCH | |
git checkout -b main-next-${{needs.dequeue.outputs.SHA}} | |
git fetch --all | |
git reset --hard ${{needs.dequeue.outputs.SHA}} | |
git push --set-upstream origin main-next-${{needs.dequeue.outputs.SHA}} | |
pull-request: | |
runs-on: ubuntu-latest | |
concurrency: | |
group: group-pr | |
cancel-in-progress: false | |
needs: [create-branch, dequeue] | |
if: needs.create-branch.result == 'success' | |
steps: | |
- run: npm install @octokit/core | |
- name: Create PR using octokit | |
uses: actions/github-script@7a5c598405937d486b0331594b5da2b14db670da # pin@v6 | |
with: | |
token: ${{ secrets.BOT_MAIN_NEXT_WORKFLOW_PAT }} | |
script: | | |
const { Octokit } = require("@octokit/core"); | |
const token = `${{ secrets.GITHUB_TOKEN }}`; | |
const sha = 'main-next-${{needs.dequeue.outputs.SHA}}'; | |
const author = '${{needs.dequeue.outputs.AUTHOR}}'; | |
const description = ` | |
## Main-next integrate PR | |
The aim of this pull request is to sync main and next branch. The expectation from the assignee is as follows: | |
> - Acknowledge the pull request by adding a comment -- "Actively working on it". | |
> - Resolve any merge conflicts between this branch and next (and push the resolution to this branch). Merge next into this branch if needed. **Do NOT rebase or squash this branch: its history must be preserved**. | |
> - Ensure CI is passing for this PR, fixing any issues. Please don't look into resolving **Real service e2e test** and **Stress test** failures as they are **non-required** CI failures. | |
> - Once the PR is ready for merge, please add a comment @mentioning the reviewers to get this PR merged in. Thank you!! | |
For more information about how to resolve merge conflicts and CI failures, visit [this wiki page] | |
(https://github.com/microsoft/FluidFramework/wiki/Main-next-Automation).`; | |
const octokit = new Octokit({ auth: token }) | |
const newPr = await octokit.request('POST /repos/{owner}/{repo}/pulls', { | |
owner: 'microsoft', | |
repo: 'FluidFramework', | |
title: 'Automation: Main Next Integrate', | |
body: description, | |
head: sha, | |
base: 'next' | |
}); | |
await octokit.request('POST /repos/{owner}/{repo}/issues/{issue_number}/assignees', { | |
owner: 'microsoft', | |
repo: 'FluidFramework', | |
issue_number: newPr.data.number, | |
assignees: [ author ] | |
}); | |
await octokit.request('POST /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers', { | |
owner: 'microsoft', | |
repo: 'FluidFramework', | |
pull_number: newPr.data.number, | |
reviewers: [ | |
'sonalideshpandemsft', | |
'tylerbutler', | |
'scottn12', | |
] | |
}); | |
await octokit.request('POST /repos/{owner}/{repo}/issues/{issue_number}/labels', { | |
owner: 'microsoft', | |
repo: 'FluidFramework', | |
issue_number: newPr.data.number, | |
labels: [ | |
'main-next-integrate', | |
'do-not-squash-merge', | |
'msftbot: merge-next' | |
] | |
}) | |
remove-from-queue: | |
runs-on: ubuntu-latest | |
concurrency: | |
group: group-pr | |
cancel-in-progress: false | |
needs: [pull-request] | |
if: needs.pull-request.result == 'success' | |
steps: | |
- uses: actions/checkout@7884fcad6b5d53d10323aee724dc68d8b9096a2e # pin@v2 | |
- uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561 # pin@v2 | |
with: | |
node-version: 14 | |
- run: npm ci | |
- run: npm install @azure/storage-queue | |
- uses: actions/github-script@7a5c598405937d486b0331594b5da2b14db670da # pin@v6 | |
with: | |
script: | | |
const { QueueClient, QueueServiceClient } = require('@azure/storage-queue') | |
const connectionString = `${{ secrets.AZURE_STORAGE_CONNECTION_STRING }}`; | |
const queueServiceClient = QueueServiceClient.fromConnectionString(connectionString); | |
const queueName = `${{ secrets.AZURE_QUEUE_NAME }}`; | |
const queueClient = queueServiceClient.getQueueClient(queueName); | |
// Get up to 5 messages from the queue | |
const receivedMsgsResp = await queueClient.receiveMessages({ numberOfMessages: 5, visibilityTimeout: 5 * 60 }); | |
for (i = 0; i < receivedMsgsResp.receivedMessageItems.length; i++) { | |
message = receivedMsgsResp.receivedMessageItems[i]; | |
console.log("Dequeuing message: ", message.messageText); | |
await queueClient.deleteMessage(message.messageId, message.popReceipt); | |
} |