mirror of
https://github.com/actions/add-to-project.git
synced 2025-12-11 04:32:47 +00:00
Compare commits
279 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31b3f3ccdc | ||
|
|
039f00e4e1 | ||
|
|
74235d0976 | ||
|
|
5d4ef34b4c | ||
|
|
38a0adc233 | ||
|
|
90818bfeba | ||
|
|
2a9da7be76 | ||
|
|
07c29ba779 | ||
|
|
5b64707bb3 | ||
|
|
321b7eb9bf | ||
|
|
83244eb733 | ||
|
|
fdae002f2c | ||
|
|
c475ba7265 | ||
|
|
7a13e6eeb9 | ||
|
|
7a13494c05 | ||
|
|
a6e07cb1e4 | ||
|
|
9e340dd475 | ||
|
|
0893101300 | ||
|
|
2250fd41d0 | ||
|
|
8a14d78fcf | ||
|
|
a3544f542a | ||
|
|
39569f9b7d | ||
|
|
15db5ef38c | ||
|
|
f6bbaa9eb7 | ||
|
|
88d0700668 | ||
|
|
399442f46a | ||
|
|
e78e561fec | ||
|
|
097fa0553b | ||
|
|
703deace27 | ||
|
|
895720c423 | ||
|
|
b433768232 | ||
|
|
22caa11a6d | ||
|
|
16df187cf9 | ||
|
|
ad9efdf1e6 | ||
|
|
777245737e | ||
|
|
5f4850959b | ||
|
|
4756e6330f | ||
|
|
9f96b16f44 | ||
|
|
5f0c606906 | ||
|
|
11ef9e1e8d | ||
|
|
a28950b59e | ||
|
|
5b15b1a619 | ||
|
|
10934d1d3d | ||
|
|
8434539ee2 | ||
|
|
83567abcd1 | ||
|
|
ba4c19ddac | ||
|
|
2547408f6f | ||
|
|
28a69b27b6 | ||
|
|
ecb32ed323 | ||
|
|
03c85cc34a | ||
|
|
70264bb4d1 | ||
|
|
5a55c0cba5 | ||
|
|
09abe09dcd | ||
|
|
ed88cdc97d | ||
|
|
a173cb1610 | ||
|
|
b6a9b6ff3a | ||
|
|
3f557757a9 | ||
|
|
36391c5bc3 | ||
|
|
b4ca87ff52 | ||
|
|
1fdfb8c67e | ||
|
|
add81c33d2 | ||
|
|
f760b9f1a0 | ||
|
|
bcf48a5d57 | ||
|
|
80b1710843 | ||
|
|
547a49eea1 | ||
|
|
91b8ba84c0 | ||
|
|
247085562b | ||
|
|
99b54d5e6f | ||
|
|
e92b0df91d | ||
|
|
6bf5cd2100 | ||
|
|
aebf7de9ea | ||
|
|
e83ada4abb | ||
|
|
f52b6e4974 | ||
|
|
60ba784944 | ||
|
|
00f7bf6e9b | ||
|
|
41f5c1fa85 | ||
|
|
f64617d938 | ||
|
|
26739f107e | ||
|
|
383f6dfeb4 | ||
|
|
ce1983ff4e | ||
|
|
52f0dde099 | ||
|
|
7d1730801e | ||
|
|
dc0c796a1a | ||
|
|
2abae3f03b | ||
|
|
00a23495f4 | ||
|
|
d19a1438a9 | ||
|
|
1b3c192b00 | ||
|
|
92471ee0d5 | ||
|
|
25580575b4 | ||
|
|
f38a93c5a3 | ||
|
|
f8f1995a9b | ||
|
|
9ce1d75007 | ||
|
|
0c2909c5fd | ||
|
|
dd0961446c | ||
|
|
26f9feae0a | ||
|
|
c261c9a95f | ||
|
|
31901d229d | ||
|
|
0a78e5c8ed | ||
|
|
c4a92acacb | ||
|
|
2ab330cfd5 | ||
|
|
06e54d7eae | ||
|
|
91af7eb93e | ||
|
|
47060e7c7b | ||
|
|
2163ff9e29 | ||
|
|
70ce5a5ec5 | ||
|
|
78711d5ed6 | ||
|
|
a4a63c373b | ||
|
|
b7cc00e404 | ||
|
|
2ca1de6159 | ||
|
|
64a7c52604 | ||
|
|
7540d630bd | ||
|
|
156525c5e2 | ||
|
|
1885da210d | ||
|
|
16a5c31be8 | ||
|
|
29766ca0ac | ||
|
|
fe1b8050dc | ||
|
|
d3e23d39c7 | ||
|
|
e20f3a98a6 | ||
|
|
5a7afe53e1 | ||
|
|
958916895a | ||
|
|
bf580a9c46 | ||
|
|
db7cb0d7f9 | ||
|
|
b6a72217f5 | ||
|
|
686c1a45e0 | ||
|
|
221804fc4f | ||
|
|
b186de4d0e | ||
|
|
75921323e3 | ||
|
|
c41809958a | ||
|
|
42ad4aed60 | ||
|
|
b56b7e6441 | ||
|
|
960fbad431 | ||
|
|
a130af5794 | ||
|
|
8d2064c2fe | ||
|
|
cd062f6530 | ||
|
|
c7ca843e95 | ||
|
|
c30dddf387 | ||
|
|
9eaa8568e2 | ||
|
|
195ebe73dd | ||
|
|
8f9378c977 | ||
|
|
edd3921f6c | ||
|
|
73dbef5228 | ||
|
|
b749f03d83 | ||
|
|
f1318f907d | ||
|
|
58045a0196 | ||
|
|
b79a170093 | ||
|
|
7a1b708e24 | ||
|
|
7e0e2c594b | ||
|
|
5a722b2d85 | ||
|
|
b84343956f | ||
|
|
fde71205f0 | ||
|
|
0639048d29 | ||
|
|
889cb383ac | ||
|
|
394bc02c66 | ||
|
|
e72a91f059 | ||
|
|
d37ee53182 | ||
|
|
b132be1646 | ||
|
|
ae3d163bf0 | ||
|
|
c6c527b7d4 | ||
|
|
17681e1444 | ||
|
|
5ee4c2c94a | ||
|
|
d3d1191194 | ||
|
|
5e951ed275 | ||
|
|
d8fd9122ff | ||
|
|
8afc027fc3 | ||
|
|
d3b6ae9953 | ||
|
|
327b1a6a80 | ||
|
|
51e172a520 | ||
|
|
2c51ab2882 | ||
|
|
283800435b | ||
|
|
bb4087f96d | ||
|
|
d5bf1a4311 | ||
|
|
7ecd3b9a8a | ||
|
|
019149543c | ||
|
|
82f0eaddf3 | ||
|
|
11ec699375 | ||
|
|
d79571d873 | ||
|
|
6979245da4 | ||
|
|
1450adf89b | ||
|
|
686e886c25 | ||
|
|
4cdd6f143b | ||
|
|
24a59b80ce | ||
|
|
eca008a168 | ||
|
|
dd6c3f1c1c | ||
|
|
338ac1805e | ||
|
|
2ecb35a6bd | ||
|
|
8ff00cfda3 | ||
|
|
dfe9c0bd14 | ||
|
|
0decb7a26e | ||
|
|
96ce2f0192 | ||
|
|
b572ef66d4 | ||
|
|
dbdd6bcdc8 | ||
|
|
8a130a1de7 | ||
|
|
b6d4389ed6 | ||
|
|
f5e0362b57 | ||
|
|
836536efd8 | ||
|
|
6133899d5e | ||
|
|
35a1c9762b | ||
|
|
8a044413b5 | ||
|
|
8bdfd1c79c | ||
|
|
1ec83d22e4 | ||
|
|
f82d1e43cf | ||
|
|
e83fe43a76 | ||
|
|
7048934db4 | ||
|
|
9b06c490c1 | ||
|
|
90e8168771 | ||
|
|
e7bfcd815f | ||
|
|
82a997c52a | ||
|
|
5369ac8c20 | ||
|
|
97730f2067 | ||
|
|
0534f9e7f3 | ||
|
|
ebb11c3a4a | ||
|
|
91ab1ce991 | ||
|
|
d8478e8b6f | ||
|
|
ce41401b09 | ||
|
|
1beac71051 | ||
|
|
cb277e5c43 | ||
|
|
e52f87eff2 | ||
|
|
48bed54846 | ||
|
|
bde4e831d3 | ||
|
|
421f1345b9 | ||
|
|
8f7d4cb823 | ||
|
|
0076c5793c | ||
|
|
8cf508be80 | ||
|
|
a59f167ad9 | ||
|
|
d9c8cc2520 | ||
|
|
33e78e7743 | ||
|
|
acb5644475 | ||
|
|
01c824da16 | ||
|
|
7bf0952e0f | ||
|
|
c9e794be13 | ||
|
|
a2183751f2 | ||
|
|
bf8911a06b | ||
|
|
ddb4a8e99c | ||
|
|
2a12e1b56a | ||
|
|
61b8a9bfc7 | ||
|
|
963602c4ed | ||
|
|
b462dfb560 | ||
|
|
725d73c5c7 | ||
|
|
79260a4f4f | ||
|
|
2b09521d05 | ||
|
|
138feafd14 | ||
|
|
865cca1361 | ||
|
|
e3acb4ebda | ||
|
|
ac1b7ef80a | ||
|
|
a9f041ddd4 | ||
|
|
1809404e28 | ||
|
|
0af0b18f28 | ||
|
|
c8dd399614 | ||
|
|
f111c2aa36 | ||
|
|
12e917e04c | ||
|
|
dbe00218fb | ||
|
|
fa0b958991 | ||
|
|
f343062b82 | ||
|
|
e639bba4f0 | ||
|
|
34ff2c7db4 | ||
|
|
4065956be9 | ||
|
|
9b0fd13e3f | ||
|
|
53d95574f4 | ||
|
|
ebd4dc568a | ||
|
|
9115f344bd | ||
|
|
31c3cce717 | ||
|
|
c1795be3bc | ||
|
|
75ae529d21 | ||
|
|
93eba4a2e5 | ||
|
|
5582d9894f | ||
|
|
97e01d66ef | ||
|
|
2a4deb3f9f | ||
|
|
458653506b | ||
|
|
322721b8cd | ||
|
|
601b150078 | ||
|
|
665443b5d9 | ||
|
|
caae605ffb | ||
|
|
5d3a082e24 | ||
|
|
80b198ce77 | ||
|
|
92eaaeabac | ||
|
|
8eedaeb3f8 | ||
|
|
3b83e6acf9 | ||
|
|
0bf2f64851 | ||
|
|
ce9d751c8c |
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -18,3 +18,5 @@ jobs:
|
|||||||
npm install
|
npm install
|
||||||
- run: |
|
- run: |
|
||||||
npm run build
|
npm run build
|
||||||
|
- run: |
|
||||||
|
npm run test
|
||||||
|
|||||||
2
.licenses/npm/@actions/core.dep.yml
generated
2
.licenses/npm/@actions/core.dep.yml
generated
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: '@actions/core'
|
name: '@actions/core'
|
||||||
version: 1.9.0
|
version: 1.10.0
|
||||||
type: npm
|
type: npm
|
||||||
summary: Actions core lib
|
summary: Actions core lib
|
||||||
homepage: https://github.com/actions/toolkit/tree/main/packages/core
|
homepage: https://github.com/actions/toolkit/tree/main/packages/core
|
||||||
|
|||||||
2
.licenses/npm/@actions/github.dep.yml
generated
2
.licenses/npm/@actions/github.dep.yml
generated
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: '@actions/github'
|
name: '@actions/github'
|
||||||
version: 5.0.3
|
version: 5.1.1
|
||||||
type: npm
|
type: npm
|
||||||
summary: Actions github lib
|
summary: Actions github lib
|
||||||
homepage: https://github.com/actions/toolkit/tree/main/packages/github
|
homepage: https://github.com/actions/toolkit/tree/main/packages/github
|
||||||
|
|||||||
20
.licenses/npm/uuid.dep.yml
generated
Normal file
20
.licenses/npm/uuid.dep.yml
generated
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: uuid
|
||||||
|
version: 8.3.2
|
||||||
|
type: npm
|
||||||
|
summary: RFC4122 (v1, v4, and v5) UUIDs
|
||||||
|
homepage:
|
||||||
|
license: mit
|
||||||
|
licenses:
|
||||||
|
- sources: LICENSE.md
|
||||||
|
text: |
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2010-2020 Robert Kieffer and other contributors
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
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.
|
||||||
|
notices: []
|
||||||
18
README.md
18
README.md
@@ -1,17 +1,13 @@
|
|||||||
# actions/add-to-project
|
# actions/add-to-project
|
||||||
|
|
||||||
Use this action to automatically add the current issue or pull request to a GitHub project.
|
Use this action to automatically add the current issue or pull request to a [GitHub project](https://docs.github.com/en/issues/trying-out-the-new-projects-experience/about-projects).
|
||||||
Note that this is for [GitHub projects
|
Note that this action does not support [GitHub projects (classic)](https://docs.github.com/en/issues/organizing-your-work-with-project-boards).
|
||||||
(beta)](https://docs.github.com/en/issues/trying-out-the-new-projects-experience/about-projects),
|
|
||||||
not the original GitHub projects.
|
|
||||||
|
|
||||||
## Current Status
|
## Current Status
|
||||||
|
|
||||||
[](https://github.com/actions/add-to-project/actions/workflows/test.yml)
|
[](https://github.com/actions/add-to-project/actions/workflows/test.yml)
|
||||||
|
|
||||||
> **NOTE:** This Action (currently) only supports auto-adding Issues/Pull Requests to a Project which lives in the same organization as your target Repository.
|
> **NOTE:** ⚠️ This action no longer uses the deprecated ProjectNext API. If you are looking for the old version of that action, use version [v0.0.5](https://github.com/actions/add-to-project/releases/tag/v0.0.5).
|
||||||
|
|
||||||
> **NOTE:** This action no longer uses the deprecated ProjectNext API. If you are looking for the old version of that action, use version [v0.0.3](https://github.com/actions/add-to-project/releases/tag/v0.0.3).
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@@ -42,6 +38,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/add-to-project@RELEASE_VERSION
|
- uses: actions/add-to-project@RELEASE_VERSION
|
||||||
with:
|
with:
|
||||||
|
# You can target a project in a different organization
|
||||||
|
# to the issue
|
||||||
project-url: https://github.com/orgs/<orgName>/projects/<projectNumber>
|
project-url: https://github.com/orgs/<orgName>/projects/<projectNumber>
|
||||||
github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}
|
github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}
|
||||||
labeled: bug, needs-triage
|
labeled: bug, needs-triage
|
||||||
@@ -145,6 +143,12 @@ Using these events ensure that a given issue or pull request, in the workflow's
|
|||||||
- add the newly created PAT as a repository secret, this secret will be referenced by the [github-token input](#github-token)
|
- add the newly created PAT as a repository secret, this secret will be referenced by the [github-token input](#github-token)
|
||||||
_See [Encrypted secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) for more information_
|
_See [Encrypted secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) for more information_
|
||||||
|
|
||||||
|
## Setting a specific status or column name to the project item
|
||||||
|
|
||||||
|
If you want to add an issue to a custom default column in a project (i.e. other than 'Todo'), you can do this directly via the project UI. You don't need to add anything else to your YAML workflow file to get this to work.
|
||||||
|
|
||||||
|
Use the [Add To GitHub Projects](https://github.com/marketplace/actions/add-to-github-projects) action to assign newly opened issues to the project. And then in the project UI simply [specify which column to use as the default](https://docs.github.com/en/issues/planning-and-tracking-with-projects/learning-about-projects/quickstart-for-projects#configure-built-in-automation)!
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
To get started contributing to this project, clone it and install dependencies.
|
To get started contributing to this project, clone it and install dependencies.
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ describe('addToProject', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockGetInput({
|
mockGetInput({
|
||||||
'project-url': 'https://github.com/orgs/github/projects/1',
|
'project-url': 'https://github.com/orgs/actions/projects/1',
|
||||||
'github-token': 'gh_token'
|
'github-token': 'gh_token',
|
||||||
})
|
})
|
||||||
|
|
||||||
outputs = mockSetOutput()
|
outputs = mockSetOutput()
|
||||||
@@ -24,28 +24,87 @@ describe('addToProject', () => {
|
|||||||
jest.restoreAllMocks()
|
jest.restoreAllMocks()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('adds an issue to the project', async () => {
|
test('adds an issue from the same organization to the project', async () => {
|
||||||
|
github.context.payload = {
|
||||||
|
issue: {
|
||||||
|
number: 1,
|
||||||
|
labels: [{name: 'bug'}],
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/actions/add-to-project/issues/74',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'add-to-project',
|
||||||
|
owner: {
|
||||||
|
login: 'actions',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
mockGraphQL(
|
mockGraphQL(
|
||||||
{
|
{
|
||||||
test: /getProject/,
|
test: /getProject/,
|
||||||
return: {
|
return: {
|
||||||
organization: {
|
organization: {
|
||||||
projectV2: {
|
projectV2: {
|
||||||
id: 'project-id'
|
id: 'project-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /addProjectV2ItemById/,
|
test: /addProjectV2ItemById/,
|
||||||
return: {
|
return: {
|
||||||
addProjectV2ItemById: {
|
addProjectV2ItemById: {
|
||||||
item: {
|
item: {
|
||||||
id: 'project-item-id'
|
id: 'project-item-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
await addToProject()
|
||||||
|
|
||||||
|
expect(outputs.itemId).toEqual('project-item-id')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('adds an issue from a different organization to the project', async () => {
|
||||||
|
github.context.payload = {
|
||||||
|
issue: {
|
||||||
|
number: 2221,
|
||||||
|
labels: [{name: 'bug'}],
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/octokit/octokit.js/issues/2221',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'octokit.js',
|
||||||
|
owner: {
|
||||||
|
login: 'octokit',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
mockGraphQL(
|
||||||
|
{
|
||||||
|
test: /getProject/,
|
||||||
|
return: {
|
||||||
|
organization: {
|
||||||
|
projectV2: {
|
||||||
|
id: 'project-id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /addProjectV2DraftIssue/,
|
||||||
|
return: {
|
||||||
|
addProjectV2DraftIssue: {
|
||||||
|
projectItem: {
|
||||||
|
id: 'project-item-id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
await addToProject()
|
await addToProject()
|
||||||
@@ -55,16 +114,24 @@ describe('addToProject', () => {
|
|||||||
|
|
||||||
test('adds matching issues with a label filter without label-operator', async () => {
|
test('adds matching issues with a label filter without label-operator', async () => {
|
||||||
mockGetInput({
|
mockGetInput({
|
||||||
'project-url': 'https://github.com/orgs/github/projects/1',
|
'project-url': 'https://github.com/orgs/actions/projects/1',
|
||||||
'github-token': 'gh_token',
|
'github-token': 'gh_token',
|
||||||
labeled: 'bug, new'
|
labeled: 'bug, new',
|
||||||
})
|
})
|
||||||
|
|
||||||
github.context.payload = {
|
github.context.payload = {
|
||||||
issue: {
|
issue: {
|
||||||
number: 1,
|
number: 1,
|
||||||
labels: [{name: 'bug'}]
|
labels: [{name: 'bug'}],
|
||||||
}
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/actions/add-to-project/issues/74',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'add-to-project',
|
||||||
|
owner: {
|
||||||
|
login: 'actions',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
mockGraphQL(
|
mockGraphQL(
|
||||||
@@ -73,21 +140,21 @@ describe('addToProject', () => {
|
|||||||
return: {
|
return: {
|
||||||
organization: {
|
organization: {
|
||||||
projectV2: {
|
projectV2: {
|
||||||
id: 'project-id'
|
id: 'project-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /addProjectV2ItemById/,
|
test: /addProjectV2ItemById/,
|
||||||
return: {
|
return: {
|
||||||
addProjectV2ItemById: {
|
addProjectV2ItemById: {
|
||||||
item: {
|
item: {
|
||||||
id: 'project-item-id'
|
id: 'project-item-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
await addToProject()
|
await addToProject()
|
||||||
@@ -97,17 +164,25 @@ describe('addToProject', () => {
|
|||||||
|
|
||||||
test('adds matching pull-requests with a label filter without label-operator', async () => {
|
test('adds matching pull-requests with a label filter without label-operator', async () => {
|
||||||
mockGetInput({
|
mockGetInput({
|
||||||
'project-url': 'https://github.com/orgs/github/projects/1',
|
'project-url': 'https://github.com/orgs/actions/projects/1',
|
||||||
'github-token': 'gh_token',
|
'github-token': 'gh_token',
|
||||||
labeled: 'bug, new'
|
labeled: 'bug, new',
|
||||||
})
|
})
|
||||||
|
|
||||||
github.context.payload = {
|
github.context.payload = {
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
pull_request: {
|
pull_request: {
|
||||||
number: 1,
|
number: 1,
|
||||||
labels: [{name: 'bug'}]
|
labels: [{name: 'bug'}],
|
||||||
}
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/actions/add-to-project/pull/136',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'add-to-project',
|
||||||
|
owner: {
|
||||||
|
login: 'actions',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
mockGraphQL(
|
mockGraphQL(
|
||||||
@@ -116,21 +191,21 @@ describe('addToProject', () => {
|
|||||||
return: {
|
return: {
|
||||||
organization: {
|
organization: {
|
||||||
projectV2: {
|
projectV2: {
|
||||||
id: 'project-id'
|
id: 'project-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /addProjectV2ItemById/,
|
test: /addProjectV2ItemById/,
|
||||||
return: {
|
return: {
|
||||||
addProjectV2ItemById: {
|
addProjectV2ItemById: {
|
||||||
item: {
|
item: {
|
||||||
id: 'project-item-id'
|
id: 'project-item-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
await addToProject()
|
await addToProject()
|
||||||
@@ -140,16 +215,24 @@ describe('addToProject', () => {
|
|||||||
|
|
||||||
test('does not add un-matching issues with a label filter without label-operator', async () => {
|
test('does not add un-matching issues with a label filter without label-operator', async () => {
|
||||||
mockGetInput({
|
mockGetInput({
|
||||||
'project-url': 'https://github.com/orgs/github/projects/1',
|
'project-url': 'https://github.com/orgs/actions/projects/1',
|
||||||
'github-token': 'gh_token',
|
'github-token': 'gh_token',
|
||||||
labeled: 'bug'
|
labeled: 'bug',
|
||||||
})
|
})
|
||||||
|
|
||||||
github.context.payload = {
|
github.context.payload = {
|
||||||
issue: {
|
issue: {
|
||||||
number: 1,
|
number: 1,
|
||||||
labels: []
|
labels: [],
|
||||||
}
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/actions/add-to-project/issues/74',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'add-to-project',
|
||||||
|
owner: {
|
||||||
|
login: 'actions',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const infoSpy = jest.spyOn(core, 'info')
|
const infoSpy = jest.spyOn(core, 'info')
|
||||||
@@ -161,17 +244,25 @@ describe('addToProject', () => {
|
|||||||
|
|
||||||
test('adds matching issues with labels filter with AND label-operator', async () => {
|
test('adds matching issues with labels filter with AND label-operator', async () => {
|
||||||
mockGetInput({
|
mockGetInput({
|
||||||
'project-url': 'https://github.com/orgs/github/projects/1',
|
'project-url': 'https://github.com/orgs/actions/projects/1',
|
||||||
'github-token': 'gh_token',
|
'github-token': 'gh_token',
|
||||||
labeled: 'bug, new',
|
labeled: 'bug, new',
|
||||||
'label-operator': 'AND'
|
'label-operator': 'AND',
|
||||||
})
|
})
|
||||||
|
|
||||||
github.context.payload = {
|
github.context.payload = {
|
||||||
issue: {
|
issue: {
|
||||||
number: 1,
|
number: 1,
|
||||||
labels: [{name: 'bug'}, {name: 'new'}]
|
labels: [{name: 'bug'}, {name: 'new'}],
|
||||||
}
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/actions/add-to-project/issues/74',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'add-to-project',
|
||||||
|
owner: {
|
||||||
|
login: 'actions',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
mockGraphQL(
|
mockGraphQL(
|
||||||
@@ -180,21 +271,21 @@ describe('addToProject', () => {
|
|||||||
return: {
|
return: {
|
||||||
organization: {
|
organization: {
|
||||||
projectV2: {
|
projectV2: {
|
||||||
id: 'project-id'
|
id: 'project-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /addProjectV2ItemById/,
|
test: /addProjectV2ItemById/,
|
||||||
return: {
|
return: {
|
||||||
addProjectV2ItemById: {
|
addProjectV2ItemById: {
|
||||||
item: {
|
item: {
|
||||||
id: 'project-item-id'
|
id: 'project-item-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
await addToProject()
|
await addToProject()
|
||||||
@@ -204,17 +295,25 @@ describe('addToProject', () => {
|
|||||||
|
|
||||||
test('does not add un-matching issues with labels filter with AND label-operator', async () => {
|
test('does not add un-matching issues with labels filter with AND label-operator', async () => {
|
||||||
mockGetInput({
|
mockGetInput({
|
||||||
'project-url': 'https://github.com/orgs/github/projects/1',
|
'project-url': 'https://github.com/orgs/actions/projects/1',
|
||||||
'github-token': 'gh_token',
|
'github-token': 'gh_token',
|
||||||
labeled: 'bug, new',
|
labeled: 'bug, new',
|
||||||
'label-operator': 'AND'
|
'label-operator': 'AND',
|
||||||
})
|
})
|
||||||
|
|
||||||
github.context.payload = {
|
github.context.payload = {
|
||||||
issue: {
|
issue: {
|
||||||
number: 1,
|
number: 1,
|
||||||
labels: [{name: 'bug'}, {name: 'other'}]
|
labels: [{name: 'bug'}, {name: 'other'}],
|
||||||
}
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/actions/add-to-project/issues/74',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'add-to-project',
|
||||||
|
owner: {
|
||||||
|
login: 'actions',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const infoSpy = jest.spyOn(core, 'info')
|
const infoSpy = jest.spyOn(core, 'info')
|
||||||
@@ -226,17 +325,25 @@ describe('addToProject', () => {
|
|||||||
|
|
||||||
test('does not add matching issues with labels filter with NOT label-operator', async () => {
|
test('does not add matching issues with labels filter with NOT label-operator', async () => {
|
||||||
mockGetInput({
|
mockGetInput({
|
||||||
'project-url': 'https://github.com/orgs/github/projects/1',
|
'project-url': 'https://github.com/orgs/actions/projects/1',
|
||||||
'github-token': 'gh_token',
|
'github-token': 'gh_token',
|
||||||
labeled: 'bug, new',
|
labeled: 'bug, new',
|
||||||
'label-operator': 'NOT'
|
'label-operator': 'NOT',
|
||||||
})
|
})
|
||||||
|
|
||||||
github.context.payload = {
|
github.context.payload = {
|
||||||
issue: {
|
issue: {
|
||||||
number: 1,
|
number: 1,
|
||||||
labels: [{name: 'bug'}]
|
labels: [{name: 'bug'}],
|
||||||
}
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/actions/add-to-project/issues/74',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'add-to-project',
|
||||||
|
owner: {
|
||||||
|
login: 'actions',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const infoSpy = jest.spyOn(core, 'info')
|
const infoSpy = jest.spyOn(core, 'info')
|
||||||
@@ -248,17 +355,25 @@ describe('addToProject', () => {
|
|||||||
|
|
||||||
test('adds issues that do not have labels present in the label list with NOT label-operator', async () => {
|
test('adds issues that do not have labels present in the label list with NOT label-operator', async () => {
|
||||||
mockGetInput({
|
mockGetInput({
|
||||||
'project-url': 'https://github.com/orgs/github/projects/1',
|
'project-url': 'https://github.com/orgs/actions/projects/1',
|
||||||
'github-token': 'gh_token',
|
'github-token': 'gh_token',
|
||||||
labeled: 'bug, new',
|
labeled: 'bug, new',
|
||||||
'label-operator': 'NOT'
|
'label-operator': 'NOT',
|
||||||
})
|
})
|
||||||
|
|
||||||
github.context.payload = {
|
github.context.payload = {
|
||||||
issue: {
|
issue: {
|
||||||
number: 1,
|
number: 1,
|
||||||
labels: [{name: 'other'}]
|
labels: [{name: 'other'}],
|
||||||
}
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/actions/add-to-project/issues/74',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'add-to-project',
|
||||||
|
owner: {
|
||||||
|
login: 'actions',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
mockGraphQL(
|
mockGraphQL(
|
||||||
@@ -266,22 +381,22 @@ describe('addToProject', () => {
|
|||||||
test: /getProject/,
|
test: /getProject/,
|
||||||
return: {
|
return: {
|
||||||
organization: {
|
organization: {
|
||||||
projectNext: {
|
projectV2: {
|
||||||
id: 'project-next-id'
|
id: 'project-next-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /addProjectNextItem/,
|
test: /addProjectV2ItemById/,
|
||||||
return: {
|
return: {
|
||||||
addProjectNextItem: {
|
addProjectV2ItemById: {
|
||||||
projectNextItem: {
|
item: {
|
||||||
id: 'project-next-item-id'
|
id: 'project-next-item-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
await addToProject()
|
await addToProject()
|
||||||
@@ -291,16 +406,24 @@ describe('addToProject', () => {
|
|||||||
|
|
||||||
test('adds matching issues with multiple label filters', async () => {
|
test('adds matching issues with multiple label filters', async () => {
|
||||||
mockGetInput({
|
mockGetInput({
|
||||||
'project-url': 'https://github.com/orgs/github/projects/1',
|
'project-url': 'https://github.com/orgs/actions/projects/1',
|
||||||
'github-token': 'gh_token',
|
'github-token': 'gh_token',
|
||||||
labeled: 'accessibility,backend,bug'
|
labeled: 'accessibility,backend,bug',
|
||||||
})
|
})
|
||||||
|
|
||||||
github.context.payload = {
|
github.context.payload = {
|
||||||
issue: {
|
issue: {
|
||||||
number: 1,
|
number: 1,
|
||||||
labels: [{name: 'accessibility'}, {name: 'backend'}]
|
labels: [{name: 'accessibility'}, {name: 'backend'}],
|
||||||
}
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/actions/add-to-project/issues/74',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'add-to-project',
|
||||||
|
owner: {
|
||||||
|
login: 'actions',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const gqlMock = mockGraphQL(
|
const gqlMock = mockGraphQL(
|
||||||
@@ -309,21 +432,21 @@ describe('addToProject', () => {
|
|||||||
return: {
|
return: {
|
||||||
organization: {
|
organization: {
|
||||||
projectV2: {
|
projectV2: {
|
||||||
id: 'project-id'
|
id: 'project-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /addProjectV2ItemById/,
|
test: /addProjectV2ItemById/,
|
||||||
return: {
|
return: {
|
||||||
addProjectV2ItemById: {
|
addProjectV2ItemById: {
|
||||||
item: {
|
item: {
|
||||||
id: 'project-item-id'
|
id: 'project-item-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const infoSpy = jest.spyOn(core, 'info')
|
const infoSpy = jest.spyOn(core, 'info')
|
||||||
@@ -331,46 +454,64 @@ describe('addToProject', () => {
|
|||||||
await addToProject()
|
await addToProject()
|
||||||
|
|
||||||
expect(gqlMock).toHaveBeenCalled()
|
expect(gqlMock).toHaveBeenCalled()
|
||||||
expect(infoSpy).not.toHaveBeenCalled()
|
expect(infoSpy).toHaveBeenCalledWith('Creating project item')
|
||||||
|
// We shouldn't have any logs relating to the issue being skipped
|
||||||
|
expect(infoSpy.mock.calls.length).toEqual(1)
|
||||||
expect(outputs.itemId).toEqual('project-item-id')
|
expect(outputs.itemId).toEqual('project-item-id')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('does not add un-matching issues with multiple label filters', async () => {
|
test('does not add un-matching issues with multiple label filters', async () => {
|
||||||
mockGetInput({
|
mockGetInput({
|
||||||
'project-url': 'https://github.com/orgs/github/projects/1',
|
'project-url': 'https://github.com/orgs/actions/projects/1',
|
||||||
'github-token': 'gh_token',
|
'github-token': 'gh_token',
|
||||||
labeled: 'accessibility, backend, bug'
|
labeled: 'accessibility, backend, bug',
|
||||||
})
|
})
|
||||||
|
|
||||||
github.context.payload = {
|
github.context.payload = {
|
||||||
issue: {
|
issue: {
|
||||||
number: 1,
|
number: 1,
|
||||||
labels: [{name: 'data'}, {name: 'frontend'}, {name: 'improvement'}]
|
labels: [{name: 'data'}, {name: 'frontend'}, {name: 'improvement'}],
|
||||||
}
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/actions/add-to-project/issues/74',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'add-to-project',
|
||||||
|
owner: {
|
||||||
|
login: 'actions',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const infoSpy = jest.spyOn(core, 'info')
|
const infoSpy = jest.spyOn(core, 'info')
|
||||||
const gqlMock = mockGraphQL()
|
const gqlMock = mockGraphQL()
|
||||||
await addToProject()
|
await addToProject()
|
||||||
expect(infoSpy).toHaveBeenCalledWith(
|
expect(infoSpy).toHaveBeenCalledWith(
|
||||||
`Skipping issue 1 because it does not have one of the labels: accessibility, backend, bug`
|
`Skipping issue 1 because it does not have one of the labels: accessibility, backend, bug`,
|
||||||
)
|
)
|
||||||
expect(gqlMock).not.toHaveBeenCalled()
|
expect(gqlMock).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('handles spaces and extra commas gracefully in label filter input', async () => {
|
test('handles spaces and extra commas gracefully in label filter input', async () => {
|
||||||
mockGetInput({
|
mockGetInput({
|
||||||
'project-url': 'https://github.com/orgs/github/projects/1',
|
'project-url': 'https://github.com/orgs/actions/projects/1',
|
||||||
'github-token': 'gh_token',
|
'github-token': 'gh_token',
|
||||||
labeled: 'accessibility , backend ,, . , bug'
|
labeled: 'accessibility , backend ,, . , bug',
|
||||||
})
|
})
|
||||||
|
|
||||||
github.context.payload = {
|
github.context.payload = {
|
||||||
issue: {
|
issue: {
|
||||||
number: 1,
|
number: 1,
|
||||||
labels: [{name: 'accessibility'}, {name: 'backend'}, {name: 'bug'}],
|
labels: [{name: 'accessibility'}, {name: 'backend'}, {name: 'bug'}],
|
||||||
'label-operator': 'AND'
|
'label-operator': 'AND',
|
||||||
}
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/actions/add-to-project/issues/74',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'add-to-project',
|
||||||
|
owner: {
|
||||||
|
login: 'actions',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const gqlMock = mockGraphQL(
|
const gqlMock = mockGraphQL(
|
||||||
@@ -379,21 +520,21 @@ describe('addToProject', () => {
|
|||||||
return: {
|
return: {
|
||||||
organization: {
|
organization: {
|
||||||
projectV2: {
|
projectV2: {
|
||||||
id: 'project-id'
|
id: 'project-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /addProjectV2ItemById/,
|
test: /addProjectV2ItemById/,
|
||||||
return: {
|
return: {
|
||||||
addProjectV2ItemById: {
|
addProjectV2ItemById: {
|
||||||
item: {
|
item: {
|
||||||
id: 'project-item-id'
|
id: 'project-item-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const infoSpy = jest.spyOn(core, 'info')
|
const infoSpy = jest.spyOn(core, 'info')
|
||||||
@@ -401,157 +542,56 @@ describe('addToProject', () => {
|
|||||||
await addToProject()
|
await addToProject()
|
||||||
|
|
||||||
expect(gqlMock).toHaveBeenCalled()
|
expect(gqlMock).toHaveBeenCalled()
|
||||||
expect(infoSpy).not.toHaveBeenCalled()
|
expect(infoSpy).toHaveBeenCalledWith('Creating project item')
|
||||||
|
// We shouldn't have any logs relating to the issue being skipped
|
||||||
|
expect(infoSpy.mock.calls.length).toEqual(1)
|
||||||
expect(outputs.itemId).toEqual('project-item-id')
|
expect(outputs.itemId).toEqual('project-item-id')
|
||||||
})
|
})
|
||||||
|
|
||||||
test(`throws an error when url isn't a valid project url`, async () => {
|
test(`throws an error when url isn't a valid project url`, async () => {
|
||||||
mockGetInput({
|
mockGetInput({
|
||||||
'project-url': 'https://github.com/orgs/github/repositories',
|
'project-url': 'https://github.com/orgs/github/repositories',
|
||||||
'github-token': 'gh_token'
|
'github-token': 'gh_token',
|
||||||
})
|
})
|
||||||
|
|
||||||
github.context.payload = {
|
github.context.payload = {
|
||||||
issue: {
|
issue: {
|
||||||
number: 1,
|
number: 1,
|
||||||
labels: []
|
labels: [],
|
||||||
}
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/actions/add-to-project/issues/74',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'add-to-project',
|
||||||
|
owner: {
|
||||||
|
login: 'actions',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const infoSpy = jest.spyOn(core, 'info')
|
const infoSpy = jest.spyOn(core, 'info')
|
||||||
const gqlMock = mockGraphQL()
|
const gqlMock = mockGraphQL()
|
||||||
await expect(addToProject()).rejects.toThrow(
|
await expect(addToProject()).rejects.toThrow(
|
||||||
'https://github.com/orgs/github/repositories. Project URL should match the format https://github.com/<orgs-or-users>/<ownerName>/projects/<projectNumber>'
|
'Invalid project URL: https://github.com/orgs/github/repositories. Project URL should match the format <GitHub server domain name>/<orgs-or-users>/<ownerName>/projects/<projectNumber>',
|
||||||
)
|
)
|
||||||
expect(infoSpy).not.toHaveBeenCalled()
|
expect(infoSpy).not.toHaveBeenCalled()
|
||||||
expect(gqlMock).not.toHaveBeenCalled()
|
expect(gqlMock).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
test(`throws an error when url isn't under the github.com domain`, async () => {
|
test(`works with URLs that are not under the github.com domain`, async () => {
|
||||||
mockGetInput({
|
|
||||||
'project-url': 'https://notgithub.com/orgs/github/projects/1',
|
|
||||||
'github-token': 'gh_token'
|
|
||||||
})
|
|
||||||
|
|
||||||
github.context.payload = {
|
github.context.payload = {
|
||||||
issue: {
|
issue: {
|
||||||
number: 1,
|
number: 1,
|
||||||
labels: []
|
labels: [{name: 'bug'}],
|
||||||
}
|
// eslint-disable-next-line camelcase
|
||||||
}
|
html_url: 'https://notgithub.com/actions/add-to-project/issues/74',
|
||||||
|
|
||||||
const infoSpy = jest.spyOn(core, 'info')
|
|
||||||
const gqlMock = mockGraphQL()
|
|
||||||
await expect(addToProject()).rejects.toThrow(
|
|
||||||
'https://notgithub.com/orgs/github/projects/1. Project URL should match the format https://github.com/<orgs-or-users>/<ownerName>/projects/<projectNumber>'
|
|
||||||
)
|
|
||||||
expect(infoSpy).not.toHaveBeenCalled()
|
|
||||||
expect(gqlMock).not.toHaveBeenCalled()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('constructs the correct graphQL query given an organization owner', async () => {
|
|
||||||
mockGetInput({
|
|
||||||
'project-url': 'https://github.com/orgs/github/projects/1',
|
|
||||||
'github-token': 'gh_token',
|
|
||||||
labeled: 'bug, new'
|
|
||||||
})
|
|
||||||
|
|
||||||
github.context.payload = {
|
|
||||||
issue: {
|
|
||||||
number: 1,
|
|
||||||
labels: [{name: 'bug'}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const gqlMock = mockGraphQL(
|
|
||||||
{
|
|
||||||
test: /getProject/,
|
|
||||||
return: {
|
|
||||||
organization: {
|
|
||||||
projectV2: {
|
|
||||||
id: 'project-id'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
repository: {
|
||||||
test: /addProjectV2ItemById/,
|
name: 'add-to-project',
|
||||||
return: {
|
owner: {
|
||||||
addProjectV2ItemById: {
|
login: 'actions',
|
||||||
item: {
|
},
|
||||||
id: 'project-item-id'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
await addToProject()
|
|
||||||
|
|
||||||
expect(gqlMock).toHaveBeenNthCalledWith(1, expect.stringContaining('organization(login: $ownerName)'), {
|
|
||||||
ownerName: 'github',
|
|
||||||
projectNumber: 1
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('constructs the correct graphQL query given a user owner', async () => {
|
|
||||||
mockGetInput({
|
|
||||||
'project-url': 'https://github.com/users/monalisa/projects/1',
|
|
||||||
'github-token': 'gh_token',
|
|
||||||
labeled: 'bug, new'
|
|
||||||
})
|
|
||||||
|
|
||||||
github.context.payload = {
|
|
||||||
issue: {
|
|
||||||
number: 1,
|
|
||||||
labels: [{name: 'bug'}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const gqlMock = mockGraphQL(
|
|
||||||
{
|
|
||||||
test: /getProject/,
|
|
||||||
return: {
|
|
||||||
organization: {
|
|
||||||
projectV2: {
|
|
||||||
id: 'project-id'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
|
||||||
test: /addProjectV2ItemById/,
|
|
||||||
return: {
|
|
||||||
addProjectV2ItemById: {
|
|
||||||
item: {
|
|
||||||
id: 'project-item-id'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
await addToProject()
|
|
||||||
|
|
||||||
expect(gqlMock).toHaveBeenNthCalledWith(1, expect.stringContaining('user(login: $ownerName)'), {
|
|
||||||
ownerName: 'monalisa',
|
|
||||||
projectNumber: 1
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('compares labels case-insensitively', async () => {
|
|
||||||
mockGetInput({
|
|
||||||
'project-url': 'https://github.com/orgs/github/projects/1',
|
|
||||||
'github-token': 'gh_token',
|
|
||||||
labeled: 'FOO, Bar, baz',
|
|
||||||
'label-operator': 'AND'
|
|
||||||
})
|
|
||||||
|
|
||||||
github.context.payload = {
|
|
||||||
issue: {
|
|
||||||
number: 1,
|
|
||||||
labels: [{name: 'foo'}, {name: 'BAR'}, {name: 'baz'}]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mockGraphQL(
|
mockGraphQL(
|
||||||
@@ -559,22 +599,179 @@ describe('addToProject', () => {
|
|||||||
test: /getProject/,
|
test: /getProject/,
|
||||||
return: {
|
return: {
|
||||||
organization: {
|
organization: {
|
||||||
projectNext: {
|
projectV2: {
|
||||||
id: 'project-next-id'
|
id: 'project-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /addProjectNextItem/,
|
test: /addProjectV2ItemById/,
|
||||||
return: {
|
return: {
|
||||||
addProjectNextItem: {
|
addProjectV2ItemById: {
|
||||||
projectNextItem: {
|
item: {
|
||||||
id: 'project-next-item-id'
|
id: 'project-item-id',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
await addToProject()
|
||||||
|
|
||||||
|
expect(outputs.itemId).toEqual('project-item-id')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('constructs the correct graphQL query given an organization owner', async () => {
|
||||||
|
mockGetInput({
|
||||||
|
'project-url': 'https://github.com/orgs/actions/projects/1',
|
||||||
|
'github-token': 'gh_token',
|
||||||
|
labeled: 'bug, new',
|
||||||
|
})
|
||||||
|
|
||||||
|
github.context.payload = {
|
||||||
|
issue: {
|
||||||
|
number: 1,
|
||||||
|
labels: [{name: 'bug'}],
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/actions/add-to-project/issues/74',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'add-to-project',
|
||||||
|
owner: {
|
||||||
|
login: 'actions',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const gqlMock = mockGraphQL(
|
||||||
|
{
|
||||||
|
test: /getProject/,
|
||||||
|
return: {
|
||||||
|
organization: {
|
||||||
|
projectV2: {
|
||||||
|
id: 'project-id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /addProjectV2ItemById/,
|
||||||
|
return: {
|
||||||
|
addProjectV2ItemById: {
|
||||||
|
item: {
|
||||||
|
id: 'project-item-id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
await addToProject()
|
||||||
|
|
||||||
|
expect(gqlMock).toHaveBeenNthCalledWith(1, expect.stringContaining('organization(login: $projectOwnerName)'), {
|
||||||
|
projectOwnerName: 'actions',
|
||||||
|
projectNumber: 1,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('constructs the correct graphQL query given a user owner', async () => {
|
||||||
|
mockGetInput({
|
||||||
|
'project-url': 'https://github.com/users/monalisa/projects/1',
|
||||||
|
'github-token': 'gh_token',
|
||||||
|
labeled: 'bug, new',
|
||||||
|
})
|
||||||
|
|
||||||
|
github.context.payload = {
|
||||||
|
issue: {
|
||||||
|
number: 1,
|
||||||
|
labels: [{name: 'bug'}],
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/monalisa/add-to-project/issues/74',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'add-to-project',
|
||||||
|
owner: {
|
||||||
|
login: 'monalisa',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const gqlMock = mockGraphQL(
|
||||||
|
{
|
||||||
|
test: /getProject/,
|
||||||
|
return: {
|
||||||
|
organization: {
|
||||||
|
projectV2: {
|
||||||
|
id: 'project-id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /addProjectV2ItemById/,
|
||||||
|
return: {
|
||||||
|
addProjectV2ItemById: {
|
||||||
|
item: {
|
||||||
|
id: 'project-item-id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
await addToProject()
|
||||||
|
|
||||||
|
expect(gqlMock).toHaveBeenNthCalledWith(1, expect.stringContaining('user(login: $projectOwnerName)'), {
|
||||||
|
projectOwnerName: 'monalisa',
|
||||||
|
projectNumber: 1,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('compares labels case-insensitively', async () => {
|
||||||
|
mockGetInput({
|
||||||
|
'project-url': 'https://github.com/orgs/actions/projects/1',
|
||||||
|
'github-token': 'gh_token',
|
||||||
|
labeled: 'FOO, Bar, baz',
|
||||||
|
'label-operator': 'AND',
|
||||||
|
})
|
||||||
|
|
||||||
|
github.context.payload = {
|
||||||
|
issue: {
|
||||||
|
number: 1,
|
||||||
|
labels: [{name: 'foo'}, {name: 'BAR'}, {name: 'baz'}],
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
html_url: 'https://github.com/actions/add-to-project/issues/74',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
name: 'add-to-project',
|
||||||
|
owner: {
|
||||||
|
login: 'actions',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
mockGraphQL(
|
||||||
|
{
|
||||||
|
test: /getProject/,
|
||||||
|
return: {
|
||||||
|
organization: {
|
||||||
|
projectV2: {
|
||||||
|
id: 'project-next-id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /addProjectV2ItemById/,
|
||||||
|
return: {
|
||||||
|
addProjectV2ItemById: {
|
||||||
|
item: {
|
||||||
|
id: 'project-next-item-id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
await addToProject()
|
await addToProject()
|
||||||
@@ -627,7 +824,7 @@ function mockGraphQL(...mocks: {test: RegExp; return: unknown}[]): jest.Mock {
|
|||||||
|
|
||||||
jest.spyOn(github, 'getOctokit').mockImplementation(() => {
|
jest.spyOn(github, 'getOctokit').mockImplementation(() => {
|
||||||
return {
|
return {
|
||||||
graphql: mock
|
graphql: mock,
|
||||||
} as unknown as ReturnType<typeof github.getOctokit>
|
} as unknown as ReturnType<typeof github.getOctokit>
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: Add To GitHub Projects Beta
|
name: Add To GitHub projects
|
||||||
description: Automatically add issues and PRs to GitHub projects beta
|
description: Automatically add issues and PRs to GitHub projects
|
||||||
author: GitHub
|
author: GitHub
|
||||||
branding:
|
branding:
|
||||||
icon: table
|
icon: table
|
||||||
|
|||||||
791
dist/index.js
generated
vendored
791
dist/index.js
generated
vendored
@@ -42,11 +42,9 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|||||||
exports.mustGetOwnerTypeQuery = exports.addToProject = void 0;
|
exports.mustGetOwnerTypeQuery = exports.addToProject = void 0;
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const github = __importStar(__nccwpck_require__(5438));
|
const github = __importStar(__nccwpck_require__(5438));
|
||||||
// TODO: Ensure this (and the Octokit client) works for non-github.com URLs, as well.
|
const urlParse = /\/(?<ownerType>orgs|users)\/(?<ownerName>[^/]+)\/projects\/(?<projectNumber>\d+)/;
|
||||||
// https://github.com/orgs|users/<ownerName>/projects/<projectNumber>
|
|
||||||
const urlParse = /^(?:https:\/\/)?github\.com\/(?<ownerType>orgs|users)\/(?<ownerName>[^/]+)\/projects\/(?<projectNumber>\d+)/;
|
|
||||||
function addToProject() {
|
function addToProject() {
|
||||||
var _a, _b, _c, _d, _e, _f, _g, _h;
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const projectUrl = core.getInput('project-url', { required: true });
|
const projectUrl = core.getInput('project-url', { required: true });
|
||||||
const ghToken = core.getInput('github-token', { required: true });
|
const ghToken = core.getInput('github-token', { required: true });
|
||||||
@@ -57,9 +55,11 @@ function addToProject() {
|
|||||||
.filter(l => l.length > 0)) !== null && _a !== void 0 ? _a : [];
|
.filter(l => l.length > 0)) !== null && _a !== void 0 ? _a : [];
|
||||||
const labelOperator = core.getInput('label-operator').trim().toLocaleLowerCase();
|
const labelOperator = core.getInput('label-operator').trim().toLocaleLowerCase();
|
||||||
const octokit = github.getOctokit(ghToken);
|
const octokit = github.getOctokit(ghToken);
|
||||||
const urlMatch = projectUrl.match(urlParse);
|
|
||||||
const issue = (_b = github.context.payload.issue) !== null && _b !== void 0 ? _b : github.context.payload.pull_request;
|
const issue = (_b = github.context.payload.issue) !== null && _b !== void 0 ? _b : github.context.payload.pull_request;
|
||||||
const issueLabels = ((_c = issue === null || issue === void 0 ? void 0 : issue.labels) !== null && _c !== void 0 ? _c : []).map((l) => l.name.toLowerCase());
|
const issueLabels = ((_c = issue === null || issue === void 0 ? void 0 : issue.labels) !== null && _c !== void 0 ? _c : []).map((l) => l.name.toLowerCase());
|
||||||
|
const issueOwnerName = (_d = github.context.payload.repository) === null || _d === void 0 ? void 0 : _d.owner.login;
|
||||||
|
core.debug(`Issue/PR owner: ${issueOwnerName}`);
|
||||||
|
core.debug(`Issue/PR labels: ${issueLabels.join(', ')}`);
|
||||||
// Ensure the issue matches our `labeled` filter based on the label-operator.
|
// Ensure the issue matches our `labeled` filter based on the label-operator.
|
||||||
if (labelOperator === 'and') {
|
if (labelOperator === 'and') {
|
||||||
if (!labeled.every(l => issueLabels.includes(l))) {
|
if (!labeled.every(l => issueLabels.includes(l))) {
|
||||||
@@ -80,45 +80,68 @@ function addToProject() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
core.debug(`Project URL: ${projectUrl}`);
|
core.debug(`Project URL: ${projectUrl}`);
|
||||||
|
const urlMatch = projectUrl.match(urlParse);
|
||||||
if (!urlMatch) {
|
if (!urlMatch) {
|
||||||
throw new Error(`Invalid project URL: ${projectUrl}. Project URL should match the format https://github.com/<orgs-or-users>/<ownerName>/projects/<projectNumber>`);
|
throw new Error(`Invalid project URL: ${projectUrl}. Project URL should match the format <GitHub server domain name>/<orgs-or-users>/<ownerName>/projects/<projectNumber>`);
|
||||||
}
|
}
|
||||||
const ownerName = (_d = urlMatch.groups) === null || _d === void 0 ? void 0 : _d.ownerName;
|
const projectOwnerName = (_e = urlMatch.groups) === null || _e === void 0 ? void 0 : _e.ownerName;
|
||||||
const projectNumber = parseInt((_f = (_e = urlMatch.groups) === null || _e === void 0 ? void 0 : _e.projectNumber) !== null && _f !== void 0 ? _f : '', 10);
|
const projectNumber = parseInt((_g = (_f = urlMatch.groups) === null || _f === void 0 ? void 0 : _f.projectNumber) !== null && _g !== void 0 ? _g : '', 10);
|
||||||
const ownerType = (_g = urlMatch.groups) === null || _g === void 0 ? void 0 : _g.ownerType;
|
const ownerType = (_h = urlMatch.groups) === null || _h === void 0 ? void 0 : _h.ownerType;
|
||||||
const ownerTypeQuery = mustGetOwnerTypeQuery(ownerType);
|
const ownerTypeQuery = mustGetOwnerTypeQuery(ownerType);
|
||||||
core.debug(`Org name: ${ownerName}`);
|
core.debug(`Project owner: ${projectOwnerName}`);
|
||||||
core.debug(`Project number: ${projectNumber}`);
|
core.debug(`Project number: ${projectNumber}`);
|
||||||
core.debug(`Owner type: ${ownerType}`);
|
core.debug(`Project owner type: ${ownerType}`);
|
||||||
// First, use the GraphQL API to request the project's node ID.
|
// First, use the GraphQL API to request the project's node ID.
|
||||||
const idResp = yield octokit.graphql(`query getProject($ownerName: String!, $projectNumber: Int!) {
|
const idResp = yield octokit.graphql(`query getProject($projectOwnerName: String!, $projectNumber: Int!) {
|
||||||
${ownerTypeQuery}(login: $ownerName) {
|
${ownerTypeQuery}(login: $projectOwnerName) {
|
||||||
projectV2(number: $projectNumber) {
|
projectV2(number: $projectNumber) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`, {
|
}`, {
|
||||||
ownerName,
|
projectOwnerName,
|
||||||
projectNumber
|
projectNumber,
|
||||||
});
|
});
|
||||||
const projectId = (_h = idResp[ownerTypeQuery]) === null || _h === void 0 ? void 0 : _h.projectV2.id;
|
const projectId = (_j = idResp[ownerTypeQuery]) === null || _j === void 0 ? void 0 : _j.projectV2.id;
|
||||||
const contentId = issue === null || issue === void 0 ? void 0 : issue.node_id;
|
const contentId = issue === null || issue === void 0 ? void 0 : issue.node_id;
|
||||||
core.debug(`Project node ID: ${projectId}`);
|
core.debug(`Project node ID: ${projectId}`);
|
||||||
core.debug(`Content ID: ${contentId}`);
|
core.debug(`Content ID: ${contentId}`);
|
||||||
// Next, use the GraphQL API to add the issue to the project.
|
// Next, use the GraphQL API to add the issue to the project.
|
||||||
const addResp = yield octokit.graphql(`mutation addIssueToProject($input: AddProjectV2ItemByIdInput!) {
|
// If the issue has the same owner as the project, we can directly
|
||||||
addProjectV2ItemById(input: $input) {
|
// add a project item. Otherwise, we add a draft issue.
|
||||||
item {
|
if (issueOwnerName === projectOwnerName) {
|
||||||
id
|
core.info('Creating project item');
|
||||||
|
const addResp = yield octokit.graphql(`mutation addIssueToProject($input: AddProjectV2ItemByIdInput!) {
|
||||||
|
addProjectV2ItemById(input: $input) {
|
||||||
|
item {
|
||||||
|
id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}`, {
|
||||||
}`, {
|
input: {
|
||||||
input: {
|
projectId,
|
||||||
|
contentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
core.setOutput('itemId', addResp.addProjectV2ItemById.item.id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.info('Creating draft issue in project');
|
||||||
|
const addResp = yield octokit.graphql(`mutation addDraftIssueToProject($projectId: ID!, $title: String!) {
|
||||||
|
addProjectV2DraftIssue(input: {
|
||||||
|
projectId: $projectId,
|
||||||
|
title: $title
|
||||||
|
}) {
|
||||||
|
projectItem {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`, {
|
||||||
projectId,
|
projectId,
|
||||||
contentId
|
title: issue === null || issue === void 0 ? void 0 : issue.html_url,
|
||||||
}
|
});
|
||||||
});
|
core.setOutput('itemId', addResp.addProjectV2DraftIssue.projectItem.id);
|
||||||
core.setOutput('itemId', addResp.addProjectV2ItemById.item.id);
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.addToProject = addToProject;
|
exports.addToProject = addToProject;
|
||||||
@@ -345,13 +368,9 @@ function exportVariable(name, val) {
|
|||||||
process.env[name] = convertedVal;
|
process.env[name] = convertedVal;
|
||||||
const filePath = process.env['GITHUB_ENV'] || '';
|
const filePath = process.env['GITHUB_ENV'] || '';
|
||||||
if (filePath) {
|
if (filePath) {
|
||||||
const delimiter = '_GitHubActionsFileCommandDelimeter_';
|
return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val));
|
||||||
const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;
|
|
||||||
file_command_1.issueCommand('ENV', commandValue);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
command_1.issueCommand('set-env', { name }, convertedVal);
|
|
||||||
}
|
}
|
||||||
|
command_1.issueCommand('set-env', { name }, convertedVal);
|
||||||
}
|
}
|
||||||
exports.exportVariable = exportVariable;
|
exports.exportVariable = exportVariable;
|
||||||
/**
|
/**
|
||||||
@@ -369,7 +388,7 @@ exports.setSecret = setSecret;
|
|||||||
function addPath(inputPath) {
|
function addPath(inputPath) {
|
||||||
const filePath = process.env['GITHUB_PATH'] || '';
|
const filePath = process.env['GITHUB_PATH'] || '';
|
||||||
if (filePath) {
|
if (filePath) {
|
||||||
file_command_1.issueCommand('PATH', inputPath);
|
file_command_1.issueFileCommand('PATH', inputPath);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
command_1.issueCommand('add-path', {}, inputPath);
|
command_1.issueCommand('add-path', {}, inputPath);
|
||||||
@@ -409,7 +428,10 @@ function getMultilineInput(name, options) {
|
|||||||
const inputs = getInput(name, options)
|
const inputs = getInput(name, options)
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.filter(x => x !== '');
|
.filter(x => x !== '');
|
||||||
return inputs;
|
if (options && options.trimWhitespace === false) {
|
||||||
|
return inputs;
|
||||||
|
}
|
||||||
|
return inputs.map(input => input.trim());
|
||||||
}
|
}
|
||||||
exports.getMultilineInput = getMultilineInput;
|
exports.getMultilineInput = getMultilineInput;
|
||||||
/**
|
/**
|
||||||
@@ -442,8 +464,12 @@ exports.getBooleanInput = getBooleanInput;
|
|||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
function setOutput(name, value) {
|
function setOutput(name, value) {
|
||||||
|
const filePath = process.env['GITHUB_OUTPUT'] || '';
|
||||||
|
if (filePath) {
|
||||||
|
return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value));
|
||||||
|
}
|
||||||
process.stdout.write(os.EOL);
|
process.stdout.write(os.EOL);
|
||||||
command_1.issueCommand('set-output', { name }, value);
|
command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value));
|
||||||
}
|
}
|
||||||
exports.setOutput = setOutput;
|
exports.setOutput = setOutput;
|
||||||
/**
|
/**
|
||||||
@@ -572,7 +598,11 @@ exports.group = group;
|
|||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
function saveState(name, value) {
|
function saveState(name, value) {
|
||||||
command_1.issueCommand('save-state', { name }, value);
|
const filePath = process.env['GITHUB_STATE'] || '';
|
||||||
|
if (filePath) {
|
||||||
|
return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value));
|
||||||
|
}
|
||||||
|
command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value));
|
||||||
}
|
}
|
||||||
exports.saveState = saveState;
|
exports.saveState = saveState;
|
||||||
/**
|
/**
|
||||||
@@ -638,13 +668,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.issueCommand = void 0;
|
exports.prepareKeyValueMessage = exports.issueFileCommand = void 0;
|
||||||
// We use any as a valid input type
|
// We use any as a valid input type
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
const fs = __importStar(__nccwpck_require__(7147));
|
const fs = __importStar(__nccwpck_require__(7147));
|
||||||
const os = __importStar(__nccwpck_require__(2037));
|
const os = __importStar(__nccwpck_require__(2037));
|
||||||
|
const uuid_1 = __nccwpck_require__(5840);
|
||||||
const utils_1 = __nccwpck_require__(5278);
|
const utils_1 = __nccwpck_require__(5278);
|
||||||
function issueCommand(command, message) {
|
function issueFileCommand(command, message) {
|
||||||
const filePath = process.env[`GITHUB_${command}`];
|
const filePath = process.env[`GITHUB_${command}`];
|
||||||
if (!filePath) {
|
if (!filePath) {
|
||||||
throw new Error(`Unable to find environment variable for file command ${command}`);
|
throw new Error(`Unable to find environment variable for file command ${command}`);
|
||||||
@@ -656,7 +687,22 @@ function issueCommand(command, message) {
|
|||||||
encoding: 'utf8'
|
encoding: 'utf8'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.issueCommand = issueCommand;
|
exports.issueFileCommand = issueFileCommand;
|
||||||
|
function prepareKeyValueMessage(key, value) {
|
||||||
|
const delimiter = `ghadelimiter_${uuid_1.v4()}`;
|
||||||
|
const convertedValue = utils_1.toCommandValue(value);
|
||||||
|
// These should realistically never happen, but just in case someone finds a
|
||||||
|
// way to exploit uuid generation let's not allow keys or values that contain
|
||||||
|
// the delimiter.
|
||||||
|
if (key.includes(delimiter)) {
|
||||||
|
throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`);
|
||||||
|
}
|
||||||
|
if (convertedValue.includes(delimiter)) {
|
||||||
|
throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`);
|
||||||
|
}
|
||||||
|
return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`;
|
||||||
|
}
|
||||||
|
exports.prepareKeyValueMessage = prepareKeyValueMessage;
|
||||||
//# sourceMappingURL=file-command.js.map
|
//# sourceMappingURL=file-command.js.map
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -1243,8 +1289,9 @@ exports.context = new Context.Context();
|
|||||||
* @param token the repo PAT or GITHUB_TOKEN
|
* @param token the repo PAT or GITHUB_TOKEN
|
||||||
* @param options other options to set
|
* @param options other options to set
|
||||||
*/
|
*/
|
||||||
function getOctokit(token, options) {
|
function getOctokit(token, options, ...additionalPlugins) {
|
||||||
return new utils_1.GitHub(utils_1.getOctokitOptions(token, options));
|
const GitHubWithPlugins = utils_1.GitHub.plugin(...additionalPlugins);
|
||||||
|
return new GitHubWithPlugins(utils_1.getOctokitOptions(token, options));
|
||||||
}
|
}
|
||||||
exports.getOctokit = getOctokit;
|
exports.getOctokit = getOctokit;
|
||||||
//# sourceMappingURL=github.js.map
|
//# sourceMappingURL=github.js.map
|
||||||
@@ -1326,7 +1373,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.getOctokitOptions = exports.GitHub = exports.context = void 0;
|
exports.getOctokitOptions = exports.GitHub = exports.defaults = exports.context = void 0;
|
||||||
const Context = __importStar(__nccwpck_require__(4087));
|
const Context = __importStar(__nccwpck_require__(4087));
|
||||||
const Utils = __importStar(__nccwpck_require__(7914));
|
const Utils = __importStar(__nccwpck_require__(7914));
|
||||||
// octokit + plugins
|
// octokit + plugins
|
||||||
@@ -1335,13 +1382,13 @@ const plugin_rest_endpoint_methods_1 = __nccwpck_require__(3044);
|
|||||||
const plugin_paginate_rest_1 = __nccwpck_require__(4193);
|
const plugin_paginate_rest_1 = __nccwpck_require__(4193);
|
||||||
exports.context = new Context.Context();
|
exports.context = new Context.Context();
|
||||||
const baseUrl = Utils.getApiBaseUrl();
|
const baseUrl = Utils.getApiBaseUrl();
|
||||||
const defaults = {
|
exports.defaults = {
|
||||||
baseUrl,
|
baseUrl,
|
||||||
request: {
|
request: {
|
||||||
agent: Utils.getProxyAgent(baseUrl)
|
agent: Utils.getProxyAgent(baseUrl)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
exports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(defaults);
|
exports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(exports.defaults);
|
||||||
/**
|
/**
|
||||||
* Convience function to correctly format Octokit Options to pass into the constructor.
|
* Convience function to correctly format Octokit Options to pass into the constructor.
|
||||||
*
|
*
|
||||||
@@ -8897,6 +8944,652 @@ exports.getUserAgent = getUserAgent;
|
|||||||
//# sourceMappingURL=index.js.map
|
//# sourceMappingURL=index.js.map
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 5840:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
Object.defineProperty(exports, "v1", ({
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _v.default;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
Object.defineProperty(exports, "v3", ({
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _v2.default;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
Object.defineProperty(exports, "v4", ({
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _v3.default;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
Object.defineProperty(exports, "v5", ({
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _v4.default;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
Object.defineProperty(exports, "NIL", ({
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _nil.default;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
Object.defineProperty(exports, "version", ({
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _version.default;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
Object.defineProperty(exports, "validate", ({
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _validate.default;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
Object.defineProperty(exports, "stringify", ({
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _stringify.default;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
Object.defineProperty(exports, "parse", ({
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return _parse.default;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
var _v = _interopRequireDefault(__nccwpck_require__(8628));
|
||||||
|
|
||||||
|
var _v2 = _interopRequireDefault(__nccwpck_require__(6409));
|
||||||
|
|
||||||
|
var _v3 = _interopRequireDefault(__nccwpck_require__(5122));
|
||||||
|
|
||||||
|
var _v4 = _interopRequireDefault(__nccwpck_require__(9120));
|
||||||
|
|
||||||
|
var _nil = _interopRequireDefault(__nccwpck_require__(5332));
|
||||||
|
|
||||||
|
var _version = _interopRequireDefault(__nccwpck_require__(1595));
|
||||||
|
|
||||||
|
var _validate = _interopRequireDefault(__nccwpck_require__(6900));
|
||||||
|
|
||||||
|
var _stringify = _interopRequireDefault(__nccwpck_require__(8950));
|
||||||
|
|
||||||
|
var _parse = _interopRequireDefault(__nccwpck_require__(2746));
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 4569:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = void 0;
|
||||||
|
|
||||||
|
var _crypto = _interopRequireDefault(__nccwpck_require__(6113));
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
function md5(bytes) {
|
||||||
|
if (Array.isArray(bytes)) {
|
||||||
|
bytes = Buffer.from(bytes);
|
||||||
|
} else if (typeof bytes === 'string') {
|
||||||
|
bytes = Buffer.from(bytes, 'utf8');
|
||||||
|
}
|
||||||
|
|
||||||
|
return _crypto.default.createHash('md5').update(bytes).digest();
|
||||||
|
}
|
||||||
|
|
||||||
|
var _default = md5;
|
||||||
|
exports["default"] = _default;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 5332:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = void 0;
|
||||||
|
var _default = '00000000-0000-0000-0000-000000000000';
|
||||||
|
exports["default"] = _default;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 2746:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = void 0;
|
||||||
|
|
||||||
|
var _validate = _interopRequireDefault(__nccwpck_require__(6900));
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
function parse(uuid) {
|
||||||
|
if (!(0, _validate.default)(uuid)) {
|
||||||
|
throw TypeError('Invalid UUID');
|
||||||
|
}
|
||||||
|
|
||||||
|
let v;
|
||||||
|
const arr = new Uint8Array(16); // Parse ########-....-....-....-............
|
||||||
|
|
||||||
|
arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24;
|
||||||
|
arr[1] = v >>> 16 & 0xff;
|
||||||
|
arr[2] = v >>> 8 & 0xff;
|
||||||
|
arr[3] = v & 0xff; // Parse ........-####-....-....-............
|
||||||
|
|
||||||
|
arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8;
|
||||||
|
arr[5] = v & 0xff; // Parse ........-....-####-....-............
|
||||||
|
|
||||||
|
arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8;
|
||||||
|
arr[7] = v & 0xff; // Parse ........-....-....-####-............
|
||||||
|
|
||||||
|
arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8;
|
||||||
|
arr[9] = v & 0xff; // Parse ........-....-....-....-############
|
||||||
|
// (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes)
|
||||||
|
|
||||||
|
arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff;
|
||||||
|
arr[11] = v / 0x100000000 & 0xff;
|
||||||
|
arr[12] = v >>> 24 & 0xff;
|
||||||
|
arr[13] = v >>> 16 & 0xff;
|
||||||
|
arr[14] = v >>> 8 & 0xff;
|
||||||
|
arr[15] = v & 0xff;
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
var _default = parse;
|
||||||
|
exports["default"] = _default;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 814:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = void 0;
|
||||||
|
var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
|
||||||
|
exports["default"] = _default;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 807:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = rng;
|
||||||
|
|
||||||
|
var _crypto = _interopRequireDefault(__nccwpck_require__(6113));
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate
|
||||||
|
|
||||||
|
let poolPtr = rnds8Pool.length;
|
||||||
|
|
||||||
|
function rng() {
|
||||||
|
if (poolPtr > rnds8Pool.length - 16) {
|
||||||
|
_crypto.default.randomFillSync(rnds8Pool);
|
||||||
|
|
||||||
|
poolPtr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rnds8Pool.slice(poolPtr, poolPtr += 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 5274:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = void 0;
|
||||||
|
|
||||||
|
var _crypto = _interopRequireDefault(__nccwpck_require__(6113));
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
function sha1(bytes) {
|
||||||
|
if (Array.isArray(bytes)) {
|
||||||
|
bytes = Buffer.from(bytes);
|
||||||
|
} else if (typeof bytes === 'string') {
|
||||||
|
bytes = Buffer.from(bytes, 'utf8');
|
||||||
|
}
|
||||||
|
|
||||||
|
return _crypto.default.createHash('sha1').update(bytes).digest();
|
||||||
|
}
|
||||||
|
|
||||||
|
var _default = sha1;
|
||||||
|
exports["default"] = _default;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 8950:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = void 0;
|
||||||
|
|
||||||
|
var _validate = _interopRequireDefault(__nccwpck_require__(6900));
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert array of 16 byte values to UUID string format of the form:
|
||||||
|
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||||
|
*/
|
||||||
|
const byteToHex = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < 256; ++i) {
|
||||||
|
byteToHex.push((i + 0x100).toString(16).substr(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
function stringify(arr, offset = 0) {
|
||||||
|
// Note: Be careful editing this code! It's been tuned for performance
|
||||||
|
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
|
||||||
|
const uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one
|
||||||
|
// of the following:
|
||||||
|
// - One or more input array values don't map to a hex octet (leading to
|
||||||
|
// "undefined" in the uuid)
|
||||||
|
// - Invalid input values for the RFC `version` or `variant` fields
|
||||||
|
|
||||||
|
if (!(0, _validate.default)(uuid)) {
|
||||||
|
throw TypeError('Stringified UUID is invalid');
|
||||||
|
}
|
||||||
|
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
var _default = stringify;
|
||||||
|
exports["default"] = _default;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 8628:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = void 0;
|
||||||
|
|
||||||
|
var _rng = _interopRequireDefault(__nccwpck_require__(807));
|
||||||
|
|
||||||
|
var _stringify = _interopRequireDefault(__nccwpck_require__(8950));
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
// **`v1()` - Generate time-based UUID**
|
||||||
|
//
|
||||||
|
// Inspired by https://github.com/LiosK/UUID.js
|
||||||
|
// and http://docs.python.org/library/uuid.html
|
||||||
|
let _nodeId;
|
||||||
|
|
||||||
|
let _clockseq; // Previous uuid creation time
|
||||||
|
|
||||||
|
|
||||||
|
let _lastMSecs = 0;
|
||||||
|
let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details
|
||||||
|
|
||||||
|
function v1(options, buf, offset) {
|
||||||
|
let i = buf && offset || 0;
|
||||||
|
const b = buf || new Array(16);
|
||||||
|
options = options || {};
|
||||||
|
let node = options.node || _nodeId;
|
||||||
|
let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not
|
||||||
|
// specified. We do this lazily to minimize issues related to insufficient
|
||||||
|
// system entropy. See #189
|
||||||
|
|
||||||
|
if (node == null || clockseq == null) {
|
||||||
|
const seedBytes = options.random || (options.rng || _rng.default)();
|
||||||
|
|
||||||
|
if (node == null) {
|
||||||
|
// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
|
||||||
|
node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clockseq == null) {
|
||||||
|
// Per 4.2.2, randomize (14 bit) clockseq
|
||||||
|
clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;
|
||||||
|
}
|
||||||
|
} // UUID timestamps are 100 nano-second units since the Gregorian epoch,
|
||||||
|
// (1582-10-15 00:00). JSNumbers aren't precise enough for this, so
|
||||||
|
// time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
|
||||||
|
// (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
|
||||||
|
|
||||||
|
|
||||||
|
let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock
|
||||||
|
// cycle to simulate higher resolution clock
|
||||||
|
|
||||||
|
let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs)
|
||||||
|
|
||||||
|
const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression
|
||||||
|
|
||||||
|
if (dt < 0 && options.clockseq === undefined) {
|
||||||
|
clockseq = clockseq + 1 & 0x3fff;
|
||||||
|
} // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
|
||||||
|
// time interval
|
||||||
|
|
||||||
|
|
||||||
|
if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {
|
||||||
|
nsecs = 0;
|
||||||
|
} // Per 4.2.1.2 Throw error if too many uuids are requested
|
||||||
|
|
||||||
|
|
||||||
|
if (nsecs >= 10000) {
|
||||||
|
throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastMSecs = msecs;
|
||||||
|
_lastNSecs = nsecs;
|
||||||
|
_clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
|
||||||
|
|
||||||
|
msecs += 12219292800000; // `time_low`
|
||||||
|
|
||||||
|
const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
|
||||||
|
b[i++] = tl >>> 24 & 0xff;
|
||||||
|
b[i++] = tl >>> 16 & 0xff;
|
||||||
|
b[i++] = tl >>> 8 & 0xff;
|
||||||
|
b[i++] = tl & 0xff; // `time_mid`
|
||||||
|
|
||||||
|
const tmh = msecs / 0x100000000 * 10000 & 0xfffffff;
|
||||||
|
b[i++] = tmh >>> 8 & 0xff;
|
||||||
|
b[i++] = tmh & 0xff; // `time_high_and_version`
|
||||||
|
|
||||||
|
b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
|
||||||
|
|
||||||
|
b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
|
||||||
|
|
||||||
|
b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low`
|
||||||
|
|
||||||
|
b[i++] = clockseq & 0xff; // `node`
|
||||||
|
|
||||||
|
for (let n = 0; n < 6; ++n) {
|
||||||
|
b[i + n] = node[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf || (0, _stringify.default)(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
var _default = v1;
|
||||||
|
exports["default"] = _default;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 6409:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = void 0;
|
||||||
|
|
||||||
|
var _v = _interopRequireDefault(__nccwpck_require__(5998));
|
||||||
|
|
||||||
|
var _md = _interopRequireDefault(__nccwpck_require__(4569));
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
const v3 = (0, _v.default)('v3', 0x30, _md.default);
|
||||||
|
var _default = v3;
|
||||||
|
exports["default"] = _default;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 5998:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = _default;
|
||||||
|
exports.URL = exports.DNS = void 0;
|
||||||
|
|
||||||
|
var _stringify = _interopRequireDefault(__nccwpck_require__(8950));
|
||||||
|
|
||||||
|
var _parse = _interopRequireDefault(__nccwpck_require__(2746));
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
function stringToBytes(str) {
|
||||||
|
str = unescape(encodeURIComponent(str)); // UTF8 escape
|
||||||
|
|
||||||
|
const bytes = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < str.length; ++i) {
|
||||||
|
bytes.push(str.charCodeAt(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
|
||||||
|
exports.DNS = DNS;
|
||||||
|
const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
|
||||||
|
exports.URL = URL;
|
||||||
|
|
||||||
|
function _default(name, version, hashfunc) {
|
||||||
|
function generateUUID(value, namespace, buf, offset) {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
value = stringToBytes(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof namespace === 'string') {
|
||||||
|
namespace = (0, _parse.default)(namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (namespace.length !== 16) {
|
||||||
|
throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');
|
||||||
|
} // Compute hash of namespace and value, Per 4.3
|
||||||
|
// Future: Use spread syntax when supported on all platforms, e.g. `bytes =
|
||||||
|
// hashfunc([...namespace, ... value])`
|
||||||
|
|
||||||
|
|
||||||
|
let bytes = new Uint8Array(16 + value.length);
|
||||||
|
bytes.set(namespace);
|
||||||
|
bytes.set(value, namespace.length);
|
||||||
|
bytes = hashfunc(bytes);
|
||||||
|
bytes[6] = bytes[6] & 0x0f | version;
|
||||||
|
bytes[8] = bytes[8] & 0x3f | 0x80;
|
||||||
|
|
||||||
|
if (buf) {
|
||||||
|
offset = offset || 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < 16; ++i) {
|
||||||
|
buf[offset + i] = bytes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0, _stringify.default)(bytes);
|
||||||
|
} // Function#name is not settable on some platforms (#270)
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
generateUUID.name = name; // eslint-disable-next-line no-empty
|
||||||
|
} catch (err) {} // For CommonJS default export support
|
||||||
|
|
||||||
|
|
||||||
|
generateUUID.DNS = DNS;
|
||||||
|
generateUUID.URL = URL;
|
||||||
|
return generateUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 5122:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = void 0;
|
||||||
|
|
||||||
|
var _rng = _interopRequireDefault(__nccwpck_require__(807));
|
||||||
|
|
||||||
|
var _stringify = _interopRequireDefault(__nccwpck_require__(8950));
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
function v4(options, buf, offset) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
|
||||||
|
|
||||||
|
|
||||||
|
rnds[6] = rnds[6] & 0x0f | 0x40;
|
||||||
|
rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
|
||||||
|
|
||||||
|
if (buf) {
|
||||||
|
offset = offset || 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < 16; ++i) {
|
||||||
|
buf[offset + i] = rnds[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0, _stringify.default)(rnds);
|
||||||
|
}
|
||||||
|
|
||||||
|
var _default = v4;
|
||||||
|
exports["default"] = _default;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 9120:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = void 0;
|
||||||
|
|
||||||
|
var _v = _interopRequireDefault(__nccwpck_require__(5998));
|
||||||
|
|
||||||
|
var _sha = _interopRequireDefault(__nccwpck_require__(5274));
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
const v5 = (0, _v.default)('v5', 0x50, _sha.default);
|
||||||
|
var _default = v5;
|
||||||
|
exports["default"] = _default;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 6900:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = void 0;
|
||||||
|
|
||||||
|
var _regex = _interopRequireDefault(__nccwpck_require__(814));
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
function validate(uuid) {
|
||||||
|
return typeof uuid === 'string' && _regex.default.test(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
var _default = validate;
|
||||||
|
exports["default"] = _default;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 1595:
|
||||||
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = void 0;
|
||||||
|
|
||||||
|
var _validate = _interopRequireDefault(__nccwpck_require__(6900));
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
function version(uuid) {
|
||||||
|
if (!(0, _validate.default)(uuid)) {
|
||||||
|
throw TypeError('Invalid UUID');
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseInt(uuid.substr(14, 1), 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
var _default = version;
|
||||||
|
exports["default"] = _default;
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 2940:
|
/***/ 2940:
|
||||||
@@ -8955,6 +9648,14 @@ module.exports = require("assert");
|
|||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 6113:
|
||||||
|
/***/ ((module) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
module.exports = require("crypto");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
/***/ 2361:
|
/***/ 2361:
|
||||||
/***/ ((module) => {
|
/***/ ((module) => {
|
||||||
|
|
||||||
|
|||||||
2
dist/index.js.map
generated
vendored
2
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
13
dist/licenses.txt
generated
vendored
13
dist/licenses.txt
generated
vendored
@@ -562,6 +562,19 @@ Permission to use, copy, modify, and/or distribute this software for any purpose
|
|||||||
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.
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
uuid
|
||||||
|
MIT
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2010-2020 Robert Kieffer and other contributors
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
webidl-conversions
|
webidl-conversions
|
||||||
BSD-2-Clause
|
BSD-2-Clause
|
||||||
# The BSD 2-Clause License
|
# The BSD 2-Clause License
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ module.exports = {
|
|||||||
moduleFileExtensions: ['js', 'ts'],
|
moduleFileExtensions: ['js', 'ts'],
|
||||||
testMatch: ['**/*.test.ts'],
|
testMatch: ['**/*.test.ts'],
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\.ts$': 'ts-jest'
|
'^.+\\.ts$': 'ts-jest',
|
||||||
},
|
},
|
||||||
verbose: true
|
verbose: true,
|
||||||
}
|
}
|
||||||
|
|||||||
2435
package-lock.json
generated
2435
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
30
package.json
30
package.json
@@ -4,28 +4,28 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"author": "GitHub and contributors",
|
"author": "GitHub and contributors",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.9.0",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/github": "^5.0.3"
|
"@actions/github": "^5.1.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.0.0 <17.0.0",
|
"node": ">=16.0.0 <20.0.0",
|
||||||
"npm": ">= 7.0.0"
|
"npm": ">= 8.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@github/prettier-config": "^0.0.4",
|
"@github/prettier-config": "^0.0.6",
|
||||||
"@types/jest": "^27.5.0",
|
"@types/jest": "^27.5.0",
|
||||||
"@types/node": "~16.11.41",
|
"@types/node": "~16.18.23",
|
||||||
"@typescript-eslint/parser": "^5.29.0",
|
"@typescript-eslint/parser": "^5.57.0",
|
||||||
"@vercel/ncc": "^0.34.0",
|
"@vercel/ncc": "^0.36.1",
|
||||||
"concurrently": "^7.2.2",
|
"concurrently": "^8.0.1",
|
||||||
"eslint": "^8.18.0",
|
"eslint": "^8.37.0",
|
||||||
"eslint-plugin-github": "^4.3.6",
|
"eslint-plugin-github": "^4.7.0",
|
||||||
"eslint-plugin-jest": "^26.5.3",
|
"eslint-plugin-jest": "^27.2.1",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"jest": "^27.5.1",
|
"jest": "^27.5.1",
|
||||||
"prettier": "2.7.1",
|
"prettier": "2.8.7",
|
||||||
"ts-jest": "^27.1.4",
|
"ts-jest": "^27.1.4",
|
||||||
"typescript": "^4.7.4"
|
"typescript": "^4.9.5"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"actions",
|
"actions",
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as github from '@actions/github'
|
import * as github from '@actions/github'
|
||||||
|
|
||||||
// TODO: Ensure this (and the Octokit client) works for non-github.com URLs, as well.
|
const urlParse = /\/(?<ownerType>orgs|users)\/(?<ownerName>[^/]+)\/projects\/(?<projectNumber>\d+)/
|
||||||
// https://github.com/orgs|users/<ownerName>/projects/<projectNumber>
|
|
||||||
const urlParse =
|
|
||||||
/^(?:https:\/\/)?github\.com\/(?<ownerType>orgs|users)\/(?<ownerName>[^/]+)\/projects\/(?<projectNumber>\d+)/
|
|
||||||
|
|
||||||
interface ProjectNodeIDResponse {
|
interface ProjectNodeIDResponse {
|
||||||
organization?: {
|
organization?: {
|
||||||
@@ -28,6 +25,14 @@ interface ProjectAddItemResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ProjectV2AddDraftIssueResponse {
|
||||||
|
addProjectV2DraftIssue: {
|
||||||
|
projectItem: {
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function addToProject(): Promise<void> {
|
export async function addToProject(): Promise<void> {
|
||||||
const projectUrl = core.getInput('project-url', {required: true})
|
const projectUrl = core.getInput('project-url', {required: true})
|
||||||
const ghToken = core.getInput('github-token', {required: true})
|
const ghToken = core.getInput('github-token', {required: true})
|
||||||
@@ -41,9 +46,12 @@ export async function addToProject(): Promise<void> {
|
|||||||
|
|
||||||
const octokit = github.getOctokit(ghToken)
|
const octokit = github.getOctokit(ghToken)
|
||||||
|
|
||||||
const urlMatch = projectUrl.match(urlParse)
|
|
||||||
const issue = github.context.payload.issue ?? github.context.payload.pull_request
|
const issue = github.context.payload.issue ?? github.context.payload.pull_request
|
||||||
const issueLabels: string[] = (issue?.labels ?? []).map((l: {name: string}) => l.name.toLowerCase())
|
const issueLabels: string[] = (issue?.labels ?? []).map((l: {name: string}) => l.name.toLowerCase())
|
||||||
|
const issueOwnerName = github.context.payload.repository?.owner.login
|
||||||
|
|
||||||
|
core.debug(`Issue/PR owner: ${issueOwnerName}`)
|
||||||
|
core.debug(`Issue/PR labels: ${issueLabels.join(', ')}`)
|
||||||
|
|
||||||
// Ensure the issue matches our `labeled` filter based on the label-operator.
|
// Ensure the issue matches our `labeled` filter based on the label-operator.
|
||||||
if (labelOperator === 'and') {
|
if (labelOperator === 'and') {
|
||||||
@@ -65,34 +73,36 @@ export async function addToProject(): Promise<void> {
|
|||||||
|
|
||||||
core.debug(`Project URL: ${projectUrl}`)
|
core.debug(`Project URL: ${projectUrl}`)
|
||||||
|
|
||||||
|
const urlMatch = projectUrl.match(urlParse)
|
||||||
|
|
||||||
if (!urlMatch) {
|
if (!urlMatch) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Invalid project URL: ${projectUrl}. Project URL should match the format https://github.com/<orgs-or-users>/<ownerName>/projects/<projectNumber>`
|
`Invalid project URL: ${projectUrl}. Project URL should match the format <GitHub server domain name>/<orgs-or-users>/<ownerName>/projects/<projectNumber>`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const ownerName = urlMatch.groups?.ownerName
|
const projectOwnerName = urlMatch.groups?.ownerName
|
||||||
const projectNumber = parseInt(urlMatch.groups?.projectNumber ?? '', 10)
|
const projectNumber = parseInt(urlMatch.groups?.projectNumber ?? '', 10)
|
||||||
const ownerType = urlMatch.groups?.ownerType
|
const ownerType = urlMatch.groups?.ownerType
|
||||||
const ownerTypeQuery = mustGetOwnerTypeQuery(ownerType)
|
const ownerTypeQuery = mustGetOwnerTypeQuery(ownerType)
|
||||||
|
|
||||||
core.debug(`Org name: ${ownerName}`)
|
core.debug(`Project owner: ${projectOwnerName}`)
|
||||||
core.debug(`Project number: ${projectNumber}`)
|
core.debug(`Project number: ${projectNumber}`)
|
||||||
core.debug(`Owner type: ${ownerType}`)
|
core.debug(`Project owner type: ${ownerType}`)
|
||||||
|
|
||||||
// First, use the GraphQL API to request the project's node ID.
|
// First, use the GraphQL API to request the project's node ID.
|
||||||
const idResp = await octokit.graphql<ProjectNodeIDResponse>(
|
const idResp = await octokit.graphql<ProjectNodeIDResponse>(
|
||||||
`query getProject($ownerName: String!, $projectNumber: Int!) {
|
`query getProject($projectOwnerName: String!, $projectNumber: Int!) {
|
||||||
${ownerTypeQuery}(login: $ownerName) {
|
${ownerTypeQuery}(login: $projectOwnerName) {
|
||||||
projectV2(number: $projectNumber) {
|
projectV2(number: $projectNumber) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
{
|
{
|
||||||
ownerName,
|
projectOwnerName,
|
||||||
projectNumber
|
projectNumber,
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const projectId = idResp[ownerTypeQuery]?.projectV2.id
|
const projectId = idResp[ownerTypeQuery]?.projectV2.id
|
||||||
@@ -102,23 +112,50 @@ export async function addToProject(): Promise<void> {
|
|||||||
core.debug(`Content ID: ${contentId}`)
|
core.debug(`Content ID: ${contentId}`)
|
||||||
|
|
||||||
// Next, use the GraphQL API to add the issue to the project.
|
// Next, use the GraphQL API to add the issue to the project.
|
||||||
const addResp = await octokit.graphql<ProjectAddItemResponse>(
|
// If the issue has the same owner as the project, we can directly
|
||||||
`mutation addIssueToProject($input: AddProjectV2ItemByIdInput!) {
|
// add a project item. Otherwise, we add a draft issue.
|
||||||
addProjectV2ItemById(input: $input) {
|
if (issueOwnerName === projectOwnerName) {
|
||||||
item {
|
core.info('Creating project item')
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}`,
|
|
||||||
{
|
|
||||||
input: {
|
|
||||||
projectId,
|
|
||||||
contentId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
core.setOutput('itemId', addResp.addProjectV2ItemById.item.id)
|
const addResp = await octokit.graphql<ProjectAddItemResponse>(
|
||||||
|
`mutation addIssueToProject($input: AddProjectV2ItemByIdInput!) {
|
||||||
|
addProjectV2ItemById(input: $input) {
|
||||||
|
item {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`,
|
||||||
|
{
|
||||||
|
input: {
|
||||||
|
projectId,
|
||||||
|
contentId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
core.setOutput('itemId', addResp.addProjectV2ItemById.item.id)
|
||||||
|
} else {
|
||||||
|
core.info('Creating draft issue in project')
|
||||||
|
|
||||||
|
const addResp = await octokit.graphql<ProjectV2AddDraftIssueResponse>(
|
||||||
|
`mutation addDraftIssueToProject($projectId: ID!, $title: String!) {
|
||||||
|
addProjectV2DraftIssue(input: {
|
||||||
|
projectId: $projectId,
|
||||||
|
title: $title
|
||||||
|
}) {
|
||||||
|
projectItem {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`,
|
||||||
|
{
|
||||||
|
projectId,
|
||||||
|
title: issue?.html_url,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
core.setOutput('itemId', addResp.addProjectV2DraftIssue.projectItem.id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mustGetOwnerTypeQuery(ownerType?: string): 'organization' | 'user' {
|
export function mustGetOwnerTypeQuery(ownerType?: string): 'organization' | 'user' {
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
"rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
|
"rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
|
||||||
"strict": true /* Enable all strict type-checking options. */,
|
"strict": true /* Enable all strict type-checking options. */,
|
||||||
"noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
|
"noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
|
||||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
|
||||||
|
"noUncheckedIndexedAccess": true
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", "**/*.test.ts"]
|
"exclude": ["node_modules", "**/*.test.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user