From da66b6c4788dac0c0007a0a51d4eaa0fb9b8a937 Mon Sep 17 00:00:00 2001 From: Jesse Hoffman Date: Tue, 10 Aug 2021 00:18:02 -0700 Subject: [PATCH] feat: add support for workflow_dispatch event (#51) * feat: support workflow dispatch trigger * feat: return json instead of text in fetch * feat: add PR_NUMBER to inputs * chore: add logging for troubleshooting * fix: wrong headers on get PR * chore: remove some logs * chore: update logs again * fix: broken url formatting * chore: build fix to url * chore: remove logs and cleanup * docs: add workflow docs to readme file * chore: change back to v1 lockfile * feat: use octokit instead of node-fetch * chore: retur error if no PR number is present * chore: finish unfinished error message * chore: update dist from build * chore: add better conditionals and checks for user input * chore: consolidate getter for PR * fix: add missing await keyword * chore: reduce logic and update pull request function * chroe: update pr number check logic * chore: test output * chore: log more output * chore: remove output logging and change PR number checks * chore: test PR number input * chore: log additional data * chore: use proper condition for check for PR * Update README.md Co-authored-by: Simone Busoli * docs: update parameter for pr number Co-authored-by: Simone Busoli Co-authored-by: Simone Busoli --- README.md | 39 +++++++++++++++++++++++++++++++++++ action.yml | 3 +++ dist/index.js | 48 ++++++++++++++++++++++++++++++++++++++----- src/getPullRequest.js | 22 ++++++++++++++++++++ src/index.js | 17 ++++++++++----- src/util.js | 1 + 6 files changed, 120 insertions(+), 10 deletions(-) create mode 100644 src/getPullRequest.js diff --git a/README.md b/README.md index 3e14de40..7509c655 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,9 @@ _Optional_ A flag to only auto-merge updates based on Semantic Versioning. Defau For more details on how semantic version difference calculated please see [semver](https://www.npmjs.com/package/semver) package +### `pr-number` + +_Optional_ A pull request number, only required if triggered from a workflow_dispatch event. Typically this would be triggered by a script running in a seperate CI provider. See [Trigger action from workflow_dispatch event](#trigger-action-from-workflow_dispatch-event) ## Example usage @@ -89,6 +92,42 @@ steps: approve-only: true ``` +### Trigger action from workflow_dispatch event + +If you need to trigger this action manually, you can use the [workflow_dispatch](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch) event. A use case might be that your CI runs on a seperate provider, so you would like to run this action as a result of a successful CI run. + +When using the `workflow_dispatch` approach, you will need to send the PR number as part of the input for this action: + +```yml +name: automerge + +on: + workflow_dispatch: + inputs: + pr-number: + required: true + +jobs: + automerge: + runs-on: ubuntu-latest + steps: + - uses: fastify/github-action-merge-dependabot@v2.2.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + pr-number: ${{ github.event.inputs.pr-number }} +``` + +You can initiate a call to trigger this event via [API](https://docs.github.com/en/rest/reference/actions/#create-a-workflow-dispatch-event): + +```bash +# Note: replace dynamic values with your relevant data +curl -X POST \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: token {token}" \ + https://api.github.com/repos/{owner}/{reponame}/actions/workflows/{workflow}/dispatches \ + -d '{"ref":"{ref}", "inputs":{ "pr-number": "{number}"}}' +``` + ## Notes - A GitHub token is automatically provided by Github Actions, which can be accessed using `secrets.GITHUB_TOKEN` and supplied to the action as an input `github-token`. diff --git a/action.yml b/action.yml index 77dcd66a..b9d3ef26 100644 --- a/action.yml +++ b/action.yml @@ -27,6 +27,9 @@ inputs: description: 'Auto-merge on major, minor, patch updates based on Semantic Versioning' required: false default: 'major' + pr-number: + description: 'A pull request number, only required if triggered from a workflow_dispatch event' + required: false runs: using: 'node12' main: 'dist/index.js' diff --git a/dist/index.js b/dist/index.js index 9cd45504..683b2355 100644 --- a/dist/index.js +++ b/dist/index.js @@ -6676,6 +6676,36 @@ const checkTargetMatchToPR = (prTitle, target) => { module.exports = checkTargetMatchToPR +/***/ }), + +/***/ 6754: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const github = __nccwpck_require__(5438) + +const getPullRequest = async ({ pullRequestNumber, githubToken }) => { + const payload = github.context.payload + const octokit = github.getOctokit(githubToken) + + const repo = payload.repository + const owner = repo.owner.login + const repoName = repo.name + + const { data: pullRequest } = await octokit.rest.pulls.get({ + owner, + repo: repoName, + pull_number: pullRequestNumber, + }) + + return pullRequest +} + +module.exports = getPullRequest + + /***/ }), /***/ 5013: @@ -6772,6 +6802,7 @@ exports.getInputs = () => ({ APPROVE_ONLY: /true/i.test(core.getInput('approve-only')), API_URL: core.getInput('api-url'), TARGET: getTargetInput(core.getInput('target')), + PR_NUMBER: core.getInput('pr-number'), }) @@ -9995,6 +10026,7 @@ const github = __nccwpck_require__(5438) const fetch = __nccwpck_require__(467) const checkTargetMatchToPR = __nccwpck_require__(7186) +const getPullRequest = __nccwpck_require__(6754) const { logInfo, logWarning, logError } = __nccwpck_require__(653) const { getInputs } = __nccwpck_require__(6254) @@ -10006,21 +10038,27 @@ const { APPROVE_ONLY, API_URL, TARGET, + PR_NUMBER, } = getInputs() const GITHUB_APP_URL = 'https://github.com/apps/dependabot-merge-action' async function run() { try { - const { pull_request: pr } = github.context.payload + const { pull_request } = github.context.payload - if (!pr) { + if (!pull_request && !PR_NUMBER) { return logError( - 'This action must be used in the context of a Pull Request' + 'This action must be used in the context of a Pull Request or with a Pull Request number' ) } - const pullRequestNumber = pr.number + const pr = + pull_request || + (await getPullRequest({ + pullRequestNumber: PR_NUMBER, + githubToken: GITHUB_TOKEN, + })) const isDependabotPR = pr.user.login === 'dependabot[bot]' @@ -10048,7 +10086,7 @@ async function run() { 'content-type': 'application/json', }, body: JSON.stringify({ - pullRequestNumber, + pullRequestNumber: pr.number, approveOnly: APPROVE_ONLY, excludePackages: EXCLUDE_PKGS, approveComment: MERGE_COMMENT, diff --git a/src/getPullRequest.js b/src/getPullRequest.js new file mode 100644 index 00000000..cd490e7b --- /dev/null +++ b/src/getPullRequest.js @@ -0,0 +1,22 @@ +'use strict' + +const github = require('@actions/github') + +const getPullRequest = async ({ pullRequestNumber, githubToken }) => { + const payload = github.context.payload + const octokit = github.getOctokit(githubToken) + + const repo = payload.repository + const owner = repo.owner.login + const repoName = repo.name + + const { data: pullRequest } = await octokit.rest.pulls.get({ + owner, + repo: repoName, + pull_number: pullRequestNumber, + }) + + return pullRequest +} + +module.exports = getPullRequest diff --git a/src/index.js b/src/index.js index cf118b2e..c47c3e0a 100644 --- a/src/index.js +++ b/src/index.js @@ -5,6 +5,7 @@ const github = require('@actions/github') const fetch = require('node-fetch') const checkTargetMatchToPR = require('./checkTargetMatchToPR') +const getPullRequest = require('./getPullRequest') const { logInfo, logWarning, logError } = require('./log') const { getInputs } = require('./util') @@ -16,21 +17,27 @@ const { APPROVE_ONLY, API_URL, TARGET, + PR_NUMBER, } = getInputs() const GITHUB_APP_URL = 'https://github.com/apps/dependabot-merge-action' async function run() { try { - const { pull_request: pr } = github.context.payload + const { pull_request } = github.context.payload - if (!pr) { + if (!pull_request && !PR_NUMBER) { return logError( - 'This action must be used in the context of a Pull Request' + 'This action must be used in the context of a Pull Request or with a Pull Request number' ) } - const pullRequestNumber = pr.number + const pr = + pull_request || + (await getPullRequest({ + pullRequestNumber: PR_NUMBER, + githubToken: GITHUB_TOKEN, + })) const isDependabotPR = pr.user.login === 'dependabot[bot]' @@ -58,7 +65,7 @@ async function run() { 'content-type': 'application/json', }, body: JSON.stringify({ - pullRequestNumber, + pullRequestNumber: pr.number, approveOnly: APPROVE_ONLY, excludePackages: EXCLUDE_PKGS, approveComment: MERGE_COMMENT, diff --git a/src/util.js b/src/util.js index b9cc5127..c95a1766 100644 --- a/src/util.js +++ b/src/util.js @@ -32,4 +32,5 @@ exports.getInputs = () => ({ APPROVE_ONLY: /true/i.test(core.getInput('approve-only')), API_URL: core.getInput('api-url'), TARGET: getTargetInput(core.getInput('target')), + PR_NUMBER: core.getInput('pr-number'), })