├── .gitignore ├── .github └── workflows │ └── ci.yml ├── package.json ├── README.md ├── index.js └── action.yml /.gitignore: -------------------------------------------------------------------------------- 1 | # JavaScript 2 | node_modules 3 | 4 | # JetBrains IDE 5 | .idea/ 6 | *.iml 7 | *.iws 8 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | - push 4 | - pull_request 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@v1 11 | - name: npm install and build 12 | run: | 13 | npm ci 14 | npm run build 15 | - name: Find Pull Request 16 | uses: ./ 17 | id: find-pull-request 18 | with: 19 | github-token: ${{ secrets.GITHUB_TOKEN }} 20 | branch: test 21 | - run: echo "Pull Request ${number} (${sha})" 22 | env: 23 | number: ${{ steps.find-pull-request.outputs.number }} 24 | sha: ${{ steps.find-pull-request.outputs.head-sha }} 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "find-pull-request-action", 3 | "private": true, 4 | "version": "1.10.0", 5 | "license": "MIT", 6 | "description": "GitHub Action for finding pull requests", 7 | "repository": "juliangruber/find-pull-request-action", 8 | "scripts": { 9 | "test": "prettier-standard index.js && standard index.js", 10 | "build": "ncc build index.js", 11 | "version": "npm run build && git add dist", 12 | "release": "np && git tag -f v1 && git push --tags -f" 13 | }, 14 | "np": { 15 | "publish": false 16 | }, 17 | "dependencies": { 18 | "@actions/core": "^1.10.0", 19 | "@actions/github": "^6.0.0" 20 | }, 21 | "devDependencies": { 22 | "@vercel/ncc": "^0.38.1", 23 | "np": "^9.2.0", 24 | "prettier-standard": "^15.0.1", 25 | "standard": "^17.1.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # find-pull-request-action 2 | 3 | A GitHub Action for finding pull requests. 4 | 5 | ## Usage 6 | 7 | ```yaml 8 | steps: 9 | - name: Find Pull Request 10 | uses: juliangruber/find-pull-request-action@v1 11 | id: find-pull-request 12 | with: 13 | branch: my-branch-name 14 | - run: echo "Pull Request ${number} (${sha})" 15 | env: 16 | number: ${{ steps.find-pull-request.outputs.number }} 17 | sha: ${{ steps.find-pull-request.outputs.head-sha }} 18 | ``` 19 | 20 | Query pull requests based on these inputs: 21 | - `branch` 22 | - `base` 23 | - `author` 24 | - `state` 25 | - `repo` 26 | - `sort` 27 | - `direction` 28 | - `labels` 29 | 30 | For the first matching pull request, these outputs will be set: 31 | - `number` 32 | - `title` 33 | - `url` 34 | - `head-ref` 35 | - `head-sha` 36 | - `base-ref` 37 | - `base-sha` 38 | - `base-repo` 39 | - `state` 40 | - `author` 41 | 42 | See [action.yml](action.yml) for more details. 43 | 44 | ## Related 45 | 46 | - [approve-pull-request-action](https://github.com/juliangruber/approve-pull-request-action) — Approve a Pull Request 47 | - [merge-pull-request-action](https://github.com/juliangruber/merge-pull-request-action) — Merge a Pull Request 48 | - [octokit-action](https://github.com/juliangruber/octokit-action) — Generic Octokit.js Action 49 | 50 | ## License 51 | 52 | MIT 53 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const core = require('@actions/core') 4 | const github = require('@actions/github') 5 | 6 | const main = async () => { 7 | const token = core.getInput('github-token') 8 | const branch = core.getInput('branch') 9 | const base = core.getInput('base') 10 | const author = core.getInput('author') 11 | const state = core.getInput('state') 12 | const sort = core.getInput('sort') 13 | const direction = core.getInput('direction') 14 | const repoString = core.getInput('repo') 15 | const labels = core.getInput('labels') 16 | 17 | let repoObject 18 | if (repoString) { 19 | const [owner, repo] = repoString.split('/') 20 | repoObject = { owner, repo } 21 | } else { 22 | repoObject = github.context.repo 23 | } 24 | 25 | const query = { 26 | ...repoObject, 27 | state 28 | } 29 | if (branch) { 30 | query.head = 31 | branch.indexOf(':') === -1 32 | ? `${github.context.repo.owner}:${branch}` 33 | : branch 34 | } 35 | if (base) { 36 | query.base = base 37 | } 38 | if (sort) { 39 | query.sort = sort 40 | } 41 | if (direction) { 42 | query.direction = direction 43 | } 44 | 45 | const octokit = github.getOctokit(token) 46 | 47 | const res = await octokit.rest.pulls.list(query) 48 | let prs = res.data 49 | if (author) { 50 | prs = prs.filter(pr => pr.user.login === author) 51 | } 52 | if (labels) { 53 | const labelNames = labels.split(',') 54 | prs = prs.filter(pr => { 55 | const prLabelNames = pr.labels.map(label => label.name) 56 | return labelNames.every(label => prLabelNames.includes(label)) 57 | }) 58 | } 59 | 60 | const pr = prs.length && prs[0] 61 | 62 | core.debug(`pr: ${JSON.stringify(pr, null, 2)}`) 63 | core.setOutput('number', pr ? pr.number : '') 64 | core.setOutput('title', pr ? pr.title : '') 65 | core.setOutput('url', pr ? pr.url : '') 66 | core.setOutput('head-ref', pr ? pr.head.ref : '') 67 | core.setOutput('head-sha', pr ? pr.head.sha : '') 68 | core.setOutput('base-ref', pr ? pr.base.ref : '') 69 | core.setOutput('base-sha', pr ? pr.base.sha : '') 70 | core.setOutput('base-repo', pr ? pr.base.repo.full_name : '') 71 | core.setOutput('state', pr ? pr.state : '') 72 | core.setOutput('author', pr ? pr.user?.login : '') 73 | } 74 | 75 | main().catch(err => core.setFailed(err.message)) 76 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: Find Pull Request 2 | author: juliangruber 3 | description: 'A GitHub Action for finding pull requests' 4 | branding: 5 | icon: 'git-pull-request' 6 | color: purple 7 | inputs: 8 | github-token: 9 | description: 'GitHub Token' 10 | required: false 11 | default: ${{ github.token }} 12 | branch: 13 | description: | 14 | The name of the branch from which the pull request was opened. For cross-repository pull requests namespace the 15 | branch with user or organization name, i.e. 'user:branch-name' or 'org:branch-name'. 16 | required: false 17 | base: 18 | description: 'The base branch name of the Pull Request' 19 | required: false 20 | author: 21 | description: 'The author of the Pull Request' 22 | required: false 23 | state: 24 | description: 'The state of the Pull Request. Can be either `open`, `closed` or `all`.' 25 | required: false 26 | default: open 27 | repo: 28 | description: 'Pull Request repo in owner/repo format' 29 | required: false 30 | sort: 31 | description: | 32 | What to sort results by. Can be either `created`, `updated`, `popularity` 33 | (comment count) or `long-running` (age, filtering by pulls updated in the last month). 34 | required: false 35 | direction: 36 | description: 'The direction of the sort. Can be either `asc` or `desc`.' 37 | default: 'desc' 38 | required: false 39 | labels: 40 | description: 'A comma-seperated list of label names, all of which must be present for the PR to be returned' 41 | required: false 42 | 43 | outputs: 44 | number: 45 | description: The Pull Request's number if one was found (e.g. '345' for #345) 46 | title: 47 | description: The Pull Request's title if one was found 48 | url: 49 | description: The Pull Request's URL if one was found 50 | head-ref: 51 | description: The Pull Request's head ref (branch name) if one was found 52 | head-sha: 53 | description: The Pull Request's head sha if one was found 54 | base-ref: 55 | description: The Pull Request's base ref (branch name) if one was found 56 | base-sha: 57 | description: The Pull Request's base sha if one was found 58 | base-repo: 59 | description: The Pull Request's base repository full name (e.g. octocat/Hello-World) 60 | state: 61 | description: The Pull Request's open or closed state if one was found 62 | author: 63 | description: The Pull Request's author if one was found 64 | 65 | runs: 66 | using: 'node20' 67 | main: 'dist/index.js' 68 | --------------------------------------------------------------------------------