mirror of
https://github.com/jlengrand/github-api.git
synced 2026-03-12 08:21:22 +00:00
Compare commits
403 Commits
github-api
...
github-api
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4261c42949 | ||
|
|
40cfb85a8e | ||
|
|
f08299b134 | ||
|
|
a04ab45abc | ||
|
|
0647df2d2b | ||
|
|
d4cc3af1e9 | ||
|
|
936ab499ce | ||
|
|
453f475b4e | ||
|
|
bda3855b86 | ||
|
|
772a6c112b | ||
|
|
9b4134cada | ||
|
|
ed9f54006d | ||
|
|
3b1f176544 | ||
|
|
d2732bcf54 | ||
|
|
a1461f401a | ||
|
|
f9fd30275c | ||
|
|
eeea14dab4 | ||
|
|
1df807a198 | ||
|
|
0848287069 | ||
|
|
334b37a256 | ||
|
|
8776a3b672 | ||
|
|
657550f767 | ||
|
|
45a0114f75 | ||
|
|
a8ddd3e12a | ||
|
|
b668396151 | ||
|
|
9e7c33369c | ||
|
|
8943ca6d1a | ||
|
|
b3460c1f9d | ||
|
|
5166c9265f | ||
|
|
35c8cfa01d | ||
|
|
8e6dbf3772 | ||
|
|
cb381dfa06 | ||
|
|
80124e3b85 | ||
|
|
7aae27e36f | ||
|
|
b212956fbb | ||
|
|
d033355e84 | ||
|
|
59d7a117d0 | ||
|
|
dfbb38c5f1 | ||
|
|
3f9954144a | ||
|
|
1b84efdbfa | ||
|
|
c33e78a7dc | ||
|
|
747c759bbb | ||
|
|
e0a709676e | ||
|
|
a96275c286 | ||
|
|
ca7c809feb | ||
|
|
a8a0bcb7db | ||
|
|
0e2bf23830 | ||
|
|
44a8b797fb | ||
|
|
cdede298a9 | ||
|
|
f6ac4d3559 | ||
|
|
7e1531dbca | ||
|
|
9aeb422157 | ||
|
|
fba0f8cf8e | ||
|
|
0f4a5227e1 | ||
|
|
d16a752b43 | ||
|
|
4d9aed90d6 | ||
|
|
4bec27fd49 | ||
|
|
be3bd74bb7 | ||
|
|
f1720b7bbc | ||
|
|
7a79a18d8f | ||
|
|
472034c950 | ||
|
|
0b14cee817 | ||
|
|
b50ab56f9e | ||
|
|
26d30663c4 | ||
|
|
ffecc390eb | ||
|
|
252ca04084 | ||
|
|
aae5c56a31 | ||
|
|
6670446037 | ||
|
|
bd39b07bb5 | ||
|
|
a9438b6121 | ||
|
|
f546cf4521 | ||
|
|
43efa78750 | ||
|
|
9e3de43802 | ||
|
|
dc615e432e | ||
|
|
cf9caa6af5 | ||
|
|
15f748358d | ||
|
|
b30d648623 | ||
|
|
33d70560b8 | ||
|
|
865a49d2e8 | ||
|
|
4fca68c25c | ||
|
|
f131a0c1c2 | ||
|
|
cd4368fa79 | ||
|
|
4ec4b160b0 | ||
|
|
a585b4957f | ||
|
|
e6b02b3bed | ||
|
|
1ef0ec0432 | ||
|
|
2e87bd86a1 | ||
|
|
0228a0d023 | ||
|
|
6365f3749d | ||
|
|
25c18130f9 | ||
|
|
436c19634d | ||
|
|
1a6facc685 | ||
|
|
bd0093c8ea | ||
|
|
e150280010 | ||
|
|
827fd5e472 | ||
|
|
f89fbc67b9 | ||
|
|
c567a88892 | ||
|
|
6a39d7fca5 | ||
|
|
a15e67f065 | ||
|
|
7a1bce9578 | ||
|
|
f2b4de7943 | ||
|
|
b3ff4ac6d9 | ||
|
|
1c56e7fab5 | ||
|
|
70ba4df385 | ||
|
|
8062c705e8 | ||
|
|
fafb23c1a6 | ||
|
|
4e7ac7030c | ||
|
|
4803daca5a | ||
|
|
facfc61316 | ||
|
|
e3e495bfb1 | ||
|
|
e007284d2f | ||
|
|
1da8416ebd | ||
|
|
79b49a469c | ||
|
|
5888efcaef | ||
|
|
459d1b4f56 | ||
|
|
9151102bda | ||
|
|
3819984add | ||
|
|
3b58fbc186 | ||
|
|
55e589b3d9 | ||
|
|
e64d64d8d8 | ||
|
|
37c2d9135b | ||
|
|
30c96221bd | ||
|
|
bf7305e3f8 | ||
|
|
3b12a229c3 | ||
|
|
5726ceb8dc | ||
|
|
c06c06624d | ||
|
|
ad40d7071e | ||
|
|
f55a39eb90 | ||
|
|
c3869bee31 | ||
|
|
6eac15df0f | ||
|
|
6f5d3c32c3 | ||
|
|
68ef40e4d0 | ||
|
|
4046bc4f72 | ||
|
|
1b8d131915 | ||
|
|
f5ad332d28 | ||
|
|
938603ff60 | ||
|
|
17af78f2bb | ||
|
|
7588267743 | ||
|
|
ed4f9c8176 | ||
|
|
bbb46e88b0 | ||
|
|
3db7aac0d8 | ||
|
|
fdbbd2e563 | ||
|
|
e92f1321d4 | ||
|
|
da2aaff9e5 | ||
|
|
208904b634 | ||
|
|
a433bcda2e | ||
|
|
4bba692170 | ||
|
|
59b61cd8be | ||
|
|
247b013e16 | ||
|
|
77baafa643 | ||
|
|
3c56f1f076 | ||
|
|
224d8c7cb4 | ||
|
|
0feb520549 | ||
|
|
ca365b12f6 | ||
|
|
bde6ad9a06 | ||
|
|
4953f4500d | ||
|
|
7fee1fcc74 | ||
|
|
4415ac8fd2 | ||
|
|
8c81e48a31 | ||
|
|
9ad0329c56 | ||
|
|
78f533bbfc | ||
|
|
79c7dd9ecf | ||
|
|
5d796d1f79 | ||
|
|
68a82be6c4 | ||
|
|
2676ef2b73 | ||
|
|
04b283c539 | ||
|
|
98b067937a | ||
|
|
8ababb60bf | ||
|
|
b51d655f77 | ||
|
|
74496d32da | ||
|
|
316e278be1 | ||
|
|
d881bf6504 | ||
|
|
c74fbbe1fd | ||
|
|
929d9fb7bd | ||
|
|
5d069d0531 | ||
|
|
dd9e6dc5d3 | ||
|
|
d22c77c41d | ||
|
|
3a11b7ccbf | ||
|
|
d7931777bc | ||
|
|
9d161b28bb | ||
|
|
9b16a1caa0 | ||
|
|
9a918e3bac | ||
|
|
d4c5c6a1e0 | ||
|
|
63fda3555c | ||
|
|
6a2381c06b | ||
|
|
e9c0a16c26 | ||
|
|
2101a67ac1 | ||
|
|
ddac568aaa | ||
|
|
262ae9f635 | ||
|
|
381502fb80 | ||
|
|
92fb441eb2 | ||
|
|
29e08037a8 | ||
|
|
84cc6d9315 | ||
|
|
b8d5a1c732 | ||
|
|
0197ab9661 | ||
|
|
b7915e61a6 | ||
|
|
586db99450 | ||
|
|
5377d0dd18 | ||
|
|
bb48d55bd4 | ||
|
|
c5d3a7d573 | ||
|
|
8267050f06 | ||
|
|
610b02968e | ||
|
|
a7112c42df | ||
|
|
8a474a3b00 | ||
|
|
59e18d155e | ||
|
|
12ca5d8063 | ||
|
|
c959e0a928 | ||
|
|
89a08b021d | ||
|
|
04b553cdec | ||
|
|
15e9ee30ee | ||
|
|
a0d650a86c | ||
|
|
1a6ad48e08 | ||
|
|
7c82eeb018 | ||
|
|
b188e74ee0 | ||
|
|
c21bd5765a | ||
|
|
b78c37a695 | ||
|
|
2f151d45c3 | ||
|
|
3ebe3afdbd | ||
|
|
f4845df6c0 | ||
|
|
272b87f04d | ||
|
|
ff790eeefb | ||
|
|
97e918da03 | ||
|
|
4f30998873 | ||
|
|
a0fc478a28 | ||
|
|
bb03fd1968 | ||
|
|
0c65f74662 | ||
|
|
29ac2bd4f5 | ||
|
|
0d8b4f32e8 | ||
|
|
83db7f24eb | ||
|
|
5f9976a193 | ||
|
|
9480ef485b | ||
|
|
a9b7432584 | ||
|
|
6d7081910f | ||
|
|
aa96089ab4 | ||
|
|
58ae681417 | ||
|
|
c038e0af5e | ||
|
|
4f9976c0cb | ||
|
|
e308e5ed57 | ||
|
|
7b1b1ca994 | ||
|
|
551be49a1a | ||
|
|
a3888e6902 | ||
|
|
43bb6a0dd8 | ||
|
|
6e3f754366 | ||
|
|
6360112432 | ||
|
|
f1ca0b5417 | ||
|
|
0894c8007c | ||
|
|
05863acbcd | ||
|
|
0e4cd06137 | ||
|
|
85d2d974e7 | ||
|
|
3f021f9552 | ||
|
|
0456f10709 | ||
|
|
b7d03f7463 | ||
|
|
07a392c2a7 | ||
|
|
5b69de770f | ||
|
|
4688870984 | ||
|
|
bf67069768 | ||
|
|
91764c1c74 | ||
|
|
8b2a3e1221 | ||
|
|
def2f0b37d | ||
|
|
5d7479a3dd | ||
|
|
ceb2d35f9f | ||
|
|
fc38dba59a | ||
|
|
75b383d398 | ||
|
|
ee2d9491fb | ||
|
|
bf86a7c75a | ||
|
|
70f6d129e2 | ||
|
|
a4ac2aa99a | ||
|
|
ae3b6fbe6b | ||
|
|
e357fca963 | ||
|
|
c84cc89805 | ||
|
|
181238cd50 | ||
|
|
214c24c736 | ||
|
|
cf51ce8f26 | ||
|
|
2b7ed40d01 | ||
|
|
349ef7a54c | ||
|
|
94df5fc389 | ||
|
|
906238a297 | ||
|
|
7963fa82b5 | ||
|
|
1aba6012fb | ||
|
|
ff4324ac67 | ||
|
|
11bc669e1d | ||
|
|
dcf26d58e4 | ||
|
|
4d46872c35 | ||
|
|
4f0d62f421 | ||
|
|
f7ad1f517b | ||
|
|
345d6197f3 | ||
|
|
bb4d44138a | ||
|
|
a8ef0cde53 | ||
|
|
77dc009c95 | ||
|
|
aa298c93cc | ||
|
|
dfb0a5240e | ||
|
|
9cfc3c22b5 | ||
|
|
b177d98e29 | ||
|
|
5405fb0370 | ||
|
|
72a1c24b3b | ||
|
|
f146ae94ec | ||
|
|
a0bbba748a | ||
|
|
81bf818573 | ||
|
|
d5913dc292 | ||
|
|
e1e901b794 | ||
|
|
2f2f26767e | ||
|
|
bffa78c1b8 | ||
|
|
c55719c67a | ||
|
|
cb3b4a6642 | ||
|
|
92c141cee6 | ||
|
|
fd1a1a1c23 | ||
|
|
b835884b2e | ||
|
|
660763908d | ||
|
|
fe8bdb755a | ||
|
|
67dc6d2d23 | ||
|
|
9c8d73cbe2 | ||
|
|
5db97d92dd | ||
|
|
ac470dddb5 | ||
|
|
43063fe8ce | ||
|
|
59e0046c1e | ||
|
|
36ab05c265 | ||
|
|
2b2be05dae | ||
|
|
fb1adbd1ef | ||
|
|
ab68a59b25 | ||
|
|
9c7de767e9 | ||
|
|
8ba5cf7c2e | ||
|
|
b194a19b98 | ||
|
|
1d344b016f | ||
|
|
474f3ef4ca | ||
|
|
9830927020 | ||
|
|
727932a442 | ||
|
|
cd92b51845 | ||
|
|
fe26d16411 | ||
|
|
d68c66ce2b | ||
|
|
e7bfbfb48f | ||
|
|
f2a88ae61c | ||
|
|
e2113f6ee5 | ||
|
|
3867224024 | ||
|
|
9ee0bf43bc | ||
|
|
2844542efa | ||
|
|
e3fcae9392 | ||
|
|
c6ccfa91f3 | ||
|
|
b6fcee1cb9 | ||
|
|
9071befb04 | ||
|
|
bdd5fe98f3 | ||
|
|
a3d3e83a49 | ||
|
|
08bde72028 | ||
|
|
108a136368 | ||
|
|
57d87ad6b1 | ||
|
|
0c22815ff7 | ||
|
|
0ca792ecfd | ||
|
|
987c34c69e | ||
|
|
c1c02bc8ab | ||
|
|
4ee369f27c | ||
|
|
c9012efdcb | ||
|
|
41524fc67d | ||
|
|
04ff61e981 | ||
|
|
532468dc67 | ||
|
|
9c9a2dae47 | ||
|
|
c8a868b57f | ||
|
|
4b3f81ee34 | ||
|
|
afa170ba7c | ||
|
|
46e3b2272e | ||
|
|
52472e90ec | ||
|
|
4ef0d00846 | ||
|
|
580f2537f2 | ||
|
|
3d9fd96026 | ||
|
|
f449b92721 | ||
|
|
3b0216b023 | ||
|
|
98cf839737 | ||
|
|
0bb0846505 | ||
|
|
70969400a3 | ||
|
|
147e8d5d12 | ||
|
|
cacc3e6edd | ||
|
|
a284eca147 | ||
|
|
0d3ba9d7f0 | ||
|
|
be8064d642 | ||
|
|
e30dba742d | ||
|
|
44b72ed647 | ||
|
|
666bd77dac | ||
|
|
0a6613e60d | ||
|
|
62e186c123 | ||
|
|
50dd8f5bcc | ||
|
|
d5fcac9c45 | ||
|
|
c2bed85190 | ||
|
|
183b463ef2 | ||
|
|
92fdac44a0 | ||
|
|
12829ecc73 | ||
|
|
51319c3b26 | ||
|
|
8fd827040b | ||
|
|
5ec46eae0d | ||
|
|
32c03301be | ||
|
|
df7f29b2ab | ||
|
|
e863113c36 | ||
|
|
8e2c1d7382 | ||
|
|
ab7b9cccba | ||
|
|
81bf61a161 | ||
|
|
b40f008647 | ||
|
|
734e41702b | ||
|
|
038dd20a91 | ||
|
|
1dd62b8550 | ||
|
|
715deebe05 | ||
|
|
b3fe3d8590 | ||
|
|
f74c3ed3ea | ||
|
|
2c9aebeeed | ||
|
|
7474f1e11f | ||
|
|
dba9c55b64 | ||
|
|
b432364397 |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.java text eol=lf
|
||||||
3
.github/PULL_REQUEST_TEMPLATE.md
vendored
3
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -7,8 +7,7 @@ We love getting PRs, but we hate asking people for the same basic changes every
|
|||||||
- [ ] Push your changes to a branch other than `master`. Create your PR from that branch.
|
- [ ] Push your changes to a branch other than `master`. Create your PR from that branch.
|
||||||
- [ ] Add JavaDocs and other comments
|
- [ ] Add JavaDocs and other comments
|
||||||
- [ ] Write tests that run and pass in CI. See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to capture snapshot data.
|
- [ ] Write tests that run and pass in CI. See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to capture snapshot data.
|
||||||
- [ ] Run `mvn clean compile` locally. This may reformat your code, commit those changes.
|
- [ ] Run `mvn -D enable-ci clean install site` locally. If this command doesn't succeed, your change will not pass CI.
|
||||||
- [ ] Run `mvn -D enable-ci clean install site` locally. If this command doesn't succeed, your change will not pass CI.
|
|
||||||
|
|
||||||
# When creating a PR:
|
# When creating a PR:
|
||||||
|
|
||||||
|
|||||||
12
.github/dependabot.yml
vendored
Normal file
12
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "maven"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "monthly"
|
||||||
|
time: "02:00"
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "monthly"
|
||||||
|
time: "02:00"
|
||||||
5
.github/release-drafter.yml
vendored
5
.github/release-drafter.yml
vendored
@@ -1,5 +1,6 @@
|
|||||||
name-template: 'v$NEXT_PATCH_VERSION 🌈'
|
name-template: 'v$NEXT_MINOR_VERSION 🌈'
|
||||||
tag-template: 'v$NEXT_PATCH_VERSION'
|
tag-template: 'github-api-$NEXT_MINOR_VERSION'
|
||||||
|
version-template: '$MAJOR.$MINOR'
|
||||||
categories:
|
categories:
|
||||||
- title: '🚀 Features'
|
- title: '🚀 Features'
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
6
.github/workflows/maven-build.yml
vendored
6
.github/workflows/maven-build.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
java-version: ${{ matrix.java }}
|
java-version: ${{ matrix.java }}
|
||||||
- name: Cached .m2
|
- name: Cached .m2
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: ~/.m2/repository
|
path: ~/.m2/repository
|
||||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||||
@@ -37,7 +37,7 @@ jobs:
|
|||||||
uses: actions/setup-java@v1
|
uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: ${{ matrix.java }}
|
java-version: ${{ matrix.java }}
|
||||||
- uses: actions/cache@v1
|
- uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: ~/.m2/repository
|
path: ~/.m2/repository
|
||||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||||
@@ -58,7 +58,7 @@ jobs:
|
|||||||
uses: actions/setup-java@v1
|
uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: ${{ matrix.java }}
|
java-version: ${{ matrix.java }}
|
||||||
- uses: actions/cache@v1
|
- uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: ~/.m2/repository
|
path: ~/.m2/repository
|
||||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
For changes after v1.101 see the [GitHub Releases page](https://github.com/hub4j/github-api/releases) for the project.
|
||||||
|
|
||||||
## [github-api-1.101](https://github.com/hub4j/github-api/tree/github-api-1.101) (2019-11-27)
|
## [github-api-1.101](https://github.com/hub4j/github-api/tree/github-api-1.101) (2019-11-27)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/hub4j/github-api/compare/github-api-1.100...github-api-1.101)
|
[Full Changelog](https://github.com/hub4j/github-api/compare/github-api-1.100...github-api-1.101)
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ Example:
|
|||||||
|
|
||||||
This the default behavior.
|
This the default behavior.
|
||||||
|
|
||||||
|
Example for a single test case:
|
||||||
|
|
||||||
|
`mvn install -Dtest=WireMockStatusReporterTest#user_whenProxying_AuthCorrectlyConfigured`
|
||||||
|
|
||||||
|
|
||||||
### Setting up credential
|
### Setting up credential
|
||||||
|
|
||||||
@@ -27,21 +31,37 @@ This the default behavior.
|
|||||||
|
|
||||||
`WireMockStatusReporterTest: GitHub proxying and user auth correctly configured for user login: <your login>`
|
`WireMockStatusReporterTest: GitHub proxying and user auth correctly configured for user login: <your login>`
|
||||||
|
|
||||||
Whenever you run tests with `-Dtest.github.useProxy`, they will try to get data from local files but will fallback to proxying to github if not found.
|
Whenever you run tests with `-Dtest.github.useProxy`, they will try to get data from local files but will fallback to proxying to GitHub if not found.
|
||||||
|
|
||||||
|
|
||||||
### Writing a new test
|
### Writing a new test
|
||||||
|
|
||||||
Once you have credentials setup, you add new test classes and test methods as you would normally.
|
Once you have credentials setup, you add new test classes and test methods as you would normally.
|
||||||
Keep `useProxy` enabled and iterate on your tests as needed. Remember, while proxying your tests are interacting with GitHub - you will need to clean up your state between runs.
|
|
||||||
|
|
||||||
When you are ready to create a snapshot of your test data,
|
#### Running tests using GitHub test proxy
|
||||||
run your test with `test.github.takeSnapshot` ("-Dtest.github.takeSnapshot" as a Java VM option). For example:
|
|
||||||
|
|
||||||
`mvn install -Dtest.github.takeSnapshot -Dtest=YourTestClassName`
|
Keep `useProxy` enabled and iterate on your tests as needed. With `useProxy` enabled your tests will interact with
|
||||||
|
GitHub - you will need to clean up your server-state between runs. This can be done manually to start with.
|
||||||
|
Once your test code is somewhat stable, use `getGitHubBeforeAfter()` to get a `GitHub` instance for test setup and cleanup.
|
||||||
|
Interactions with that `GitHub` instance will not be recorded as part of the test, keeping the test data files to a minimum.
|
||||||
|
|
||||||
The above command would create snapshot WireMock data files under the path `src/test/resources/org/kohsuhke/github/YourTestClassName/wiremock`.
|
#### Running tests against your personal GitHub user account
|
||||||
Each method would get a separate director that would hold the data files for that test method.
|
|
||||||
|
By default, test helper methods such as `getTempRepository()` target the `hub4j-test-org` GitHub organization.
|
||||||
|
Please request access to this org to record your tests before submitting a PR. This helps keep the project stable and nimble.
|
||||||
|
Until you have access (or if you don't want access), you can set the following additional system property to target
|
||||||
|
your personal github account.
|
||||||
|
|
||||||
|
`mvn install -Dtest.github.org=false -Dtest=YourTestClassName`
|
||||||
|
|
||||||
|
#### Taking a snapshot
|
||||||
|
|
||||||
|
When you are ready to create a snapshot of your test data, run your test with `test.github.takeSnapshot` ("-Dtest.github.takeSnapshot" as
|
||||||
|
a Java VM option). For example:
|
||||||
|
|
||||||
|
`mvn install -Dtest.github.takeSnapshot -Dtest.github.org=false -Dtest=YourTestClassName`
|
||||||
|
|
||||||
|
The above command will create snapshot WireMock data files under the path `src/test/resources/org/kohsuhke/github/YourTestClassName/wiremock`.
|
||||||
|
Each method will get a separate directory that will hold the data files for that test method.
|
||||||
|
|
||||||
Add all files including the generated data to your commit and submit a PR.
|
Add all files including the generated data to your commit and submit a PR.
|
||||||
|
|
||||||
|
|||||||
198
pom.xml
198
pom.xml
@@ -2,7 +2,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.kohsuke</groupId>
|
<groupId>org.kohsuke</groupId>
|
||||||
<artifactId>github-api</artifactId>
|
<artifactId>github-api</artifactId>
|
||||||
<version>1.114</version>
|
<version>1.123</version>
|
||||||
<name>GitHub API for Java</name>
|
<name>GitHub API for Java</name>
|
||||||
<url>https://github-api.kohsuke.org/</url>
|
<url>https://github-api.kohsuke.org/</url>
|
||||||
<description>GitHub API for Java</description>
|
<description>GitHub API for Java</description>
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
<connection>scm:git:git@github.com/hub4j/${project.artifactId}.git</connection>
|
<connection>scm:git:git@github.com/hub4j/${project.artifactId}.git</connection>
|
||||||
<developerConnection>scm:git:ssh://git@github.com/hub4j/${project.artifactId}.git</developerConnection>
|
<developerConnection>scm:git:ssh://git@github.com/hub4j/${project.artifactId}.git</developerConnection>
|
||||||
<url>https://github.com/hub4j/github-api/</url>
|
<url>https://github.com/hub4j/github-api/</url>
|
||||||
<tag>github-api-1.114</tag>
|
<tag>github-api-1.123</tag>
|
||||||
</scm>
|
</scm>
|
||||||
|
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
@@ -33,19 +33,18 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<spotbugs-maven-plugin.version>4.0.0</spotbugs-maven-plugin.version>
|
<spotbugs-maven-plugin.version>4.2.0</spotbugs-maven-plugin.version>
|
||||||
<spotbugs.version>4.0.4</spotbugs.version>
|
<spotbugs.version>4.1.3</spotbugs.version>
|
||||||
<spotbugs-maven-plugin.failOnError>true</spotbugs-maven-plugin.failOnError>
|
<spotbugs-maven-plugin.failOnError>true</spotbugs-maven-plugin.failOnError>
|
||||||
<hamcrest.version>2.2</hamcrest.version>
|
<hamcrest.version>2.2</hamcrest.version>
|
||||||
<okhttp3.version>4.4.1</okhttp3.version>
|
<okhttp3.version>4.4.1</okhttp3.version>
|
||||||
<okio.version>2.5.0</okio.version>
|
<okio.version>2.5.0</okio.version>
|
||||||
<formatter-maven-plugin.goal>format</formatter-maven-plugin.goal>
|
|
||||||
<impsort-maven-plugin.goal>sort</impsort-maven-plugin.goal>
|
|
||||||
<!-- Using this as the minimum bar for code coverage. Adding methods without covering them will fail this. -->
|
<!-- Using this as the minimum bar for code coverage. Adding methods without covering them will fail this. -->
|
||||||
<jacoco.coverage.target.bundle.method>0.60</jacoco.coverage.target.bundle.method>
|
<jacoco.coverage.target.bundle.method>0.70</jacoco.coverage.target.bundle.method>
|
||||||
<jacoco.coverage.target.class.method>0.25</jacoco.coverage.target.class.method>
|
<jacoco.coverage.target.class.method>0.50</jacoco.coverage.target.class.method>
|
||||||
<!-- For non-ci builds we'd like the build to still complete if jacoco metrics aren't met. -->
|
<!-- For non-ci builds we'd like the build to still complete if jacoco metrics aren't met. -->
|
||||||
<jacoco.haltOnFailure>false</jacoco.haltOnFailure>
|
<jacoco.haltOnFailure>false</jacoco.haltOnFailure>
|
||||||
|
<jjwt.suite.version>0.11.2</jjwt.suite.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -79,6 +78,14 @@
|
|||||||
</testResources>
|
</testResources>
|
||||||
<pluginManagement>
|
<pluginManagement>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.22.2</version>
|
||||||
|
<configuration>
|
||||||
|
<!-- SUREFIRE-1226 workaround -->
|
||||||
|
<trimStackTrace>false</trimStackTrace>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-source-plugin</artifactId>
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
@@ -92,7 +99,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.jacoco</groupId>
|
<groupId>org.jacoco</groupId>
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
<version>0.8.5</version>
|
<version>0.8.6</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<goals>
|
<goals>
|
||||||
@@ -145,59 +152,39 @@
|
|||||||
<!-- Sample only -->
|
<!-- Sample only -->
|
||||||
<exclude>org.kohsuke.github.example.*</exclude>
|
<exclude>org.kohsuke.github.example.*</exclude>
|
||||||
|
|
||||||
<!-- No methods -->
|
|
||||||
<exclude>org.kohsuke.github.Previews</exclude>
|
|
||||||
|
|
||||||
<!-- Deprecated -->
|
<!-- Deprecated -->
|
||||||
<exclude>org.kohsuke.github.extras.OkHttp3Connector</exclude>
|
<exclude>org.kohsuke.github.extras.OkHttp3Connector</exclude>
|
||||||
<exclude>org.kohsuke.github.EnforcementLevel</exclude>
|
<exclude>org.kohsuke.github.EnforcementLevel</exclude>
|
||||||
<exclude>org.kohsuke.github.GHPerson.1</exclude>
|
<exclude>org.kohsuke.github.GHPerson.1</exclude>
|
||||||
|
<!-- TODO: Some coverage, but more needed -->
|
||||||
<!-- These fail coverage on windows because tests are disabled -->
|
<exclude>org.kohsuke.github.GHPullRequestReviewBuilder.DraftReviewComment</exclude>
|
||||||
<exclude>org.kohsuke.github.GHAsset</exclude>
|
<exclude>org.kohsuke.github.GHIssue.PullRequest</exclude>
|
||||||
<exclude>org.kohsuke.github.GHReleaseBuilder</exclude>
|
<exclude>org.kohsuke.github.GHCommitSearchBuilder</exclude>
|
||||||
<exclude>org.kohsuke.github.GHRelease</exclude>
|
<exclude>org.kohsuke.github.GHRepositorySearchBuilder</exclude>
|
||||||
|
<exclude>org.kohsuke.github.GHUserSearchBuilder</exclude>
|
||||||
|
|
||||||
<!-- TODO: These still need test coverage -->
|
<!-- TODO: These still need test coverage -->
|
||||||
<exclude>org.kohsuke.github.GHBranchProtection.RequiredSignatures</exclude>
|
<exclude>org.kohsuke.github.GHBranchProtection.RequiredSignatures</exclude>
|
||||||
<exclude>org.kohsuke.github.GHBranchProtectionBuilder.Restrictions</exclude>
|
<exclude>org.kohsuke.github.GHBranchProtectionBuilder.Restrictions</exclude>
|
||||||
<exclude>org.kohsuke.github.GHBranchProtection.Restrictions</exclude>
|
<exclude>org.kohsuke.github.GHBranchProtection.Restrictions</exclude>
|
||||||
<exclude>org.kohsuke.github.GHCommentAuthorAssociation</exclude>
|
<exclude>org.kohsuke.github.GHCommentAuthorAssociation</exclude>
|
||||||
<exclude>org.kohsuke.github.GHCommitBuilder.UserInfo</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHCommitState</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHCompare.Commit</exclude>
|
<exclude>org.kohsuke.github.GHCompare.Commit</exclude>
|
||||||
<exclude>org.kohsuke.github.GHCompare.InnerCommit</exclude>
|
<exclude>org.kohsuke.github.GHCompare.InnerCommit</exclude>
|
||||||
<exclude>org.kohsuke.github.GHCompare.Status</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHCompare.Tree</exclude>
|
<exclude>org.kohsuke.github.GHCompare.Tree</exclude>
|
||||||
<exclude>org.kohsuke.github.GHCompare.User</exclude>
|
<exclude>org.kohsuke.github.GHCompare.User</exclude>
|
||||||
<exclude>org.kohsuke.github.GHCompare</exclude>
|
<exclude>org.kohsuke.github.GHCompare</exclude>
|
||||||
<exclude>org.kohsuke.github.GHDeployKey</exclude>
|
<exclude>org.kohsuke.github.GHDeployKey</exclude>
|
||||||
<exclude>org.kohsuke.github.GHDeploymentStatusBuilder</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHDirection</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHEmail</exclude>
|
<exclude>org.kohsuke.github.GHEmail</exclude>
|
||||||
<exclude>org.kohsuke.github.GHEventPayload.Ping</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHEventPayload.Release</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHException</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHHook</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHHooks.OrgContext</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHInvitation</exclude>
|
<exclude>org.kohsuke.github.GHInvitation</exclude>
|
||||||
<exclude>org.kohsuke.github.GHMilestoneState</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHOrgHook</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHProject.ProjectStateFilter</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.Authorship</exclude>
|
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.Authorship</exclude>
|
||||||
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.Commit</exclude>
|
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.Commit</exclude>
|
||||||
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.CommitPointer</exclude>
|
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.CommitPointer</exclude>
|
||||||
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.Tree</exclude>
|
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.Tree</exclude>
|
||||||
<exclude>org.kohsuke.github.GHPullRequestCommitDetail</exclude>
|
<exclude>org.kohsuke.github.GHPullRequestCommitDetail</exclude>
|
||||||
<exclude>org.kohsuke.github.GHPullRequestFileDetail</exclude>
|
<exclude>org.kohsuke.github.GHPullRequestFileDetail</exclude>
|
||||||
<exclude>org.kohsuke.github.GHPullRequestQueryBuilder.Sort</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHReleaseUpdater</exclude>
|
<exclude>org.kohsuke.github.GHReleaseUpdater</exclude>
|
||||||
<exclude>org.kohsuke.github.GHRepository.ForkSort</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHRequestedAction</exclude>
|
<exclude>org.kohsuke.github.GHRequestedAction</exclude>
|
||||||
<exclude>org.kohsuke.github.GHStargazer</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHTagObject</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHTeam.Role</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHUserSearchBuilder.Sort</exclude>
|
|
||||||
<exclude>org.kohsuke.github.GHVerifiedKey</exclude>
|
<exclude>org.kohsuke.github.GHVerifiedKey</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</rule>
|
</rule>
|
||||||
@@ -233,7 +220,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-site-plugin</artifactId>
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
<version>3.9.0</version>
|
<version>3.9.1</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
@@ -253,7 +240,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||||
<version>3.1.0</version>
|
<version>3.1.1</version>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.bcel</groupId>
|
<groupId>org.apache.bcel</groupId>
|
||||||
@@ -280,16 +267,31 @@
|
|||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>2.22.2</version>
|
<executions>
|
||||||
<configuration>
|
<execution>
|
||||||
<!-- SUREFIRE-1226 workaround -->
|
<id>default-test</id>
|
||||||
<trimStackTrace>false</trimStackTrace>
|
<configuration>
|
||||||
</configuration>
|
<excludesFile>src/test/resources/slow-or-flaky-tests.txt</excludesFile>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>slow-or-flaky-test</id>
|
||||||
|
<phase>test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<rerunFailingTestsCount>2</rerunFailingTestsCount>
|
||||||
|
<!-- There are some tests that take longer or are a little flaky. Run them here. -->
|
||||||
|
<includesFile>src/test/resources/slow-or-flaky-tests.txt</includesFile>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>animal-sniffer-maven-plugin</artifactId>
|
<artifactId>animal-sniffer-maven-plugin</artifactId>
|
||||||
<version>1.18</version>
|
<version>1.19</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<signature>
|
<signature>
|
||||||
<groupId>org.codehaus.mojo.signature</groupId>
|
<groupId>org.codehaus.mojo.signature</groupId>
|
||||||
@@ -320,36 +322,35 @@
|
|||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>net.revelc.code.formatter</groupId>
|
<groupId>com.diffplug.spotless</groupId>
|
||||||
<artifactId>formatter-maven-plugin</artifactId>
|
<artifactId>spotless-maven-plugin</artifactId>
|
||||||
<version>2.11.0</version>
|
<version>2.8.1</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
<id>spotless-check</id>
|
||||||
|
<!-- runs in verify phase by default -->
|
||||||
<goals>
|
<goals>
|
||||||
<goal>${formatter-maven-plugin.goal}</goal>
|
<!-- can be disabled using -Dspotless.check.skip=true -->
|
||||||
|
<goal>check</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
|
||||||
<configFile>src/main/resources/eclipse/formatter.xml</configFile>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>net.revelc.code</groupId>
|
|
||||||
<artifactId>impsort-maven-plugin</artifactId>
|
|
||||||
<version>1.4.1</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<groups>*,java.,javax.</groups>
|
<java>
|
||||||
<removeUnused>true</removeUnused>
|
<eclipse>
|
||||||
<staticAfter>true</staticAfter>
|
<file>${basedir}/src/build/eclipse/formatter.xml</file>
|
||||||
|
</eclipse>
|
||||||
|
|
||||||
|
<importOrder>
|
||||||
|
<file>${basedir}/src/build/eclipse/eclipse.importorder</file>
|
||||||
|
</importOrder>
|
||||||
|
<removeUnusedImports />
|
||||||
|
|
||||||
|
<trimTrailingWhitespace />
|
||||||
|
<endWithNewline />
|
||||||
|
|
||||||
|
</java>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<goals>
|
|
||||||
<goal>${impsort-maven-plugin.goal}</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.github.spotbugs</groupId>
|
<groupId>com.github.spotbugs</groupId>
|
||||||
@@ -386,6 +387,12 @@
|
|||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>3.9</version>
|
<version>3.9</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.tngtech.archunit</groupId>
|
||||||
|
<artifactId>archunit</artifactId>
|
||||||
|
<version>0.16.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hamcrest</groupId>
|
<groupId>org.hamcrest</groupId>
|
||||||
<artifactId>hamcrest</artifactId>
|
<artifactId>hamcrest</artifactId>
|
||||||
@@ -408,13 +415,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.13</version>
|
<version>4.13.1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<version>2.10.2</version>
|
<version>2.12.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
@@ -445,7 +452,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.kohsuke.stapler</groupId>
|
<groupId>org.kohsuke.stapler</groupId>
|
||||||
<artifactId>stapler</artifactId>
|
<artifactId>stapler</artifactId>
|
||||||
<version>1.259</version>
|
<version>1.262</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -457,9 +464,27 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jgit</groupId>
|
<groupId>org.eclipse.jgit</groupId>
|
||||||
<artifactId>org.eclipse.jgit</artifactId>
|
<artifactId>org.eclipse.jgit</artifactId>
|
||||||
<version>5.7.0.202003110725-r</version>
|
<version>5.10.0.202012080955-r</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-api</artifactId>
|
||||||
|
<version>${jjwt.suite.version}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-impl</artifactId>
|
||||||
|
<version>${jjwt.suite.version}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-jackson</artifactId>
|
||||||
|
<version>${jjwt.suite.version}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.squareup.okio</groupId>
|
<groupId>com.squareup.okio</groupId>
|
||||||
<artifactId>okio</artifactId>
|
<artifactId>okio</artifactId>
|
||||||
@@ -495,7 +520,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-core</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
<version>3.3.3</version>
|
<version>3.7.7</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -507,7 +532,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.tomakehurst</groupId>
|
<groupId>com.github.tomakehurst</groupId>
|
||||||
<artifactId>wiremock-jre8-standalone</artifactId>
|
<artifactId>wiremock-jre8-standalone</artifactId>
|
||||||
<version>2.26.3</version>
|
<version>2.27.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -516,6 +541,12 @@
|
|||||||
<version>2.8.6</version>
|
<version>2.8.6</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-simple</artifactId>
|
||||||
|
<version>1.7.30</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
@@ -541,8 +572,8 @@
|
|||||||
</os>
|
</os>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<formatter-maven-plugin.goal>validate</formatter-maven-plugin.goal>
|
<!-- Only fail code coverage on non-windows machines -->
|
||||||
<impsort-maven-plugin.goal>check</impsort-maven-plugin.goal>
|
<jacoco.haltOnFailure>true</jacoco.haltOnFailure>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
@@ -552,24 +583,31 @@
|
|||||||
<name>enable-ci</name>
|
<name>enable-ci</name>
|
||||||
</property>
|
</property>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
|
||||||
<jacoco.haltOnFailure>true</jacoco.haltOnFailure>
|
|
||||||
</properties>
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.jacoco</groupId>
|
<groupId>org.jacoco</groupId>
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.diffplug.spotless</groupId>
|
||||||
|
<artifactId>spotless-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>spotless-check</id>
|
||||||
|
<!-- In CI, run check early in the build -->
|
||||||
|
<phase>process-sources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>release</id>
|
<id>release</id>
|
||||||
<properties>
|
|
||||||
<formatter-maven-plugin.goal>validate</formatter-maven-plugin.goal>
|
|
||||||
<impsort-maven-plugin.goal>check</impsort-maven-plugin.goal>
|
|
||||||
</properties>
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|||||||
6
src/build/eclipse/eclipse.importorder
Normal file
6
src/build/eclipse/eclipse.importorder
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#Organize Import Order
|
||||||
|
# Import this file in Window -> Preferences -> Java -> Code Style -> Organize Imports -> Import...
|
||||||
|
0=
|
||||||
|
1=java
|
||||||
|
2=javax
|
||||||
|
3=\#
|
||||||
@@ -12,14 +12,14 @@ import javax.annotation.Nonnull;
|
|||||||
* <p>
|
* <p>
|
||||||
* Batching looks like this:
|
* Batching looks like this:
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* update().someName(value).otherName(value).done()
|
* update().someName(value).otherName(value).done()
|
||||||
* </pre>
|
* </pre>
|
||||||
* <p>
|
* <p>
|
||||||
* Single changes look like this:
|
* Single changes look like this:
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* set().someName(value);
|
* set().someName(value);
|
||||||
* set().otherName(value);
|
* set().otherName(value);
|
||||||
@@ -38,7 +38,7 @@ import javax.annotation.Nonnull;
|
|||||||
* Intermediate return type for this builder returned by calls to {@link #with(String, Object)}. If {@link S}
|
* Intermediate return type for this builder returned by calls to {@link #with(String, Object)}. If {@link S}
|
||||||
* the same as {@link R}, this builder will commit changes after each call to {@link #with(String, Object)}.
|
* the same as {@link R}, this builder will commit changes after each call to {@link #with(String, Object)}.
|
||||||
*/
|
*/
|
||||||
abstract class AbstractBuilder<R, S> {
|
abstract class AbstractBuilder<R, S> extends GitHubInteractiveObject {
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private final Class<R> returnType;
|
private final Class<R> returnType;
|
||||||
@@ -75,6 +75,7 @@ abstract class AbstractBuilder<R, S> {
|
|||||||
@Nonnull Class<S> intermediateReturnType,
|
@Nonnull Class<S> intermediateReturnType,
|
||||||
@Nonnull GitHub root,
|
@Nonnull GitHub root,
|
||||||
@CheckForNull R baseInstance) {
|
@CheckForNull R baseInstance) {
|
||||||
|
super(root);
|
||||||
this.requester = root.createRequest();
|
this.requester = root.createRequest();
|
||||||
this.returnType = finalReturnType;
|
this.returnType = finalReturnType;
|
||||||
this.commitChangesImmediately = returnType.equals(intermediateReturnType);
|
this.commitChangesImmediately = returnType.equals(intermediateReturnType);
|
||||||
@@ -97,7 +98,7 @@ abstract class AbstractBuilder<R, S> {
|
|||||||
* if there is an I/O Exception
|
* if there is an I/O Exception
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public R done() throws IOException {
|
public R done() throws IOException {
|
||||||
R result;
|
R result;
|
||||||
@@ -127,7 +128,7 @@ abstract class AbstractBuilder<R, S> {
|
|||||||
* if an I/O error occurs
|
* if an I/O error occurs
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
protected S with(@Nonnull String name, Object value) throws IOException {
|
protected S with(@Nonnull String name, Object value) throws IOException {
|
||||||
requester.with(name, value);
|
requester.with(name, value);
|
||||||
@@ -148,7 +149,7 @@ abstract class AbstractBuilder<R, S> {
|
|||||||
* if an I/O error occurs
|
* if an I/O error occurs
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
protected S continueOrDone() throws IOException {
|
protected S continueOrDone() throws IOException {
|
||||||
// This little bit of roughness in this base class means all inheriting builders get to create Updater and
|
// This little bit of roughness in this base class means all inheriting builders get to create Updater and
|
||||||
|
|||||||
18
src/main/java/org/kohsuke/github/BetaApi.java
Normal file
18
src/main/java/org/kohsuke/github/BetaApi.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the method/class/etc marked is a beta implementation of an sdk feature.
|
||||||
|
* <p>
|
||||||
|
* These APIs are subject to change and not a part of the backward compatibility commitment. Always used in conjunction
|
||||||
|
* with 'deprecated' to raise awareness to clients.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface BetaApi {
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ import java.net.URL;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.MACHINE_MAN;
|
import static org.kohsuke.github.internal.Previews.MACHINE_MAN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Github App.
|
* A Github App.
|
||||||
@@ -15,7 +15,6 @@ import static org.kohsuke.github.Previews.MACHINE_MAN;
|
|||||||
*/
|
*/
|
||||||
public class GHApp extends GHObject {
|
public class GHApp extends GHObject {
|
||||||
|
|
||||||
private GitHub root;
|
|
||||||
private GHUser owner;
|
private GHUser owner;
|
||||||
private String name;
|
private String name;
|
||||||
private String description;
|
private String description;
|
||||||
@@ -189,7 +188,7 @@ public class GHApp extends GHObject {
|
|||||||
* @return a list of App installations
|
* @return a list of App installations
|
||||||
* @see <a href="https://developer.github.com/v3/apps/#list-installations">List installations</a>
|
* @see <a href="https://developer.github.com/v3/apps/#list-installations">List installations</a>
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(MACHINE_MAN)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public PagedIterable<GHAppInstallation> listInstallations() {
|
public PagedIterable<GHAppInstallation> listInstallations() {
|
||||||
return root.createRequest()
|
return root.createRequest()
|
||||||
@@ -210,7 +209,7 @@ public class GHApp extends GHObject {
|
|||||||
* on error
|
* on error
|
||||||
* @see <a href="https://developer.github.com/v3/apps/#get-an-installation">Get an installation</a>
|
* @see <a href="https://developer.github.com/v3/apps/#get-an-installation">Get an installation</a>
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(MACHINE_MAN)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHAppInstallation getInstallationById(long id) throws IOException {
|
public GHAppInstallation getInstallationById(long id) throws IOException {
|
||||||
return root.createRequest()
|
return root.createRequest()
|
||||||
@@ -233,7 +232,7 @@ public class GHApp extends GHObject {
|
|||||||
* @see <a href="https://developer.github.com/v3/apps/#get-an-organization-installation">Get an organization
|
* @see <a href="https://developer.github.com/v3/apps/#get-an-organization-installation">Get an organization
|
||||||
* installation</a>
|
* installation</a>
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(MACHINE_MAN)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHAppInstallation getInstallationByOrganization(String name) throws IOException {
|
public GHAppInstallation getInstallationByOrganization(String name) throws IOException {
|
||||||
return root.createRequest()
|
return root.createRequest()
|
||||||
@@ -258,7 +257,7 @@ public class GHApp extends GHObject {
|
|||||||
* @see <a href="https://developer.github.com/v3/apps/#get-a-repository-installation">Get a repository
|
* @see <a href="https://developer.github.com/v3/apps/#get-a-repository-installation">Get a repository
|
||||||
* installation</a>
|
* installation</a>
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(MACHINE_MAN)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHAppInstallation getInstallationByRepository(String ownerName, String repositoryName) throws IOException {
|
public GHAppInstallation getInstallationByRepository(String ownerName, String repositoryName) throws IOException {
|
||||||
return root.createRequest()
|
return root.createRequest()
|
||||||
@@ -280,7 +279,7 @@ public class GHApp extends GHObject {
|
|||||||
* on error
|
* on error
|
||||||
* @see <a href="https://developer.github.com/v3/apps/#get-a-user-installation">Get a user installation</a>
|
* @see <a href="https://developer.github.com/v3/apps/#get-a-user-installation">Get a user installation</a>
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(MACHINE_MAN)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHAppInstallation getInstallationByUser(String name) throws IOException {
|
public GHAppInstallation getInstallationByUser(String name) throws IOException {
|
||||||
return root.createRequest()
|
return root.createRequest()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.MACHINE_MAN;
|
import static org.kohsuke.github.internal.Previews.MACHINE_MAN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a access token for a GitHub App Installation
|
* Creates a access token for a GitHub App Installation
|
||||||
@@ -14,12 +14,11 @@ import static org.kohsuke.github.Previews.MACHINE_MAN;
|
|||||||
* @see GHAppInstallation#createToken(Map) GHAppInstallation#createToken(Map)
|
* @see GHAppInstallation#createToken(Map) GHAppInstallation#createToken(Map)
|
||||||
* @see GHAppInstallation#createToken() GHAppInstallation#createToken()
|
* @see GHAppInstallation#createToken() GHAppInstallation#createToken()
|
||||||
*/
|
*/
|
||||||
public class GHAppCreateTokenBuilder {
|
public class GHAppCreateTokenBuilder extends GitHubInteractiveObject {
|
||||||
private final GitHub root;
|
|
||||||
protected final Requester builder;
|
protected final Requester builder;
|
||||||
private final String apiUrlTail;
|
private final String apiUrlTail;
|
||||||
|
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
GHAppCreateTokenBuilder(GitHub root, String apiUrlTail) {
|
GHAppCreateTokenBuilder(GitHub root, String apiUrlTail) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
@@ -27,7 +26,7 @@ public class GHAppCreateTokenBuilder {
|
|||||||
this.builder = root.createRequest();
|
this.builder = root.createRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
GHAppCreateTokenBuilder(GitHub root, String apiUrlTail, Map<String, GHPermissionType> permissions) {
|
GHAppCreateTokenBuilder(GitHub root, String apiUrlTail, Map<String, GHPermissionType> permissions) {
|
||||||
this(root, apiUrlTail);
|
this(root, apiUrlTail);
|
||||||
@@ -43,7 +42,7 @@ public class GHAppCreateTokenBuilder {
|
|||||||
* Array containing the repositories Ids
|
* Array containing the repositories Ids
|
||||||
* @return a GHAppCreateTokenBuilder
|
* @return a GHAppCreateTokenBuilder
|
||||||
*/
|
*/
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHAppCreateTokenBuilder repositoryIds(List<Long> repositoryIds) {
|
public GHAppCreateTokenBuilder repositoryIds(List<Long> repositoryIds) {
|
||||||
this.builder.with("repository_ids", repositoryIds);
|
this.builder.with("repository_ids", repositoryIds);
|
||||||
@@ -58,7 +57,7 @@ public class GHAppCreateTokenBuilder {
|
|||||||
* Map containing the permission names and types.
|
* Map containing the permission names and types.
|
||||||
* @return a GHAppCreateTokenBuilder
|
* @return a GHAppCreateTokenBuilder
|
||||||
*/
|
*/
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHAppCreateTokenBuilder permissions(Map<String, GHPermissionType> permissions) {
|
public GHAppCreateTokenBuilder permissions(Map<String, GHPermissionType> permissions) {
|
||||||
Map<String, String> retMap = new HashMap<>();
|
Map<String, String> retMap = new HashMap<>();
|
||||||
@@ -78,7 +77,7 @@ public class GHAppCreateTokenBuilder {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* on error
|
* on error
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(MACHINE_MAN)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHAppInstallationToken create() throws IOException {
|
public GHAppInstallationToken create() throws IOException {
|
||||||
return builder.method("POST")
|
return builder.method("POST")
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ package org.kohsuke.github;
|
|||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.GAMBIT;
|
import static org.kohsuke.github.internal.Previews.GAMBIT;
|
||||||
|
import static org.kohsuke.github.internal.Previews.MACHINE_MAN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Github App Installation.
|
* A Github App Installation.
|
||||||
@@ -20,7 +22,6 @@ import static org.kohsuke.github.Previews.GAMBIT;
|
|||||||
* @see GHApp#getInstallationByUser(String) GHApp#getInstallationByUser(String)
|
* @see GHApp#getInstallationByUser(String) GHApp#getInstallationByUser(String)
|
||||||
*/
|
*/
|
||||||
public class GHAppInstallation extends GHObject {
|
public class GHAppInstallation extends GHObject {
|
||||||
private GitHub root;
|
|
||||||
private GHUser account;
|
private GHUser account;
|
||||||
|
|
||||||
@JsonProperty("access_tokens_url")
|
@JsonProperty("access_tokens_url")
|
||||||
@@ -117,6 +118,36 @@ public class GHAppInstallation extends GHObject {
|
|||||||
return repositoriesUrl;
|
return repositoriesUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List repositories that this app installation can access.
|
||||||
|
*
|
||||||
|
* @return the paged iterable
|
||||||
|
*/
|
||||||
|
@Preview(MACHINE_MAN)
|
||||||
|
@Deprecated
|
||||||
|
public PagedSearchIterable<GHRepository> listRepositories() {
|
||||||
|
GitHubRequest request;
|
||||||
|
|
||||||
|
try {
|
||||||
|
request = root.createRequest().withPreview(MACHINE_MAN).withUrlPath("/installation/repositories").build();
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
throw new GHException("", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PagedSearchIterable<>(root, request, GHAppInstallationRepositoryResult.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GHAppInstallationRepositoryResult extends SearchResult<GHRepository> {
|
||||||
|
private GHRepository[] repositories;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
GHRepository[] getItems(GitHub root) {
|
||||||
|
for (GHRepository item : repositories)
|
||||||
|
item.wrap(root);
|
||||||
|
return repositories;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets repositories url.
|
* Sets repositories url.
|
||||||
*
|
*
|
||||||
@@ -290,7 +321,7 @@ public class GHAppInstallation extends GHObject {
|
|||||||
* on error
|
* on error
|
||||||
* @see <a href="https://developer.github.com/v3/apps/#delete-an-installation">Delete an installation</a>
|
* @see <a href="https://developer.github.com/v3/apps/#delete-an-installation">Delete an installation</a>
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(GAMBIT)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void deleteInstallation() throws IOException {
|
public void deleteInstallation() throws IOException {
|
||||||
root.createRequest()
|
root.createRequest()
|
||||||
@@ -312,7 +343,7 @@ public class GHAppInstallation extends GHObject {
|
|||||||
* @return a GHAppCreateTokenBuilder instance
|
* @return a GHAppCreateTokenBuilder instance
|
||||||
* @deprecated Use {@link GHAppInstallation#createToken()} instead.
|
* @deprecated Use {@link GHAppInstallation#createToken()} instead.
|
||||||
*/
|
*/
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHAppCreateTokenBuilder createToken(Map<String, GHPermissionType> permissions) {
|
public GHAppCreateTokenBuilder createToken(Map<String, GHPermissionType> permissions) {
|
||||||
return new GHAppCreateTokenBuilder(root,
|
return new GHAppCreateTokenBuilder(root,
|
||||||
@@ -329,7 +360,7 @@ public class GHAppInstallation extends GHObject {
|
|||||||
*
|
*
|
||||||
* @return a GHAppCreateTokenBuilder instance
|
* @return a GHAppCreateTokenBuilder instance
|
||||||
*/
|
*/
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHAppCreateTokenBuilder createToken() {
|
public GHAppCreateTokenBuilder createToken() {
|
||||||
return new GHAppCreateTokenBuilder(root, String.format("/app/installations/%d/access_tokens", getId()));
|
return new GHAppCreateTokenBuilder(root, String.format("/app/installations/%d/access_tokens", getId()));
|
||||||
|
|||||||
@@ -14,9 +14,7 @@ import java.util.Map;
|
|||||||
* @author Paulo Miguel Almeida
|
* @author Paulo Miguel Almeida
|
||||||
* @see GHAppInstallation#createToken(Map) GHAppInstallation#createToken(Map)
|
* @see GHAppInstallation#createToken(Map) GHAppInstallation#createToken(Map)
|
||||||
*/
|
*/
|
||||||
public class GHAppInstallationToken {
|
public class GHAppInstallationToken extends GitHubInteractiveObject {
|
||||||
private GitHub root;
|
|
||||||
|
|
||||||
private String token;
|
private String token;
|
||||||
protected String expires_at;
|
protected String expires_at;
|
||||||
private Map<String, String> permissions;
|
private Map<String, String> permissions;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import java.net.URL;
|
|||||||
* @see GHRelease#getAssets() GHRelease#getAssets()
|
* @see GHRelease#getAssets() GHRelease#getAssets()
|
||||||
*/
|
*/
|
||||||
public class GHAsset extends GHObject {
|
public class GHAsset extends GHObject {
|
||||||
GitHub root;
|
|
||||||
GHRepository owner;
|
GHRepository owner;
|
||||||
private String name;
|
private String name;
|
||||||
private String label;
|
private String label;
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ public class GHAuthorization extends GHObject {
|
|||||||
public static final String WRITE_KEY = "write:public_key";
|
public static final String WRITE_KEY = "write:public_key";
|
||||||
public static final String ADMIN_KEY = "admin:public_key";
|
public static final String ADMIN_KEY = "admin:public_key";
|
||||||
|
|
||||||
private GitHub root;
|
|
||||||
private List<String> scopes;
|
private List<String> scopes;
|
||||||
private String token;
|
private String token;
|
||||||
private String token_last_eight;
|
private String token_last_eight;
|
||||||
|
|||||||
@@ -3,12 +3,15 @@ package org.kohsuke.github;
|
|||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
import org.kohsuke.github.internal.Previews;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import javax.annotation.CheckForNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A branch in a repository.
|
* A branch in a repository.
|
||||||
*
|
*
|
||||||
@@ -18,8 +21,7 @@ import java.util.Objects;
|
|||||||
value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
|
value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
|
||||||
"URF_UNREAD_FIELD" },
|
"URF_UNREAD_FIELD" },
|
||||||
justification = "JSON API")
|
justification = "JSON API")
|
||||||
public class GHBranch {
|
public class GHBranch extends GitHubInteractiveObject {
|
||||||
private GitHub root;
|
|
||||||
private GHRepository owner;
|
private GHRepository owner;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
@@ -76,7 +78,7 @@ public class GHBranch {
|
|||||||
*
|
*
|
||||||
* @return true if the push to this branch is restricted via branch protection.
|
* @return true if the push to this branch is restricted via branch protection.
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(Previews.LUKE_CAGE)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public boolean isProtected() {
|
public boolean isProtected() {
|
||||||
return protection;
|
return protection;
|
||||||
@@ -87,7 +89,7 @@ public class GHBranch {
|
|||||||
*
|
*
|
||||||
* @return API URL that deals with the protection of this branch.
|
* @return API URL that deals with the protection of this branch.
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(Previews.LUKE_CAGE)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public URL getProtectionUrl() {
|
public URL getProtectionUrl() {
|
||||||
return GitHubClient.parseURL(protection_url);
|
return GitHubClient.parseURL(protection_url);
|
||||||
@@ -100,8 +102,14 @@ public class GHBranch {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
|
@Preview(Previews.LUKE_CAGE)
|
||||||
|
@Deprecated
|
||||||
public GHBranchProtection getProtection() throws IOException {
|
public GHBranchProtection getProtection() throws IOException {
|
||||||
return root.createRequest().setRawUrlPath(protection_url).fetch(GHBranchProtection.class).wrap(this);
|
return root.createRequest()
|
||||||
|
.withPreview(Previews.LUKE_CAGE)
|
||||||
|
.setRawUrlPath(protection_url)
|
||||||
|
.fetch(GHBranchProtection.class)
|
||||||
|
.wrap(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -129,7 +137,7 @@ public class GHBranch {
|
|||||||
* @return GHBranchProtectionBuilder for enabling protection
|
* @return GHBranchProtectionBuilder for enabling protection
|
||||||
* @see GHCommitStatus#getContext() GHCommitStatus#getContext()
|
* @see GHCommitStatus#getContext() GHCommitStatus#getContext()
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(Previews.LUKE_CAGE)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHBranchProtectionBuilder enableProtection() {
|
public GHBranchProtectionBuilder enableProtection() {
|
||||||
return new GHBranchProtectionBuilder(this);
|
return new GHBranchProtectionBuilder(this);
|
||||||
@@ -161,6 +169,59 @@ public class GHBranch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge a branch into this branch.
|
||||||
|
*
|
||||||
|
* @param headBranch
|
||||||
|
* the branch whose head will be merged
|
||||||
|
*
|
||||||
|
* @param commitMessage
|
||||||
|
* the commit message
|
||||||
|
*
|
||||||
|
* @return the merge {@link GHCommit} created, or {@code null} if the base already contains the head (nothing to
|
||||||
|
* merge).
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* if merging fails
|
||||||
|
*/
|
||||||
|
@CheckForNull
|
||||||
|
public GHCommit merge(GHBranch headBranch, String commitMessage) throws IOException {
|
||||||
|
return merge(headBranch.getName(), commitMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge a ref into this branch.
|
||||||
|
*
|
||||||
|
* @param head
|
||||||
|
* the ref name that will be merged into this branch. Follows the usual ref naming rules, could be a
|
||||||
|
* branch name, tag, or commit sha.
|
||||||
|
*
|
||||||
|
* @param commitMessage
|
||||||
|
* the commit message
|
||||||
|
*
|
||||||
|
* @return the merge {@link GHCommit} created, or {@code null} if the base already contains the head (nothing to
|
||||||
|
* merge).
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* if merging fails
|
||||||
|
*/
|
||||||
|
@CheckForNull
|
||||||
|
public GHCommit merge(String head, String commitMessage) throws IOException {
|
||||||
|
GHCommit result = root.createRequest()
|
||||||
|
.withUrlPath(owner.getApiTailUrl("merges"))
|
||||||
|
.method("POST")
|
||||||
|
.with("commit_message", commitMessage)
|
||||||
|
.with("base", this.name)
|
||||||
|
.with("head", head)
|
||||||
|
.fetch(GHCommit.class);
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
result.wrapUp(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
String getApiRoute() {
|
String getApiRoute() {
|
||||||
return owner.getApiTailUrl("/branches/" + name);
|
return owner.getApiTailUrl("/branches/" + name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,23 +6,23 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.ZZZAX;
|
import static org.kohsuke.github.internal.Previews.ZZZAX;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type GHBranchProtection.
|
* The type GHBranchProtection.
|
||||||
|
*
|
||||||
|
* @see <a href="https://docs.github.com/en/rest/reference/repos#get-branch-protection">GitHub Branch Protection</a>
|
||||||
*/
|
*/
|
||||||
@SuppressFBWarnings(
|
@SuppressFBWarnings(
|
||||||
value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
|
value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
|
||||||
"URF_UNREAD_FIELD" },
|
"URF_UNREAD_FIELD" },
|
||||||
justification = "JSON API")
|
justification = "JSON API")
|
||||||
public class GHBranchProtection {
|
public class GHBranchProtection extends GitHubInteractiveObject {
|
||||||
private static final String REQUIRE_SIGNATURES_URI = "/required_signatures";
|
private static final String REQUIRE_SIGNATURES_URI = "/required_signatures";
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private EnforceAdmins enforceAdmins;
|
private EnforceAdmins enforceAdmins;
|
||||||
|
|
||||||
private GitHub root;
|
|
||||||
|
|
||||||
@JsonProperty("required_pull_request_reviews")
|
@JsonProperty("required_pull_request_reviews")
|
||||||
private RequiredReviews requiredReviews;
|
private RequiredReviews requiredReviews;
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ public class GHBranchProtection {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(ZZZAX)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void enabledSignedCommits() throws IOException {
|
public void enabledSignedCommits() throws IOException {
|
||||||
requester().method("POST").withUrlPath(url + REQUIRE_SIGNATURES_URI).fetch(RequiredSignatures.class);
|
requester().method("POST").withUrlPath(url + REQUIRE_SIGNATURES_URI).fetch(RequiredSignatures.class);
|
||||||
@@ -53,7 +53,7 @@ public class GHBranchProtection {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(ZZZAX)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void disableSignedCommits() throws IOException {
|
public void disableSignedCommits() throws IOException {
|
||||||
requester().method("DELETE").withUrlPath(url + REQUIRE_SIGNATURES_URI).send();
|
requester().method("DELETE").withUrlPath(url + REQUIRE_SIGNATURES_URI).send();
|
||||||
@@ -84,7 +84,7 @@ public class GHBranchProtection {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(ZZZAX)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public boolean getRequiredSignatures() throws IOException {
|
public boolean getRequiredSignatures() throws IOException {
|
||||||
return requester().withUrlPath(url + REQUIRE_SIGNATURES_URI).fetch(RequiredSignatures.class).enabled;
|
return requester().withUrlPath(url + REQUIRE_SIGNATURES_URI).fetch(RequiredSignatures.class).enabled;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.*;
|
import static org.kohsuke.github.internal.Previews.LUKE_CAGE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder to configure the branch protection settings.
|
* Builder to configure the branch protection settings.
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
import org.kohsuke.github.internal.Previews;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a check run.
|
* Represents a check run.
|
||||||
@@ -14,8 +20,9 @@ import java.util.Date;
|
|||||||
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD", "URF_UNREAD_FIELD" },
|
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD", "URF_UNREAD_FIELD" },
|
||||||
justification = "JSON API")
|
justification = "JSON API")
|
||||||
public class GHCheckRun extends GHObject {
|
public class GHCheckRun extends GHObject {
|
||||||
|
|
||||||
|
@JsonProperty("repository")
|
||||||
GHRepository owner;
|
GHRepository owner;
|
||||||
GitHub root;
|
|
||||||
|
|
||||||
private String status;
|
private String status;
|
||||||
private String conclusion;
|
private String conclusion;
|
||||||
@@ -34,7 +41,7 @@ public class GHCheckRun extends GHObject {
|
|||||||
|
|
||||||
GHCheckRun wrap(GHRepository owner) {
|
GHCheckRun wrap(GHRepository owner) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.root = owner.root;
|
wrap(owner.root);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +49,24 @@ public class GHCheckRun extends GHObject {
|
|||||||
this.root = root;
|
this.root = root;
|
||||||
if (owner != null) {
|
if (owner != null) {
|
||||||
owner.wrap(root);
|
owner.wrap(root);
|
||||||
|
if (pullRequests != null && pullRequests.length != 0) {
|
||||||
|
for (GHPullRequest singlePull : pullRequests) {
|
||||||
|
singlePull.wrap(owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if (checkSuite != null) {
|
||||||
|
if (owner != null) {
|
||||||
|
checkSuite.wrap(owner);
|
||||||
|
} else {
|
||||||
|
checkSuite.wrap(root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (app != null) {
|
||||||
|
app.wrapUp(root);
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,8 +98,14 @@ public class GHCheckRun extends GHObject {
|
|||||||
return conclusion;
|
return conclusion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Final conclusion of the check.
|
||||||
|
*
|
||||||
|
* From <a href="https://docs.github.com/en/rest/reference/checks#create-a-check-run--parameters">Check Run
|
||||||
|
* Parameters - <code>conclusion</code></a>.
|
||||||
|
*/
|
||||||
public static enum Conclusion {
|
public static enum Conclusion {
|
||||||
SUCCESS, FAILURE, NEUTRAL, CANCELLED, TIMED_OUT, ACTION_REQUIRED
|
SUCCESS, FAILURE, NEUTRAL, CANCELLED, TIMED_OUT, ACTION_REQUIRED, SKIPPED
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,15 +129,22 @@ public class GHCheckRun extends GHObject {
|
|||||||
/**
|
/**
|
||||||
* Gets the pull requests participated in this check run.
|
* Gets the pull requests participated in this check run.
|
||||||
*
|
*
|
||||||
* @return Pull requests of this check run
|
* Note this field is only populated for events. When getting a {@link GHCheckRun} outside of an event, this is
|
||||||
|
* always empty.
|
||||||
|
*
|
||||||
|
* @return the list of {@link GHPullRequest}s for this check run. Only populated for events.
|
||||||
|
* @throws IOException
|
||||||
|
* the io exception
|
||||||
*/
|
*/
|
||||||
GHPullRequest[] getPullRequests() throws IOException {
|
public List<GHPullRequest> getPullRequests() throws IOException {
|
||||||
if (pullRequests != null && pullRequests.length != 0) {
|
if (pullRequests != null && pullRequests.length != 0) {
|
||||||
for (GHPullRequest singlePull : pullRequests) {
|
for (GHPullRequest singlePull : pullRequests) {
|
||||||
singlePull.refresh();
|
// Only refresh if we haven't do so before
|
||||||
|
singlePull.refresh(singlePull.getTitle());
|
||||||
}
|
}
|
||||||
|
return Collections.unmodifiableList(Arrays.asList(pullRequests));
|
||||||
}
|
}
|
||||||
return pullRequests;
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -256,4 +293,15 @@ public class GHCheckRun extends GHObject {
|
|||||||
NOTICE, WARNING, FAILURE
|
NOTICE, WARNING, FAILURE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates this check run.
|
||||||
|
*
|
||||||
|
* @return a builder which you should customize, then call {@link GHCheckRunBuilder#create}
|
||||||
|
*/
|
||||||
|
@Preview(Previews.ANTIOPE)
|
||||||
|
@Deprecated
|
||||||
|
public @NonNull GHCheckRunBuilder update() {
|
||||||
|
return new GHCheckRunBuilder(owner, getId());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
|
|||||||
import edu.umd.cs.findbugs.annotations.CheckForNull;
|
import edu.umd.cs.findbugs.annotations.CheckForNull;
|
||||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
import org.kohsuke.github.internal.Previews;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -37,30 +38,45 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drafts a check run.
|
* Drafts or updates a check run.
|
||||||
*
|
*
|
||||||
* @see GHCheckRun
|
* @see GHCheckRun
|
||||||
* @see GHRepository#createCheckRun
|
* @see GHRepository#createCheckRun
|
||||||
* @see <a href="https://developer.github.com/v3/checks/runs/#create-a-check-run">documentation</a>
|
* @see <a href="https://developer.github.com/v3/checks/runs/#create-a-check-run">documentation</a>
|
||||||
|
* @see GHCheckRun#update()
|
||||||
|
* @see <a href="https://developer.github.com/v3/checks/runs/#update-a-check-run">documentation</a>
|
||||||
*/
|
*/
|
||||||
@SuppressFBWarnings(value = "URF_UNREAD_FIELD", justification = "Jackson serializes these even without a getter")
|
@SuppressFBWarnings(value = "URF_UNREAD_FIELD", justification = "Jackson serializes these even without a getter")
|
||||||
@Preview
|
@Preview(Previews.ANTIOPE)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public final class GHCheckRunBuilder {
|
public final class GHCheckRunBuilder {
|
||||||
|
|
||||||
private final GHRepository repo;
|
protected final GHRepository repo;
|
||||||
private final Requester requester;
|
protected final Requester requester;
|
||||||
private Output output;
|
private Output output;
|
||||||
private List<Action> actions;
|
private List<Action> actions;
|
||||||
|
|
||||||
GHCheckRunBuilder(GHRepository repo, String name, String headSHA) {
|
private GHCheckRunBuilder(GHRepository repo, Requester requester) {
|
||||||
this.repo = repo;
|
this.repo = repo;
|
||||||
requester = repo.root.createRequest()
|
this.requester = requester;
|
||||||
.withPreview(Previews.ANTIOPE)
|
}
|
||||||
.method("POST")
|
|
||||||
.with("name", name)
|
GHCheckRunBuilder(GHRepository repo, String name, String headSHA) {
|
||||||
.with("head_sha", headSHA)
|
this(repo,
|
||||||
.withUrlPath(repo.getApiTailUrl("check-runs"));
|
repo.root.createRequest()
|
||||||
|
.withPreview(Previews.ANTIOPE)
|
||||||
|
.method("POST")
|
||||||
|
.with("name", name)
|
||||||
|
.with("head_sha", headSHA)
|
||||||
|
.withUrlPath(repo.getApiTailUrl("check-runs")));
|
||||||
|
}
|
||||||
|
|
||||||
|
GHCheckRunBuilder(GHRepository repo, long checkId) {
|
||||||
|
this(repo,
|
||||||
|
repo.root.createRequest()
|
||||||
|
.withPreview(Previews.ANTIOPE)
|
||||||
|
.method("PATCH")
|
||||||
|
.withUrlPath(repo.getApiTailUrl("check-runs/" + checkId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NonNull GHCheckRunBuilder withDetailsURL(@CheckForNull String detailsURL) {
|
public @NonNull GHCheckRunBuilder withDetailsURL(@CheckForNull String detailsURL) {
|
||||||
@@ -136,7 +152,7 @@ public final class GHCheckRunBuilder {
|
|||||||
}
|
}
|
||||||
GHCheckRun run = requester.with("output", output).with("actions", actions).fetch(GHCheckRun.class).wrap(repo);
|
GHCheckRun run = requester.with("output", output).with("actions", actions).fetch(GHCheckRun.class).wrap(repo);
|
||||||
while (!extraAnnotations.isEmpty()) {
|
while (!extraAnnotations.isEmpty()) {
|
||||||
Output output2 = new Output(output.title, output.summary);
|
Output output2 = new Output(output.title, output.summary).withText(output.text);
|
||||||
int i = Math.min(extraAnnotations.size(), MAX_ANNOTATIONS);
|
int i = Math.min(extraAnnotations.size(), MAX_ANNOTATIONS);
|
||||||
output2.annotations = extraAnnotations.subList(0, i);
|
output2.annotations = extraAnnotations.subList(0, i);
|
||||||
extraAnnotations = extraAnnotations.subList(i, extraAnnotations.size());
|
extraAnnotations = extraAnnotations.subList(i, extraAnnotations.size());
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import javax.annotation.Nonnull;
|
|||||||
* Iterable for check-runs listing.
|
* Iterable for check-runs listing.
|
||||||
*/
|
*/
|
||||||
class GHCheckRunsIterable extends PagedIterable<GHCheckRun> {
|
class GHCheckRunsIterable extends PagedIterable<GHCheckRun> {
|
||||||
private GitHub root;
|
private final transient GitHub root;
|
||||||
private final GitHubRequest request;
|
private final GitHubRequest request;
|
||||||
|
|
||||||
private GHCheckRunsPage result;
|
private GHCheckRunsPage result;
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a check suite.
|
* Represents a check suite.
|
||||||
@@ -14,8 +18,9 @@ import java.util.Date;
|
|||||||
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD", "URF_UNREAD_FIELD" },
|
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD", "URF_UNREAD_FIELD" },
|
||||||
justification = "JSON API")
|
justification = "JSON API")
|
||||||
public class GHCheckSuite extends GHObject {
|
public class GHCheckSuite extends GHObject {
|
||||||
|
|
||||||
|
@JsonProperty("repository")
|
||||||
GHRepository owner;
|
GHRepository owner;
|
||||||
GitHub root;
|
|
||||||
|
|
||||||
private String nodeId;
|
private String nodeId;
|
||||||
private String headBranch;
|
private String headBranch;
|
||||||
@@ -32,7 +37,7 @@ public class GHCheckSuite extends GHObject {
|
|||||||
|
|
||||||
GHCheckSuite wrap(GHRepository owner) {
|
GHCheckSuite wrap(GHRepository owner) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.root = owner.root;
|
this.wrap(owner.root);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,6 +45,14 @@ public class GHCheckSuite extends GHObject {
|
|||||||
this.root = root;
|
this.root = root;
|
||||||
if (owner != null) {
|
if (owner != null) {
|
||||||
owner.wrap(root);
|
owner.wrap(root);
|
||||||
|
if (pullRequests != null && pullRequests.length != 0) {
|
||||||
|
for (GHPullRequest singlePull : pullRequests) {
|
||||||
|
singlePull.wrap(owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (app != null) {
|
||||||
|
app.wrapUp(root);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -153,15 +166,22 @@ public class GHCheckSuite extends GHObject {
|
|||||||
/**
|
/**
|
||||||
* Gets the pull requests participated in this check suite.
|
* Gets the pull requests participated in this check suite.
|
||||||
*
|
*
|
||||||
* @return Pull requests
|
* Note this field is only populated for events. When getting a {@link GHCheckSuite} outside of an event, this is
|
||||||
|
* always empty.
|
||||||
|
*
|
||||||
|
* @return the list of {@link GHPullRequest}s for this check suite. Only populated for events.
|
||||||
|
* @throws IOException
|
||||||
|
* the io exception
|
||||||
*/
|
*/
|
||||||
GHPullRequest[] getPullRequests() throws IOException {
|
public List<GHPullRequest> getPullRequests() throws IOException {
|
||||||
if (pullRequests != null && pullRequests.length != 0) {
|
if (pullRequests != null && pullRequests.length != 0) {
|
||||||
for (GHPullRequest singlePull : pullRequests) {
|
for (GHPullRequest singlePull : pullRequests) {
|
||||||
singlePull.refresh();
|
// Only refresh if we haven't do so before
|
||||||
|
singlePull.refresh(singlePull.getTitle());
|
||||||
}
|
}
|
||||||
|
return Collections.unmodifiableList(Arrays.asList(pullRequests));
|
||||||
}
|
}
|
||||||
return pullRequests;
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ import java.util.Collections;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.kohsuke.github.internal.Previews.ANTIOPE;
|
||||||
|
import static org.kohsuke.github.internal.Previews.GROOT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A commit in a repository.
|
* A commit in a repository.
|
||||||
*
|
*
|
||||||
@@ -63,7 +66,7 @@ public class GHCommit {
|
|||||||
* @return the authored date
|
* @return the authored date
|
||||||
*/
|
*/
|
||||||
public Date getAuthoredDate() {
|
public Date getAuthoredDate() {
|
||||||
return GitHubClient.parseDate(author.date);
|
return author.getDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,7 +85,7 @@ public class GHCommit {
|
|||||||
* @return the commit date
|
* @return the commit date
|
||||||
*/
|
*/
|
||||||
public Date getCommitDate() {
|
public Date getCommitDate() {
|
||||||
return GitHubClient.parseDate(committer.date);
|
return committer.getDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -119,7 +122,6 @@ public class GHCommit {
|
|||||||
* @deprecated Use {@link GitUser} instead.
|
* @deprecated Use {@link GitUser} instead.
|
||||||
*/
|
*/
|
||||||
public static class GHAuthor extends GitUser {
|
public static class GHAuthor extends GitUser {
|
||||||
private String date;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -446,6 +448,39 @@ public class GHCommit {
|
|||||||
return owner.root.getUser(author.login);
|
return owner.root.getUser(author.login);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a list of pull requests which contain this commit.
|
||||||
|
*
|
||||||
|
* @return {@link PagedIterable} with the pull requests which contain this commit
|
||||||
|
*/
|
||||||
|
@Preview(GROOT)
|
||||||
|
@Deprecated
|
||||||
|
public PagedIterable<GHPullRequest> listPullRequests() {
|
||||||
|
return owner.root.createRequest()
|
||||||
|
.withPreview(GROOT)
|
||||||
|
.withUrlPath(String.format("/repos/%s/%s/commits/%s/pulls", owner.getOwnerName(), owner.getName(), sha))
|
||||||
|
.toIterable(GHPullRequest[].class, item -> item.wrapUp(owner));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a list of branches where this commit is the head commit.
|
||||||
|
*
|
||||||
|
* @return {@link PagedIterable} with the branches where the commit is the head commit
|
||||||
|
* @throws IOException
|
||||||
|
* the io exception
|
||||||
|
*/
|
||||||
|
@Preview(GROOT)
|
||||||
|
@Deprecated
|
||||||
|
public PagedIterable<GHBranch> listBranchesWhereHead() throws IOException {
|
||||||
|
return owner.root.createRequest()
|
||||||
|
.withPreview(GROOT)
|
||||||
|
.withUrlPath(String.format("/repos/%s/%s/commits/%s/branches-where-head",
|
||||||
|
owner.getOwnerName(),
|
||||||
|
owner.getName(),
|
||||||
|
sha))
|
||||||
|
.toIterable(GHBranch[].class, item -> item.wrap(owner));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List comments paged iterable.
|
* List comments paged iterable.
|
||||||
*
|
*
|
||||||
@@ -530,7 +565,7 @@ public class GHCommit {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* on error
|
* on error
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(ANTIOPE)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public PagedIterable<GHCheckRun> getCheckRuns() throws IOException {
|
public PagedIterable<GHCheckRun> getCheckRuns() throws IOException {
|
||||||
return owner.getCheckRuns(sha);
|
return owner.getCheckRuns(sha);
|
||||||
@@ -538,7 +573,7 @@ public class GHCommit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Some of the fields are not always filled in when this object is retrieved as a part of another API call.
|
* Some of the fields are not always filled in when this object is retrieved as a part of another API call.
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* on error
|
* on error
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -89,6 +89,19 @@ public class GHCommitBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the PGP signature of this commit.
|
||||||
|
*
|
||||||
|
* @param signature
|
||||||
|
* the signature calculated from the commit
|
||||||
|
*
|
||||||
|
* @return the gh commit builder
|
||||||
|
*/
|
||||||
|
public GHCommitBuilder withSignature(String signature) {
|
||||||
|
req.with("signature", signature);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the committer of this commit.
|
* Configures the committer of this commit.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.*;
|
import static org.kohsuke.github.internal.Previews.SQUIRREL_GIRL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A comment attached to a commit (or a specific line in a specific file of a commit.)
|
* A comment attached to a commit (or a specific line in a specific file of a commit.)
|
||||||
@@ -121,7 +121,7 @@ public class GHCommitComment extends GHObject implements Reactable {
|
|||||||
this.body = body;
|
this.body = body;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview(SQUIRREL_GIRL)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHReaction createReaction(ReactionContent content) throws IOException {
|
public GHReaction createReaction(ReactionContent content) throws IOException {
|
||||||
return owner.root.createRequest()
|
return owner.root.createRequest()
|
||||||
@@ -133,7 +133,7 @@ public class GHCommitComment extends GHObject implements Reactable {
|
|||||||
.wrap(owner.root);
|
.wrap(owner.root);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview(SQUIRREL_GIRL)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public PagedIterable<GHReaction> listReactions() {
|
public PagedIterable<GHReaction> listReactions() {
|
||||||
return owner.root.createRequest()
|
return owner.root.createRequest()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.kohsuke.github.internal.Previews;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@@ -10,7 +11,7 @@ import java.io.IOException;
|
|||||||
* @author Marc de Verdelhan
|
* @author Marc de Verdelhan
|
||||||
* @see GitHub#searchCommits() GitHub#searchCommits()
|
* @see GitHub#searchCommits() GitHub#searchCommits()
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(Previews.CLOAK)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public class GHCommitSearchBuilder extends GHSearchBuilder<GHCommit> {
|
public class GHCommitSearchBuilder extends GHSearchBuilder<GHCommit> {
|
||||||
GHCommitSearchBuilder(GitHub root) {
|
GHCommitSearchBuilder(GitHub root) {
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ public class GHCommitStatus extends GHObject {
|
|||||||
String context;
|
String context;
|
||||||
GHUser creator;
|
GHUser creator;
|
||||||
|
|
||||||
private GitHub root;
|
|
||||||
|
|
||||||
GHCommitStatus wrapUp(GitHub root) {
|
GHCommitStatus wrapUp(GitHub root) {
|
||||||
if (creator != null)
|
if (creator != null)
|
||||||
creator.wrapUp(root);
|
creator.wrapUp(root);
|
||||||
|
|||||||
@@ -15,21 +15,20 @@ import java.util.Base64;
|
|||||||
* @see GHRepository#getFileContent(String) GHRepository#getFileContent(String)
|
* @see GHRepository#getFileContent(String) GHRepository#getFileContent(String)
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "UnusedDeclaration" })
|
@SuppressWarnings({ "UnusedDeclaration" })
|
||||||
public class GHContent implements Refreshable {
|
public class GHContent extends GitHubInteractiveObject implements Refreshable {
|
||||||
/*
|
/*
|
||||||
* In normal use of this class, repository field is set via wrap(), but in the code search API, there's a nested
|
* In normal use of this class, repository field is set via wrap(), but in the code search API, there's a nested
|
||||||
* 'repository' field that gets populated from JSON.
|
* 'repository' field that gets populated from JSON.
|
||||||
*/
|
*/
|
||||||
private GHRepository repository;
|
private GHRepository repository;
|
||||||
|
|
||||||
private GitHub root;
|
|
||||||
|
|
||||||
private String type;
|
private String type;
|
||||||
private String encoding;
|
private String encoding;
|
||||||
private long size;
|
private long size;
|
||||||
private String sha;
|
private String sha;
|
||||||
private String name;
|
private String name;
|
||||||
private String path;
|
private String path;
|
||||||
|
private String target;
|
||||||
private String content;
|
private String content;
|
||||||
private String url; // this is the API url
|
private String url; // this is the API url
|
||||||
private String git_url; // this is the Blob url
|
private String git_url; // this is the Blob url
|
||||||
@@ -99,6 +98,15 @@ public class GHContent implements Refreshable {
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets target of a symlink. This will only be set if {@code "symlink".equals(getType())}
|
||||||
|
*
|
||||||
|
* @return the target
|
||||||
|
*/
|
||||||
|
public String getTarget() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the decoded content that is stored at this location.
|
* Retrieve the decoded content that is stored at this location.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,166 +1,25 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
|
||||||
|
import static org.kohsuke.github.internal.Previews.BAPTISTE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a repository
|
* Creates a repository
|
||||||
*
|
*
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
public class GHCreateRepositoryBuilder {
|
public class GHCreateRepositoryBuilder extends GHRepositoryBuilder<GHCreateRepositoryBuilder> {
|
||||||
private final GitHub root;
|
|
||||||
protected final Requester builder;
|
|
||||||
private final String apiUrlTail;
|
|
||||||
|
|
||||||
GHCreateRepositoryBuilder(GitHub root, String apiUrlTail, String name) {
|
public GHCreateRepositoryBuilder(String name, GitHub root, String apiTail) {
|
||||||
this.root = root;
|
super(GHCreateRepositoryBuilder.class, root, null);
|
||||||
this.apiUrlTail = apiUrlTail;
|
requester.method("POST").withUrlPath(apiTail);
|
||||||
this.builder = root.createRequest();
|
|
||||||
this.builder.with("name", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
try {
|
||||||
* Description for repository
|
name(name);
|
||||||
*
|
} catch (IOException e) {
|
||||||
* @param description
|
// not going to happen here
|
||||||
* description of repository
|
}
|
||||||
* @return a builder to continue with building
|
|
||||||
*/
|
|
||||||
public GHCreateRepositoryBuilder description(String description) {
|
|
||||||
this.builder.with("description", description);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Homepage for repository
|
|
||||||
*
|
|
||||||
* @param homepage
|
|
||||||
* homepage of repository
|
|
||||||
* @return a builder to continue with building
|
|
||||||
*/
|
|
||||||
public GHCreateRepositoryBuilder homepage(URL homepage) {
|
|
||||||
return homepage(homepage.toExternalForm());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Homepage for repository
|
|
||||||
*
|
|
||||||
* @param homepage
|
|
||||||
* homepage of repository
|
|
||||||
* @return a builder to continue with building
|
|
||||||
*/
|
|
||||||
public GHCreateRepositoryBuilder homepage(String homepage) {
|
|
||||||
this.builder.with("homepage", homepage);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a private repository
|
|
||||||
*
|
|
||||||
* @param enabled
|
|
||||||
* private if true
|
|
||||||
* @return a builder to continue with building
|
|
||||||
*/
|
|
||||||
public GHCreateRepositoryBuilder private_(boolean enabled) {
|
|
||||||
this.builder.with("private", enabled);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables issue tracker
|
|
||||||
*
|
|
||||||
* @param enabled
|
|
||||||
* true if enabled
|
|
||||||
* @return a builder to continue with building
|
|
||||||
*/
|
|
||||||
public GHCreateRepositoryBuilder issues(boolean enabled) {
|
|
||||||
this.builder.with("has_issues", enabled);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables projects
|
|
||||||
*
|
|
||||||
* @param enabled
|
|
||||||
* true if enabled
|
|
||||||
* @return a builder to continue with building
|
|
||||||
*/
|
|
||||||
public GHCreateRepositoryBuilder projects(boolean enabled) {
|
|
||||||
this.builder.with("has_projects", enabled);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables wiki
|
|
||||||
*
|
|
||||||
* @param enabled
|
|
||||||
* true if enabled
|
|
||||||
* @return a builder to continue with building
|
|
||||||
*/
|
|
||||||
public GHCreateRepositoryBuilder wiki(boolean enabled) {
|
|
||||||
this.builder.with("has_wiki", enabled);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables downloads
|
|
||||||
*
|
|
||||||
* @param enabled
|
|
||||||
* true if enabled
|
|
||||||
* @return a builder to continue with building
|
|
||||||
*/
|
|
||||||
public GHCreateRepositoryBuilder downloads(boolean enabled) {
|
|
||||||
this.builder.with("has_downloads", enabled);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If true, create an initial commit with empty README.
|
|
||||||
*
|
|
||||||
* @param enabled
|
|
||||||
* true if enabled
|
|
||||||
* @return a builder to continue with building
|
|
||||||
*/
|
|
||||||
public GHCreateRepositoryBuilder autoInit(boolean enabled) {
|
|
||||||
this.builder.with("auto_init", enabled);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allow or disallow squash-merging pull requests.
|
|
||||||
*
|
|
||||||
* @param enabled
|
|
||||||
* true if enabled
|
|
||||||
* @return a builder to continue with building
|
|
||||||
*/
|
|
||||||
public GHCreateRepositoryBuilder allowSquashMerge(boolean enabled) {
|
|
||||||
this.builder.with("allow_squash_merge", enabled);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allow or disallow merging pull requests with a merge commit.
|
|
||||||
*
|
|
||||||
* @param enabled
|
|
||||||
* true if enabled
|
|
||||||
* @return a builder to continue with building
|
|
||||||
*/
|
|
||||||
public GHCreateRepositoryBuilder allowMergeCommit(boolean enabled) {
|
|
||||||
this.builder.with("allow_merge_commit", enabled);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allow or disallow rebase-merging pull requests.
|
|
||||||
*
|
|
||||||
* @param enabled
|
|
||||||
* true if enabled
|
|
||||||
* @return a builder to continue with building
|
|
||||||
*/
|
|
||||||
public GHCreateRepositoryBuilder allowRebaseMerge(boolean enabled) {
|
|
||||||
this.builder.with("allow_rebase_merge", enabled);
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,10 +28,11 @@ public class GHCreateRepositoryBuilder {
|
|||||||
* @param language
|
* @param language
|
||||||
* template to base the ignore file on
|
* template to base the ignore file on
|
||||||
* @return a builder to continue with building See https://developer.github.com/v3/repos/#create
|
* @return a builder to continue with building See https://developer.github.com/v3/repos/#create
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
*/
|
*/
|
||||||
public GHCreateRepositoryBuilder gitignoreTemplate(String language) {
|
public GHCreateRepositoryBuilder gitignoreTemplate(String language) throws IOException {
|
||||||
this.builder.with("gitignore_template", language);
|
return with("gitignore_template", language);
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -181,10 +41,24 @@ public class GHCreateRepositoryBuilder {
|
|||||||
* @param license
|
* @param license
|
||||||
* template to base the license file on
|
* template to base the license file on
|
||||||
* @return a builder to continue with building See https://developer.github.com/v3/repos/#create
|
* @return a builder to continue with building See https://developer.github.com/v3/repos/#create
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
*/
|
*/
|
||||||
public GHCreateRepositoryBuilder licenseTemplate(String license) {
|
public GHCreateRepositoryBuilder licenseTemplate(String license) throws IOException {
|
||||||
this.builder.with("license_template", license);
|
return with("license_template", license);
|
||||||
return this;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If true, create an initial commit with empty README.
|
||||||
|
*
|
||||||
|
* @param enabled
|
||||||
|
* true if enabled
|
||||||
|
* @return a builder to continue with building
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
public GHCreateRepositoryBuilder autoInit(boolean enabled) throws IOException {
|
||||||
|
return with("auto_init", enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -193,10 +67,57 @@ public class GHCreateRepositoryBuilder {
|
|||||||
* @param team
|
* @param team
|
||||||
* team to grant access to
|
* team to grant access to
|
||||||
* @return a builder to continue with building
|
* @return a builder to continue with building
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
*/
|
*/
|
||||||
public GHCreateRepositoryBuilder team(GHTeam team) {
|
public GHCreateRepositoryBuilder team(GHTeam team) throws IOException {
|
||||||
if (team != null)
|
if (team != null)
|
||||||
this.builder.with("team_id", team.getId());
|
return with("team_id", team.getId());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether the repository is a template.
|
||||||
|
*
|
||||||
|
* @param enabled
|
||||||
|
* true if enabled
|
||||||
|
* @return a builder to continue with building
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
* @deprecated Use {@link #isTemplate(boolean)} method instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public GHCreateRepositoryBuilder templateRepository(boolean enabled) throws IOException {
|
||||||
|
return isTemplate(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the ownership of the repository.
|
||||||
|
*
|
||||||
|
* @param owner
|
||||||
|
* organization or personage
|
||||||
|
* @return a builder to continue with building
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
public GHCreateRepositoryBuilder owner(String owner) throws IOException {
|
||||||
|
return with("owner", owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create repository from template repository
|
||||||
|
*
|
||||||
|
* @param templateOwner
|
||||||
|
* template repository owner
|
||||||
|
* @param templateRepo
|
||||||
|
* template repository
|
||||||
|
* @return a builder to continue with building
|
||||||
|
* @see <a href="https://developer.github.com/v3/previews/">GitHub API Previews</a>
|
||||||
|
*/
|
||||||
|
@Preview(BAPTISTE)
|
||||||
|
@Deprecated
|
||||||
|
public GHCreateRepositoryBuilder fromTemplateRepository(String templateOwner, String templateRepo) {
|
||||||
|
requester.withPreview(BAPTISTE).withUrlPath("/repos/" + templateOwner + "/" + templateRepo + "/generate");
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,10 +126,9 @@ public class GHCreateRepositoryBuilder {
|
|||||||
*
|
*
|
||||||
* @return the gh repository
|
* @return the gh repository
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if repsitory cannot be created
|
* if repository cannot be created
|
||||||
*/
|
*/
|
||||||
public GHRepository create() throws IOException {
|
public GHRepository create() throws IOException {
|
||||||
return builder.method("POST").withUrlPath(apiUrlTail).fetch(GHRepository.class).wrap(root);
|
return done();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import org.kohsuke.github.internal.Previews;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a deployment
|
* Represents a deployment
|
||||||
@@ -13,7 +16,6 @@ import java.net.URL;
|
|||||||
*/
|
*/
|
||||||
public class GHDeployment extends GHObject {
|
public class GHDeployment extends GHObject {
|
||||||
private GHRepository owner;
|
private GHRepository owner;
|
||||||
private GitHub root;
|
|
||||||
protected String sha;
|
protected String sha;
|
||||||
protected String ref;
|
protected String ref;
|
||||||
protected String task;
|
protected String task;
|
||||||
@@ -23,6 +25,9 @@ public class GHDeployment extends GHObject {
|
|||||||
protected String statuses_url;
|
protected String statuses_url;
|
||||||
protected String repository_url;
|
protected String repository_url;
|
||||||
protected GHUser creator;
|
protected GHUser creator;
|
||||||
|
protected String original_environment;
|
||||||
|
protected boolean transient_environment;
|
||||||
|
protected boolean production_environment;
|
||||||
|
|
||||||
GHDeployment wrap(GHRepository owner) {
|
GHDeployment wrap(GHRepository owner) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
@@ -60,7 +65,8 @@ public class GHDeployment extends GHObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets payload.
|
* Gets payload. <b>NOTE:</b> only use this method if you can guarantee the payload will be a simple string,
|
||||||
|
* otherwise use {@link #getPayloadObject()}.
|
||||||
*
|
*
|
||||||
* @return the payload
|
* @return the payload
|
||||||
*/
|
*/
|
||||||
@@ -68,6 +74,38 @@ public class GHDeployment extends GHObject {
|
|||||||
return (String) payload;
|
return (String) payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets payload. <b>NOTE:</b> only use this method if you can guarantee the payload will be a JSON object (Map),
|
||||||
|
* otherwise use {@link #getPayloadObject()}.
|
||||||
|
*
|
||||||
|
* @return the payload
|
||||||
|
*/
|
||||||
|
public Map<String, Object> getPayloadMap() {
|
||||||
|
return (Map<String, Object>) payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets payload without assuming its type. It could be a String or a Map.
|
||||||
|
*
|
||||||
|
* @return the payload
|
||||||
|
*/
|
||||||
|
public Object getPayloadObject() {
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The environment defined when the deployment was first created.
|
||||||
|
*
|
||||||
|
* @deprecated until preview feature has graduated to stable
|
||||||
|
*
|
||||||
|
* @return the original deployment environment
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Preview(Previews.FLASH)
|
||||||
|
public String getOriginalEnvironment() {
|
||||||
|
return original_environment;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets environment.
|
* Gets environment.
|
||||||
*
|
*
|
||||||
@@ -77,6 +115,33 @@ public class GHDeployment extends GHObject {
|
|||||||
return environment;
|
return environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies if the given environment is specific to the deployment and will no longer exist at some point in the
|
||||||
|
* future.
|
||||||
|
*
|
||||||
|
* @deprecated until preview feature has graduated to stable
|
||||||
|
*
|
||||||
|
* @return the environment is transient
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Preview(Previews.ANT_MAN)
|
||||||
|
public boolean isTransientEnvironment() {
|
||||||
|
return transient_environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies if the given environment is one that end-users directly interact with.
|
||||||
|
*
|
||||||
|
* @deprecated until preview feature has graduated to stable
|
||||||
|
*
|
||||||
|
* @return the environment is used by end-users directly
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Preview(Previews.ANT_MAN)
|
||||||
|
public boolean isProductionEnvironment() {
|
||||||
|
return production_environment;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets creator.
|
* Gets creator.
|
||||||
*
|
*
|
||||||
@@ -133,6 +198,8 @@ public class GHDeployment extends GHObject {
|
|||||||
public PagedIterable<GHDeploymentStatus> listStatuses() {
|
public PagedIterable<GHDeploymentStatus> listStatuses() {
|
||||||
return root.createRequest()
|
return root.createRequest()
|
||||||
.withUrlPath(statuses_url)
|
.withUrlPath(statuses_url)
|
||||||
|
.withPreview(Previews.ANT_MAN)
|
||||||
|
.withPreview(Previews.FLASH)
|
||||||
.toIterable(GHDeploymentStatus[].class, item -> item.wrap(owner));
|
.toIterable(GHDeploymentStatus[].class, item -> item.wrap(owner));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import org.kohsuke.github.internal.Previews;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -19,7 +21,10 @@ public class GHDeploymentBuilder {
|
|||||||
*/
|
*/
|
||||||
public GHDeploymentBuilder(GHRepository repo) {
|
public GHDeploymentBuilder(GHRepository repo) {
|
||||||
this.repo = repo;
|
this.repo = repo;
|
||||||
this.builder = repo.root.createRequest().method("POST");
|
this.builder = repo.root.createRequest()
|
||||||
|
.withPreview(Previews.ANT_MAN)
|
||||||
|
.withPreview(Previews.FLASH)
|
||||||
|
.method("POST");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,6 +45,7 @@ public class GHDeploymentBuilder {
|
|||||||
*
|
*
|
||||||
* @param branch
|
* @param branch
|
||||||
* the branch
|
* the branch
|
||||||
|
*
|
||||||
* @return the gh deployment builder
|
* @return the gh deployment builder
|
||||||
*/
|
*/
|
||||||
public GHDeploymentBuilder ref(String branch) {
|
public GHDeploymentBuilder ref(String branch) {
|
||||||
@@ -52,6 +58,7 @@ public class GHDeploymentBuilder {
|
|||||||
*
|
*
|
||||||
* @param task
|
* @param task
|
||||||
* the task
|
* the task
|
||||||
|
*
|
||||||
* @return the gh deployment builder
|
* @return the gh deployment builder
|
||||||
*/
|
*/
|
||||||
public GHDeploymentBuilder task(String task) {
|
public GHDeploymentBuilder task(String task) {
|
||||||
@@ -64,6 +71,7 @@ public class GHDeploymentBuilder {
|
|||||||
*
|
*
|
||||||
* @param autoMerge
|
* @param autoMerge
|
||||||
* the auto merge
|
* the auto merge
|
||||||
|
*
|
||||||
* @return the gh deployment builder
|
* @return the gh deployment builder
|
||||||
*/
|
*/
|
||||||
public GHDeploymentBuilder autoMerge(boolean autoMerge) {
|
public GHDeploymentBuilder autoMerge(boolean autoMerge) {
|
||||||
@@ -76,6 +84,7 @@ public class GHDeploymentBuilder {
|
|||||||
*
|
*
|
||||||
* @param requiredContexts
|
* @param requiredContexts
|
||||||
* the required contexts
|
* the required contexts
|
||||||
|
*
|
||||||
* @return the gh deployment builder
|
* @return the gh deployment builder
|
||||||
*/
|
*/
|
||||||
public GHDeploymentBuilder requiredContexts(List<String> requiredContexts) {
|
public GHDeploymentBuilder requiredContexts(List<String> requiredContexts) {
|
||||||
@@ -88,6 +97,7 @@ public class GHDeploymentBuilder {
|
|||||||
*
|
*
|
||||||
* @param payload
|
* @param payload
|
||||||
* the payload
|
* the payload
|
||||||
|
*
|
||||||
* @return the gh deployment builder
|
* @return the gh deployment builder
|
||||||
*/
|
*/
|
||||||
public GHDeploymentBuilder payload(String payload) {
|
public GHDeploymentBuilder payload(String payload) {
|
||||||
@@ -100,6 +110,7 @@ public class GHDeploymentBuilder {
|
|||||||
*
|
*
|
||||||
* @param environment
|
* @param environment
|
||||||
* the environment
|
* the environment
|
||||||
|
*
|
||||||
* @return the gh deployment builder
|
* @return the gh deployment builder
|
||||||
*/
|
*/
|
||||||
public GHDeploymentBuilder environment(String environment) {
|
public GHDeploymentBuilder environment(String environment) {
|
||||||
@@ -107,11 +118,47 @@ public class GHDeploymentBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies if the given environment is specific to the deployment and will no longer exist at some point in the
|
||||||
|
* future.
|
||||||
|
*
|
||||||
|
* @deprecated until preview feature has graduated to stable
|
||||||
|
*
|
||||||
|
* @param transientEnvironment
|
||||||
|
* the environment is transient
|
||||||
|
*
|
||||||
|
* @return the gh deployment builder
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Preview(Previews.ANT_MAN)
|
||||||
|
public GHDeploymentBuilder transientEnvironment(boolean transientEnvironment) {
|
||||||
|
builder.with("transient_environment", transientEnvironment);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies if the given environment is one that end-users directly interact with.
|
||||||
|
*
|
||||||
|
* @deprecated until preview feature has graduated to stable
|
||||||
|
*
|
||||||
|
* @param productionEnvironment
|
||||||
|
* the environment is used by end-users directly
|
||||||
|
*
|
||||||
|
* @return the gh deployment builder
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Preview(Previews.ANT_MAN)
|
||||||
|
public GHDeploymentBuilder productionEnvironment(boolean productionEnvironment) {
|
||||||
|
builder.with("production_environment", productionEnvironment);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description gh deployment builder.
|
* Description gh deployment builder.
|
||||||
*
|
*
|
||||||
* @param description
|
* @param description
|
||||||
* the description
|
* the description
|
||||||
|
*
|
||||||
* @return the gh deployment builder
|
* @return the gh deployment builder
|
||||||
*/
|
*/
|
||||||
public GHDeploymentBuilder description(String description) {
|
public GHDeploymentBuilder description(String description) {
|
||||||
@@ -123,6 +170,7 @@ public class GHDeploymentBuilder {
|
|||||||
* Create gh deployment.
|
* Create gh deployment.
|
||||||
*
|
*
|
||||||
* @return the gh deployment
|
* @return the gh deployment
|
||||||
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,8 +1,40 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import org.kohsuke.github.internal.Previews;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the state of deployment
|
* Represents the state of deployment
|
||||||
*/
|
*/
|
||||||
public enum GHDeploymentState {
|
public enum GHDeploymentState {
|
||||||
PENDING, SUCCESS, ERROR, FAILURE
|
PENDING,
|
||||||
|
SUCCESS,
|
||||||
|
ERROR,
|
||||||
|
FAILURE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The state of the deployment currently reflects it's in progress.
|
||||||
|
*
|
||||||
|
* @deprecated until preview feature has graduated to stable
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Preview(Previews.FLASH)
|
||||||
|
IN_PROGRESS,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The state of the deployment currently reflects it's queued up for processing.
|
||||||
|
*
|
||||||
|
* @deprecated until preview feature has graduated to stable
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Preview(Previews.FLASH)
|
||||||
|
QUEUED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The state of the deployment currently reflects it's no longer active.
|
||||||
|
*
|
||||||
|
* @deprecated until preview feature has graduated to stable
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Preview(Previews.ANT_MAN)
|
||||||
|
INACTIVE
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import org.kohsuke.github.internal.Previews;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@@ -8,19 +10,21 @@ import java.util.Locale;
|
|||||||
*/
|
*/
|
||||||
public class GHDeploymentStatus extends GHObject {
|
public class GHDeploymentStatus extends GHObject {
|
||||||
private GHRepository owner;
|
private GHRepository owner;
|
||||||
private GitHub root;
|
|
||||||
protected GHUser creator;
|
protected GHUser creator;
|
||||||
protected String state;
|
protected String state;
|
||||||
protected String description;
|
protected String description;
|
||||||
protected String target_url;
|
protected String target_url;
|
||||||
|
protected String log_url;
|
||||||
protected String deployment_url;
|
protected String deployment_url;
|
||||||
protected String repository_url;
|
protected String repository_url;
|
||||||
|
protected String environment_url;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrap gh deployment status.
|
* Wrap gh deployment status.
|
||||||
*
|
*
|
||||||
* @param owner
|
* @param owner
|
||||||
* the owner
|
* the owner
|
||||||
|
*
|
||||||
* @return the gh deployment status
|
* @return the gh deployment status
|
||||||
*/
|
*/
|
||||||
public GHDeploymentStatus wrap(GHRepository owner) {
|
public GHDeploymentStatus wrap(GHRepository owner) {
|
||||||
@@ -34,12 +38,30 @@ public class GHDeploymentStatus extends GHObject {
|
|||||||
/**
|
/**
|
||||||
* Gets target url.
|
* Gets target url.
|
||||||
*
|
*
|
||||||
|
* @deprecated Target url is deprecated in favor of {@link #getLogUrl() getLogUrl}
|
||||||
|
*
|
||||||
* @return the target url
|
* @return the target url
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public URL getTargetUrl() {
|
public URL getTargetUrl() {
|
||||||
return GitHubClient.parseURL(target_url);
|
return GitHubClient.parseURL(target_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets target url.
|
||||||
|
* <p>
|
||||||
|
* This method replaces {@link #getTargetUrl() getTargetUrl}}.
|
||||||
|
*
|
||||||
|
* @deprecated until preview feature has graduated to stable
|
||||||
|
*
|
||||||
|
* @return the target url
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Preview(Previews.ANT_MAN)
|
||||||
|
public URL getLogUrl() {
|
||||||
|
return GitHubClient.parseURL(log_url);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets deployment url.
|
* Gets deployment url.
|
||||||
*
|
*
|
||||||
@@ -49,6 +71,19 @@ public class GHDeploymentStatus extends GHObject {
|
|||||||
return GitHubClient.parseURL(deployment_url);
|
return GitHubClient.parseURL(deployment_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets deployment environment url.
|
||||||
|
*
|
||||||
|
* @deprecated until preview feature has graduated to stable
|
||||||
|
*
|
||||||
|
* @return the deployment environment url
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Preview(Previews.ANT_MAN)
|
||||||
|
public URL getEnvironmentUrl() {
|
||||||
|
return GitHubClient.parseURL(environment_url);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets repository url.
|
* Gets repository url.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import org.kohsuke.github.internal.Previews;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,6 +23,7 @@ public class GHDeploymentStatusBuilder {
|
|||||||
* the deployment id
|
* the deployment id
|
||||||
* @param state
|
* @param state
|
||||||
* the state
|
* the state
|
||||||
|
*
|
||||||
* @deprecated Use {@link GHDeployment#createStatus(GHDeploymentState)}
|
* @deprecated Use {@link GHDeployment#createStatus(GHDeploymentState)}
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@@ -31,15 +34,38 @@ public class GHDeploymentStatusBuilder {
|
|||||||
GHDeploymentStatusBuilder(GHRepository repo, long deploymentId, GHDeploymentState state) {
|
GHDeploymentStatusBuilder(GHRepository repo, long deploymentId, GHDeploymentState state) {
|
||||||
this.repo = repo;
|
this.repo = repo;
|
||||||
this.deploymentId = deploymentId;
|
this.deploymentId = deploymentId;
|
||||||
this.builder = repo.root.createRequest().method("POST");
|
this.builder = repo.root.createRequest()
|
||||||
|
.withPreview(Previews.ANT_MAN)
|
||||||
|
.withPreview(Previews.FLASH)
|
||||||
|
.method("POST");
|
||||||
|
|
||||||
this.builder.with("state", state);
|
this.builder.with("state", state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an inactive status to all prior non-transient, non-production environment deployments with the same
|
||||||
|
* repository and environment name as the created status's deployment.
|
||||||
|
*
|
||||||
|
* @deprecated until preview feature has graduated to stable
|
||||||
|
*
|
||||||
|
* @param autoInactive
|
||||||
|
* Add inactive status flag
|
||||||
|
*
|
||||||
|
* @return the gh deployment status builder
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Preview({ Previews.ANT_MAN, Previews.FLASH })
|
||||||
|
public GHDeploymentStatusBuilder autoInactive(boolean autoInactive) {
|
||||||
|
this.builder.with("auto_inactive", autoInactive);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description gh deployment status builder.
|
* Description gh deployment status builder.
|
||||||
*
|
*
|
||||||
* @param description
|
* @param description
|
||||||
* the description
|
* the description
|
||||||
|
*
|
||||||
* @return the gh deployment status builder
|
* @return the gh deployment status builder
|
||||||
*/
|
*/
|
||||||
public GHDeploymentStatusBuilder description(String description) {
|
public GHDeploymentStatusBuilder description(String description) {
|
||||||
@@ -47,13 +73,70 @@ public class GHDeploymentStatusBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name for the target deployment environment, which can be changed when setting a deploy status.
|
||||||
|
*
|
||||||
|
* @deprecated until preview feature has graduated to stable
|
||||||
|
*
|
||||||
|
* @param environment
|
||||||
|
* the environment name
|
||||||
|
*
|
||||||
|
* @return the gh deployment status builder
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Preview(Previews.FLASH)
|
||||||
|
public GHDeploymentStatusBuilder environment(String environment) {
|
||||||
|
this.builder.with("environment", environment);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL for accessing the environment
|
||||||
|
*
|
||||||
|
* @deprecated until preview feature has graduated to stable
|
||||||
|
*
|
||||||
|
* @param environmentUrl
|
||||||
|
* the environment url
|
||||||
|
*
|
||||||
|
* @return the gh deployment status builder
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Preview(Previews.ANT_MAN)
|
||||||
|
public GHDeploymentStatusBuilder environmentUrl(String environmentUrl) {
|
||||||
|
this.builder.with("environment_url", environmentUrl);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The full URL of the deployment's output.
|
||||||
|
* <p>
|
||||||
|
* This method replaces {@link #targetUrl(String) targetUrl}.
|
||||||
|
*
|
||||||
|
* @deprecated until preview feature has graduated to stable
|
||||||
|
*
|
||||||
|
* @param logUrl
|
||||||
|
* the deployment output url
|
||||||
|
*
|
||||||
|
* @return the gh deployment status builder
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Preview(Previews.ANT_MAN)
|
||||||
|
public GHDeploymentStatusBuilder logUrl(String logUrl) {
|
||||||
|
this.builder.with("log_url", logUrl);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Target url gh deployment status builder.
|
* Target url gh deployment status builder.
|
||||||
*
|
*
|
||||||
|
* @deprecated Target url is deprecated in favor of {@link #logUrl(String) logUrl}
|
||||||
|
*
|
||||||
* @param targetUrl
|
* @param targetUrl
|
||||||
* the target url
|
* the target url
|
||||||
|
*
|
||||||
* @return the gh deployment status builder
|
* @return the gh deployment status builder
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public GHDeploymentStatusBuilder targetUrl(String targetUrl) {
|
public GHDeploymentStatusBuilder targetUrl(String targetUrl) {
|
||||||
this.builder.with("target_url", targetUrl);
|
this.builder.with("target_url", targetUrl);
|
||||||
return this;
|
return this;
|
||||||
@@ -63,6 +146,7 @@ public class GHDeploymentStatusBuilder {
|
|||||||
* Create gh deployment status.
|
* Create gh deployment status.
|
||||||
*
|
*
|
||||||
* @return the gh deployment status
|
* @return the gh deployment status
|
||||||
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JacksonInject;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import org.kohsuke.github.internal.Previews;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@@ -18,8 +18,6 @@ import javax.annotation.Nonnull;
|
|||||||
*/
|
*/
|
||||||
public class GHDiscussion extends GHObject {
|
public class GHDiscussion extends GHObject {
|
||||||
|
|
||||||
@JacksonInject
|
|
||||||
private GitHub root;
|
|
||||||
private GHTeam team;
|
private GHTeam team;
|
||||||
private long number;
|
private long number;
|
||||||
private String body, title, htmlUrl;
|
private String body, title, htmlUrl;
|
||||||
@@ -130,7 +128,7 @@ public class GHDiscussion extends GHObject {
|
|||||||
*
|
*
|
||||||
* @return a {@link GHDiscussion.Updater}
|
* @return a {@link GHDiscussion.Updater}
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(Previews.SQUIRREL_GIRL)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHDiscussion.Updater update() {
|
public GHDiscussion.Updater update() {
|
||||||
return new GHDiscussion.Updater(this);
|
return new GHDiscussion.Updater(this);
|
||||||
@@ -141,7 +139,7 @@ public class GHDiscussion extends GHObject {
|
|||||||
*
|
*
|
||||||
* @return a {@link GHDiscussion.Setter}
|
* @return a {@link GHDiscussion.Setter}
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(Previews.SQUIRREL_GIRL)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHDiscussion.Setter set() {
|
public GHDiscussion.Setter set() {
|
||||||
return new GHDiscussion.Setter(this);
|
return new GHDiscussion.Setter(this);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import java.util.Locale;
|
|||||||
public enum GHEvent {
|
public enum GHEvent {
|
||||||
CHECK_RUN,
|
CHECK_RUN,
|
||||||
CHECK_SUITE,
|
CHECK_SUITE,
|
||||||
|
CODE_SCANNING_ALERT,
|
||||||
COMMIT_COMMENT,
|
COMMIT_COMMENT,
|
||||||
CONTENT_REFERENCE,
|
CONTENT_REFERENCE,
|
||||||
CREATE,
|
CREATE,
|
||||||
@@ -62,6 +63,8 @@ public enum GHEvent {
|
|||||||
TEAM,
|
TEAM,
|
||||||
TEAM_ADD,
|
TEAM_ADD,
|
||||||
WATCH,
|
WATCH,
|
||||||
|
WORKFLOW_DISPATCH,
|
||||||
|
WORKFLOW_RUN,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Special event type that means "every possible event"
|
* Special event type that means "every possible event"
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ import java.util.Date;
|
|||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
@SuppressFBWarnings(value = "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", justification = "JSON API")
|
@SuppressFBWarnings(value = "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", justification = "JSON API")
|
||||||
public class GHEventInfo {
|
public class GHEventInfo extends GitHubInteractiveObject {
|
||||||
private GitHub root;
|
|
||||||
|
|
||||||
// we don't want to expose Jackson dependency to the user. This needs databinding
|
// we don't want to expose Jackson dependency to the user. This needs databinding
|
||||||
private ObjectNode payload;
|
private ObjectNode payload;
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,6 @@ import java.util.Map.Entry;
|
|||||||
public class GHGist extends GHObject {
|
public class GHGist extends GHObject {
|
||||||
|
|
||||||
final GHUser owner;
|
final GHUser owner;
|
||||||
final GitHub root;
|
|
||||||
|
|
||||||
private String forks_url, commits_url, id, git_pull_url, git_push_url, html_url;
|
private String forks_url, commits_url, id, git_pull_url, git_push_url, html_url;
|
||||||
|
|
||||||
@@ -123,7 +122,7 @@ public class GHGist extends GHObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the html url.
|
* Get the html url.
|
||||||
*
|
*
|
||||||
* @return the github html url
|
* @return the github html url
|
||||||
*/
|
*/
|
||||||
public URL getHtmlUrl() {
|
public URL getHtmlUrl() {
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import javax.annotation.Nonnull;
|
|||||||
* @see GitHub#createGist() GitHub#createGist()
|
* @see GitHub#createGist() GitHub#createGist()
|
||||||
*/
|
*/
|
||||||
public class GHGistBuilder {
|
public class GHGistBuilder {
|
||||||
private final GitHub root;
|
|
||||||
private final Requester req;
|
private final Requester req;
|
||||||
private final LinkedHashMap<String, Object> files = new LinkedHashMap<String, Object>();
|
private final LinkedHashMap<String, Object> files = new LinkedHashMap<String, Object>();
|
||||||
|
|
||||||
@@ -24,7 +23,6 @@ public class GHGistBuilder {
|
|||||||
* the root
|
* the root
|
||||||
*/
|
*/
|
||||||
public GHGistBuilder(GitHub root) {
|
public GHGistBuilder(GitHub root) {
|
||||||
this.root = root;
|
|
||||||
req = root.createRequest().method("POST");
|
req = root.createRequest().method("POST");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ import java.util.Map;
|
|||||||
* functionality
|
* functionality
|
||||||
*/
|
*/
|
||||||
class GHHooks {
|
class GHHooks {
|
||||||
static abstract class Context {
|
static abstract class Context extends GitHubInteractiveObject {
|
||||||
private final GitHub root;
|
|
||||||
|
|
||||||
private Context(GitHub root) {
|
private Context(GitHub root) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import java.net.URL;
|
|||||||
"UUF_UNUSED_FIELD" },
|
"UUF_UNUSED_FIELD" },
|
||||||
justification = "JSON API")
|
justification = "JSON API")
|
||||||
public class GHInvitation extends GHObject {
|
public class GHInvitation extends GHObject {
|
||||||
/* package almost final */ GitHub root;
|
|
||||||
|
|
||||||
private int id;
|
private int id;
|
||||||
private GHRepository repository;
|
private GHRepository repository;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.SQUIRREL_GIRL;
|
import static org.kohsuke.github.internal.Previews.SQUIRREL_GIRL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an issue on GitHub.
|
* Represents an issue on GitHub.
|
||||||
@@ -53,7 +53,6 @@ import static org.kohsuke.github.Previews.SQUIRREL_GIRL;
|
|||||||
public class GHIssue extends GHObject implements Reactable {
|
public class GHIssue extends GHObject implements Reactable {
|
||||||
private static final String ASSIGNEES = "assignees";
|
private static final String ASSIGNEES = "assignees";
|
||||||
|
|
||||||
GitHub root;
|
|
||||||
GHRepository owner;
|
GHRepository owner;
|
||||||
|
|
||||||
// API v3
|
// API v3
|
||||||
@@ -158,10 +157,8 @@ public class GHIssue extends GHObject implements Reactable {
|
|||||||
* Gets labels.
|
* Gets labels.
|
||||||
*
|
*
|
||||||
* @return the labels
|
* @return the labels
|
||||||
* @throws IOException
|
|
||||||
* the io exception
|
|
||||||
*/
|
*/
|
||||||
public Collection<GHLabel> getLabels() throws IOException {
|
public Collection<GHLabel> getLabels() {
|
||||||
if (labels == null) {
|
if (labels == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
@@ -239,7 +236,7 @@ public class GHIssue extends GHObject implements Reactable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void editIssue(String key, Object value) throws IOException {
|
private void editIssue(String key, Object value) throws IOException {
|
||||||
root.createRequest().with(key, value).method("PATCH").withUrlPath(getIssuesApiRoute()).send();
|
root.createRequest().withNullable(key, value).method("PATCH").withUrlPath(getIssuesApiRoute()).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -296,9 +293,9 @@ public class GHIssue extends GHObject implements Reactable {
|
|||||||
*/
|
*/
|
||||||
public void setMilestone(GHMilestone milestone) throws IOException {
|
public void setMilestone(GHMilestone milestone) throws IOException {
|
||||||
if (milestone == null) {
|
if (milestone == null) {
|
||||||
editNullable("milestone", null);
|
editIssue("milestone", null);
|
||||||
} else {
|
} else {
|
||||||
edit("milestone", milestone.getNumber());
|
editIssue("milestone", milestone.getNumber());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,7 +447,7 @@ public class GHIssue extends GHObject implements Reactable {
|
|||||||
.toIterable(GHIssueComment[].class, item -> item.wrapUp(this));
|
.toIterable(GHIssueComment[].class, item -> item.wrapUp(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview(SQUIRREL_GIRL)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHReaction createReaction(ReactionContent content) throws IOException {
|
public GHReaction createReaction(ReactionContent content) throws IOException {
|
||||||
return root.createRequest()
|
return root.createRequest()
|
||||||
@@ -462,7 +459,7 @@ public class GHIssue extends GHObject implements Reactable {
|
|||||||
.wrap(root);
|
.wrap(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview(SQUIRREL_GIRL)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public PagedIterable<GHReaction> listReactions() {
|
public PagedIterable<GHReaction> listReactions() {
|
||||||
return root.createRequest()
|
return root.createRequest()
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ package org.kohsuke.github;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.*;
|
import static org.kohsuke.github.internal.Previews.SQUIRREL_GIRL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Comment to the issue
|
* Comment to the issue
|
||||||
@@ -126,7 +126,7 @@ public class GHIssueComment extends GHObject implements Reactable {
|
|||||||
owner.root.createRequest().method("DELETE").withUrlPath(getApiRoute()).send();
|
owner.root.createRequest().method("DELETE").withUrlPath(getApiRoute()).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview(SQUIRREL_GIRL)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHReaction createReaction(ReactionContent content) throws IOException {
|
public GHReaction createReaction(ReactionContent content) throws IOException {
|
||||||
return owner.root.createRequest()
|
return owner.root.createRequest()
|
||||||
@@ -138,7 +138,7 @@ public class GHIssueComment extends GHObject implements Reactable {
|
|||||||
.wrap(owner.root);
|
.wrap(owner.root);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview(SQUIRREL_GIRL)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public PagedIterable<GHReaction> listReactions() {
|
public PagedIterable<GHReaction> listReactions() {
|
||||||
return owner.root.createRequest()
|
return owner.root.createRequest()
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ import java.util.Date;
|
|||||||
*
|
*
|
||||||
* @author Martin van Zijl
|
* @author Martin van Zijl
|
||||||
*/
|
*/
|
||||||
public class GHIssueEvent {
|
public class GHIssueEvent extends GitHubInteractiveObject {
|
||||||
private GitHub root;
|
|
||||||
|
|
||||||
private long id;
|
private long id;
|
||||||
private String node_id;
|
private String node_id;
|
||||||
private String url;
|
private String url;
|
||||||
|
|||||||
@@ -31,4 +31,4 @@ package org.kohsuke.github;
|
|||||||
*/
|
*/
|
||||||
public enum GHIssueState {
|
public enum GHIssueState {
|
||||||
OPEN, CLOSED, ALL
|
OPEN, CLOSED, ALL
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
|
|||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
@SuppressFBWarnings(value = "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", justification = "JSON API")
|
@SuppressFBWarnings(value = "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", justification = "JSON API")
|
||||||
public class GHKey {
|
public class GHKey extends GitHubInteractiveObject {
|
||||||
/* package almost final */ GitHub root;
|
|
||||||
|
|
||||||
protected String url, key, title;
|
protected String url, key, title;
|
||||||
protected boolean verified;
|
protected boolean verified;
|
||||||
protected int id;
|
protected int id;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import javax.annotation.Nonnull;
|
|||||||
* @see GHIssue#getLabels() GHIssue#getLabels()
|
* @see GHIssue#getLabels() GHIssue#getLabels()
|
||||||
* @see GHRepository#listLabels() GHRepository#listLabels()
|
* @see GHRepository#listLabels() GHRepository#listLabels()
|
||||||
*/
|
*/
|
||||||
public class GHLabel {
|
public class GHLabel extends GitHubInteractiveObject {
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private String url, name, color;
|
private String url, name, color;
|
||||||
@@ -28,9 +28,6 @@ public class GHLabel {
|
|||||||
@CheckForNull
|
@CheckForNull
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private final GitHub root;
|
|
||||||
|
|
||||||
@JsonCreator
|
@JsonCreator
|
||||||
private GHLabel(@JacksonInject @Nonnull GitHub root) {
|
private GHLabel(@JacksonInject @Nonnull GitHub root) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
@@ -132,7 +129,7 @@ public class GHLabel {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
static Creator create(GHRepository repository) throws IOException {
|
static Creator create(GHRepository repository) throws IOException {
|
||||||
return new Creator(repository);
|
return new Creator(repository);
|
||||||
@@ -179,7 +176,7 @@ public class GHLabel {
|
|||||||
*
|
*
|
||||||
* @return a {@link Updater}
|
* @return a {@link Updater}
|
||||||
*/
|
*/
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Updater update() {
|
public Updater update() {
|
||||||
return new Updater(this);
|
return new Updater(this);
|
||||||
@@ -187,10 +184,10 @@ public class GHLabel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Begins a single property update.
|
* Begins a single property update.
|
||||||
*
|
*
|
||||||
* @return a {@link Setter}
|
* @return a {@link Setter}
|
||||||
*/
|
*/
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Setter set() {
|
public Setter set() {
|
||||||
return new Setter(this);
|
return new Setter(this);
|
||||||
@@ -227,7 +224,7 @@ public class GHLabel {
|
|||||||
*
|
*
|
||||||
* {@link #done()} is called automatically after the property is set.
|
* {@link #done()} is called automatically after the property is set.
|
||||||
*/
|
*/
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static class Setter extends GHLabelBuilder<GHLabel> {
|
public static class Setter extends GHLabelBuilder<GHLabel> {
|
||||||
private Setter(@Nonnull GHLabel base) {
|
private Setter(@Nonnull GHLabel base) {
|
||||||
@@ -241,7 +238,7 @@ public class GHLabel {
|
|||||||
*
|
*
|
||||||
* Consumer must call {@link #done()} to commit changes.
|
* Consumer must call {@link #done()} to commit changes.
|
||||||
*/
|
*/
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static class Updater extends GHLabelBuilder<Updater> {
|
public static class Updater extends GHLabelBuilder<Updater> {
|
||||||
private Updater(@Nonnull GHLabel base) {
|
private Updater(@Nonnull GHLabel base) {
|
||||||
@@ -255,7 +252,7 @@ public class GHLabel {
|
|||||||
*
|
*
|
||||||
* Consumer must call {@link #done()} to create the new instance.
|
* Consumer must call {@link #done()} to create the new instance.
|
||||||
*/
|
*/
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static class Creator extends GHLabelBuilder<Creator> {
|
public static class Creator extends GHLabelBuilder<Creator> {
|
||||||
private Creator(@Nonnull GHRepository repository) {
|
private Creator(@Nonnull GHRepository repository) {
|
||||||
|
|||||||
@@ -38,21 +38,21 @@ class GHLabelBuilder<S> extends AbstractBuilder<GHLabel, S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public S name(String value) throws IOException {
|
public S name(String value) throws IOException {
|
||||||
return with("name", value);
|
return with("name", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public S color(String value) throws IOException {
|
public S color(String value) throws IOException {
|
||||||
return with("color", value);
|
return with("color", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public S description(String value) throws IOException {
|
public S description(String value) throws IOException {
|
||||||
return with("description", value);
|
return with("description", value);
|
||||||
|
|||||||
@@ -44,9 +44,6 @@ import java.util.Objects;
|
|||||||
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
||||||
justification = "JSON API")
|
justification = "JSON API")
|
||||||
public class GHLicense extends GHObject {
|
public class GHLicense extends GHObject {
|
||||||
@SuppressFBWarnings("IS2_INCONSISTENT_SYNC")
|
|
||||||
// root is set before the object is returned to the app
|
|
||||||
/* package almost final */ GitHub root;
|
|
||||||
|
|
||||||
// these fields are always present, even in the short form
|
// these fields are always present, even in the short form
|
||||||
protected String key, name;
|
protected String key, name;
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ import java.net.URL;
|
|||||||
* @see GitHub#getMyMarketplacePurchases()
|
* @see GitHub#getMyMarketplacePurchases()
|
||||||
* @see GHMarketplaceListAccountBuilder#createRequest()
|
* @see GHMarketplaceListAccountBuilder#createRequest()
|
||||||
*/
|
*/
|
||||||
public class GHMarketplaceAccount {
|
public class GHMarketplaceAccount extends GitHubInteractiveObject {
|
||||||
|
|
||||||
protected GitHub root;
|
|
||||||
private String url;
|
private String url;
|
||||||
private long id;
|
private long id;
|
||||||
private String login;
|
private String login;
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ import java.io.IOException;
|
|||||||
* @author Paulo Miguel Almeida
|
* @author Paulo Miguel Almeida
|
||||||
* @see GHMarketplacePlan#listAccounts()
|
* @see GHMarketplacePlan#listAccounts()
|
||||||
*/
|
*/
|
||||||
public class GHMarketplaceListAccountBuilder {
|
public class GHMarketplaceListAccountBuilder extends GitHubInteractiveObject {
|
||||||
private final GitHub root;
|
|
||||||
private final Requester builder;
|
private final Requester builder;
|
||||||
private final long planId;
|
private final long planId;
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ import java.util.Date;
|
|||||||
* @author Paulo Miguel Almeida
|
* @author Paulo Miguel Almeida
|
||||||
* @see GHMarketplaceListAccountBuilder#createRequest()
|
* @see GHMarketplaceListAccountBuilder#createRequest()
|
||||||
*/
|
*/
|
||||||
public class GHMarketplacePendingChange {
|
public class GHMarketplacePendingChange extends GitHubInteractiveObject {
|
||||||
private GitHub root;
|
|
||||||
private long id;
|
private long id;
|
||||||
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
|
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
|
||||||
private Long unitCount;
|
private Long unitCount;
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ import java.util.List;
|
|||||||
* @author Paulo Miguel Almeida
|
* @author Paulo Miguel Almeida
|
||||||
* @see GitHub#listMarketplacePlans()
|
* @see GitHub#listMarketplacePlans()
|
||||||
*/
|
*/
|
||||||
public class GHMarketplacePlan {
|
public class GHMarketplacePlan extends GitHubInteractiveObject {
|
||||||
|
|
||||||
private GitHub root;
|
|
||||||
private String url;
|
private String url;
|
||||||
private String accountsUrl;
|
private String accountsUrl;
|
||||||
private long id;
|
private long id;
|
||||||
|
|||||||
@@ -10,9 +10,8 @@ import java.util.Date;
|
|||||||
* @author Paulo Miguel Almeida
|
* @author Paulo Miguel Almeida
|
||||||
* @see GHMarketplaceListAccountBuilder#createRequest() GHMarketplaceListAccountBuilder#createRequest()
|
* @see GHMarketplaceListAccountBuilder#createRequest() GHMarketplaceListAccountBuilder#createRequest()
|
||||||
*/
|
*/
|
||||||
public class GHMarketplacePurchase {
|
public class GHMarketplacePurchase extends GitHubInteractiveObject {
|
||||||
|
|
||||||
private GitHub root;
|
|
||||||
private String billingCycle;
|
private String billingCycle;
|
||||||
private String nextBillingDate;
|
private String nextBillingDate;
|
||||||
private boolean onFreeTrial;
|
private boolean onFreeTrial;
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ import java.util.Date;
|
|||||||
* @author Paulo Miguel Almeida
|
* @author Paulo Miguel Almeida
|
||||||
* @see GitHub#getMyMarketplacePurchases()
|
* @see GitHub#getMyMarketplacePurchases()
|
||||||
*/
|
*/
|
||||||
public class GHMarketplaceUserPurchase {
|
public class GHMarketplaceUserPurchase extends GitHubInteractiveObject {
|
||||||
protected GitHub root;
|
|
||||||
private String billingCycle;
|
private String billingCycle;
|
||||||
private String nextBillingDate;
|
private String nextBillingDate;
|
||||||
private boolean onFreeTrial;
|
private boolean onFreeTrial;
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ import java.util.Locale;
|
|||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
* @see GHMyself#listOrgMemberships() GHMyself#listOrgMemberships()
|
* @see GHMyself#listOrgMemberships() GHMyself#listOrgMemberships()
|
||||||
*/
|
*/
|
||||||
public class GHMembership /* extends GHObject --- but it doesn't have id, created_at, etc. */ {
|
public class GHMembership extends GitHubInteractiveObject {
|
||||||
GitHub root;
|
|
||||||
|
|
||||||
String url;
|
String url;
|
||||||
String state;
|
String state;
|
||||||
String role;
|
String role;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import java.util.Locale;
|
|||||||
* @author Yusuke Kokubo
|
* @author Yusuke Kokubo
|
||||||
*/
|
*/
|
||||||
public class GHMilestone extends GHObject {
|
public class GHMilestone extends GHObject {
|
||||||
GitHub root;
|
|
||||||
GHRepository owner;
|
GHRepository owner;
|
||||||
|
|
||||||
GHUser creator;
|
GHUser creator;
|
||||||
|
|||||||
@@ -7,4 +7,4 @@ package org.kohsuke.github;
|
|||||||
*/
|
*/
|
||||||
public enum GHMilestoneState {
|
public enum GHMilestoneState {
|
||||||
OPEN, CLOSED
|
OPEN, CLOSED
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ import java.util.NoSuchElementException;
|
|||||||
* @see GitHub#listNotifications() GitHub#listNotifications()
|
* @see GitHub#listNotifications() GitHub#listNotifications()
|
||||||
* @see GHRepository#listNotifications() GHRepository#listNotifications()
|
* @see GHRepository#listNotifications() GHRepository#listNotifications()
|
||||||
*/
|
*/
|
||||||
public class GHNotificationStream implements Iterable<GHThread> {
|
public class GHNotificationStream extends GitHubInteractiveObject implements Iterable<GHThread> {
|
||||||
private final GitHub root;
|
|
||||||
|
|
||||||
private Boolean all, participating;
|
private Boolean all, participating;
|
||||||
private String since;
|
private String since;
|
||||||
private String apiUrl;
|
private String apiUrl;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import javax.annotation.CheckForNull;
|
|||||||
*/
|
*/
|
||||||
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
||||||
justification = "JSON API")
|
justification = "JSON API")
|
||||||
public abstract class GHObject {
|
public abstract class GHObject extends GitHubInteractiveObject {
|
||||||
/**
|
/**
|
||||||
* Capture response HTTP headers on the state object.
|
* Capture response HTTP headers on the state object.
|
||||||
*/
|
*/
|
||||||
@@ -38,7 +38,7 @@ public abstract class GHObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by Jackson
|
* Called by Jackson
|
||||||
*
|
*
|
||||||
* @param responseInfo
|
* @param responseInfo
|
||||||
* the {@link GitHubResponse.ResponseInfo} to get headers from.
|
* the {@link GitHubResponse.ResponseInfo} to get headers from.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.INERTIA;
|
import static org.kohsuke.github.internal.Previews.INERTIA;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type GHOrganization.
|
* The type GHOrganization.
|
||||||
@@ -97,7 +97,7 @@ public class GHOrganization extends GHPerson {
|
|||||||
* @return the gh create repository builder
|
* @return the gh create repository builder
|
||||||
*/
|
*/
|
||||||
public GHCreateRepositoryBuilder createRepository(String name) {
|
public GHCreateRepositoryBuilder createRepository(String name) {
|
||||||
return new GHCreateRepositoryBuilder(root, "/orgs/" + login + "/repos", name);
|
return new GHCreateRepositoryBuilder(name, root, "/orgs/" + login + "/repos");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -181,7 +181,7 @@ public class GHOrganization extends GHPerson {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a team that has the given slug in its {@link GHTeam#getSlug()}
|
* Finds a team that has the given slug in its {@link GHTeam#getSlug()}
|
||||||
*
|
*
|
||||||
* @param slug
|
* @param slug
|
||||||
* the slug
|
* the slug
|
||||||
* @return the team by slug
|
* @return the team by slug
|
||||||
@@ -421,7 +421,7 @@ public class GHOrganization extends GHPerson {
|
|||||||
* The enum Permission.
|
* The enum Permission.
|
||||||
*/
|
*/
|
||||||
public enum Permission {
|
public enum Permission {
|
||||||
ADMIN, PUSH, PULL
|
ADMIN, MAINTAIN, PUSH, TRIAGE, PULL
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import java.util.Locale;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Permission for a user in a repository.
|
* Permission for a user in a repository.
|
||||||
*
|
*
|
||||||
* @see <a href="https://developer.github.com/v3/repos/collaborators/#review-a-users-permission-level">API</a>
|
* @see <a href="https://developer.github.com/v3/repos/collaborators/#review-a-users-permission-level">API</a>
|
||||||
*/
|
*/
|
||||||
class GHPermission {
|
class GHPermission {
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import java.util.TreeMap;
|
|||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
public abstract class GHPerson extends GHObject {
|
public abstract class GHPerson extends GHObject {
|
||||||
/* package almost final */ GitHub root;
|
|
||||||
|
|
||||||
// core data fields that exist even for "small" user data (such as the user info in pull request)
|
// core data fields that exist even for "small" user data (such as the user info in pull request)
|
||||||
protected String login, avatar_url;
|
protected String login, avatar_url;
|
||||||
@@ -154,10 +153,7 @@ public abstract class GHPerson extends GHObject {
|
|||||||
*/
|
*/
|
||||||
public GHRepository getRepository(String name) throws IOException {
|
public GHRepository getRepository(String name) throws IOException {
|
||||||
try {
|
try {
|
||||||
return root.createRequest()
|
return GHRepository.read(root, login, name);
|
||||||
.withUrlPath("/repos/" + login + '/' + name)
|
|
||||||
.fetch(GHRepository.class)
|
|
||||||
.wrap(root);
|
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -239,7 +235,7 @@ public abstract class GHPerson extends GHObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Twitter Username of this user, like "GitHub"
|
* Gets the Twitter Username of this user, like "GitHub"
|
||||||
*
|
*
|
||||||
* @return the Twitter username
|
* @return the Twitter username
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* the io exception
|
* the io exception
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import java.io.IOException;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.INERTIA;
|
import static org.kohsuke.github.internal.Previews.INERTIA;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A GitHub project.
|
* A GitHub project.
|
||||||
@@ -37,7 +37,6 @@ import static org.kohsuke.github.Previews.INERTIA;
|
|||||||
* @see <a href="https://developer.github.com/v3/projects/">Projects</a>
|
* @see <a href="https://developer.github.com/v3/projects/">Projects</a>
|
||||||
*/
|
*/
|
||||||
public class GHProject extends GHObject {
|
public class GHProject extends GHObject {
|
||||||
protected GitHub root;
|
|
||||||
protected GHObject owner;
|
protected GHObject owner;
|
||||||
|
|
||||||
private String owner_url;
|
private String owner_url;
|
||||||
@@ -80,10 +79,8 @@ public class GHProject extends GHObject {
|
|||||||
} else if (owner_url.contains("/users/")) {
|
} else if (owner_url.contains("/users/")) {
|
||||||
owner = root.createRequest().withUrlPath(getOwnerUrl().getPath()).fetch(GHUser.class).wrapUp(root);
|
owner = root.createRequest().withUrlPath(getOwnerUrl().getPath()).fetch(GHUser.class).wrapUp(root);
|
||||||
} else if (owner_url.contains("/repos/")) {
|
} else if (owner_url.contains("/repos/")) {
|
||||||
owner = root.createRequest()
|
String[] pathElements = getOwnerUrl().getPath().split("/");
|
||||||
.withUrlPath(getOwnerUrl().getPath())
|
owner = GHRepository.read(root, pathElements[1], pathElements[2]);
|
||||||
.fetch(GHRepository.class)
|
|
||||||
.wrap(root);
|
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
return null;
|
return null;
|
||||||
@@ -313,4 +310,4 @@ public class GHProject extends GHObject {
|
|||||||
.fetch(GHProjectColumn.class)
|
.fetch(GHProjectColumn.class)
|
||||||
.wrap(this);
|
.wrap(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.INERTIA;
|
import static org.kohsuke.github.internal.Previews.INERTIA;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type GHProjectCard.
|
* The type GHProjectCard.
|
||||||
@@ -14,7 +14,6 @@ import static org.kohsuke.github.Previews.INERTIA;
|
|||||||
* @author Gunnar Skjold
|
* @author Gunnar Skjold
|
||||||
*/
|
*/
|
||||||
public class GHProjectCard extends GHObject {
|
public class GHProjectCard extends GHObject {
|
||||||
private GitHub root;
|
|
||||||
private GHProject project;
|
private GHProject project;
|
||||||
private GHProjectColumn column;
|
private GHProjectColumn column;
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.INERTIA;
|
import static org.kohsuke.github.internal.Previews.INERTIA;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type GHProjectColumn.
|
* The type GHProjectColumn.
|
||||||
@@ -12,7 +12,6 @@ import static org.kohsuke.github.Previews.INERTIA;
|
|||||||
* @author Gunnar Skjold
|
* @author Gunnar Skjold
|
||||||
*/
|
*/
|
||||||
public class GHProjectColumn extends GHObject {
|
public class GHProjectColumn extends GHObject {
|
||||||
protected GitHub root;
|
|
||||||
protected GHProject project;
|
protected GHProject project;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import java.io.IOException;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -37,7 +36,8 @@ import java.util.Objects;
|
|||||||
|
|
||||||
import javax.annotation.CheckForNull;
|
import javax.annotation.CheckForNull;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.SHADOW_CAT;
|
import static org.kohsuke.github.internal.Previews.LYDIAN;
|
||||||
|
import static org.kohsuke.github.internal.Previews.SHADOW_CAT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A pull request.
|
* A pull request.
|
||||||
@@ -72,13 +72,6 @@ public class GHPullRequest extends GHIssue implements Refreshable {
|
|||||||
private GHUser[] requested_reviewers;
|
private GHUser[] requested_reviewers;
|
||||||
private GHTeam[] requested_teams;
|
private GHTeam[] requested_teams;
|
||||||
|
|
||||||
/**
|
|
||||||
* GitHub doesn't return some properties of {@link GHIssue} when requesting the GET on the 'pulls' API route as
|
|
||||||
* opposed to 'issues' API route. This flag remembers whether we made the GET call on the 'issues' route on this
|
|
||||||
* object to fill in those missing details
|
|
||||||
*/
|
|
||||||
private transient boolean fetchedIssueDetails;
|
|
||||||
|
|
||||||
GHPullRequest wrapUp(GHRepository owner) {
|
GHPullRequest wrapUp(GHRepository owner) {
|
||||||
this.wrap(owner);
|
this.wrap(owner);
|
||||||
return wrapUp(owner.root);
|
return wrapUp(owner.root);
|
||||||
@@ -177,12 +170,6 @@ public class GHPullRequest extends GHIssue implements Refreshable {
|
|||||||
return GitHubClient.parseDate(merged_at);
|
return GitHubClient.parseDate(merged_at);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<GHLabel> getLabels() throws IOException {
|
|
||||||
fetchIssue();
|
|
||||||
return super.getLabels();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GHUser getClosedBy() {
|
public GHUser getClosedBy() {
|
||||||
return null;
|
return null;
|
||||||
@@ -565,6 +552,41 @@ public class GHPullRequest extends GHIssue implements Refreshable {
|
|||||||
.send();
|
.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the base branch on the pull request
|
||||||
|
*
|
||||||
|
* @param newBaseBranch
|
||||||
|
* the name of the new base branch
|
||||||
|
* @throws IOException
|
||||||
|
* the io exception
|
||||||
|
* @return the updated pull request
|
||||||
|
*/
|
||||||
|
public GHPullRequest setBaseBranch(String newBaseBranch) throws IOException {
|
||||||
|
return root.createRequest()
|
||||||
|
.method("PATCH")
|
||||||
|
.with("base", newBaseBranch)
|
||||||
|
.withUrlPath(getApiRoute())
|
||||||
|
.fetch(GHPullRequest.class)
|
||||||
|
.wrapUp(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the branch. The same as pressing the button in the web GUI.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* the io exception
|
||||||
|
*/
|
||||||
|
@Preview(LYDIAN)
|
||||||
|
@Deprecated
|
||||||
|
public void updateBranch() throws IOException {
|
||||||
|
root.createRequest()
|
||||||
|
.withPreview(LYDIAN)
|
||||||
|
.method("PUT")
|
||||||
|
.with("expected_head_sha", head.getSha())
|
||||||
|
.withUrlPath(getApiRoute() + "/update-branch")
|
||||||
|
.send();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge this pull request.
|
* Merge this pull request.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -626,10 +648,4 @@ public class GHPullRequest extends GHIssue implements Refreshable {
|
|||||||
MERGE, SQUASH, REBASE
|
MERGE, SQUASH, REBASE
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchIssue() throws IOException {
|
|
||||||
if (!fetchedIssueDetails) {
|
|
||||||
root.createRequest().withUrlPath(getIssuesApiRoute()).fetchInto(this);
|
|
||||||
fetchedIssueDetails = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
86
src/main/java/org/kohsuke/github/GHPullRequestChanges.java
Normal file
86
src/main/java/org/kohsuke/github/GHPullRequestChanges.java
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper to define changed fields on pull_request action="edited"
|
||||||
|
*
|
||||||
|
* @see GHEventPayload.PullRequest
|
||||||
|
*/
|
||||||
|
@SuppressFBWarnings("UWF_UNWRITTEN_FIELD")
|
||||||
|
public class GHPullRequestChanges {
|
||||||
|
|
||||||
|
private GHCommitPointer base;
|
||||||
|
private GHFrom title;
|
||||||
|
private GHFrom body;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Old target branch for pull request.
|
||||||
|
*
|
||||||
|
* @return old target branch info (or null if not changed)
|
||||||
|
*/
|
||||||
|
public GHCommitPointer getBase() {
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Old pull request title.
|
||||||
|
*
|
||||||
|
* @return old pull request title (or null if not changed)
|
||||||
|
*/
|
||||||
|
public GHFrom getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Old pull request body.
|
||||||
|
*
|
||||||
|
* @return old pull request body (or null if not changed)
|
||||||
|
*/
|
||||||
|
public GHFrom getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.kohsuke.github.GHCommitPointer
|
||||||
|
*/
|
||||||
|
public static class GHCommitPointer {
|
||||||
|
private GHFrom ref;
|
||||||
|
private GHFrom sha;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Named ref to the commit. This (from value) appears to be a "short ref" that doesn't include "refs/heads/"
|
||||||
|
* portion.
|
||||||
|
*
|
||||||
|
* @return the ref
|
||||||
|
*/
|
||||||
|
public GHFrom getRef() {
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHA1 of the commit.
|
||||||
|
*
|
||||||
|
* @return sha
|
||||||
|
*/
|
||||||
|
public GHFrom getSha() {
|
||||||
|
return sha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for changed values.
|
||||||
|
*/
|
||||||
|
public static class GHFrom {
|
||||||
|
private String from;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Previous value that was changed.
|
||||||
|
*
|
||||||
|
* @return previous value
|
||||||
|
*/
|
||||||
|
public String getFrom() {
|
||||||
|
return from;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.SHADOW_CAT;
|
import static org.kohsuke.github.internal.Previews.SHADOW_CAT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists up pull requests with some filtering and sorting.
|
* Lists up pull requests with some filtering and sorting.
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public class GHPullRequestReview extends GHObject {
|
|||||||
private String commit_id;
|
private String commit_id;
|
||||||
private GHPullRequestReviewState state;
|
private GHPullRequestReviewState state;
|
||||||
private String submitted_at;
|
private String submitted_at;
|
||||||
|
private String html_url;
|
||||||
|
|
||||||
GHPullRequestReview wrapUp(GHPullRequest owner) {
|
GHPullRequestReview wrapUp(GHPullRequest owner) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
@@ -102,7 +103,7 @@ public class GHPullRequestReview extends GHObject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URL getHtmlUrl() {
|
public URL getHtmlUrl() {
|
||||||
return null;
|
return GitHubClient.parseURL(html_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import java.net.URL;
|
|||||||
|
|
||||||
import javax.annotation.CheckForNull;
|
import javax.annotation.CheckForNull;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.*;
|
import static org.kohsuke.github.internal.Previews.SQUIRREL_GIRL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Review comment to the pull request
|
* Review comment to the pull request
|
||||||
@@ -153,7 +153,20 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
|
|||||||
* @return the api route
|
* @return the api route
|
||||||
*/
|
*/
|
||||||
protected String getApiRoute() {
|
protected String getApiRoute() {
|
||||||
return "/repos/" + owner.getRepository().getFullName() + "/pulls/comments/" + getId();
|
return getApiRoute(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets api route.
|
||||||
|
*
|
||||||
|
* @param includePullNumber
|
||||||
|
* if true, includes the owning pull request's number in the route.
|
||||||
|
*
|
||||||
|
* @return the api route
|
||||||
|
*/
|
||||||
|
protected String getApiRoute(boolean includePullNumber) {
|
||||||
|
return "/repos/" + owner.getRepository().getFullName() + "/pulls"
|
||||||
|
+ (includePullNumber ? "/" + owner.getNumber() : "") + "/comments/" + getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -192,13 +205,12 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
|
|||||||
return owner.root.createRequest()
|
return owner.root.createRequest()
|
||||||
.method("POST")
|
.method("POST")
|
||||||
.with("body", body)
|
.with("body", body)
|
||||||
.with("in_reply_to", getId())
|
.withUrlPath(getApiRoute(true) + "/replies")
|
||||||
.withUrlPath(getApiRoute() + "/comments")
|
|
||||||
.fetch(GHPullRequestReviewComment.class)
|
.fetch(GHPullRequestReviewComment.class)
|
||||||
.wrapUp(owner);
|
.wrapUp(owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview(SQUIRREL_GIRL)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHReaction createReaction(ReactionContent content) throws IOException {
|
public GHReaction createReaction(ReactionContent content) throws IOException {
|
||||||
return owner.root.createRequest()
|
return owner.root.createRequest()
|
||||||
@@ -210,7 +222,7 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
|
|||||||
.wrap(owner.root);
|
.wrap(owner.root);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview(SQUIRREL_GIRL)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public PagedIterable<GHReaction> listReactions() {
|
public PagedIterable<GHReaction> listReactions() {
|
||||||
return owner.root.createRequest()
|
return owner.root.createRequest()
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ package org.kohsuke.github;
|
|||||||
* the type parameter
|
* the type parameter
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
public abstract class GHQueryBuilder<T> {
|
public abstract class GHQueryBuilder<T> extends GitHubInteractiveObject {
|
||||||
protected final GitHub root;
|
|
||||||
protected final Requester req;
|
protected final Requester req;
|
||||||
|
|
||||||
GHQueryBuilder(GitHub root) {
|
GHQueryBuilder(GitHub root) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.DateTimeParseException;
|
import java.time.format.DateTimeParseException;
|
||||||
@@ -29,7 +30,7 @@ public class GHRateLimit {
|
|||||||
/**
|
/**
|
||||||
* Remaining calls that can be made.
|
* Remaining calls that can be made.
|
||||||
*
|
*
|
||||||
* @deprecated This value should never have been made public. Use {@link #getRemaining()}
|
* @deprecated This field should never have been made public. Use {@link #getRemaining()}
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public int remaining;
|
public int remaining;
|
||||||
@@ -37,7 +38,7 @@ public class GHRateLimit {
|
|||||||
/**
|
/**
|
||||||
* Allotted API call per hour.
|
* Allotted API call per hour.
|
||||||
*
|
*
|
||||||
* @deprecated This value should never have been made public. Use {@link #getLimit()}
|
* @deprecated This field should never have been made public. Use {@link #getLimit()}
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public int limit;
|
public int limit;
|
||||||
@@ -48,7 +49,7 @@ public class GHRateLimit {
|
|||||||
* date. To use this field in any meaningful way, it must be converted to a long using {@link Date#getTime()}
|
* date. To use this field in any meaningful way, it must be converted to a long using {@link Date#getTime()}
|
||||||
* multiplied by 1000.
|
* multiplied by 1000.
|
||||||
*
|
*
|
||||||
* @deprecated This value should never have been made public. Use {@link #getResetDate()}
|
* @deprecated This field should never have been made public. Use {@link #getResetDate()}
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Date reset;
|
public Date reset;
|
||||||
@@ -65,17 +66,58 @@ public class GHRateLimit {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
private final Record integrationManifest;
|
private final Record integrationManifest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default GHRateLimit provided to new {@link GitHubClient}s.
|
||||||
|
*
|
||||||
|
* Contains all expired records that will cause {@link GitHubClient#rateLimit(RateLimitTarget)} to refresh with new
|
||||||
|
* data when called.
|
||||||
|
*
|
||||||
|
* Private, but made internal for testing.
|
||||||
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
static GHRateLimit Unknown() {
|
static final GHRateLimit DEFAULT = new GHRateLimit(UnknownLimitRecord.DEFAULT,
|
||||||
return new GHRateLimit(new UnknownLimitRecord(),
|
UnknownLimitRecord.DEFAULT,
|
||||||
new UnknownLimitRecord(),
|
UnknownLimitRecord.DEFAULT,
|
||||||
new UnknownLimitRecord(),
|
UnknownLimitRecord.DEFAULT);
|
||||||
new UnknownLimitRecord());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link GHRateLimit} from a single record for the specified endpoint with place holders for other
|
||||||
|
* records.
|
||||||
|
*
|
||||||
|
* This is used to create {@link GHRateLimit} instances that can merged with other instances.
|
||||||
|
*
|
||||||
|
* @param record
|
||||||
|
* the rate limit record. Can be a regular {@link Record} constructed from header information or an
|
||||||
|
* {@link UnknownLimitRecord} placeholder.
|
||||||
|
* @param rateLimitTarget
|
||||||
|
* which rate limit record to fill
|
||||||
|
* @return a new {@link GHRateLimit} instance containing the supplied record
|
||||||
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
static GHRateLimit fromHeaderRecord(Record header) {
|
static GHRateLimit fromRecord(@Nonnull Record record, @Nonnull RateLimitTarget rateLimitTarget) {
|
||||||
return new GHRateLimit(header, new UnknownLimitRecord(), new UnknownLimitRecord(), new UnknownLimitRecord());
|
if (rateLimitTarget == RateLimitTarget.CORE || rateLimitTarget == RateLimitTarget.NONE) {
|
||||||
|
return new GHRateLimit(record,
|
||||||
|
UnknownLimitRecord.DEFAULT,
|
||||||
|
UnknownLimitRecord.DEFAULT,
|
||||||
|
UnknownLimitRecord.DEFAULT);
|
||||||
|
} else if (rateLimitTarget == RateLimitTarget.SEARCH) {
|
||||||
|
return new GHRateLimit(UnknownLimitRecord.DEFAULT,
|
||||||
|
record,
|
||||||
|
UnknownLimitRecord.DEFAULT,
|
||||||
|
UnknownLimitRecord.DEFAULT);
|
||||||
|
} else if (rateLimitTarget == RateLimitTarget.GRAPHQL) {
|
||||||
|
return new GHRateLimit(UnknownLimitRecord.DEFAULT,
|
||||||
|
UnknownLimitRecord.DEFAULT,
|
||||||
|
record,
|
||||||
|
UnknownLimitRecord.DEFAULT);
|
||||||
|
} else if (rateLimitTarget == RateLimitTarget.INTEGRATION_MANIFEST) {
|
||||||
|
return new GHRateLimit(UnknownLimitRecord.DEFAULT,
|
||||||
|
UnknownLimitRecord.DEFAULT,
|
||||||
|
UnknownLimitRecord.DEFAULT,
|
||||||
|
record);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unknown rate limit target: " + rateLimitTarget.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonCreator
|
@JsonCreator
|
||||||
@@ -142,7 +184,7 @@ public class GHRateLimit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the rate limit reset date for this instance has passed.
|
* Whether the reset date for the Core API rate limit has passed.
|
||||||
*
|
*
|
||||||
* @return true if the rate limit reset date has passed. Otherwise false.
|
* @return true if the rate limit reset date has passed. Otherwise false.
|
||||||
* @since 1.100
|
* @since 1.100
|
||||||
@@ -152,7 +194,7 @@ public class GHRateLimit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The core object provides your rate limit status for all non-search-related resources in the REST API.
|
* The core object provides the rate limit status for all non-search-related resources in the REST API.
|
||||||
*
|
*
|
||||||
* @return a rate limit record
|
* @return a rate limit record
|
||||||
* @since 1.100
|
* @since 1.100
|
||||||
@@ -163,42 +205,43 @@ public class GHRateLimit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The search object provides your rate limit status for the Search API. TODO: integrate with header limit updating.
|
* The search record provides the rate limit status for the Search API.
|
||||||
* Issue #605.
|
|
||||||
*
|
*
|
||||||
* @return a rate limit record
|
* @return a rate limit record
|
||||||
|
* @since 1.115
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
Record getSearch() {
|
public Record getSearch() {
|
||||||
return search;
|
return search;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The graphql object provides your rate limit status for the GraphQL API. TODO: integrate with header limit
|
* The graphql record provides the rate limit status for the GraphQL API.
|
||||||
* updating. Issue #605.
|
|
||||||
*
|
*
|
||||||
* @return a rate limit record
|
* @return a rate limit record
|
||||||
|
* @since 1.115
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
Record getGraphQL() {
|
public Record getGraphQL() {
|
||||||
return graphql;
|
return graphql;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The integration_manifest object provides your rate limit status for the GitHub App Manifest code conversion
|
* The integration manifest record provides the rate limit status for the GitHub App Manifest code conversion
|
||||||
* endpoint. TODO: integrate with header limit updating. Issue #605.
|
* endpoint.
|
||||||
*
|
*
|
||||||
* @return a rate limit record
|
* @return a rate limit record
|
||||||
|
* @since 1.115
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
Record getIntegrationManifest() {
|
public Record getIntegrationManifest() {
|
||||||
return integrationManifest;
|
return integrationManifest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "GHRateLimit {" + "core " + getCore().toString() + "search " + getSearch().toString() + "graphql "
|
return "GHRateLimit {" + "core " + getCore().toString() + ", search " + getSearch().toString() + ", graphql "
|
||||||
+ getGraphQL().toString() + "integrationManifest " + getIntegrationManifest().toString() + '}';
|
+ getGraphQL().toString() + ", integrationManifest " + getIntegrationManifest().toString() + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -221,44 +264,111 @@ public class GHRateLimit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the appropriate {@link Record} for a particular url path.
|
* Merge a {@link GHRateLimit} with another one to create a new {@link GHRateLimit} keeping the latest
|
||||||
|
* {@link Record}s from each.
|
||||||
*
|
*
|
||||||
* @param urlPath
|
* @param newLimit
|
||||||
* the url path of the request
|
* {@link GHRateLimit} with potentially updated {@link Record}s.
|
||||||
* @return the {@link Record} for a url path.
|
* @return a merged {@link GHRateLimit} with the latest {@link Record}s from these two instances. If the merged
|
||||||
|
* instance is equal to the current instance, the current instance is returned.
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
Record getRecordForUrlPath(@Nonnull String urlPath) {
|
GHRateLimit getMergedRateLimit(@Nonnull GHRateLimit newLimit) {
|
||||||
if (urlPath.equals("/rate_limit")) {
|
|
||||||
return new UnknownLimitRecord();
|
GHRateLimit merged = new GHRateLimit(getCore().currentOrUpdated(newLimit.getCore()),
|
||||||
} else if (urlPath.startsWith("/search")) {
|
getSearch().currentOrUpdated(newLimit.getSearch()),
|
||||||
return getSearch();
|
getGraphQL().currentOrUpdated(newLimit.getGraphQL()),
|
||||||
} else if (urlPath.startsWith("/graphql")) {
|
getIntegrationManifest().currentOrUpdated(newLimit.getIntegrationManifest()));
|
||||||
return getGraphQL();
|
|
||||||
} else if (urlPath.startsWith("/app-manifests")) {
|
if (merged.equals(this)) {
|
||||||
return getIntegrationManifest();
|
merged = this;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the specified {@link Record}.
|
||||||
|
*
|
||||||
|
* {@link RateLimitTarget#NONE} will return {@link UnknownLimitRecord#DEFAULT} to prevent any clients from
|
||||||
|
* accidentally waiting on that record to reset before continuing.
|
||||||
|
*
|
||||||
|
* @param rateLimitTarget
|
||||||
|
* the target rate limit record
|
||||||
|
* @return the target {@link Record} from this instance.
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
Record getRecord(@Nonnull RateLimitTarget rateLimitTarget) {
|
||||||
|
if (rateLimitTarget == RateLimitTarget.CORE) {
|
||||||
return getCore();
|
return getCore();
|
||||||
|
} else if (rateLimitTarget == RateLimitTarget.SEARCH) {
|
||||||
|
return getSearch();
|
||||||
|
} else if (rateLimitTarget == RateLimitTarget.GRAPHQL) {
|
||||||
|
return getGraphQL();
|
||||||
|
} else if (rateLimitTarget == RateLimitTarget.INTEGRATION_MANIFEST) {
|
||||||
|
return getIntegrationManifest();
|
||||||
|
} else if (rateLimitTarget == RateLimitTarget.NONE) {
|
||||||
|
return UnknownLimitRecord.DEFAULT;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unknown rate limit target: " + rateLimitTarget.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A limit record used as a placeholder when the the actual limit is not known.
|
* A limit record used as a placeholder when the the actual limit is not known.
|
||||||
* <p>
|
|
||||||
* Has a large limit and long duration so that it will doesn't expire too often.
|
|
||||||
*
|
*
|
||||||
* @since 1.100
|
* @since 1.100
|
||||||
*/
|
*/
|
||||||
public static class UnknownLimitRecord extends Record {
|
public static class UnknownLimitRecord extends Record {
|
||||||
|
|
||||||
// One hour
|
private static final long defaultUnknownLimitResetSeconds = Duration.ofSeconds(30).getSeconds();
|
||||||
private static final long unknownLimitResetSeconds = 60L * 60L;
|
|
||||||
|
/**
|
||||||
|
* The number of seconds until a {@link UnknownLimitRecord} will expire.
|
||||||
|
*
|
||||||
|
* This is set to a somewhat short duration, rather than a long one. This avoids
|
||||||
|
* {@link {@link GitHubClient#rateLimit(RateLimitTarget)}} requesting rate limit updates continuously, but also
|
||||||
|
* avoids holding on to stale unknown records indefinitely.
|
||||||
|
*
|
||||||
|
* When merging {@link GHRateLimit} instances, {@link UnknownLimitRecord}s will be superseded by incoming
|
||||||
|
* regular {@link Record}s.
|
||||||
|
*
|
||||||
|
* @see GHRateLimit#getMergedRateLimit(GHRateLimit)
|
||||||
|
*/
|
||||||
|
static long unknownLimitResetSeconds = defaultUnknownLimitResetSeconds;
|
||||||
|
|
||||||
static final int unknownLimit = 1000000;
|
static final int unknownLimit = 1000000;
|
||||||
static final int unknownRemaining = 999999;
|
static final int unknownRemaining = 999999;
|
||||||
|
|
||||||
private UnknownLimitRecord() {
|
// The default UnknownLimitRecord is an expired record.
|
||||||
super(unknownLimit, unknownRemaining, System.currentTimeMillis() / 1000L + unknownLimitResetSeconds);
|
private static final UnknownLimitRecord DEFAULT = new UnknownLimitRecord(Long.MIN_VALUE);
|
||||||
|
|
||||||
|
// The starting current UnknownLimitRecord is an expired record.
|
||||||
|
private static UnknownLimitRecord current = DEFAULT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new unknown record that resets at the specified time.
|
||||||
|
*
|
||||||
|
* @param resetEpochSeconds
|
||||||
|
* the epoch second time when this record will expire.
|
||||||
|
*/
|
||||||
|
private UnknownLimitRecord(long resetEpochSeconds) {
|
||||||
|
super(unknownLimit, unknownRemaining, resetEpochSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
static synchronized Record current() {
|
||||||
|
if (current.isExpired()) {
|
||||||
|
current = new UnknownLimitRecord(System.currentTimeMillis() / 1000L + unknownLimitResetSeconds);
|
||||||
|
}
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the current UnknownLimitRecord. For use during testing only.
|
||||||
|
*/
|
||||||
|
static synchronized void reset() {
|
||||||
|
current = DEFAULT;
|
||||||
|
unknownLimitResetSeconds = defaultUnknownLimitResetSeconds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,14 +384,12 @@ public class GHRateLimit {
|
|||||||
private final int remaining;
|
private final int remaining;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allotted API call per hour.
|
* Allotted API call per time period.
|
||||||
*/
|
*/
|
||||||
private final int limit;
|
private final int limit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The time at which the current rate limit window resets in UTC epoch seconds.
|
* The time at which the current rate limit window resets in UTC epoch seconds.
|
||||||
*
|
|
||||||
* This is the raw value returned by the server.
|
|
||||||
*/
|
*/
|
||||||
private final long resetEpochSeconds;
|
private final long resetEpochSeconds;
|
||||||
|
|
||||||
@@ -291,9 +399,11 @@ public class GHRateLimit {
|
|||||||
private final long createdAtEpochSeconds = System.currentTimeMillis() / 1000;
|
private final long createdAtEpochSeconds = System.currentTimeMillis() / 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The time at which the rate limit will reset. This value is calculated based on
|
* The date at which the rate limit will reset, adjusted to local machine time if the local machine's clock not
|
||||||
* {@link #getResetEpochSeconds()} by calling {@link #calculateResetDate}. If the clock on the local machine not
|
* synchronized with to the same clock as the GitHub server.
|
||||||
* synchronized with the server clock, this time value will be adjusted to match the local machine's clock.
|
*
|
||||||
|
* @see #calculateResetDate(String)
|
||||||
|
* @see #getResetDate()
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private final Date resetDate;
|
private final Date resetDate;
|
||||||
@@ -341,12 +451,58 @@ public class GHRateLimit {
|
|||||||
this.resetDate = calculateResetDate(updatedAt);
|
this.resetDate = calculateResetDate(updatedAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the current {@link Record} is outdated compared to another. Rate Limit dates are only accurate
|
||||||
|
* to the second, so we look at other information in the record as well.
|
||||||
|
*
|
||||||
|
* {@link Record}s with earlier {@link #getResetEpochSeconds()} are replaced by those with later.
|
||||||
|
* {@link Record}s with the same {@link #getResetEpochSeconds()} are replaced by those with less remaining
|
||||||
|
* count.
|
||||||
|
*
|
||||||
|
* {@link UnknownLimitRecord}s compare with each other like regular {@link Record}s.
|
||||||
|
*
|
||||||
|
* {@link Record}s are replaced by {@link UnknownLimitRecord}s only when the current {@link Record} is expired
|
||||||
|
* and the {@link UnknownLimitRecord} is not. Otherwise Regular {@link Record}s are not replaced by
|
||||||
|
* {@link UnknownLimitRecord}s.
|
||||||
|
*
|
||||||
|
* Expiration is only considered after other checks, meaning expired records may sometimes be replaced by other
|
||||||
|
* expired records.
|
||||||
|
*
|
||||||
|
* @param other
|
||||||
|
* the other {@link Record}
|
||||||
|
* @return the {@link Record} that is most current
|
||||||
|
*/
|
||||||
|
Record currentOrUpdated(@Nonnull Record other) {
|
||||||
|
// This set of checks avoids most calls to isExpired()
|
||||||
|
// Depends on UnknownLimitRecord.current() to prevent continuous updating of GHRateLimit rateLimit()
|
||||||
|
if (getResetEpochSeconds() > other.getResetEpochSeconds()
|
||||||
|
|| (getResetEpochSeconds() == other.getResetEpochSeconds()
|
||||||
|
&& getRemaining() <= other.getRemaining())) {
|
||||||
|
// If the current record has a later reset
|
||||||
|
// or the current record has the same reset and fewer or same requests remaining
|
||||||
|
// Then it is most recent
|
||||||
|
return this;
|
||||||
|
} else if (!(other instanceof UnknownLimitRecord)) {
|
||||||
|
// If the above is not the case that means other has a later reset
|
||||||
|
// or the same resent and fewer requests remaining.
|
||||||
|
// If the other record is not an unknown record, the the other is more recent
|
||||||
|
return other;
|
||||||
|
} else if (this.isExpired() && !other.isExpired()) {
|
||||||
|
// The other is an unknown record.
|
||||||
|
// If the current record has expired and the other hasn't, return the other.
|
||||||
|
return other;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If none of the above, the current record is most valid.
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recalculates the {@link #resetDate} relative to the local machine clock.
|
* Recalculates the {@link #resetDate} relative to the local machine clock.
|
||||||
* <p>
|
* <p>
|
||||||
* {@link RateLimitChecker}s and {@link RateLimitHandler}s use {@link #getResetDate()} to make decisions about
|
* {@link RateLimitChecker}s and {@link RateLimitHandler}s use {@link #getResetDate()} to make decisions about
|
||||||
* how long to wait for until for the rate limit to reset. That means that {@link #getResetDate()} needs to be
|
* how long to wait for until for the rate limit to reset. That means that {@link #getResetDate()} needs to be
|
||||||
* accurate to the local machine.
|
* calculated based on the local machine clock.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* When we say that the clock on two machines is "synchronized", we mean that the UTC time returned from
|
* When we say that the clock on two machines is "synchronized", we mean that the UTC time returned from
|
||||||
@@ -415,7 +571,7 @@ public class GHRateLimit {
|
|||||||
* {@link #getResetDate()} or implement a {@link RateLimitChecker} instead.
|
* {@link #getResetDate()} or implement a {@link RateLimitChecker} instead.
|
||||||
*
|
*
|
||||||
* @return a long representing the time in epoch seconds when the rate limit will reset
|
* @return a long representing the time in epoch seconds when the rate limit will reset
|
||||||
* @see #getResetDate() #getResetDate()
|
* @see #getResetDate()
|
||||||
*/
|
*/
|
||||||
public long getResetEpochSeconds() {
|
public long getResetEpochSeconds() {
|
||||||
return resetEpochSeconds;
|
return resetEpochSeconds;
|
||||||
@@ -424,6 +580,8 @@ public class GHRateLimit {
|
|||||||
/**
|
/**
|
||||||
* Whether the rate limit reset date indicated by this instance is expired
|
* Whether the rate limit reset date indicated by this instance is expired
|
||||||
*
|
*
|
||||||
|
* If attempting to wait for the rate limit to reset, consider implementing a {@link RateLimitChecker} instead.
|
||||||
|
*
|
||||||
* @return true if the rate limit reset date has passed. Otherwise false.
|
* @return true if the rate limit reset date has passed. Otherwise false.
|
||||||
*/
|
*/
|
||||||
public boolean isExpired() {
|
public boolean isExpired() {
|
||||||
@@ -431,8 +589,8 @@ public class GHRateLimit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the date at which the rate limit will reset, adjusted to local machine time if the local machine's
|
* The date at which the rate limit will reset, adjusted to local machine time if the local machine's clock not
|
||||||
* clock not synchronized with to the same clock as the GitHub server.
|
* synchronized with to the same clock as the GitHub server.
|
||||||
*
|
*
|
||||||
* If attempting to wait for the rate limit to reset, consider implementing a {@link RateLimitChecker} instead.
|
* If attempting to wait for the rate limit to reset, consider implementing a {@link RateLimitChecker} instead.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package org.kohsuke.github;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.*;
|
import static org.kohsuke.github.internal.Previews.SQUIRREL_GIRL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reaction to issue, comment, PR, and so on.
|
* Reaction to issue, comment, PR, and so on.
|
||||||
@@ -11,10 +11,9 @@ import static org.kohsuke.github.Previews.*;
|
|||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
* @see Reactable
|
* @see Reactable
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(SQUIRREL_GIRL)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public class GHReaction extends GHObject {
|
public class GHReaction extends GHObject {
|
||||||
private GitHub root;
|
|
||||||
|
|
||||||
private GHUser user;
|
private GHUser user;
|
||||||
private ReactionContent content;
|
private ReactionContent content;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -10,9 +11,7 @@ import java.net.URL;
|
|||||||
*
|
*
|
||||||
* @author Michael Clarke
|
* @author Michael Clarke
|
||||||
*/
|
*/
|
||||||
public class GHRef {
|
public class GHRef extends GitHubInteractiveObject {
|
||||||
/* package almost final */ GitHub root;
|
|
||||||
|
|
||||||
private String ref, url;
|
private String ref, url;
|
||||||
private GHObject object;
|
private GHObject object;
|
||||||
|
|
||||||
@@ -90,6 +89,78 @@ public class GHRef {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrive a ref of the given type for the current GitHub repository.
|
||||||
|
*
|
||||||
|
* @param repository
|
||||||
|
* the repository to read from
|
||||||
|
* @param refName
|
||||||
|
* eg: heads/branch
|
||||||
|
* @return refs matching the request type
|
||||||
|
* @throws IOException
|
||||||
|
* on failure communicating with GitHub, potentially due to an invalid ref type being requested
|
||||||
|
*/
|
||||||
|
static GHRef read(GHRepository repository, String refName) throws IOException {
|
||||||
|
// Also accept e.g. "refs/heads/branch" for consistency with createRef().
|
||||||
|
if (refName.startsWith("refs/")) {
|
||||||
|
refName = refName.replaceFirst("refs/", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// We would expect this to use `git/ref/%s` but some versions of GHE seem to not support it
|
||||||
|
// Instead use `git/refs/%s` and check the result actually matches the ref
|
||||||
|
GHRef result = null;
|
||||||
|
try {
|
||||||
|
result = repository.root.createRequest()
|
||||||
|
.withUrlPath(repository.getApiTailUrl(String.format("git/refs/%s", refName)))
|
||||||
|
.fetch(GHRef.class)
|
||||||
|
.wrap(repository.root);
|
||||||
|
} catch (IOException e) {
|
||||||
|
// If the parse exception is due to the above returning an array instead of a single ref
|
||||||
|
// that means the individual ref did not exist. Handled by result check below.
|
||||||
|
// Otherwise, rethrow.
|
||||||
|
if (!(e.getCause() instanceof JsonMappingException)) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that the ref returned is the one requested
|
||||||
|
// Used .endsWith(refName) instead of .equals("refs/" + refName) to workaround a GitBucket
|
||||||
|
// issue where the "ref" field omits the "refs/" prefix. "endsWith()" is functionally
|
||||||
|
// the same for this scenario - the server refs matching is prefix-based, so
|
||||||
|
// a ref that ends with the correct string will always be the correct one.
|
||||||
|
if (result == null || !result.getRef().endsWith(refName)) {
|
||||||
|
throw new GHFileNotFoundException(String.format("git/refs/%s", refName)
|
||||||
|
+ " {\"message\":\"Not Found\",\"documentation_url\":\"https://developer.github.com/v3/git/refs/#get-a-reference\"}");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all refs of the given type for the current GitHub repository.
|
||||||
|
*
|
||||||
|
* @param repository
|
||||||
|
* the repository to read from
|
||||||
|
* @param refType
|
||||||
|
* the type of reg to search for e.g. <code>tags</code> or <code>commits</code>
|
||||||
|
* @return paged iterable of all refs of the specified type
|
||||||
|
* @throws IOException
|
||||||
|
* on failure communicating with GitHub, potentially due to an invalid ref type being requested
|
||||||
|
*/
|
||||||
|
static PagedIterable<GHRef> readMatching(GHRepository repository, String refType) throws IOException {
|
||||||
|
if (refType.startsWith("refs/")) {
|
||||||
|
refType = refType.replaceFirst("refs/", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
String url = repository.getApiTailUrl(String.format("git/refs/%s", refType));
|
||||||
|
// if no types, do not end with slash just to be safe.
|
||||||
|
if (refType.equals("")) {
|
||||||
|
url = url.substring(0, url.length() - 1);
|
||||||
|
}
|
||||||
|
return repository.root.createRequest()
|
||||||
|
.withUrlPath(url)
|
||||||
|
.toIterable(GHRef[].class, item -> item.wrap(repository.root));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type GHObject.
|
* The type GHObject.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -15,14 +15,15 @@ import static java.lang.String.*;
|
|||||||
* Release in a github repository.
|
* Release in a github repository.
|
||||||
*
|
*
|
||||||
* @see GHRepository#getReleases() GHRepository#getReleases()
|
* @see GHRepository#getReleases() GHRepository#getReleases()
|
||||||
|
* @see GHRepository#listReleases() () GHRepository#listReleases()
|
||||||
* @see GHRepository#createRelease(String) GHRepository#createRelease(String)
|
* @see GHRepository#createRelease(String) GHRepository#createRelease(String)
|
||||||
*/
|
*/
|
||||||
public class GHRelease extends GHObject {
|
public class GHRelease extends GHObject {
|
||||||
GitHub root;
|
|
||||||
GHRepository owner;
|
GHRepository owner;
|
||||||
|
|
||||||
private String html_url;
|
private String html_url;
|
||||||
private String assets_url;
|
private String assets_url;
|
||||||
|
private List<GHAsset> assets;
|
||||||
private String upload_url;
|
private String upload_url;
|
||||||
private String tag_name;
|
private String tag_name;
|
||||||
private String target_commitish;
|
private String target_commitish;
|
||||||
@@ -249,18 +250,44 @@ public class GHRelease extends GHObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets assets.
|
* Get the cached assets.
|
||||||
|
*
|
||||||
|
* @return the assets
|
||||||
|
*
|
||||||
|
* @deprecated This should be the default behavior of {@link #getAssets()} in a future release. This method is
|
||||||
|
* introduced in addition to enable a transition to using cached asset information while keeping the
|
||||||
|
* existing logic in place for backwards compatibility.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public List<GHAsset> assets() {
|
||||||
|
return assets;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-fetch the assets of this release.
|
||||||
|
*
|
||||||
|
* @return the assets
|
||||||
|
* @throws IOException
|
||||||
|
* the io exception
|
||||||
|
* @deprecated The behavior of this method will change in a future release. It will then provide cached assets as
|
||||||
|
* provided by {@link #assets()}. Use {@link #listAssets()} instead to fetch up-to-date information of
|
||||||
|
* assets.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public List<GHAsset> getAssets() throws IOException {
|
||||||
|
return listAssets().toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-fetch the assets of this release.
|
||||||
*
|
*
|
||||||
* @return the assets
|
* @return the assets
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public List<GHAsset> getAssets() throws IOException {
|
public PagedIterable<GHAsset> listAssets() throws IOException {
|
||||||
Requester builder = owner.root.createRequest();
|
Requester builder = owner.root.createRequest();
|
||||||
|
return builder.withUrlPath(getApiTailUrl("assets")).toIterable(GHAsset[].class, item -> item.wrap(this));
|
||||||
return builder.withUrlPath(getApiTailUrl("assets"))
|
|
||||||
.toIterable(GHAsset[].class, item -> item.wrap(this))
|
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -25,12 +25,12 @@ package org.kohsuke.github;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import com.fasterxml.jackson.core.JsonParseException;
|
import com.fasterxml.jackson.core.JsonParseException;
|
||||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
|
||||||
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
||||||
import edu.umd.cs.findbugs.annotations.CheckForNull;
|
import edu.umd.cs.findbugs.annotations.CheckForNull;
|
||||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.kohsuke.github.function.InputStreamFunction;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -47,15 +47,18 @@ import java.util.Date;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import static java.util.Arrays.*;
|
import static java.util.Arrays.*;
|
||||||
import static org.kohsuke.github.Previews.*;
|
import static java.util.Objects.requireNonNull;
|
||||||
|
import static org.kohsuke.github.internal.Previews.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A repository on GitHub.
|
* A repository on GitHub.
|
||||||
@@ -66,10 +69,11 @@ import static org.kohsuke.github.Previews.*;
|
|||||||
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
||||||
justification = "JSON API")
|
justification = "JSON API")
|
||||||
public class GHRepository extends GHObject {
|
public class GHRepository extends GHObject {
|
||||||
/* package almost final */ transient GitHub root;
|
|
||||||
|
|
||||||
private String nodeId, description, homepage, name, full_name;
|
private String nodeId, description, homepage, name, full_name;
|
||||||
|
|
||||||
private String html_url; // this is the UI
|
private String html_url; // this is the UI
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The license information makes use of the preview API.
|
* The license information makes use of the preview API.
|
||||||
*
|
*
|
||||||
@@ -78,22 +82,30 @@ public class GHRepository extends GHObject {
|
|||||||
private GHLicense license;
|
private GHLicense license;
|
||||||
|
|
||||||
private String git_url, ssh_url, clone_url, svn_url, mirror_url;
|
private String git_url, ssh_url, clone_url, svn_url, mirror_url;
|
||||||
|
|
||||||
private GHUser owner; // not fully populated. beware.
|
private GHUser owner; // not fully populated. beware.
|
||||||
|
|
||||||
private boolean has_issues, has_wiki, fork, has_downloads, has_pages, archived, has_projects;
|
private boolean has_issues, has_wiki, fork, has_downloads, has_pages, archived, has_projects;
|
||||||
|
|
||||||
private boolean allow_squash_merge;
|
private boolean allow_squash_merge;
|
||||||
|
|
||||||
private boolean allow_merge_commit;
|
private boolean allow_merge_commit;
|
||||||
|
|
||||||
private boolean allow_rebase_merge;
|
private boolean allow_rebase_merge;
|
||||||
|
|
||||||
private boolean delete_branch_on_merge;
|
private boolean delete_branch_on_merge;
|
||||||
|
|
||||||
@JsonProperty("private")
|
@JsonProperty("private")
|
||||||
private boolean _private;
|
private boolean _private;
|
||||||
|
|
||||||
private int forks_count, stargazers_count, watchers_count, size, open_issues_count, subscribers_count;
|
private int forks_count, stargazers_count, watchers_count, size, open_issues_count, subscribers_count;
|
||||||
|
|
||||||
private String pushed_at;
|
private String pushed_at;
|
||||||
|
|
||||||
private Map<Integer, GHMilestone> milestones = new WeakHashMap<Integer, GHMilestone>();
|
private Map<Integer, GHMilestone> milestones = new WeakHashMap<Integer, GHMilestone>();
|
||||||
|
|
||||||
private String default_branch, language;
|
private String default_branch, language;
|
||||||
|
|
||||||
private Map<String, GHCommit> commits = new WeakHashMap<String, GHCommit>();
|
private Map<String, GHCommit> commits = new WeakHashMap<String, GHCommit>();
|
||||||
|
|
||||||
@SkipFromToString
|
@SkipFromToString
|
||||||
@@ -101,6 +113,12 @@ public class GHRepository extends GHObject {
|
|||||||
|
|
||||||
private GHRepository source, parent;
|
private GHRepository source, parent;
|
||||||
|
|
||||||
|
private Boolean isTemplate;
|
||||||
|
|
||||||
|
static GHRepository read(GitHub root, String owner, String name) throws IOException {
|
||||||
|
return root.createRequest().withUrlPath("/repos/" + owner + '/' + name).fetch(GHRepository.class).wrap(root);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create deployment gh deployment builder.
|
* Create deployment gh deployment builder.
|
||||||
*
|
*
|
||||||
@@ -147,6 +165,8 @@ public class GHRepository extends GHObject {
|
|||||||
.with("task", task)
|
.with("task", task)
|
||||||
.with("environment", environment)
|
.with("environment", environment)
|
||||||
.withUrlPath(getApiTailUrl("deployments"))
|
.withUrlPath(getApiTailUrl("deployments"))
|
||||||
|
.withPreview(ANT_MAN)
|
||||||
|
.withPreview(FLASH)
|
||||||
.toIterable(GHDeployment[].class, item -> item.wrap(this));
|
.toIterable(GHDeployment[].class, item -> item.wrap(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,6 +182,8 @@ public class GHRepository extends GHObject {
|
|||||||
public GHDeployment getDeployment(long id) throws IOException {
|
public GHDeployment getDeployment(long id) throws IOException {
|
||||||
return root.createRequest()
|
return root.createRequest()
|
||||||
.withUrlPath(getApiTailUrl("deployments/" + id))
|
.withUrlPath(getApiTailUrl("deployments/" + id))
|
||||||
|
.withPreview(ANT_MAN)
|
||||||
|
.withPreview(FLASH)
|
||||||
.fetch(GHDeployment.class)
|
.fetch(GHDeployment.class)
|
||||||
.wrap(this);
|
.wrap(this);
|
||||||
}
|
}
|
||||||
@@ -682,6 +704,28 @@ public class GHRepository extends GHObject {
|
|||||||
return _private;
|
return _private;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is template boolean.
|
||||||
|
*
|
||||||
|
* @return the boolean
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Preview(BAPTISTE)
|
||||||
|
public boolean isTemplate() {
|
||||||
|
// isTemplate is still in preview, we do not want to retrieve it unless needed.
|
||||||
|
if (isTemplate == null) {
|
||||||
|
try {
|
||||||
|
populate();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Convert this to a runtime exception to avoid messy method signature
|
||||||
|
throw new GHException("Could not populate the template setting of the repository", e);
|
||||||
|
}
|
||||||
|
// if this somehow is not populated, set it to false;
|
||||||
|
isTemplate = Boolean.TRUE.equals(isTemplate);
|
||||||
|
}
|
||||||
|
return isTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has downloads boolean.
|
* Has downloads boolean.
|
||||||
*
|
*
|
||||||
@@ -776,6 +820,13 @@ public class GHRepository extends GHObject {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Affiliation of a repository collaborator
|
||||||
|
*/
|
||||||
|
public enum CollaboratorAffiliation {
|
||||||
|
ALL, DIRECT, OUTSIDE
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the collaborators on this repository. This set always appear to include the owner.
|
* Gets the collaborators on this repository. This set always appear to include the owner.
|
||||||
*
|
*
|
||||||
@@ -799,6 +850,19 @@ public class GHRepository extends GHObject {
|
|||||||
return listUsers("collaborators");
|
return listUsers("collaborators");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists up the collaborators on this repository.
|
||||||
|
*
|
||||||
|
* @param affiliation
|
||||||
|
* Filter users by affiliation
|
||||||
|
* @return Users paged iterable
|
||||||
|
* @throws IOException
|
||||||
|
* the io exception
|
||||||
|
*/
|
||||||
|
public PagedIterable<GHUser> listCollaborators(CollaboratorAffiliation affiliation) throws IOException {
|
||||||
|
return listUsers(root.createRequest().with("affiliation", affiliation), "collaborators");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists all
|
* Lists all
|
||||||
* <a href="https://help.github.com/articles/assigning-issues-and-pull-requests-to-other-github-users/">the
|
* <a href="https://help.github.com/articles/assigning-issues-and-pull-requests-to-other-github-users/">the
|
||||||
@@ -846,6 +910,29 @@ public class GHRepository extends GHObject {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the names of the collaborators on this repository. This method deviates from the principle of this library
|
||||||
|
* but it works a lot faster than {@link #getCollaborators()}.
|
||||||
|
*
|
||||||
|
* @param affiliation
|
||||||
|
* Filter users by affiliation
|
||||||
|
* @return the collaborator names
|
||||||
|
* @throws IOException
|
||||||
|
* the io exception
|
||||||
|
*/
|
||||||
|
public Set<String> getCollaboratorNames(CollaboratorAffiliation affiliation) throws IOException {
|
||||||
|
Set<String> r = new HashSet<>();
|
||||||
|
// no initializer - we just want to the logins
|
||||||
|
PagedIterable<GHUser> users = root.createRequest()
|
||||||
|
.withUrlPath(getApiTailUrl("collaborators"))
|
||||||
|
.with("affiliation", affiliation)
|
||||||
|
.toIterable(GHUser[].class, null);
|
||||||
|
for (GHUser u : users.toArray()) {
|
||||||
|
r.add(u.login);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain permission for a given user in this repository.
|
* Obtain permission for a given user in this repository.
|
||||||
*
|
*
|
||||||
@@ -971,12 +1058,12 @@ public class GHRepository extends GHObject {
|
|||||||
@NonNull String method,
|
@NonNull String method,
|
||||||
@CheckForNull GHOrganization.Permission permission) throws IOException {
|
@CheckForNull GHOrganization.Permission permission) throws IOException {
|
||||||
Requester requester = root.createRequest().method(method);
|
Requester requester = root.createRequest().method(method);
|
||||||
|
|
||||||
if (permission != null) {
|
if (permission != null) {
|
||||||
requester = requester.with("permission", permission).inBody();
|
requester = requester.with("permission", permission).inBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (GHUser user : users) {
|
// Make sure that the users collection doesn't have any duplicates
|
||||||
|
for (GHUser user : new LinkedHashSet<GHUser>(users)) {
|
||||||
requester.withUrlPath(getApiTailUrl("collaborators/" + user.getLogin())).send();
|
requester.withUrlPath(getApiTailUrl("collaborators/" + user.getLogin())).send();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1001,13 +1088,6 @@ public class GHRepository extends GHObject {
|
|||||||
.send();
|
.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void edit(String key, String value) throws IOException {
|
|
||||||
Requester requester = root.createRequest();
|
|
||||||
if (!key.equals("name"))
|
|
||||||
requester.with("name", name); // even when we don't change the name, we need to send it in
|
|
||||||
requester.with(key, value).method("PATCH").withUrlPath(getApiTailUrl("")).send();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables or disables the issue tracker for this repository.
|
* Enables or disables the issue tracker for this repository.
|
||||||
*
|
*
|
||||||
@@ -1017,7 +1097,7 @@ public class GHRepository extends GHObject {
|
|||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public void enableIssueTracker(boolean v) throws IOException {
|
public void enableIssueTracker(boolean v) throws IOException {
|
||||||
edit("has_issues", String.valueOf(v));
|
set().issues(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1029,7 +1109,7 @@ public class GHRepository extends GHObject {
|
|||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public void enableProjects(boolean v) throws IOException {
|
public void enableProjects(boolean v) throws IOException {
|
||||||
edit("has_projects", String.valueOf(v));
|
set().projects(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1041,7 +1121,7 @@ public class GHRepository extends GHObject {
|
|||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public void enableWiki(boolean v) throws IOException {
|
public void enableWiki(boolean v) throws IOException {
|
||||||
edit("has_wiki", String.valueOf(v));
|
set().wiki(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1053,7 +1133,7 @@ public class GHRepository extends GHObject {
|
|||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public void enableDownloads(boolean v) throws IOException {
|
public void enableDownloads(boolean v) throws IOException {
|
||||||
edit("has_downloads", String.valueOf(v));
|
set().downloads(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1065,7 +1145,7 @@ public class GHRepository extends GHObject {
|
|||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public void renameTo(String name) throws IOException {
|
public void renameTo(String name) throws IOException {
|
||||||
edit("name", name);
|
set().name(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1077,7 +1157,7 @@ public class GHRepository extends GHObject {
|
|||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public void setDescription(String value) throws IOException {
|
public void setDescription(String value) throws IOException {
|
||||||
edit("description", value);
|
set().description(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1089,7 +1169,7 @@ public class GHRepository extends GHObject {
|
|||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public void setHomepage(String value) throws IOException {
|
public void setHomepage(String value) throws IOException {
|
||||||
edit("homepage", value);
|
set().homepage(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1101,7 +1181,7 @@ public class GHRepository extends GHObject {
|
|||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public void setDefaultBranch(String value) throws IOException {
|
public void setDefaultBranch(String value) throws IOException {
|
||||||
edit("default_branch", value);
|
set().defaultBranch(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1113,7 +1193,7 @@ public class GHRepository extends GHObject {
|
|||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public void setPrivate(boolean value) throws IOException {
|
public void setPrivate(boolean value) throws IOException {
|
||||||
edit("private", Boolean.toString(value));
|
set().private_(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1125,7 +1205,7 @@ public class GHRepository extends GHObject {
|
|||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public void allowSquashMerge(boolean value) throws IOException {
|
public void allowSquashMerge(boolean value) throws IOException {
|
||||||
edit("allow_squash_merge", Boolean.toString(value));
|
set().allowSquashMerge(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1137,7 +1217,7 @@ public class GHRepository extends GHObject {
|
|||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public void allowMergeCommit(boolean value) throws IOException {
|
public void allowMergeCommit(boolean value) throws IOException {
|
||||||
edit("allow_merge_commit", Boolean.toString(value));
|
set().allowMergeCommit(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1149,7 +1229,7 @@ public class GHRepository extends GHObject {
|
|||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public void allowRebaseMerge(boolean value) throws IOException {
|
public void allowRebaseMerge(boolean value) throws IOException {
|
||||||
edit("allow_rebase_merge", Boolean.toString(value));
|
set().allowRebaseMerge(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1161,7 +1241,7 @@ public class GHRepository extends GHObject {
|
|||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public void deleteBranchOnMerge(boolean value) throws IOException {
|
public void deleteBranchOnMerge(boolean value) throws IOException {
|
||||||
edit("delete_branch_on_merge", Boolean.toString(value));
|
set().deleteBranchOnMerge(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1198,12 +1278,30 @@ public class GHRepository extends GHObject {
|
|||||||
* In case of any networking error or error from the server.
|
* In case of any networking error or error from the server.
|
||||||
*/
|
*/
|
||||||
public void archive() throws IOException {
|
public void archive() throws IOException {
|
||||||
edit("archived", "true");
|
set().archive();
|
||||||
// Generall would not update this record,
|
// Generally would not update this record,
|
||||||
// but do so here since this will result in any other update actions failing
|
// but doing so here since this will result in any other update actions failing
|
||||||
archived = true;
|
archived = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a builder that can be used to bulk update repository settings.
|
||||||
|
*
|
||||||
|
* @return the repository updater
|
||||||
|
*/
|
||||||
|
public Updater update() {
|
||||||
|
return new Updater(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a builder that can be used to bulk update repository settings.
|
||||||
|
*
|
||||||
|
* @return the repository updater
|
||||||
|
*/
|
||||||
|
public Setter set() {
|
||||||
|
return new Setter(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort orders for listing forks
|
* Sort orders for listing forks
|
||||||
*/
|
*/
|
||||||
@@ -1249,8 +1347,9 @@ public class GHRepository extends GHObject {
|
|||||||
// this API is asynchronous. we need to wait for a bit
|
// this API is asynchronous. we need to wait for a bit
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
GHRepository r = root.getMyself().getRepository(name);
|
GHRepository r = root.getMyself().getRepository(name);
|
||||||
if (r != null)
|
if (r != null) {
|
||||||
return r;
|
return r;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
Thread.sleep(3000);
|
Thread.sleep(3000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@@ -1279,8 +1378,9 @@ public class GHRepository extends GHObject {
|
|||||||
// this API is asynchronous. we need to wait for a bit
|
// this API is asynchronous. we need to wait for a bit
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
GHRepository r = org.getRepository(name);
|
GHRepository r = org.getRepository(name);
|
||||||
if (r != null)
|
if (r != null) {
|
||||||
return r;
|
return r;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
Thread.sleep(3000);
|
Thread.sleep(3000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@@ -1541,8 +1641,7 @@ public class GHRepository extends GHObject {
|
|||||||
* on failure communicating with GitHub, potentially due to an invalid ref type being requested
|
* on failure communicating with GitHub, potentially due to an invalid ref type being requested
|
||||||
*/
|
*/
|
||||||
public PagedIterable<GHRef> listRefs() throws IOException {
|
public PagedIterable<GHRef> listRefs() throws IOException {
|
||||||
final String url = String.format("/repos/%s/%s/git/refs", getOwnerName(), name);
|
return listRefs("");
|
||||||
return root.createRequest().withUrlPath(url).toIterable(GHRef[].class, item -> item.wrap(root));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1568,11 +1667,7 @@ public class GHRepository extends GHObject {
|
|||||||
* on failure communicating with GitHub, potentially due to an invalid ref type being requested
|
* on failure communicating with GitHub, potentially due to an invalid ref type being requested
|
||||||
*/
|
*/
|
||||||
public PagedIterable<GHRef> listRefs(String refType) throws IOException {
|
public PagedIterable<GHRef> listRefs(String refType) throws IOException {
|
||||||
if (refType.startsWith("refs/")) {
|
return GHRef.readMatching(this, refType);
|
||||||
refType = refType.replaceFirst("refs/", "");
|
|
||||||
}
|
|
||||||
final String url = String.format("/repos/%s/%s/git/refs/%s", getOwnerName(), name, refType);
|
|
||||||
return root.createRequest().withUrlPath(url).toIterable(GHRef[].class, item -> item.wrap(root));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1585,34 +1680,7 @@ public class GHRepository extends GHObject {
|
|||||||
* on failure communicating with GitHub, potentially due to an invalid ref type being requested
|
* on failure communicating with GitHub, potentially due to an invalid ref type being requested
|
||||||
*/
|
*/
|
||||||
public GHRef getRef(String refName) throws IOException {
|
public GHRef getRef(String refName) throws IOException {
|
||||||
// Also accept e.g. "refs/heads/branch" for consistency with createRef().
|
return GHRef.read(this, refName);
|
||||||
if (refName.startsWith("refs/")) {
|
|
||||||
refName = refName.replaceFirst("refs/", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
// We would expect this to use `git/ref/%s` but some versions of GHE seem to not support it
|
|
||||||
// Instead use `git/refs/%s` and check the result actually matches the ref
|
|
||||||
GHRef result = null;
|
|
||||||
try {
|
|
||||||
result = root.createRequest()
|
|
||||||
.withUrlPath(getApiTailUrl(String.format("git/refs/%s", refName)))
|
|
||||||
.fetch(GHRef.class)
|
|
||||||
.wrap(root);
|
|
||||||
} catch (IOException e) {
|
|
||||||
// If the parse exception is due to the above returning an array instead of a single ref
|
|
||||||
// that means the individual ref did not exist
|
|
||||||
if (!(e.getCause() instanceof JsonMappingException)) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that the ref returned is the one requested
|
|
||||||
if (result == null || !result.getRef().equals("refs/" + refName)) {
|
|
||||||
throw new GHFileNotFoundException(String.format("git/refs/%s", refName)
|
|
||||||
+ " {\"message\":\"Not Found\",\"documentation_url\":\"https://developer.github.com/v3/git/refs/#get-a-reference\"}");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1715,7 +1783,7 @@ public class GHRepository extends GHObject {
|
|||||||
return root.createRequest()
|
return root.createRequest()
|
||||||
.withHeader("Accept", "application/vnd.github.v3.raw")
|
.withHeader("Accept", "application/vnd.github.v3.raw")
|
||||||
.withUrlPath(target)
|
.withUrlPath(target)
|
||||||
.fetchStream();
|
.fetchStream(Requester::copyInputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1779,6 +1847,20 @@ public class GHRepository extends GHObject {
|
|||||||
.toIterable(GHCommitComment[].class, item -> item.wrap(this));
|
.toIterable(GHCommitComment[].class, item -> item.wrap(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists all comments on a specific commit.
|
||||||
|
*
|
||||||
|
* @param commitSha
|
||||||
|
* the hash of the commit
|
||||||
|
*
|
||||||
|
* @return the paged iterable
|
||||||
|
*/
|
||||||
|
public PagedIterable<GHCommitComment> listCommitComments(String commitSha) {
|
||||||
|
return root.createRequest()
|
||||||
|
.withUrlPath(String.format("/repos/%s/%s/commits/%s/comments", getOwnerName(), name, commitSha))
|
||||||
|
.toIterable(GHCommitComment[].class, item -> item.wrap(this));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the basic license details for the repository.
|
* Gets the basic license details for the repository.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -1855,7 +1937,7 @@ public class GHRepository extends GHObject {
|
|||||||
* @see <a href="https://developer.github.com/v3/checks/runs/#list-check-runs-for-a-specific-ref">List check runs
|
* @see <a href="https://developer.github.com/v3/checks/runs/#list-check-runs-for-a-specific-ref">List check runs
|
||||||
* for a specific ref</a>
|
* for a specific ref</a>
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(ANTIOPE)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public PagedIterable<GHCheckRun> getCheckRuns(String ref) throws IOException {
|
public PagedIterable<GHCheckRun> getCheckRuns(String ref) throws IOException {
|
||||||
GitHubRequest request = root.createRequest()
|
GitHubRequest request = root.createRequest()
|
||||||
@@ -1929,12 +2011,25 @@ public class GHRepository extends GHObject {
|
|||||||
* the commit hash
|
* the commit hash
|
||||||
* @return a builder which you should customize, then call {@link GHCheckRunBuilder#create}
|
* @return a builder which you should customize, then call {@link GHCheckRunBuilder#create}
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(ANTIOPE)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public @NonNull GHCheckRunBuilder createCheckRun(@NonNull String name, @NonNull String headSHA) {
|
public @NonNull GHCheckRunBuilder createCheckRun(@NonNull String name, @NonNull String headSHA) {
|
||||||
return new GHCheckRunBuilder(this, name, headSHA);
|
return new GHCheckRunBuilder(this, name, headSHA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing check run.
|
||||||
|
*
|
||||||
|
* @param checkId
|
||||||
|
* the existing checkId
|
||||||
|
* @return a builder which you should customize, then call {@link GHCheckRunBuilder#create}
|
||||||
|
*/
|
||||||
|
@Preview(BAPTISTE)
|
||||||
|
@Deprecated
|
||||||
|
public @NonNull GHCheckRunBuilder updateCheckRun(long checkId) {
|
||||||
|
return new GHCheckRunBuilder(this, checkId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists repository events.
|
* Lists repository events.
|
||||||
*
|
*
|
||||||
@@ -2052,9 +2147,11 @@ public class GHRepository extends GHObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private PagedIterable<GHUser> listUsers(final String suffix) {
|
private PagedIterable<GHUser> listUsers(final String suffix) {
|
||||||
return root.createRequest()
|
return listUsers(root.createRequest(), suffix);
|
||||||
.withUrlPath(getApiTailUrl(suffix))
|
}
|
||||||
.toIterable(GHUser[].class, item -> item.wrapUp(root));
|
|
||||||
|
private PagedIterable<GHUser> listUsers(Requester requester, final String suffix) {
|
||||||
|
return requester.withUrlPath(getApiTailUrl(suffix)).toIterable(GHUser[].class, item -> item.wrapUp(root));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2117,7 +2214,12 @@ public class GHRepository extends GHObject {
|
|||||||
justification = "It causes a performance degradation, but we have already exposed it to the API")
|
justification = "It causes a performance degradation, but we have already exposed it to the API")
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Set<URL> getPostCommitHooks() {
|
public Set<URL> getPostCommitHooks() {
|
||||||
return postCommitHooks;
|
synchronized (this) {
|
||||||
|
if (postCommitHooks == null) {
|
||||||
|
postCommitHooks = setupPostCommitHooks();
|
||||||
|
}
|
||||||
|
return postCommitHooks;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2126,57 +2228,63 @@ public class GHRepository extends GHObject {
|
|||||||
@SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS",
|
@SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS",
|
||||||
justification = "It causes a performance degradation, but we have already exposed it to the API")
|
justification = "It causes a performance degradation, but we have already exposed it to the API")
|
||||||
@SkipFromToString
|
@SkipFromToString
|
||||||
private final Set<URL> postCommitHooks = new AbstractSet<URL>() {
|
private /* final */ transient Set<URL> postCommitHooks;
|
||||||
private List<URL> getPostCommitHooks() {
|
|
||||||
try {
|
@SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS",
|
||||||
List<URL> r = new ArrayList<>();
|
justification = "It causes a performance degradation, but we have already exposed it to the API")
|
||||||
for (GHHook h : getHooks()) {
|
private Set<URL> setupPostCommitHooks() {
|
||||||
if (h.getName().equals("web")) {
|
return new AbstractSet<URL>() {
|
||||||
r.add(new URL(h.getConfig().get("url")));
|
private List<URL> getPostCommitHooks() {
|
||||||
|
try {
|
||||||
|
List<URL> r = new ArrayList<>();
|
||||||
|
for (GHHook h : getHooks()) {
|
||||||
|
if (h.getName().equals("web")) {
|
||||||
|
r.add(new URL(h.getConfig().get("url")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return r;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new GHException("Failed to retrieve post-commit hooks", e);
|
||||||
}
|
}
|
||||||
return r;
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new GHException("Failed to retrieve post-commit hooks", e);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<URL> iterator() {
|
public Iterator<URL> iterator() {
|
||||||
return getPostCommitHooks().iterator();
|
return getPostCommitHooks().iterator();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return getPostCommitHooks().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean add(URL url) {
|
|
||||||
try {
|
|
||||||
createWebHook(url);
|
|
||||||
return true;
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new GHException("Failed to update post-commit hooks", e);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean remove(Object url) {
|
public int size() {
|
||||||
try {
|
return getPostCommitHooks().size();
|
||||||
String _url = ((URL) url).toExternalForm();
|
}
|
||||||
for (GHHook h : getHooks()) {
|
|
||||||
if (h.getName().equals("web") && h.getConfig().get("url").equals(_url)) {
|
@Override
|
||||||
h.delete();
|
public boolean add(URL url) {
|
||||||
return true;
|
try {
|
||||||
|
createWebHook(url);
|
||||||
|
return true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new GHException("Failed to update post-commit hooks", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object url) {
|
||||||
|
try {
|
||||||
|
String _url = ((URL) url).toExternalForm();
|
||||||
|
for (GHHook h : getHooks()) {
|
||||||
|
if (h.getName().equals("web") && h.getConfig().get("url").equals(_url)) {
|
||||||
|
h.delete();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new GHException("Failed to update post-commit hooks", e);
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new GHException("Failed to update post-commit hooks", e);
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
GHRepository wrap(GitHub root) {
|
GHRepository wrap(GitHub root) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
@@ -2702,7 +2810,7 @@ public class GHRepository extends GHObject {
|
|||||||
.with("mode", mode == null ? null : mode.toString())
|
.with("mode", mode == null ? null : mode.toString())
|
||||||
.with("context", getFullName())
|
.with("context", getFullName())
|
||||||
.withUrlPath("/markdown")
|
.withUrlPath("/markdown")
|
||||||
.fetchStream(),
|
.fetchStream(Requester::copyInputStream),
|
||||||
"UTF-8");
|
"UTF-8");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2754,8 +2862,9 @@ public class GHRepository extends GHObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String getApiTailUrl(String tail) {
|
String getApiTailUrl(String tail) {
|
||||||
if (tail.length() > 0 && !tail.startsWith("/"))
|
if (tail.length() > 0 && !tail.startsWith("/")) {
|
||||||
tail = '/' + tail;
|
tail = '/' + tail;
|
||||||
|
}
|
||||||
return "/repos/" + getOwnerName() + "/" + name + tail;
|
return "/repos/" + getOwnerName() + "/" + name + tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2855,6 +2964,52 @@ public class GHRepository extends GHObject {
|
|||||||
.wrap(this);
|
.wrap(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Streams a zip archive of the repository, optionally at a given <code>ref</code>.
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
* the type of result
|
||||||
|
* @param streamFunction
|
||||||
|
* The {@link InputStreamFunction} that will process the stream
|
||||||
|
* @param ref
|
||||||
|
* if <code>null</code> the repository's default branch, usually <code>master</code>,
|
||||||
|
* @throws IOException
|
||||||
|
* The IO exception.
|
||||||
|
* @return the result of reading the stream.
|
||||||
|
*/
|
||||||
|
public <T> T readZip(InputStreamFunction<T> streamFunction, String ref) throws IOException {
|
||||||
|
return downloadArchive("zip", ref, streamFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Streams a tar archive of the repository, optionally at a given <code>ref</code>.
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
* the type of result
|
||||||
|
* @param streamFunction
|
||||||
|
* The {@link InputStreamFunction} that will process the stream
|
||||||
|
* @param ref
|
||||||
|
* if <code>null</code> the repository's default branch, usually <code>master</code>,
|
||||||
|
* @throws IOException
|
||||||
|
* The IO exception.
|
||||||
|
* @return the result of reading the stream.
|
||||||
|
*/
|
||||||
|
public <T> T readTar(InputStreamFunction<T> streamFunction, String ref) throws IOException {
|
||||||
|
return downloadArchive("tar", ref, streamFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T downloadArchive(@Nonnull String type,
|
||||||
|
@CheckForNull String ref,
|
||||||
|
@Nonnull InputStreamFunction<T> streamFunction) throws IOException {
|
||||||
|
requireNonNull(streamFunction, "Sink must not be null");
|
||||||
|
String tailUrl = getApiTailUrl(type + "ball");
|
||||||
|
if (ref != null) {
|
||||||
|
tailUrl += "/" + ref;
|
||||||
|
}
|
||||||
|
final Requester builder = root.createRequest().method("GET").withUrlPath(tailUrl);
|
||||||
|
return builder.fetchStream(streamFunction);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate this object.
|
* Populate this object.
|
||||||
*
|
*
|
||||||
@@ -2862,23 +3017,64 @@ public class GHRepository extends GHObject {
|
|||||||
* The IO exception
|
* The IO exception
|
||||||
*/
|
*/
|
||||||
void populate() throws IOException {
|
void populate() throws IOException {
|
||||||
if (root.isOffline())
|
if (root.isOffline()) {
|
||||||
return; // can't populate if the root is offline
|
return; // can't populate if the root is offline
|
||||||
|
}
|
||||||
|
|
||||||
final URL url = Objects.requireNonNull(getUrl(), "Missing instance URL!");
|
final URL url = requireNonNull(getUrl(), "Missing instance URL!");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// IMPORTANT: the url for repository records is does not reliably point to the API url.
|
// IMPORTANT: the url for repository records does not reliably point to the API url.
|
||||||
// There is bug in Push event payloads that returns the wrong url.
|
// There is bug in Push event payloads that returns the wrong url.
|
||||||
// All other occurrences of "url" take the form "https://api.github.com/...".
|
// All other occurrences of "url" take the form "https://api.github.com/...".
|
||||||
// For Push event repository records, they take the form "https://github.com/{fullName}".
|
// For Push event repository records, they take the form "https://github.com/{fullName}".
|
||||||
root.createRequest().setRawUrlPath(url.toString()).fetchInto(this).wrap(root);
|
root.createRequest().withPreview(BAPTISTE).setRawUrlPath(url.toString()).fetchInto(this).wrap(root);
|
||||||
} catch (HttpException e) {
|
} catch (HttpException e) {
|
||||||
if (e.getCause() instanceof JsonParseException) {
|
if (e.getCause() instanceof JsonParseException) {
|
||||||
root.createRequest().withUrlPath("/repos/" + full_name).fetchInto(this).wrap(root);
|
root.createRequest()
|
||||||
|
.withPreview(BAPTISTE)
|
||||||
|
.withUrlPath("/repos/" + full_name)
|
||||||
|
.fetchInto(this)
|
||||||
|
.wrap(root);
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link GHRepositoryBuilder} that allows multiple properties to be updated per request.
|
||||||
|
*
|
||||||
|
* Consumer must call {@link #done()} to commit changes.
|
||||||
|
*/
|
||||||
|
@BetaApi
|
||||||
|
@Deprecated
|
||||||
|
public static class Updater extends GHRepositoryBuilder<Updater> {
|
||||||
|
protected Updater(@Nonnull GHRepository repository) {
|
||||||
|
super(Updater.class, repository.root, null);
|
||||||
|
// even when we don't change the name, we need to send it in
|
||||||
|
// this requirement may be out-of-date, but we do not want to break it
|
||||||
|
requester.with("name", repository.name);
|
||||||
|
|
||||||
|
requester.method("PATCH").withUrlPath(repository.getApiTailUrl(""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link GHRepositoryBuilder} that allows multiple properties to be updated per request.
|
||||||
|
*
|
||||||
|
* Consumer must call {@link #done()} to commit changes.
|
||||||
|
*/
|
||||||
|
@BetaApi
|
||||||
|
@Deprecated
|
||||||
|
public static class Setter extends GHRepositoryBuilder<GHRepository> {
|
||||||
|
protected Setter(@Nonnull GHRepository repository) {
|
||||||
|
super(GHRepository.class, repository.root, null);
|
||||||
|
// even when we don't change the name, we need to send it in
|
||||||
|
// this requirement may be out-of-date, but we do not want to break it
|
||||||
|
requester.with("name", repository.name);
|
||||||
|
|
||||||
|
requester.method("PATCH").withUrlPath(repository.getApiTailUrl(""));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
235
src/main/java/org/kohsuke/github/GHRepositoryBuilder.java
Normal file
235
src/main/java/org/kohsuke/github/GHRepositoryBuilder.java
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import static org.kohsuke.github.internal.Previews.BAPTISTE;
|
||||||
|
|
||||||
|
abstract class GHRepositoryBuilder<S> extends AbstractBuilder<GHRepository, S> {
|
||||||
|
|
||||||
|
protected GHRepositoryBuilder(Class<S> intermediateReturnType, GitHub root, GHRepository baseInstance) {
|
||||||
|
super(GHRepository.class, intermediateReturnType, root, baseInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow or disallow squash-merging pull requests.
|
||||||
|
*
|
||||||
|
* @param enabled
|
||||||
|
* true if enabled
|
||||||
|
*
|
||||||
|
* @return a builder to continue with building
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
public S allowSquashMerge(boolean enabled) throws IOException {
|
||||||
|
return with("allow_squash_merge", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow or disallow merging pull requests with a merge commit.
|
||||||
|
*
|
||||||
|
* @param enabled
|
||||||
|
* true if enabled
|
||||||
|
*
|
||||||
|
* @return a builder to continue with building
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
public S allowMergeCommit(boolean enabled) throws IOException {
|
||||||
|
return with("allow_merge_commit", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow or disallow rebase-merging pull requests.
|
||||||
|
*
|
||||||
|
* @param enabled
|
||||||
|
* true if enabled
|
||||||
|
*
|
||||||
|
* @return a builder to continue with building
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
public S allowRebaseMerge(boolean enabled) throws IOException {
|
||||||
|
return with("allow_rebase_merge", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After pull requests are merged, you can have head branches deleted automatically.
|
||||||
|
*
|
||||||
|
* @param enabled
|
||||||
|
* true if enabled
|
||||||
|
*
|
||||||
|
* @return a builder to continue with building
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
public S deleteBranchOnMerge(boolean enabled) throws IOException {
|
||||||
|
return with("delete_branch_on_merge", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default repository branch
|
||||||
|
*
|
||||||
|
* @param branch
|
||||||
|
* branch name
|
||||||
|
*
|
||||||
|
* @return a builder to continue with building
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
public S defaultBranch(String branch) throws IOException {
|
||||||
|
return with("default_branch", branch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description for repository
|
||||||
|
*
|
||||||
|
* @param description
|
||||||
|
* description of repository
|
||||||
|
*
|
||||||
|
* @return a builder to continue with building
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
public S description(String description) throws IOException {
|
||||||
|
return with("description", description);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Homepage for repository
|
||||||
|
*
|
||||||
|
* @param homepage
|
||||||
|
* homepage of repository
|
||||||
|
*
|
||||||
|
* @return a builder to continue with building
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
public S homepage(URL homepage) throws IOException {
|
||||||
|
return homepage(homepage.toExternalForm());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Homepage for repository
|
||||||
|
*
|
||||||
|
* @param homepage
|
||||||
|
* homepage of repository
|
||||||
|
*
|
||||||
|
* @return a builder to continue with building
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
public S homepage(String homepage) throws IOException {
|
||||||
|
return with("homepage", homepage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the repository to private
|
||||||
|
*
|
||||||
|
* @param enabled
|
||||||
|
* private if true
|
||||||
|
*
|
||||||
|
* @return a builder to continue with building
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
public S private_(boolean enabled) throws IOException {
|
||||||
|
return with("private", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables issue tracker
|
||||||
|
*
|
||||||
|
* @param enabled
|
||||||
|
* true if enabled
|
||||||
|
*
|
||||||
|
* @return a builder to continue with building
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
public S issues(boolean enabled) throws IOException {
|
||||||
|
return with("has_issues", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables projects
|
||||||
|
*
|
||||||
|
* @param enabled
|
||||||
|
* true if enabled
|
||||||
|
*
|
||||||
|
* @return a builder to continue with building
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
public S projects(boolean enabled) throws IOException {
|
||||||
|
return with("has_projects", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables wiki
|
||||||
|
*
|
||||||
|
* @param enabled
|
||||||
|
* true if enabled
|
||||||
|
* @return a builder to continue with building
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
public S wiki(boolean enabled) throws IOException {
|
||||||
|
return with("has_wiki", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables downloads
|
||||||
|
*
|
||||||
|
* @param enabled
|
||||||
|
* true if enabled
|
||||||
|
*
|
||||||
|
* @return a builder to continue with building
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
public S downloads(boolean enabled) throws IOException {
|
||||||
|
return with("has_downloads", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether the repository is a template.
|
||||||
|
*
|
||||||
|
* @param enabled
|
||||||
|
* true if enabled
|
||||||
|
* @return a builder to continue with building
|
||||||
|
* @throws IOException
|
||||||
|
* In case of any networking error or error from the server.
|
||||||
|
*/
|
||||||
|
@Preview(BAPTISTE)
|
||||||
|
@Deprecated
|
||||||
|
public S isTemplate(boolean enabled) throws IOException {
|
||||||
|
requester.withPreview(BAPTISTE);
|
||||||
|
return with("is_template", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GHRepository done() throws IOException {
|
||||||
|
return super.done().wrap(this.root);
|
||||||
|
}
|
||||||
|
|
||||||
|
S archive() throws IOException {
|
||||||
|
return with("archived", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
S name(String name) throws IOException {
|
||||||
|
return with("name", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,10 +16,9 @@ import java.util.NoSuchElementException;
|
|||||||
*
|
*
|
||||||
* @author Martin van Zijl
|
* @author Martin van Zijl
|
||||||
*/
|
*/
|
||||||
public class GHRepositoryStatistics {
|
public class GHRepositoryStatistics extends GitHubInteractiveObject {
|
||||||
|
|
||||||
private final GHRepository repo;
|
private final GHRepository repo;
|
||||||
private final GitHub root;
|
|
||||||
|
|
||||||
private static final int MAX_WAIT_ITERATIONS = 3;
|
private static final int MAX_WAIT_ITERATIONS = 3;
|
||||||
private static final int WAIT_SLEEP_INTERVAL = 5000;
|
private static final int WAIT_SLEEP_INTERVAL = 5000;
|
||||||
@@ -60,7 +59,7 @@ public class GHRepositoryStatistics {
|
|||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
* the interrupted exception
|
* the interrupted exception
|
||||||
*/
|
*/
|
||||||
@Preview
|
@BetaApi
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@SuppressWarnings("SleepWhileInLoop")
|
@SuppressWarnings("SleepWhileInLoop")
|
||||||
@SuppressFBWarnings(value = { "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE" }, justification = "JSON API")
|
@SuppressFBWarnings(value = { "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE" }, justification = "JSON API")
|
||||||
@@ -99,7 +98,6 @@ public class GHRepositoryStatistics {
|
|||||||
"URF_UNREAD_FIELD" },
|
"URF_UNREAD_FIELD" },
|
||||||
justification = "JSON API")
|
justification = "JSON API")
|
||||||
public static class ContributorStats extends GHObject {
|
public static class ContributorStats extends GHObject {
|
||||||
/* package almost final */ private GitHub root;
|
|
||||||
private GHUser author;
|
private GHUser author;
|
||||||
private int total;
|
private int total;
|
||||||
private List<Week> weeks;
|
private List<Week> weeks;
|
||||||
@@ -255,7 +253,6 @@ public class GHRepositoryStatistics {
|
|||||||
value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
||||||
justification = "JSON API")
|
justification = "JSON API")
|
||||||
public static class CommitActivity extends GHObject {
|
public static class CommitActivity extends GHObject {
|
||||||
/* package almost final */ private GitHub root;
|
|
||||||
private List<Integer> days;
|
private List<Integer> days;
|
||||||
private int total;
|
private int total;
|
||||||
private long week;
|
private long week;
|
||||||
@@ -398,7 +395,6 @@ public class GHRepositoryStatistics {
|
|||||||
* The type Participation.
|
* The type Participation.
|
||||||
*/
|
*/
|
||||||
public static class Participation extends GHObject {
|
public static class Participation extends GHObject {
|
||||||
/* package almost final */ private GitHub root;
|
|
||||||
private List<Integer> all;
|
private List<Integer> all;
|
||||||
private List<Integer> owner;
|
private List<Integer> owner;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import java.net.URL;
|
|||||||
justification = "JSON API")
|
justification = "JSON API")
|
||||||
public class GHRequestedAction extends GHObject {
|
public class GHRequestedAction extends GHObject {
|
||||||
private GHRepository owner;
|
private GHRepository owner;
|
||||||
private GitHub root;
|
|
||||||
private String identifier;
|
private String identifier;
|
||||||
private String label;
|
private String label;
|
||||||
private String description;
|
private String description;
|
||||||
@@ -46,4 +45,4 @@ public class GHRequestedAction extends GHObject {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ public abstract class GHSearchBuilder<T> extends GHQueryBuilder<T> {
|
|||||||
super(root);
|
super(root);
|
||||||
this.receiverType = receiverType;
|
this.receiverType = receiverType;
|
||||||
req.withUrlPath(getApiUrl());
|
req.withUrlPath(getApiUrl());
|
||||||
|
req.rateLimit(RateLimitTarget.SEARCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -10,11 +10,10 @@ import java.util.Date;
|
|||||||
* @see GHRepository#getSubscription() GHRepository#getSubscription()
|
* @see GHRepository#getSubscription() GHRepository#getSubscription()
|
||||||
* @see GHThread#getSubscription() GHThread#getSubscription()
|
* @see GHThread#getSubscription() GHThread#getSubscription()
|
||||||
*/
|
*/
|
||||||
public class GHSubscription {
|
public class GHSubscription extends GitHubInteractiveObject {
|
||||||
private String created_at, url, repository_url, reason;
|
private String created_at, url, repository_url, reason;
|
||||||
private boolean subscribed, ignored;
|
private boolean subscribed, ignored;
|
||||||
|
|
||||||
private GitHub root;
|
|
||||||
private GHRepository repo;
|
private GHRepository repo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -9,9 +9,8 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
|||||||
*/
|
*/
|
||||||
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
||||||
justification = "JSON API")
|
justification = "JSON API")
|
||||||
public class GHTag {
|
public class GHTag extends GitHubInteractiveObject {
|
||||||
private GHRepository owner;
|
private GHRepository owner;
|
||||||
private GitHub root;
|
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private GHCommit commit;
|
private GHCommit commit;
|
||||||
|
|||||||
@@ -9,9 +9,8 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
|||||||
*/
|
*/
|
||||||
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
||||||
justification = "JSON API")
|
justification = "JSON API")
|
||||||
public class GHTagObject {
|
public class GHTagObject extends GitHubInteractiveObject {
|
||||||
private GHRepository owner;
|
private GHRepository owner;
|
||||||
private GitHub root;
|
|
||||||
|
|
||||||
private String tag;
|
private String tag;
|
||||||
private String sha;
|
private String sha;
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ public class GHTeam extends GHObject implements Refreshable {
|
|||||||
|
|
||||||
private GHOrganization organization; // populated by GET /user/teams where Teams+Orgs are returned together
|
private GHOrganization organization; // populated by GET /user/teams where Teams+Orgs are returned together
|
||||||
|
|
||||||
protected /* final */ GitHub root;
|
|
||||||
|
|
||||||
public enum Privacy {
|
public enum Privacy {
|
||||||
SECRET, // only visible to organization owners and members of this team.
|
SECRET, // only visible to organization owners and members of this team.
|
||||||
CLOSED // visible to all members of this organization.
|
CLOSED // visible to all members of this organization.
|
||||||
@@ -145,6 +143,22 @@ public class GHTeam extends GHObject implements Refreshable {
|
|||||||
return GHDiscussion.readAll(this);
|
return GHDiscussion.readAll(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List members with specified role paged iterable.
|
||||||
|
*
|
||||||
|
* @param role
|
||||||
|
* the role
|
||||||
|
* @return the paged iterable
|
||||||
|
* @throws IOException
|
||||||
|
* the io exception
|
||||||
|
*/
|
||||||
|
public PagedIterable<GHUser> listMembers(String role) throws IOException {
|
||||||
|
return root.createRequest()
|
||||||
|
.withUrlPath(api("/members"))
|
||||||
|
.with("role", role)
|
||||||
|
.toIterable(GHUser[].class, item -> item.wrapUp(root));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a single discussion by ID.
|
* Gets a single discussion by ID.
|
||||||
*
|
*
|
||||||
@@ -171,7 +185,20 @@ public class GHTeam extends GHObject implements Refreshable {
|
|||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public PagedIterable<GHUser> listMembers() throws IOException {
|
public PagedIterable<GHUser> listMembers() throws IOException {
|
||||||
return root.createRequest().withUrlPath(api("/members")).toIterable(GHUser[].class, item -> item.wrapUp(root));
|
return listMembers("all");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the teams that are children of this team.
|
||||||
|
*
|
||||||
|
* @return the paged iterable
|
||||||
|
* @throws IOException
|
||||||
|
* the io exception
|
||||||
|
*/
|
||||||
|
public PagedIterable<GHTeam> listChildTeams() throws IOException {
|
||||||
|
return root.createRequest()
|
||||||
|
.withUrlPath(api("/teams"))
|
||||||
|
.toIterable(GHTeam[].class, item -> item.wrapUp(this.organization));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,9 +7,7 @@ import java.io.IOException;
|
|||||||
*
|
*
|
||||||
* https://developer.github.com/v3/teams/#create-team
|
* https://developer.github.com/v3/teams/#create-team
|
||||||
*/
|
*/
|
||||||
public class GHTeamBuilder {
|
public class GHTeamBuilder extends GitHubInteractiveObject {
|
||||||
|
|
||||||
private final GitHub root;
|
|
||||||
protected final Requester builder;
|
protected final Requester builder;
|
||||||
private final String orgName;
|
private final String orgName;
|
||||||
|
|
||||||
@@ -75,7 +73,7 @@ public class GHTeamBuilder {
|
|||||||
* parentTeamId of team
|
* parentTeamId of team
|
||||||
* @return a builder to continue with building
|
* @return a builder to continue with building
|
||||||
*/
|
*/
|
||||||
public GHTeamBuilder parentTeamId(int parentTeamId) {
|
public GHTeamBuilder parentTeamId(long parentTeamId) {
|
||||||
this.builder.with("parent_team_id", parentTeamId);
|
this.builder.with("parent_team_id", parentTeamId);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import java.util.Date;
|
|||||||
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
||||||
justification = "JSON API")
|
justification = "JSON API")
|
||||||
public class GHThread extends GHObject {
|
public class GHThread extends GHObject {
|
||||||
private GitHub root;
|
|
||||||
private GHRepository repository;
|
private GHRepository repository;
|
||||||
private Subject subject;
|
private Subject subject;
|
||||||
private String reason;
|
private String reason;
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ package org.kohsuke.github;
|
|||||||
import com.fasterxml.jackson.databind.ObjectReader;
|
import com.fasterxml.jackson.databind.ObjectReader;
|
||||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||||
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
||||||
|
import org.kohsuke.github.authorization.AuthorizationProvider;
|
||||||
|
import org.kohsuke.github.internal.Previews;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -37,8 +39,8 @@ import java.util.logging.Logger;
|
|||||||
import javax.annotation.CheckForNull;
|
import javax.annotation.CheckForNull;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import static org.kohsuke.github.Previews.INERTIA;
|
import static org.kohsuke.github.internal.Previews.INERTIA;
|
||||||
import static org.kohsuke.github.Previews.MACHINE_MAN;
|
import static org.kohsuke.github.internal.Previews.MACHINE_MAN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Root of the GitHub API.
|
* Root of the GitHub API.
|
||||||
@@ -93,39 +95,112 @@ public class GitHub {
|
|||||||
* "http://ghe.acme.com/api/v3". Note that GitHub Enterprise has <code>/api/v3</code> in the URL. For
|
* "http://ghe.acme.com/api/v3". Note that GitHub Enterprise has <code>/api/v3</code> in the URL. For
|
||||||
* historical reasons, this parameter still accepts the bare domain name, but that's considered
|
* historical reasons, this parameter still accepts the bare domain name, but that's considered
|
||||||
* deprecated. Password is also considered deprecated as it is no longer required for api usage.
|
* deprecated. Password is also considered deprecated as it is no longer required for api usage.
|
||||||
* @param login
|
|
||||||
* The user ID on GitHub that you are logging in as. Can be omitted if the OAuth token is provided or if
|
|
||||||
* logging in anonymously. Specifying this would save one API call.
|
|
||||||
* @param oauthAccessToken
|
|
||||||
* Secret OAuth token.
|
|
||||||
* @param password
|
|
||||||
* User's password. Always used in conjunction with the {@code login} parameter
|
|
||||||
* @param connector
|
* @param connector
|
||||||
* HttpConnector to use. Pass null to use default connector.
|
* a connector
|
||||||
|
* @param rateLimitHandler
|
||||||
|
* rateLimitHandler
|
||||||
|
* @param abuseLimitHandler
|
||||||
|
* abuseLimitHandler
|
||||||
|
* @param rateLimitChecker
|
||||||
|
* rateLimitChecker
|
||||||
|
* @param authorizationProvider
|
||||||
|
* a authorization provider
|
||||||
*/
|
*/
|
||||||
GitHub(String apiUrl,
|
GitHub(String apiUrl,
|
||||||
String login,
|
|
||||||
String oauthAccessToken,
|
|
||||||
String jwtToken,
|
|
||||||
String password,
|
|
||||||
HttpConnector connector,
|
HttpConnector connector,
|
||||||
RateLimitHandler rateLimitHandler,
|
RateLimitHandler rateLimitHandler,
|
||||||
AbuseLimitHandler abuseLimitHandler,
|
AbuseLimitHandler abuseLimitHandler,
|
||||||
GitHubRateLimitChecker rateLimitChecker) throws IOException {
|
GitHubRateLimitChecker rateLimitChecker,
|
||||||
|
AuthorizationProvider authorizationProvider) throws IOException {
|
||||||
|
if (authorizationProvider instanceof DependentAuthorizationProvider) {
|
||||||
|
((DependentAuthorizationProvider) authorizationProvider).bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
this.client = new GitHubHttpUrlConnectionClient(apiUrl,
|
this.client = new GitHubHttpUrlConnectionClient(apiUrl,
|
||||||
login,
|
|
||||||
oauthAccessToken,
|
|
||||||
jwtToken,
|
|
||||||
password,
|
|
||||||
connector,
|
connector,
|
||||||
rateLimitHandler,
|
rateLimitHandler,
|
||||||
abuseLimitHandler,
|
abuseLimitHandler,
|
||||||
rateLimitChecker,
|
rateLimitChecker,
|
||||||
(myself) -> setMyself(myself));
|
(myself) -> setMyself(myself),
|
||||||
|
authorizationProvider);
|
||||||
users = new ConcurrentHashMap<>();
|
users = new ConcurrentHashMap<>();
|
||||||
orgs = new ConcurrentHashMap<>();
|
orgs = new ConcurrentHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private GitHub(GitHubClient client) {
|
||||||
|
this.client = client;
|
||||||
|
users = new ConcurrentHashMap<>();
|
||||||
|
orgs = new ConcurrentHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class DependentAuthorizationProvider implements AuthorizationProvider {
|
||||||
|
|
||||||
|
private GitHub baseGitHub;
|
||||||
|
private GitHub gitHub;
|
||||||
|
private final AuthorizationProvider authorizationProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An AuthorizationProvider that requires an authenticated GitHub instance to provide its authorization.
|
||||||
|
*
|
||||||
|
* @param authorizationProvider
|
||||||
|
* A authorization provider to be used when refreshing this authorization provider.
|
||||||
|
*/
|
||||||
|
@BetaApi
|
||||||
|
@Deprecated
|
||||||
|
protected DependentAuthorizationProvider(AuthorizationProvider authorizationProvider) {
|
||||||
|
this.authorizationProvider = authorizationProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds this authorization provider to a github instance.
|
||||||
|
*
|
||||||
|
* Only needs to be implemented by dynamic credentials providers that use a github instance in order to refresh.
|
||||||
|
*
|
||||||
|
* @param github
|
||||||
|
* The github instance to be used for refreshing dynamic credentials
|
||||||
|
*/
|
||||||
|
synchronized void bind(GitHub github) {
|
||||||
|
if (baseGitHub != null) {
|
||||||
|
throw new IllegalStateException("Already bound to another GitHub instance.");
|
||||||
|
}
|
||||||
|
this.baseGitHub = github;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected synchronized final GitHub gitHub() {
|
||||||
|
if (gitHub == null) {
|
||||||
|
gitHub = new GitHub.AuthorizationRefreshGitHubWrapper(this.baseGitHub, authorizationProvider);
|
||||||
|
}
|
||||||
|
return gitHub;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class AuthorizationRefreshGitHubWrapper extends GitHub {
|
||||||
|
|
||||||
|
private final AuthorizationProvider authorizationProvider;
|
||||||
|
|
||||||
|
AuthorizationRefreshGitHubWrapper(GitHub github, AuthorizationProvider authorizationProvider) {
|
||||||
|
super(github.client);
|
||||||
|
this.authorizationProvider = authorizationProvider;
|
||||||
|
|
||||||
|
// no dependent authorization providers nest like this currently, but they might in future
|
||||||
|
if (authorizationProvider instanceof DependentAuthorizationProvider) {
|
||||||
|
((DependentAuthorizationProvider) authorizationProvider).bind(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
Requester createRequest() {
|
||||||
|
try {
|
||||||
|
// Override
|
||||||
|
return super.createRequest().setHeader("Authorization", authorizationProvider.getEncodedAuthorization())
|
||||||
|
.rateLimit(RateLimitTarget.NONE);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new GHException("Failed to create requester to refresh credentials", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the credential from "~/.github" or from the System Environment Properties.
|
* Obtains the credential from "~/.github" or from the System Environment Properties.
|
||||||
*
|
*
|
||||||
@@ -373,12 +448,20 @@ public class GitHub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current rate limit.
|
* Gets the current full rate limit information from the server.
|
||||||
|
*
|
||||||
|
* For some versions of GitHub Enterprise, the {@code /rate_limit} endpoint returns a {@code 404 Not Found}. In that
|
||||||
|
* case, the most recent {@link GHRateLimit} information will be returned, including rate limit information returned
|
||||||
|
* in the response header for this request in if was present.
|
||||||
|
*
|
||||||
|
* For most use cases it would be better to implement a {@link RateLimitChecker} and add it via
|
||||||
|
* {@link GitHubBuilder#withRateLimitChecker(RateLimitChecker)}.
|
||||||
*
|
*
|
||||||
* @return the rate limit
|
* @return the rate limit
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
|
@Nonnull
|
||||||
public GHRateLimit getRateLimit() throws IOException {
|
public GHRateLimit getRateLimit() throws IOException {
|
||||||
return client.getRateLimit();
|
return client.getRateLimit();
|
||||||
}
|
}
|
||||||
@@ -388,8 +471,11 @@ public class GitHub {
|
|||||||
* GitHub Enterprise) or if no requests have been made.
|
* GitHub Enterprise) or if no requests have been made.
|
||||||
*
|
*
|
||||||
* @return the most recently observed rate limit data or {@code null}.
|
* @return the most recently observed rate limit data or {@code null}.
|
||||||
|
* @deprecated implement a {@link RateLimitChecker} and add it via
|
||||||
|
* {@link GitHubBuilder#withRateLimitChecker(RateLimitChecker)}.
|
||||||
*/
|
*/
|
||||||
@CheckForNull
|
@Nonnull
|
||||||
|
@Deprecated
|
||||||
public GHRateLimit lastRateLimit() {
|
public GHRateLimit lastRateLimit() {
|
||||||
return client.lastRateLimit();
|
return client.lastRateLimit();
|
||||||
}
|
}
|
||||||
@@ -400,10 +486,13 @@ public class GitHub {
|
|||||||
* @return the current rate limit data.
|
* @return the current rate limit data.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if we couldn't get the current rate limit data.
|
* if we couldn't get the current rate limit data.
|
||||||
|
* @deprecated implement a {@link RateLimitChecker} and add it via
|
||||||
|
* {@link GitHubBuilder#withRateLimitChecker(RateLimitChecker)}.
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
@Deprecated
|
||||||
public GHRateLimit rateLimit() throws IOException {
|
public GHRateLimit rateLimit() throws IOException {
|
||||||
return client.rateLimit();
|
return client.rateLimit(RateLimitTarget.CORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -518,7 +607,7 @@ public class GitHub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the repository object from 'user/reponame' string that GitHub calls as "repository name"
|
* Gets the repository object from 'owner/repo' string that GitHub calls as "repository name"
|
||||||
*
|
*
|
||||||
* @param name
|
* @param name
|
||||||
* the name
|
* the name
|
||||||
@@ -529,9 +618,27 @@ public class GitHub {
|
|||||||
*/
|
*/
|
||||||
public GHRepository getRepository(String name) throws IOException {
|
public GHRepository getRepository(String name) throws IOException {
|
||||||
String[] tokens = name.split("/");
|
String[] tokens = name.split("/");
|
||||||
return createRequest().withUrlPath("/repos/" + tokens[0] + '/' + tokens[1])
|
if (tokens.length < 2) {
|
||||||
.fetch(GHRepository.class)
|
throw new IllegalArgumentException("Repository name must be in format owner/repo");
|
||||||
.wrap(this);
|
}
|
||||||
|
return GHRepository.read(this, tokens[0], tokens[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the repository object from its ID
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* the id
|
||||||
|
* @return the repository by id
|
||||||
|
* @throws IOException
|
||||||
|
* the io exception
|
||||||
|
*
|
||||||
|
* @deprecated Do not use this method. It was added due to misunderstanding of the type of parameter. Use
|
||||||
|
* {@link #getRepositoryById(long)} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public GHRepository getRepositoryById(String id) throws IOException {
|
||||||
|
return createRequest().withUrlPath("/repositories/" + id).fetch(GHRepository.class).wrap(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -543,7 +650,7 @@ public class GitHub {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* the io exception
|
* the io exception
|
||||||
*/
|
*/
|
||||||
public GHRepository getRepositoryById(String id) throws IOException {
|
public GHRepository getRepositoryById(long id) throws IOException {
|
||||||
return createRequest().withUrlPath("/repositories/" + id).fetch(GHRepository.class).wrap(this);
|
return createRequest().withUrlPath("/repositories/" + id).fetch(GHRepository.class).wrap(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -726,7 +833,7 @@ public class GitHub {
|
|||||||
* @return the team
|
* @return the team
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* the io exception
|
* the io exception
|
||||||
*
|
*
|
||||||
* @deprecated Use {@link GHOrganization#getTeam(long)}
|
* @deprecated Use {@link GHOrganization#getTeam(long)}
|
||||||
* @see <a href= "https://developer.github.com/v3/teams/#get-team-legacy">deprecation notice</a>
|
* @see <a href= "https://developer.github.com/v3/teams/#get-team-legacy">deprecation notice</a>
|
||||||
*/
|
*/
|
||||||
@@ -830,7 +937,7 @@ public class GitHub {
|
|||||||
* @return the gh create repository builder
|
* @return the gh create repository builder
|
||||||
*/
|
*/
|
||||||
public GHCreateRepositoryBuilder createRepository(String name) {
|
public GHCreateRepositoryBuilder createRepository(String name) {
|
||||||
return new GHCreateRepositoryBuilder(this, "/user/repos", name);
|
return new GHCreateRepositoryBuilder(name, this, "/user/repos");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -998,7 +1105,7 @@ public class GitHub {
|
|||||||
* @see <a href="https://developer.github.com/v3/apps/#get-the-authenticated-github-app">Get the authenticated
|
* @see <a href="https://developer.github.com/v3/apps/#get-the-authenticated-github-app">Get the authenticated
|
||||||
* GitHub App</a>
|
* GitHub App</a>
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(MACHINE_MAN)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHApp getApp() throws IOException {
|
public GHApp getApp() throws IOException {
|
||||||
return createRequest().withPreview(MACHINE_MAN).withUrlPath("/app").fetch(GHApp.class).wrapUp(this);
|
return createRequest().withPreview(MACHINE_MAN).withUrlPath("/app").fetch(GHApp.class).wrapUp(this);
|
||||||
@@ -1093,7 +1200,7 @@ public class GitHub {
|
|||||||
*
|
*
|
||||||
* @return the gh commit search builder
|
* @return the gh commit search builder
|
||||||
*/
|
*/
|
||||||
@Preview
|
@Preview(Previews.CLOAK)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public GHCommitSearchBuilder searchCommits() {
|
public GHCommitSearchBuilder searchCommits() {
|
||||||
return new GHCommitSearchBuilder(this);
|
return new GHCommitSearchBuilder(this);
|
||||||
@@ -1188,31 +1295,39 @@ public class GitHub {
|
|||||||
.with(new ByteArrayInputStream(text.getBytes("UTF-8")))
|
.with(new ByteArrayInputStream(text.getBytes("UTF-8")))
|
||||||
.contentType("text/plain;charset=UTF-8")
|
.contentType("text/plain;charset=UTF-8")
|
||||||
.withUrlPath("/markdown/raw")
|
.withUrlPath("/markdown/raw")
|
||||||
.fetchStream(),
|
.fetchStream(Requester::copyInputStream),
|
||||||
"UTF-8");
|
"UTF-8");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do not use this method. This method will be removed and should never have been needed in the first place.
|
* Gets an {@link ObjectWriter} that can be used to convert data objects in this library to JSON.
|
||||||
|
*
|
||||||
|
* If you must convert data object in this library to JSON, the {@link ObjectWriter} returned by this method is the
|
||||||
|
* only supported way of doing so. This {@link ObjectWriter} can be used to convert any library data object to JSON
|
||||||
|
* without throwing an exception.
|
||||||
|
*
|
||||||
|
* WARNING: While the JSON generated is generally expected to be stable, it is not part of the API of this library
|
||||||
|
* and may change without warning. Use with extreme caution.
|
||||||
*
|
*
|
||||||
* @return an {@link ObjectWriter} instance that can be further configured.
|
* @return an {@link ObjectWriter} instance that can be further configured.
|
||||||
* @deprecated DO NOT USE THIS METHOD. Provided for backward compatibility with projects that did their own jackson
|
|
||||||
* mapping of this project's data objects, such as Jenkins Blue Ocean.
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static ObjectWriter getMappingObjectWriter() {
|
public static ObjectWriter getMappingObjectWriter() {
|
||||||
return GitHubClient.getMappingObjectWriter();
|
return GitHubClient.getMappingObjectWriter();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do not use this method. This method will be removed and should never have been needed in the first place.
|
* Gets an {@link ObjectReader} that can be used to convert JSON into library data objects.
|
||||||
|
*
|
||||||
|
* If you must manually create library data objects from JSON, the {@link ObjectReader} returned by this method is
|
||||||
|
* the only supported way of doing so.
|
||||||
|
*
|
||||||
|
* WARNING: Objects generated from this method have limited functionality. They will not throw when being crated
|
||||||
|
* from valid JSON matching the expected object, but they are not guaranteed to be usable beyond that. Use with
|
||||||
|
* extreme caution.
|
||||||
*
|
*
|
||||||
* @return an {@link ObjectReader} instance that can be further configured.
|
* @return an {@link ObjectReader} instance that can be further configured.
|
||||||
* @deprecated DO NOT USE THIS METHOD. Provided for backward compatibility with projects that did their own jackson
|
|
||||||
* mapping of this project's data objects, such as Jenkins Blue Ocean.
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static ObjectReader getMappingObjectReader() {
|
public static ObjectReader getMappingObjectReader() {
|
||||||
return GitHubClient.getMappingObjectReader(GitHub.offline());
|
return GitHubClient.getMappingObjectReader(GitHub.offline());
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.kohsuke.github.authorization.AuthorizationProvider;
|
||||||
|
import org.kohsuke.github.authorization.ImmutableAuthorizationProvider;
|
||||||
import org.kohsuke.github.extras.ImpatientHttpConnector;
|
import org.kohsuke.github.extras.ImpatientHttpConnector;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -24,16 +26,13 @@ public class GitHubBuilder implements Cloneable {
|
|||||||
|
|
||||||
// default scoped so unit tests can read them.
|
// default scoped so unit tests can read them.
|
||||||
/* private */ String endpoint = GitHubClient.GITHUB_URL;
|
/* private */ String endpoint = GitHubClient.GITHUB_URL;
|
||||||
/* private */ String user;
|
|
||||||
/* private */ String password;
|
|
||||||
/* private */ String oauthToken;
|
|
||||||
/* private */ String jwtToken;
|
|
||||||
|
|
||||||
private HttpConnector connector;
|
private HttpConnector connector;
|
||||||
|
|
||||||
private RateLimitHandler rateLimitHandler = RateLimitHandler.WAIT;
|
private RateLimitHandler rateLimitHandler = RateLimitHandler.WAIT;
|
||||||
private AbuseLimitHandler abuseLimitHandler = AbuseLimitHandler.WAIT;
|
private AbuseLimitHandler abuseLimitHandler = AbuseLimitHandler.WAIT;
|
||||||
private GitHubRateLimitChecker rateLimitChecker = new GitHubRateLimitChecker();
|
private GitHubRateLimitChecker rateLimitChecker = new GitHubRateLimitChecker();
|
||||||
|
/* private */ AuthorizationProvider authorizationProvider = AuthorizationProvider.ANONYMOUS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new Git hub builder.
|
* Instantiates a new Git hub builder.
|
||||||
@@ -61,13 +60,13 @@ public class GitHubBuilder implements Cloneable {
|
|||||||
|
|
||||||
builder = fromEnvironment();
|
builder = fromEnvironment();
|
||||||
|
|
||||||
if (builder.oauthToken != null || builder.user != null || builder.jwtToken != null)
|
if (builder.authorizationProvider != null)
|
||||||
return builder;
|
return builder;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
builder = fromPropertyFile();
|
builder = fromPropertyFile();
|
||||||
|
|
||||||
if (builder.oauthToken != null || builder.user != null || builder.jwtToken != null)
|
if (builder.authorizationProvider != null)
|
||||||
return builder;
|
return builder;
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
// fall through
|
// fall through
|
||||||
@@ -215,9 +214,20 @@ public class GitHubBuilder implements Cloneable {
|
|||||||
*/
|
*/
|
||||||
public static GitHubBuilder fromProperties(Properties props) {
|
public static GitHubBuilder fromProperties(Properties props) {
|
||||||
GitHubBuilder self = new GitHubBuilder();
|
GitHubBuilder self = new GitHubBuilder();
|
||||||
self.withOAuthToken(props.getProperty("oauth"), props.getProperty("login"));
|
String oauth = props.getProperty("oauth");
|
||||||
self.withJwtToken(props.getProperty("jwt"));
|
String jwt = props.getProperty("jwt");
|
||||||
self.withPassword(props.getProperty("login"), props.getProperty("password"));
|
String login = props.getProperty("login");
|
||||||
|
String password = props.getProperty("password");
|
||||||
|
|
||||||
|
if (oauth != null) {
|
||||||
|
self.withOAuthToken(oauth, login);
|
||||||
|
}
|
||||||
|
if (jwt != null) {
|
||||||
|
self.withJwtToken(jwt);
|
||||||
|
}
|
||||||
|
if (password != null) {
|
||||||
|
self.withPassword(login, password);
|
||||||
|
}
|
||||||
self.withEndpoint(props.getProperty("endpoint", GitHubClient.GITHUB_URL));
|
self.withEndpoint(props.getProperty("endpoint", GitHubClient.GITHUB_URL));
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@@ -247,9 +257,7 @@ public class GitHubBuilder implements Cloneable {
|
|||||||
* @return the git hub builder
|
* @return the git hub builder
|
||||||
*/
|
*/
|
||||||
public GitHubBuilder withPassword(String user, String password) {
|
public GitHubBuilder withPassword(String user, String password) {
|
||||||
this.user = user;
|
return withAuthorizationProvider(ImmutableAuthorizationProvider.fromLoginAndPassword(user, password));
|
||||||
this.password = password;
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -260,7 +268,7 @@ public class GitHubBuilder implements Cloneable {
|
|||||||
* @return the git hub builder
|
* @return the git hub builder
|
||||||
*/
|
*/
|
||||||
public GitHubBuilder withOAuthToken(String oauthToken) {
|
public GitHubBuilder withOAuthToken(String oauthToken) {
|
||||||
return withOAuthToken(oauthToken, null);
|
return withAuthorizationProvider(ImmutableAuthorizationProvider.fromOauthToken(oauthToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -273,8 +281,21 @@ public class GitHubBuilder implements Cloneable {
|
|||||||
* @return the git hub builder
|
* @return the git hub builder
|
||||||
*/
|
*/
|
||||||
public GitHubBuilder withOAuthToken(String oauthToken, String user) {
|
public GitHubBuilder withOAuthToken(String oauthToken, String user) {
|
||||||
this.oauthToken = oauthToken;
|
return withAuthorizationProvider(ImmutableAuthorizationProvider.fromOauthToken(oauthToken, user));
|
||||||
this.user = user;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures a {@link AuthorizationProvider} for this builder
|
||||||
|
*
|
||||||
|
* There can be only one authorization provider per client instance.
|
||||||
|
*
|
||||||
|
* @param authorizationProvider
|
||||||
|
* the authorization provider
|
||||||
|
* @return the git hub builder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public GitHubBuilder withAuthorizationProvider(final AuthorizationProvider authorizationProvider) {
|
||||||
|
this.authorizationProvider = authorizationProvider;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,7 +308,7 @@ public class GitHubBuilder implements Cloneable {
|
|||||||
* @see GHAppInstallation#createToken(java.util.Map) GHAppInstallation#createToken(java.util.Map)
|
* @see GHAppInstallation#createToken(java.util.Map) GHAppInstallation#createToken(java.util.Map)
|
||||||
*/
|
*/
|
||||||
public GitHubBuilder withAppInstallationToken(String appInstallationToken) {
|
public GitHubBuilder withAppInstallationToken(String appInstallationToken) {
|
||||||
return withOAuthToken(appInstallationToken, "");
|
return withAuthorizationProvider(ImmutableAuthorizationProvider.fromAppInstallationToken(appInstallationToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -298,8 +319,7 @@ public class GitHubBuilder implements Cloneable {
|
|||||||
* @return the git hub builder
|
* @return the git hub builder
|
||||||
*/
|
*/
|
||||||
public GitHubBuilder withJwtToken(String jwtToken) {
|
public GitHubBuilder withJwtToken(String jwtToken) {
|
||||||
this.jwtToken = jwtToken;
|
return withAuthorizationProvider(ImmutableAuthorizationProvider.fromJwtToken(jwtToken));
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -358,6 +378,18 @@ public class GitHubBuilder implements Cloneable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a {@link RateLimitChecker} for the Core API for this {@link GitHubBuilder}.
|
||||||
|
*
|
||||||
|
* @param coreRateLimitChecker
|
||||||
|
* the {@link RateLimitChecker} for core GitHub API requests
|
||||||
|
* @return the git hub builder
|
||||||
|
* @see #withRateLimitChecker(RateLimitChecker, RateLimitTarget)
|
||||||
|
*/
|
||||||
|
public GitHubBuilder withRateLimitChecker(@Nonnull RateLimitChecker coreRateLimitChecker) {
|
||||||
|
return withRateLimitChecker(coreRateLimitChecker, RateLimitTarget.CORE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a {@link RateLimitChecker} to this {@link GitHubBuilder}.
|
* Adds a {@link RateLimitChecker} to this {@link GitHubBuilder}.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -376,15 +408,15 @@ public class GitHubBuilder implements Cloneable {
|
|||||||
* request.
|
* request.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param coreRateLimitChecker
|
* @param rateLimitChecker
|
||||||
* the {@link RateLimitChecker} for core GitHub API requests
|
* the {@link RateLimitChecker} for requests
|
||||||
|
* @param rateLimitTarget
|
||||||
|
* the {@link RateLimitTarget} specifying which rate limit record to check
|
||||||
* @return the git hub builder
|
* @return the git hub builder
|
||||||
*/
|
*/
|
||||||
public GitHubBuilder withRateLimitChecker(@Nonnull RateLimitChecker coreRateLimitChecker) {
|
public GitHubBuilder withRateLimitChecker(@Nonnull RateLimitChecker rateLimitChecker,
|
||||||
this.rateLimitChecker = new GitHubRateLimitChecker(coreRateLimitChecker,
|
@Nonnull RateLimitTarget rateLimitTarget) {
|
||||||
RateLimitChecker.NONE,
|
this.rateLimitChecker = this.rateLimitChecker.with(rateLimitChecker, rateLimitTarget);
|
||||||
RateLimitChecker.NONE,
|
|
||||||
RateLimitChecker.NONE);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,14 +441,11 @@ public class GitHubBuilder implements Cloneable {
|
|||||||
*/
|
*/
|
||||||
public GitHub build() throws IOException {
|
public GitHub build() throws IOException {
|
||||||
return new GitHub(endpoint,
|
return new GitHub(endpoint,
|
||||||
user,
|
|
||||||
oauthToken,
|
|
||||||
jwtToken,
|
|
||||||
password,
|
|
||||||
connector,
|
connector,
|
||||||
rateLimitHandler,
|
rateLimitHandler,
|
||||||
abuseLimitHandler,
|
abuseLimitHandler,
|
||||||
rateLimitChecker);
|
rateLimitChecker,
|
||||||
|
authorizationProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,34 +1,19 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.*;
|
||||||
import com.fasterxml.jackson.databind.InjectableValues;
|
|
||||||
import com.fasterxml.jackson.databind.MapperFeature;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectReader;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
|
||||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
|
||||||
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
|
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.kohsuke.github.authorization.AuthorizationProvider;
|
||||||
|
import org.kohsuke.github.authorization.UserAuthorizationProvider;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InterruptedIOException;
|
import java.io.InterruptedIOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.*;
|
||||||
import java.net.MalformedURLException;
|
import java.time.Instant;
|
||||||
import java.net.SocketException;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.net.SocketTimeoutException;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.net.URL;
|
import java.util.*;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@@ -45,7 +30,7 @@ import static java.util.logging.Level.*;
|
|||||||
* A GitHub API Client
|
* A GitHub API Client
|
||||||
* <p>
|
* <p>
|
||||||
* A GitHubClient can be used to send requests and retrieve their responses. GitHubClient is thread-safe and can be used
|
* A GitHubClient can be used to send requests and retrieve their responses. GitHubClient is thread-safe and can be used
|
||||||
* to send multiple requests. GitHubClient also track some GitHub API information such as {@link #rateLimit()}.
|
* to send multiple requests. GitHubClient also track some GitHub API information such as {@link GHRateLimit}.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
abstract class GitHubClient {
|
abstract class GitHubClient {
|
||||||
@@ -57,32 +42,28 @@ abstract class GitHubClient {
|
|||||||
static final int retryTimeoutMillis = 100;
|
static final int retryTimeoutMillis = 100;
|
||||||
/* private */ final String login;
|
/* private */ final String login;
|
||||||
|
|
||||||
/**
|
|
||||||
* Value of the authorization header to be sent with the request.
|
|
||||||
*/
|
|
||||||
/* private */ final String encodedAuthorization;
|
|
||||||
|
|
||||||
// Cache of myself object.
|
// Cache of myself object.
|
||||||
private final String apiUrl;
|
private final String apiUrl;
|
||||||
|
|
||||||
protected final RateLimitHandler rateLimitHandler;
|
protected final RateLimitHandler rateLimitHandler;
|
||||||
protected final AbuseLimitHandler abuseLimitHandler;
|
protected final AbuseLimitHandler abuseLimitHandler;
|
||||||
private final GitHubRateLimitChecker rateLimitChecker;
|
private final GitHubRateLimitChecker rateLimitChecker;
|
||||||
|
private final AuthorizationProvider authorizationProvider;
|
||||||
|
|
||||||
private HttpConnector connector;
|
private HttpConnector connector;
|
||||||
|
|
||||||
private final Object headerRateLimitLock = new Object();
|
private final Object rateLimitLock = new Object();
|
||||||
private GHRateLimit headerRateLimit = null;
|
|
||||||
private volatile GHRateLimit rateLimit = null;
|
@Nonnull
|
||||||
|
private GHRateLimit rateLimit = GHRateLimit.DEFAULT;
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(GitHubClient.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(GitHubClient.class.getName());
|
||||||
|
|
||||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||||
static final String GITHUB_URL = "https://api.github.com";
|
static final String GITHUB_URL = "https://api.github.com";
|
||||||
|
|
||||||
private static final String[] TIME_FORMATS = { "yyyy/MM/dd HH:mm:ss ZZZZ", "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
private static final DateTimeFormatter DATE_TIME_PARSER_SLASHES = DateTimeFormatter
|
||||||
"yyyy-MM-dd'T'HH:mm:ss.S'Z'" // GitHub App endpoints return a different date format
|
.ofPattern("yyyy/MM/dd HH:mm:ss Z");
|
||||||
};
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
MAPPER.setVisibility(new VisibilityChecker.Std(NONE, NONE, NONE, NONE, ANY));
|
MAPPER.setVisibility(new VisibilityChecker.Std(NONE, NONE, NONE, NONE, ANY));
|
||||||
@@ -92,15 +73,12 @@ abstract class GitHubClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GitHubClient(String apiUrl,
|
GitHubClient(String apiUrl,
|
||||||
String login,
|
|
||||||
String oauthAccessToken,
|
|
||||||
String jwtToken,
|
|
||||||
String password,
|
|
||||||
HttpConnector connector,
|
HttpConnector connector,
|
||||||
RateLimitHandler rateLimitHandler,
|
RateLimitHandler rateLimitHandler,
|
||||||
AbuseLimitHandler abuseLimitHandler,
|
AbuseLimitHandler abuseLimitHandler,
|
||||||
GitHubRateLimitChecker rateLimitChecker,
|
GitHubRateLimitChecker rateLimitChecker,
|
||||||
Consumer<GHMyself> myselfConsumer) throws IOException {
|
Consumer<GHMyself> myselfConsumer,
|
||||||
|
AuthorizationProvider authorizationProvider) throws IOException {
|
||||||
|
|
||||||
if (apiUrl.endsWith("/")) {
|
if (apiUrl.endsWith("/")) {
|
||||||
apiUrl = apiUrl.substring(0, apiUrl.length() - 1); // normalize
|
apiUrl = apiUrl.substring(0, apiUrl.length() - 1); // normalize
|
||||||
@@ -112,40 +90,43 @@ abstract class GitHubClient {
|
|||||||
this.apiUrl = apiUrl;
|
this.apiUrl = apiUrl;
|
||||||
this.connector = connector;
|
this.connector = connector;
|
||||||
|
|
||||||
if (oauthAccessToken != null) {
|
// Prefer credential configuration via provider
|
||||||
encodedAuthorization = "token " + oauthAccessToken;
|
this.authorizationProvider = authorizationProvider;
|
||||||
} else {
|
|
||||||
if (jwtToken != null) {
|
|
||||||
encodedAuthorization = "Bearer " + jwtToken;
|
|
||||||
} else if (password != null) {
|
|
||||||
String authorization = (login + ':' + password);
|
|
||||||
String charsetName = StandardCharsets.UTF_8.name();
|
|
||||||
encodedAuthorization = "Basic "
|
|
||||||
+ Base64.getEncoder().encodeToString(authorization.getBytes(charsetName));
|
|
||||||
} else {// anonymous access
|
|
||||||
encodedAuthorization = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.rateLimitHandler = rateLimitHandler;
|
this.rateLimitHandler = rateLimitHandler;
|
||||||
this.abuseLimitHandler = abuseLimitHandler;
|
this.abuseLimitHandler = abuseLimitHandler;
|
||||||
this.rateLimitChecker = rateLimitChecker;
|
this.rateLimitChecker = rateLimitChecker;
|
||||||
|
|
||||||
if (login == null && encodedAuthorization != null && jwtToken == null) {
|
this.login = getCurrentUser(myselfConsumer);
|
||||||
GHMyself myself = fetch(GHMyself.class, "/user");
|
}
|
||||||
login = myself.getLogin();
|
|
||||||
if (myselfConsumer != null) {
|
private String getCurrentUser(Consumer<GHMyself> myselfConsumer) throws IOException {
|
||||||
myselfConsumer.accept(myself);
|
String login = null;
|
||||||
|
if (this.authorizationProvider instanceof UserAuthorizationProvider
|
||||||
|
&& this.authorizationProvider.getEncodedAuthorization() != null) {
|
||||||
|
|
||||||
|
UserAuthorizationProvider userAuthorizationProvider = (UserAuthorizationProvider) this.authorizationProvider;
|
||||||
|
|
||||||
|
login = userAuthorizationProvider.getLogin();
|
||||||
|
|
||||||
|
if (login == null) {
|
||||||
|
try {
|
||||||
|
GHMyself myself = fetch(GHMyself.class, "/user");
|
||||||
|
if (myselfConsumer != null) {
|
||||||
|
myselfConsumer.accept(myself);
|
||||||
|
}
|
||||||
|
login = myself.getLogin();
|
||||||
|
} catch (IOException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.login = login;
|
return login;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T fetch(Class<T> type, String urlPath) throws IOException {
|
private <T> T fetch(Class<T> type, String urlPath) throws IOException {
|
||||||
return this
|
GitHubRequest request = GitHubRequest.newBuilder().withApiUrl(getApiUrl()).withUrlPath(urlPath).build();
|
||||||
.sendRequest(GitHubRequest.newBuilder().withApiUrl(getApiUrl()).withUrlPath(urlPath).build(),
|
return this.sendRequest(request, (responseInfo) -> GitHubResponse.parseBody(responseInfo, type)).body();
|
||||||
(responseInfo) -> GitHubResponse.parseBody(responseInfo, type))
|
|
||||||
.body();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -205,15 +186,24 @@ abstract class GitHubClient {
|
|||||||
* @return {@code true} if operations that require authentication will fail.
|
* @return {@code true} if operations that require authentication will fail.
|
||||||
*/
|
*/
|
||||||
public boolean isAnonymous() {
|
public boolean isAnonymous() {
|
||||||
return login == null && encodedAuthorization == null;
|
try {
|
||||||
|
return login == null && this.authorizationProvider.getEncodedAuthorization() == null;
|
||||||
|
} catch (IOException e) {
|
||||||
|
// An exception here means that the provider failed to provide authorization parameters,
|
||||||
|
// basically meaning the same as "no auth"
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current rate limit from the server.
|
* Gets the current full rate limit information from the server.
|
||||||
*
|
*
|
||||||
* For some versions of GitHub Enterprise, the {@code /rate_limit} endpoint returns a {@code 404 Not Found}. In
|
* For some versions of GitHub Enterprise, the {@code /rate_limit} endpoint returns a {@code 404 Not Found}. In that
|
||||||
* that, if {@link #lastRateLimit()} is not {@code null} and is not expired, it will be returned. Otherwise, a
|
* case, the most recent {@link GHRateLimit} information will be returned, including rate limit information returned
|
||||||
* placeholder {@link GHRateLimit} instance with {@link GHRateLimit.UnknownLimitRecord}s will be returned.
|
* in the response header for this request in if was present.
|
||||||
|
*
|
||||||
|
* For most use cases it would be better to implement a {@link RateLimitChecker} and add it via
|
||||||
|
* {@link GitHubBuilder#withRateLimitChecker(RateLimitChecker)}.
|
||||||
*
|
*
|
||||||
* @return the rate limit
|
* @return the rate limit
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
@@ -221,59 +211,100 @@ abstract class GitHubClient {
|
|||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public GHRateLimit getRateLimit() throws IOException {
|
public GHRateLimit getRateLimit() throws IOException {
|
||||||
|
return getRateLimit(RateLimitTarget.NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@CheckForNull
|
||||||
|
protected String getEncodedAuthorization() throws IOException {
|
||||||
|
return authorizationProvider.getEncodedAuthorization();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
GHRateLimit getRateLimit(@Nonnull RateLimitTarget rateLimitTarget) throws IOException {
|
||||||
GHRateLimit result;
|
GHRateLimit result;
|
||||||
try {
|
try {
|
||||||
result = fetch(JsonRateLimit.class, "/rate_limit").resources;
|
GitHubRequest request = GitHubRequest.newBuilder()
|
||||||
|
.rateLimit(RateLimitTarget.NONE)
|
||||||
|
.withApiUrl(getApiUrl())
|
||||||
|
.withUrlPath("/rate_limit")
|
||||||
|
.build();
|
||||||
|
result = this
|
||||||
|
.sendRequest(request, (responseInfo) -> GitHubResponse.parseBody(responseInfo, JsonRateLimit.class))
|
||||||
|
.body().resources;
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
// For some versions of GitHub Enterprise, the rate_limit endpoint returns a 404.
|
// For some versions of GitHub Enterprise, the rate_limit endpoint returns a 404.
|
||||||
|
LOGGER.log(FINE, "/rate_limit returned 404 Not Found.");
|
||||||
|
|
||||||
// However some newer versions of GHE include rate limit header information
|
// However some newer versions of GHE include rate limit header information
|
||||||
// Use that if available
|
// If the header info is missing and the endpoint returns 404, fill the rate limit
|
||||||
result = lastRateLimit();
|
// with unknown
|
||||||
if (result == null || result.isExpired()) {
|
result = GHRateLimit.fromRecord(GHRateLimit.UnknownLimitRecord.current(), rateLimitTarget);
|
||||||
// return a default rate limit
|
|
||||||
result = GHRateLimit.Unknown();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return updateRateLimit(result);
|
||||||
return rateLimit = result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the most recently observed rate limit data or {@code null} if either there is no rate limit (for example
|
* Returns the most recently observed rate limit data.
|
||||||
* GitHub Enterprise) or if no requests have been made.
|
|
||||||
*
|
*
|
||||||
* @return the most recently observed rate limit data or {@code null}.
|
* Generally, instead of calling this you should implement a {@link RateLimitChecker} or call
|
||||||
|
*
|
||||||
|
* @return the most recently observed rate limit data. This may include expired or
|
||||||
|
* {@link GHRateLimit.UnknownLimitRecord} entries.
|
||||||
|
* @deprecated implement a {@link RateLimitChecker} and add it via
|
||||||
|
* {@link GitHubBuilder#withRateLimitChecker(RateLimitChecker)}.
|
||||||
*/
|
*/
|
||||||
@CheckForNull
|
@Nonnull
|
||||||
public GHRateLimit lastRateLimit() {
|
@Deprecated
|
||||||
synchronized (headerRateLimitLock) {
|
GHRateLimit lastRateLimit() {
|
||||||
return headerRateLimit;
|
synchronized (rateLimitLock) {
|
||||||
|
return rateLimit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current rate limit while trying not to actually make any remote requests unless absolutely necessary.
|
* Gets the current rate limit for an endpoint while trying not to actually make any remote requests unless
|
||||||
|
* absolutely necessary.
|
||||||
*
|
*
|
||||||
* If {@link #lastRateLimit()} is not {@code null} and is not expired, it will be returned. If the information
|
* If the {@link GHRateLimit.Record} for {@code urlPath} is not expired, it is returned. If the
|
||||||
* returned from the last call to {@link #getRateLimit()} is not {@code null} and is not expired, then it will be
|
* {@link GHRateLimit.Record} for {@code urlPath} is expired, {@link #getRateLimit()} will be called to get the
|
||||||
* returned. Otherwise, the result of a call to {@link #getRateLimit()} will be returned.
|
* current rate limit.
|
||||||
*
|
*
|
||||||
* @return the current rate limit data.
|
* @param rateLimitTarget
|
||||||
|
* the endpoint to get the rate limit for.
|
||||||
|
*
|
||||||
|
* @return the current rate limit data. {@link GHRateLimit.Record}s in this instance may be expired when returned.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if there was an error getting current rate limit data.
|
* if there was an error getting current rate limit data.
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public GHRateLimit rateLimit() throws IOException {
|
GHRateLimit rateLimit(@Nonnull RateLimitTarget rateLimitTarget) throws IOException {
|
||||||
synchronized (headerRateLimitLock) {
|
synchronized (rateLimitLock) {
|
||||||
if (headerRateLimit != null && !headerRateLimit.isExpired()) {
|
if (rateLimit.getRecord(rateLimitTarget).isExpired()) {
|
||||||
return headerRateLimit;
|
getRateLimit(rateLimitTarget);
|
||||||
}
|
}
|
||||||
|
return rateLimit;
|
||||||
}
|
}
|
||||||
GHRateLimit result = this.rateLimit;
|
}
|
||||||
if (result == null || result.isExpired()) {
|
|
||||||
result = getRateLimit();
|
/**
|
||||||
|
* Update the Rate Limit with the latest info from response header.
|
||||||
|
*
|
||||||
|
* Due to multi-threading, requests might complete out of order. This method calls
|
||||||
|
* {@link GHRateLimit#getMergedRateLimit(GHRateLimit)} to ensure the most current records are used.
|
||||||
|
*
|
||||||
|
* @param observed
|
||||||
|
* {@link GHRateLimit.Record} constructed from the response header information
|
||||||
|
*/
|
||||||
|
private GHRateLimit updateRateLimit(@Nonnull GHRateLimit observed) {
|
||||||
|
synchronized (rateLimitLock) {
|
||||||
|
observed = rateLimit.getMergedRateLimit(observed);
|
||||||
|
|
||||||
|
if (rateLimit != observed) {
|
||||||
|
rateLimit = observed;
|
||||||
|
LOGGER.log(FINE, "Rate limit now: {0}", rateLimit);
|
||||||
|
}
|
||||||
|
return rateLimit;
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -358,7 +389,6 @@ abstract class GitHubClient {
|
|||||||
"GitHub API request [" + (login == null ? "anonymous" : login) + "]: "
|
"GitHub API request [" + (login == null ? "anonymous" : login) + "]: "
|
||||||
+ request.method() + " " + request.url().toString());
|
+ request.method() + " " + request.url().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
rateLimitChecker.checkRateLimit(this, request);
|
rateLimitChecker.checkRateLimit(this, request);
|
||||||
|
|
||||||
responseInfo = getResponseInfo(request);
|
responseInfo = getResponseInfo(request);
|
||||||
@@ -369,7 +399,7 @@ abstract class GitHubClient {
|
|||||||
// Setting "Cache-Control" to "no-cache" stops the cache from supplying
|
// Setting "Cache-Control" to "no-cache" stops the cache from supplying
|
||||||
// "If-Modified-Since" or "If-None-Match" values.
|
// "If-Modified-Since" or "If-None-Match" values.
|
||||||
// This makes GitHub give us current data (not incorrectly cached data)
|
// This makes GitHub give us current data (not incorrectly cached data)
|
||||||
request = request.toBuilder().withHeader("Cache-Control", "no-cache").build();
|
request = request.toBuilder().setHeader("Cache-Control", "no-cache").build();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!(isRateLimitResponse(responseInfo) || isAbuseLimitResponse(responseInfo))) {
|
if (!(isRateLimitResponse(responseInfo) || isAbuseLimitResponse(responseInfo))) {
|
||||||
@@ -517,58 +547,25 @@ abstract class GitHubClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void noteRateLimit(@Nonnull GitHubResponse.ResponseInfo responseInfo) {
|
private void noteRateLimit(@Nonnull GitHubResponse.ResponseInfo responseInfo) {
|
||||||
if (responseInfo.request().urlPath().startsWith("/search")) {
|
|
||||||
// the search API uses a different rate limit
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String limitString = responseInfo.headerField("X-RateLimit-Limit");
|
|
||||||
if (StringUtils.isBlank(limitString)) {
|
|
||||||
// if we are missing a header, return fast
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String remainingString = responseInfo.headerField("X-RateLimit-Remaining");
|
|
||||||
if (StringUtils.isBlank(remainingString)) {
|
|
||||||
// if we are missing a header, return fast
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String resetString = responseInfo.headerField("X-RateLimit-Reset");
|
|
||||||
if (StringUtils.isBlank(resetString)) {
|
|
||||||
// if we are missing a header, return fast
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int limit, remaining;
|
|
||||||
long reset;
|
|
||||||
try {
|
try {
|
||||||
|
String limitString = Objects.requireNonNull(responseInfo.headerField("X-RateLimit-Limit"),
|
||||||
|
"Missing X-RateLimit-Limit");
|
||||||
|
String remainingString = Objects.requireNonNull(responseInfo.headerField("X-RateLimit-Remaining"),
|
||||||
|
"Missing X-RateLimit-Remaining");
|
||||||
|
String resetString = Objects.requireNonNull(responseInfo.headerField("X-RateLimit-Reset"),
|
||||||
|
"Missing X-RateLimit-Reset");
|
||||||
|
int limit, remaining;
|
||||||
|
long reset;
|
||||||
limit = Integer.parseInt(limitString);
|
limit = Integer.parseInt(limitString);
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
if (LOGGER.isLoggable(FINEST)) {
|
|
||||||
LOGGER.log(FINEST, "Malformed X-RateLimit-Limit header value " + limitString, e);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
|
|
||||||
remaining = Integer.parseInt(remainingString);
|
remaining = Integer.parseInt(remainingString);
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
if (LOGGER.isLoggable(FINEST)) {
|
|
||||||
LOGGER.log(FINEST, "Malformed X-RateLimit-Remaining header value " + remainingString, e);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
reset = Long.parseLong(resetString);
|
reset = Long.parseLong(resetString);
|
||||||
} catch (NumberFormatException e) {
|
GHRateLimit.Record observed = new GHRateLimit.Record(limit, remaining, reset, responseInfo);
|
||||||
|
updateRateLimit(GHRateLimit.fromRecord(observed, responseInfo.request().rateLimitTarget()));
|
||||||
|
} catch (NumberFormatException | NullPointerException e) {
|
||||||
if (LOGGER.isLoggable(FINEST)) {
|
if (LOGGER.isLoggable(FINEST)) {
|
||||||
LOGGER.log(FINEST, "Malformed X-RateLimit-Reset header value " + resetString, e);
|
LOGGER.log(FINEST, "Missing or malformed X-RateLimit header: ", e);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GHRateLimit.Record observed = new GHRateLimit.Record(limit, remaining, reset, responseInfo);
|
|
||||||
|
|
||||||
updateCoreRateLimit(observed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void detectOTPRequired(@Nonnull GitHubResponse.ResponseInfo responseInfo) throws GHIOException {
|
private static void detectOTPRequired(@Nonnull GitHubResponse.ResponseInfo responseInfo) throws GHIOException {
|
||||||
@@ -588,23 +585,6 @@ abstract class GitHubClient {
|
|||||||
"This operation requires a credential but none is given to the GitHub constructor");
|
"This operation requires a credential but none is given to the GitHub constructor");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the Rate Limit with the latest info from response header. Due to multi-threading requests might complete
|
|
||||||
* out of order, we want to pick the one with the most recent info from the server. Calls
|
|
||||||
* {@link #shouldReplace(GHRateLimit.Record, GHRateLimit.Record)}
|
|
||||||
*
|
|
||||||
* @param observed
|
|
||||||
* {@link GHRateLimit.Record} constructed from the response header information
|
|
||||||
*/
|
|
||||||
private void updateCoreRateLimit(@Nonnull GHRateLimit.Record observed) {
|
|
||||||
synchronized (headerRateLimitLock) {
|
|
||||||
if (headerRateLimit == null || shouldReplace(observed, headerRateLimit.getCore())) {
|
|
||||||
headerRateLimit = GHRateLimit.fromHeaderRecord(observed);
|
|
||||||
LOGGER.log(FINE, "Rate limit now: {0}", headerRateLimit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class GHApiInfo {
|
private static class GHApiInfo {
|
||||||
private String rate_limit_url;
|
private String rate_limit_url;
|
||||||
|
|
||||||
@@ -654,37 +634,6 @@ abstract class GitHubClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if one {@link GHRateLimit.Record} should replace another. Header date is only accurate to the second,
|
|
||||||
* so we look at the information in the record itself.
|
|
||||||
*
|
|
||||||
* {@link GHRateLimit.UnknownLimitRecord}s are always replaced by regular {@link GHRateLimit.Record}s. Regular
|
|
||||||
* {@link GHRateLimit.Record}s are never replaced by {@link GHRateLimit.UnknownLimitRecord}s. Candidates with
|
|
||||||
* resetEpochSeconds later than current record are more recent. Candidates with the same reset and a lower remaining
|
|
||||||
* count are more recent. Candidates with an earlier reset are older.
|
|
||||||
*
|
|
||||||
* @param candidate
|
|
||||||
* {@link GHRateLimit.Record} constructed from the response header information
|
|
||||||
* @param current
|
|
||||||
* the current {@link GHRateLimit.Record} record
|
|
||||||
*/
|
|
||||||
static boolean shouldReplace(@Nonnull GHRateLimit.Record candidate, @Nonnull GHRateLimit.Record current) {
|
|
||||||
if (candidate instanceof GHRateLimit.UnknownLimitRecord
|
|
||||||
&& !(current instanceof GHRateLimit.UnknownLimitRecord)) {
|
|
||||||
// Unknown candidate never replaces a regular record
|
|
||||||
return false;
|
|
||||||
} else if (current instanceof GHRateLimit.UnknownLimitRecord
|
|
||||||
&& !(candidate instanceof GHRateLimit.UnknownLimitRecord)) {
|
|
||||||
// Any real record should replace an unknown Record.
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
// records of the same type compare to each other as normal.
|
|
||||||
return current.getResetEpochSeconds() < candidate.getResetEpochSeconds()
|
|
||||||
|| (current.getResetEpochSeconds() == candidate.getResetEpochSeconds()
|
|
||||||
&& current.getRemaining() > candidate.getRemaining());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static URL parseURL(String s) {
|
static URL parseURL(String s) {
|
||||||
try {
|
try {
|
||||||
return s == null ? null : new URL(s);
|
return s == null ? null : new URL(s);
|
||||||
@@ -696,22 +645,24 @@ abstract class GitHubClient {
|
|||||||
static Date parseDate(String timestamp) {
|
static Date parseDate(String timestamp) {
|
||||||
if (timestamp == null)
|
if (timestamp == null)
|
||||||
return null;
|
return null;
|
||||||
for (String f : TIME_FORMATS) {
|
|
||||||
try {
|
return Date.from(parseInstant(timestamp));
|
||||||
SimpleDateFormat df = new SimpleDateFormat(f);
|
}
|
||||||
df.setTimeZone(TimeZone.getTimeZone("GMT"));
|
|
||||||
return df.parse(timestamp);
|
static Instant parseInstant(String timestamp) {
|
||||||
} catch (ParseException e) {
|
if (timestamp == null)
|
||||||
// try next
|
return null;
|
||||||
}
|
|
||||||
|
if (timestamp.charAt(4) == '/') {
|
||||||
|
// Unsure where this is used, but retained for compatibility.
|
||||||
|
return Instant.from(DATE_TIME_PARSER_SLASHES.parse(timestamp));
|
||||||
|
} else {
|
||||||
|
return Instant.from(DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(timestamp));
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Unable to parse the timestamp: " + timestamp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static String printDate(Date dt) {
|
static String printDate(Date dt) {
|
||||||
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
|
return DateTimeFormatter.ISO_INSTANT.format(Instant.ofEpochMilli(dt.getTime()).truncatedTo(ChronoUnit.SECONDS));
|
||||||
df.setTimeZone(TimeZone.getTimeZone("GMT"));
|
|
||||||
return df.format(dt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.kohsuke.github.authorization.AuthorizationProvider;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -24,7 +25,7 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
|
|||||||
* A GitHub API Client for HttpUrlConnection
|
* A GitHub API Client for HttpUrlConnection
|
||||||
* <p>
|
* <p>
|
||||||
* A GitHubClient can be used to send requests and retrieve their responses. GitHubClient is thread-safe and can be used
|
* A GitHubClient can be used to send requests and retrieve their responses. GitHubClient is thread-safe and can be used
|
||||||
* to send multiple requests. GitHubClient also track some GitHub API information such as {@link #rateLimit()}.
|
* to send multiple requests. GitHubClient also track some GitHub API information such as {@link GHRateLimit}.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* GitHubHttpUrlConnectionClient gets a new {@link HttpURLConnection} for each call to send.
|
* GitHubHttpUrlConnectionClient gets a new {@link HttpURLConnection} for each call to send.
|
||||||
@@ -33,25 +34,19 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
|
|||||||
class GitHubHttpUrlConnectionClient extends GitHubClient {
|
class GitHubHttpUrlConnectionClient extends GitHubClient {
|
||||||
|
|
||||||
GitHubHttpUrlConnectionClient(String apiUrl,
|
GitHubHttpUrlConnectionClient(String apiUrl,
|
||||||
String login,
|
|
||||||
String oauthAccessToken,
|
|
||||||
String jwtToken,
|
|
||||||
String password,
|
|
||||||
HttpConnector connector,
|
HttpConnector connector,
|
||||||
RateLimitHandler rateLimitHandler,
|
RateLimitHandler rateLimitHandler,
|
||||||
AbuseLimitHandler abuseLimitHandler,
|
AbuseLimitHandler abuseLimitHandler,
|
||||||
GitHubRateLimitChecker rateLimitChecker,
|
GitHubRateLimitChecker rateLimitChecker,
|
||||||
Consumer<GHMyself> myselfConsumer) throws IOException {
|
Consumer<GHMyself> myselfConsumer,
|
||||||
|
AuthorizationProvider authorizationProvider) throws IOException {
|
||||||
super(apiUrl,
|
super(apiUrl,
|
||||||
login,
|
|
||||||
oauthAccessToken,
|
|
||||||
jwtToken,
|
|
||||||
password,
|
|
||||||
connector,
|
connector,
|
||||||
rateLimitHandler,
|
rateLimitHandler,
|
||||||
abuseLimitHandler,
|
abuseLimitHandler,
|
||||||
rateLimitChecker,
|
rateLimitChecker,
|
||||||
myselfConsumer);
|
myselfConsumer,
|
||||||
|
authorizationProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@@ -114,8 +109,12 @@ class GitHubHttpUrlConnectionClient extends GitHubClient {
|
|||||||
|
|
||||||
// if the authentication is needed but no credential is given, try it anyway (so that some calls
|
// if the authentication is needed but no credential is given, try it anyway (so that some calls
|
||||||
// that do work with anonymous access in the reduced form should still work.)
|
// that do work with anonymous access in the reduced form should still work.)
|
||||||
if (client.encodedAuthorization != null)
|
if (!request.headers().containsKey("Authorization")) {
|
||||||
connection.setRequestProperty("Authorization", client.encodedAuthorization);
|
String authorization = client.getEncodedAuthorization();
|
||||||
|
if (authorization != null) {
|
||||||
|
connection.setRequestProperty("Authorization", client.getEncodedAuthorization());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setRequestMethod(request.method(), connection);
|
setRequestMethod(request.method(), connection);
|
||||||
buildRequest(request, connection);
|
buildRequest(request, connection);
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JacksonInject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a base class that all classes in this library that interact with GitHub inherit from.
|
||||||
|
*
|
||||||
|
* Ensures that all data references to GitHub connection are transient.
|
||||||
|
*
|
||||||
|
* Classes that do not need to interact with GitHub after they are instantiated do not need to inherit from this class.
|
||||||
|
*/
|
||||||
|
abstract class GitHubInteractiveObject {
|
||||||
|
@JacksonInject
|
||||||
|
/* package almost final */ transient GitHub root;
|
||||||
|
|
||||||
|
GitHubInteractiveObject() {
|
||||||
|
root = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
GitHubInteractiveObject(GitHub root) {
|
||||||
|
this.root = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
GitHub getRoot() {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,26 +3,28 @@ package org.kohsuke.github;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InterruptedIOException;
|
import java.io.InterruptedIOException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A GitHub API Rate Limit Checker called before each request. This class provides the basic infrastructure for calling
|
* A GitHub API Rate Limit Checker called before each request.
|
||||||
* the appropriate {@link RateLimitChecker} for a request and retrying as many times as needed. This class supports more
|
*
|
||||||
* complex throttling strategies and polling, but leaves the specifics to the {@link RateLimitChecker} implementations.
|
|
||||||
* <p>
|
* <p>
|
||||||
* GitHub allots a certain number of requests to each user or application per period of time (usually per hour). The
|
* GitHub allots a certain number of requests to each user or application per period of time. The number of requests
|
||||||
* number of requests remaining is returned in the response header and can also be requested using
|
* remaining and the time when the number will be reset is returned in the response header and can also be requested
|
||||||
* {@link GitHub#getRateLimit()}. This requests per interval is referred to as the "rate limit".
|
* using {@link GitHub#getRateLimit()}. The "requests per interval" is referred to as the "rate limit".
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* GitHub prefers that clients stop before exceeding their rate limit rather than stopping after they exceed it. The
|
* Different parts of the GitHub API have separate rate limits, but most of REST API uses {@link RateLimitTarget#CORE}.
|
||||||
* {@link RateLimitChecker} is called before each request to check the rate limit and wait if the checker criteria are
|
* Checking your rate limit using {@link GitHub#getRateLimit()} does not effect your rate limit. GitHub prefers that
|
||||||
* met.
|
* clients stop before exceeding their rate limit rather than stopping after they exceed it.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* Checking your rate limit using {@link GitHub#getRateLimit()} does not effect your rate limit, but each {@link GitHub}
|
* This class provides the infrastructure for calling the appropriate {@link RateLimitChecker} before each request and
|
||||||
* instance will attempt to cache and reuse the last see rate limit rather than making a new request.
|
* retrying than call many times as needed. Each {@link RateLimitChecker} decides whether to wait and for how long. This
|
||||||
|
* allows for a wide range of {@link RateLimitChecker} implementations, including complex throttling strategies and
|
||||||
|
* polling.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
class GitHubRateLimitChecker {
|
class GitHubRateLimitChecker {
|
||||||
@@ -39,6 +41,8 @@ class GitHubRateLimitChecker {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
private final RateLimitChecker integrationManifest;
|
private final RateLimitChecker integrationManifest;
|
||||||
|
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(GitHubRateLimitChecker.class.getName());
|
||||||
|
|
||||||
GitHubRateLimitChecker() {
|
GitHubRateLimitChecker() {
|
||||||
this(RateLimitChecker.NONE, RateLimitChecker.NONE, RateLimitChecker.NONE, RateLimitChecker.NONE);
|
this(RateLimitChecker.NONE, RateLimitChecker.NONE, RateLimitChecker.NONE, RateLimitChecker.NONE);
|
||||||
}
|
}
|
||||||
@@ -48,40 +52,57 @@ class GitHubRateLimitChecker {
|
|||||||
@Nonnull RateLimitChecker graphql,
|
@Nonnull RateLimitChecker graphql,
|
||||||
@Nonnull RateLimitChecker integrationManifest) {
|
@Nonnull RateLimitChecker integrationManifest) {
|
||||||
this.core = Objects.requireNonNull(core);
|
this.core = Objects.requireNonNull(core);
|
||||||
|
|
||||||
// for now only support rate limiting on core
|
|
||||||
// remove these asserts when that changes
|
|
||||||
assert search == RateLimitChecker.NONE;
|
|
||||||
assert graphql == RateLimitChecker.NONE;
|
|
||||||
assert integrationManifest == RateLimitChecker.NONE;
|
|
||||||
|
|
||||||
this.search = Objects.requireNonNull(search);
|
this.search = Objects.requireNonNull(search);
|
||||||
this.graphql = Objects.requireNonNull(graphql);
|
this.graphql = Objects.requireNonNull(graphql);
|
||||||
this.integrationManifest = Objects.requireNonNull(integrationManifest);
|
this.integrationManifest = Objects.requireNonNull(integrationManifest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link GitHubRateLimitChecker} with a new checker for a particular target.
|
||||||
|
*
|
||||||
|
* Only one {@link RateLimitChecker} is allowed per target.
|
||||||
|
*
|
||||||
|
* @param checker
|
||||||
|
* the {@link RateLimitChecker} to apply.
|
||||||
|
* @param rateLimitTarget
|
||||||
|
* the {@link RateLimitTarget} for this checker. If {@link RateLimitTarget#NONE}, checker will be ignored
|
||||||
|
* and no change will be made.
|
||||||
|
* @return a new {@link GitHubRateLimitChecker}
|
||||||
|
*/
|
||||||
|
GitHubRateLimitChecker with(@Nonnull RateLimitChecker checker, @Nonnull RateLimitTarget rateLimitTarget) {
|
||||||
|
return new GitHubRateLimitChecker(rateLimitTarget == RateLimitTarget.CORE ? checker : core,
|
||||||
|
rateLimitTarget == RateLimitTarget.SEARCH ? checker : search,
|
||||||
|
rateLimitTarget == RateLimitTarget.GRAPHQL ? checker : graphql,
|
||||||
|
rateLimitTarget == RateLimitTarget.INTEGRATION_MANIFEST ? checker : integrationManifest);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether there is sufficient requests remaining within this client's rate limit quota to make the current
|
* Checks whether there is sufficient requests remaining within this client's rate limit quota to make the current
|
||||||
* request.
|
* request.
|
||||||
* <p>
|
* <p>
|
||||||
* This method does not do the actual check. Instead it select the appropriate {@link RateLimitChecker} and
|
* This method does not do the actual check. Instead it selects the appropriate {@link RateLimitChecker} and
|
||||||
* {@link GHRateLimit.Record} for the current request's urlPath. If the {@link RateLimitChecker} for this the
|
* {@link GHRateLimit.Record} for the current request's {@link RateLimitTarget}. It then calls
|
||||||
* current request's urlPath is {@link RateLimitChecker#NONE} the rate limit is not checked. If not, it calls
|
* {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)}.
|
||||||
* {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)}. which decides if the rate limit has been
|
|
||||||
* exceeded and then sleeps for as long is it choose.
|
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* It is up to the {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)} which decide if the rate limit
|
* It is up to {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)} to which decide if the rate limit
|
||||||
* has been exceeded. If it has, that method will sleep for as long is it chooses and then return {@code true}. If
|
* has been exceeded. If it has, {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)} will sleep for as
|
||||||
* not, that method will return {@code false}.
|
* long is it chooses and then return {@code true}. If not, that method will return {@code false}.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* As long as {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)} returns {@code true}, this method
|
* As long as {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)} returns {@code true}, this method
|
||||||
* will request updated rate limit information and call
|
* will request updated rate limit information and call
|
||||||
* {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)} again. This looping allows implementers of
|
* {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)} again. This looping allows different
|
||||||
* {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)} to apply any number of strategies to
|
* {@link RateLimitChecker} implementations to apply any number of strategies to controlling the speed at which
|
||||||
* controlling the speed at which requests are made. When it returns {@code false} this method will return and the
|
* requests are made.
|
||||||
* request will be sent.
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* When the {@link RateLimitChecker} returns {@code false} this method will return and the request processing will
|
||||||
|
* continue.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* If the {@link RateLimitChecker} for this the current request's urlPath is {@link RateLimitChecker#NONE} the rate
|
||||||
|
* limit is not checked.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param client
|
* @param client
|
||||||
@@ -92,14 +113,14 @@ class GitHubRateLimitChecker {
|
|||||||
* if there is an I/O error
|
* if there is an I/O error
|
||||||
*/
|
*/
|
||||||
void checkRateLimit(GitHubClient client, GitHubRequest request) throws IOException {
|
void checkRateLimit(GitHubClient client, GitHubRequest request) throws IOException {
|
||||||
RateLimitChecker guard = selectChecker(request.urlPath());
|
RateLimitChecker guard = selectChecker(request.rateLimitTarget());
|
||||||
if (guard == RateLimitChecker.NONE) {
|
if (guard == RateLimitChecker.NONE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For the first rate limit, accept the current limit if a valid one is already present.
|
// For the first rate limit, accept the current limit if a valid one is already present.
|
||||||
GHRateLimit rateLimit = client.rateLimit();
|
GHRateLimit rateLimit = client.rateLimit(request.rateLimitTarget());
|
||||||
GHRateLimit.Record rateLimitRecord = rateLimit.getRecordForUrlPath(request.urlPath());
|
GHRateLimit.Record rateLimitRecord = rateLimit.getRecord(request.rateLimitTarget());
|
||||||
long waitCount = 0;
|
long waitCount = 0;
|
||||||
try {
|
try {
|
||||||
while (guard.checkRateLimit(rateLimitRecord, waitCount)) {
|
while (guard.checkRateLimit(rateLimitRecord, waitCount)) {
|
||||||
@@ -112,8 +133,8 @@ class GitHubRateLimitChecker {
|
|||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
|
|
||||||
// After the first wait, always request a new rate limit from the server.
|
// After the first wait, always request a new rate limit from the server.
|
||||||
rateLimit = client.getRateLimit();
|
rateLimit = client.getRateLimit(request.rateLimitTarget());
|
||||||
rateLimitRecord = rateLimit.getRecordForUrlPath(request.urlPath());
|
rateLimitRecord = rateLimit.getRecord(request.rateLimitTarget());
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw (IOException) new InterruptedIOException(e.getMessage()).initCause(e);
|
throw (IOException) new InterruptedIOException(e.getMessage()).initCause(e);
|
||||||
@@ -121,25 +142,28 @@ class GitHubRateLimitChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the appropriate {@link RateLimitChecker} for a particular url path. Similar to
|
* Gets the appropriate {@link RateLimitChecker} for a particular target.
|
||||||
* {@link GHRateLimit#getRecordForUrlPath(String)}.
|
|
||||||
*
|
*
|
||||||
* @param urlPath
|
* Analogous with {@link GHRateLimit#getRecord(RateLimitTarget)}.
|
||||||
* the url path of the request
|
*
|
||||||
* @return the {@link RateLimitChecker} for a url path.
|
* @param rateLimitTarget
|
||||||
|
* the rate limit to check
|
||||||
|
* @return the {@link RateLimitChecker} for a particular target
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private RateLimitChecker selectChecker(@Nonnull String urlPath) {
|
private RateLimitChecker selectChecker(@Nonnull RateLimitTarget rateLimitTarget) {
|
||||||
if (urlPath.equals("/rate_limit")) {
|
if (rateLimitTarget == RateLimitTarget.NONE) {
|
||||||
return RateLimitChecker.NONE;
|
return RateLimitChecker.NONE;
|
||||||
} else if (urlPath.startsWith("/search")) {
|
} else if (rateLimitTarget == RateLimitTarget.CORE) {
|
||||||
|
return core;
|
||||||
|
} else if (rateLimitTarget == RateLimitTarget.SEARCH) {
|
||||||
return search;
|
return search;
|
||||||
} else if (urlPath.startsWith("/graphql")) {
|
} else if (rateLimitTarget == RateLimitTarget.GRAPHQL) {
|
||||||
return graphql;
|
return graphql;
|
||||||
} else if (urlPath.startsWith("/app-manifests")) {
|
} else if (rateLimitTarget == RateLimitTarget.INTEGRATION_MANIFEST) {
|
||||||
return integrationManifest;
|
return integrationManifest;
|
||||||
} else {
|
} else {
|
||||||
return core;
|
throw new IllegalArgumentException("Unknown rate limit target: " + rateLimitTarget.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.kohsuke.github;
|
|||||||
|
|
||||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.kohsuke.github.internal.Previews;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
@@ -45,6 +46,7 @@ class GitHubRequest {
|
|||||||
private final String apiUrl;
|
private final String apiUrl;
|
||||||
private final String urlPath;
|
private final String urlPath;
|
||||||
private final String method;
|
private final String method;
|
||||||
|
private final RateLimitTarget rateLimitTarget;
|
||||||
private final InputStream body;
|
private final InputStream body;
|
||||||
private final boolean forceBody;
|
private final boolean forceBody;
|
||||||
|
|
||||||
@@ -56,6 +58,7 @@ class GitHubRequest {
|
|||||||
@Nonnull String apiUrl,
|
@Nonnull String apiUrl,
|
||||||
@Nonnull String urlPath,
|
@Nonnull String urlPath,
|
||||||
@Nonnull String method,
|
@Nonnull String method,
|
||||||
|
@Nonnull RateLimitTarget rateLimitTarget,
|
||||||
@CheckForNull InputStream body,
|
@CheckForNull InputStream body,
|
||||||
boolean forceBody) throws MalformedURLException {
|
boolean forceBody) throws MalformedURLException {
|
||||||
this.args = Collections.unmodifiableList(new ArrayList<>(args));
|
this.args = Collections.unmodifiableList(new ArrayList<>(args));
|
||||||
@@ -64,6 +67,7 @@ class GitHubRequest {
|
|||||||
this.apiUrl = apiUrl;
|
this.apiUrl = apiUrl;
|
||||||
this.urlPath = urlPath;
|
this.urlPath = urlPath;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
|
this.rateLimitTarget = rateLimitTarget;
|
||||||
this.body = body;
|
this.body = body;
|
||||||
this.forceBody = forceBody;
|
this.forceBody = forceBody;
|
||||||
String tailApiUrl = buildTailApiUrl();
|
String tailApiUrl = buildTailApiUrl();
|
||||||
@@ -72,7 +76,7 @@ class GitHubRequest {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link Builder}.
|
* Create a new {@link Builder}.
|
||||||
*
|
*
|
||||||
* @return a new {@link Builder}.
|
* @return a new {@link Builder}.
|
||||||
*/
|
*/
|
||||||
public static Builder<?> newBuilder() {
|
public static Builder<?> newBuilder() {
|
||||||
@@ -119,6 +123,16 @@ class GitHubRequest {
|
|||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rate limit target for this request.
|
||||||
|
*
|
||||||
|
* @return the rate limit to use for this request.
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public RateLimitTarget rateLimitTarget() {
|
||||||
|
return rateLimitTarget;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The arguments for this request. Depending on the {@link #method()} and {@code #inBody()} these maybe added to the
|
* The arguments for this request. Depending on the {@link #method()} and {@code #inBody()} these maybe added to the
|
||||||
* url or to the request body.
|
* url or to the request body.
|
||||||
@@ -152,7 +166,7 @@ class GitHubRequest {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The base GitHub API URL for this request represented as a {@link String}
|
* The base GitHub API URL for this request represented as a {@link String}
|
||||||
*
|
*
|
||||||
* @return the url string
|
* @return the url string
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@@ -163,7 +177,7 @@ class GitHubRequest {
|
|||||||
/**
|
/**
|
||||||
* The url path to be added to the {@link #apiUrl()} for this request. If this does not start with a "/", it instead
|
* The url path to be added to the {@link #apiUrl()} for this request. If this does not start with a "/", it instead
|
||||||
* represents the full url string for this request.
|
* represents the full url string for this request.
|
||||||
*
|
*
|
||||||
* @return a url path or full url string
|
* @return a url path or full url string
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@@ -173,7 +187,7 @@ class GitHubRequest {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The content type to to be sent by this request.
|
* The content type to to be sent by this request.
|
||||||
*
|
*
|
||||||
* @return the content type.
|
* @return the content type.
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@@ -183,7 +197,7 @@ class GitHubRequest {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link InputStream} to be sent as the body of this request.
|
* The {@link InputStream} to be sent as the body of this request.
|
||||||
*
|
*
|
||||||
* @return the {@link InputStream}.
|
* @return the {@link InputStream}.
|
||||||
*/
|
*/
|
||||||
@CheckForNull
|
@CheckForNull
|
||||||
@@ -193,7 +207,7 @@ class GitHubRequest {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link URL} for this request. This is the actual URL the {@link GitHubClient} will send this request to.
|
* The {@link URL} for this request. This is the actual URL the {@link GitHubClient} will send this request to.
|
||||||
*
|
*
|
||||||
* @return the request {@link URL}
|
* @return the request {@link URL}
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@@ -203,7 +217,7 @@ class GitHubRequest {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether arguments for this request should be included in the URL or in the body of the request.
|
* Whether arguments for this request should be included in the URL or in the body of the request.
|
||||||
*
|
*
|
||||||
* @return true if the arguements should be sent in the body of the request.
|
* @return true if the arguements should be sent in the body of the request.
|
||||||
*/
|
*/
|
||||||
public boolean inBody() {
|
public boolean inBody() {
|
||||||
@@ -213,11 +227,19 @@ class GitHubRequest {
|
|||||||
/**
|
/**
|
||||||
* Create a {@link Builder} from this request. Initial values of the builder will be the same as this
|
* Create a {@link Builder} from this request. Initial values of the builder will be the same as this
|
||||||
* {@link GitHubRequest}.
|
* {@link GitHubRequest}.
|
||||||
*
|
*
|
||||||
* @return a {@link Builder} based on this request.
|
* @return a {@link Builder} based on this request.
|
||||||
*/
|
*/
|
||||||
public Builder<?> toBuilder() {
|
public Builder<?> toBuilder() {
|
||||||
return new Builder<>(args, headers, injectedMappingValues, apiUrl, urlPath, method, body, forceBody);
|
return new Builder<>(args,
|
||||||
|
headers,
|
||||||
|
injectedMappingValues,
|
||||||
|
apiUrl,
|
||||||
|
urlPath,
|
||||||
|
method,
|
||||||
|
rateLimitTarget,
|
||||||
|
body,
|
||||||
|
forceBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildTailApiUrl() {
|
private String buildTailApiUrl() {
|
||||||
@@ -281,6 +303,10 @@ class GitHubRequest {
|
|||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private String method;
|
private String method;
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private RateLimitTarget rateLimitTarget;
|
||||||
|
|
||||||
private InputStream body;
|
private InputStream body;
|
||||||
private boolean forceBody;
|
private boolean forceBody;
|
||||||
|
|
||||||
@@ -294,6 +320,7 @@ class GitHubRequest {
|
|||||||
GitHubClient.GITHUB_URL,
|
GitHubClient.GITHUB_URL,
|
||||||
"/",
|
"/",
|
||||||
"GET",
|
"GET",
|
||||||
|
RateLimitTarget.CORE,
|
||||||
null,
|
null,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
@@ -304,6 +331,7 @@ class GitHubRequest {
|
|||||||
@Nonnull String apiUrl,
|
@Nonnull String apiUrl,
|
||||||
@Nonnull String urlPath,
|
@Nonnull String urlPath,
|
||||||
@Nonnull String method,
|
@Nonnull String method,
|
||||||
|
@Nonnull RateLimitTarget rateLimitTarget,
|
||||||
@CheckForNull @WillClose InputStream body,
|
@CheckForNull @WillClose InputStream body,
|
||||||
boolean forceBody) {
|
boolean forceBody) {
|
||||||
this.args = new ArrayList<>(args);
|
this.args = new ArrayList<>(args);
|
||||||
@@ -312,19 +340,28 @@ class GitHubRequest {
|
|||||||
this.apiUrl = apiUrl;
|
this.apiUrl = apiUrl;
|
||||||
this.urlPath = urlPath;
|
this.urlPath = urlPath;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
|
this.rateLimitTarget = rateLimitTarget;
|
||||||
this.body = body;
|
this.body = body;
|
||||||
this.forceBody = forceBody;
|
this.forceBody = forceBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a {@link GitHubRequest} from this builder.
|
* Builds a {@link GitHubRequest} from this builder.
|
||||||
*
|
*
|
||||||
* @return a {@link GitHubRequest}
|
* @return a {@link GitHubRequest}
|
||||||
* @throws MalformedURLException
|
* @throws MalformedURLException
|
||||||
* if the GitHub API URL cannot be constructed
|
* if the GitHub API URL cannot be constructed
|
||||||
*/
|
*/
|
||||||
public GitHubRequest build() throws MalformedURLException {
|
public GitHubRequest build() throws MalformedURLException {
|
||||||
return new GitHubRequest(args, headers, injectedMappingValues, apiUrl, urlPath, method, body, forceBody);
|
return new GitHubRequest(args,
|
||||||
|
headers,
|
||||||
|
injectedMappingValues,
|
||||||
|
apiUrl,
|
||||||
|
urlPath,
|
||||||
|
method,
|
||||||
|
rateLimitTarget,
|
||||||
|
body,
|
||||||
|
forceBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -348,9 +385,11 @@ class GitHubRequest {
|
|||||||
* the name
|
* the name
|
||||||
* @param value
|
* @param value
|
||||||
* the value
|
* the value
|
||||||
|
* @return the request builder
|
||||||
*/
|
*/
|
||||||
public void setHeader(String name, String value) {
|
public B setHeader(String name, String value) {
|
||||||
headers.put(name, value);
|
headers.put(name, value);
|
||||||
|
return (B) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -363,8 +402,11 @@ class GitHubRequest {
|
|||||||
* @return the request builder
|
* @return the request builder
|
||||||
*/
|
*/
|
||||||
public B withHeader(String name, String value) {
|
public B withHeader(String name, String value) {
|
||||||
setHeader(name, value);
|
String oldValue = headers.get(name);
|
||||||
return (B) this;
|
if (!StringUtils.isBlank(oldValue)) {
|
||||||
|
value = oldValue + ", " + value;
|
||||||
|
}
|
||||||
|
return setHeader(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -396,6 +438,25 @@ class GitHubRequest {
|
|||||||
return withHeader("Accept", name);
|
return withHeader("Accept", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public B withPreview(Previews preview) {
|
||||||
|
return withPreview(preview.mediaType());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* With requester.
|
||||||
|
*
|
||||||
|
* @param Map
|
||||||
|
* map of key value pairs to add
|
||||||
|
* @return the request builder
|
||||||
|
*/
|
||||||
|
public B with(Map<String, Object> map) {
|
||||||
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||||
|
with(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return (B) this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* With requester.
|
* With requester.
|
||||||
*
|
*
|
||||||
@@ -562,6 +623,18 @@ class GitHubRequest {
|
|||||||
return (B) this;
|
return (B) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method requester.
|
||||||
|
*
|
||||||
|
* @param rateLimitTarget
|
||||||
|
* the rate limit target for this request. Default is {@link RateLimitTarget#CORE}.
|
||||||
|
* @return the request builder
|
||||||
|
*/
|
||||||
|
public B rateLimit(@Nonnull RateLimitTarget rateLimitTarget) {
|
||||||
|
this.rateLimitTarget = rateLimitTarget;
|
||||||
|
return (B) this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Content type requester.
|
* Content type requester.
|
||||||
*
|
*
|
||||||
@@ -623,13 +696,9 @@ class GitHubRequest {
|
|||||||
tailUrlPath += "/" + String.join("/", urlPathItems);
|
tailUrlPath += "/" + String.join("/", urlPathItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.urlPath.endsWith("/")) {
|
tailUrlPath = StringUtils.prependIfMissing(tailUrlPath, "/");
|
||||||
tailUrlPath = StringUtils.stripStart(tailUrlPath, "/");
|
|
||||||
} else {
|
|
||||||
tailUrlPath = StringUtils.prependIfMissing(tailUrlPath, "/");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.urlPath += urlPathEncode(tailUrlPath);
|
this.urlPath = urlPathEncode(tailUrlPath);
|
||||||
return (B) this;
|
return (B) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonParseException;
|
|||||||
import com.fasterxml.jackson.databind.InjectableValues;
|
import com.fasterxml.jackson.databind.InjectableValues;
|
||||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.kohsuke.github.function.FunctionThrows;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -78,9 +79,14 @@ class GitHubResponse<T> {
|
|||||||
@CheckForNull
|
@CheckForNull
|
||||||
static <T> T parseBody(ResponseInfo responseInfo, Class<T> type) throws IOException {
|
static <T> T parseBody(ResponseInfo responseInfo, Class<T> type) throws IOException {
|
||||||
|
|
||||||
if (responseInfo.statusCode() == HttpURLConnection.HTTP_NO_CONTENT && type != null && type.isArray()) {
|
if (responseInfo.statusCode() == HttpURLConnection.HTTP_NO_CONTENT) {
|
||||||
// no content
|
if (type != null && type.isArray()) {
|
||||||
return type.cast(Array.newInstance(type.getComponentType(), 0));
|
// no content for array should be empty array
|
||||||
|
return type.cast(Array.newInstance(type.getComponentType(), 0));
|
||||||
|
} else {
|
||||||
|
// no content for object should be null
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String data = responseInfo.getBodyAsString();
|
String data = responseInfo.getBodyAsString();
|
||||||
@@ -189,24 +195,11 @@ class GitHubResponse<T> {
|
|||||||
/**
|
/**
|
||||||
* Represents a supplier of results that can throw.
|
* Represents a supplier of results that can throw.
|
||||||
*
|
*
|
||||||
* <p>
|
|
||||||
* This is a <a href="package-summary.html">functional interface</a> whose functional method is
|
|
||||||
* {@link #apply(ResponseInfo)}.
|
|
||||||
*
|
|
||||||
* @param <T>
|
* @param <T>
|
||||||
* the type of results supplied by this supplier
|
* the type of results supplied by this supplier
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
interface BodyHandler<T> {
|
interface BodyHandler<T> extends FunctionThrows<ResponseInfo, T, IOException> {
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a result.
|
|
||||||
*
|
|
||||||
* @return a result
|
|
||||||
* @throws IOException
|
|
||||||
* if an I/O Exception occurs.
|
|
||||||
*/
|
|
||||||
T apply(ResponseInfo input) throws IOException;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
|||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.annotation.CheckForNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a user in Git who authors/commits a commit.
|
* Represents a user in Git who authors/commits a commit.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -15,10 +17,10 @@ import java.util.Date;
|
|||||||
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
|
||||||
justification = "JSON API")
|
justification = "JSON API")
|
||||||
public class GitUser {
|
public class GitUser {
|
||||||
private String name, email, date;
|
private String name, email, date, username;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets name.
|
* Gets the git user name for an author or committer on a git commit.
|
||||||
*
|
*
|
||||||
* @return Human readable name of the user, such as "Kohsuke Kawaguchi"
|
* @return Human readable name of the user, such as "Kohsuke Kawaguchi"
|
||||||
*/
|
*/
|
||||||
@@ -27,18 +29,28 @@ public class GitUser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets email.
|
* Gets the git email for an author or committer on a git commit.
|
||||||
*
|
*
|
||||||
* @return E -mail address, such as "foo@example.com"
|
* @return E-mail address, such as "foo@example.com"
|
||||||
*/
|
*/
|
||||||
public String getEmail() {
|
public String getEmail() {
|
||||||
return email;
|
return email;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets username. Note: it presents only in events.
|
||||||
|
*
|
||||||
|
* @return GitHub username
|
||||||
|
*/
|
||||||
|
@CheckForNull
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets date.
|
* Gets date.
|
||||||
*
|
*
|
||||||
* @return This field doesn't appear to be consistently available in all the situations where this class is used.
|
* @return Commit Date.
|
||||||
*/
|
*/
|
||||||
public Date getDate() {
|
public Date getDate() {
|
||||||
return GitHubClient.parseDate(date);
|
return GitHubClient.parseDate(date);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user