From 6a98c1504a938b4cb729268aeb8a460f8f963531 Mon Sep 17 00:00:00 2001 From: Mintu Date: Sun, 17 Dec 2023 14:51:06 +0530 Subject: [PATCH 1/5] implemment pagination --- .../automerge-for-humans-merging.yml | 52 +++++++++++-------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/.github/workflows/automerge-for-humans-merging.yml b/.github/workflows/automerge-for-humans-merging.yml index 9ba0be90..85cf52d5 100644 --- a/.github/workflows/automerge-for-humans-merging.yml +++ b/.github/workflows/automerge-for-humans-merging.yml @@ -21,27 +21,37 @@ jobs: if: github.event.pull_request.draft == false && (github.event.pull_request.user.login != 'asyncapi-bot' || github.event.pull_request.user.login != 'dependabot[bot]' || github.event.pull_request.user.login != 'dependabot-preview[bot]') #it runs only if PR actor is not a bot, at least not a bot that we know runs-on: ubuntu-latest steps: - - name: Get list of authors - uses: sergeysova/jq-action@v2 - id: authors - with: - # This cmd does following (line by line): - # 1. CURL querying the list of commits of the current PR via GH API. Why? Because the current event payload does not carry info about the commits. - # 2. Iterates over the previous returned payload, and creates an array with the filtered results (see below) so we can work wit it later. An example of payload can be found in https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#webhook-payload-example-34. - # 3. Grabs the data we need for adding the `Co-authored-by: ...` lines later and puts it into objects to be used later on. - # 4. Filters the results by excluding the current PR sender. We don't need to add it as co-author since is the PR creator and it will become by default the main author. - # 5. Removes repeated authors (authors can have more than one commit in the PR). - # 6. Builds the `Co-authored-by: ...` lines with actual info. - # 7. Transforms the array into plain text. Thanks to this, the actual stdout of this step can be used by the next Workflow step (wich is basically the automerge). - cmd: | - curl -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${{ secrets.GH_TOKEN }}" "${{github.event.pull_request._links.commits.href}}?per_page=100" | - jq -r '[.[] - | {name: .commit.author.name, email: .commit.author.email, login: .author.login}] - | map(select(.login != "${{github.event.pull_request.user.login}}")) - | unique - | map("Co-authored-by: " + .name + " <" + .email + ">") - | join("\n")' - multiline: true + - name: fetch commits and authors + id: fetch-commits-and-authors + run: | + page = 1 + per_page = 100 + commits=() + + while : ; do + result = $(curl -s -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${{ secrets.GH_TOKEN }}" "${{ github.event.pull_request._links.commits.href }}?per_page=$per_page&page=$page") + + if [ $(echo "$result" | jq length ) -eq 0 ]; then + break + fi + commits+=("$result") + ((page++)) + done + + co_authors=() + for commit in "${commits[@]}"; do + authors=$(echo "$commit" | jq -r '.[] | {name: .commit.author.name, email: .commit.author.email, login: .author.login} | select(.login != "${{github.event.pull_request.user.login}}")') + + while read -r author; do + name=$(echo "$author" | jq -r '.name') + email=$(echo "$author" | jq -r '.email') + co_authors+=("Co-authored-by: $name <$email>") + done <<< "$authors" + done + + co_authors=$(echo "${co_authors[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ') + + echo "::set-output name=co_authors::$co_authors" - name: Automerge PR uses: pascalgn/automerge-action@22948e0bc22f0aa673800da838595a3e7347e584 #v0.15.6 https://github.com/pascalgn/automerge-action/releases/tag/v0.15.6 env: From a4bda300c1e2138c429712e3354efb36f246ae64 Mon Sep 17 00:00:00 2001 From: Mintu Gogoi <127925465+Min2who@users.noreply.github.com> Date: Sun, 14 Jan 2024 10:42:25 +0000 Subject: [PATCH 2/5] added the co-authored by to next line --- .../automerge-for-humans-merging.yml | 106 ++++++++++++------ 1 file changed, 71 insertions(+), 35 deletions(-) diff --git a/.github/workflows/automerge-for-humans-merging.yml b/.github/workflows/automerge-for-humans-merging.yml index 85cf52d5..6aa34ff2 100644 --- a/.github/workflows/automerge-for-humans-merging.yml +++ b/.github/workflows/automerge-for-humans-merging.yml @@ -1,7 +1,3 @@ -# This workflow is centrally managed in https://github.com/asyncapi/.github/ -# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo - -# Purpose of this workflow is to allow people to merge PR without a need of maintainer doing it. If all checks are in place (including maintainers approval) - JUST MERGE IT! name: Automerge For Humans on: @@ -18,48 +14,88 @@ on: jobs: automerge-for-humans: - if: github.event.pull_request.draft == false && (github.event.pull_request.user.login != 'asyncapi-bot' || github.event.pull_request.user.login != 'dependabot[bot]' || github.event.pull_request.user.login != 'dependabot-preview[bot]') #it runs only if PR actor is not a bot, at least not a bot that we know + if: + github.event.pull_request.draft == false && + (github.event.pull_request.user.login != 'asyncapi-bot' && + github.event.pull_request.user.login != 'dependabot[bot]' && + github.event.pull_request.user.login != 'dependabot-preview[bot]') + runs-on: ubuntu-latest + steps: - - name: fetch commits and authors - id: fetch-commits-and-authors - run: | - page = 1 - per_page = 100 - commits=() + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: '16' - while : ; do - result = $(curl -s -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${{ secrets.GH_TOKEN }}" "${{ github.event.pull_request._links.commits.href }}?per_page=$per_page&page=$page") + - name: Install dependencies + run: npm install @octokit/core @octokit/plugin-paginate-rest @octokit/rest cross-fetch - if [ $(echo "$result" | jq length ) -eq 0 ]; then - break - fi - commits+=("$result") - ((page++)) - done + - name: Get List of authors + id: authors + uses: actions/github-script@v5 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { Octokit } = require('@octokit/rest'); + const { paginateRest } = require('@octokit/plugin-paginate-rest'); - co_authors=() - for commit in "${commits[@]}"; do - authors=$(echo "$commit" | jq -r '.[] | {name: .commit.author.name, email: .commit.author.email, login: .author.login} | select(.login != "${{github.event.pull_request.user.login}}")') + const fetch = require('cross-fetch'); - while read -r author; do - name=$(echo "$author" | jq -r '.name') - email=$(echo "$author" | jq -r '.email') - co_authors+=("Co-authored-by: $name <$email>") - done <<< "$authors" - done + const token = process.env.GITHUB_TOKEN; + const prNumber = process.env.PR_NUMBER; + const repository = process.env.GITHUB_REPOSITORY; - co_authors=$(echo "${co_authors[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ') + async function getCoAuthors() { + try { + const octokit = new Octokit({ + auth: token, + request: { + fetch, + }, + }); + + const commitsResponse = await octokit.paginate("GET /repos/{owner}/{repo}/pulls/{pull_number}/commits", { + owner: repository.split('/')[0], + repo: repository.split('/')[1], + pull_number: ${{ github.event.number }}, + per_page: 100, + }); + + const authors = commitsResponse + .map(data => ({ + name: data.commit.author.name, + email: data.commit.author.email, + login: data.commit.author.login, + })) + .filter(author => author.login !== 'PR_sender_login') + .reduce((uniqueAuthors, author) => { + if (!uniqueAuthors.some(a => a.email === author.email)) { + uniqueAuthors.push(author); + } + return uniqueAuthors; + }, []) + .map(author => `Co-authored-by: ${author.name} <${author.email}>`) + .join('\n'); + console.log(authors); + return authors; + } catch (error) { + console.error('Error fetching commits:', error); + return null; + } + } + + await getCoAuthors(); - echo "::set-output name=co_authors::$co_authors" - name: Automerge PR - uses: pascalgn/automerge-action@22948e0bc22f0aa673800da838595a3e7347e584 #v0.15.6 https://github.com/pascalgn/automerge-action/releases/tag/v0.15.6 + uses: pascalgn/automerge-action@v0.15.6 env: - GITHUB_TOKEN: "${{ secrets.GH_TOKEN }}" + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" MERGE_LABELS: "!do-not-merge,ready-to-merge" MERGE_METHOD: "squash" - # Using the output of the previous step (`Co-authored-by: ...` lines) as commit description. - # Important to keep 2 empty lines as https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors#creating-co-authored-commits-on-the-command-line mentions - MERGE_COMMIT_MESSAGE: "{pullRequest.title} (#{pullRequest.number})\n\n\n${{ steps.authors.outputs.value }}" + MERGE_COMMIT_MESSAGE: "{pullRequest.title} (#{pullRequest.number})\n\n\n${{ steps.authors.outputs.value }}" MERGE_RETRIES: "20" MERGE_RETRY_SLEEP: "30000" From 78732144d83cb870ef5a7696777bf13f6a2ceb98 Mon Sep 17 00:00:00 2001 From: Mintu Gogoi <127925465+Min2who@users.noreply.github.com> Date: Mon, 15 Jan 2024 17:01:33 +0000 Subject: [PATCH 3/5] done the reviewed changes --- .github/workflows/automerge-for-humans-merging.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/automerge-for-humans-merging.yml b/.github/workflows/automerge-for-humans-merging.yml index 6aa34ff2..1467aa71 100644 --- a/.github/workflows/automerge-for-humans-merging.yml +++ b/.github/workflows/automerge-for-humans-merging.yml @@ -1,3 +1,8 @@ +# This workflow is centrally managed in https://github.com/asyncapi/.github/ +# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo + +# Purpose of this workflow is to allow people to merge PR without a need of maintainer doing it. If all checks are in place (including maintainers approval) - JUST MERGE IT! + name: Automerge For Humans on: @@ -91,11 +96,13 @@ jobs: await getCoAuthors(); - name: Automerge PR - uses: pascalgn/automerge-action@v0.15.6 + uses: pascalgn/automerge-action@22948e0bc22f0aa673800da838595a3e7347e584 #v0.15.6 https://github.com/pascalgn/automerge-action/releases/tag/v0.15.6 env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + GITHUB_TOKEN: "${{ secrets.GH_TOKEN }}" MERGE_LABELS: "!do-not-merge,ready-to-merge" MERGE_METHOD: "squash" + # Using the output of the previous step (`Co-authored-by: ...` lines) as commit description. + # Important to keep 2 empty lines as https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors#creating-co-authored-commits-on-the-command-line mentions MERGE_COMMIT_MESSAGE: "{pullRequest.title} (#{pullRequest.number})\n\n\n${{ steps.authors.outputs.value }}" MERGE_RETRIES: "20" MERGE_RETRY_SLEEP: "30000" From 322078e180d6f7657f7815042908249dedc4e729 Mon Sep 17 00:00:00 2001 From: Mintu Gogoi Date: Mon, 11 Mar 2024 21:24:14 +0000 Subject: [PATCH 4/5] cleanup --- .../automerge-for-humans-merging.yml | 31 +++++-------------- 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/.github/workflows/automerge-for-humans-merging.yml b/.github/workflows/automerge-for-humans-merging.yml index 1467aa71..fd3dca60 100644 --- a/.github/workflows/automerge-for-humans-merging.yml +++ b/.github/workflows/automerge-for-humans-merging.yml @@ -29,41 +29,24 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: - node-version: '16' + node-version: '20' - name: Install dependencies run: npm install @octokit/core @octokit/plugin-paginate-rest @octokit/rest cross-fetch - name: Get List of authors id: authors - uses: actions/github-script@v5 + uses: actions/github-script@v7 with: - github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { Octokit } = require('@octokit/rest'); - const { paginateRest } = require('@octokit/plugin-paginate-rest'); - - const fetch = require('cross-fetch'); - - const token = process.env.GITHUB_TOKEN; - const prNumber = process.env.PR_NUMBER; - const repository = process.env.GITHUB_REPOSITORY; - async function getCoAuthors() { - try { - const octokit = new Octokit({ - auth: token, - request: { - fetch, - }, - }); - - const commitsResponse = await octokit.paginate("GET /repos/{owner}/{repo}/pulls/{pull_number}/commits", { + try { + const commitsResponse = await github.paginate("GET /repos/{owner}/{repo}/pulls/{pull_number}/commits", { owner: repository.split('/')[0], repo: repository.split('/')[1], pull_number: ${{ github.event.number }}, @@ -76,7 +59,7 @@ jobs: email: data.commit.author.email, login: data.commit.author.login, })) - .filter(author => author.login !== 'PR_sender_login') + .filter(author => author.email !== commitsResponse[0].commit.author.email) .reduce((uniqueAuthors, author) => { if (!uniqueAuthors.some(a => a.email === author.email)) { uniqueAuthors.push(author); From efbeb9d631337a1cf71d75d64c3c8abfc4422296 Mon Sep 17 00:00:00 2001 From: Mintu Date: Thu, 28 Mar 2024 20:22:13 +0530 Subject: [PATCH 5/5] removed `install dependencies` strep --- .github/workflows/automerge-for-humans-merging.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/automerge-for-humans-merging.yml b/.github/workflows/automerge-for-humans-merging.yml index fd3dca60..83bb6ec1 100644 --- a/.github/workflows/automerge-for-humans-merging.yml +++ b/.github/workflows/automerge-for-humans-merging.yml @@ -36,9 +36,6 @@ jobs: with: node-version: '20' - - name: Install dependencies - run: npm install @octokit/core @octokit/plugin-paginate-rest @octokit/rest cross-fetch - - name: Get List of authors id: authors uses: actions/github-script@v7