mirror of
https://forgejo.stefka.eu/jiriks74/create-pull-request.git
synced 2025-01-18 16:01:06 +01:00
feat: add @octokit/plugin-throttling to handle GH rate limits
This commit is contained in:
parent
9fd47c87b5
commit
5a8d2e3d13
9 changed files with 1917 additions and 37 deletions
|
@ -50,7 +50,7 @@ All inputs are **optional**. If not set, sensible defaults will be used.
|
||||||
**Note**: If you want pull requests created by this action to trigger an `on: push` or `on: pull_request` workflow then you cannot use the default `GITHUB_TOKEN`. See the [documentation here](docs/concepts-guidelines.md#triggering-further-workflow-runs) for workarounds.
|
**Note**: If you want pull requests created by this action to trigger an `on: push` or `on: pull_request` workflow then you cannot use the default `GITHUB_TOKEN`. See the [documentation here](docs/concepts-guidelines.md#triggering-further-workflow-runs) for workarounds.
|
||||||
|
|
||||||
| Name | Description | Default |
|
| Name | Description | Default |
|
||||||
| --- | --- | --- |
|
|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|
|
||||||
| `token` | `GITHUB_TOKEN` (permissions `contents: write` and `pull-requests: write`) or a `repo` scoped [Personal Access Token (PAT)](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token). | `GITHUB_TOKEN` |
|
| `token` | `GITHUB_TOKEN` (permissions `contents: write` and `pull-requests: write`) or a `repo` scoped [Personal Access Token (PAT)](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token). | `GITHUB_TOKEN` |
|
||||||
| `path` | Relative path under `GITHUB_WORKSPACE` to the repository. | `GITHUB_WORKSPACE` |
|
| `path` | Relative path under `GITHUB_WORKSPACE` to the repository. | `GITHUB_WORKSPACE` |
|
||||||
| `add-paths` | A comma or newline-separated list of file paths to commit. Paths should follow git's [pathspec](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec) syntax. If no paths are specified, all new and modified files are added. See [Add specific paths](#add-specific-paths). | |
|
| `add-paths` | A comma or newline-separated list of file paths to commit. Paths should follow git's [pathspec](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec) syntax. If no paths are specified, all new and modified files are added. See [Add specific paths](#add-specific-paths). | |
|
||||||
|
@ -72,6 +72,8 @@ All inputs are **optional**. If not set, sensible defaults will be used.
|
||||||
| `team-reviewers` | A comma or newline-separated list of GitHub teams to request a review from. Note that a `repo` scoped [PAT](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token), or equivalent [GitHub App permissions](docs/concepts-guidelines.md#authenticating-with-github-app-generated-tokens), are required. | |
|
| `team-reviewers` | A comma or newline-separated list of GitHub teams to request a review from. Note that a `repo` scoped [PAT](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token), or equivalent [GitHub App permissions](docs/concepts-guidelines.md#authenticating-with-github-app-generated-tokens), are required. | |
|
||||||
| `milestone` | The number of the milestone to associate this pull request with. | |
|
| `milestone` | The number of the milestone to associate this pull request with. | |
|
||||||
| `draft` | Create a [draft pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests). It is not possible to change draft status after creation except through the web interface. | `false` |
|
| `draft` | Create a [draft pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests). It is not possible to change draft status after creation except through the web interface. | `false` |
|
||||||
|
| `retry-attempts` | Number of times throttled attempts should be retried before failing. | 10 |
|
||||||
|
| `minimum-retry-after` | Minimum time in seconds to wait before retry. | 60 |
|
||||||
|
|
||||||
For self-hosted runners behind a corporate proxy set the `https_proxy` environment variable.
|
For self-hosted runners behind a corporate proxy set the `https_proxy` environment variable.
|
||||||
```yml
|
```yml
|
||||||
|
|
|
@ -71,6 +71,12 @@ inputs:
|
||||||
draft:
|
draft:
|
||||||
description: 'Create a draft pull request. It is not possible to change draft status after creation except through the web interface'
|
description: 'Create a draft pull request. It is not possible to change draft status after creation except through the web interface'
|
||||||
default: false
|
default: false
|
||||||
|
retry-attempts:
|
||||||
|
description: 'Number of times throttled attempts should be retried before failing'
|
||||||
|
default: 10
|
||||||
|
minimum-retry-after:
|
||||||
|
description: 'Minimum time in seconds to wait before retry'
|
||||||
|
default: 60
|
||||||
outputs:
|
outputs:
|
||||||
pull-request-number:
|
pull-request-number:
|
||||||
description: 'The pull request number'
|
description: 'The pull request number'
|
||||||
|
|
1818
dist/index.js
vendored
1818
dist/index.js
vendored
File diff suppressed because it is too large
Load diff
34
package-lock.json
generated
34
package-lock.json
generated
|
@ -14,6 +14,7 @@
|
||||||
"@octokit/core": "^4.2.4",
|
"@octokit/core": "^4.2.4",
|
||||||
"@octokit/plugin-paginate-rest": "^5.0.1",
|
"@octokit/plugin-paginate-rest": "^5.0.1",
|
||||||
"@octokit/plugin-rest-endpoint-methods": "^6.8.1",
|
"@octokit/plugin-rest-endpoint-methods": "^6.8.1",
|
||||||
|
"@octokit/plugin-throttling": "^6.1.0",
|
||||||
"https-proxy-agent": "^5.0.1",
|
"https-proxy-agent": "^5.0.1",
|
||||||
"proxy-from-env": "^1.1.0",
|
"proxy-from-env": "^1.1.0",
|
||||||
"uuid": "^9.0.0"
|
"uuid": "^9.0.0"
|
||||||
|
@ -1362,6 +1363,34 @@
|
||||||
"@octokit/core": ">=3"
|
"@octokit/core": ">=3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/plugin-throttling": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-JqMbTiPC0sUSTsLQsdq3JVx1mx8UtTo5mwR80YqPXE93+XhevvSyOR1rO2Z+NbO/r0TK4hqFJSSi/9oIZBxZTg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^9.0.0",
|
||||||
|
"bottleneck": "^2.15.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@octokit/core": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-throttling/node_modules/@octokit/openapi-types": {
|
||||||
|
"version": "18.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz",
|
||||||
|
"integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw=="
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-throttling/node_modules/@octokit/types": {
|
||||||
|
"version": "9.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz",
|
||||||
|
"integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/openapi-types": "^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@octokit/request": {
|
"node_modules/@octokit/request": {
|
||||||
"version": "6.2.2",
|
"version": "6.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.2.tgz",
|
||||||
|
@ -2349,6 +2378,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
||||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
|
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/bottleneck": {
|
||||||
|
"version": "2.19.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
|
||||||
|
"integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
|
||||||
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
"@octokit/core": "^4.2.4",
|
"@octokit/core": "^4.2.4",
|
||||||
"@octokit/plugin-paginate-rest": "^5.0.1",
|
"@octokit/plugin-paginate-rest": "^5.0.1",
|
||||||
"@octokit/plugin-rest-endpoint-methods": "^6.8.1",
|
"@octokit/plugin-rest-endpoint-methods": "^6.8.1",
|
||||||
|
"@octokit/plugin-throttling": "^6.1.0",
|
||||||
"https-proxy-agent": "^5.0.1",
|
"https-proxy-agent": "^5.0.1",
|
||||||
"proxy-from-env": "^1.1.0",
|
"proxy-from-env": "^1.1.0",
|
||||||
"uuid": "^9.0.0"
|
"uuid": "^9.0.0"
|
||||||
|
|
|
@ -31,6 +31,8 @@ export interface Inputs {
|
||||||
teamReviewers: string[]
|
teamReviewers: string[]
|
||||||
milestone: number
|
milestone: number
|
||||||
draft: boolean
|
draft: boolean
|
||||||
|
retryAttempts: number
|
||||||
|
minimumRetryAfter: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createPullRequest(inputs: Inputs): Promise<void> {
|
export async function createPullRequest(inputs: Inputs): Promise<void> {
|
||||||
|
@ -67,7 +69,7 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
|
||||||
core.endGroup()
|
core.endGroup()
|
||||||
|
|
||||||
// Init the GitHub client
|
// Init the GitHub client
|
||||||
const githubHelper = new GitHubHelper(inputs.token)
|
const githubHelper = new GitHubHelper(inputs)
|
||||||
|
|
||||||
core.startGroup('Determining the base and head repositories')
|
core.startGroup('Determining the base and head repositories')
|
||||||
// Determine the base repository from git config
|
// Determine the base repository from git config
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {Inputs} from './create-pull-request'
|
import {Inputs} from './create-pull-request'
|
||||||
import {Octokit, OctokitOptions} from './octokit-client'
|
import {Octokit, OctokitOptions} from './octokit-client'
|
||||||
|
@ -20,12 +21,38 @@ interface Pull {
|
||||||
export class GitHubHelper {
|
export class GitHubHelper {
|
||||||
private octokit: InstanceType<typeof Octokit>
|
private octokit: InstanceType<typeof Octokit>
|
||||||
|
|
||||||
constructor(token: string) {
|
constructor(inputs: Inputs) {
|
||||||
const options: OctokitOptions = {}
|
const options: OctokitOptions = {
|
||||||
if (token) {
|
throttle: {
|
||||||
options.auth = `${token}`
|
onRateLimit: (retryAfter, options, octokit, retryCount) => {
|
||||||
|
octokit.log.warn(
|
||||||
|
// @ts-ignore
|
||||||
|
`Request quota exhausted for request ${options.method} ${options.url}`
|
||||||
|
)
|
||||||
|
if (retryCount < inputs.retryAttempts) {
|
||||||
|
octokit.log.info(
|
||||||
|
// @ts-ignore
|
||||||
|
`retrying request ${options.method} ${options.url} after ${retryAfter} seconds`
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSecondaryRateLimit: (retryAfter, options, octokit, retryCount) => {
|
||||||
|
if (retryCount < 3) {
|
||||||
|
octokit.log.info(
|
||||||
|
// @ts-ignore
|
||||||
|
`retrying request ${options.method} ${options.url} after ${retryAfter} seconds`
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (inputs.token) {
|
||||||
|
options.auth = `${inputs.token}`
|
||||||
}
|
}
|
||||||
options.baseUrl = process.env['GITHUB_API_URL'] || 'https://api.github.com'
|
options.baseUrl = process.env['GITHUB_API_URL'] || 'https://api.github.com'
|
||||||
|
|
||||||
this.octokit = new Octokit(options)
|
this.octokit = new Octokit(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,9 @@ async function run(): Promise<void> {
|
||||||
reviewers: utils.getInputAsArray('reviewers'),
|
reviewers: utils.getInputAsArray('reviewers'),
|
||||||
teamReviewers: utils.getInputAsArray('team-reviewers'),
|
teamReviewers: utils.getInputAsArray('team-reviewers'),
|
||||||
milestone: Number(core.getInput('milestone')),
|
milestone: Number(core.getInput('milestone')),
|
||||||
draft: core.getBooleanInput('draft')
|
draft: core.getBooleanInput('draft'),
|
||||||
|
retryAttempts: Number(core.getInput('retry-attempts')),
|
||||||
|
minimumRetryAfter: Number(core.getInput('minimum-retry-after'))
|
||||||
}
|
}
|
||||||
core.debug(`Inputs: ${inspect(inputs)}`)
|
core.debug(`Inputs: ${inspect(inputs)}`)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import {Octokit as Core} from '@octokit/core'
|
import {Octokit as Core} from '@octokit/core'
|
||||||
|
import {throttling} from '@octokit/plugin-throttling'
|
||||||
import {paginateRest} from '@octokit/plugin-paginate-rest'
|
import {paginateRest} from '@octokit/plugin-paginate-rest'
|
||||||
import {restEndpointMethods} from '@octokit/plugin-rest-endpoint-methods'
|
import {restEndpointMethods} from '@octokit/plugin-rest-endpoint-methods'
|
||||||
import {HttpsProxyAgent} from 'https-proxy-agent'
|
import {HttpsProxyAgent} from 'https-proxy-agent'
|
||||||
|
@ -9,7 +10,8 @@ export {OctokitOptions} from '@octokit/core/dist-types/types'
|
||||||
export const Octokit = Core.plugin(
|
export const Octokit = Core.plugin(
|
||||||
paginateRest,
|
paginateRest,
|
||||||
restEndpointMethods,
|
restEndpointMethods,
|
||||||
autoProxyAgent
|
autoProxyAgent,
|
||||||
|
throttling
|
||||||
)
|
)
|
||||||
|
|
||||||
// Octokit plugin to support the standard environment variables http_proxy, https_proxy and no_proxy
|
// Octokit plugin to support the standard environment variables http_proxy, https_proxy and no_proxy
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue