├── .circleci
└── config.yml
├── .github
└── dependabot.yml
├── .gitignore
├── LICENSE
├── README.md
├── action.yml
├── bin
└── automerge.js
├── dist
├── LICENSE
└── index.js
├── docs
└── screenshot.svg
├── eslint.config.mjs
├── it
└── it.js
├── lib
├── api.js
├── common.js
├── git.js
├── merge.js
├── update.js
└── util.js
├── package.json
├── test
├── api.test.js
├── common.js
├── common.test.js
├── git.test.js
├── merge.test.js
├── update.test.js
└── util.test.js
└── yarn.lock
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | jobs:
3 | build:
4 | docker:
5 | - image: cimg/node:20.10.0
6 | steps:
7 | - checkout
8 | - run:
9 | name: yarn
10 | command: yarn
11 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "npm"
4 | directory: "/"
5 | schedule:
6 | interval: "weekly"
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .env
3 | node_modules/
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright 2019 Pascal
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # automerge-action
2 |
3 | GitHub action to automatically merge pull requests when they are ready.
4 |
5 |
6 |
7 | When added, this action will run the following tasks on pull requests with the
8 | `automerge` label:
9 |
10 | - Changes from the base branch will automatically be merged into the pull
11 | request (only when "Require branches to be up to date before merging"
12 | is enabled in the branch protection rules)
13 | - When the pull request is ready, it will automatically be merged. The action
14 | will only wait for status checks that are marked as required in the branch
15 | protection rules
16 | - Pull requests without any configured labels will be ignored
17 |
18 | Labels, merge and update strategies are configurable, see [Configuration](#configuration).
19 |
20 | A pull request is considered ready when:
21 |
22 | 1. the required number of review approvals has been given (if enabled in the
23 | branch protection rules) and
24 | 2. the required checks have passed (if enabled in the branch protection rules)
25 | and
26 | 3. the pull request is up to date (if enabled in the branch protection rules)
27 |
28 | After the pull request has been merged successfully, the branch will _not_ be
29 | deleted. To delete branches after they are merged,
30 | see [automatic deletion of branches](https://help.github.com/en/articles/managing-the-automatic-deletion-of-branches).
31 |
32 | ----
33 |
34 | **This functionality is now available directly in GitHub as [auto-merge](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/automatically-merging-a-pull-request).** Note that GitHub does not currently support auto-rebasing pull requests. The automerge-action project will still be maintained, but users are encouraged to switch to auto-merge for simple workflows, as it offers a faster and more stable experience.
35 |
36 | ## Usage
37 |
38 | Create a new `.github/workflows/automerge.yml` file:
39 |
40 | ```yaml
41 | name: automerge
42 | on:
43 | pull_request:
44 | types:
45 | - labeled
46 | - unlabeled
47 | - synchronize
48 | - opened
49 | - edited
50 | - ready_for_review
51 | - reopened
52 | - unlocked
53 | pull_request_review:
54 | types:
55 | - submitted
56 | check_suite:
57 | types:
58 | - completed
59 | status: {}
60 | jobs:
61 | automerge:
62 | runs-on: ubuntu-latest
63 | permissions:
64 | contents: write
65 | pull-requests: write
66 | steps:
67 | - id: automerge
68 | name: automerge
69 | uses: "pascalgn/automerge-action@v0.16.4"
70 | env:
71 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
72 | ```
73 |
74 | For the latest version, see the [list of releases](https://github.com/pascalgn/automerge-action/releases).
75 |
76 | ## Configuration
77 |
78 | The following merge options are supported:
79 |
80 | - `MERGE_LABELS`: The labels that need to be present for a pull request to be
81 | merged (using `MERGE_METHOD`). The default value is `automerge`.
82 |
83 | This option can be a comma-separated list of labels that will be checked. All
84 | labels in the list need to be present, otherwise the pull request will be
85 | skipped (until all labels are present). Labels prefixed with an exclamation
86 | mark (`!`) will block a pull request from being merged, when present.
87 |
88 | For example, when `automerge,!wip,!work in progress` is given,
89 | any pull requests with the labels `wip` or `work in progress` and any pull
90 | requests _without_ the label `automerge` will not be merged.
91 | Blocking labels take precedence, so if a pull request has both labels
92 | `wip` and `automerge`, it will not be merged.
93 |
94 | When an empty string (`""`) is given, all pull requests will be merged.
95 |
96 | - `MERGE_REMOVE_LABELS`: The labels to automatically remove from a pull request
97 | once it has been merged by the action. The default value is `""`.
98 |
99 | This option can be a comma-separated list of labels that will be removed.
100 |
101 | When an empty string (`""`) is given, no labels will be removed.
102 |
103 | - `MERGE_METHOD`: Which method to use when merging the pull request into
104 | the base branch. Possible values are
105 | [`merge`](https://help.github.com/en/articles/about-pull-request-merges) (create a merge commit),
106 | [`rebase`](https://help.github.com/en/articles/about-pull-request-merges#rebase-and-merge-your-pull-request-commits)
107 | (rebase all commits of the branch onto the base branch)
108 | or [`squash`](https://help.github.com/en/articles/about-pull-request-merges#squash-and-merge-your-pull-request-commits)
109 | (squash all commits into a single commit). The default option is `merge`.
110 |
111 | - `MERGE_METHOD_LABELS`: Set to allow labels to determine the merge method
112 | (see `MERGE_METHOD` for possible values).
113 | For example, `automerge=merge,autosquash=squash`. If no such label is present,
114 | the method set by `MERGE_METHOD` will be used. The default value is `""`.
115 |
116 | - `MERGE_METHOD_LABEL_REQUIRED`: Set to `"true"` to require one of the
117 | `MERGE_METHOD_LABELS` to be set. The default value is `"false"`.
118 |
119 | - `MERGE_COMMIT_MESSAGE`: The commit message to use when merging the pull
120 | request into the base branch. Possible values are `automatic` (use GitHub's
121 | default message), `pull-request-title` (use the pull request's title),
122 | `pull-request-description` (use the pull request's description),
123 | `pull-request-title-and-description` or a literal
124 | value with optional placeholders (for example `Auto merge {pullRequest.number}`).
125 | The default value is `automatic`.
126 |
127 | - `MERGE_COMMIT_MESSAGE_REGEX`: When using a commit message containing the
128 | PR's body, use the first capturing subgroup from this regex as the commit
129 | message. Can be used to separate content that should go with the commit into
130 | the code base's history from boilerplate associated with the PR (licensing
131 | notices, check lists, etc). For example, `(.*)^---` would keep everything up
132 | until the first 3-dash line (horizontal rule in MarkDown) from the commit
133 | message. The default value is empty, which disables this feature.
134 |
135 | - `MERGE_FILTER_AUTHOR`: When set, only pull requests raised by this author
136 | will be merged automatically.
137 |
138 | - `MERGE_FORKS`: Whether merging from external repositories is enabled
139 | or not. By default, pull requests with branches from forked repositories will
140 | be merged the same way as pull requests with branches from the main
141 | repository. Set this option to `"false"` to disable merging of pull requests
142 | from forked repositories. The default value is `"true"`.
143 |
144 | - `MERGE_RETRIES` and `MERGE_RETRY_SLEEP`: Sometimes, the pull request check
145 | runs haven't finished yet, so the action will retry the merge after some time.
146 | The number of retries can be set with `MERGE_RETRIES`.
147 | The default number of retries is `6` and setting it to `0` disables the retry logic.
148 | `MERGE_RETRY_SLEEP` sets the time to sleep between retries, in milliseconds.
149 | The default is `5000` (5 seconds) and setting it to `0` disables sleeping
150 | between retries.
151 |
152 | - `MERGE_REQUIRED_APPROVALS`: Count of required approvals. The default is `0`.
153 |
154 | - `MERGE_DELETE_BRANCH`: Automatic deletion of branches does not work for all
155 | repositories. Set this option to `"true"` to automatically delete branches
156 | after they have been merged. The default value is `"false"`.
157 |
158 | - `MERGE_DELETE_BRANCH_FILTER`: A comma-separated list of branches that will not
159 | be deleted. This is not the list of GitHub's protected branches, which are never
160 | deleted, but an additional list of branches to protect. The default value is `""`.
161 |
162 | - `MERGE_ERROR_FAIL`: Set this to `"true"` to have the action exit with error code `1`
163 | when the pull request could not be merged successfully during a run.
164 |
165 | - `MERGE_READY_STATE`: The state(s) of a pull request for which to attempt a
166 | merge. This option can be a comma-separated list of states that will be considered mergeable.
167 | The default value is `clean,has_hooks,unknown,unstable`.
168 |
169 | The following update options are supported:
170 |
171 | - `UPDATE_LABELS`: The labels that need to be present for a pull request to be
172 | updated (using `UPDATE_METHOD`). The default value is `automerge`.
173 |
174 | Note that updating will only happen when the option "Require branches to be
175 | up to date before merging" is enabled in the branch protection rules.
176 |
177 | This option can be a comma-separated list of labels, see the `MERGE_LABELS`
178 | option for more information.
179 |
180 | - `UPDATE_METHOD`: Which method to use when updating the pull request
181 | to the base branch. Possible values are `merge` (create a merge commit) or
182 | `rebase` (rebase the branch onto the head of the base branch). The default
183 | option is `merge`.
184 |
185 | When the option is `rebase` and the [rebasing](https://git-scm.com/book/en/v2/Git-Branching-Rebasing)
186 | failed, the action will exit with error code 1. This will also be visible
187 | in the pull request page, with a message like "this branch has conflicts
188 | that must be resolved" and a list of conflicting files.
189 |
190 | - `UPDATE_RETRIES` and `UPDATE_RETRY_SLEEP`: Sometimes, the pull request check
191 | runs haven't finished yet and the action doesn't know if an update is
192 | necessary. To query the pull request state multiple times, the number of
193 | retries can be set with `UPDATE_RETRIES`. The default number of retries is `1`
194 | and setting it to `0` disables the retry logic.
195 | `UPDATE_RETRY_SLEEP` sets the time to sleep between retries, in milliseconds.
196 | The default is `5000` (5 seconds) and setting it to `0` disables sleeping
197 | between retries.
198 |
199 | Also, the following general options are supported:
200 |
201 | - `GITHUB_TOKEN`: This should always be `"${{ secrets.GITHUB_TOKEN }}"`.
202 | However, in some cases it can be useful to run this action as a certain user
203 | (by default, it will run as `github-actions`). This can be useful if you want
204 | to use the "Restrict who can push to matching branches" option in the branch
205 | protection rules, for example.
206 |
207 | To use this setting for manually providing a token, you need to create a
208 | [personal access token](https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line)
209 | for the user (make sure to check `public_repo` when it's a public repository
210 | or `repo` when it's a private repository). All API requests (merge/rebase)
211 | will then be executed as the specified user. The token should be kept secret,
212 | so make sure to add it as secret, not as environment variable, in the GitHub
213 | workflow file!
214 |
215 | - `PULL_REQUEST`: If provided, this action will attempt to merge the specified pull request. By default, it will attempt to use the pull request specified in the GitHub context. If a pull request number is provided via this input, this action will search in the current repo for the provided pull request number. If you want to merge a pull request in another repo, just provide the repo slug before the pull request number, like `Some-Org/Some-Repo/1234`
216 |
217 | - `BASE_BRANCHES`: If provided, the action will be restricted in terms of base branches. Can be comma-separated list of simple branch names (i.e `main,dev`).
218 |
219 | - `MAX_PR_COUNT`: If provided, will control how many GitHub pull requests are considered in a single run. The default is `10`.
220 |
221 | You can configure the environment variables in the workflow file like this:
222 |
223 | ```yaml
224 | env:
225 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
226 | MERGE_LABELS: "automerge,!work in progress"
227 | MERGE_REMOVE_LABELS: "automerge"
228 | MERGE_METHOD: "squash"
229 | MERGE_COMMIT_MESSAGE: "pull-request-description"
230 | MERGE_FORKS: "false"
231 | MERGE_RETRIES: "6"
232 | MERGE_RETRY_SLEEP: "10000"
233 | MERGE_REQUIRED_APPROVALS: "0"
234 | UPDATE_LABELS: ""
235 | UPDATE_METHOD: "rebase"
236 | PULL_REQUEST: "1234"
237 | MAX_PR_COUNT: "25"
238 | ```
239 |
240 | ## Supported Events
241 |
242 | Automerge can be configured to run for these events:
243 |
244 | * `check_run`
245 | * `check_suite`
246 | * `issue_comment`
247 | * `pull_request_review`
248 | * `pull_request_target`
249 | * `pull_request`
250 | * `push`
251 | * `repository_dispatch`
252 | * `schedule`
253 | * `status`
254 | * `workflow_dispatch`
255 | * `workflow_run`
256 |
257 | For more information on when these occur, see the Github documentation on [events that trigger workflows](https://docs.github.com/en/actions/reference/events-that-trigger-workflows) and [their payloads](https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads).
258 |
259 | ## Outputs
260 |
261 | The action will provide two [outputs](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idoutputs):
262 |
263 | * `mergeResult` - The result from the action run, one of `skipped`, `not_ready`, `author_filtered`, `merge_failed`, `merged`
264 | * `pullRequestNumber` - The pull request number (or `0`, if no pull request was affected)
265 |
266 | Please note:
267 |
268 | 1. When there are multiple pull requests affected, only the first one will be available in the output
269 | 2. To access these outputs, your workflow configuration must define an `id` for the automerge-action step
270 | 3. Unless a personal access token is used, this action will not trigger other actions, see [Limitations](#limitations)
271 |
272 | Example usage:
273 |
274 | ```yaml
275 | steps:
276 | - id: automerge
277 | name: automerge
278 | uses: "pascalgn/automerge-action@v0.15.6"
279 | env:
280 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
281 | - name: feedback
282 | if: ${{ steps.automerge.outputs.mergeResult == 'merged' }}
283 | run: |
284 | echo "Pull request ${{ steps.automerge.outputs.pullRequestNumber }} merged!"
285 | ```
286 |
287 | ## Limitations
288 |
289 | - When a pull request is merged by this action, the merge will not trigger other GitHub workflows.
290 | Similarly, when another GitHub workflow creates a pull request, this action will not be triggered.
291 | This is because [an action in a workflow run can't trigger a new workflow run](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/events-that-trigger-workflows). However, the [`workflow_run`](https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#workflow_run) event is triggered as expected.
292 | - When [using a personal access token (PAT) to work around the above limitation](https://help.github.com/en/actions/reference/events-that-trigger-workflows#triggering-new-workflows-using-a-personal-access-token), note that when the user issuing the PAT is an administrator and [branch restrictions do not include administrators](https://help.github.com/en/github/administering-a-repository/enabling-branch-restrictions), pull requests may be merged even if they are not mergeable for non-administrators (see [#65](https://github.com/pascalgn/automerge-action/issues/65)).
293 | - Currently, there is no way to trigger workflows when the pull request branch
294 | becomes out of date with the base branch. There is a request in the
295 | [GitHub community forum](https://github.community/t5/GitHub-Actions/New-Trigger-is-mergable-state/m-p/36908).
296 |
297 | ## Debugging
298 |
299 | To run the action with full debug logging, update your workflow file as follows:
300 |
301 | ```yaml
302 | - name: automerge
303 | uses: pascalgn/automerge-action@...
304 | env:
305 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
306 | LOG: "TRACE" # or "DEBUG"
307 | ```
308 |
309 | If you need to further debug the action, you can run it locally.
310 |
311 | You will need a [personal access token](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line).
312 |
313 | Then clone this repository, create a file `.env` in the repository, such as:
314 |
315 | ```
316 | GITHUB_TOKEN="123abc..."
317 | URL="https://github.com/pascalgn/repository-name/pull/123"
318 | ```
319 |
320 | Install dependencies with `yarn`, and finally run `yarn it` (or `npm run it`).
321 |
322 | ## License
323 |
324 | [MIT](./LICENSE)
325 |
--------------------------------------------------------------------------------
/action.yml:
--------------------------------------------------------------------------------
1 | name: "Merge pull requests (automerge-action)"
2 | description: "Automatically merge pull requests that are ready"
3 | runs:
4 | using: "node20"
5 | main: "dist/index.js"
6 | branding:
7 | icon: "git-pull-request"
8 | color: "blue"
9 |
--------------------------------------------------------------------------------
/bin/automerge.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const process = require("process");
4 |
5 | const fse = require("fs-extra");
6 | const { ArgumentParser } = require("argparse");
7 | const { Octokit } = require("@octokit/rest");
8 |
9 | const { ClientError, logger, createConfig } = require("../lib/common");
10 | const { executeLocally, executeGitHubAction } = require("../lib/api");
11 |
12 | const pkg = require("../package.json");
13 |
14 | const OLD_CONFIG = [
15 | "MERGE_LABEL",
16 | "UPDATE_LABEL",
17 | "LABELS",
18 | "AUTOMERGE",
19 | "AUTOREBASE",
20 | "COMMIT_MESSAGE_TEMPLATE",
21 | "TOKEN"
22 | ];
23 |
24 | const GITHUB_API_URL = process.env.GITHUB_API_URL || "https://api.github.com";
25 |
26 | async function main() {
27 | const parser = new ArgumentParser({
28 | prog: pkg.name,
29 | add_help: true,
30 | description: pkg.description
31 | });
32 | parser.add_argument("-v", "--version", {
33 | action: "version",
34 | version: pkg.version,
35 | help: "Show version number and exit"
36 | });
37 | parser.add_argument("url", {
38 | metavar: "",
39 | nargs: "?",
40 | help: "GitHub URL to process instead of environment variables"
41 | });
42 |
43 | const args = parser.parse_args();
44 |
45 | if (process.env.LOG === "TRACE") {
46 | logger.level = "trace";
47 | } else if (process.env.LOG === "DEBUG") {
48 | logger.level = "debug";
49 | } else if (process.env.LOG && process.env.LOG.length > 0) {
50 | logger.error("Invalid log level:", process.env.LOG);
51 | }
52 |
53 | checkOldConfig();
54 |
55 | const token = env("GITHUB_TOKEN");
56 |
57 | const octokit = new Octokit({
58 | baseUrl: GITHUB_API_URL,
59 | auth: `token ${token}`,
60 | userAgent: "pascalgn/automerge-action"
61 | });
62 |
63 | const config = createConfig(process.env);
64 | logger.debug("Configuration:", config);
65 |
66 | const context = { token, octokit, config };
67 |
68 | if (args.url) {
69 | await executeLocally(context, args.url);
70 | } else {
71 | const eventPath = env("GITHUB_EVENT_PATH");
72 | const eventName = env("GITHUB_EVENT_NAME");
73 |
74 | const eventDataStr = await fse.readFile(eventPath, "utf8");
75 | const eventData = JSON.parse(eventDataStr);
76 |
77 | await executeGitHubAction(context, eventName, eventData);
78 | }
79 | }
80 |
81 | function checkOldConfig() {
82 | let error = false;
83 | for (const old of OLD_CONFIG) {
84 | if (process.env[old] != null) {
85 | logger.error("Old configuration option present:", old);
86 | error = true;
87 | }
88 | }
89 | if (error) {
90 | logger.error(
91 | "You have passed configuration options that were used by an old " +
92 | "version of this action. Please see " +
93 | "https://github.com/pascalgn/automerge-action for the latest " +
94 | "documentation of the configuration options!"
95 | );
96 | throw new Error(`old configuration present!`);
97 | }
98 | }
99 |
100 | function env(name) {
101 | const val = process.env[name];
102 | if (!val || !val.length) {
103 | throw new ClientError(`environment variable ${name} not set!`);
104 | }
105 | return val;
106 | }
107 |
108 | if (require.main === module) {
109 | main().catch(e => {
110 | if (e instanceof ClientError) {
111 | process.exitCode = 2;
112 | logger.error(e);
113 | } else {
114 | process.exitCode = 1;
115 | logger.error(e);
116 | }
117 | });
118 | }
119 |
--------------------------------------------------------------------------------
/dist/LICENSE:
--------------------------------------------------------------------------------
1 | @actions/core
2 | MIT
3 | The MIT License (MIT)
4 |
5 | Copyright 2019 GitHub
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8 |
9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10 |
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12 |
13 | @actions/http-client
14 | MIT
15 | Actions Http Client for Node.js
16 |
17 | Copyright (c) GitHub, Inc.
18 |
19 | All rights reserved.
20 |
21 | MIT License
22 |
23 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
24 | associated documentation files (the "Software"), to deal in the Software without restriction,
25 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
26 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
27 | subject to the following conditions:
28 |
29 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
30 |
31 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
32 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
33 | NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
34 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
35 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 |
37 |
38 | @fastify/busboy
39 | MIT
40 | Copyright Brian White. All rights reserved.
41 |
42 | Permission is hereby granted, free of charge, to any person obtaining a copy
43 | of this software and associated documentation files (the "Software"), to
44 | deal in the Software without restriction, including without limitation the
45 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
46 | sell copies of the Software, and to permit persons to whom the Software is
47 | furnished to do so, subject to the following conditions:
48 |
49 | The above copyright notice and this permission notice shall be included in
50 | all copies or substantial portions of the Software.
51 |
52 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
55 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
56 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
57 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
58 | IN THE SOFTWARE.
59 |
60 | @octokit/auth-token
61 | MIT
62 | The MIT License
63 |
64 | Copyright (c) 2019 Octokit contributors
65 |
66 | Permission is hereby granted, free of charge, to any person obtaining a copy
67 | of this software and associated documentation files (the "Software"), to deal
68 | in the Software without restriction, including without limitation the rights
69 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
70 | copies of the Software, and to permit persons to whom the Software is
71 | furnished to do so, subject to the following conditions:
72 |
73 | The above copyright notice and this permission notice shall be included in
74 | all copies or substantial portions of the Software.
75 |
76 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
77 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
78 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
79 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
80 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
81 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
82 | THE SOFTWARE.
83 |
84 |
85 | @octokit/core
86 | MIT
87 | The MIT License
88 |
89 | Copyright (c) 2019 Octokit contributors
90 |
91 | Permission is hereby granted, free of charge, to any person obtaining a copy
92 | of this software and associated documentation files (the "Software"), to deal
93 | in the Software without restriction, including without limitation the rights
94 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
95 | copies of the Software, and to permit persons to whom the Software is
96 | furnished to do so, subject to the following conditions:
97 |
98 | The above copyright notice and this permission notice shall be included in
99 | all copies or substantial portions of the Software.
100 |
101 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
102 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
103 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
104 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
105 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
106 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
107 | THE SOFTWARE.
108 |
109 |
110 | @octokit/endpoint
111 | MIT
112 | The MIT License
113 |
114 | Copyright (c) 2018 Octokit contributors
115 |
116 | Permission is hereby granted, free of charge, to any person obtaining a copy
117 | of this software and associated documentation files (the "Software"), to deal
118 | in the Software without restriction, including without limitation the rights
119 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
120 | copies of the Software, and to permit persons to whom the Software is
121 | furnished to do so, subject to the following conditions:
122 |
123 | The above copyright notice and this permission notice shall be included in
124 | all copies or substantial portions of the Software.
125 |
126 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
127 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
128 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
129 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
130 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
131 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
132 | THE SOFTWARE.
133 |
134 |
135 | @octokit/graphql
136 | MIT
137 | The MIT License
138 |
139 | Copyright (c) 2018 Octokit contributors
140 |
141 | Permission is hereby granted, free of charge, to any person obtaining a copy
142 | of this software and associated documentation files (the "Software"), to deal
143 | in the Software without restriction, including without limitation the rights
144 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
145 | copies of the Software, and to permit persons to whom the Software is
146 | furnished to do so, subject to the following conditions:
147 |
148 | The above copyright notice and this permission notice shall be included in
149 | all copies or substantial portions of the Software.
150 |
151 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
152 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
153 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
154 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
155 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
156 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
157 | THE SOFTWARE.
158 |
159 |
160 | @octokit/plugin-paginate-rest
161 | MIT
162 | MIT License Copyright (c) 2019 Octokit contributors
163 |
164 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
165 |
166 | The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
167 |
168 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
169 |
170 |
171 | @octokit/plugin-request-log
172 | MIT
173 | MIT License Copyright (c) 2020 Octokit contributors
174 |
175 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
176 |
177 | The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
178 |
179 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
180 |
181 |
182 | @octokit/plugin-rest-endpoint-methods
183 | MIT
184 | MIT License Copyright (c) 2019 Octokit contributors
185 |
186 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
187 |
188 | The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
189 |
190 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
191 |
192 |
193 | @octokit/request
194 | MIT
195 | The MIT License
196 |
197 | Copyright (c) 2018 Octokit contributors
198 |
199 | Permission is hereby granted, free of charge, to any person obtaining a copy
200 | of this software and associated documentation files (the "Software"), to deal
201 | in the Software without restriction, including without limitation the rights
202 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
203 | copies of the Software, and to permit persons to whom the Software is
204 | furnished to do so, subject to the following conditions:
205 |
206 | The above copyright notice and this permission notice shall be included in
207 | all copies or substantial portions of the Software.
208 |
209 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
210 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
211 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
212 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
213 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
214 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
215 | THE SOFTWARE.
216 |
217 |
218 | @octokit/request-error
219 | MIT
220 | The MIT License
221 |
222 | Copyright (c) 2019 Octokit contributors
223 |
224 | Permission is hereby granted, free of charge, to any person obtaining a copy
225 | of this software and associated documentation files (the "Software"), to deal
226 | in the Software without restriction, including without limitation the rights
227 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
228 | copies of the Software, and to permit persons to whom the Software is
229 | furnished to do so, subject to the following conditions:
230 |
231 | The above copyright notice and this permission notice shall be included in
232 | all copies or substantial portions of the Software.
233 |
234 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
235 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
236 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
237 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
238 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
239 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
240 | THE SOFTWARE.
241 |
242 |
243 | @octokit/rest
244 | MIT
245 | The MIT License
246 |
247 | Copyright (c) 2012 Cloud9 IDE, Inc. (Mike de Boer)
248 | Copyright (c) 2017-2018 Octokit contributors
249 |
250 | Permission is hereby granted, free of charge, to any person obtaining a copy
251 | of this software and associated documentation files (the "Software"), to deal
252 | in the Software without restriction, including without limitation the rights
253 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
254 | copies of the Software, and to permit persons to whom the Software is
255 | furnished to do so, subject to the following conditions:
256 |
257 | The above copyright notice and this permission notice shall be included in
258 | all copies or substantial portions of the Software.
259 |
260 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
261 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
262 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
263 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
264 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
265 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
266 | THE SOFTWARE.
267 |
268 |
269 | argparse
270 | Python-2.0
271 | A. HISTORY OF THE SOFTWARE
272 | ==========================
273 |
274 | Python was created in the early 1990s by Guido van Rossum at Stichting
275 | Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
276 | as a successor of a language called ABC. Guido remains Python's
277 | principal author, although it includes many contributions from others.
278 |
279 | In 1995, Guido continued his work on Python at the Corporation for
280 | National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
281 | in Reston, Virginia where he released several versions of the
282 | software.
283 |
284 | In May 2000, Guido and the Python core development team moved to
285 | BeOpen.com to form the BeOpen PythonLabs team. In October of the same
286 | year, the PythonLabs team moved to Digital Creations, which became
287 | Zope Corporation. In 2001, the Python Software Foundation (PSF, see
288 | https://www.python.org/psf/) was formed, a non-profit organization
289 | created specifically to own Python-related Intellectual Property.
290 | Zope Corporation was a sponsoring member of the PSF.
291 |
292 | All Python releases are Open Source (see http://www.opensource.org for
293 | the Open Source Definition). Historically, most, but not all, Python
294 | releases have also been GPL-compatible; the table below summarizes
295 | the various releases.
296 |
297 | Release Derived Year Owner GPL-
298 | from compatible? (1)
299 |
300 | 0.9.0 thru 1.2 1991-1995 CWI yes
301 | 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes
302 | 1.6 1.5.2 2000 CNRI no
303 | 2.0 1.6 2000 BeOpen.com no
304 | 1.6.1 1.6 2001 CNRI yes (2)
305 | 2.1 2.0+1.6.1 2001 PSF no
306 | 2.0.1 2.0+1.6.1 2001 PSF yes
307 | 2.1.1 2.1+2.0.1 2001 PSF yes
308 | 2.1.2 2.1.1 2002 PSF yes
309 | 2.1.3 2.1.2 2002 PSF yes
310 | 2.2 and above 2.1.1 2001-now PSF yes
311 |
312 | Footnotes:
313 |
314 | (1) GPL-compatible doesn't mean that we're distributing Python under
315 | the GPL. All Python licenses, unlike the GPL, let you distribute
316 | a modified version without making your changes open source. The
317 | GPL-compatible licenses make it possible to combine Python with
318 | other software that is released under the GPL; the others don't.
319 |
320 | (2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
321 | because its license has a choice of law clause. According to
322 | CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
323 | is "not incompatible" with the GPL.
324 |
325 | Thanks to the many outside volunteers who have worked under Guido's
326 | direction to make these releases possible.
327 |
328 |
329 | B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
330 | ===============================================================
331 |
332 | PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
333 | --------------------------------------------
334 |
335 | 1. This LICENSE AGREEMENT is between the Python Software Foundation
336 | ("PSF"), and the Individual or Organization ("Licensee") accessing and
337 | otherwise using this software ("Python") in source or binary form and
338 | its associated documentation.
339 |
340 | 2. Subject to the terms and conditions of this License Agreement, PSF hereby
341 | grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
342 | analyze, test, perform and/or display publicly, prepare derivative works,
343 | distribute, and otherwise use Python alone or in any derivative version,
344 | provided, however, that PSF's License Agreement and PSF's notice of copyright,
345 | i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
346 | 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Python Software Foundation;
347 | All Rights Reserved" are retained in Python alone or in any derivative version
348 | prepared by Licensee.
349 |
350 | 3. In the event Licensee prepares a derivative work that is based on
351 | or incorporates Python or any part thereof, and wants to make
352 | the derivative work available to others as provided herein, then
353 | Licensee hereby agrees to include in any such work a brief summary of
354 | the changes made to Python.
355 |
356 | 4. PSF is making Python available to Licensee on an "AS IS"
357 | basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
358 | IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
359 | DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
360 | FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
361 | INFRINGE ANY THIRD PARTY RIGHTS.
362 |
363 | 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
364 | FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
365 | A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
366 | OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
367 |
368 | 6. This License Agreement will automatically terminate upon a material
369 | breach of its terms and conditions.
370 |
371 | 7. Nothing in this License Agreement shall be deemed to create any
372 | relationship of agency, partnership, or joint venture between PSF and
373 | Licensee. This License Agreement does not grant permission to use PSF
374 | trademarks or trade name in a trademark sense to endorse or promote
375 | products or services of Licensee, or any third party.
376 |
377 | 8. By copying, installing or otherwise using Python, Licensee
378 | agrees to be bound by the terms and conditions of this License
379 | Agreement.
380 |
381 |
382 | BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
383 | -------------------------------------------
384 |
385 | BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
386 |
387 | 1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
388 | office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
389 | Individual or Organization ("Licensee") accessing and otherwise using
390 | this software in source or binary form and its associated
391 | documentation ("the Software").
392 |
393 | 2. Subject to the terms and conditions of this BeOpen Python License
394 | Agreement, BeOpen hereby grants Licensee a non-exclusive,
395 | royalty-free, world-wide license to reproduce, analyze, test, perform
396 | and/or display publicly, prepare derivative works, distribute, and
397 | otherwise use the Software alone or in any derivative version,
398 | provided, however, that the BeOpen Python License is retained in the
399 | Software, alone or in any derivative version prepared by Licensee.
400 |
401 | 3. BeOpen is making the Software available to Licensee on an "AS IS"
402 | basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
403 | IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
404 | DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
405 | FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
406 | INFRINGE ANY THIRD PARTY RIGHTS.
407 |
408 | 4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
409 | SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
410 | AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
411 | DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
412 |
413 | 5. This License Agreement will automatically terminate upon a material
414 | breach of its terms and conditions.
415 |
416 | 6. This License Agreement shall be governed by and interpreted in all
417 | respects by the law of the State of California, excluding conflict of
418 | law provisions. Nothing in this License Agreement shall be deemed to
419 | create any relationship of agency, partnership, or joint venture
420 | between BeOpen and Licensee. This License Agreement does not grant
421 | permission to use BeOpen trademarks or trade names in a trademark
422 | sense to endorse or promote products or services of Licensee, or any
423 | third party. As an exception, the "BeOpen Python" logos available at
424 | http://www.pythonlabs.com/logos.html may be used according to the
425 | permissions granted on that web page.
426 |
427 | 7. By copying, installing or otherwise using the software, Licensee
428 | agrees to be bound by the terms and conditions of this License
429 | Agreement.
430 |
431 |
432 | CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
433 | ---------------------------------------
434 |
435 | 1. This LICENSE AGREEMENT is between the Corporation for National
436 | Research Initiatives, having an office at 1895 Preston White Drive,
437 | Reston, VA 20191 ("CNRI"), and the Individual or Organization
438 | ("Licensee") accessing and otherwise using Python 1.6.1 software in
439 | source or binary form and its associated documentation.
440 |
441 | 2. Subject to the terms and conditions of this License Agreement, CNRI
442 | hereby grants Licensee a nonexclusive, royalty-free, world-wide
443 | license to reproduce, analyze, test, perform and/or display publicly,
444 | prepare derivative works, distribute, and otherwise use Python 1.6.1
445 | alone or in any derivative version, provided, however, that CNRI's
446 | License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
447 | 1995-2001 Corporation for National Research Initiatives; All Rights
448 | Reserved" are retained in Python 1.6.1 alone or in any derivative
449 | version prepared by Licensee. Alternately, in lieu of CNRI's License
450 | Agreement, Licensee may substitute the following text (omitting the
451 | quotes): "Python 1.6.1 is made available subject to the terms and
452 | conditions in CNRI's License Agreement. This Agreement together with
453 | Python 1.6.1 may be located on the Internet using the following
454 | unique, persistent identifier (known as a handle): 1895.22/1013. This
455 | Agreement may also be obtained from a proxy server on the Internet
456 | using the following URL: http://hdl.handle.net/1895.22/1013".
457 |
458 | 3. In the event Licensee prepares a derivative work that is based on
459 | or incorporates Python 1.6.1 or any part thereof, and wants to make
460 | the derivative work available to others as provided herein, then
461 | Licensee hereby agrees to include in any such work a brief summary of
462 | the changes made to Python 1.6.1.
463 |
464 | 4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
465 | basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
466 | IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
467 | DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
468 | FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
469 | INFRINGE ANY THIRD PARTY RIGHTS.
470 |
471 | 5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
472 | 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
473 | A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
474 | OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
475 |
476 | 6. This License Agreement will automatically terminate upon a material
477 | breach of its terms and conditions.
478 |
479 | 7. This License Agreement shall be governed by the federal
480 | intellectual property law of the United States, including without
481 | limitation the federal copyright law, and, to the extent such
482 | U.S. federal law does not apply, by the law of the Commonwealth of
483 | Virginia, excluding Virginia's conflict of law provisions.
484 | Notwithstanding the foregoing, with regard to derivative works based
485 | on Python 1.6.1 that incorporate non-separable material that was
486 | previously distributed under the GNU General Public License (GPL), the
487 | law of the Commonwealth of Virginia shall govern this License
488 | Agreement only as to issues arising under or with respect to
489 | Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this
490 | License Agreement shall be deemed to create any relationship of
491 | agency, partnership, or joint venture between CNRI and Licensee. This
492 | License Agreement does not grant permission to use CNRI trademarks or
493 | trade name in a trademark sense to endorse or promote products or
494 | services of Licensee, or any third party.
495 |
496 | 8. By clicking on the "ACCEPT" button where indicated, or by copying,
497 | installing or otherwise using Python 1.6.1, Licensee agrees to be
498 | bound by the terms and conditions of this License Agreement.
499 |
500 | ACCEPT
501 |
502 |
503 | CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
504 | --------------------------------------------------
505 |
506 | Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
507 | The Netherlands. All rights reserved.
508 |
509 | Permission to use, copy, modify, and distribute this software and its
510 | documentation for any purpose and without fee is hereby granted,
511 | provided that the above copyright notice appear in all copies and that
512 | both that copyright notice and this permission notice appear in
513 | supporting documentation, and that the name of Stichting Mathematisch
514 | Centrum or CWI not be used in advertising or publicity pertaining to
515 | distribution of the software without specific, written prior
516 | permission.
517 |
518 | STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
519 | THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
520 | FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
521 | FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
522 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
523 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
524 | OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
525 |
526 |
527 | before-after-hook
528 | Apache-2.0
529 | Apache License
530 | Version 2.0, January 2004
531 | http://www.apache.org/licenses/
532 |
533 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
534 |
535 | 1. Definitions.
536 |
537 | "License" shall mean the terms and conditions for use, reproduction,
538 | and distribution as defined by Sections 1 through 9 of this document.
539 |
540 | "Licensor" shall mean the copyright owner or entity authorized by
541 | the copyright owner that is granting the License.
542 |
543 | "Legal Entity" shall mean the union of the acting entity and all
544 | other entities that control, are controlled by, or are under common
545 | control with that entity. For the purposes of this definition,
546 | "control" means (i) the power, direct or indirect, to cause the
547 | direction or management of such entity, whether by contract or
548 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
549 | outstanding shares, or (iii) beneficial ownership of such entity.
550 |
551 | "You" (or "Your") shall mean an individual or Legal Entity
552 | exercising permissions granted by this License.
553 |
554 | "Source" form shall mean the preferred form for making modifications,
555 | including but not limited to software source code, documentation
556 | source, and configuration files.
557 |
558 | "Object" form shall mean any form resulting from mechanical
559 | transformation or translation of a Source form, including but
560 | not limited to compiled object code, generated documentation,
561 | and conversions to other media types.
562 |
563 | "Work" shall mean the work of authorship, whether in Source or
564 | Object form, made available under the License, as indicated by a
565 | copyright notice that is included in or attached to the work
566 | (an example is provided in the Appendix below).
567 |
568 | "Derivative Works" shall mean any work, whether in Source or Object
569 | form, that is based on (or derived from) the Work and for which the
570 | editorial revisions, annotations, elaborations, or other modifications
571 | represent, as a whole, an original work of authorship. For the purposes
572 | of this License, Derivative Works shall not include works that remain
573 | separable from, or merely link (or bind by name) to the interfaces of,
574 | the Work and Derivative Works thereof.
575 |
576 | "Contribution" shall mean any work of authorship, including
577 | the original version of the Work and any modifications or additions
578 | to that Work or Derivative Works thereof, that is intentionally
579 | submitted to Licensor for inclusion in the Work by the copyright owner
580 | or by an individual or Legal Entity authorized to submit on behalf of
581 | the copyright owner. For the purposes of this definition, "submitted"
582 | means any form of electronic, verbal, or written communication sent
583 | to the Licensor or its representatives, including but not limited to
584 | communication on electronic mailing lists, source code control systems,
585 | and issue tracking systems that are managed by, or on behalf of, the
586 | Licensor for the purpose of discussing and improving the Work, but
587 | excluding communication that is conspicuously marked or otherwise
588 | designated in writing by the copyright owner as "Not a Contribution."
589 |
590 | "Contributor" shall mean Licensor and any individual or Legal Entity
591 | on behalf of whom a Contribution has been received by Licensor and
592 | subsequently incorporated within the Work.
593 |
594 | 2. Grant of Copyright License. Subject to the terms and conditions of
595 | this License, each Contributor hereby grants to You a perpetual,
596 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
597 | copyright license to reproduce, prepare Derivative Works of,
598 | publicly display, publicly perform, sublicense, and distribute the
599 | Work and such Derivative Works in Source or Object form.
600 |
601 | 3. Grant of Patent License. Subject to the terms and conditions of
602 | this License, each Contributor hereby grants to You a perpetual,
603 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
604 | (except as stated in this section) patent license to make, have made,
605 | use, offer to sell, sell, import, and otherwise transfer the Work,
606 | where such license applies only to those patent claims licensable
607 | by such Contributor that are necessarily infringed by their
608 | Contribution(s) alone or by combination of their Contribution(s)
609 | with the Work to which such Contribution(s) was submitted. If You
610 | institute patent litigation against any entity (including a
611 | cross-claim or counterclaim in a lawsuit) alleging that the Work
612 | or a Contribution incorporated within the Work constitutes direct
613 | or contributory patent infringement, then any patent licenses
614 | granted to You under this License for that Work shall terminate
615 | as of the date such litigation is filed.
616 |
617 | 4. Redistribution. You may reproduce and distribute copies of the
618 | Work or Derivative Works thereof in any medium, with or without
619 | modifications, and in Source or Object form, provided that You
620 | meet the following conditions:
621 |
622 | (a) You must give any other recipients of the Work or
623 | Derivative Works a copy of this License; and
624 |
625 | (b) You must cause any modified files to carry prominent notices
626 | stating that You changed the files; and
627 |
628 | (c) You must retain, in the Source form of any Derivative Works
629 | that You distribute, all copyright, patent, trademark, and
630 | attribution notices from the Source form of the Work,
631 | excluding those notices that do not pertain to any part of
632 | the Derivative Works; and
633 |
634 | (d) If the Work includes a "NOTICE" text file as part of its
635 | distribution, then any Derivative Works that You distribute must
636 | include a readable copy of the attribution notices contained
637 | within such NOTICE file, excluding those notices that do not
638 | pertain to any part of the Derivative Works, in at least one
639 | of the following places: within a NOTICE text file distributed
640 | as part of the Derivative Works; within the Source form or
641 | documentation, if provided along with the Derivative Works; or,
642 | within a display generated by the Derivative Works, if and
643 | wherever such third-party notices normally appear. The contents
644 | of the NOTICE file are for informational purposes only and
645 | do not modify the License. You may add Your own attribution
646 | notices within Derivative Works that You distribute, alongside
647 | or as an addendum to the NOTICE text from the Work, provided
648 | that such additional attribution notices cannot be construed
649 | as modifying the License.
650 |
651 | You may add Your own copyright statement to Your modifications and
652 | may provide additional or different license terms and conditions
653 | for use, reproduction, or distribution of Your modifications, or
654 | for any such Derivative Works as a whole, provided Your use,
655 | reproduction, and distribution of the Work otherwise complies with
656 | the conditions stated in this License.
657 |
658 | 5. Submission of Contributions. Unless You explicitly state otherwise,
659 | any Contribution intentionally submitted for inclusion in the Work
660 | by You to the Licensor shall be under the terms and conditions of
661 | this License, without any additional terms or conditions.
662 | Notwithstanding the above, nothing herein shall supersede or modify
663 | the terms of any separate license agreement you may have executed
664 | with Licensor regarding such Contributions.
665 |
666 | 6. Trademarks. This License does not grant permission to use the trade
667 | names, trademarks, service marks, or product names of the Licensor,
668 | except as required for reasonable and customary use in describing the
669 | origin of the Work and reproducing the content of the NOTICE file.
670 |
671 | 7. Disclaimer of Warranty. Unless required by applicable law or
672 | agreed to in writing, Licensor provides the Work (and each
673 | Contributor provides its Contributions) on an "AS IS" BASIS,
674 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
675 | implied, including, without limitation, any warranties or conditions
676 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
677 | PARTICULAR PURPOSE. You are solely responsible for determining the
678 | appropriateness of using or redistributing the Work and assume any
679 | risks associated with Your exercise of permissions under this License.
680 |
681 | 8. Limitation of Liability. In no event and under no legal theory,
682 | whether in tort (including negligence), contract, or otherwise,
683 | unless required by applicable law (such as deliberate and grossly
684 | negligent acts) or agreed to in writing, shall any Contributor be
685 | liable to You for damages, including any direct, indirect, special,
686 | incidental, or consequential damages of any character arising as a
687 | result of this License or out of the use or inability to use the
688 | Work (including but not limited to damages for loss of goodwill,
689 | work stoppage, computer failure or malfunction, or any and all
690 | other commercial damages or losses), even if such Contributor
691 | has been advised of the possibility of such damages.
692 |
693 | 9. Accepting Warranty or Additional Liability. While redistributing
694 | the Work or Derivative Works thereof, You may choose to offer,
695 | and charge a fee for, acceptance of support, warranty, indemnity,
696 | or other liability obligations and/or rights consistent with this
697 | License. However, in accepting such obligations, You may act only
698 | on Your own behalf and on Your sole responsibility, not on behalf
699 | of any other Contributor, and only if You agree to indemnify,
700 | defend, and hold each Contributor harmless for any liability
701 | incurred by, or claims asserted against, such Contributor by reason
702 | of your accepting any such warranty or additional liability.
703 |
704 | END OF TERMS AND CONDITIONS
705 |
706 | APPENDIX: How to apply the Apache License to your work.
707 |
708 | To apply the Apache License to your work, attach the following
709 | boilerplate notice, with the fields enclosed by brackets "{}"
710 | replaced with your own identifying information. (Don't include
711 | the brackets!) The text should be enclosed in the appropriate
712 | comment syntax for the file format. We also recommend that a
713 | file or class name and description of purpose be included on the
714 | same "printed page" as the copyright notice for easier
715 | identification within third-party archives.
716 |
717 | Copyright 2018 Gregor Martynus and other contributors.
718 |
719 | Licensed under the Apache License, Version 2.0 (the "License");
720 | you may not use this file except in compliance with the License.
721 | You may obtain a copy of the License at
722 |
723 | http://www.apache.org/licenses/LICENSE-2.0
724 |
725 | Unless required by applicable law or agreed to in writing, software
726 | distributed under the License is distributed on an "AS IS" BASIS,
727 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
728 | See the License for the specific language governing permissions and
729 | limitations under the License.
730 |
731 |
732 | deprecation
733 | ISC
734 | The ISC License
735 |
736 | Copyright (c) Gregor Martynus and contributors
737 |
738 | Permission to use, copy, modify, and/or distribute this software for any
739 | purpose with or without fee is hereby granted, provided that the above
740 | copyright notice and this permission notice appear in all copies.
741 |
742 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
743 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
744 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
745 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
746 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
747 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
748 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
749 |
750 |
751 | fs-extra
752 | MIT
753 | (The MIT License)
754 |
755 | Copyright (c) 2011-2017 JP Richardson
756 |
757 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
758 | (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
759 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
760 | furnished to do so, subject to the following conditions:
761 |
762 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
763 |
764 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
765 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
766 | OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
767 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
768 |
769 |
770 | graceful-fs
771 | ISC
772 | The ISC License
773 |
774 | Copyright (c) 2011-2022 Isaac Z. Schlueter, Ben Noordhuis, and Contributors
775 |
776 | Permission to use, copy, modify, and/or distribute this software for any
777 | purpose with or without fee is hereby granted, provided that the above
778 | copyright notice and this permission notice appear in all copies.
779 |
780 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
781 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
782 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
783 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
784 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
785 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
786 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
787 |
788 |
789 | jsonfile
790 | MIT
791 | (The MIT License)
792 |
793 | Copyright (c) 2012-2015, JP Richardson
794 |
795 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
796 | (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
797 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
798 | furnished to do so, subject to the following conditions:
799 |
800 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
801 |
802 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
803 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
804 | OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
805 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
806 |
807 |
808 | object-resolve-path
809 | MIT
810 | The MIT License (MIT)
811 |
812 | Copyright (c) 2015 Jiri Spac
813 |
814 | Permission is hereby granted, free of charge, to any person obtaining a copy
815 | of this software and associated documentation files (the "Software"), to deal
816 | in the Software without restriction, including without limitation the rights
817 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
818 | copies of the Software, and to permit persons to whom the Software is
819 | furnished to do so, subject to the following conditions:
820 |
821 | The above copyright notice and this permission notice shall be included in all
822 | copies or substantial portions of the Software.
823 |
824 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
825 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
826 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
827 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
828 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
829 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
830 | SOFTWARE.
831 |
832 |
833 |
834 | once
835 | ISC
836 | The ISC License
837 |
838 | Copyright (c) Isaac Z. Schlueter and Contributors
839 |
840 | Permission to use, copy, modify, and/or distribute this software for any
841 | purpose with or without fee is hereby granted, provided that the above
842 | copyright notice and this permission notice appear in all copies.
843 |
844 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
845 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
846 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
847 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
848 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
849 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
850 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
851 |
852 |
853 | tmp
854 | MIT
855 | The MIT License (MIT)
856 |
857 | Copyright (c) 2014 KARASZI István
858 |
859 | Permission is hereby granted, free of charge, to any person obtaining a copy
860 | of this software and associated documentation files (the "Software"), to deal
861 | in the Software without restriction, including without limitation the rights
862 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
863 | copies of the Software, and to permit persons to whom the Software is
864 | furnished to do so, subject to the following conditions:
865 |
866 | The above copyright notice and this permission notice shall be included in all
867 | copies or substantial portions of the Software.
868 |
869 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
870 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
871 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
872 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
873 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
874 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
875 | SOFTWARE.
876 |
877 |
878 | tunnel
879 | MIT
880 | The MIT License (MIT)
881 |
882 | Copyright (c) 2012 Koichi Kobayashi
883 |
884 | Permission is hereby granted, free of charge, to any person obtaining a copy
885 | of this software and associated documentation files (the "Software"), to deal
886 | in the Software without restriction, including without limitation the rights
887 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
888 | copies of the Software, and to permit persons to whom the Software is
889 | furnished to do so, subject to the following conditions:
890 |
891 | The above copyright notice and this permission notice shall be included in
892 | all copies or substantial portions of the Software.
893 |
894 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
895 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
896 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
897 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
898 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
899 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
900 | THE SOFTWARE.
901 |
902 |
903 | undici
904 | MIT
905 | MIT License
906 |
907 | Copyright (c) Matteo Collina and Undici contributors
908 |
909 | Permission is hereby granted, free of charge, to any person obtaining a copy
910 | of this software and associated documentation files (the "Software"), to deal
911 | in the Software without restriction, including without limitation the rights
912 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
913 | copies of the Software, and to permit persons to whom the Software is
914 | furnished to do so, subject to the following conditions:
915 |
916 | The above copyright notice and this permission notice shall be included in all
917 | copies or substantial portions of the Software.
918 |
919 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
920 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
921 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
922 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
923 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
924 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
925 | SOFTWARE.
926 |
927 |
928 | universal-user-agent
929 | ISC
930 | # [ISC License](https://spdx.org/licenses/ISC)
931 |
932 | Copyright (c) 2018, Gregor Martynus (https://github.com/gr2m)
933 |
934 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
935 |
936 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
937 |
938 |
939 | universalify
940 | MIT
941 | (The MIT License)
942 |
943 | Copyright (c) 2017, Ryan Zimmerman
944 |
945 | Permission is hereby granted, free of charge, to any person obtaining a copy of
946 | this software and associated documentation files (the 'Software'), to deal in
947 | the Software without restriction, including without limitation the rights to
948 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
949 | the Software, and to permit persons to whom the Software is furnished to do so,
950 | subject to the following conditions:
951 |
952 | The above copyright notice and this permission notice shall be included in all
953 | copies or substantial portions of the Software.
954 |
955 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
956 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
957 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
958 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
959 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
960 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
961 |
962 |
963 | uuid
964 | MIT
965 | The MIT License (MIT)
966 |
967 | Copyright (c) 2010-2020 Robert Kieffer and other contributors
968 |
969 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
970 |
971 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
972 |
973 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
974 |
975 |
976 | wrappy
977 | ISC
978 | The ISC License
979 |
980 | Copyright (c) Isaac Z. Schlueter and Contributors
981 |
982 | Permission to use, copy, modify, and/or distribute this software for any
983 | purpose with or without fee is hereby granted, provided that the above
984 | copyright notice and this permission notice appear in all copies.
985 |
986 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
987 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
988 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
989 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
990 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
991 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
992 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
993 |
--------------------------------------------------------------------------------
/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import js from "@eslint/js";
2 | import jest from "eslint-plugin-jest";
3 | import globals from "globals";
4 |
5 | export default [
6 | js.configs.recommended,
7 | {
8 | languageOptions: {
9 | parserOptions: {
10 | ecmaVersion: 2017,
11 | sourceType: "module"
12 | },
13 | globals: {
14 | ...globals.node,
15 | ...globals.es2015,
16 | ...globals.jest
17 | }
18 | },
19 | plugins: { jest },
20 | rules: {
21 | semi: "error",
22 | "no-tabs": "error",
23 | "no-console": "off"
24 | }
25 | },
26 | {
27 | ignores: ["eslint.config.mjs", "dist/*"]
28 | }
29 | ];
30 |
--------------------------------------------------------------------------------
/it/it.js:
--------------------------------------------------------------------------------
1 | const { Octokit } = require("@octokit/rest");
2 |
3 | const { executeLocally } = require("../lib/api");
4 | const { createConfig } = require("../lib/common");
5 |
6 | async function main() {
7 | require("dotenv").config();
8 |
9 | const token = process.env.GITHUB_TOKEN;
10 |
11 | const octokit = new Octokit({
12 | baseUrl: "https://api.github.com",
13 | auth: `token ${token}`,
14 | userAgent: "pascalgn/automerge-action-it"
15 | });
16 |
17 | const config = createConfig({
18 | UPDATE_LABELS: "it-update",
19 | MERGE_LABELS: "it-merge",
20 | MERGE_REQUIRED_APPROVALS: "0",
21 | MERGE_REMOVE_LABELS: "it-merge",
22 | MERGE_RETRIES: "3",
23 | MERGE_RETRY_SLEEP: "2000",
24 | MERGE_ERROR_FAIL: "true"
25 | });
26 |
27 | const context = { token, octokit, config };
28 |
29 | await executeLocally(context, process.env.URL);
30 | }
31 |
32 | main().catch(e => {
33 | process.exitCode = 1;
34 | console.error(e);
35 | });
36 |
--------------------------------------------------------------------------------
/lib/api.js:
--------------------------------------------------------------------------------
1 | const process = require("process");
2 |
3 | const { setOutput } = require("@actions/core");
4 |
5 | const {
6 | ClientError,
7 | logger,
8 | RESULT_NOT_READY,
9 | RESULT_SKIPPED
10 | } = require("./common");
11 | const { update } = require("./update");
12 | const { merge } = require("./merge");
13 | const { branchName } = require("./util");
14 |
15 | const GITHUB_SERVER_URL = process.env.GITHUB_SERVER_URL || "https://github.com";
16 |
17 | const URL_REGEXP = new RegExp(
18 | `^${GITHUB_SERVER_URL}/([^/]+)/([^/]+)/(pull|tree)/([^ ]+)$`
19 | );
20 |
21 | const RELEVANT_ACTIONS = [
22 | "labeled",
23 | "unlabeled",
24 | "synchronize",
25 | "opened",
26 | "edited",
27 | "ready_for_review",
28 | "reopened",
29 | "unlocked"
30 | ];
31 |
32 | // we'll only update a few PRs at once:
33 | const MAX_PR_COUNT = process.env.MAX_PR_COUNT || 10;
34 |
35 | async function executeLocally(context, url) {
36 | const { octokit } = context;
37 |
38 | const m = url.match(URL_REGEXP);
39 | if (m && m[3] === "pull") {
40 | logger.debug("Getting PR data...");
41 | const { data: pull_request } = await octokit.pulls.get({
42 | owner: m[1],
43 | repo: m[2],
44 | pull_number: m[4],
45 | headers: { "If-None-Match": "" }
46 | });
47 |
48 | const event = {
49 | action: "opened",
50 | pull_request
51 | };
52 |
53 | return executeGitHubAction(context, "pull_request", event);
54 | } else if (m && m[3] === "tree") {
55 | const event = {
56 | ref: `refs/heads/${m[4]}`,
57 | repository: {
58 | name: m[2],
59 | owner: {
60 | name: m[1]
61 | }
62 | }
63 | };
64 |
65 | return executeGitHubAction(context, "push", event);
66 | } else {
67 | throw new ClientError(`invalid URL: ${url}`);
68 | }
69 | }
70 |
71 | async function executeGitHubAction(context, eventName, eventData) {
72 | const result = await executeGitHubActionImpl(context, eventName, eventData);
73 | logger.info("Action result:", result);
74 |
75 | let singleResult;
76 | if (Array.isArray(result)) {
77 | logger.info("More than one result, using first result for action output");
78 | singleResult = result[0];
79 | } else if (result != null) {
80 | singleResult = result;
81 | } else {
82 | throw new Error("invalid result!");
83 | }
84 |
85 | const { mergeResult, pullRequestNumber } = singleResult || {};
86 | setOutput("mergeResult", mergeResult || RESULT_SKIPPED);
87 | setOutput("pullRequestNumber", pullRequestNumber || 0);
88 | }
89 |
90 | async function executeGitHubActionImpl(context, eventName, eventData) {
91 | logger.info("Event name:", eventName);
92 | logger.trace("Event data:", eventData);
93 |
94 | if (context.config.pullRequest != null) {
95 | return await handleArbitraryPullRequestUpdate(context, eventData);
96 | } else if (["push"].includes(eventName)) {
97 | await handleBaseBranchUpdate(context, eventName, eventData);
98 | } else if (["status"].includes(eventName)) {
99 | return await handleStatusUpdate(context, eventName, eventData);
100 | } else if (["pull_request", "pull_request_target"].includes(eventName)) {
101 | return await handlePullRequestUpdate(context, eventName, eventData);
102 | } else if (["check_suite", "check_run", "workflow_run"].includes(eventName)) {
103 | return await handleCheckOrWorkflowUpdate(context, eventName, eventData);
104 | } else if (["pull_request_review"].includes(eventName)) {
105 | return await handlePullRequestReviewUpdate(context, eventName, eventData);
106 | } else if (["schedule", "repository_dispatch"].includes(eventName)) {
107 | return await handleScheduleTriggerOrRepositoryDispatch(context);
108 | } else if (["issue_comment"].includes(eventName)) {
109 | return await handleIssueComment(context, eventName, eventData);
110 | } else if (["workflow_dispatch"].includes(eventName)) {
111 | return await handleWorkflowDispatch(context, eventName, eventData);
112 | } else {
113 | throw new ClientError(`invalid event type: ${eventName}`);
114 | }
115 | }
116 |
117 | async function handlePullRequestUpdate(context, eventName, event) {
118 | const { action } = event;
119 | if (!RELEVANT_ACTIONS.includes(action)) {
120 | logger.info("Action ignored:", eventName, action);
121 | return { mergeResult: RESULT_SKIPPED };
122 | }
123 |
124 | const pullRequest = await fetchPullRequest(
125 | context,
126 | event.pull_request.base.repo,
127 | event.pull_request
128 | );
129 |
130 | return updateAndMerge(context, pullRequest);
131 | }
132 |
133 | async function handleArbitraryPullRequestUpdate(context, eventData) {
134 | const { config, octokit } = context;
135 |
136 | const repoOwner =
137 | config.pullRequest.repoOwner || eventData.repository.owner.login;
138 | const repoName = config.pullRequest.repoName || eventData.repository.name;
139 | const { pullRequestNumber } = config.pullRequest;
140 |
141 | logger.info(`Looking for pull request #${pullRequestNumber}...`);
142 |
143 | try {
144 | const { data: pullRequest } = await octokit.pulls.get({
145 | owner: repoOwner,
146 | repo: repoName,
147 | pull_number: pullRequestNumber,
148 | headers: { "If-None-Match": "" }
149 | });
150 | logger.trace("Full PR:", pullRequest);
151 |
152 | return updateAndMerge(context, pullRequest);
153 | } catch (e) {
154 | logger.error(
155 | `Error fetching pull request: ${repoOwner}/${repoName}/${pullRequestNumber}`
156 | );
157 | throw e;
158 | }
159 | }
160 |
161 | async function handleCheckOrWorkflowUpdate(context, eventName, event) {
162 | const { action } = event;
163 | const eventType = eventName === "workflow_run" ? "workflow" : "status check";
164 | if (action !== "completed") {
165 | logger.info(`A ${eventType} is not yet complete:`, eventName);
166 | return { mergeResult: RESULT_NOT_READY };
167 | }
168 |
169 | const payload = event[eventName];
170 | if (!payload) {
171 | throw new Error(`failed to find payload for event type: ${eventName}`);
172 | }
173 | if (payload.conclusion !== "success") {
174 | logger.info(`A ${eventType} completed unsuccessfully:`, eventName);
175 | return { mergeResult: RESULT_NOT_READY };
176 | }
177 |
178 | logger.info(`${eventType} completed successfully`);
179 |
180 | const eventPullRequest = payload.pull_requests[0];
181 | if (eventPullRequest != null) {
182 | const { octokit } = context;
183 | const { data: pullRequest } = await octokit.request(eventPullRequest.url);
184 | logger.trace("PR:", pullRequest);
185 |
186 | return updateAndMerge(context, pullRequest);
187 | } else {
188 | const branchName = payload.head_branch;
189 | if (branchName != null) {
190 | return await checkPullRequestsForBranches(context, event, branchName);
191 | } else {
192 | return await checkPullRequestsForHeadSha(
193 | context,
194 | event.repository,
195 | payload.head_sha
196 | );
197 | }
198 | }
199 | }
200 |
201 | async function handlePullRequestReviewUpdate(context, eventName, event) {
202 | const { action, review } = event;
203 | if (action === "submitted") {
204 | if (review.state === "approved") {
205 | const pullRequest = await fetchPullRequest(
206 | context,
207 | event.pull_request.base.repo,
208 | event.pull_request
209 | );
210 | return updateAndMerge(context, pullRequest);
211 | } else {
212 | logger.info("Review state is not approved:", review.state);
213 | logger.info("Action ignored:", eventName, action);
214 | }
215 | } else {
216 | logger.info("Action ignored:", eventName, action);
217 | }
218 | return { mergeResult: RESULT_SKIPPED };
219 | }
220 |
221 | async function handleStatusUpdate(context, eventName, event) {
222 | const { state, branches } = event;
223 | if (state !== "success") {
224 | logger.info("Event state ignored:", eventName, state);
225 | return [];
226 | }
227 |
228 | if (!branches || branches.length === 0) {
229 | logger.info("No branches have been referenced:", eventName);
230 | return [];
231 | }
232 |
233 | let results = [];
234 | for (const branch of branches) {
235 | results = results.concat(
236 | await checkPullRequestsForBranches(context, event, branch.name)
237 | );
238 | }
239 | return results;
240 | }
241 |
242 | async function checkPullRequestsForBranches(context, event, branchName) {
243 | const { octokit } = context;
244 | logger.debug("Listing pull requests for", branchName, "...");
245 | const { data: pullRequests } = await octokit.pulls.list({
246 | owner: event.repository.owner.login,
247 | repo: event.repository.name,
248 | state: "open",
249 | head: `${event.repository.owner.login}:${branchName}`,
250 | sort: "updated",
251 | direction: "desc",
252 | per_page: MAX_PR_COUNT
253 | });
254 |
255 | logger.trace("PR list:", pullRequests);
256 |
257 | let updated = 0;
258 | let results = [];
259 | for (const pullRequest of pullRequests) {
260 | try {
261 | const result = await updateAndMerge(context, pullRequest);
262 | results.push(result);
263 | ++updated;
264 | } catch (e) {
265 | logger.error(e);
266 | }
267 | }
268 |
269 | if (updated === 0) {
270 | logger.info("No PRs have been updated/merged");
271 | }
272 | return results;
273 | }
274 |
275 | async function checkPullRequestsForHeadSha(context, repo, head_sha) {
276 | const { octokit } = context;
277 | logger.debug("Listing pull requests to look for", head_sha, "...");
278 | const { data: pullRequests } = await octokit.pulls.list({
279 | owner: repo.owner.login,
280 | repo: repo.name,
281 | state: "open",
282 | sort: "updated",
283 | direction: "desc",
284 | per_page: MAX_PR_COUNT
285 | });
286 |
287 | let updated = 0;
288 | let foundPR = false;
289 | let results = [];
290 | for (const pullRequest of pullRequests) {
291 | if (pullRequest.head.sha !== head_sha) {
292 | continue;
293 | }
294 | foundPR = true;
295 | try {
296 | const result = await updateAndMerge(context, pullRequest);
297 | results.push(result);
298 | ++updated;
299 | } catch (e) {
300 | logger.error(e);
301 | }
302 | }
303 |
304 | if (updated === 0) {
305 | logger.info("No PRs have been updated/merged");
306 | }
307 | if (!foundPR) {
308 | logger.info(
309 | "Could not find branch name in this status check result" +
310 | " or corresponding PR from a forked repository"
311 | );
312 | }
313 | return results;
314 | }
315 |
316 | async function handleBaseBranchUpdate(context, eventName, event) {
317 | const { ref } = event;
318 | const branch = branchName(ref);
319 | if (!branch) {
320 | logger.info("Push does not reference a branch:", ref);
321 | return;
322 | }
323 |
324 | logger.debug("Updated branch:", branch);
325 |
326 | const { octokit } = context;
327 |
328 | logger.debug("Listing pull requests...");
329 | const { data: pullRequests } = await octokit.pulls.list({
330 | owner: event.repository.owner.login,
331 | repo: event.repository.name,
332 | state: "open",
333 | base: branch,
334 | sort: "updated",
335 | direction: "desc",
336 | per_page: MAX_PR_COUNT
337 | });
338 |
339 | logger.trace("PR list:", pullRequests);
340 |
341 | if (pullRequests.length > 0) {
342 | logger.info("Open PRs:", pullRequests.length);
343 | } else {
344 | logger.info("No open PRs for", branch);
345 | return;
346 | }
347 |
348 | let updated = 0;
349 | for (const pullRequest of pullRequests) {
350 | try {
351 | await update(context, pullRequest);
352 | updated++;
353 | } catch (e) {
354 | logger.error(e);
355 | }
356 | }
357 |
358 | if (updated > 0) {
359 | logger.info(updated, "PRs based on", branch, "have been updated");
360 | } else {
361 | logger.info("No PRs based on", branch, "have been updated");
362 | }
363 | }
364 |
365 | async function handleWorkflowDispatch(context, eventName, event) {
366 | const { ref } = event;
367 | const branch = branchName(ref);
368 | if (!branch) {
369 | logger.info("Dispatch does not reference a branch:", ref);
370 | return { mergeResult: RESULT_SKIPPED };
371 | }
372 |
373 | return await checkPullRequestsForBranches(context, event, branch);
374 | }
375 |
376 | async function handleScheduleTriggerOrRepositoryDispatch(context) {
377 | const { octokit } = context;
378 |
379 | const { GITHUB_REPOSITORY } = process.env;
380 | const [owner, repo] = (GITHUB_REPOSITORY || "").split("/", 2);
381 |
382 | if (!owner || !repo) {
383 | throw new Error(`invalid GITHUB_REPOSITORY value: ${GITHUB_REPOSITORY}`);
384 | }
385 |
386 | logger.debug("Listing pull requests ...");
387 | const { data: pullRequests } = await octokit.pulls.list({
388 | owner,
389 | repo,
390 | state: "open",
391 | sort: "updated",
392 | direction: "desc",
393 | per_page: MAX_PR_COUNT
394 | });
395 |
396 | logger.trace("PR list:", pullRequests);
397 |
398 | let updated = 0;
399 | let results = [];
400 | for (const pullRequest of pullRequests) {
401 | try {
402 | const result = await updateAndMerge(context, pullRequest);
403 | results.push(result);
404 | ++updated;
405 | } catch (e) {
406 | logger.error(e);
407 | }
408 | }
409 |
410 | if (updated === 0) {
411 | logger.info("No PRs have been updated/merged");
412 | }
413 | return results;
414 | }
415 |
416 | async function handleIssueComment(context, eventName, event) {
417 | const { action, issue, repository } = event;
418 | if (action === "created") {
419 | if (issue.pull_request == null) {
420 | logger.info("Comment not on a PR, skipping");
421 | } else {
422 | const pullRequest = await fetchPullRequest(context, repository, issue);
423 | return updateAndMerge(context, pullRequest);
424 | }
425 | } else {
426 | logger.info("Action ignored:", eventName, action);
427 | }
428 | return { mergeResult: RESULT_SKIPPED };
429 | }
430 |
431 | async function fetchPullRequest(context, repository, issue) {
432 | const { octokit } = context;
433 | const { number } = issue;
434 |
435 | logger.debug("Getting pull request info for", number, "...");
436 | let { data: pullRequest } = await octokit.pulls.get({
437 | owner: repository.owner.login,
438 | repo: repository.name,
439 | pull_number: number,
440 | headers: { "If-None-Match": "" }
441 | });
442 |
443 | logger.trace("Full PR:", pullRequest);
444 | return pullRequest;
445 | }
446 |
447 | async function updateAndMerge(context, pullRequest) {
448 | const approvalCount = await fetchApprovalReviewCount(context, pullRequest);
449 | await update(context, pullRequest);
450 | const mergeResult = await merge(context, pullRequest, approvalCount);
451 | return { mergeResult, pullRequestNumber: pullRequest.number };
452 | }
453 |
454 | async function fetchApprovalReviewCount(context, pullRequest) {
455 | const {
456 | octokit,
457 | config: { mergeRequiredApprovals }
458 | } = context;
459 | const { number } = pullRequest;
460 |
461 | if (mergeRequiredApprovals === 0) {
462 | // If we don't care about review approvals, let's short circuit.
463 | return 0;
464 | }
465 |
466 | logger.debug("Getting reviews for", number, "...");
467 | const reviews = await octokit.paginate(octokit.pulls.listReviews, {
468 | owner: pullRequest.base.repo.owner.login,
469 | repo: pullRequest.base.repo.name,
470 | pull_number: number
471 | });
472 |
473 | const approvingReviewers = reviews
474 | .filter(review => review.state === "APPROVED")
475 | .map(review => review.user.login);
476 | const uniqueApprovingReviewers = [...new Set(approvingReviewers)];
477 |
478 | logger.trace("Approval reviewers:", uniqueApprovingReviewers);
479 | return uniqueApprovingReviewers.length;
480 | }
481 |
482 | module.exports = { executeLocally, executeGitHubAction };
483 |
--------------------------------------------------------------------------------
/lib/common.js:
--------------------------------------------------------------------------------
1 | const util = require("util");
2 | const process = require("process");
3 | const fse = require("fs-extra");
4 | const tmp = require("tmp");
5 |
6 | const RESULT_SKIPPED = "skipped";
7 | const RESULT_NOT_READY = "not_ready";
8 | const RESULT_AUTHOR_FILTERED = "author_filtered";
9 | const RESULT_MERGE_FAILED = "merge_failed";
10 | const RESULT_MERGED = "merged";
11 |
12 | class ClientError extends Error {}
13 |
14 | class TimeoutError extends Error {}
15 |
16 | function log(prefix, obj) {
17 | if (process.env.NODE_ENV !== "test") {
18 | const now = new Date().toISOString();
19 | const str = obj.map(o => (typeof o === "object" ? inspect(o) : o));
20 | if (prefix) {
21 | console.log.apply(console, [now, prefix, ...str]);
22 | } else {
23 | console.log.apply(console, [now, ...str]);
24 | }
25 | }
26 | }
27 |
28 | const logger = {
29 | level: "info",
30 |
31 | trace: (...str) => {
32 | if (logger.level === "trace") {
33 | log("TRACE", str);
34 | }
35 | },
36 |
37 | debug: (...str) => {
38 | if (logger.level === "trace" || logger.level === "debug") {
39 | log("DEBUG", str);
40 | }
41 | },
42 |
43 | info: (...str) => log("INFO ", str),
44 |
45 | error: (...str) => {
46 | if (str.length === 1 && str[0] instanceof Error) {
47 | if (logger.level === "trace" || logger.level === "debug") {
48 | log(null, [str[0].stack || str[0]]);
49 | } else {
50 | log("ERROR", [str[0].message || str[0]]);
51 | }
52 | } else {
53 | log("ERROR", str);
54 | }
55 | }
56 | };
57 |
58 | function inspect(obj) {
59 | return util.inspect(obj, false, null, true);
60 | }
61 |
62 | function createConfig(env = {}) {
63 | function parseMergeLabels(str, defaultValue) {
64 | const arr = (str == null ? defaultValue : str)
65 | .split(",")
66 | .map(s => s.trim());
67 | return {
68 | required: arr.filter(s => !s.startsWith("!") && s.length > 0),
69 | blocking: arr
70 | .filter(s => s.startsWith("!"))
71 | .map(s => s.substr(1).trim())
72 | .filter(s => s.length > 0)
73 | };
74 | }
75 |
76 | function parseLabelMethods(str) {
77 | return (str ? str.split(",") : []).map(lm => {
78 | const [label, method] = lm.split("=");
79 | if (!label || !method) {
80 | throw new Error(
81 | `Couldn't parse "${lm}" as "