From e442c324d4e52aae8bf940c40eedde91a4b25bb3 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Sun, 31 Oct 2021 10:53:39 -0700 Subject: [PATCH] feat: `auto-merge` option (#312) --- .github/workflows/test.yml | 23 ++++++++++++++ README.md | 3 ++ index.js | 65 ++++++++++++++++++++++++++++---------- package-lock.json | 14 ++------ package.json | 2 +- 5 files changed, 78 insertions(+), 29 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bfdb03c6..b746e36a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -104,6 +104,29 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + autoMerge: + name: "[TEST] Auto merge" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + persist-credentials: false + - run: "date > test.txt" + - run: "npm ci" + - run: "npm run build" + - uses: ./ + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ACTIONS_STEP_DEBUG: true + with: + title: Test pull request for `auto-merge` option + commit-message: "Testing auto-merge" + auto-merge: squash + branch: test-auto-merge + - run: "git push https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git :test-auto-merge" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # expect to detect changes in a hidden file: # https://github.com/gr2m/create-or-update-pull-request-action/pull/262 hiddenFile: diff --git a/README.md b/README.md index f3cf7f99..b949228c 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,11 @@ with: author: "Lorem J. Ipsum " labels: label1, label2 assignees: user1, user2 + auto-merge: squash ``` +**Note:** `auto-merge` is optional. It can be set to `merge`, `squash`, or `rebase`. If [auto-merging](https://docs.github.com/en/github/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/automatically-merging-a-pull-request) is disabled in the repository, a warning will be logged, but the action will not fail. + To create multiple commits for different paths, use the action multiple times ```yml diff --git a/index.js b/index.js index 66adca51..7d0eb8c4 100644 --- a/index.js +++ b/index.js @@ -3,9 +3,7 @@ const { inspect } = require("util"); const { command } = require("execa"); const core = require("@actions/core"); -const { - request: { defaults }, -} = require("@octokit/request"); +const { Octokit } = require("@octokit/core"); const TEMPORARY_BRANCH_NAME = `tmp-create-or-update-pull-request-action-${Math.random() .toString(36) @@ -38,10 +36,8 @@ async function main() { return; } - const request = defaults({ - headers: { - authorization: `token ${process.env.GITHUB_TOKEN}`, - }, + const octokit = new Octokit({ + auth: process.env.GITHUB_TOKEN, }); const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/"); @@ -55,14 +51,25 @@ async function main() { commitMessage: core.getInput("commit-message"), author: core.getInput("author"), labels: core.getInput("labels"), - assignees: core.getInput("assignees") + assignees: core.getInput("assignees"), + autoMerge: core.getInput("auto-merge"), }; core.debug(`Inputs: ${inspect(inputs)}`); + if ( + inputs.autoMerge && + !["merge", "squash", "rebase"].includes(inputs.autoMerge) + ) { + core.setFailed( + `auto-merge is set to "${inputs.autoMerge}", but must be one of "merge", "squash", "rebase"` + ); + process.exit(1); + } + const { data: { default_branch }, - } = await request(`GET /repos/{owner}/{repo}`, { + } = await octokit.request(`GET /repos/{owner}/{repo}`, { owner, repo, }); @@ -138,7 +145,7 @@ async function main() { if (remoteBranchExists) { const q = `head:${inputs.branch} type:pr is:open repo:${process.env.GITHUB_REPOSITORY}`; - const { data } = await request("GET /search/issues", { + const { data } = await octokit.request("GET /search/issues", { q, }); @@ -152,8 +159,8 @@ async function main() { core.debug(`Creating pull request`); const { - data: { html_url, number }, - } = await request(`POST /repos/{owner}/{repo}/pulls`, { + data: { html_url, number, node_id }, + } = await octokit.request(`POST /repos/{owner}/{repo}/pulls`, { owner, repo, title: inputs.title, @@ -167,7 +174,7 @@ async function main() { if (inputs.labels) { core.debug(`Adding labels: ${inputs.labels}`); const labels = inputs.labels.trim().split(/\s*,\s*/); - const { data } = await request( + const { data } = await octokit.request( `POST /repos/{owner}/{repo}/issues/{issue_number}/labels`, { owner, @@ -183,7 +190,7 @@ async function main() { if (inputs.assignees) { core.debug(`Adding assignees: ${inputs.assignees}`); const assignees = inputs.assignees.trim().split(/\s*,\s*/); - const { data } = await request( + const { data } = await octokit.request( `POST /repos/{owner}/{repo}/issues/{issue_number}/assignees`, { owner, @@ -196,6 +203,31 @@ async function main() { core.debug(inspect(data)); } + if (inputs.autoMerge) { + const query = ` + mutation($pullRequestId: ID!, $mergeMethod: PullRequestMergeMethod!, $commitHeadline: String!) { + enablePullRequestAutoMerge(input: {pullRequestId: $pullRequestId, mergeMethod: $mergeMethod, commitHeadline: $commitHeadline}) { + actor { + login + } + } + } + `; + try { + const result = await octokit.graphql(query, { + pullRequestId: node_id, + mergeMethod: inputs.autoMerge.toUpperCase(), + commitHeadline: inputs.title, + }); + core.info(`Auto merge enabled`); + core.debug(inspect(result)); + } catch (error) { + core.warning( + `Auto merge could not be enabled for the pull request. Make sure the feature is enabled in the repository settings` + ); + } + } + await runShellCommand(`git stash pop || true`); } catch (error) { core.info(inspect(error)); @@ -210,9 +242,8 @@ async function getLocalChanges(path) { return {}; } - const hasUncommitedChanges = /(Changes to be committed|Changes not staged|Untracked files)/.test( - output - ); + const hasUncommitedChanges = + /(Changes to be committed|Changes not staged|Untracked files)/.test(output); return { hasUncommitedChanges, diff --git a/package-lock.json b/package-lock.json index 185a7dde..5fe240b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "ISC", "dependencies": { "@actions/core": "^1.2.6", - "@octokit/request": "^5.1.0", + "@octokit/core": "^3.5.1", "execa": "^2.0.4" }, "devDependencies": { @@ -171,7 +171,6 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", - "dev": true, "dependencies": { "@octokit/types": "^6.0.3" } @@ -180,7 +179,6 @@ "version": "3.5.1", "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", - "dev": true, "dependencies": { "@octokit/auth-token": "^2.4.4", "@octokit/graphql": "^4.5.8", @@ -205,7 +203,6 @@ "version": "4.8.0", "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", - "dev": true, "dependencies": { "@octokit/request": "^5.6.0", "@octokit/types": "^6.0.3", @@ -682,8 +679,7 @@ "node_modules/before-after-hook": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", - "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==", - "dev": true + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==" }, "node_modules/bottleneck": { "version": "2.19.5", @@ -6676,7 +6672,6 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", - "dev": true, "requires": { "@octokit/types": "^6.0.3" } @@ -6685,7 +6680,6 @@ "version": "3.5.1", "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", - "dev": true, "requires": { "@octokit/auth-token": "^2.4.4", "@octokit/graphql": "^4.5.8", @@ -6710,7 +6704,6 @@ "version": "4.8.0", "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", - "dev": true, "requires": { "@octokit/request": "^5.6.0", "@octokit/types": "^6.0.3", @@ -7085,8 +7078,7 @@ "before-after-hook": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", - "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==", - "dev": true + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==" }, "bottleneck": { "version": "2.19.5", diff --git a/package.json b/package.json index ff87a386..028be64f 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "license": "ISC", "dependencies": { "@actions/core": "^1.2.6", - "@octokit/request": "^5.1.0", + "@octokit/core": "^3.5.1", "execa": "^2.0.4" }, "devDependencies": {