mirror of
https://github.com/jlengrand/github-api.git
synced 2026-03-11 00:11:25 +00:00
Compare commits
130 Commits
github-api
...
github-api
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9022455d85 | ||
|
|
7c8a7ff26e | ||
|
|
064d6944f3 | ||
|
|
b8b3cf9c80 | ||
|
|
18e7138812 | ||
|
|
bfb3b94478 | ||
|
|
6167d196d9 | ||
|
|
43ed7c7ac7 | ||
|
|
fc98e72569 | ||
|
|
258acf79f6 | ||
|
|
b509076d6f | ||
|
|
f57ea4c4e9 | ||
|
|
578fe085ce | ||
|
|
2553a79b02 | ||
|
|
4770316898 | ||
|
|
99f192d33c | ||
|
|
fc3bac0e77 | ||
|
|
ad2990b1b6 | ||
|
|
fab848a0d3 | ||
|
|
4a2244e661 | ||
|
|
bab5399327 | ||
|
|
52705ac695 | ||
|
|
73d2e1db5c | ||
|
|
83aa9d04ef | ||
|
|
97652c6803 | ||
|
|
f40daf8488 | ||
|
|
3e6a5bc718 | ||
|
|
78ffe5a759 | ||
|
|
9abfdc805b | ||
|
|
9e47a2b8c6 | ||
|
|
feba6ed8b6 | ||
|
|
acab40b704 | ||
|
|
435272065f | ||
|
|
c5c04672fc | ||
|
|
5eef764cba | ||
|
|
2682e0a1e2 | ||
|
|
a68d16d5de | ||
|
|
304ab10cf9 | ||
|
|
dc46341432 | ||
|
|
99aea9296e | ||
|
|
b0693037f3 | ||
|
|
c19cfd98d1 | ||
|
|
cdc0e2ad6b | ||
|
|
6606b5c7d1 | ||
|
|
551dbf2a06 | ||
|
|
d734237788 | ||
|
|
47e2a5aea1 | ||
|
|
57cdc308e8 | ||
|
|
8919c5f8c7 | ||
|
|
b8f00bc699 | ||
|
|
042038f480 | ||
|
|
fb03e749bd | ||
|
|
e522239832 | ||
|
|
ae69324196 | ||
|
|
5194c2d9bc | ||
|
|
daf5c5eb98 | ||
|
|
a7b4c97020 | ||
|
|
420d5d06f3 | ||
|
|
a7cd052b7c | ||
|
|
6e1b943823 | ||
|
|
8a3559ada5 | ||
|
|
ea3cbd4c71 | ||
|
|
34a1f9d6e4 | ||
|
|
629bd510c1 | ||
|
|
40937a5cc6 | ||
|
|
8509957102 | ||
|
|
b0aea0c575 | ||
|
|
1f7f646bec | ||
|
|
a59ee6a82d | ||
|
|
1fefc77582 | ||
|
|
199eee4e25 | ||
|
|
854df5321b | ||
|
|
bd509070ac | ||
|
|
a8c7c97d06 | ||
|
|
6d86cfb4f6 | ||
|
|
fb3e956502 | ||
|
|
9b0dbe6f34 | ||
|
|
c10c7237a7 | ||
|
|
36612fe97f | ||
|
|
18e2056a10 | ||
|
|
8c8f1451d4 | ||
|
|
be67f1d9e2 | ||
|
|
90bc250269 | ||
|
|
1bd178654f | ||
|
|
f22bf160f9 | ||
|
|
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 | ||
|
|
4d9aed90d6 | ||
|
|
f1720b7bbc | ||
|
|
7a79a18d8f | ||
|
|
472034c950 | ||
|
|
b50ab56f9e | ||
|
|
26d30663c4 | ||
|
|
ffecc390eb | ||
|
|
aae5c56a31 | ||
|
|
d7931777bc | ||
|
|
bb48d55bd4 |
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.
|
||||
- [ ] 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.
|
||||
- [ ] 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:
|
||||
|
||||
|
||||
36
.github/workflows/maven-build.yml
vendored
36
.github/workflows/maven-build.yml
vendored
@@ -2,14 +2,18 @@ name: CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
# this is required by spotless for JDK 16+
|
||||
env:
|
||||
JAVA_11_PLUS_MAVEN_OPTS: "--add-opens jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build-only (Java ${{ matrix.java }})
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java: [ 13 ]
|
||||
java: [ 16 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK
|
||||
@@ -17,18 +21,21 @@ jobs:
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
- name: Cached .m2
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v2.1.4
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
- name: Maven Install (skipTests)
|
||||
run: mvn -B install -DskipTests -D enable-ci --file pom.xml
|
||||
env:
|
||||
MAVEN_OPTS: ${{ env.JAVA_11_PLUS_MAVEN_OPTS }}
|
||||
run: mvn -B install -DskipTests --file pom.xml
|
||||
site:
|
||||
name: site (Java ${{ matrix.java }})
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java: [ 8, 11 ]
|
||||
steps:
|
||||
@@ -37,7 +44,7 @@ jobs:
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
- uses: actions/cache@v2
|
||||
- uses: actions/cache@v2.1.4
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
@@ -49,24 +56,37 @@ jobs:
|
||||
name: test (${{ matrix.os }}, Java ${{ matrix.java }})
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu, windows ]
|
||||
java: [ 8, 11, 13, 15-ea ]
|
||||
java: [ 8, 11, 16 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
- uses: actions/cache@v2
|
||||
- uses: actions/cache@v2.1.4
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
# JDK 8
|
||||
- name: Maven Install without Code Coverage
|
||||
if: matrix.os == 'windows'
|
||||
if: matrix.os == 'windows' && matrix.java == '8'
|
||||
run: mvn -B install --file pom.xml
|
||||
- name: Maven Install with Code Coverage
|
||||
if: matrix.os != 'windows'
|
||||
if: matrix.os != 'windows' && matrix.java == '8'
|
||||
run: mvn -B install -D enable-ci --file pom.xml
|
||||
# JDK 11+
|
||||
- name: Maven Install without Code Coverage
|
||||
if: matrix.os == 'windows' && matrix.java != '8'
|
||||
env:
|
||||
MAVEN_OPTS: ${{ env.JAVA_11_PLUS_MAVEN_OPTS }}
|
||||
run: mvn -B install --file pom.xml
|
||||
- name: Maven Install with Code Coverage
|
||||
if: matrix.os != 'windows' && matrix.java != '8'
|
||||
env:
|
||||
MAVEN_OPTS: ${{ env.JAVA_11_PLUS_MAVEN_OPTS }}
|
||||
run: mvn -B install -D enable-ci --file pom.xml
|
||||
|
||||
@@ -21,7 +21,7 @@ Example for a single test case:
|
||||
|
||||
### Setting up credential
|
||||
|
||||
1. Create an OAuth token on github.com
|
||||
1. Create a "Personal access token" on https://github.com/ (`Settings` > `Developer settings` > `Personal access tokens`)
|
||||
2. Set the GITHUB_OAUTH environment variable to the value of that token
|
||||
3. Set the system property `test.github.useProxy` (usually like "-Dtest.github.useProxy" as a Java VM option)
|
||||
|
||||
|
||||
178
pom.xml
178
pom.xml
@@ -2,7 +2,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.kohsuke</groupId>
|
||||
<artifactId>github-api</artifactId>
|
||||
<version>1.121</version>
|
||||
<version>1.127</version>
|
||||
<name>GitHub API for Java</name>
|
||||
<url>https://github-api.kohsuke.org/</url>
|
||||
<description>GitHub API for Java</description>
|
||||
@@ -11,7 +11,7 @@
|
||||
<connection>scm:git:git@github.com/hub4j/${project.artifactId}.git</connection>
|
||||
<developerConnection>scm:git:ssh://git@github.com/hub4j/${project.artifactId}.git</developerConnection>
|
||||
<url>https://github.com/hub4j/github-api/</url>
|
||||
<tag>github-api-1.121</tag>
|
||||
<tag>github-api-1.127</tag>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
@@ -33,19 +33,21 @@
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<spotbugs-maven-plugin.version>4.1.4</spotbugs-maven-plugin.version>
|
||||
<spotbugs.version>4.1.3</spotbugs.version>
|
||||
<spotbugs-maven-plugin.version>4.2.0</spotbugs-maven-plugin.version>
|
||||
<spotbugs.version>4.2.2</spotbugs.version>
|
||||
<spotbugs-maven-plugin.failOnError>true</spotbugs-maven-plugin.failOnError>
|
||||
<hamcrest.version>2.2</hamcrest.version>
|
||||
<okhttp3.version>4.4.1</okhttp3.version>
|
||||
<okio.version>2.5.0</okio.version>
|
||||
<spotless-maven-plugin.goal>apply</spotless-maven-plugin.goal>
|
||||
<!-- 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.class.method>0.25</jacoco.coverage.target.class.method>
|
||||
<jacoco.coverage.target.bundle.method>0.70</jacoco.coverage.target.bundle.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. -->
|
||||
<jacoco.haltOnFailure>false</jacoco.haltOnFailure>
|
||||
<jjwt.suite.version>0.11.2</jjwt.suite.version>
|
||||
|
||||
<jacoco.surefire.argLine />
|
||||
<surefire.argLine />
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
@@ -106,6 +108,9 @@
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<propertyName>jacoco.surefire.argLine</propertyName>
|
||||
</configuration>
|
||||
</execution>
|
||||
<!-- attached to Maven test phase -->
|
||||
<execution>
|
||||
@@ -153,59 +158,39 @@
|
||||
<!-- Sample only -->
|
||||
<exclude>org.kohsuke.github.example.*</exclude>
|
||||
|
||||
<!-- No methods -->
|
||||
<exclude>org.kohsuke.github.internal.Previews</exclude>
|
||||
|
||||
<!-- Deprecated -->
|
||||
<exclude>org.kohsuke.github.extras.OkHttp3Connector</exclude>
|
||||
<exclude>org.kohsuke.github.EnforcementLevel</exclude>
|
||||
<exclude>org.kohsuke.github.GHPerson.1</exclude>
|
||||
|
||||
<!-- These fail coverage on windows because tests are disabled -->
|
||||
<exclude>org.kohsuke.github.GHAsset</exclude>
|
||||
<exclude>org.kohsuke.github.GHReleaseBuilder</exclude>
|
||||
<exclude>org.kohsuke.github.GHRelease</exclude>
|
||||
<!-- TODO: Some coverage, but more needed -->
|
||||
<exclude>org.kohsuke.github.GHPullRequestReviewBuilder.DraftReviewComment</exclude>
|
||||
<exclude>org.kohsuke.github.GHIssue.PullRequest</exclude>
|
||||
<exclude>org.kohsuke.github.GHCommitSearchBuilder</exclude>
|
||||
<exclude>org.kohsuke.github.GHRepositorySearchBuilder</exclude>
|
||||
<exclude>org.kohsuke.github.GHUserSearchBuilder</exclude>
|
||||
|
||||
<!-- TODO: These still need test coverage -->
|
||||
<exclude>org.kohsuke.github.GHBranchProtection.RequiredSignatures</exclude>
|
||||
<exclude>org.kohsuke.github.GHBranchProtectionBuilder.Restrictions</exclude>
|
||||
<exclude>org.kohsuke.github.GHBranchProtection.Restrictions</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.InnerCommit</exclude>
|
||||
<exclude>org.kohsuke.github.GHCompare.Status</exclude>
|
||||
<exclude>org.kohsuke.github.GHCompare.Tree</exclude>
|
||||
<exclude>org.kohsuke.github.GHCompare.User</exclude>
|
||||
<exclude>org.kohsuke.github.GHCompare</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.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.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.Commit</exclude>
|
||||
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.CommitPointer</exclude>
|
||||
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.Tree</exclude>
|
||||
<exclude>org.kohsuke.github.GHPullRequestCommitDetail</exclude>
|
||||
<exclude>org.kohsuke.github.GHPullRequestFileDetail</exclude>
|
||||
<exclude>org.kohsuke.github.GHPullRequestQueryBuilder.Sort</exclude>
|
||||
<exclude>org.kohsuke.github.GHReleaseUpdater</exclude>
|
||||
<exclude>org.kohsuke.github.GHRepository.ForkSort</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>
|
||||
</excludes>
|
||||
</rule>
|
||||
@@ -293,18 +278,7 @@
|
||||
<id>default-test</id>
|
||||
<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>
|
||||
<argLine>@{jacoco.surefire.argLine} ${surefire.argLine}</argLine>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
@@ -312,7 +286,7 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>animal-sniffer-maven-plugin</artifactId>
|
||||
<version>1.19</version>
|
||||
<version>1.20</version>
|
||||
<configuration>
|
||||
<signature>
|
||||
<groupId>org.codehaus.mojo.signature</groupId>
|
||||
@@ -345,13 +319,14 @@
|
||||
<plugin>
|
||||
<groupId>com.diffplug.spotless</groupId>
|
||||
<artifactId>spotless-maven-plugin</artifactId>
|
||||
<version>2.6.1</version>
|
||||
<version>2.9.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>spotless-check</id>
|
||||
<phase>process-sources</phase>
|
||||
<!-- runs in verify phase by default -->
|
||||
<goals>
|
||||
<goal>${spotless-maven-plugin.goal}</goal>
|
||||
<!-- can be disabled using -Dspotless.check.skip=true -->
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
@@ -410,7 +385,7 @@
|
||||
<dependency>
|
||||
<groupId>com.tngtech.archunit</groupId>
|
||||
<artifactId>archunit</artifactId>
|
||||
<version>0.15.0</version>
|
||||
<version>0.17.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -435,13 +410,19 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<version>4.13.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<version>4.0.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.10.2</version>
|
||||
<version>2.12.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
@@ -484,7 +465,7 @@
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jgit</groupId>
|
||||
<artifactId>org.eclipse.jgit</artifactId>
|
||||
<version>5.10.0.202012080955-r</version>
|
||||
<version>5.11.0.202103091610-r</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -540,7 +521,7 @@
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>3.6.28</version>
|
||||
<version>3.8.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -581,6 +562,48 @@
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
<profiles>
|
||||
<!-- only enable slow-or-flaky-test if -Dtest= is not present -->
|
||||
<profile>
|
||||
<id>slow-or-flaky-test</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!test</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<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>
|
||||
<argLine>@{jacoco.surefire.argLine} ${surefire.argLine}</argLine>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>jdk11+</id>
|
||||
<activation>
|
||||
<jdk>[11,)</jdk>
|
||||
</activation>
|
||||
<properties>
|
||||
<!-- this is required for GithubHttpUrlConnectionClient#setRequestMethod() to work with JDK 16+ -->
|
||||
<surefire.argLine>--add-opens java.base/java.net=ALL-UNNAMED</surefire.argLine>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>ci-non-windows</id>
|
||||
<activation>
|
||||
@@ -592,7 +615,8 @@
|
||||
</os>
|
||||
</activation>
|
||||
<properties>
|
||||
<spotless-maven-plugin.goal>check</spotless-maven-plugin.goal>
|
||||
<!-- Only fail code coverage on non-windows machines -->
|
||||
<jacoco.haltOnFailure>true</jacoco.haltOnFailure>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
@@ -602,23 +626,55 @@
|
||||
<name>enable-ci</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<jacoco.haltOnFailure>true</jacoco.haltOnFailure>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
</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>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>3.0.0-M3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-jacoco-exist</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requireFilesExist>
|
||||
<files>
|
||||
<file>${project.build.directory}/jacoco.exec</file>
|
||||
</files>
|
||||
</requireFilesExist>
|
||||
</rules>
|
||||
<fail>true</fail>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>release</id>
|
||||
<properties>
|
||||
<spotless-maven-plugin.goal>check</spotless-maven-plugin.goal>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
140
src/main/java/org/kohsuke/github/GHArtifact.java
Normal file
140
src/main/java/org/kohsuke/github/GHArtifact.java
Normal file
@@ -0,0 +1,140 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.kohsuke.github.function.InputStreamFunction;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* An artifact from a workflow run.
|
||||
*
|
||||
* @author Guillaume Smet
|
||||
*/
|
||||
public class GHArtifact extends GHObject {
|
||||
|
||||
// Not provided by the API.
|
||||
@JsonIgnore
|
||||
private GHRepository owner;
|
||||
|
||||
private String name;
|
||||
private long sizeInBytes;
|
||||
private String archiveDownloadUrl;
|
||||
private boolean expired;
|
||||
private String expiresAt;
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the artifact in bytes.
|
||||
*
|
||||
* @return the size
|
||||
*/
|
||||
public long getSizeInBytes() {
|
||||
return sizeInBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the archive download URL.
|
||||
*
|
||||
* @return the archive download URL
|
||||
*/
|
||||
public URL getArchiveDownloadUrl() {
|
||||
return GitHubClient.parseURL(archiveDownloadUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* If this artifact has expired.
|
||||
*
|
||||
* @return if the artifact has expired
|
||||
*/
|
||||
public boolean isExpired() {
|
||||
return expired;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the date at which this artifact will expire.
|
||||
*
|
||||
* @return the date of expiration
|
||||
*/
|
||||
public Date getExpiresAt() {
|
||||
return GitHubClient.parseDate(expiresAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Repository to which the artifact belongs.
|
||||
*
|
||||
* @return the repository
|
||||
*/
|
||||
public GHRepository getRepository() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This object has no HTML URL.
|
||||
*/
|
||||
@Override
|
||||
public URL getHtmlUrl() throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the artifact.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void delete() throws IOException {
|
||||
root.createRequest().method("DELETE").withUrlPath(getApiRoute()).fetchHttpStatusCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads the artifact.
|
||||
*
|
||||
* @param <T>
|
||||
* the type of result
|
||||
* @param streamFunction
|
||||
* The {@link InputStreamFunction} that will process the stream
|
||||
* @throws IOException
|
||||
* The IO exception.
|
||||
* @return the result of reading the stream.
|
||||
*/
|
||||
public <T> T download(InputStreamFunction<T> streamFunction) throws IOException {
|
||||
requireNonNull(streamFunction, "Stream function must not be null");
|
||||
|
||||
return root.createRequest().method("GET").withUrlPath(getApiRoute(), "zip").fetchStream(streamFunction);
|
||||
}
|
||||
|
||||
private String getApiRoute() {
|
||||
if (owner == null) {
|
||||
// Workflow runs returned from search to do not have an owner. Attempt to use url.
|
||||
final URL url = Objects.requireNonNull(getUrl(), "Missing instance URL!");
|
||||
return StringUtils.prependIfMissing(url.toString().replace(root.getApiUrl(), ""), "/");
|
||||
}
|
||||
return "/repos/" + owner.getOwnerName() + "/" + owner.getName() + "/actions/artifacts/" + getId();
|
||||
}
|
||||
|
||||
GHArtifact wrapUp(GHRepository owner) {
|
||||
this.owner = owner;
|
||||
return wrapUp(owner.root);
|
||||
}
|
||||
|
||||
GHArtifact wrapUp(GitHub root) {
|
||||
this.root = root;
|
||||
if (owner != null)
|
||||
owner.wrap(root);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
49
src/main/java/org/kohsuke/github/GHArtifactsIterable.java
Normal file
49
src/main/java/org/kohsuke/github/GHArtifactsIterable.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Iterable for artifacts listing.
|
||||
*/
|
||||
class GHArtifactsIterable extends PagedIterable<GHArtifact> {
|
||||
private final transient GHRepository owner;
|
||||
private final GitHubRequest request;
|
||||
|
||||
private GHArtifactsPage result;
|
||||
|
||||
public GHArtifactsIterable(GHRepository owner, GitHubRequest.Builder<?> requestBuilder) {
|
||||
this.owner = owner;
|
||||
try {
|
||||
this.request = requestBuilder.build();
|
||||
} catch (MalformedURLException e) {
|
||||
throw new GHException("Malformed URL", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public PagedIterator<GHArtifact> _iterator(int pageSize) {
|
||||
return new PagedIterator<>(
|
||||
adapt(GitHubPageIterator.create(owner.getRoot().getClient(), GHArtifactsPage.class, request, pageSize)),
|
||||
null);
|
||||
}
|
||||
|
||||
protected Iterator<GHArtifact[]> adapt(final Iterator<GHArtifactsPage> base) {
|
||||
return new Iterator<GHArtifact[]>() {
|
||||
public boolean hasNext() {
|
||||
return base.hasNext();
|
||||
}
|
||||
|
||||
public GHArtifact[] next() {
|
||||
GHArtifactsPage v = base.next();
|
||||
if (result == null) {
|
||||
result = v;
|
||||
}
|
||||
return v.getArtifacts(owner);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
20
src/main/java/org/kohsuke/github/GHArtifactsPage.java
Normal file
20
src/main/java/org/kohsuke/github/GHArtifactsPage.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* Represents the one page of artifacts result when listing artifacts.
|
||||
*/
|
||||
class GHArtifactsPage {
|
||||
private int total_count;
|
||||
private GHArtifact[] artifacts;
|
||||
|
||||
public int getTotalCount() {
|
||||
return total_count;
|
||||
}
|
||||
|
||||
GHArtifact[] getArtifacts(GHRepository owner) {
|
||||
for (GHArtifact artifact : artifacts) {
|
||||
artifact.wrapUp(owner);
|
||||
}
|
||||
return artifacts;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import org.kohsuke.github.GHWorkflowRun.Conclusion;
|
||||
import org.kohsuke.github.GHWorkflowRun.Status;
|
||||
import org.kohsuke.github.internal.EnumUtils;
|
||||
import org.kohsuke.github.internal.Previews;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -11,6 +15,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Represents a check run.
|
||||
@@ -80,12 +85,27 @@ public class GHCheckRun extends GHObject {
|
||||
* @return Status of the check run
|
||||
* @see Status
|
||||
*/
|
||||
public String getStatus() {
|
||||
@WithBridgeMethods(value = String.class, adapterMethod = "statusAsStr")
|
||||
public Status getStatus() {
|
||||
return Status.from(status);
|
||||
}
|
||||
|
||||
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getStatus")
|
||||
private Object statusAsStr(Status status, Class type) {
|
||||
return status;
|
||||
}
|
||||
|
||||
public static enum Status {
|
||||
QUEUED, IN_PROGRESS, COMPLETED
|
||||
QUEUED, IN_PROGRESS, COMPLETED, UNKNOWN;
|
||||
|
||||
public static Status from(String value) {
|
||||
return EnumUtils.getNullableEnumOrDefault(Status.class, value, Status.UNKNOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,7 +114,13 @@ public class GHCheckRun extends GHObject {
|
||||
* @return Status of the check run
|
||||
* @see Conclusion
|
||||
*/
|
||||
public String getConclusion() {
|
||||
@WithBridgeMethods(value = String.class, adapterMethod = "conclusionAsStr")
|
||||
public Conclusion getConclusion() {
|
||||
return Conclusion.from(conclusion);
|
||||
}
|
||||
|
||||
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getConclusion")
|
||||
private Object conclusionAsStr(Conclusion conclusion, Class type) {
|
||||
return conclusion;
|
||||
}
|
||||
|
||||
@@ -105,7 +131,16 @@ public class GHCheckRun extends GHObject {
|
||||
* Parameters - <code>conclusion</code></a>.
|
||||
*/
|
||||
public static enum Conclusion {
|
||||
SUCCESS, FAILURE, NEUTRAL, CANCELLED, TIMED_OUT, ACTION_REQUIRED, SKIPPED
|
||||
ACTION_REQUIRED, CANCELLED, FAILURE, NEUTRAL, SUCCESS, SKIPPED, STALE, TIMED_OUT, UNKNOWN;
|
||||
|
||||
public static Conclusion from(String value) {
|
||||
return EnumUtils.getNullableEnumOrDefault(Conclusion.class, value, Conclusion.UNKNOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -152,7 +152,7 @@ public final class GHCheckRunBuilder {
|
||||
}
|
||||
GHCheckRun run = requester.with("output", output).with("actions", actions).fetch(GHCheckRun.class).wrap(repo);
|
||||
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);
|
||||
output2.annotations = extraAnnotations.subList(0, i);
|
||||
extraAnnotations = extraAnnotations.subList(i, extraAnnotations.size());
|
||||
|
||||
@@ -5,7 +5,9 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Base type for types used in databinding of the event payload.
|
||||
@@ -380,9 +382,9 @@ public class GHEventPayload extends GitHubInteractiveObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets label.
|
||||
* Gets the added or removed label for labeled/unlabeled events.
|
||||
*
|
||||
* @return the label
|
||||
* @return label the added or removed label
|
||||
*/
|
||||
public GHLabel getLabel() {
|
||||
return label;
|
||||
@@ -519,6 +521,10 @@ public class GHEventPayload extends GitHubInteractiveObject {
|
||||
public static class Issue extends GHEventPayload {
|
||||
private GHIssue issue;
|
||||
|
||||
private GHLabel label;
|
||||
|
||||
private GHIssueChanges changes;
|
||||
|
||||
/**
|
||||
* Gets issue.
|
||||
*
|
||||
@@ -538,6 +544,24 @@ public class GHEventPayload extends GitHubInteractiveObject {
|
||||
this.issue = issue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the added or removed label for labeled/unlabeled events.
|
||||
*
|
||||
* @return label the added or removed label
|
||||
*/
|
||||
public GHLabel getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get changes (for action="edited")
|
||||
*
|
||||
* @return changes
|
||||
*/
|
||||
public GHIssueChanges getChanges() {
|
||||
return changes;
|
||||
}
|
||||
|
||||
@Override
|
||||
void wrapUp(GitHub root) {
|
||||
super.wrapUp(root);
|
||||
@@ -1067,7 +1091,7 @@ public class GHEventPayload extends GitHubInteractiveObject {
|
||||
public static class PushCommit {
|
||||
private GitUser author;
|
||||
private GitUser committer;
|
||||
private String url, sha, message;
|
||||
private String url, sha, message, timestamp;
|
||||
private boolean distinct;
|
||||
private List<String> added, removed, modified;
|
||||
|
||||
@@ -1156,6 +1180,15 @@ public class GHEventPayload extends GitHubInteractiveObject {
|
||||
public List<String> getModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the timestamp of the commit
|
||||
*
|
||||
* @return the timestamp
|
||||
*/
|
||||
public Date getTimestamp() {
|
||||
return GitHubClient.parseDate(timestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1294,4 +1327,84 @@ public class GHEventPayload extends GitHubInteractiveObject {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Occurs when someone triggered a workflow run or sends a POST request to the "Create a workflow dispatch event"
|
||||
* endpoint.
|
||||
*
|
||||
* @see <a href=
|
||||
* "https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads#workflow_dispatch">
|
||||
* workflow dispatch event</a>
|
||||
* @see <a href=
|
||||
* "https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch">Events that
|
||||
* trigger workflows</a>
|
||||
*/
|
||||
public static class WorkflowDispatch extends GHEventPayload {
|
||||
private Map<String, Object> inputs;
|
||||
private String ref;
|
||||
private String workflow;
|
||||
|
||||
/**
|
||||
* Gets the map of input parameters passed to the workflow.
|
||||
*
|
||||
* @return the map of input parameters
|
||||
*/
|
||||
public Map<String, Object> getInputs() {
|
||||
return inputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ref of the branch (e.g. refs/heads/main)
|
||||
*
|
||||
* @return the ref of the branch
|
||||
*/
|
||||
public String getRef() {
|
||||
return ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path of the workflow file (e.g. .github/workflows/hello-world-workflow.yml).
|
||||
*
|
||||
* @return the path of the workflow file
|
||||
*/
|
||||
public String getWorkflow() {
|
||||
return workflow;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A workflow run was requested or completed.
|
||||
*
|
||||
* @see <a href=
|
||||
* "https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads#workflow_run">
|
||||
* workflow run event</a>
|
||||
* @see <a href="https://docs.github.com/en/rest/reference/actions#workflow-runs">Actions Workflow Runs</a>
|
||||
*/
|
||||
public static class WorkflowRun extends GHEventPayload {
|
||||
private GHWorkflowRun workflowRun;
|
||||
private GHWorkflow workflow;
|
||||
|
||||
public GHWorkflowRun getWorkflowRun() {
|
||||
return workflowRun;
|
||||
}
|
||||
|
||||
public GHWorkflow getWorkflow() {
|
||||
return workflow;
|
||||
}
|
||||
|
||||
@Override
|
||||
void wrapUp(GitHub root) {
|
||||
super.wrapUp(root);
|
||||
if (workflowRun == null || workflow == null) {
|
||||
throw new IllegalStateException(
|
||||
"Expected workflow and workflow_run payload, but got something else. Maybe we've got another type of event?");
|
||||
}
|
||||
GHRepository repository = getRepository();
|
||||
if (repository == null) {
|
||||
throw new IllegalStateException("Repository must not be null");
|
||||
}
|
||||
workflowRun.wrapUp(repository);
|
||||
workflow.wrapUp(repository);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ public class GHIssue extends GHObject implements Reactable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets labels.
|
||||
* Sets labels on the target to a specific list.
|
||||
*
|
||||
* @param labels
|
||||
* the labels
|
||||
@@ -326,6 +326,8 @@ public class GHIssue extends GHObject implements Reactable {
|
||||
/**
|
||||
* Adds labels to the issue.
|
||||
*
|
||||
* Labels that are already present on the target are ignored.
|
||||
*
|
||||
* @param names
|
||||
* Names of the label
|
||||
* @throws IOException
|
||||
@@ -338,6 +340,8 @@ public class GHIssue extends GHObject implements Reactable {
|
||||
/**
|
||||
* Add labels.
|
||||
*
|
||||
* Labels that are already present on the target are ignored.
|
||||
*
|
||||
* @param labels
|
||||
* the labels
|
||||
* @throws IOException
|
||||
@@ -350,6 +354,8 @@ public class GHIssue extends GHObject implements Reactable {
|
||||
/**
|
||||
* Add labels.
|
||||
*
|
||||
* Labels that are already present on the target are ignored.
|
||||
*
|
||||
* @param labels
|
||||
* the labels
|
||||
* @throws IOException
|
||||
@@ -360,21 +366,27 @@ public class GHIssue extends GHObject implements Reactable {
|
||||
}
|
||||
|
||||
private void _addLabels(Collection<String> names) throws IOException {
|
||||
List<String> newLabels = new ArrayList<String>();
|
||||
|
||||
for (GHLabel label : getLabels()) {
|
||||
newLabels.add(label.getName());
|
||||
}
|
||||
for (String name : names) {
|
||||
if (!newLabels.contains(name)) {
|
||||
newLabels.add(name);
|
||||
}
|
||||
}
|
||||
setLabels(newLabels.toArray(new String[0]));
|
||||
root.createRequest().with("labels", names).method("POST").withUrlPath(getIssuesApiRoute() + "/labels").send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a given label by name from this issue.
|
||||
* Remove a single label.
|
||||
*
|
||||
* Attempting to remove a label that is not present throws {@link GHFileNotFoundException}.
|
||||
*
|
||||
* @param name
|
||||
* the name
|
||||
* @throws IOException
|
||||
* the io exception, throws {@link GHFileNotFoundException} if label was not present.
|
||||
*/
|
||||
public void removeLabel(String name) throws IOException {
|
||||
root.createRequest().method("DELETE").withUrlPath(getIssuesApiRoute() + "/labels", name).send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a collection of labels.
|
||||
*
|
||||
* Attempting to remove labels that are not present on the target are ignored.
|
||||
*
|
||||
* @param names
|
||||
* the names
|
||||
@@ -386,7 +398,9 @@ public class GHIssue extends GHObject implements Reactable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove labels.
|
||||
* Remove a collection of labels.
|
||||
*
|
||||
* Attempting to remove labels that are not present on the target are ignored.
|
||||
*
|
||||
* @param labels
|
||||
* the labels
|
||||
@@ -399,7 +413,9 @@ public class GHIssue extends GHObject implements Reactable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove labels.
|
||||
* Remove a collection of labels.
|
||||
*
|
||||
* Attempting to remove labels that are not present on the target are ignored.
|
||||
*
|
||||
* @param labels
|
||||
* the labels
|
||||
@@ -411,15 +427,13 @@ public class GHIssue extends GHObject implements Reactable {
|
||||
}
|
||||
|
||||
private void _removeLabels(Collection<String> names) throws IOException {
|
||||
List<String> newLabels = new ArrayList<String>();
|
||||
|
||||
for (GHLabel l : getLabels()) {
|
||||
if (!names.contains(l.getName())) {
|
||||
newLabels.add(l.getName());
|
||||
for (String name : names) {
|
||||
try {
|
||||
removeLabel(name);
|
||||
} catch (GHFileNotFoundException e) {
|
||||
// when trying to remove multiple labels, we ignore already removed
|
||||
}
|
||||
}
|
||||
|
||||
setLabels(newLabels.toArray(new String[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
49
src/main/java/org/kohsuke/github/GHIssueChanges.java
Normal file
49
src/main/java/org/kohsuke/github/GHIssueChanges.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
/**
|
||||
* Wrapper to define changed fields on issues action="edited"
|
||||
*
|
||||
* @see GHEventPayload.Issue
|
||||
*/
|
||||
@SuppressFBWarnings("UWF_UNWRITTEN_FIELD")
|
||||
public class GHIssueChanges {
|
||||
|
||||
private GHFrom title;
|
||||
private GHFrom body;
|
||||
|
||||
/**
|
||||
* Old issue title.
|
||||
*
|
||||
* @return old issue title (or null if not changed)
|
||||
*/
|
||||
public GHFrom getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Old issue body.
|
||||
*
|
||||
* @return old issue body (or null if not changed)
|
||||
*/
|
||||
public GHFrom getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for changed values.
|
||||
*/
|
||||
public static class GHFrom {
|
||||
private String from;
|
||||
|
||||
/**
|
||||
* Previous value that was changed.
|
||||
*
|
||||
* @return previous value
|
||||
*/
|
||||
public String getFrom() {
|
||||
return from;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package org.kohsuke.github;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonInject;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -22,6 +23,11 @@ import javax.annotation.Nonnull;
|
||||
*/
|
||||
public class GHLabel extends GitHubInteractiveObject {
|
||||
|
||||
private long id;
|
||||
private String nodeId;
|
||||
@JsonProperty("default")
|
||||
private boolean default_;
|
||||
|
||||
@Nonnull
|
||||
private String url, name, color;
|
||||
|
||||
@@ -42,6 +48,24 @@ public class GHLabel extends GitHubInteractiveObject {
|
||||
return Objects.requireNonNull(root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets node id.
|
||||
*
|
||||
* @return the node id.
|
||||
*/
|
||||
public String getNodeId() {
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets url.
|
||||
*
|
||||
@@ -82,6 +106,15 @@ public class GHLabel extends GitHubInteractiveObject {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the label is one of the default labels created by GitHub automatically.
|
||||
*
|
||||
* @return true if the label is a default one
|
||||
*/
|
||||
public boolean isDefault() {
|
||||
return default_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets color.
|
||||
*
|
||||
|
||||
@@ -153,7 +153,20 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
|
||||
* @return the api route
|
||||
*/
|
||||
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,8 +205,7 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
|
||||
return owner.root.createRequest()
|
||||
.method("POST")
|
||||
.with("body", body)
|
||||
.with("in_reply_to", getId())
|
||||
.withUrlPath(getApiRoute() + "/comments")
|
||||
.withUrlPath(getApiRoute(true) + "/replies")
|
||||
.fetch(GHPullRequestReviewComment.class)
|
||||
.wrapUp(owner);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ import edu.umd.cs.findbugs.annotations.CheckForNull;
|
||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.kohsuke.github.function.InputStreamFunction;
|
||||
import org.kohsuke.github.internal.EnumUtils;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
@@ -48,21 +50,23 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import static java.util.Arrays.*;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.kohsuke.github.internal.Previews.ANTIOPE;
|
||||
import static org.kohsuke.github.internal.Previews.ANT_MAN;
|
||||
import static org.kohsuke.github.internal.Previews.BAPTISTE;
|
||||
import static org.kohsuke.github.internal.Previews.FLASH;
|
||||
import static org.kohsuke.github.internal.Previews.INERTIA;
|
||||
import static org.kohsuke.github.internal.Previews.MERCY;
|
||||
import static org.kohsuke.github.internal.Previews.NEBULA;
|
||||
import static org.kohsuke.github.internal.Previews.SHADOW_CAT;
|
||||
|
||||
/**
|
||||
@@ -103,6 +107,8 @@ public class GHRepository extends GHObject {
|
||||
@JsonProperty("private")
|
||||
private boolean _private;
|
||||
|
||||
private String visibility;
|
||||
|
||||
private int forks_count, stargazers_count, watchers_count, size, open_issues_count, subscribers_count;
|
||||
|
||||
private String pushed_at;
|
||||
@@ -709,6 +715,41 @@ public class GHRepository extends GHObject {
|
||||
return _private;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visibility of a repository.
|
||||
*/
|
||||
public enum Visibility {
|
||||
PUBLIC, INTERNAL, PRIVATE, UNKNOWN;
|
||||
|
||||
public static Visibility from(String value) {
|
||||
return EnumUtils.getNullableEnumOrDefault(Visibility.class, value, Visibility.UNKNOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the visibility of the repository.
|
||||
*
|
||||
* @return the visibility
|
||||
*/
|
||||
@Deprecated
|
||||
@Preview(NEBULA)
|
||||
public Visibility getVisibility() {
|
||||
if (visibility == null) {
|
||||
try {
|
||||
populate();
|
||||
} catch (final IOException e) {
|
||||
// Convert this to a runtime exception to avoid messy method signature
|
||||
throw new GHException("Could not populate the visibility of the repository", e);
|
||||
}
|
||||
}
|
||||
return Visibility.from(visibility);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is template boolean.
|
||||
*
|
||||
@@ -1201,6 +1242,26 @@ public class GHRepository extends GHObject {
|
||||
set().private_(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets visibility.
|
||||
*
|
||||
* @param value
|
||||
* the value
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
@Deprecated
|
||||
@Preview(NEBULA)
|
||||
public void setVisibility(final Visibility value) throws IOException {
|
||||
root.createRequest()
|
||||
.method("PATCH")
|
||||
.withPreview(NEBULA)
|
||||
.with("name", name)
|
||||
.with("visibility", value)
|
||||
.withUrlPath(getApiTailUrl(""))
|
||||
.send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow squash merge.
|
||||
*
|
||||
@@ -1788,7 +1849,7 @@ public class GHRepository extends GHObject {
|
||||
return root.createRequest()
|
||||
.withHeader("Accept", "application/vnd.github.v3.raw")
|
||||
.withUrlPath(target)
|
||||
.fetchStream();
|
||||
.fetchStream(Requester::copyInputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2815,7 +2876,7 @@ public class GHRepository extends GHObject {
|
||||
.with("mode", mode == null ? null : mode.toString())
|
||||
.with("context", getFullName())
|
||||
.withUrlPath("/markdown")
|
||||
.fetchStream(),
|
||||
.fetchStream(Requester::copyInputStream),
|
||||
"UTF-8");
|
||||
}
|
||||
|
||||
@@ -2903,6 +2964,110 @@ public class GHRepository extends GHObject {
|
||||
.wrapUp(root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all the workflows of this repository.
|
||||
*
|
||||
* @return the paged iterable
|
||||
*/
|
||||
public PagedIterable<GHWorkflow> listWorkflows() {
|
||||
return new GHWorkflowsIterable(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a workflow by id.
|
||||
*
|
||||
* @param id
|
||||
* the id of the workflow run
|
||||
* @return the workflow run
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public GHWorkflow getWorkflow(long id) throws IOException {
|
||||
return getWorkflow(String.valueOf(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a workflow by name of the file.
|
||||
*
|
||||
* @param nameOrId
|
||||
* either the name of the file (e.g. my-workflow.yml) or the id as a string
|
||||
* @return the workflow run
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public GHWorkflow getWorkflow(String nameOrId) throws IOException {
|
||||
return root.createRequest()
|
||||
.withUrlPath(getApiTailUrl("actions/workflows"), nameOrId)
|
||||
.fetch(GHWorkflow.class)
|
||||
.wrapUp(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves workflow runs.
|
||||
*
|
||||
* @return the workflow run query builder
|
||||
*/
|
||||
public GHWorkflowRunQueryBuilder queryWorkflowRuns() {
|
||||
return new GHWorkflowRunQueryBuilder(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a workflow run.
|
||||
*
|
||||
* @param id
|
||||
* the id of the workflow run
|
||||
* @return the workflow run
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public GHWorkflowRun getWorkflowRun(long id) throws IOException {
|
||||
return root.createRequest()
|
||||
.withUrlPath(getApiTailUrl("actions/runs"), String.valueOf(id))
|
||||
.fetch(GHWorkflowRun.class)
|
||||
.wrapUp(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all the artifacts of this repository.
|
||||
*
|
||||
* @return the paged iterable
|
||||
*/
|
||||
public PagedIterable<GHArtifact> listArtifacts() {
|
||||
return new GHArtifactsIterable(this, root.createRequest().withUrlPath(getApiTailUrl("actions/artifacts")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an artifact by id.
|
||||
*
|
||||
* @param id
|
||||
* the id of the artifact
|
||||
* @return the artifact
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public GHArtifact getArtifact(long id) throws IOException {
|
||||
return root.createRequest()
|
||||
.withUrlPath(getApiTailUrl("actions/artifacts"), String.valueOf(id))
|
||||
.fetch(GHArtifact.class)
|
||||
.wrapUp(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a job from a workflow run by id.
|
||||
*
|
||||
* @param id
|
||||
* the id of the job
|
||||
* @return the job
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public GHWorkflowJob getWorkflowJob(long id) throws IOException {
|
||||
return root.createRequest()
|
||||
.withUrlPath(getApiTailUrl("/actions/jobs/"), String.valueOf(id))
|
||||
.fetch(GHWorkflowJob.class)
|
||||
.wrapUp(this);
|
||||
}
|
||||
|
||||
// Only used within listTopics().
|
||||
private static class Topics {
|
||||
public List<String> names;
|
||||
@@ -2969,6 +3134,52 @@ public class GHRepository extends GHObject {
|
||||
.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.
|
||||
*
|
||||
@@ -2980,18 +3191,24 @@ public class GHRepository extends GHObject {
|
||||
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 {
|
||||
// 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.
|
||||
// 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}".
|
||||
root.createRequest().withPreview(BAPTISTE).setRawUrlPath(url.toString()).fetchInto(this).wrap(root);
|
||||
root.createRequest()
|
||||
.withPreview(BAPTISTE)
|
||||
.withPreview(NEBULA)
|
||||
.setRawUrlPath(url.toString())
|
||||
.fetchInto(this)
|
||||
.wrap(root);
|
||||
} catch (HttpException e) {
|
||||
if (e.getCause() instanceof JsonParseException) {
|
||||
root.createRequest()
|
||||
.withPreview(BAPTISTE)
|
||||
.withPreview(NEBULA)
|
||||
.withUrlPath("/repos/" + full_name)
|
||||
.fetchInto(this)
|
||||
.wrap(root);
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import org.kohsuke.github.GHRepository.Visibility;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import static org.kohsuke.github.internal.Previews.BAPTISTE;
|
||||
import static org.kohsuke.github.internal.Previews.NEBULA;
|
||||
|
||||
abstract class GHRepositoryBuilder<S> extends AbstractBuilder<GHRepository, S> {
|
||||
|
||||
@@ -146,6 +149,20 @@ abstract class GHRepositoryBuilder<S> extends AbstractBuilder<GHRepository, S> {
|
||||
return with("private", enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the repository visibility
|
||||
*
|
||||
* @param visibility
|
||||
* visibility of repository
|
||||
* @return a builder to continue with building
|
||||
* @throws IOException
|
||||
* In case of any networking error or error from the server.
|
||||
*/
|
||||
public S visibility(final Visibility visibility) throws IOException {
|
||||
requester.withPreview(NEBULA);
|
||||
return with("visibility", visibility);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables issue tracker
|
||||
*
|
||||
|
||||
158
src/main/java/org/kohsuke/github/GHWorkflow.java
Normal file
158
src/main/java/org/kohsuke/github/GHWorkflow.java
Normal file
@@ -0,0 +1,158 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A workflow.
|
||||
*
|
||||
* @author Guillaume Smet
|
||||
* @see GHRepository#getWorkflow(long)
|
||||
*/
|
||||
public class GHWorkflow extends GHObject {
|
||||
|
||||
// Not provided by the API.
|
||||
@JsonIgnore
|
||||
private GHRepository owner;
|
||||
|
||||
private String name;
|
||||
private String path;
|
||||
private String state;
|
||||
|
||||
private String htmlUrl;
|
||||
private String badgeUrl;
|
||||
|
||||
/**
|
||||
* The name of the workflow.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The path of the workflow e.g. .github/workflows/blank.yaml
|
||||
*
|
||||
* @return the path
|
||||
*/
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* The state of the workflow.
|
||||
*
|
||||
* @return the state
|
||||
*/
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getHtmlUrl() throws IOException {
|
||||
return GitHubClient.parseURL(htmlUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Repository to which the workflow belongs.
|
||||
*
|
||||
* @return the repository
|
||||
*/
|
||||
public GHRepository getRepository() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* The badge URL, like https://github.com/octo-org/octo-repo/workflows/CI/badge.svg
|
||||
*
|
||||
* @return the badge url
|
||||
*/
|
||||
public URL getBadgeUrl() {
|
||||
return GitHubClient.parseURL(badgeUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the workflow.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void disable() throws IOException {
|
||||
root.createRequest().method("PUT").withUrlPath(getApiRoute(), "disable").fetchHttpStatusCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the workflow.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void enable() throws IOException {
|
||||
root.createRequest().method("PUT").withUrlPath(getApiRoute(), "enable").fetchHttpStatusCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a workflow dispatch event which triggers a manual workflow run.
|
||||
*
|
||||
* @param ref
|
||||
* the git reference for the workflow. The reference can be a branch or tag name.
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void dispatch(String ref) throws IOException {
|
||||
dispatch(ref, Collections.emptyMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a workflow dispatch event which triggers a manual workflow run.
|
||||
*
|
||||
* @param ref
|
||||
* the git reference for the workflow. The reference can be a branch or tag name.
|
||||
* @param inputs
|
||||
* input keys and values configured in the workflow file. The maximum number of properties is 10. Any
|
||||
* default properties configured in the workflow file will be used when inputs are omitted.
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void dispatch(String ref, Map<String, Object> inputs) throws IOException {
|
||||
Requester requester = root.createRequest()
|
||||
.method("POST")
|
||||
.withUrlPath(getApiRoute(), "dispatches")
|
||||
.with("ref", ref);
|
||||
|
||||
if (!inputs.isEmpty()) {
|
||||
requester.with("inputs", inputs);
|
||||
}
|
||||
|
||||
requester.fetchHttpStatusCode();
|
||||
}
|
||||
|
||||
private String getApiRoute() {
|
||||
if (owner == null) {
|
||||
// Workflow runs returned from search to do not have an owner. Attempt to use url.
|
||||
final URL url = Objects.requireNonNull(getUrl(), "Missing instance URL!");
|
||||
return StringUtils.prependIfMissing(url.toString().replace(root.getApiUrl(), ""), "/");
|
||||
|
||||
}
|
||||
return "/repos/" + owner.getOwnerName() + "/" + owner.getName() + "/actions/workflows/" + getId();
|
||||
}
|
||||
|
||||
GHWorkflow wrapUp(GHRepository owner) {
|
||||
this.owner = owner;
|
||||
return wrapUp(owner.root);
|
||||
}
|
||||
|
||||
GHWorkflow wrapUp(GitHub root) {
|
||||
this.root = root;
|
||||
if (owner != null)
|
||||
owner.wrap(root);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
256
src/main/java/org/kohsuke/github/GHWorkflowJob.java
Normal file
256
src/main/java/org/kohsuke/github/GHWorkflowJob.java
Normal file
@@ -0,0 +1,256 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.kohsuke.github.GHWorkflowRun.Conclusion;
|
||||
import org.kohsuke.github.GHWorkflowRun.Status;
|
||||
import org.kohsuke.github.function.InputStreamFunction;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* A workflow run job.
|
||||
*
|
||||
* @author Guillaume Smet
|
||||
*/
|
||||
public class GHWorkflowJob extends GHObject {
|
||||
|
||||
// Not provided by the API.
|
||||
@JsonIgnore
|
||||
private GHRepository owner;
|
||||
|
||||
private String name;
|
||||
|
||||
private String headSha;
|
||||
|
||||
private String startedAt;
|
||||
private String completedAt;
|
||||
|
||||
private String status;
|
||||
private String conclusion;
|
||||
|
||||
private long runId;
|
||||
|
||||
private String htmlUrl;
|
||||
private String checkRunUrl;
|
||||
|
||||
private List<Step> steps = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The name of the job.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HEAD SHA.
|
||||
*
|
||||
* @return sha for the HEAD commit
|
||||
*/
|
||||
public String getHeadSha() {
|
||||
return headSha;
|
||||
}
|
||||
|
||||
/**
|
||||
* When was this job started?
|
||||
*
|
||||
* @return start date
|
||||
*/
|
||||
public Date getStartedAt() {
|
||||
return GitHubClient.parseDate(startedAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* When was this job completed?
|
||||
*
|
||||
* @return completion date
|
||||
*/
|
||||
public Date getCompletedAt() {
|
||||
return GitHubClient.parseDate(completedAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets status of the job.
|
||||
* <p>
|
||||
* Can be {@code UNKNOWN} if the value returned by GitHub is unknown from the API.
|
||||
*
|
||||
* @return status of the job
|
||||
*/
|
||||
public Status getStatus() {
|
||||
return Status.from(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the conclusion of the job.
|
||||
* <p>
|
||||
* Can be {@code UNKNOWN} if the value returned by GitHub is unknown from the API.
|
||||
*
|
||||
* @return conclusion of the job
|
||||
*/
|
||||
public Conclusion getConclusion() {
|
||||
return Conclusion.from(conclusion);
|
||||
}
|
||||
|
||||
/**
|
||||
* The run id.
|
||||
*
|
||||
* @return the run id
|
||||
*/
|
||||
public long getRunId() {
|
||||
return runId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getHtmlUrl() {
|
||||
return GitHubClient.parseURL(htmlUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* The check run URL.
|
||||
*
|
||||
* @return the check run url
|
||||
*/
|
||||
public URL getCheckRunUrl() {
|
||||
return GitHubClient.parseURL(checkRunUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the execution steps of this job.
|
||||
*
|
||||
* @return the execution steps
|
||||
*/
|
||||
public List<Step> getSteps() {
|
||||
return steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Repository to which the job belongs.
|
||||
*
|
||||
* @return the repository
|
||||
*/
|
||||
public GHRepository getRepository() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads the logs.
|
||||
* <p>
|
||||
* The logs are returned as a text file.
|
||||
*
|
||||
* @param <T>
|
||||
* the type of result
|
||||
* @param streamFunction
|
||||
* The {@link InputStreamFunction} that will process the stream
|
||||
* @throws IOException
|
||||
* The IO exception.
|
||||
* @return the result of reading the stream.
|
||||
*/
|
||||
public <T> T downloadLogs(InputStreamFunction<T> streamFunction) throws IOException {
|
||||
requireNonNull(streamFunction, "Stream function must not be null");
|
||||
|
||||
return root.createRequest().method("GET").withUrlPath(getApiRoute(), "logs").fetchStream(streamFunction);
|
||||
}
|
||||
|
||||
private String getApiRoute() {
|
||||
if (owner == null) {
|
||||
// Workflow runs returned from search to do not have an owner. Attempt to use url.
|
||||
final URL url = Objects.requireNonNull(getUrl(), "Missing instance URL!");
|
||||
return StringUtils.prependIfMissing(url.toString().replace(root.getApiUrl(), ""), "/");
|
||||
|
||||
}
|
||||
return "/repos/" + owner.getOwnerName() + "/" + owner.getName() + "/actions/jobs/" + getId();
|
||||
}
|
||||
|
||||
GHWorkflowJob wrapUp(GHRepository owner) {
|
||||
this.owner = owner;
|
||||
return wrapUp(owner.root);
|
||||
}
|
||||
|
||||
GHWorkflowJob wrapUp(GitHub root) {
|
||||
this.root = root;
|
||||
if (owner != null) {
|
||||
owner.wrap(root);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public static class Step {
|
||||
|
||||
private String name;
|
||||
private int number;
|
||||
|
||||
private String startedAt;
|
||||
private String completedAt;
|
||||
|
||||
private String status;
|
||||
private String conclusion;
|
||||
|
||||
/**
|
||||
* Gets the name of the step.
|
||||
*
|
||||
* @return name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sequential number of the step.
|
||||
*
|
||||
* @return number
|
||||
*/
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* When was this step started?
|
||||
*
|
||||
* @return start date
|
||||
*/
|
||||
public Date getStartedAt() {
|
||||
return GitHubClient.parseDate(startedAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* When was this step completed?
|
||||
*
|
||||
* @return completion date
|
||||
*/
|
||||
public Date getCompletedAt() {
|
||||
return GitHubClient.parseDate(completedAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets status of the step.
|
||||
* <p>
|
||||
* Can be {@code UNKNOWN} if the value returned by GitHub is unknown from the API.
|
||||
*
|
||||
* @return status of the step
|
||||
*/
|
||||
public Status getStatus() {
|
||||
return Status.from(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the conclusion of the step.
|
||||
* <p>
|
||||
* Can be {@code UNKNOWN} if the value returned by GitHub is unknown from the API.
|
||||
*
|
||||
* @return conclusion of the step
|
||||
*/
|
||||
public Conclusion getConclusion() {
|
||||
return Conclusion.from(conclusion);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
/**
|
||||
* Lists up jobs of a workflow run with some filtering.
|
||||
*
|
||||
* @author Guillaume Smet
|
||||
*/
|
||||
public class GHWorkflowJobQueryBuilder extends GHQueryBuilder<GHWorkflowJob> {
|
||||
private final GHRepository repo;
|
||||
|
||||
GHWorkflowJobQueryBuilder(GHWorkflowRun workflowRun) {
|
||||
super(workflowRun.getRepository().root);
|
||||
this.repo = workflowRun.getRepository();
|
||||
req.withUrlPath(repo.getApiTailUrl("actions/runs"), String.valueOf(workflowRun.getId()), "jobs");
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a filter to only return the jobs of the most recent execution of the workflow run.
|
||||
*
|
||||
* @return the workflow run job query builder
|
||||
*/
|
||||
public GHWorkflowJobQueryBuilder latest() {
|
||||
req.with("filter", "latest");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a filter to return jobs from all executions of this workflow run.
|
||||
*
|
||||
* @return the workflow run job run query builder
|
||||
*/
|
||||
public GHWorkflowJobQueryBuilder all() {
|
||||
req.with("filter", "all");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PagedIterable<GHWorkflowJob> list() {
|
||||
try {
|
||||
return new GHWorkflowJobsIterable(repo, req.build());
|
||||
} catch (MalformedURLException e) {
|
||||
throw new GHException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
44
src/main/java/org/kohsuke/github/GHWorkflowJobsIterable.java
Normal file
44
src/main/java/org/kohsuke/github/GHWorkflowJobsIterable.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Iterable for workflow run jobs listing.
|
||||
*/
|
||||
class GHWorkflowJobsIterable extends PagedIterable<GHWorkflowJob> {
|
||||
private final GHRepository repo;
|
||||
private final GitHubRequest request;
|
||||
|
||||
private GHWorkflowJobsPage result;
|
||||
|
||||
public GHWorkflowJobsIterable(GHRepository repo, GitHubRequest request) {
|
||||
this.repo = repo;
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public PagedIterator<GHWorkflowJob> _iterator(int pageSize) {
|
||||
return new PagedIterator<>(
|
||||
adapt(GitHubPageIterator.create(repo.root.getClient(), GHWorkflowJobsPage.class, request, pageSize)),
|
||||
null);
|
||||
}
|
||||
|
||||
protected Iterator<GHWorkflowJob[]> adapt(final Iterator<GHWorkflowJobsPage> base) {
|
||||
return new Iterator<GHWorkflowJob[]>() {
|
||||
public boolean hasNext() {
|
||||
return base.hasNext();
|
||||
}
|
||||
|
||||
public GHWorkflowJob[] next() {
|
||||
GHWorkflowJobsPage v = base.next();
|
||||
if (result == null) {
|
||||
result = v;
|
||||
}
|
||||
return v.getWorkflowJobs(repo);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
20
src/main/java/org/kohsuke/github/GHWorkflowJobsPage.java
Normal file
20
src/main/java/org/kohsuke/github/GHWorkflowJobsPage.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* Represents the one page of jobs result when listing jobs from a workflow run.
|
||||
*/
|
||||
class GHWorkflowJobsPage {
|
||||
private int total_count;
|
||||
private GHWorkflowJob[] jobs;
|
||||
|
||||
public int getTotalCount() {
|
||||
return total_count;
|
||||
}
|
||||
|
||||
GHWorkflowJob[] getWorkflowJobs(GHRepository repo) {
|
||||
for (GHWorkflowJob job : jobs) {
|
||||
job.wrapUp(repo);
|
||||
}
|
||||
return jobs;
|
||||
}
|
||||
}
|
||||
457
src/main/java/org/kohsuke/github/GHWorkflowRun.java
Normal file
457
src/main/java/org/kohsuke/github/GHWorkflowRun.java
Normal file
@@ -0,0 +1,457 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.kohsuke.github.function.InputStreamFunction;
|
||||
import org.kohsuke.github.internal.EnumUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* A workflow run.
|
||||
*
|
||||
* @author Guillaume Smet
|
||||
* @see GHRepository#getWorkflowRun(long)
|
||||
*/
|
||||
public class GHWorkflowRun extends GHObject {
|
||||
|
||||
@JsonProperty("repository")
|
||||
private GHRepository owner;
|
||||
|
||||
private String name;
|
||||
private long runNumber;
|
||||
private long workflowId;
|
||||
|
||||
private String htmlUrl;
|
||||
private String jobsUrl;
|
||||
private String logsUrl;
|
||||
private String checkSuiteUrl;
|
||||
private String artifactsUrl;
|
||||
private String cancelUrl;
|
||||
private String rerunUrl;
|
||||
private String workflowUrl;
|
||||
|
||||
private String headBranch;
|
||||
private String headSha;
|
||||
private GHRepository headRepository;
|
||||
private HeadCommit headCommit;
|
||||
|
||||
private String event;
|
||||
private String status;
|
||||
private String conclusion;
|
||||
|
||||
private GHPullRequest[] pullRequests;
|
||||
|
||||
/**
|
||||
* The name of the workflow run.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The run number.
|
||||
*
|
||||
* @return the run number
|
||||
*/
|
||||
public long getRunNumber() {
|
||||
return runNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* The workflow id.
|
||||
*
|
||||
* @return the workflow id
|
||||
*/
|
||||
public long getWorkflowId() {
|
||||
return workflowId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getHtmlUrl() throws IOException {
|
||||
return GitHubClient.parseURL(htmlUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* The jobs URL, like https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642/jobs
|
||||
*
|
||||
* @return the jobs url
|
||||
*/
|
||||
public URL getJobsUrl() {
|
||||
return GitHubClient.parseURL(jobsUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* The logs URL, like https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642/logs
|
||||
*
|
||||
* @return the logs url
|
||||
*/
|
||||
public URL getLogsUrl() {
|
||||
return GitHubClient.parseURL(logsUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* The check suite URL, like https://api.github.com/repos/octo-org/octo-repo/check-suites/414944374
|
||||
*
|
||||
* @return the check suite url
|
||||
*/
|
||||
public URL getCheckSuiteUrl() {
|
||||
return GitHubClient.parseURL(checkSuiteUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* The artifacts URL, like https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642/artifacts
|
||||
*
|
||||
* @return the artifacts url
|
||||
*/
|
||||
public URL getArtifactsUrl() {
|
||||
return GitHubClient.parseURL(artifactsUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* The cancel URL, like https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642/cancel
|
||||
*
|
||||
* @return the cancel url
|
||||
*/
|
||||
public URL getCancelUrl() {
|
||||
return GitHubClient.parseURL(cancelUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* The rerun URL, like https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642/rerun
|
||||
*
|
||||
* @return the rerun url
|
||||
*/
|
||||
public URL getRerunUrl() {
|
||||
return GitHubClient.parseURL(rerunUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* The workflow URL, like https://api.github.com/repos/octo-org/octo-repo/actions/workflows/159038
|
||||
*
|
||||
* @return the workflow url
|
||||
*/
|
||||
public URL getWorkflowUrl() {
|
||||
return GitHubClient.parseURL(workflowUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* The head branch name the changes are on.
|
||||
*
|
||||
* @return head branch name
|
||||
*/
|
||||
public String getHeadBranch() {
|
||||
return headBranch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HEAD SHA.
|
||||
*
|
||||
* @return sha for the HEAD commit
|
||||
*/
|
||||
public String getHeadSha() {
|
||||
return headSha;
|
||||
}
|
||||
|
||||
/**
|
||||
* The commit of current head.
|
||||
*
|
||||
* @return head commit
|
||||
*/
|
||||
public HeadCommit getHeadCommit() {
|
||||
return headCommit;
|
||||
}
|
||||
|
||||
/**
|
||||
* The repository of current head.
|
||||
*
|
||||
* @return head repository
|
||||
*/
|
||||
public GHRepository getHeadRepository() {
|
||||
return headRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of event that triggered the build.
|
||||
*
|
||||
* @return type of event
|
||||
*/
|
||||
public GHEvent getEvent() {
|
||||
return Enum.valueOf(GHEvent.class, event.toUpperCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets status of the workflow run.
|
||||
* <p>
|
||||
* Can be {@code UNKNOWN} if the value returned by GitHub is unknown from the API.
|
||||
*
|
||||
* @return status of the workflow run
|
||||
*/
|
||||
public Status getStatus() {
|
||||
return Status.from(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the conclusion of the workflow run.
|
||||
* <p>
|
||||
* Can be {@code UNKNOWN} if the value returned by GitHub is unknown from the API.
|
||||
*
|
||||
* @return conclusion of the workflow run
|
||||
*/
|
||||
public Conclusion getConclusion() {
|
||||
return Conclusion.from(conclusion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Repository to which the workflow run belongs.
|
||||
*
|
||||
* @return the repository
|
||||
*/
|
||||
public GHRepository getRepository() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pull requests participated in this workflow run.
|
||||
*
|
||||
* Note this field is only populated for events. When getting a {@link GHWorkflowRun} outside of an event, this is
|
||||
* always empty.
|
||||
*
|
||||
* @return the list of {@link GHPullRequest}s for this workflow run. Only populated for events.
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public List<GHPullRequest> getPullRequests() throws IOException {
|
||||
if (pullRequests != null && pullRequests.length != 0) {
|
||||
for (GHPullRequest pullRequest : pullRequests) {
|
||||
// Only refresh if we haven't do so before
|
||||
pullRequest.refresh(pullRequest.getTitle());
|
||||
}
|
||||
return Collections.unmodifiableList(Arrays.asList(pullRequests));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the workflow run.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void cancel() throws IOException {
|
||||
root.createRequest().method("POST").withUrlPath(getApiRoute(), "cancel").fetchHttpStatusCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the workflow run.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void delete() throws IOException {
|
||||
root.createRequest().method("DELETE").withUrlPath(getApiRoute()).fetchHttpStatusCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rerun the workflow run.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void rerun() throws IOException {
|
||||
root.createRequest().method("POST").withUrlPath(getApiRoute(), "rerun").fetchHttpStatusCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists the artifacts attached to this workflow run.
|
||||
*
|
||||
* @return the paged iterable
|
||||
*/
|
||||
public PagedIterable<GHArtifact> listArtifacts() {
|
||||
return new GHArtifactsIterable(owner, root.createRequest().withUrlPath(getApiRoute(), "artifacts"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads the logs.
|
||||
* <p>
|
||||
* The logs are in the form of a zip archive.
|
||||
* <p>
|
||||
* Note that the archive is the same as the one downloaded from a workflow run so it contains the logs for all jobs.
|
||||
*
|
||||
* @param <T>
|
||||
* the type of result
|
||||
* @param streamFunction
|
||||
* The {@link InputStreamFunction} that will process the stream
|
||||
* @throws IOException
|
||||
* The IO exception.
|
||||
* @return the result of reading the stream.
|
||||
*/
|
||||
public <T> T downloadLogs(InputStreamFunction<T> streamFunction) throws IOException {
|
||||
requireNonNull(streamFunction, "Stream function must not be null");
|
||||
|
||||
return root.createRequest().method("GET").withUrlPath(getApiRoute(), "logs").fetchStream(streamFunction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the logs.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void deleteLogs() throws IOException {
|
||||
root.createRequest().method("DELETE").withUrlPath(getApiRoute(), "logs").fetchHttpStatusCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of jobs of this workflow run for the last execution.
|
||||
*
|
||||
* @return list of jobs from the last execution
|
||||
*/
|
||||
public PagedIterable<GHWorkflowJob> listJobs() {
|
||||
return new GHWorkflowJobQueryBuilder(this).latest().list();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of jobs from all the executions of this workflow run.
|
||||
*
|
||||
* @return list of jobs from all the executions
|
||||
*/
|
||||
public PagedIterable<GHWorkflowJob> listAllJobs() {
|
||||
return new GHWorkflowJobQueryBuilder(this).all().list();
|
||||
}
|
||||
|
||||
private String getApiRoute() {
|
||||
if (owner == null) {
|
||||
// Workflow runs returned from search to do not have an owner. Attempt to use url.
|
||||
final URL url = Objects.requireNonNull(getUrl(), "Missing instance URL!");
|
||||
return StringUtils.prependIfMissing(url.toString().replace(root.getApiUrl(), ""), "/");
|
||||
|
||||
}
|
||||
return "/repos/" + owner.getOwnerName() + "/" + owner.getName() + "/actions/runs/" + getId();
|
||||
}
|
||||
|
||||
GHWorkflowRun wrapUp(GHRepository owner) {
|
||||
this.owner = owner;
|
||||
return wrapUp(owner.root);
|
||||
}
|
||||
|
||||
GHWorkflowRun wrapUp(GitHub root) {
|
||||
this.root = root;
|
||||
if (owner != null) {
|
||||
owner.wrap(root);
|
||||
if (pullRequests != null) {
|
||||
for (GHPullRequest singlePull : pullRequests) {
|
||||
singlePull.wrap(owner);
|
||||
}
|
||||
}
|
||||
} else if (pullRequests != null) {
|
||||
for (GHPullRequest singlePull : pullRequests) {
|
||||
singlePull.wrap(root);
|
||||
}
|
||||
}
|
||||
if (headRepository != null) {
|
||||
headRepository.wrap(root);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public static class HeadCommit {
|
||||
private String id;
|
||||
private String treeId;
|
||||
private String message;
|
||||
private String timestamp;
|
||||
private GitUser author;
|
||||
private GitUser committer;
|
||||
|
||||
/**
|
||||
* Gets id of the commit
|
||||
*
|
||||
* @return id of the commit
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets id of the tree.
|
||||
*
|
||||
* @return id of the tree
|
||||
*/
|
||||
public String getTreeId() {
|
||||
return treeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets message.
|
||||
*
|
||||
* @return commit message.
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets timestamp of the commit.
|
||||
*
|
||||
* @return timestamp of the commit
|
||||
*/
|
||||
public Date getTimestamp() {
|
||||
return GitHubClient.parseDate(timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets author.
|
||||
*
|
||||
* @return the author
|
||||
*/
|
||||
public GitUser getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets committer.
|
||||
*
|
||||
* @return the committer
|
||||
*/
|
||||
public GitUser getCommitter() {
|
||||
return committer;
|
||||
}
|
||||
}
|
||||
|
||||
public static enum Status {
|
||||
QUEUED, IN_PROGRESS, COMPLETED, UNKNOWN;
|
||||
|
||||
public static Status from(String value) {
|
||||
return EnumUtils.getNullableEnumOrDefault(Status.class, value, Status.UNKNOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
public static enum Conclusion {
|
||||
ACTION_REQUIRED, CANCELLED, FAILURE, NEUTRAL, SUCCESS, SKIPPED, STALE, TIMED_OUT, UNKNOWN;
|
||||
|
||||
public static Conclusion from(String value) {
|
||||
return EnumUtils.getNullableEnumOrDefault(Conclusion.class, value, Conclusion.UNKNOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
101
src/main/java/org/kohsuke/github/GHWorkflowRunQueryBuilder.java
Normal file
101
src/main/java/org/kohsuke/github/GHWorkflowRunQueryBuilder.java
Normal file
@@ -0,0 +1,101 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import org.kohsuke.github.GHWorkflowRun.Status;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
/**
|
||||
* Lists up workflow runs with some filtering and sorting.
|
||||
*
|
||||
* @author Guillaume Smet
|
||||
* @see GHRepository#queryWorkflowRuns()
|
||||
*/
|
||||
public class GHWorkflowRunQueryBuilder extends GHQueryBuilder<GHWorkflowRun> {
|
||||
private final GHRepository repo;
|
||||
|
||||
GHWorkflowRunQueryBuilder(GHRepository repo) {
|
||||
super(repo.root);
|
||||
this.repo = repo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actor workflow run query builder.
|
||||
*
|
||||
* @param actor
|
||||
* the actor
|
||||
* @return the gh workflow run query builder
|
||||
*/
|
||||
public GHWorkflowRunQueryBuilder actor(String actor) {
|
||||
req.with("actor", actor);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actor workflow run query builder.
|
||||
*
|
||||
* @param actor
|
||||
* the actor
|
||||
* @return the gh workflow run query builder
|
||||
*/
|
||||
public GHWorkflowRunQueryBuilder actor(GHUser actor) {
|
||||
req.with("actor", actor.getLogin());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Branch workflow run query builder.
|
||||
*
|
||||
* @param branch
|
||||
* the branch
|
||||
* @return the gh workflow run query builder
|
||||
*/
|
||||
public GHWorkflowRunQueryBuilder branch(String branch) {
|
||||
req.with("branch", branch);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event workflow run query builder.
|
||||
*
|
||||
* @param event
|
||||
* the event
|
||||
* @return the gh workflow run query builder
|
||||
*/
|
||||
public GHWorkflowRunQueryBuilder event(GHEvent event) {
|
||||
req.with("event", event.symbol());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event workflow run query builder.
|
||||
*
|
||||
* @param event
|
||||
* the event
|
||||
* @return the gh workflow run query builder
|
||||
*/
|
||||
public GHWorkflowRunQueryBuilder event(String event) {
|
||||
req.with("event", event);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Status workflow run query builder.
|
||||
*
|
||||
* @param status
|
||||
* the status
|
||||
* @return the gh workflow run query builder
|
||||
*/
|
||||
public GHWorkflowRunQueryBuilder status(Status status) {
|
||||
req.with("status", status.toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PagedIterable<GHWorkflowRun> list() {
|
||||
try {
|
||||
return new GHWorkflowRunsIterable(repo, req.withUrlPath(repo.getApiTailUrl("actions/runs")).build());
|
||||
} catch (MalformedURLException e) {
|
||||
throw new GHException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
45
src/main/java/org/kohsuke/github/GHWorkflowRunsIterable.java
Normal file
45
src/main/java/org/kohsuke/github/GHWorkflowRunsIterable.java
Normal file
@@ -0,0 +1,45 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Iterable for workflow runs listing.
|
||||
*/
|
||||
class GHWorkflowRunsIterable extends PagedIterable<GHWorkflowRun> {
|
||||
private final GHRepository owner;
|
||||
private final GitHubRequest request;
|
||||
|
||||
private GHWorkflowRunsPage result;
|
||||
|
||||
public GHWorkflowRunsIterable(GHRepository owner, GitHubRequest request) {
|
||||
this.owner = owner;
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public PagedIterator<GHWorkflowRun> _iterator(int pageSize) {
|
||||
return new PagedIterator<>(
|
||||
adapt(GitHubPageIterator
|
||||
.create(owner.getRoot().getClient(), GHWorkflowRunsPage.class, request, pageSize)),
|
||||
null);
|
||||
}
|
||||
|
||||
protected Iterator<GHWorkflowRun[]> adapt(final Iterator<GHWorkflowRunsPage> base) {
|
||||
return new Iterator<GHWorkflowRun[]>() {
|
||||
public boolean hasNext() {
|
||||
return base.hasNext();
|
||||
}
|
||||
|
||||
public GHWorkflowRun[] next() {
|
||||
GHWorkflowRunsPage v = base.next();
|
||||
if (result == null) {
|
||||
result = v;
|
||||
}
|
||||
return v.getWorkflowRuns(owner);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
20
src/main/java/org/kohsuke/github/GHWorkflowRunsPage.java
Normal file
20
src/main/java/org/kohsuke/github/GHWorkflowRunsPage.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* Represents the one page of workflow runs result when listing workflow runs.
|
||||
*/
|
||||
class GHWorkflowRunsPage {
|
||||
private int totalCount;
|
||||
private GHWorkflowRun[] workflowRuns;
|
||||
|
||||
public int getTotalCount() {
|
||||
return totalCount;
|
||||
}
|
||||
|
||||
GHWorkflowRun[] getWorkflowRuns(GHRepository owner) {
|
||||
for (GHWorkflowRun workflowRun : workflowRuns) {
|
||||
workflowRun.wrapUp(owner);
|
||||
}
|
||||
return workflowRuns;
|
||||
}
|
||||
}
|
||||
53
src/main/java/org/kohsuke/github/GHWorkflowsIterable.java
Normal file
53
src/main/java/org/kohsuke/github/GHWorkflowsIterable.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Iterable for workflows listing.
|
||||
*/
|
||||
class GHWorkflowsIterable extends PagedIterable<GHWorkflow> {
|
||||
private final transient GHRepository owner;
|
||||
|
||||
private GHWorkflowsPage result;
|
||||
|
||||
public GHWorkflowsIterable(GHRepository owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public PagedIterator<GHWorkflow> _iterator(int pageSize) {
|
||||
try {
|
||||
GitHubRequest request = owner.getRoot()
|
||||
.createRequest()
|
||||
.withUrlPath(owner.getApiTailUrl("actions/workflows"))
|
||||
.build();
|
||||
|
||||
return new PagedIterator<>(
|
||||
adapt(GitHubPageIterator
|
||||
.create(owner.getRoot().getClient(), GHWorkflowsPage.class, request, pageSize)),
|
||||
null);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new GHException("Malformed URL", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected Iterator<GHWorkflow[]> adapt(final Iterator<GHWorkflowsPage> base) {
|
||||
return new Iterator<GHWorkflow[]>() {
|
||||
public boolean hasNext() {
|
||||
return base.hasNext();
|
||||
}
|
||||
|
||||
public GHWorkflow[] next() {
|
||||
GHWorkflowsPage v = base.next();
|
||||
if (result == null) {
|
||||
result = v;
|
||||
}
|
||||
return v.getWorkflows(owner);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
20
src/main/java/org/kohsuke/github/GHWorkflowsPage.java
Normal file
20
src/main/java/org/kohsuke/github/GHWorkflowsPage.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* Represents the one page of workflow result when listing workflows.
|
||||
*/
|
||||
class GHWorkflowsPage {
|
||||
private int total_count;
|
||||
private GHWorkflow[] workflows;
|
||||
|
||||
public int getTotalCount() {
|
||||
return total_count;
|
||||
}
|
||||
|
||||
GHWorkflow[] getWorkflows(GHRepository owner) {
|
||||
for (GHWorkflow workflow : workflows) {
|
||||
workflow.wrapUp(owner);
|
||||
}
|
||||
return workflows;
|
||||
}
|
||||
}
|
||||
@@ -632,11 +632,28 @@ public class GitHub {
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the repository object from its ID
|
||||
*
|
||||
* @param id
|
||||
* the id
|
||||
* @return the repository by id
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public GHRepository getRepositoryById(long id) throws IOException {
|
||||
return createRequest().withUrlPath("/repositories/" + id).fetch(GHRepository.class).wrap(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of popular open source licenses
|
||||
*
|
||||
@@ -1278,7 +1295,7 @@ public class GitHub {
|
||||
.with(new ByteArrayInputStream(text.getBytes("UTF-8")))
|
||||
.contentType("text/plain;charset=UTF-8")
|
||||
.withUrlPath("/markdown/raw")
|
||||
.fetchStream(),
|
||||
.fetchStream(Requester::copyInputStream),
|
||||
"UTF-8");
|
||||
}
|
||||
|
||||
|
||||
@@ -20,4 +20,8 @@ abstract class GitHubInteractiveObject {
|
||||
GitHubInteractiveObject(GitHub root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
GitHub getRoot() {
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.databind.InjectableValues;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.kohsuke.github.function.FunctionThrows;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
@@ -194,24 +195,11 @@ class GitHubResponse<T> {
|
||||
/**
|
||||
* 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>
|
||||
* the type of results supplied by this supplier
|
||||
*/
|
||||
@FunctionalInterface
|
||||
interface BodyHandler<T> {
|
||||
|
||||
/**
|
||||
* Gets a result.
|
||||
*
|
||||
* @return a result
|
||||
* @throws IOException
|
||||
* if an I/O Exception occurs.
|
||||
*/
|
||||
T apply(ResponseInfo input) throws IOException;
|
||||
interface BodyHandler<T> extends FunctionThrows<ResponseInfo, T, IOException> {
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
*/
|
||||
package org.kohsuke.github;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.kohsuke.github.function.InputStreamFunction;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
@@ -106,15 +108,31 @@ class Requester extends GitHubRequest.Builder<Requester> {
|
||||
* Response input stream. There are scenarios where direct stream reading is needed, however it is better to use
|
||||
* {@link #fetch(Class)} where possible.
|
||||
*
|
||||
* @return the input stream
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public InputStream fetchStream() throws IOException {
|
||||
return client
|
||||
.sendRequest(this,
|
||||
(responseInfo) -> new ByteArrayInputStream(IOUtils.toByteArray(responseInfo.bodyStream())))
|
||||
.body();
|
||||
public <T> T fetchStream(@Nonnull InputStreamFunction<T> handler) throws IOException {
|
||||
return client.sendRequest(this, (responseInfo) -> handler.apply(responseInfo.bodyStream())).body();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to make it easy to pull streams.
|
||||
*
|
||||
* Copies an input stream to an in-memory input stream. The performance on this is not great but
|
||||
* {@link GitHubResponse.ResponseInfo#bodyStream()} is closed at the end of every call to
|
||||
* {@link GitHubClient#sendRequest(GitHubRequest, GitHubResponse.BodyHandler)}, so any reads to the original input
|
||||
* stream must be completed before then. There are a number of deprecated methods that return {@link InputStream}.
|
||||
* This method keeps all of them using the same code path.
|
||||
*
|
||||
* @param inputStream
|
||||
* the input stream to be copied
|
||||
* @return an in-memory copy of the passed input stream
|
||||
* @throws IOException
|
||||
* if an error occurs while copying the stream
|
||||
*/
|
||||
@NonNull
|
||||
public static InputStream copyInputStream(InputStream inputStream) throws IOException {
|
||||
return new ByteArrayInputStream(IOUtils.toByteArray(inputStream));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,11 +42,15 @@ public class JWTTokenProvider implements AuthorizationProvider {
|
||||
private final String applicationId;
|
||||
|
||||
public JWTTokenProvider(String applicationId, File keyFile) throws GeneralSecurityException, IOException {
|
||||
this(applicationId, loadPrivateKey(keyFile.toPath()));
|
||||
this(applicationId, keyFile.toPath());
|
||||
}
|
||||
|
||||
public JWTTokenProvider(String applicationId, Path keyPath) throws GeneralSecurityException, IOException {
|
||||
this(applicationId, loadPrivateKey(keyPath));
|
||||
this(applicationId, new String(Files.readAllBytes(keyPath), StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
public JWTTokenProvider(String applicationId, String keyString) throws GeneralSecurityException {
|
||||
this(applicationId, getPrivateKeyFromString(keyString));
|
||||
}
|
||||
|
||||
public JWTTokenProvider(String applicationId, PrivateKey privateKey) {
|
||||
@@ -64,18 +68,6 @@ public class JWTTokenProvider implements AuthorizationProvider {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add dependencies for a jwt suite You can generate a key to load in this method with:
|
||||
*
|
||||
* <pre>
|
||||
* openssl pkcs8 -topk8 -inform PEM -outform DER -in ~/github-api-app.private-key.pem -out ~/github-api-app.private-key.der -nocrypt
|
||||
* </pre>
|
||||
*/
|
||||
private static PrivateKey loadPrivateKey(Path keyPath) throws GeneralSecurityException, IOException {
|
||||
String keyString = new String(Files.readAllBytes(keyPath), StandardCharsets.UTF_8);
|
||||
return getPrivateKeyFromString(keyString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a PKCS#8 formatted private key in string format into a java PrivateKey
|
||||
*
|
||||
@@ -111,20 +103,28 @@ public class JWTTokenProvider implements AuthorizationProvider {
|
||||
private String refreshJWT() {
|
||||
Instant now = Instant.now();
|
||||
|
||||
// Token expires in 10 minutes
|
||||
Instant expiration = Instant.now().plus(Duration.ofMinutes(10));
|
||||
// Max token expiration is 10 minutes for GitHub
|
||||
// We use a smaller window since we likely will not need more than a few seconds
|
||||
Instant expiration = now.plus(Duration.ofMinutes(8));
|
||||
|
||||
// Setting the issued at to a time in the past to allow for clock skew
|
||||
Instant issuedAt = getIssuedAt(now);
|
||||
|
||||
// Let's set the JWT Claims
|
||||
JwtBuilder builder = Jwts.builder()
|
||||
.setIssuedAt(Date.from(now))
|
||||
.setIssuedAt(Date.from(issuedAt))
|
||||
.setExpiration(Date.from(expiration))
|
||||
.setIssuer(this.applicationId)
|
||||
.signWith(privateKey, SignatureAlgorithm.RS256);
|
||||
|
||||
// Token will refresh after 8 minutes
|
||||
// Token will refresh 2 minutes before it expires
|
||||
validUntil = expiration.minus(Duration.ofMinutes(2));
|
||||
|
||||
// Builds the JWT and serializes it to a compact, URL-safe string
|
||||
return builder.compact();
|
||||
}
|
||||
|
||||
Instant getIssuedAt(Instant now) {
|
||||
return now.minus(Duration.ofMinutes(2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.kohsuke.github.function;
|
||||
|
||||
/**
|
||||
* A functional interface, equivalent to {@link java.util.function.Function} but that allows throwing {@link Throwable}
|
||||
*
|
||||
* @param <T>
|
||||
* the type of input
|
||||
* @param <R>
|
||||
* the type of output
|
||||
* @param <E>
|
||||
* the type of error
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface FunctionThrows<T, R, E extends Throwable> {
|
||||
/**
|
||||
* Apply r.
|
||||
*
|
||||
* @param input
|
||||
* the input
|
||||
* @return the r
|
||||
* @throws E
|
||||
* the e
|
||||
*/
|
||||
R apply(T input) throws E;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.kohsuke.github.function;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* A functional interface, equivalent to {@link java.util.function.Function} but that allows throwing {@link Throwable}
|
||||
*
|
||||
* @param <R>
|
||||
* the type to of object to be returned
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface InputStreamFunction<R> extends FunctionThrows<InputStream, R, IOException> {
|
||||
}
|
||||
39
src/main/java/org/kohsuke/github/internal/EnumUtils.java
Normal file
39
src/main/java/org/kohsuke/github/internal/EnumUtils.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package org.kohsuke.github.internal;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Utils for Enums.
|
||||
*/
|
||||
public final class EnumUtils {
|
||||
|
||||
/**
|
||||
* Returns an enum value matching the value if found, null if the value is null and {@code defaultEnum} if the value
|
||||
* cannot be matched to a value of the enum.
|
||||
* <p>
|
||||
* The value is converted to uppercase before being matched to the enum values.
|
||||
*
|
||||
* @param <E>
|
||||
* the type of the enum
|
||||
* @param enumClass
|
||||
* the type of the enum
|
||||
* @param value
|
||||
* the value to interpret
|
||||
* @param defaultEnum
|
||||
* the default enum value if the value doesn't match one of the enum value
|
||||
* @return an enum value or null
|
||||
*/
|
||||
public static <E extends Enum<E>> E getNullableEnumOrDefault(Class<E> enumClass, String value, E defaultEnum) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Enum.valueOf(enumClass, value.toUpperCase(Locale.ROOT));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return defaultEnum;
|
||||
}
|
||||
}
|
||||
|
||||
private EnumUtils() {
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ import org.kohsuke.github.extras.authorization.JWTTokenProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PrivateKey;
|
||||
@@ -34,9 +36,12 @@ public class AbstractGHAppInstallationTest extends AbstractGitHubWireMockTest {
|
||||
JWT_PROVIDER_1 = new JWTTokenProvider(TEST_APP_ID_1,
|
||||
new File(this.getClass().getResource(PRIVATE_KEY_FILE_APP_1).getFile()));
|
||||
JWT_PROVIDER_2 = new JWTTokenProvider(TEST_APP_ID_2,
|
||||
new File(this.getClass().getResource(PRIVATE_KEY_FILE_APP_2).getFile()));
|
||||
new File(this.getClass().getResource(PRIVATE_KEY_FILE_APP_2).getFile()).toPath());
|
||||
JWT_PROVIDER_3 = new JWTTokenProvider(TEST_APP_ID_3,
|
||||
new File(this.getClass().getResource(PRIVATE_KEY_FILE_APP_3).getFile()));
|
||||
new String(
|
||||
Files.readAllBytes(
|
||||
new File(this.getClass().getResource(PRIVATE_KEY_FILE_APP_3).getFile()).toPath()),
|
||||
StandardCharsets.UTF_8));
|
||||
} catch (GeneralSecurityException | IOException e) {
|
||||
throw new RuntimeException("These should never fail", e);
|
||||
}
|
||||
@@ -75,10 +80,11 @@ public class AbstractGHAppInstallationTest extends AbstractGitHubWireMockTest {
|
||||
.findFirst()
|
||||
.get();
|
||||
|
||||
appInstallation
|
||||
.setRoot(getGitHubBuilder().withAppInstallationToken(appInstallation.createToken().create().getToken())
|
||||
.withEndpoint(mockGitHub.apiServer().baseUrl())
|
||||
.build());
|
||||
// TODO: this is odd
|
||||
// appInstallation
|
||||
// .setRoot(getGitHubBuilder().withAppInstallationToken(appInstallation.createToken().create().getToken())
|
||||
// .withEndpoint(mockGitHub.apiServer().baseUrl())
|
||||
// .build());
|
||||
|
||||
return appInstallation;
|
||||
}
|
||||
|
||||
@@ -19,10 +19,7 @@ import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||
import static org.hamcrest.Matchers.hasProperty;
|
||||
import static org.hamcrest.Matchers.oneOf;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
/**
|
||||
* Unit test for simple App.
|
||||
@@ -37,10 +34,11 @@ public class AppTest extends AbstractGitHubWireMockTest {
|
||||
cleanupUserRepository("github-api-test-rename");
|
||||
cleanupUserRepository(targetName);
|
||||
|
||||
GHRepository r = gitHub.createRepository("github-api-test-rename",
|
||||
"a test repository",
|
||||
"http://github-api.kohsuke.org/",
|
||||
true);
|
||||
GHRepository r = gitHub.createRepository("github-api-test-rename")
|
||||
.description("a test repository")
|
||||
.homepage("http://github-api.kohsuke.org/")
|
||||
.private_(false)
|
||||
.create();
|
||||
|
||||
assertThat(r.hasIssues(), is(true));
|
||||
assertThat(r.hasWiki(), is(true));
|
||||
@@ -137,13 +135,36 @@ public class AppTest extends AbstractGitHubWireMockTest {
|
||||
@Test
|
||||
public void testIssueWithNoComment() throws IOException {
|
||||
GHRepository repository = gitHub.getRepository("kohsuke/test");
|
||||
List<GHIssueComment> v = repository.getIssue(4).getComments();
|
||||
GHIssue i = repository.getIssue(4);
|
||||
List<GHIssueComment> v = i.getComments();
|
||||
// System.out.println(v);
|
||||
assertTrue(v.isEmpty());
|
||||
|
||||
v = repository.getIssue(3).getComments();
|
||||
i = repository.getIssue(3);
|
||||
v = i.getComments();
|
||||
// System.out.println(v);
|
||||
assertTrue(v.size() == 3);
|
||||
assertThat(v.size(), equalTo(3));
|
||||
assertThat(v.get(0).getHtmlUrl().toString(),
|
||||
equalTo("https://github.com/kohsuke/test/issues/3#issuecomment-8547249"));
|
||||
assertThat(v.get(0).getUrl().toString(), endsWith("/repos/kohsuke/test/issues/comments/8547249"));
|
||||
assertThat(v.get(0).getNodeId(), equalTo("MDEyOklzc3VlQ29tbWVudDg1NDcyNDk="));
|
||||
assertThat(v.get(0).getParent().getNumber(), equalTo(3));
|
||||
assertThat(v.get(0).getParent().getId(), equalTo(6863845L));
|
||||
assertThat(v.get(0).getUser().getLogin(), equalTo("kohsuke"));
|
||||
assertThat(v.get(0).listReactions().toList().size(), equalTo(0));
|
||||
|
||||
assertThat(v.get(1).getHtmlUrl().toString(),
|
||||
equalTo("https://github.com/kohsuke/test/issues/3#issuecomment-8547251"));
|
||||
assertThat(v.get(1).getUrl().toString(), endsWith("/repos/kohsuke/test/issues/comments/8547251"));
|
||||
assertThat(v.get(1).getNodeId(), equalTo("MDEyOklzc3VlQ29tbWVudDg1NDcyNTE="));
|
||||
assertThat(v.get(1).getParent().getNumber(), equalTo(3));
|
||||
assertThat(v.get(1).getUser().getLogin(), equalTo("kohsuke"));
|
||||
List<GHReaction> reactions = v.get(1).listReactions().toList();
|
||||
assertThat(reactions.size(), equalTo(3));
|
||||
|
||||
// TODO: Add comment CRUD test
|
||||
// TODO: Add reactions CRUD test
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -165,49 +186,60 @@ public class AppTest extends AbstractGitHubWireMockTest {
|
||||
@Test
|
||||
public void testCreateAndListDeployments() throws IOException {
|
||||
GHRepository repository = getTestRepository();
|
||||
GHDeployment deployment = repository.createDeployment("master")
|
||||
GHDeployment deployment = repository.createDeployment("main")
|
||||
.payload("{\"user\":\"atmos\",\"room_id\":123456}")
|
||||
.description("question")
|
||||
.environment("unittest")
|
||||
.create();
|
||||
assertNotNull(deployment.getCreator());
|
||||
assertNotNull(deployment.getId());
|
||||
List<GHDeployment> deployments = repository.listDeployments(null, "master", null, "unittest").toList();
|
||||
assertNotNull(deployments);
|
||||
assertFalse(Iterables.isEmpty(deployments));
|
||||
GHDeployment unitTestDeployment = deployments.get(0);
|
||||
assertEquals("unittest", unitTestDeployment.getEnvironment());
|
||||
assertEquals("unittest", unitTestDeployment.getOriginalEnvironment());
|
||||
assertEquals(false, unitTestDeployment.isProductionEnvironment());
|
||||
assertEquals(true, unitTestDeployment.isTransientEnvironment());
|
||||
assertEquals("master", unitTestDeployment.getRef());
|
||||
try {
|
||||
assertNotNull(deployment.getCreator());
|
||||
assertNotNull(deployment.getId());
|
||||
List<GHDeployment> deployments = repository.listDeployments(null, "main", null, "unittest").toList();
|
||||
assertNotNull(deployments);
|
||||
assertFalse(Iterables.isEmpty(deployments));
|
||||
GHDeployment unitTestDeployment = deployments.get(0);
|
||||
assertEquals("unittest", unitTestDeployment.getEnvironment());
|
||||
assertEquals("unittest", unitTestDeployment.getOriginalEnvironment());
|
||||
assertEquals(false, unitTestDeployment.isProductionEnvironment());
|
||||
assertEquals(false, unitTestDeployment.isTransientEnvironment());
|
||||
assertEquals("main", unitTestDeployment.getRef());
|
||||
} finally {
|
||||
// deployment.delete();
|
||||
assert true;
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Needs mocking check")
|
||||
@Test
|
||||
public void testGetDeploymentStatuses() throws IOException {
|
||||
GHRepository repository = getTestRepository();
|
||||
GHDeployment deployment = repository.createDeployment("master")
|
||||
GHDeployment deployment = repository.createDeployment("main")
|
||||
.description("question")
|
||||
.payload("{\"user\":\"atmos\",\"room_id\":123456}")
|
||||
.create();
|
||||
GHDeploymentStatus ghDeploymentStatus = deployment.createStatus(GHDeploymentState.QUEUED)
|
||||
.description("success")
|
||||
.targetUrl("http://www.github.com")
|
||||
.logUrl("http://www.github.com/logurl")
|
||||
.environmentUrl("http://www.github.com/envurl")
|
||||
.environment("new-ci-env")
|
||||
.create();
|
||||
Iterable<GHDeploymentStatus> deploymentStatuses = deployment.listStatuses();
|
||||
assertNotNull(deploymentStatuses);
|
||||
assertEquals(1, Iterables.size(deploymentStatuses));
|
||||
GHDeploymentStatus actualStatus = Iterables.get(deploymentStatuses, 0);
|
||||
assertEquals(ghDeploymentStatus.getId(), actualStatus.getId());
|
||||
assertEquals(ghDeploymentStatus.getState(), actualStatus.getState());
|
||||
assertEquals(ghDeploymentStatus.getLogUrl(), actualStatus.getLogUrl());
|
||||
// Target url was deprecated and replaced with log url. The gh api will
|
||||
// prefer the log url value and return it in place of target url.
|
||||
assertEquals(ghDeploymentStatus.getTargetUrl(), actualStatus.getLogUrl());
|
||||
try {
|
||||
GHDeploymentStatus ghDeploymentStatus = deployment.createStatus(GHDeploymentState.QUEUED)
|
||||
.description("success")
|
||||
.targetUrl("http://www.github.com")
|
||||
.logUrl("http://www.github.com/logurl")
|
||||
.environmentUrl("http://www.github.com/envurl")
|
||||
.environment("new-ci-env")
|
||||
.create();
|
||||
Iterable<GHDeploymentStatus> deploymentStatuses = deployment.listStatuses();
|
||||
assertNotNull(deploymentStatuses);
|
||||
assertEquals(1, Iterables.size(deploymentStatuses));
|
||||
GHDeploymentStatus actualStatus = Iterables.get(deploymentStatuses, 0);
|
||||
assertEquals(ghDeploymentStatus.getId(), actualStatus.getId());
|
||||
assertEquals(ghDeploymentStatus.getState(), actualStatus.getState());
|
||||
assertEquals(ghDeploymentStatus.getLogUrl(), actualStatus.getLogUrl());
|
||||
// Target url was deprecated and replaced with log url. The gh api will
|
||||
// prefer the log url value and return it in place of target url.
|
||||
assertEquals(ghDeploymentStatus.getTargetUrl(), actualStatus.getLogUrl());
|
||||
assertThat(ghDeploymentStatus.getDeploymentUrl(), equalTo(deployment.getUrl()));
|
||||
assertThat(ghDeploymentStatus.getRepositoryUrl(), equalTo(repository.getUrl()));
|
||||
} finally {
|
||||
// deployment.delete();
|
||||
assert true;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -324,7 +356,7 @@ public class AppTest extends AbstractGitHubWireMockTest {
|
||||
assertEquals(teamByName.getId(), teamById.getId());
|
||||
assertEquals(teamByName.getDescription(), teamById.getDescription());
|
||||
|
||||
GHTeam teamById2 = organization.getTeam((int) teamByName.getId());
|
||||
GHTeam teamById2 = organization.getTeam(teamByName.getId());
|
||||
assertNotNull(teamById2);
|
||||
|
||||
assertEquals(teamByName.getId(), teamById2.getId());
|
||||
@@ -445,6 +477,16 @@ public class AppTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
File f = commit.getFiles().get(0);
|
||||
assertEquals(48, f.getLinesChanged());
|
||||
assertThat(f.getLinesAdded(), equalTo(40));
|
||||
assertThat(f.getLinesDeleted(), equalTo(8));
|
||||
assertThat(f.getPreviousFilename(), nullValue());
|
||||
assertThat(f.getPatch(), startsWith("@@ -54,6 +54,14 @@\n"));
|
||||
assertThat(f.getSha(), equalTo("04d3e54017542ad0ff46355eababacd4850ccba5"));
|
||||
assertThat(f.getBlobUrl().toString(),
|
||||
equalTo("https://github.com/jenkinsci/jenkins/blob/08c1c9970af4d609ae754fbe803e06186e3206f7/changelog.html"));
|
||||
assertThat(f.getRawUrl().toString(),
|
||||
equalTo("https://github.com/jenkinsci/jenkins/raw/08c1c9970af4d609ae754fbe803e06186e3206f7/changelog.html"));
|
||||
|
||||
assertEquals("modified", f.getStatus());
|
||||
assertEquals("changelog.html", f.getFileName());
|
||||
|
||||
@@ -464,22 +506,6 @@ public class AppTest extends AbstractGitHubWireMockTest {
|
||||
assertEquals(1, sha1.size());
|
||||
}
|
||||
|
||||
public void testQueryCommits() throws Exception {
|
||||
List<String> sha1 = new ArrayList<String>();
|
||||
for (GHCommit c : gitHub.getUser("jenkinsci")
|
||||
.getRepository("jenkins")
|
||||
.queryCommits()
|
||||
.since(new Date(1199174400000L))
|
||||
.until(1201852800000L)
|
||||
.path("pom.xml")
|
||||
.list()) {
|
||||
// System.out.println(c.getSHA1());
|
||||
sha1.add(c.getSHA1());
|
||||
}
|
||||
assertEquals("1cccddb22e305397151b2b7b87b4b47d74ca337b", sha1.get(0));
|
||||
assertEquals(29, sha1.size());
|
||||
}
|
||||
|
||||
@Ignore("Needs mocking check")
|
||||
@Test
|
||||
public void testBranches() throws Exception {
|
||||
@@ -504,23 +530,65 @@ public class AppTest extends AbstractGitHubWireMockTest {
|
||||
.getRepository("sandbox-ant")
|
||||
.getCommit("8ae38db0ea5837313ab5f39d43a6f73de3bd9000");
|
||||
GHCommitComment c = commit.createComment("[testing](http://kohsuse.org/)");
|
||||
// System.out.println(c);
|
||||
c.update("updated text");
|
||||
// System.out.println(c);
|
||||
c.delete();
|
||||
try {
|
||||
assertThat(c.getPath(), nullValue());
|
||||
assertThat(c.getLine(), equalTo(-1));
|
||||
assertThat(c.getHtmlUrl().toString(),
|
||||
containsString(
|
||||
"kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000#commitcomment-"));
|
||||
assertThat(c.listReactions().toList(), is(empty()));
|
||||
|
||||
c.update("updated text");
|
||||
assertThat(c.getBody(), equalTo("updated text"));
|
||||
} finally {
|
||||
c.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tryHook() throws Exception {
|
||||
kohsuke();
|
||||
GHRepository r = gitHub.getOrganization(GITHUB_API_TEST_ORG).getRepository("github-api");
|
||||
GHHook hook = r.createWebHook(new URL("http://www.google.com/"));
|
||||
// System.out.println(hook);
|
||||
GHOrganization o = gitHub.getOrganization(GITHUB_API_TEST_ORG);
|
||||
GHRepository r = o.getRepository("github-api");
|
||||
try {
|
||||
GHHook hook = r.createWebHook(new URL("http://www.google.com/"));
|
||||
assertThat(hook.getName(), equalTo("web"));
|
||||
assertThat(hook.getEvents().size(), equalTo(1));
|
||||
assertThat(hook.getEvents(), contains(GHEvent.PUSH));
|
||||
assertThat(hook.getConfig().size(), equalTo(3));
|
||||
assertThat(hook.isActive(), equalTo(true));
|
||||
|
||||
if (mockGitHub.isUseProxy()) {
|
||||
r = getGitHubBeforeAfter().getOrganization(GITHUB_API_TEST_ORG).getRepository("github-api");
|
||||
for (GHHook h : r.getHooks()) {
|
||||
h.delete();
|
||||
GHHook hook2 = r.getHook((int) hook.getId());
|
||||
assertThat(hook2.getName(), equalTo("web"));
|
||||
assertThat(hook2.getEvents().size(), equalTo(1));
|
||||
assertThat(hook2.getEvents(), contains(GHEvent.PUSH));
|
||||
assertThat(hook2.getConfig().size(), equalTo(3));
|
||||
assertThat(hook2.isActive(), equalTo(true));
|
||||
hook2.ping();
|
||||
hook2.delete();
|
||||
|
||||
hook = o.createWebHook(new URL("http://www.google.com/"));
|
||||
assertThat(hook.getName(), equalTo("web"));
|
||||
assertThat(hook.getEvents().size(), equalTo(1));
|
||||
assertThat(hook.getEvents(), contains(GHEvent.PUSH));
|
||||
assertThat(hook.getConfig().size(), equalTo(3));
|
||||
assertThat(hook.isActive(), equalTo(true));
|
||||
|
||||
hook2 = o.getHook((int) hook.getId());
|
||||
assertThat(hook2.getName(), equalTo("web"));
|
||||
assertThat(hook2.getEvents().size(), equalTo(1));
|
||||
assertThat(hook2.getEvents(), contains(GHEvent.PUSH));
|
||||
assertThat(hook2.getConfig().size(), equalTo(3));
|
||||
assertThat(hook2.isActive(), equalTo(true));
|
||||
hook2.ping();
|
||||
hook2.delete();
|
||||
|
||||
// System.out.println(hook);
|
||||
} finally {
|
||||
if (mockGitHub.isUseProxy()) {
|
||||
r = getGitHubBeforeAfter().getOrganization(GITHUB_API_TEST_ORG).getRepository("github-api");
|
||||
for (GHHook h : r.getHooks()) {
|
||||
h.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -529,6 +597,14 @@ public class AppTest extends AbstractGitHubWireMockTest {
|
||||
public void testEventApi() throws Exception {
|
||||
for (GHEventInfo ev : gitHub.getEvents()) {
|
||||
if (ev.getType() == GHEvent.PULL_REQUEST) {
|
||||
if (ev.getId() == 10680625394L) {
|
||||
assertThat(ev.getActorLogin(), equalTo("pull[bot]"));
|
||||
assertThat(ev.getOrganization(), nullValue());
|
||||
assertThat(ev.getRepository().getFullName(), equalTo("daddyfatstacksBIG/lerna"));
|
||||
assertThat(ev.getCreatedAt(), equalTo(GitHubClient.parseDate("2019-10-21T21:54:52Z")));
|
||||
assertThat(ev.getType(), equalTo(GHEvent.PULL_REQUEST));
|
||||
}
|
||||
|
||||
GHEventPayload.PullRequest pr = ev.getPayload(GHEventPayload.PullRequest.class);
|
||||
assertThat(pr.getNumber(), is(pr.getPullRequest().getNumber()));
|
||||
}
|
||||
@@ -859,8 +935,18 @@ public class AppTest extends AbstractGitHubWireMockTest {
|
||||
for (GHTreeEntry e : masterTree.getTree()) {
|
||||
if (e.getPath().endsWith(AppTest.class.getSimpleName() + ".java")) {
|
||||
foundThisFile = true;
|
||||
assertThat(e.getPath(), equalTo("src/test/java/org/kohsuke/github/AppTest.java"));
|
||||
assertThat(e.getSha(), equalTo("baad7a7c4cf409f610a0e8c7eba17664eb655c44"));
|
||||
assertThat(e.getMode(), equalTo("100755"));
|
||||
assertThat(e.getSize(), greaterThan(30000L));
|
||||
assertThat(e.getUrl().toString(),
|
||||
containsString("/repos/hub4j/github-api/git/blobs/baad7a7c4cf409f610a0e8c7eba17664eb655c44"));
|
||||
GHBlob blob = e.asBlob();
|
||||
assertThat(e.asBlob().getUrl().toString(),
|
||||
containsString("/repos/hub4j/github-api/git/blobs/baad7a7c4cf409f610a0e8c7eba17664eb655c44"));
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
assertTrue(foundThisFile);
|
||||
}
|
||||
@@ -879,6 +965,9 @@ public class AppTest extends AbstractGitHubWireMockTest {
|
||||
GHLabel e = r.getLabel("enhancement");
|
||||
assertEquals("enhancement", e.getName());
|
||||
assertNotNull(e.getUrl());
|
||||
assertEquals(177339106, e.getId());
|
||||
assertEquals("MDU6TGFiZWwxNzczMzkxMDY=", e.getNodeId());
|
||||
assertTrue(e.isDefault());
|
||||
assertTrue(Pattern.matches("[0-9a-fA-F]{6}", e.getColor()));
|
||||
|
||||
GHLabel t = null;
|
||||
@@ -890,12 +979,17 @@ public class AppTest extends AbstractGitHubWireMockTest {
|
||||
assertThat(t, not(sameInstance(t2)));
|
||||
assertThat(t, equalTo(t2));
|
||||
|
||||
assertFalse(t2.isDefault());
|
||||
|
||||
assertEquals(t.getId(), t2.getId());
|
||||
assertEquals(t.getNodeId(), t2.getNodeId());
|
||||
assertEquals(t.getName(), t2.getName());
|
||||
assertEquals(t.getColor(), "123456");
|
||||
assertEquals(t.getColor(), t2.getColor());
|
||||
assertEquals(t.getDescription(), "");
|
||||
assertEquals(t.getDescription(), t2.getDescription());
|
||||
assertEquals(t.getUrl(), t2.getUrl());
|
||||
assertEquals(t.isDefault(), t2.isDefault());
|
||||
|
||||
// update works on multiple changes in one call
|
||||
t3 = t.update().color("000000").description("It is dark!").done();
|
||||
|
||||
@@ -33,6 +33,7 @@ public class BridgeMethodTest extends Assert {
|
||||
verifyBridgeMethods(GHIssue.class, "getCreatedAt", Date.class, String.class);
|
||||
verifyBridgeMethods(GHIssue.class, "getId", int.class, long.class, String.class);
|
||||
verifyBridgeMethods(GHIssue.class, "getUrl", String.class, URL.class);
|
||||
verifyBridgeMethods(GHIssue.class, "comment", 1, void.class, GHIssueComment.class);
|
||||
|
||||
verifyBridgeMethods(GHOrganization.class, "getHtmlUrl", String.class, URL.class);
|
||||
verifyBridgeMethods(GHOrganization.class, "getId", int.class, long.class, String.class);
|
||||
@@ -55,12 +56,17 @@ public class BridgeMethodTest extends Assert {
|
||||
}
|
||||
|
||||
void verifyBridgeMethods(@Nonnull Class<?> targetClass, @Nonnull String methodName, Class<?>... returnTypes) {
|
||||
verifyBridgeMethods(targetClass, methodName, 0, returnTypes);
|
||||
}
|
||||
|
||||
void verifyBridgeMethods(@Nonnull Class<?> targetClass,
|
||||
@Nonnull String methodName,
|
||||
int parameterCount,
|
||||
Class<?>... returnTypes) {
|
||||
List<Class<?>> foundMethods = new ArrayList<>();
|
||||
Method[] methods = targetClass.getMethods();
|
||||
for (Method method : methods) {
|
||||
if (method.getName().equalsIgnoreCase(methodName)) {
|
||||
// Bridge methods are only
|
||||
assertThat(method.getParameterCount(), equalTo(0));
|
||||
if (method.getName().equalsIgnoreCase(methodName) && method.getParameterCount() == parameterCount) {
|
||||
foundMethods.add(method.getReturnType());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ import com.google.common.collect.Iterables;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
@@ -29,6 +31,85 @@ public class CommitTest extends AbstractGitHubWireMockTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryCommits() throws Exception {
|
||||
List<String> sha1 = new ArrayList<String>();
|
||||
List<GHCommit> commits = gitHub.getUser("jenkinsci")
|
||||
.getRepository("jenkins")
|
||||
.queryCommits()
|
||||
.since(1199174400000L)
|
||||
.until(1201852800000L)
|
||||
.path("pom.xml")
|
||||
.pageSize(100)
|
||||
.list()
|
||||
.toList();
|
||||
|
||||
assertThat(commits.get(0).getSHA1(), equalTo("1cccddb22e305397151b2b7b87b4b47d74ca337b"));
|
||||
assertThat(commits.size(), equalTo(29));
|
||||
|
||||
commits = gitHub.getUser("jenkinsci")
|
||||
.getRepository("jenkins")
|
||||
.queryCommits()
|
||||
.since(new Date(1199174400000L))
|
||||
.until(new Date(1201852800000L))
|
||||
.path("pom.xml")
|
||||
.pageSize(100)
|
||||
.list()
|
||||
.toList();
|
||||
|
||||
assertThat(commits.get(0).getSHA1(), equalTo("1cccddb22e305397151b2b7b87b4b47d74ca337b"));
|
||||
assertThat(commits.get(15).getSHA1(), equalTo("a5259970acaec9813e2a12a91f37dfc7871a5ef5"));
|
||||
assertThat(commits.size(), equalTo(29));
|
||||
|
||||
commits = gitHub.getUser("jenkinsci")
|
||||
.getRepository("jenkins")
|
||||
.queryCommits()
|
||||
.since(new Date(1199174400000L))
|
||||
.until(new Date(1201852800000L))
|
||||
.path("pom.xml")
|
||||
.from("a5259970acaec9813e2a12a91f37dfc7871a5ef5")
|
||||
.list()
|
||||
.toList();
|
||||
|
||||
assertThat(commits.get(0).getSHA1(), equalTo("a5259970acaec9813e2a12a91f37dfc7871a5ef5"));
|
||||
assertThat(commits.size(), equalTo(14));
|
||||
|
||||
commits = gitHub.getUser("jenkinsci")
|
||||
.getRepository("jenkins")
|
||||
.queryCommits()
|
||||
.until(new Date(1201852800000L))
|
||||
.path("pom.xml")
|
||||
.author("kohsuke")
|
||||
.list()
|
||||
.toList();
|
||||
|
||||
assertThat(commits.size(), equalTo(0));
|
||||
|
||||
commits = gitHub.getUser("jenkinsci")
|
||||
.getRepository("jenkins")
|
||||
.queryCommits()
|
||||
.until(new Date(1201852800000L))
|
||||
.path("pom.xml")
|
||||
.pageSize(100)
|
||||
.author("kohsuke@71c3de6d-444a-0410-be80-ed276b4c234a")
|
||||
.list()
|
||||
.toList();
|
||||
|
||||
assertThat(commits.size(), equalTo(266));
|
||||
|
||||
commits = gitHub.getUser("jenkinsci")
|
||||
.getRepository("jenkins")
|
||||
.queryCommits()
|
||||
.path("pom.xml")
|
||||
.pageSize(100)
|
||||
.author("kohsuke@71c3de6d-444a-0410-be80-ed276b4c234a")
|
||||
.list()
|
||||
.toList();
|
||||
|
||||
assertThat(commits.size(), equalTo(648));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listPullRequestsOfNotIncludedCommit() throws Exception {
|
||||
GHRepository repo = gitHub.getOrganization("hub4j-test-org").getRepository("listPrsListHeads");
|
||||
|
||||
85
src/test/java/org/kohsuke/github/EnumTest.java
Normal file
85
src/test/java/org/kohsuke/github/EnumTest.java
Normal file
@@ -0,0 +1,85 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
|
||||
/**
|
||||
* Unit test for {@link GitHub} static helpers.
|
||||
*
|
||||
* @author Liam Newman
|
||||
*/
|
||||
public class EnumTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
@Test
|
||||
public void touchEnums() {
|
||||
assertThat(GHCheckRun.AnnotationLevel.values().length, equalTo(3));
|
||||
assertThat(GHCheckRun.Conclusion.values().length, equalTo(9));
|
||||
assertThat(GHCheckRun.Status.values().length, equalTo(4));
|
||||
|
||||
assertThat(GHCommentAuthorAssociation.values().length, equalTo(7));
|
||||
|
||||
assertThat(GHCommitState.values().length, equalTo(4));
|
||||
|
||||
assertThat(GHCompare.Status.values().length, equalTo(4));
|
||||
|
||||
assertThat(GHDeploymentState.values().length, equalTo(7));
|
||||
|
||||
assertThat(GHDirection.values().length, equalTo(2));
|
||||
|
||||
assertThat(GHEvent.values().length, equalTo(56));
|
||||
assertThat(GHEvent.ALL.symbol(), equalTo("*"));
|
||||
assertThat(GHEvent.PULL_REQUEST.symbol(), equalTo(GHEvent.PULL_REQUEST.toString().toLowerCase()));
|
||||
|
||||
assertThat(GHIssueSearchBuilder.Sort.values().length, equalTo(3));
|
||||
|
||||
assertThat(GHIssueState.values().length, equalTo(3));
|
||||
|
||||
assertThat(GHMarketplaceAccountType.values().length, equalTo(2));
|
||||
|
||||
assertThat(GHMarketplaceListAccountBuilder.Sort.values().length, equalTo(2));
|
||||
|
||||
assertThat(GHMarketplacePriceModel.values().length, equalTo(3));
|
||||
|
||||
assertThat(GHMembership.Role.values().length, equalTo(2));
|
||||
|
||||
assertThat(GHMilestoneState.values().length, equalTo(2));
|
||||
|
||||
assertThat(GHMyself.RepositoryListFilter.values().length, equalTo(5));
|
||||
|
||||
assertThat(GHOrganization.Role.values().length, equalTo(2));
|
||||
assertThat(GHOrganization.Permission.values().length, equalTo(5));
|
||||
|
||||
assertThat(GHPermissionType.values().length, equalTo(4));
|
||||
|
||||
assertThat(GHProject.ProjectState.values().length, equalTo(2));
|
||||
assertThat(GHProject.ProjectStateFilter.values().length, equalTo(3));
|
||||
|
||||
assertThat(GHPullRequest.MergeMethod.values().length, equalTo(3));
|
||||
|
||||
assertThat(GHPullRequestQueryBuilder.Sort.values().length, equalTo(4));
|
||||
|
||||
assertThat(GHPullRequestReviewEvent.values().length, equalTo(4));
|
||||
assertThat(GHPullRequestReviewEvent.PENDING.toState(), equalTo(GHPullRequestReviewState.PENDING));
|
||||
assertThat(GHPullRequestReviewEvent.PENDING.action(), nullValue());
|
||||
|
||||
assertThat(GHPullRequestReviewState.values().length, equalTo(6));
|
||||
assertThat(GHPullRequestReviewState.PENDING.toEvent(), equalTo(GHPullRequestReviewEvent.PENDING));
|
||||
assertThat(GHPullRequestReviewState.APPROVED.action(), equalTo(GHPullRequestReviewEvent.APPROVE.action()));
|
||||
assertThat(GHPullRequestReviewState.DISMISSED.toEvent(), nullValue());
|
||||
|
||||
assertThat(GHRepository.CollaboratorAffiliation.values().length, equalTo(3));
|
||||
assertThat(GHRepository.ForkSort.values().length, equalTo(3));
|
||||
assertThat(GHRepository.Visibility.values().length, equalTo(4));
|
||||
|
||||
assertThat(GHRepositorySearchBuilder.Sort.values().length, equalTo(3));
|
||||
|
||||
assertThat(GHRepositorySelection.values().length, equalTo(2));
|
||||
|
||||
assertThat(GHTeam.Role.values().length, equalTo(2));
|
||||
assertThat(GHTeam.Privacy.values().length, equalTo(2));
|
||||
|
||||
assertThat(GHUserSearchBuilder.Sort.values().length, equalTo(3));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -103,7 +103,8 @@ public class GHAppTest extends AbstractGitHubWireMockTest {
|
||||
permissions.put("metadata", GHPermissionType.READ);
|
||||
|
||||
// Create token specifying both permissions and repository ids
|
||||
GHAppInstallationToken installationToken = installation.createToken(permissions)
|
||||
GHAppInstallationToken installationToken = installation.createToken()
|
||||
.permissions(permissions)
|
||||
.repositoryIds(Collections.singletonList((long) 111111111))
|
||||
.create();
|
||||
|
||||
|
||||
@@ -25,11 +25,13 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.kohsuke.github.GHCheckRun.Status;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
@SuppressWarnings("deprecation") // preview
|
||||
public class GHCheckRunBuilderTest extends AbstractGHAppInstallationTest {
|
||||
@@ -48,7 +50,7 @@ public class GHCheckRunBuilderTest extends AbstractGHAppInstallationTest {
|
||||
.withExternalID("whatever")
|
||||
.withStartedAt(new Date(999_999_000))
|
||||
.withCompletedAt(new Date(999_999_999))
|
||||
.add(new GHCheckRunBuilder.Output("Some Title", "what happened…")
|
||||
.add(new GHCheckRunBuilder.Output("Some Title", "what happened…").withText("Hello Text!")
|
||||
.add(new GHCheckRunBuilder.Annotation("stuff.txt",
|
||||
1,
|
||||
GHCheckRun.AnnotationLevel.NOTICE,
|
||||
@@ -58,14 +60,17 @@ public class GHCheckRunBuilderTest extends AbstractGHAppInstallationTest {
|
||||
.withCaption("Princess Unikitty")))
|
||||
.add(new GHCheckRunBuilder.Action("Help", "what I need help with", "doit"))
|
||||
.create();
|
||||
assertEquals("completed", checkRun.getStatus());
|
||||
assertEquals(Status.COMPLETED, checkRun.getStatus());
|
||||
assertEquals(1, checkRun.getOutput().getAnnotationsCount());
|
||||
assertEquals(1424883286, checkRun.getId());
|
||||
assertEquals("Hello Text!", checkRun.getOutput().getText());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createCheckRunManyAnnotations() throws Exception {
|
||||
GHCheckRunBuilder.Output output = new GHCheckRunBuilder.Output("Big Run", "Lots of stuff here »");
|
||||
GHCheckRunBuilder.Output output = new GHCheckRunBuilder.Output("Big Run", "Lots of stuff here »")
|
||||
.withText("Hello Text!");
|
||||
|
||||
for (int i = 0; i < 101; i++) {
|
||||
output.add(
|
||||
new GHCheckRunBuilder.Annotation("stuff.txt", 1, GHCheckRun.AnnotationLevel.NOTICE, "hello #" + i));
|
||||
@@ -75,10 +80,11 @@ public class GHCheckRunBuilderTest extends AbstractGHAppInstallationTest {
|
||||
.withConclusion(GHCheckRun.Conclusion.SUCCESS)
|
||||
.add(output)
|
||||
.create();
|
||||
assertEquals("completed", checkRun.getStatus());
|
||||
assertEquals(Status.COMPLETED, checkRun.getStatus());
|
||||
assertEquals("Big Run", checkRun.getOutput().getTitle());
|
||||
assertEquals("Lots of stuff here »", checkRun.getOutput().getSummary());
|
||||
assertEquals(101, checkRun.getOutput().getAnnotationsCount());
|
||||
assertEquals("Hello Text!", checkRun.getOutput().getText());
|
||||
assertEquals(1424883599, checkRun.getId());
|
||||
}
|
||||
|
||||
@@ -89,7 +95,7 @@ public class GHCheckRunBuilderTest extends AbstractGHAppInstallationTest {
|
||||
.withConclusion(GHCheckRun.Conclusion.NEUTRAL)
|
||||
.add(new GHCheckRunBuilder.Output("Quick note", "nothing more to see here"))
|
||||
.create();
|
||||
assertEquals("completed", checkRun.getStatus());
|
||||
assertEquals(Status.COMPLETED, checkRun.getStatus());
|
||||
assertEquals(0, checkRun.getOutput().getAnnotationsCount());
|
||||
assertEquals(1424883957, checkRun.getId());
|
||||
}
|
||||
@@ -100,7 +106,7 @@ public class GHCheckRunBuilderTest extends AbstractGHAppInstallationTest {
|
||||
.createCheckRun("outstanding", "89a9ae301e35e667756034fdc933b1fc94f63fc1")
|
||||
.withStatus(GHCheckRun.Status.IN_PROGRESS)
|
||||
.create();
|
||||
assertEquals("in_progress", checkRun.getStatus());
|
||||
assertEquals(Status.IN_PROGRESS, checkRun.getStatus());
|
||||
assertNull(checkRun.getConclusion());
|
||||
assertEquals(1424883451, checkRun.getId());
|
||||
}
|
||||
@@ -116,6 +122,8 @@ public class GHCheckRunBuilderTest extends AbstractGHAppInstallationTest {
|
||||
} catch (HttpException x) {
|
||||
assertEquals(422, x.getResponseCode());
|
||||
assertThat(x.getMessage(), containsString("\\\"conclusion\\\" wasn't supplied"));
|
||||
assertThat(x.getUrl(), containsString("/repos/hub4j-test-org/test-checks/check-runs"));
|
||||
assertThat(x.getResponseMessage(), equalTo("422 Unprocessable Entity"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,14 @@ public class GHContentIntegrationTest extends AbstractGitHubWireMockTest {
|
||||
repo = gitHub.getRepository("hub4j-test-org/GHContentIntegrationTest");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRepository() throws Exception {
|
||||
GHRepository testRepo = gitHub.getRepositoryById(repo.getId());
|
||||
assertThat(testRepo.getName(), equalTo(repo.getName()));
|
||||
testRepo = gitHub.getRepositoryById(Long.toString(repo.getId()));
|
||||
assertThat(testRepo.getName(), equalTo(repo.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFileContent() throws Exception {
|
||||
repo = gitHub.getRepository("hub4j-test-org/GHContentIntegrationTest");
|
||||
|
||||
@@ -2,14 +2,26 @@ package org.kohsuke.github;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.kohsuke.github.GHCheckRun.Conclusion;
|
||||
import org.kohsuke.github.GHCheckRun.Status;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static java.lang.Boolean.TRUE;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.Matchers.aMapWithSize;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.endsWith;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasToString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.lessThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
|
||||
public class GHEventPayloadTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
@@ -141,6 +153,45 @@ public class GHEventPayloadTest extends AbstractGitHubWireMockTest {
|
||||
assertThat(event.getSender().getLogin(), is("baxterthehacker"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void issue_labeled() throws Exception {
|
||||
GHEventPayload.Issue event = GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.Issue.class);
|
||||
assertThat(event.getAction(), is("labeled"));
|
||||
assertThat(event.getIssue().getNumber(), is(42));
|
||||
assertThat(event.getIssue().getTitle(), is("Test GHEventPayload.Issue label/unlabel"));
|
||||
assertThat(event.getIssue().getLabels().size(), is(1));
|
||||
assertThat(event.getIssue().getLabels().iterator().next().getName(), is("enhancement"));
|
||||
assertThat(event.getLabel().getName(), is("enhancement"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void issue_unlabeled() throws Exception {
|
||||
GHEventPayload.Issue event = GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.Issue.class);
|
||||
assertThat(event.getAction(), is("unlabeled"));
|
||||
assertThat(event.getIssue().getNumber(), is(42));
|
||||
assertThat(event.getIssue().getTitle(), is("Test GHEventPayload.Issue label/unlabel"));
|
||||
assertThat(event.getIssue().getLabels().size(), is(0));
|
||||
assertThat(event.getLabel().getName(), is("enhancement"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void issue_title_edited() throws Exception {
|
||||
GHEventPayload.Issue event = GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.Issue.class);
|
||||
assertThat(event.getAction(), is("edited"));
|
||||
assertThat(event.getIssue().getNumber(), is(43));
|
||||
assertThat(event.getIssue().getTitle(), is("Test GHEventPayload.Issue changes [updated]"));
|
||||
assertThat(event.getChanges().getTitle().getFrom(), is("Test GHEventPayload.Issue changes"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void issue_body_edited() throws Exception {
|
||||
GHEventPayload.Issue event = GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.Issue.class);
|
||||
assertThat(event.getAction(), is("edited"));
|
||||
assertThat(event.getIssue().getNumber(), is(43));
|
||||
assertThat(event.getIssue().getBody(), is("Description [updated]."));
|
||||
assertThat(event.getChanges().getBody().getFrom(), is("Description."));
|
||||
}
|
||||
|
||||
// TODO implement support classes and write test
|
||||
// @Test
|
||||
// public void label() throws Exception {}
|
||||
@@ -361,6 +412,9 @@ public class GHEventPayloadTest extends AbstractGitHubWireMockTest {
|
||||
assertThat(event.getCommits().get(0).getRemoved().size(), is(0));
|
||||
assertThat(event.getCommits().get(0).getModified().size(), is(1));
|
||||
assertThat(event.getCommits().get(0).getModified().get(0), is("README.md"));
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
|
||||
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
assertThat(formatter.format(event.getCommits().get(0).getTimestamp()), is("2015-05-05T23:40:15Z"));
|
||||
assertThat(event.getRepository().getName(), is("public-repo"));
|
||||
assertThat(event.getRepository().getOwnerName(), is("baxterthehacker"));
|
||||
assertThat(event.getRepository().getUrl().toExternalForm(),
|
||||
@@ -515,12 +569,13 @@ public class GHEventPayloadTest extends AbstractGitHubWireMockTest {
|
||||
assertThat(event.getRepository().getName(), is("Hello-World"));
|
||||
assertThat(event.getRepository().getOwner().getLogin(), is("Codertocat"));
|
||||
assertThat(event.getAction(), is("created"));
|
||||
assertThat(event.getRequestedAction(), nullValue());
|
||||
|
||||
// Checks the deserialization of check_run
|
||||
GHCheckRun checkRun = event.getCheckRun();
|
||||
assertThat(checkRun.getName(), is("Octocoders-linter"));
|
||||
assertThat(checkRun.getHeadSha(), is("ec26c3e57ca3a959ca5aad62de7213c562f8c821"));
|
||||
assertThat(checkRun.getStatus(), is("completed"));
|
||||
assertThat(checkRun.getStatus(), is(Status.COMPLETED));
|
||||
assertThat(checkRun.getNodeId(), is("MDg6Q2hlY2tSdW4xMjg2MjAyMjg="));
|
||||
assertThat(checkRun.getExternalId(), is(""));
|
||||
|
||||
@@ -529,7 +584,7 @@ public class GHEventPayloadTest extends AbstractGitHubWireMockTest {
|
||||
assertThat(formatter.format(checkRun.getStartedAt()), is("2019-05-15T15:21:12Z"));
|
||||
assertThat(formatter.format(checkRun.getCompletedAt()), is("2019-05-15T20:22:22Z"));
|
||||
|
||||
assertThat(checkRun.getConclusion(), is("success"));
|
||||
assertThat(checkRun.getConclusion(), is(Conclusion.SUCCESS));
|
||||
assertThat(checkRun.getUrl().toString(), endsWith("/repos/Codertocat/Hello-World/check-runs/128620228"));
|
||||
assertThat(checkRun.getHtmlUrl().toString(),
|
||||
endsWith("https://github.com/Codertocat/Hello-World/runs/128620228"));
|
||||
@@ -650,4 +705,104 @@ public class GHEventPayloadTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
assertThat(event.getSender().getLogin(), is("octocat"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void workflow_dispatch() throws Exception {
|
||||
GHEventPayload.WorkflowDispatch workflowDispatchPayload = GitHub.offline()
|
||||
.parseEventPayload(payload.asReader(), GHEventPayload.WorkflowDispatch.class);
|
||||
|
||||
assertThat(workflowDispatchPayload.getRef(), is("refs/heads/main"));
|
||||
assertThat(workflowDispatchPayload.getAction(), is(nullValue()));
|
||||
assertThat(workflowDispatchPayload.getWorkflow(), is(".github/workflows/main.yml"));
|
||||
assertThat(workflowDispatchPayload.getInputs(), aMapWithSize(1));
|
||||
assertThat(workflowDispatchPayload.getInputs().keySet(), contains("logLevel"));
|
||||
assertThat(workflowDispatchPayload.getInputs().values(), contains("warning"));
|
||||
assertThat(workflowDispatchPayload.getRepository().getName(), is("quarkus-bot-java-playground"));
|
||||
assertThat(workflowDispatchPayload.getSender().getLogin(), is("gsmet"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void workflow_run() throws Exception {
|
||||
GHEventPayload.WorkflowRun workflowRunPayload = GitHub.offline()
|
||||
.parseEventPayload(payload.asReader(), GHEventPayload.WorkflowRun.class);
|
||||
|
||||
assertThat(workflowRunPayload.getAction(), is("completed"));
|
||||
assertThat(workflowRunPayload.getRepository().getFullName(), is("gsmet/quarkus-bot-java-playground"));
|
||||
assertThat(workflowRunPayload.getSender().getLogin(), is("gsmet"));
|
||||
|
||||
GHWorkflow workflow = workflowRunPayload.getWorkflow();
|
||||
assertThat(workflow.getId(), is(7087581L));
|
||||
assertThat(workflow.getName(), is("CI"));
|
||||
assertThat(workflow.getPath(), is(".github/workflows/main.yml"));
|
||||
assertThat(workflow.getState(), is("active"));
|
||||
assertThat(workflow.getUrl().toString(),
|
||||
is("https://api.github.com/repos/gsmet/quarkus-bot-java-playground/actions/workflows/7087581"));
|
||||
assertThat(workflow.getHtmlUrl().toString(),
|
||||
is("https://github.com/gsmet/quarkus-bot-java-playground/blob/main/.github/workflows/main.yml"));
|
||||
assertThat(workflow.getBadgeUrl().toString(),
|
||||
is("https://github.com/gsmet/quarkus-bot-java-playground/workflows/CI/badge.svg"));
|
||||
|
||||
GHWorkflowRun workflowRun = workflowRunPayload.getWorkflowRun();
|
||||
assertThat(workflowRun.getId(), is(680604745L));
|
||||
assertThat(workflowRun.getName(), is("CI"));
|
||||
assertThat(workflowRun.getHeadBranch(), is("main"));
|
||||
assertThat(workflowRun.getHeadSha(), is("dbea8d8b6ed2cf764dfd84a215f3f9040b3d4423"));
|
||||
assertThat(workflowRun.getRunNumber(), is(6L));
|
||||
assertThat(workflowRun.getEvent(), is(GHEvent.WORKFLOW_DISPATCH));
|
||||
assertThat(workflowRun.getStatus(), is(GHWorkflowRun.Status.COMPLETED));
|
||||
assertThat(workflowRun.getConclusion(), is(GHWorkflowRun.Conclusion.SUCCESS));
|
||||
assertThat(workflowRun.getWorkflowId(), is(7087581L));
|
||||
assertThat(workflowRun.getUrl().toString(),
|
||||
is("https://api.github.com/repos/gsmet/quarkus-bot-java-playground/actions/runs/680604745"));
|
||||
assertThat(workflowRun.getHtmlUrl().toString(),
|
||||
is("https://github.com/gsmet/quarkus-bot-java-playground/actions/runs/680604745"));
|
||||
assertThat(workflowRun.getJobsUrl().toString(),
|
||||
is("https://api.github.com/repos/gsmet/quarkus-bot-java-playground/actions/runs/680604745/jobs"));
|
||||
assertThat(workflowRun.getLogsUrl().toString(),
|
||||
is("https://api.github.com/repos/gsmet/quarkus-bot-java-playground/actions/runs/680604745/logs"));
|
||||
assertThat(workflowRun.getCheckSuiteUrl().toString(),
|
||||
is("https://api.github.com/repos/gsmet/quarkus-bot-java-playground/check-suites/2327154397"));
|
||||
assertThat(workflowRun.getArtifactsUrl().toString(),
|
||||
is("https://api.github.com/repos/gsmet/quarkus-bot-java-playground/actions/runs/680604745/artifacts"));
|
||||
assertThat(workflowRun.getCancelUrl().toString(),
|
||||
is("https://api.github.com/repos/gsmet/quarkus-bot-java-playground/actions/runs/680604745/cancel"));
|
||||
assertThat(workflowRun.getRerunUrl().toString(),
|
||||
is("https://api.github.com/repos/gsmet/quarkus-bot-java-playground/actions/runs/680604745/rerun"));
|
||||
assertThat(workflowRun.getWorkflowUrl().toString(),
|
||||
is("https://api.github.com/repos/gsmet/quarkus-bot-java-playground/actions/workflows/7087581"));
|
||||
assertThat(workflowRun.getCreatedAt().getTime(), is(1616524526000L));
|
||||
assertThat(workflowRun.getUpdatedAt().getTime(), is(1616524543000L));
|
||||
assertThat(workflowRun.getHeadCommit().getId(), is("dbea8d8b6ed2cf764dfd84a215f3f9040b3d4423"));
|
||||
assertThat(workflowRun.getHeadCommit().getTreeId(), is("b17089e6a2574ec1002566fe980923e62dce3026"));
|
||||
assertThat(workflowRun.getHeadCommit().getMessage(), is("Update main.yml"));
|
||||
assertThat(workflowRun.getHeadCommit().getTimestamp().getTime(), is(1616523390000L));
|
||||
assertThat(workflowRun.getHeadCommit().getAuthor().getName(), is("Guillaume Smet"));
|
||||
assertThat(workflowRun.getHeadCommit().getAuthor().getEmail(), is("guillaume.smet@gmail.com"));
|
||||
assertThat(workflowRun.getHeadCommit().getCommitter().getName(), is("GitHub"));
|
||||
assertThat(workflowRun.getHeadCommit().getCommitter().getEmail(), is("noreply@github.com"));
|
||||
assertThat(workflowRun.getHeadRepository().getFullName(), is("gsmet/quarkus-bot-java-playground"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void workflow_run_pull_request() throws Exception {
|
||||
GHEventPayload.WorkflowRun workflowRunPayload = GitHub.offline()
|
||||
.parseEventPayload(payload.asReader(), GHEventPayload.WorkflowRun.class);
|
||||
|
||||
List<GHPullRequest> pullRequests = workflowRunPayload.getWorkflowRun().getPullRequests();
|
||||
assertThat(pullRequests.size(), is(1));
|
||||
|
||||
GHPullRequest pullRequest = pullRequests.get(0);
|
||||
assertThat(pullRequest.getId(), is(599098265L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void workflow_run_other_repository() throws Exception {
|
||||
GHEventPayload.WorkflowRun workflowRunPayload = GitHub.offline()
|
||||
.parseEventPayload(payload.asReader(), GHEventPayload.WorkflowRun.class);
|
||||
GHWorkflowRun workflowRun = workflowRunPayload.getWorkflowRun();
|
||||
|
||||
assertThat(workflowRunPayload.getRepository().getFullName(), is("gsmet/quarkus-bot-java-playground"));
|
||||
assertThat(workflowRun.getHeadRepository().getFullName(),
|
||||
is("gsmet-bot-playground/quarkus-bot-java-playground"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public class GHIssueEventTest extends AbstractGitHubWireMockTest {
|
||||
GHIssue issue = builder.create();
|
||||
|
||||
// Generate some events.
|
||||
issue.addLabels("test-label");
|
||||
issue.setLabels("test-label");
|
||||
|
||||
// Test that the events are present.
|
||||
List<GHIssueEvent> list = issue.listEvents().toList();
|
||||
|
||||
@@ -79,9 +79,19 @@ public class GHLicenseTest extends AbstractGitHubWireMockTest {
|
||||
String key = "mit";
|
||||
GHLicense license = gitHub.getLicense(key);
|
||||
assertNotNull(license);
|
||||
assertTrue("The name is correct", license.getName().equals("MIT License"));
|
||||
assertTrue("The HTML URL is correct",
|
||||
license.getHtmlUrl().equals(new URL("http://choosealicense.com/licenses/mit/")));
|
||||
assertThat("The name is correct", license.getName(), equalTo("MIT License"));
|
||||
assertThat("The HTML URL is correct",
|
||||
license.getHtmlUrl(),
|
||||
equalTo(new URL("http://choosealicense.com/licenses/mit/")));
|
||||
assertThat(license.getBody(), startsWith("MIT License\n" + "\n" + "Copyright (c) [year] [fullname]\n\n"));
|
||||
assertThat(license.getForbidden().size(), equalTo(0));
|
||||
assertThat(license.getPermitted().size(), equalTo(0));
|
||||
assertThat(license.getImplementation(),
|
||||
equalTo("Create a text file (typically named LICENSE or LICENSE.txt) in the root of your source code and copy the text of the license into the file. Replace [year] with the current year and [fullname] with the name (or names) of the copyright holders."));
|
||||
assertThat(license.getCategory(), nullValue());
|
||||
assertThat(license.isFeatured(), equalTo(true));
|
||||
assertThat(license.equals(null), equalTo(false));
|
||||
assertThat(license.equals(gitHub.getLicense(key)), equalTo(true));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,11 +36,12 @@ public class GHOrganizationTest extends AbstractGitHubWireMockTest {
|
||||
cleanupRepository(GITHUB_API_TEST_ORG + '/' + GITHUB_API_TEST);
|
||||
|
||||
GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG);
|
||||
GHRepository repository = org.createRepository(GITHUB_API_TEST,
|
||||
"a test repository used to test kohsuke's github-api",
|
||||
"http://github-api.kohsuke.org/",
|
||||
"Core Developers",
|
||||
true);
|
||||
GHRepository repository = org.createRepository(GITHUB_API_TEST)
|
||||
.description("a test repository used to test kohsuke's github-api")
|
||||
.homepage("http://github-api.kohsuke.org/")
|
||||
.team(org.getTeamByName("Core Developers"))
|
||||
.private_(false)
|
||||
.create();
|
||||
Assert.assertNotNull(repository);
|
||||
}
|
||||
|
||||
@@ -72,7 +73,7 @@ public class GHOrganizationTest extends AbstractGitHubWireMockTest {
|
||||
.homepage("http://github-api.kohsuke.org/")
|
||||
.team(team)
|
||||
.autoInit(true)
|
||||
.templateRepository(true)
|
||||
.isTemplate(true)
|
||||
.create();
|
||||
Assert.assertNotNull(repository);
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(requestCount + 1));
|
||||
@@ -136,7 +137,7 @@ public class GHOrganizationTest extends AbstractGitHubWireMockTest {
|
||||
public void testListMembersWithFilter() throws IOException {
|
||||
GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG);
|
||||
|
||||
List<GHUser> admins = org.listMembersWithFilter("all").asList();
|
||||
List<GHUser> admins = org.listMembersWithFilter("all").toList();
|
||||
|
||||
assertNotNull(admins);
|
||||
assertTrue(admins.size() >= 12); // In case more are added in the future
|
||||
@@ -158,7 +159,7 @@ public class GHOrganizationTest extends AbstractGitHubWireMockTest {
|
||||
public void testListMembersWithRole() throws IOException {
|
||||
GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG);
|
||||
|
||||
List<GHUser> admins = org.listMembersWithRole("admin").asList();
|
||||
List<GHUser> admins = org.listMembersWithRole("admin").toList();
|
||||
|
||||
assertNotNull(admins);
|
||||
assertTrue(admins.size() >= 12); // In case more are added in the future
|
||||
|
||||
@@ -5,12 +5,18 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasProperty;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
@@ -112,28 +118,52 @@ public class GHPullRequestTest extends AbstractGitHubWireMockTest {
|
||||
public void pullRequestReviewComments() throws Exception {
|
||||
String name = "pullRequestReviewComments";
|
||||
GHPullRequest p = getRepository().createPullRequest(name, "test/stable", "master", "## test");
|
||||
// System.out.println(p.getUrl());
|
||||
assertTrue(p.listReviewComments().toList().isEmpty());
|
||||
p.createReviewComment("Sample review comment", p.getHead().getSha(), "README.md", 1);
|
||||
List<GHPullRequestReviewComment> comments = p.listReviewComments().toList();
|
||||
assertEquals(1, comments.size());
|
||||
GHPullRequestReviewComment comment = comments.get(0);
|
||||
assertEquals("Sample review comment", comment.getBody());
|
||||
try {
|
||||
// System.out.println(p.getUrl());
|
||||
assertTrue(p.listReviewComments().toList().isEmpty());
|
||||
p.createReviewComment("Sample review comment", p.getHead().getSha(), "README.md", 1);
|
||||
List<GHPullRequestReviewComment> comments = p.listReviewComments().toList();
|
||||
assertEquals(1, comments.size());
|
||||
GHPullRequestReviewComment comment = comments.get(0);
|
||||
assertEquals("Sample review comment", comment.getBody());
|
||||
assertThat(comment.getInReplyToId(), equalTo(-1L));
|
||||
assertThat(comment.getPath(), equalTo("README.md"));
|
||||
assertThat(comment.getPosition(), equalTo(1));
|
||||
assertThat(comment.getUser(), notNullValue());
|
||||
// Assert htmlUrl is not null
|
||||
assertThat(comment.getHtmlUrl(), notNullValue());
|
||||
assertThat(comment.getHtmlUrl().toString(),
|
||||
containsString("hub4j-test-org/github-api/pull/" + p.getNumber()));
|
||||
|
||||
// Assert htmlUrl is not null
|
||||
assertNotNull(comment.getHtmlUrl());
|
||||
assertEquals(new URL("https://github.com/hub4j-test-org/github-api/pull/266#discussion_r321995146"),
|
||||
comment.getHtmlUrl());
|
||||
List<GHReaction> reactions = comment.listReactions().toList();
|
||||
assertThat(reactions.size(), equalTo(0));
|
||||
|
||||
comment.update("Updated review comment");
|
||||
comments = p.listReviewComments().toList();
|
||||
assertEquals(1, comments.size());
|
||||
comment = comments.get(0);
|
||||
assertEquals("Updated review comment", comment.getBody());
|
||||
GHReaction reaction = comment.createReaction(ReactionContent.CONFUSED);
|
||||
assertThat(reaction.getContent(), equalTo(ReactionContent.CONFUSED));
|
||||
|
||||
comment.delete();
|
||||
comments = p.listReviewComments().toList();
|
||||
assertTrue(comments.isEmpty());
|
||||
reactions = comment.listReactions().toList();
|
||||
assertThat(reactions.size(), equalTo(1));
|
||||
|
||||
GHPullRequestReviewComment reply = comment.reply("This is a reply.");
|
||||
assertThat(reply.getInReplyToId(), equalTo(comment.getId()));
|
||||
comments = p.listReviewComments().toList();
|
||||
|
||||
assertEquals(2, comments.size());
|
||||
|
||||
comment.update("Updated review comment");
|
||||
comments = p.listReviewComments().toList();
|
||||
comment = comments.get(0);
|
||||
assertEquals("Updated review comment", comment.getBody());
|
||||
|
||||
comment.delete();
|
||||
comments = p.listReviewComments().toList();
|
||||
// Reply is still present after delete of original comment, but no longer has replyToId
|
||||
assertThat(comments.size(), equalTo(1));
|
||||
assertThat(comments.get(0).getId(), equalTo(reply.getId()));
|
||||
assertThat(comments.get(0).getInReplyToId(), equalTo(-1L));
|
||||
} finally {
|
||||
p.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -395,7 +425,93 @@ public class GHPullRequestTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
Collection<GHLabel> labels = getRepository().getPullRequest(p.getNumber()).getLabels();
|
||||
assertEquals(1, labels.size());
|
||||
assertEquals(label, labels.iterator().next().getName());
|
||||
GHLabel savedLabel = labels.iterator().next();
|
||||
assertEquals(label, savedLabel.getName());
|
||||
assertNotNull(savedLabel.getId());
|
||||
assertNotNull(savedLabel.getNodeId());
|
||||
assertFalse(savedLabel.isDefault());
|
||||
}
|
||||
|
||||
@Test
|
||||
// Requires push access to the test repo to pass
|
||||
public void addLabels() throws Exception {
|
||||
GHPullRequest p = getRepository().createPullRequest("addLabels", "test/stable", "master", "## test");
|
||||
String addedLabel1 = "addLabels_label_name_1";
|
||||
String addedLabel2 = "addLabels_label_name_2";
|
||||
String addedLabel3 = "addLabels_label_name_3";
|
||||
|
||||
p.addLabels(addedLabel1);
|
||||
|
||||
int requestCount = mockGitHub.getRequestCount();
|
||||
p.addLabels(addedLabel2, addedLabel3);
|
||||
// multiple labels can be added with one api call
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(requestCount + 1));
|
||||
|
||||
Collection<GHLabel> labels = getRepository().getPullRequest(p.getNumber()).getLabels();
|
||||
assertEquals(3, labels.size());
|
||||
assertThat(labels,
|
||||
containsInAnyOrder(hasProperty("name", equalTo(addedLabel1)),
|
||||
hasProperty("name", equalTo(addedLabel2)),
|
||||
hasProperty("name", equalTo(addedLabel3))));
|
||||
|
||||
// Adding a label which is already present does not throw an error
|
||||
p.addLabels(addedLabel1);
|
||||
}
|
||||
|
||||
@Test
|
||||
// Requires push access to the test repo to pass
|
||||
public void addLabelsConcurrencyIssue() throws Exception {
|
||||
String addedLabel1 = "addLabelsConcurrencyIssue_label_name_1";
|
||||
String addedLabel2 = "addLabelsConcurrencyIssue_label_name_2";
|
||||
|
||||
GHPullRequest p1 = getRepository()
|
||||
.createPullRequest("addLabelsConcurrencyIssue", "test/stable", "master", "## test");
|
||||
p1.getLabels();
|
||||
|
||||
GHPullRequest p2 = getRepository().getPullRequest(p1.getNumber());
|
||||
p2.addLabels(addedLabel2);
|
||||
|
||||
p1.addLabels(addedLabel1);
|
||||
|
||||
Collection<GHLabel> labels = getRepository().getPullRequest(p1.getNumber()).getLabels();
|
||||
assertEquals(2, labels.size());
|
||||
assertThat(labels,
|
||||
containsInAnyOrder(hasProperty("name", equalTo(addedLabel1)),
|
||||
hasProperty("name", equalTo(addedLabel2))));
|
||||
}
|
||||
|
||||
@Test
|
||||
// Requires push access to the test repo to pass
|
||||
public void removeLabels() throws Exception {
|
||||
GHPullRequest p = getRepository().createPullRequest("removeLabels", "test/stable", "master", "## test");
|
||||
String label1 = "removeLabels_label_name_1";
|
||||
String label2 = "removeLabels_label_name_2";
|
||||
String label3 = "removeLabels_label_name_3";
|
||||
p.setLabels(label1, label2, label3);
|
||||
|
||||
Collection<GHLabel> labels = getRepository().getPullRequest(p.getNumber()).getLabels();
|
||||
assertEquals(3, labels.size());
|
||||
|
||||
int requestCount = mockGitHub.getRequestCount();
|
||||
p.removeLabels(label2, label3);
|
||||
// each label deleted is a separate api call
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(requestCount + 2));
|
||||
|
||||
labels = getRepository().getPullRequest(p.getNumber()).getLabels();
|
||||
assertEquals(1, labels.size());
|
||||
assertEquals(label1, labels.iterator().next().getName());
|
||||
|
||||
// Removing some labels that are not present does not throw
|
||||
// This is consistent with earlier behavior and with addLabels()
|
||||
p.removeLabels(label3);
|
||||
|
||||
// Calling removeLabel() on label that is not present will throw
|
||||
try {
|
||||
p.removeLabel(label3);
|
||||
fail("Expected GHFileNotFoundException");
|
||||
} catch (GHFileNotFoundException e) {
|
||||
assertThat(e.getMessage(), containsString("Label does not exist"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -412,15 +528,15 @@ public class GHPullRequestTest extends AbstractGitHubWireMockTest {
|
||||
public void getUserTest() throws IOException {
|
||||
GHPullRequest p = getRepository().createPullRequest("getUserTest", "test/stable", "master", "## test");
|
||||
GHPullRequest prSingle = getRepository().getPullRequest(p.getNumber());
|
||||
assertNotNull(prSingle.getUser().root);
|
||||
assertNotNull(prSingle.getUser().getRoot());
|
||||
prSingle.getMergeable();
|
||||
assertNotNull(prSingle.getUser().root);
|
||||
assertNotNull(prSingle.getUser().getRoot());
|
||||
|
||||
PagedIterable<GHPullRequest> ghPullRequests = getRepository().listPullRequests(GHIssueState.OPEN);
|
||||
for (GHPullRequest pr : ghPullRequests) {
|
||||
assertNotNull(pr.getUser().root);
|
||||
assertNotNull(pr.getUser().getRoot());
|
||||
pr.getMergeable();
|
||||
assertNotNull(pr.getUser().root);
|
||||
assertNotNull(pr.getUser().getRoot());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -312,9 +312,6 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
// Give this a moment
|
||||
Thread.sleep(1500);
|
||||
|
||||
// lastRateLimit the same as rateLimit
|
||||
assertThat(gitHub.lastRateLimit(), sameInstance(rateLimit));
|
||||
|
||||
// ratelimit() tries not to make additional requests, uses queried rate limit since header not available
|
||||
Thread.sleep(1500);
|
||||
assertThat(gitHub.rateLimit(), sameInstance(rateLimit));
|
||||
@@ -490,9 +487,6 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
assertThat("rateLimit() selects header instance when not expired, does not ask server",
|
||||
gitHub.rateLimit(),
|
||||
sameInstance(headerRateLimit));
|
||||
assertThat("lastRateLimit() always selects header instance, does not ask server",
|
||||
gitHub.lastRateLimit(),
|
||||
sameInstance(headerRateLimit));
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(1));
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ public class GHRepositoryStatisticsTest extends AbstractGitHubWireMockTest {
|
||||
for (GHRepositoryStatistics.ContributorStats statsForAuthor : list) {
|
||||
if (authorLogin.equals(statsForAuthor.getAuthor().getLogin())) {
|
||||
assertEquals(715, statsForAuthor.getTotal());
|
||||
assertEquals("kohsuke made 715 contributions over 494 weeks", statsForAuthor.toString());
|
||||
|
||||
List<GHRepositoryStatistics.ContributorStats.Week> weeks = statsForAuthor.getWeeks();
|
||||
assertEquals(494, weeks.size());
|
||||
@@ -46,6 +47,8 @@ public class GHRepositoryStatisticsTest extends AbstractGitHubWireMockTest {
|
||||
assertEquals(63, week.getNumberOfAdditions());
|
||||
assertEquals(56, week.getNumberOfDeletions());
|
||||
assertEquals(5, week.getNumberOfCommits());
|
||||
assertEquals("Week starting 1541289600 - Additions: 63, Deletions: 56, Commits: 5",
|
||||
week.toString());
|
||||
} catch (NoSuchElementException e) {
|
||||
fail("Did not find week 1546128000");
|
||||
}
|
||||
@@ -131,6 +134,7 @@ public class GHRepositoryStatisticsTest extends AbstractGitHubWireMockTest {
|
||||
if (item.getWeekTimestamp() == 1535241600) {
|
||||
assertEquals(185, item.getAdditions());
|
||||
assertEquals(-243, item.getDeletions());
|
||||
assertEquals("Week starting 1535241600 has 185 additions and 243 deletions", item.toString());
|
||||
foundWeek = true;
|
||||
break;
|
||||
}
|
||||
@@ -196,6 +200,7 @@ public class GHRepositoryStatisticsTest extends AbstractGitHubWireMockTest {
|
||||
// TODO: Make an easier access method. Perhaps wrap in an
|
||||
// object and have a method such as GetCommits(1, 16).
|
||||
assertEquals(16, item.getNumberOfCommits());
|
||||
assertEquals("Day 2 Hour 10: 16 commits", item.toString());
|
||||
hourFound = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3,11 +3,16 @@ package org.kohsuke.github;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.Test;
|
||||
import org.kohsuke.github.GHCheckRun.Conclusion;
|
||||
import org.kohsuke.github.GHRepository.Visibility;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -28,6 +33,20 @@ public class GHRepositoryTest extends AbstractGitHubWireMockTest {
|
||||
return gitHub.getOrganization("hub4j-test-org").getRepository("github-api");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZipball() throws IOException {
|
||||
getTempRepository().readZip((InputStream inputstream) -> {
|
||||
return new ByteArrayInputStream(IOUtils.toByteArray(inputstream));
|
||||
}, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTarball() throws IOException {
|
||||
getTempRepository().readTar((InputStream inputstream) -> {
|
||||
return new ByteArrayInputStream(IOUtils.toByteArray(inputstream));
|
||||
}, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetters() throws IOException {
|
||||
GHRepository r = getTempRepository();
|
||||
@@ -110,6 +129,19 @@ public class GHRepositoryTest extends AbstractGitHubWireMockTest {
|
||||
assertEquals(UNKNOWN_SIGNATURE_TYPE, verification.getReason());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listStargazers() throws IOException {
|
||||
GHRepository repository = getRepository();
|
||||
assertThat(repository.listStargazers2().toList(), empty());
|
||||
|
||||
repository = gitHub.getOrganization("hub4j").getRepository("github-api");
|
||||
Iterable<GHStargazer> stargazers = repository.listStargazers2();
|
||||
GHStargazer stargazer = stargazers.iterator().next();
|
||||
assertThat(stargazer.getStarredAt(), equalTo(new Date(1271650383000L)));
|
||||
assertThat(stargazer.getUser().getLogin(), equalTo("nielswind"));
|
||||
assertThat(stargazer.getRepository(), sameInstance(repository));
|
||||
}
|
||||
|
||||
// Issue #607
|
||||
@Test
|
||||
public void getBranchNonExistentBut200Status() throws Exception {
|
||||
@@ -135,11 +167,20 @@ public class GHRepositoryTest extends AbstractGitHubWireMockTest {
|
||||
public void subscription() throws Exception {
|
||||
GHRepository r = getRepository();
|
||||
assertNull(r.getSubscription());
|
||||
|
||||
GHSubscription s = r.subscribe(true, false);
|
||||
assertEquals(s.getRepository(), r);
|
||||
try {
|
||||
|
||||
s.delete();
|
||||
assertEquals(s.getRepository(), r);
|
||||
assertThat(s.isIgnored(), equalTo(false));
|
||||
assertThat(s.isSubscribed(), equalTo(true));
|
||||
assertThat(s.getRepositoryUrl().toString(), containsString("/repos/hub4j-test-org/github-api"));
|
||||
assertThat(s.getUrl().toString(), containsString("/repos/hub4j-test-org/github-api/subscription"));
|
||||
|
||||
assertThat(s.getReason(), nullValue());
|
||||
assertThat(s.getCreatedAt(), equalTo(new Date(1611377286000L)));
|
||||
} finally {
|
||||
s.delete();
|
||||
}
|
||||
|
||||
assertNull(r.getSubscription());
|
||||
}
|
||||
@@ -209,6 +250,30 @@ public class GHRepositoryTest extends AbstractGitHubWireMockTest {
|
||||
assertThat(redux.getDescription(), equalTo(updatedDescription));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRepositoryWithVisibility() throws IOException {
|
||||
snapshotNotAllowed();
|
||||
final String repoName = "test-repo-visibility";
|
||||
final GHRepository repo = getTempRepository(repoName);
|
||||
assertEquals(Visibility.PUBLIC, repo.getVisibility());
|
||||
|
||||
repo.setVisibility(Visibility.INTERNAL);
|
||||
assertEquals(Visibility.INTERNAL,
|
||||
gitHub.getRepository(repo.getOwnerName() + "/" + repo.getName()).getVisibility());
|
||||
|
||||
repo.setVisibility(Visibility.PRIVATE);
|
||||
assertEquals(Visibility.PRIVATE,
|
||||
gitHub.getRepository(repo.getOwnerName() + "/" + repo.getName()).getVisibility());
|
||||
|
||||
repo.setVisibility(Visibility.PUBLIC);
|
||||
assertEquals(Visibility.PUBLIC,
|
||||
gitHub.getRepository(repo.getOwnerName() + "/" + repo.getName()).getVisibility());
|
||||
|
||||
// deliberately bogus response in snapshot
|
||||
assertEquals(Visibility.UNKNOWN,
|
||||
gitHub.getRepository(repo.getOwnerName() + "/" + repo.getName()).getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listContributors() throws IOException {
|
||||
GHRepository r = gitHub.getOrganization("hub4j").getRepository("github-api");
|
||||
@@ -641,17 +706,6 @@ public class GHRepositoryTest extends AbstractGitHubWireMockTest {
|
||||
assertThat(e, instanceOf(GHFileNotFoundException.class));
|
||||
assertThat(e.getMessage(), containsString("/repos/hub4j-test-org/temp-listRefsEmptyTags/git/refs/tags"));
|
||||
}
|
||||
|
||||
try {
|
||||
GHRepository repo = getTempRepository();
|
||||
repo.listRefs("tags").asList();
|
||||
fail();
|
||||
} catch (Exception e) {
|
||||
assertThat(e, instanceOf(GHException.class));
|
||||
assertThat(e.getMessage(), containsString("Failed to retrieve "));
|
||||
assertThat(e.getMessage(), containsString("/repos/hub4j-test-org/temp-listRefsEmptyTags/git/refs/tags"));
|
||||
assertThat(e.getCause(), instanceOf(GHFileNotFoundException.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -715,7 +769,7 @@ public class GHRepositoryTest extends AbstractGitHubWireMockTest {
|
||||
// Check if the checkruns are all succeeded and if we got all of them
|
||||
int checkRunsCount = 0;
|
||||
for (GHCheckRun checkRun : checkRuns) {
|
||||
assertThat(checkRun.getConclusion(), equalTo("success"));
|
||||
assertThat(checkRun.getConclusion(), equalTo(Conclusion.SUCCESS));
|
||||
checkRunsCount++;
|
||||
}
|
||||
assertThat(checkRunsCount, equalTo(expectedCount));
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
@@ -49,6 +50,10 @@ public class GHTagTest extends AbstractGitHubWireMockTest {
|
||||
assertEquals(commitSha, tag.getObject().getSha());
|
||||
assertFalse(tag.getVerification().isVerified());
|
||||
assertEquals(tag.getVerification().getReason(), GHVerification.Reason.UNSIGNED);
|
||||
assertThat(tag.getUrl(),
|
||||
containsString("/repos/hub4j-test-org/github-api/git/tags/e7aa6d4afbaa48669f0bbe11ca3c4d787b2b153c"));
|
||||
assertThat(tag.getOwner().getId(), equalTo(repo.getId()));
|
||||
assertThat(tag.getTagger().getEmail(), equalTo("martin.vanzijl@gmail.com"));
|
||||
|
||||
// Make a reference to the newly created tag.
|
||||
GHRef ref = repo.createRef("refs/tags/" + tagName, tag.getSha());
|
||||
|
||||
@@ -41,7 +41,7 @@ public class GHTeamTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
GHTeam team = gitHub.getOrganization(GITHUB_API_TEST_ORG).getTeamBySlug(teamSlug);
|
||||
|
||||
List<GHUser> admins = team.listMembers("admin").asList();
|
||||
List<GHUser> admins = team.listMembers("admin").toList();
|
||||
|
||||
assertNotNull(admins);
|
||||
assertThat("One admin in dummy team", admins.size() == 1);
|
||||
@@ -55,7 +55,7 @@ public class GHTeamTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
GHTeam team = gitHub.getOrganization(GITHUB_API_TEST_ORG).getTeamBySlug(teamSlug);
|
||||
|
||||
List<GHUser> justMembers = team.listMembers("member").asList();
|
||||
List<GHUser> justMembers = team.listMembers("member").toList();
|
||||
|
||||
assertThat("No regular members in team", justMembers.isEmpty());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,9 @@ import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class GHTreeBuilderTest extends AbstractGitHubWireMockTest {
|
||||
@@ -87,22 +89,30 @@ public class GHTreeBuilderTest extends AbstractGitHubWireMockTest {
|
||||
treeBuilder.add(PATH_DATA1, CONTENT_DATA1, false);
|
||||
treeBuilder.add(PATH_DATA2, CONTENT_DATA2, false);
|
||||
|
||||
updateTree();
|
||||
GHCommit commit = updateTree();
|
||||
|
||||
assertEquals(CONTENT_SCRIPT.length(), getFileSize(PATH_SCRIPT));
|
||||
assertEquals(CONTENT_README.length(), getFileSize(PATH_README));
|
||||
assertEquals(CONTENT_DATA1.length, getFileSize(PATH_DATA1));
|
||||
assertEquals(CONTENT_DATA2.length, getFileSize(PATH_DATA2));
|
||||
|
||||
assertThat(commit.getCommitShortInfo().getAuthor().getEmail(), equalTo("author@author.com"));
|
||||
assertThat(commit.getCommitShortInfo().getCommitter().getEmail(), equalTo("committer@committer.com"));
|
||||
|
||||
}
|
||||
|
||||
private void updateTree() throws IOException {
|
||||
private GHCommit updateTree() throws IOException {
|
||||
String treeSha = treeBuilder.create().getSha();
|
||||
String commitSha = new GHCommitBuilder(repo).message("Add files")
|
||||
GHCommit commit = new GHCommitBuilder(repo).message("Add files")
|
||||
.tree(treeSha)
|
||||
.author("author", "author@author.com", new Date(1611433225969L))
|
||||
.committer("committer", "committer@committer.com", new Date(1611433225968L))
|
||||
.parent(masterRef.getObject().getSha())
|
||||
.create()
|
||||
.getSHA1();
|
||||
.create();
|
||||
|
||||
String commitSha = commit.getSHA1();
|
||||
masterRef.updateTo(commitSha);
|
||||
return commit;
|
||||
}
|
||||
|
||||
private long getFileSize(String path) throws IOException {
|
||||
|
||||
@@ -39,14 +39,27 @@ public class GHUserTest extends AbstractGitHubWireMockTest {
|
||||
}
|
||||
});
|
||||
assertEquals(1066173, ghKeys.get(0).getId());
|
||||
assertThat(ghKeys.get(0).getTitle(), nullValue());
|
||||
assertThat(ghKeys.get(0).getUrl(), nullValue());
|
||||
assertThat(ghKeys.get(0).isVerified(), equalTo(false));
|
||||
assertThat(ghKeys.get(0).toString(),
|
||||
containsString(
|
||||
"title=<null>,id=1066173,key=ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAueiy12T5bvFhsc9YjfLc3aVIxgySd3gDxQWy/bletIoZL8omKmzocBYJ7F58U1asoyfWsy2ToTOY8jJp1eToXmbD6L5+xvHba0A7djYh9aQRrFam7doKQ0zp0ZSUF6+R1v0OM4nnWqK4n2ECIYd+Bdzrp+xA5+XlW3ZSNzlnW2BeWznzmgRMcp6wI+zQ9GMHWviR1cxpml5Z6wrxTZ0aX91btvnNPqoOGva976B6e6403FOEkkIFTk6CC1TFKwc/VjbqxYBg4kU0JhiTP+iEZibcQrYjWdYUgAotYbFVe5/DneHMLNsMPdeihba4PUwt62rXyNegenuCRmCntLcaFQ=="));
|
||||
|
||||
assertEquals(
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAueiy12T5bvFhsc9YjfLc3aVIxgySd3gDxQWy/bletIoZL8omKmzocBYJ7F58U1asoyfWsy2ToTOY8jJp1eToXmbD6L5+xvHba0A7djYh9aQRrFam7doKQ0zp0ZSUF6+R1v0OM4nnWqK4n2ECIYd+Bdzrp+xA5+XlW3ZSNzlnW2BeWznzmgRMcp6wI+zQ9GMHWviR1cxpml5Z6wrxTZ0aX91btvnNPqoOGva976B6e6403FOEkkIFTk6CC1TFKwc/VjbqxYBg4kU0JhiTP+iEZibcQrYjWdYUgAotYbFVe5/DneHMLNsMPdeihba4PUwt62rXyNegenuCRmCntLcaFQ==",
|
||||
ghKeys.get(0).getKey());
|
||||
assertEquals(28136459, ghKeys.get(1).getId());
|
||||
assertThat(ghKeys.get(1).getTitle(), nullValue());
|
||||
assertThat(ghKeys.get(1).getUrl(), nullValue());
|
||||
assertThat(ghKeys.get(1).isVerified(), equalTo(false));
|
||||
assertEquals(
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDTU0s5OKCC6VpKZGL9NJD4mNLY0AtujkVB1JkkuQ4OkMi2YGUHJtGhTbTwEVhNxpm0x2dM5KSzse6MLDYuGBW0qkE/VVuD9+9I73hbq461KqP0+WlupNh+Qc86kbiLBDv64+vWc+50mp1dbINpoM5xvaPYxgjnemydPv7vu5bhCHBugW7aN8VcLgfFgcp8vZCEanMtd3hIRjRU8v8Skk233ZGu1bXkG8iIOBQPabvEtZ0VDMg9pT3Q1R6lnnKqfCwHXd6zP6uAtejFSxvKRGKpu3OLGQMHwk7NlImVuhkVdaEFBq7pQtpOaGuP2eLKcN1wy5jsTYE+ZB6pvHCi2ecb",
|
||||
ghKeys.get(1).getKey());
|
||||
assertEquals(31452581, ghKeys.get(2).getId());
|
||||
assertThat(ghKeys.get(2).getTitle(), nullValue());
|
||||
assertThat(ghKeys.get(2).getUrl(), nullValue());
|
||||
assertThat(ghKeys.get(2).isVerified(), equalTo(false));
|
||||
assertEquals(
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC3JhH2FZBDmHLjXTcBoV6tdcYKmsQ7sgu8k1RsUhwxGsXm65+Cuas6GcMVoA1DncKfJGQkulHDFiTxIROIBmedh9/otHWBlZ4HqYZ4MQ1A8W5quULkXwX/kF+UdRBUxFvjigibEbuHB+LARVxRRzFlPnTSE9rAfAv8OOEsb3lNUGT/IGhN8w1vwe8GclB90tgqN1RBDgrVqwLFwn5AfrW9kUIa2f2oT4RjYu1OrhKhVIIzfHADo85aD+s8wEhqwI96BCJG3qTWrypoHwBUoj1O6Ak5CGc1iKz9o8XyTMjudRt2ddCjfOtxsuwSlTbVtQXJGIpgKviX1sgh4pPvGh7BVAFP+mdAK4F+mEugDnuj47GO/K5KGGDRCL56kh9+h28l4q/+fZvp7DhtmSN2EzrVAdQFskF8yY/6Xit/aAvjeKm03DcjbylSXbG26EJefaLHlwYFq2mUFRMak25wuuCZS71GF3RC3Sl/bMoxBKRYkyfYtGafeaYTFNGn8Dbd+hfVUCz31ebI8cvmlQR5b5AbCre3T7HTVgw8FKbAxWRf1Fio56PnqHsj+sT1KVj255Zo1F8iD9GrgERSVAlkh5bY/CKszQ8ZSd01c9Qp2a47/gR7XAAbxhzGHP+cSOlrqDlJ24fbPtcpVsM0llqKUcxpmoOBFNboRmE1QqnSmAf9ww==",
|
||||
ghKeys.get(2).getKey());
|
||||
@@ -109,5 +122,11 @@ public class GHUserTest extends AbstractGitHubWireMockTest {
|
||||
assertThat(u.getBio(), equalTo("I like to program things and I hope to program something cool one day :D"));
|
||||
assertTrue(u.isHireable());
|
||||
assertNotNull(u.getTwitterUsername());
|
||||
assertThat(u.getBlog(), equalTo("https://chew.pw"));
|
||||
assertThat(u.getCompany(), equalTo("@Memerator"));
|
||||
assertThat(u.getFollowersCount(), equalTo(29));
|
||||
assertThat(u.getFollowingCount(), equalTo(3));
|
||||
assertThat(u.getPublicGistCount(), equalTo(4));
|
||||
assertThat(u.getPublicRepoCount(), equalTo(96));
|
||||
}
|
||||
}
|
||||
|
||||
506
src/test/java/org/kohsuke/github/GHWorkflowRunTest.java
Normal file
506
src/test/java/org/kohsuke/github/GHWorkflowRunTest.java
Normal file
@@ -0,0 +1,506 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import org.awaitility.Awaitility;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.kohsuke.github.GHWorkflowJob.Step;
|
||||
import org.kohsuke.github.GHWorkflowRun.Conclusion;
|
||||
import org.kohsuke.github.GHWorkflowRun.Status;
|
||||
import org.kohsuke.github.function.InputStreamFunction;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Scanner;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.hasItems;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
public class GHWorkflowRunTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
private static final String REPO_NAME = "hub4j-test-org/GHWorkflowRunTest";
|
||||
private static final String MAIN_BRANCH = "main";
|
||||
private static final String SECOND_BRANCH = "second-branch";
|
||||
|
||||
private static final String FAST_WORKFLOW_PATH = "fast-workflow.yml";
|
||||
private static final String FAST_WORKFLOW_NAME = "Fast workflow";
|
||||
|
||||
private static final String SLOW_WORKFLOW_PATH = "slow-workflow.yml";
|
||||
private static final String SLOW_WORKFLOW_NAME = "Slow workflow";
|
||||
|
||||
private static final String ARTIFACTS_WORKFLOW_PATH = "artifacts-workflow.yml";
|
||||
private static final String ARTIFACTS_WORKFLOW_NAME = "Artifacts workflow";
|
||||
|
||||
private static final String MULTI_JOBS_WORKFLOW_PATH = "multi-jobs-workflow.yml";
|
||||
private static final String MULTI_JOBS_WORKFLOW_NAME = "Multi jobs workflow";
|
||||
private static final String RUN_A_ONE_LINE_SCRIPT_STEP_NAME = "Run a one-line script";
|
||||
|
||||
private GHRepository repo;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
repo = gitHub.getRepository(REPO_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManualRunAndBasicInformation() throws IOException {
|
||||
GHWorkflow workflow = repo.getWorkflow(FAST_WORKFLOW_PATH);
|
||||
|
||||
long latestPreexistingWorkflowRunId = getLatestPreexistingWorkflowRunId();
|
||||
|
||||
workflow.dispatch(MAIN_BRANCH);
|
||||
|
||||
await((nonRecordingRepo) -> getWorkflowRun(nonRecordingRepo,
|
||||
FAST_WORKFLOW_NAME,
|
||||
MAIN_BRANCH,
|
||||
Status.COMPLETED,
|
||||
latestPreexistingWorkflowRunId).isPresent());
|
||||
|
||||
GHWorkflowRun workflowRun = getWorkflowRun(FAST_WORKFLOW_NAME,
|
||||
MAIN_BRANCH,
|
||||
Status.COMPLETED,
|
||||
latestPreexistingWorkflowRunId).orElseThrow(
|
||||
() -> new IllegalStateException("We must have a valid workflow run starting from here"));
|
||||
|
||||
assertEquals(workflow.getId(), workflowRun.getWorkflowId());
|
||||
assertNotNull(workflowRun.getId());
|
||||
assertNotNull(workflowRun.getNodeId());
|
||||
assertEquals(REPO_NAME, workflowRun.getRepository().getFullName());
|
||||
assertTrue(workflowRun.getUrl().getPath().contains("/actions/runs/"));
|
||||
assertTrue(workflowRun.getHtmlUrl().getPath().contains("/actions/runs/"));
|
||||
assertTrue(workflowRun.getJobsUrl().getPath().endsWith("/jobs"));
|
||||
assertTrue(workflowRun.getLogsUrl().getPath().endsWith("/logs"));
|
||||
assertTrue(workflowRun.getCheckSuiteUrl().getPath().contains("/check-suites/"));
|
||||
assertTrue(workflowRun.getArtifactsUrl().getPath().endsWith("/artifacts"));
|
||||
assertTrue(workflowRun.getCancelUrl().getPath().endsWith("/cancel"));
|
||||
assertTrue(workflowRun.getRerunUrl().getPath().endsWith("/rerun"));
|
||||
assertTrue(workflowRun.getWorkflowUrl().getPath().contains("/actions/workflows/"));
|
||||
assertEquals(MAIN_BRANCH, workflowRun.getHeadBranch());
|
||||
assertNotNull(workflowRun.getHeadCommit().getId());
|
||||
assertNotNull(workflowRun.getHeadCommit().getTreeId());
|
||||
assertNotNull(workflowRun.getHeadCommit().getMessage());
|
||||
assertNotNull(workflowRun.getHeadCommit().getTimestamp());
|
||||
assertNotNull(workflowRun.getHeadCommit().getAuthor().getEmail());
|
||||
assertNotNull(workflowRun.getHeadCommit().getCommitter().getEmail());
|
||||
assertEquals(GHEvent.WORKFLOW_DISPATCH, workflowRun.getEvent());
|
||||
assertEquals(Status.COMPLETED, workflowRun.getStatus());
|
||||
assertEquals(Conclusion.SUCCESS, workflowRun.getConclusion());
|
||||
assertNotNull(workflowRun.getHeadSha());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelAndRerun() throws IOException {
|
||||
GHWorkflow workflow = repo.getWorkflow(SLOW_WORKFLOW_PATH);
|
||||
|
||||
long latestPreexistingWorkflowRunId = getLatestPreexistingWorkflowRunId();
|
||||
|
||||
workflow.dispatch(MAIN_BRANCH);
|
||||
|
||||
// now that we have triggered the workflow run, we will wait until it's in progress and then cancel it
|
||||
await((nonRecordingRepo) -> getWorkflowRun(nonRecordingRepo,
|
||||
SLOW_WORKFLOW_NAME,
|
||||
MAIN_BRANCH,
|
||||
Status.IN_PROGRESS,
|
||||
latestPreexistingWorkflowRunId).isPresent());
|
||||
|
||||
GHWorkflowRun workflowRun = getWorkflowRun(SLOW_WORKFLOW_NAME,
|
||||
MAIN_BRANCH,
|
||||
Status.IN_PROGRESS,
|
||||
latestPreexistingWorkflowRunId).orElseThrow(
|
||||
() -> new IllegalStateException("We must have a valid workflow run starting from here"));
|
||||
|
||||
assertNotNull(workflowRun.getId());
|
||||
|
||||
workflowRun.cancel();
|
||||
long cancelledWorkflowRunId = workflowRun.getId();
|
||||
|
||||
// let's wait until it's completed
|
||||
await((nonRecordingRepo) -> getWorkflowRunStatus(nonRecordingRepo, cancelledWorkflowRunId) == Status.COMPLETED);
|
||||
|
||||
// let's check that it has been properly cancelled
|
||||
workflowRun = repo.getWorkflowRun(cancelledWorkflowRunId);
|
||||
assertEquals(Conclusion.CANCELLED, workflowRun.getConclusion());
|
||||
|
||||
// now let's rerun it
|
||||
workflowRun.rerun();
|
||||
|
||||
// let's check that it has been rerun
|
||||
await((nonRecordingRepo) -> getWorkflowRunStatus(nonRecordingRepo,
|
||||
cancelledWorkflowRunId) == Status.IN_PROGRESS);
|
||||
|
||||
// cancel it again
|
||||
workflowRun.cancel();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete() throws IOException {
|
||||
GHWorkflow workflow = repo.getWorkflow(FAST_WORKFLOW_PATH);
|
||||
|
||||
long latestPreexistingWorkflowRunId = getLatestPreexistingWorkflowRunId();
|
||||
|
||||
workflow.dispatch(MAIN_BRANCH);
|
||||
|
||||
await((nonRecordingRepo) -> getWorkflowRun(nonRecordingRepo,
|
||||
FAST_WORKFLOW_NAME,
|
||||
MAIN_BRANCH,
|
||||
Status.COMPLETED,
|
||||
latestPreexistingWorkflowRunId).isPresent());
|
||||
|
||||
GHWorkflowRun workflowRunToDelete = getWorkflowRun(FAST_WORKFLOW_NAME,
|
||||
MAIN_BRANCH,
|
||||
Status.COMPLETED,
|
||||
latestPreexistingWorkflowRunId).orElseThrow(
|
||||
() -> new IllegalStateException("We must have a valid workflow run starting from here"));
|
||||
|
||||
assertNotNull(workflowRunToDelete.getId());
|
||||
|
||||
workflowRunToDelete.delete();
|
||||
|
||||
try {
|
||||
repo.getWorkflowRun(workflowRunToDelete.getId());
|
||||
Assert.fail("The workflow " + workflowRunToDelete.getId() + " should have been deleted.");
|
||||
} catch (GHFileNotFoundException e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchOnBranch() throws IOException {
|
||||
GHWorkflow workflow = repo.getWorkflow(FAST_WORKFLOW_PATH);
|
||||
|
||||
long latestPreexistingWorkflowRunId = getLatestPreexistingWorkflowRunId();
|
||||
|
||||
workflow.dispatch(SECOND_BRANCH);
|
||||
|
||||
await((nonRecordingRepo) -> getWorkflowRun(nonRecordingRepo,
|
||||
FAST_WORKFLOW_NAME,
|
||||
SECOND_BRANCH,
|
||||
Status.COMPLETED,
|
||||
latestPreexistingWorkflowRunId).isPresent());
|
||||
|
||||
GHWorkflowRun workflowRun = getWorkflowRun(FAST_WORKFLOW_NAME,
|
||||
SECOND_BRANCH,
|
||||
Status.COMPLETED,
|
||||
latestPreexistingWorkflowRunId).orElseThrow(
|
||||
() -> new IllegalStateException("We must have a valid workflow run starting from here"));
|
||||
|
||||
assertEquals(workflow.getId(), workflowRun.getWorkflowId());
|
||||
assertEquals(SECOND_BRANCH, workflowRun.getHeadBranch());
|
||||
assertEquals(GHEvent.WORKFLOW_DISPATCH, workflowRun.getEvent());
|
||||
assertEquals(Status.COMPLETED, workflowRun.getStatus());
|
||||
assertEquals(Conclusion.SUCCESS, workflowRun.getConclusion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogs() throws IOException {
|
||||
GHWorkflow workflow = repo.getWorkflow(FAST_WORKFLOW_PATH);
|
||||
|
||||
long latestPreexistingWorkflowRunId = getLatestPreexistingWorkflowRunId();
|
||||
|
||||
workflow.dispatch(MAIN_BRANCH);
|
||||
|
||||
await((nonRecordingRepo) -> getWorkflowRun(nonRecordingRepo,
|
||||
FAST_WORKFLOW_NAME,
|
||||
MAIN_BRANCH,
|
||||
Status.COMPLETED,
|
||||
latestPreexistingWorkflowRunId).isPresent());
|
||||
|
||||
GHWorkflowRun workflowRun = getWorkflowRun(FAST_WORKFLOW_NAME,
|
||||
MAIN_BRANCH,
|
||||
Status.COMPLETED,
|
||||
latestPreexistingWorkflowRunId).orElseThrow(
|
||||
() -> new IllegalStateException("We must have a valid workflow run starting from here"));
|
||||
|
||||
List<String> logsArchiveEntries = new ArrayList<>();
|
||||
String fullLogContent = workflowRun
|
||||
.downloadLogs(getLogArchiveInputStreamFunction("1_build.txt", logsArchiveEntries));
|
||||
|
||||
assertThat(logsArchiveEntries, hasItems("1_build.txt", "build/9_Complete job.txt"));
|
||||
assertThat(fullLogContent, containsString("Hello, world!"));
|
||||
|
||||
workflowRun.deleteLogs();
|
||||
|
||||
try {
|
||||
workflowRun.downloadLogs((is) -> "");
|
||||
Assert.fail("Downloading logs should not be possible as they were deleted");
|
||||
} catch (GHFileNotFoundException e) {
|
||||
assertThat(e.getMessage(), containsString("Not Found"));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@Test
|
||||
public void testArtifacts() throws IOException {
|
||||
GHWorkflow workflow = repo.getWorkflow(ARTIFACTS_WORKFLOW_PATH);
|
||||
|
||||
long latestPreexistingWorkflowRunId = getLatestPreexistingWorkflowRunId();
|
||||
|
||||
workflow.dispatch(MAIN_BRANCH);
|
||||
|
||||
await((nonRecordingRepo) -> getWorkflowRun(nonRecordingRepo,
|
||||
ARTIFACTS_WORKFLOW_NAME,
|
||||
MAIN_BRANCH,
|
||||
Status.COMPLETED,
|
||||
latestPreexistingWorkflowRunId).isPresent());
|
||||
|
||||
GHWorkflowRun workflowRun = getWorkflowRun(ARTIFACTS_WORKFLOW_NAME,
|
||||
MAIN_BRANCH,
|
||||
Status.COMPLETED,
|
||||
latestPreexistingWorkflowRunId).orElseThrow(
|
||||
() -> new IllegalStateException("We must have a valid workflow run starting from here"));
|
||||
|
||||
List<GHArtifact> artifacts = new ArrayList<>(workflowRun.listArtifacts().toList());
|
||||
artifacts.sort((a1, a2) -> a1.getName().compareTo(a2.getName()));
|
||||
|
||||
assertThat(artifacts.size(), is(2));
|
||||
|
||||
// Test properties
|
||||
checkArtifactProperties(artifacts.get(0), "artifact1");
|
||||
checkArtifactProperties(artifacts.get(1), "artifact2");
|
||||
|
||||
// Test download
|
||||
String artifactContent = artifacts.get(0).download((is) -> {
|
||||
try (ZipInputStream zis = new ZipInputStream(is)) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
ZipEntry ze = zis.getNextEntry();
|
||||
assertThat(ze.getName(), is("artifact1.txt"));
|
||||
|
||||
// the scanner has to be kept open to avoid closing zis
|
||||
Scanner scanner = new Scanner(zis);
|
||||
while (scanner.hasNextLine()) {
|
||||
sb.append(scanner.nextLine());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
});
|
||||
|
||||
assertThat(artifactContent, is("artifact1"));
|
||||
|
||||
// Test GHRepository#getArtifact(long) as we are sure we have artifacts around
|
||||
GHArtifact artifactById = repo.getArtifact(artifacts.get(0).getId());
|
||||
checkArtifactProperties(artifactById, "artifact1");
|
||||
|
||||
artifactById = repo.getArtifact(artifacts.get(1).getId());
|
||||
checkArtifactProperties(artifactById, "artifact2");
|
||||
|
||||
// Test GHRepository#listArtifacts() as we are sure we have artifacts around
|
||||
List<GHArtifact> artifactsFromRepo = new ArrayList<>(
|
||||
repo.listArtifacts().withPageSize(2).iterator().nextPage());
|
||||
artifactsFromRepo.sort((a1, a2) -> a1.getName().compareTo(a2.getName()));
|
||||
|
||||
// We have at least the two artifacts we just added
|
||||
assertThat(artifactsFromRepo.size(), is(2));
|
||||
|
||||
// Test properties
|
||||
checkArtifactProperties(artifactsFromRepo.get(0), "artifact1");
|
||||
checkArtifactProperties(artifactsFromRepo.get(1), "artifact2");
|
||||
|
||||
// Now let's test the delete() method
|
||||
GHArtifact artifact1 = artifacts.get(0);
|
||||
artifact1.delete();
|
||||
|
||||
try {
|
||||
repo.getArtifact(artifact1.getId());
|
||||
Assert.fail("Getting the artifact should fail as it was deleted");
|
||||
} catch (GHFileNotFoundException e) {
|
||||
assertThat(e.getMessage(), containsString("Not Found"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJobs() throws IOException {
|
||||
GHWorkflow workflow = repo.getWorkflow(MULTI_JOBS_WORKFLOW_PATH);
|
||||
|
||||
long latestPreexistingWorkflowRunId = getLatestPreexistingWorkflowRunId();
|
||||
|
||||
workflow.dispatch(MAIN_BRANCH);
|
||||
|
||||
await((nonRecordingRepo) -> getWorkflowRun(nonRecordingRepo,
|
||||
MULTI_JOBS_WORKFLOW_NAME,
|
||||
MAIN_BRANCH,
|
||||
Status.COMPLETED,
|
||||
latestPreexistingWorkflowRunId).isPresent());
|
||||
|
||||
GHWorkflowRun workflowRun = getWorkflowRun(MULTI_JOBS_WORKFLOW_NAME,
|
||||
MAIN_BRANCH,
|
||||
Status.COMPLETED,
|
||||
latestPreexistingWorkflowRunId).orElseThrow(
|
||||
() -> new IllegalStateException("We must have a valid workflow run starting from here"));
|
||||
|
||||
List<GHWorkflowJob> jobs = workflowRun.listJobs()
|
||||
.toList()
|
||||
.stream()
|
||||
.sorted((j1, j2) -> j1.getName().compareTo(j2.getName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(jobs.size(), is(2));
|
||||
|
||||
GHWorkflowJob job1 = jobs.get(0);
|
||||
checkJobProperties(workflowRun.getId(), job1, "job1");
|
||||
String fullLogContent = job1.downloadLogs(getLogTextInputStreamFunction());
|
||||
assertThat(fullLogContent, containsString("Hello from job1!"));
|
||||
|
||||
GHWorkflowJob job2 = jobs.get(1);
|
||||
checkJobProperties(workflowRun.getId(), job2, "job2");
|
||||
fullLogContent = job2.downloadLogs(getLogTextInputStreamFunction());
|
||||
assertThat(fullLogContent, containsString("Hello from job2!"));
|
||||
|
||||
// while we have a job around, test GHRepository#getWorkflowJob(id)
|
||||
GHWorkflowJob job1ById = repo.getWorkflowJob(job1.getId());
|
||||
checkJobProperties(workflowRun.getId(), job1ById, "job1");
|
||||
|
||||
// Also test listAllJobs() works correctly
|
||||
List<GHWorkflowJob> allJobs = workflowRun.listAllJobs().withPageSize(10).iterator().nextPage();
|
||||
assertThat(allJobs.size(), greaterThanOrEqualTo(2));
|
||||
}
|
||||
|
||||
private void await(Function<GHRepository, Boolean> condition) throws IOException {
|
||||
if (!mockGitHub.isUseProxy()) {
|
||||
return;
|
||||
}
|
||||
|
||||
GHRepository nonRecordingRepo = getGitHubBeforeAfter().getRepository(REPO_NAME);
|
||||
|
||||
Awaitility.await().pollInterval(Duration.ofSeconds(5)).atMost(Duration.ofSeconds(60)).until(() -> {
|
||||
return condition.apply(nonRecordingRepo);
|
||||
});
|
||||
}
|
||||
|
||||
private long getLatestPreexistingWorkflowRunId() {
|
||||
return repo.queryWorkflowRuns().list().withPageSize(1).iterator().next().getId();
|
||||
}
|
||||
|
||||
private static Optional<GHWorkflowRun> getWorkflowRun(GHRepository repository,
|
||||
String workflowName,
|
||||
String branch,
|
||||
Status status,
|
||||
long latestPreexistingWorkflowRunId) {
|
||||
List<GHWorkflowRun> workflowRuns = repository.queryWorkflowRuns()
|
||||
.branch(branch)
|
||||
.status(status)
|
||||
.event(GHEvent.WORKFLOW_DISPATCH)
|
||||
.list()
|
||||
.withPageSize(20)
|
||||
.iterator()
|
||||
.nextPage();
|
||||
|
||||
for (GHWorkflowRun workflowRun : workflowRuns) {
|
||||
if (workflowRun.getName().equals(workflowName) && workflowRun.getId() > latestPreexistingWorkflowRunId) {
|
||||
return Optional.of(workflowRun);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private Optional<GHWorkflowRun> getWorkflowRun(String workflowName,
|
||||
String branch,
|
||||
Status status,
|
||||
long latestPreexistingWorkflowRunId) {
|
||||
return getWorkflowRun(this.repo, workflowName, branch, status, latestPreexistingWorkflowRunId);
|
||||
}
|
||||
|
||||
private static Status getWorkflowRunStatus(GHRepository repository, long workflowRunId) {
|
||||
try {
|
||||
return repository.getWorkflowRun(workflowRunId).getStatus();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Unable to get workflow run status", e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
private static InputStreamFunction<String> getLogArchiveInputStreamFunction(String mainLogFileName,
|
||||
List<String> logsArchiveEntries) {
|
||||
return (is) -> {
|
||||
try (ZipInputStream zis = new ZipInputStream(is)) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
ZipEntry ze;
|
||||
while ((ze = zis.getNextEntry()) != null) {
|
||||
logsArchiveEntries.add(ze.getName());
|
||||
if (mainLogFileName.equals(ze.getName())) {
|
||||
// the scanner has to be kept open to avoid closing zis
|
||||
Scanner scanner = new Scanner(zis);
|
||||
while (scanner.hasNextLine()) {
|
||||
sb.append(scanner.nextLine()).append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
private static InputStreamFunction<String> getLogTextInputStreamFunction() {
|
||||
return (is) -> {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Scanner scanner = new Scanner(is);
|
||||
while (scanner.hasNextLine()) {
|
||||
sb.append(scanner.nextLine()).append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
};
|
||||
}
|
||||
|
||||
private static void checkArtifactProperties(GHArtifact artifact, String artifactName) throws IOException {
|
||||
assertNotNull(artifact.getId());
|
||||
assertNotNull(artifact.getNodeId());
|
||||
assertEquals(REPO_NAME, artifact.getRepository().getFullName());
|
||||
assertThat(artifact.getName(), is(artifactName));
|
||||
assertThat(artifact.getArchiveDownloadUrl().getPath(), containsString("actions/artifacts"));
|
||||
assertNotNull(artifact.getCreatedAt());
|
||||
assertNotNull(artifact.getUpdatedAt());
|
||||
assertNotNull(artifact.getExpiresAt());
|
||||
assertThat(artifact.getSizeInBytes(), greaterThan(0L));
|
||||
assertFalse(artifact.isExpired());
|
||||
}
|
||||
|
||||
private static void checkJobProperties(long workflowRunId, GHWorkflowJob job, String jobName) throws IOException {
|
||||
assertNotNull(job.getId());
|
||||
assertNotNull(job.getNodeId());
|
||||
assertEquals(REPO_NAME, job.getRepository().getFullName());
|
||||
assertThat(job.getName(), is(jobName));
|
||||
assertNotNull(job.getStartedAt());
|
||||
assertNotNull(job.getCompletedAt());
|
||||
assertNotNull(job.getHeadSha());
|
||||
assertThat(job.getStatus(), is(Status.COMPLETED));
|
||||
assertThat(job.getConclusion(), is(Conclusion.SUCCESS));
|
||||
assertThat(job.getRunId(), is(workflowRunId));
|
||||
assertThat(job.getUrl().getPath(), containsString("/actions/jobs/"));
|
||||
assertThat(job.getHtmlUrl().getPath(), containsString("/runs/" + job.getId()));
|
||||
assertThat(job.getCheckRunUrl().getPath(), containsString("/check-runs/"));
|
||||
|
||||
// we only test the step we have control over, the others are added by GitHub
|
||||
Optional<Step> step = job.getSteps()
|
||||
.stream()
|
||||
.filter(s -> RUN_A_ONE_LINE_SCRIPT_STEP_NAME.equals(s.getName()))
|
||||
.findFirst();
|
||||
if (!step.isPresent()) {
|
||||
fail("Unable to find " + RUN_A_ONE_LINE_SCRIPT_STEP_NAME + " step");
|
||||
}
|
||||
|
||||
checkStepProperties(step.get(), RUN_A_ONE_LINE_SCRIPT_STEP_NAME, 2);
|
||||
}
|
||||
|
||||
private static void checkStepProperties(Step step, String name, int number) {
|
||||
assertThat(step.getName(), is(name));
|
||||
assertThat(step.getNumber(), is(number));
|
||||
assertThat(step.getStatus(), is(Status.COMPLETED));
|
||||
assertThat(step.getConclusion(), is(Conclusion.SUCCESS));
|
||||
assertNotNull(step.getStartedAt());
|
||||
assertNotNull(step.getCompletedAt());
|
||||
}
|
||||
}
|
||||
108
src/test/java/org/kohsuke/github/GHWorkflowTest.java
Normal file
108
src/test/java/org/kohsuke/github/GHWorkflowTest.java
Normal file
@@ -0,0 +1,108 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.containing;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
|
||||
|
||||
public class GHWorkflowTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
private static String REPO_NAME = "hub4j-test-org/GHWorkflowTest";
|
||||
|
||||
private GHRepository repo;
|
||||
|
||||
@Before
|
||||
@After
|
||||
public void cleanup() throws Exception {
|
||||
if (mockGitHub.isUseProxy()) {
|
||||
repo = getGitHubBeforeAfter().getRepository(REPO_NAME);
|
||||
|
||||
// we need to make sure the workflow is enabled before the tests
|
||||
GHWorkflow workflow = repo.getWorkflow("test-workflow.yml");
|
||||
if (!workflow.getState().equals("active")) {
|
||||
workflow.enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
repo = gitHub.getRepository(REPO_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicInformation() throws IOException {
|
||||
GHWorkflow workflow = repo.getWorkflow("test-workflow.yml");
|
||||
|
||||
assertEquals("test-workflow", workflow.getName());
|
||||
assertEquals(REPO_NAME, workflow.getRepository().getFullName());
|
||||
assertEquals(".github/workflows/test-workflow.yml", workflow.getPath());
|
||||
assertEquals("active", workflow.getState());
|
||||
assertEquals("/repos/hub4j-test-org/GHWorkflowTest/actions/workflows/6817859", workflow.getUrl().getPath());
|
||||
assertEquals("/hub4j-test-org/GHWorkflowTest/blob/main/.github/workflows/test-workflow.yml",
|
||||
workflow.getHtmlUrl().getPath());
|
||||
assertEquals("/hub4j-test-org/GHWorkflowTest/workflows/test-workflow/badge.svg",
|
||||
workflow.getBadgeUrl().getPath());
|
||||
|
||||
GHWorkflow workflowById = repo.getWorkflow(workflow.getId());
|
||||
assertEquals(workflow.getNodeId(), workflowById.getNodeId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisableEnable() throws IOException {
|
||||
GHWorkflow workflow = repo.getWorkflow("test-workflow.yml");
|
||||
|
||||
assertEquals("active", workflow.getState());
|
||||
|
||||
workflow.disable();
|
||||
|
||||
workflow = repo.getWorkflow("test-workflow.yml");
|
||||
assertEquals("disabled_manually", workflow.getState());
|
||||
|
||||
workflow.enable();
|
||||
|
||||
workflow = repo.getWorkflow("test-workflow.yml");
|
||||
assertEquals("active", workflow.getState());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDispatch() throws IOException {
|
||||
GHWorkflow workflow = repo.getWorkflow("test-workflow.yml");
|
||||
|
||||
workflow.dispatch("main");
|
||||
verify(postRequestedFor(
|
||||
urlPathEqualTo("/repos/hub4j-test-org/GHWorkflowTest/actions/workflows/6817859/dispatches")));
|
||||
|
||||
workflow.dispatch("main", Collections.singletonMap("parameter", "value"));
|
||||
verify(postRequestedFor(
|
||||
urlPathEqualTo("/repos/hub4j-test-org/GHWorkflowTest/actions/workflows/6817859/dispatches"))
|
||||
.withRequestBody(containing("inputs"))
|
||||
.withRequestBody(containing("parameter"))
|
||||
.withRequestBody(containing("value")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListWorkflows() throws IOException {
|
||||
List<GHWorkflow> workflows = repo.listWorkflows().toList();
|
||||
|
||||
GHWorkflow workflow = workflows.get(0);
|
||||
assertEquals(6817859L, workflow.getId());
|
||||
assertEquals("MDg6V29ya2Zsb3c2ODE3ODU5", workflow.getNodeId());
|
||||
assertEquals("test-workflow", workflow.getName());
|
||||
assertEquals(".github/workflows/test-workflow.yml", workflow.getPath());
|
||||
assertEquals("active", workflow.getState());
|
||||
assertEquals("/repos/hub4j-test-org/GHWorkflowTest/actions/workflows/6817859", workflow.getUrl().getPath());
|
||||
assertEquals("/hub4j-test-org/GHWorkflowTest/blob/main/.github/workflows/test-workflow.yml",
|
||||
workflow.getHtmlUrl().getPath());
|
||||
assertEquals("/hub4j-test-org/GHWorkflowTest/workflows/test-workflow/badge.svg",
|
||||
workflow.getBadgeUrl().getPath());
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,20 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import org.junit.Assume;
|
||||
import org.junit.Test;
|
||||
import org.kohsuke.github.authorization.UserAuthorizationProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.lessThan;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
/**
|
||||
* Unit test for {@link GitHub}.
|
||||
@@ -56,6 +63,8 @@ public class GitHubConnectionTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
@Test
|
||||
public void testGitHubBuilderFromEnvironment() throws IOException {
|
||||
// we disable this test for JDK 16+ as the current hacks in setupEnvironment() don't work with JDK 16+
|
||||
Assume.assumeThat(Double.valueOf(System.getProperty("java.specification.version")), lessThan(16.0));
|
||||
|
||||
Map<String, String> props = new HashMap<String, String>();
|
||||
|
||||
@@ -98,6 +107,9 @@ public class GitHubConnectionTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
@Test
|
||||
public void testGitHubBuilderFromCustomEnvironment() throws IOException {
|
||||
// we disable this test for JDK 16+ as the current hacks in setupEnvironment() don't work with JDK 16+
|
||||
Assume.assumeThat(Double.valueOf(System.getProperty("java.specification.version")), lessThan(16.0));
|
||||
|
||||
Map<String, String> props = new HashMap<String, String>();
|
||||
|
||||
props.put("customEndpoint", "bogus endpoint url");
|
||||
|
||||
@@ -2,7 +2,9 @@ package org.kohsuke.github;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
@@ -10,6 +12,9 @@ import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.core.IsInstanceOf.instanceOf;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
@@ -19,6 +24,34 @@ import static org.junit.Assert.fail;
|
||||
*/
|
||||
public class GitHubStaticTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
@Test
|
||||
public void testParseURL() throws Exception {
|
||||
assertThat(GitHubClient.parseURL("https://api.github.com"), equalTo(new URL("https://api.github.com")));
|
||||
assertThat(GitHubClient.parseURL(null), nullValue());
|
||||
|
||||
try {
|
||||
GitHubClient.parseURL("bogus");
|
||||
fail();
|
||||
} catch (IllegalStateException e) {
|
||||
assertThat(e.getMessage(), equalTo("Invalid URL: bogus"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseInstant() throws Exception {
|
||||
assertThat(GitHubClient.parseInstant(null), nullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRawUrlPathInvalid() throws Exception {
|
||||
try {
|
||||
gitHub.createRequest().setRawUrlPath("invalid.path.com");
|
||||
fail();
|
||||
} catch (GHException e) {
|
||||
assertThat(e.getMessage(), equalTo("Raw URL must start with 'http'"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void timeRoundTrip() throws Exception {
|
||||
final long stableInstantEpochMilli = 1533721222255L;
|
||||
@@ -78,6 +111,62 @@ public class GitHubStaticTest extends AbstractGitHubWireMockTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromRecord() throws Exception {
|
||||
final long stableInstantEpochSeconds = 11610674762L;
|
||||
|
||||
GHRateLimit rateLimit_none = GHRateLimit.fromRecord(new GHRateLimit.Record(9876,
|
||||
5432,
|
||||
(stableInstantEpochSeconds + Duration.ofMinutes(30).toMillis()) / 1000L), RateLimitTarget.NONE);
|
||||
|
||||
GHRateLimit rateLimit_core = GHRateLimit.fromRecord(new GHRateLimit.Record(9876,
|
||||
5432,
|
||||
(stableInstantEpochSeconds + Duration.ofMinutes(30).toMillis()) / 1000L), RateLimitTarget.CORE);
|
||||
|
||||
GHRateLimit rateLimit_search = GHRateLimit.fromRecord(new GHRateLimit.Record(19876,
|
||||
15432,
|
||||
(stableInstantEpochSeconds + Duration.ofHours(1).toMillis()) / 1000L), RateLimitTarget.SEARCH);
|
||||
|
||||
GHRateLimit rateLimit_graphql = GHRateLimit.fromRecord(new GHRateLimit.Record(29876,
|
||||
25432,
|
||||
(stableInstantEpochSeconds + Duration.ofHours(2).toMillis()) / 1000L), RateLimitTarget.GRAPHQL);
|
||||
|
||||
GHRateLimit rateLimit_integration = GHRateLimit.fromRecord(
|
||||
new GHRateLimit.Record(39876,
|
||||
35432,
|
||||
(stableInstantEpochSeconds + Duration.ofHours(3).toMillis()) / 1000L),
|
||||
RateLimitTarget.INTEGRATION_MANIFEST);
|
||||
|
||||
assertThat(rateLimit_none, equalTo(rateLimit_core));
|
||||
assertThat(rateLimit_none, not(sameInstance(rateLimit_core)));
|
||||
assertTrue(rateLimit_none.hashCode() == rateLimit_core.hashCode());
|
||||
assertTrue(rateLimit_none.equals(rateLimit_core));
|
||||
|
||||
assertThat(rateLimit_none, not(equalTo(rateLimit_search)));
|
||||
|
||||
assertThat(rateLimit_none.getCore(), not(sameInstance(rateLimit_core.getCore())));
|
||||
|
||||
assertThat(rateLimit_core.getRecord(RateLimitTarget.NONE), instanceOf(GHRateLimit.UnknownLimitRecord.class));
|
||||
assertThat(rateLimit_core.getRecord(RateLimitTarget.NONE),
|
||||
sameInstance(rateLimit_none.getRecord(RateLimitTarget.NONE)));
|
||||
|
||||
assertThat(rateLimit_core.getRecord(RateLimitTarget.SEARCH), sameInstance(rateLimit_search.getGraphQL()));
|
||||
assertThat(rateLimit_search.getRecord(RateLimitTarget.GRAPHQL),
|
||||
sameInstance(rateLimit_graphql.getIntegrationManifest()));
|
||||
assertThat(rateLimit_graphql.getRecord(RateLimitTarget.INTEGRATION_MANIFEST),
|
||||
sameInstance(rateLimit_integration.getCore()));
|
||||
assertThat(rateLimit_integration.getRecord(RateLimitTarget.CORE), sameInstance(rateLimit_core.getSearch()));
|
||||
|
||||
assertThat(rateLimit_none.getRecord(RateLimitTarget.CORE).getLimit(), equalTo(9876));
|
||||
assertThat(rateLimit_core.getRecord(RateLimitTarget.CORE).getLimit(), equalTo(9876));
|
||||
assertThat(rateLimit_search.getRecord(RateLimitTarget.SEARCH).getLimit(), equalTo(19876));
|
||||
assertThat(rateLimit_graphql.getRecord(RateLimitTarget.GRAPHQL).getLimit(), equalTo(29876));
|
||||
assertThat(rateLimit_integration.getRecord(RateLimitTarget.INTEGRATION_MANIFEST).getLimit(), equalTo(39876));
|
||||
|
||||
assertThat(rateLimit_core.toString(), containsString("GHRateLimit {core {remaining=5432, limit=9876"));
|
||||
assertThat(rateLimit_core.toString(), containsString("search {remaining=999999, limit=1000000"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGitHubRateLimitShouldReplaceRateLimit() throws Exception {
|
||||
|
||||
@@ -225,7 +314,7 @@ public class GitHubStaticTest extends AbstractGitHubWireMockTest {
|
||||
// this makes sure they don't break.
|
||||
|
||||
GHRepository repo = getTempRepository();
|
||||
assertThat(repo.root, not(nullValue()));
|
||||
assertThat(repo.getRoot(), not(nullValue()));
|
||||
assertThat(repo.getResponseHeaderFields(), not(nullValue()));
|
||||
|
||||
String repoString = GitHub.getMappingObjectWriter().writeValueAsString(repo);
|
||||
@@ -237,13 +326,13 @@ public class GitHubStaticTest extends AbstractGitHubWireMockTest {
|
||||
.readValue(repoString);
|
||||
|
||||
// This should never happen if the internal method isn't used
|
||||
assertThat(readRepo.root, nullValue());
|
||||
assertThat(readRepo.getRoot(), nullValue());
|
||||
assertThat(readRepo.getResponseHeaderFields(), nullValue());
|
||||
|
||||
readRepo = GitHub.getMappingObjectReader().forType(GHRepository.class).readValue(repoString);
|
||||
|
||||
// This should never happen if the internal method isn't used
|
||||
assertThat(readRepo.root.getConnector(), equalTo(HttpConnector.OFFLINE));
|
||||
assertThat(readRepo.getRoot().getConnector(), equalTo(HttpConnector.OFFLINE));
|
||||
assertThat(readRepo.getResponseHeaderFields(), nullValue());
|
||||
|
||||
String readRepoString = GitHub.getMappingObjectWriter().writeValueAsString(readRepo);
|
||||
|
||||
@@ -25,6 +25,22 @@ public class GitHubTest extends AbstractGitHubWireMockTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRepository() throws IOException {
|
||||
GHRepository repo = gitHub.getRepository("hub4j/github-api");
|
||||
|
||||
assertThat(repo.getFullName(), equalTo("hub4j/github-api"));
|
||||
|
||||
GHRepository repo2 = gitHub.getRepositoryById(Long.toString(repo.getId()));
|
||||
assertThat(repo2.getFullName(), equalTo("hub4j/github-api"));
|
||||
|
||||
try {
|
||||
gitHub.getRepository("hub4j_github-api");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage(), equalTo("Repository name must be in format owner/repo"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getOrgs() throws IOException {
|
||||
int iterations = 10;
|
||||
@@ -34,6 +50,18 @@ public class GitHubTest extends AbstractGitHubWireMockTest {
|
||||
// System.out.println(org.getName());
|
||||
}
|
||||
assertThat(orgIds.size(), equalTo(iterations));
|
||||
|
||||
GHOrganization org = gitHub.getOrganization("hub4j");
|
||||
GHOrganization org2 = gitHub.getOrganization("hub4j");
|
||||
assertThat(org.getLogin(), equalTo("hub4j"));
|
||||
// caching
|
||||
assertThat(org, sameInstance(org2));
|
||||
|
||||
gitHub.refreshCache();
|
||||
org2 = gitHub.getOrganization("hub4j");
|
||||
assertThat(org2.getLogin(), equalTo("hub4j"));
|
||||
// cache cleared
|
||||
assertThat(org, not(sameInstance(org2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@@ -24,19 +25,27 @@ public class Github2faTest extends AbstractGitHubWireMockTest {
|
||||
// collide with older tokens
|
||||
|
||||
GHAuthorization token = gitHub
|
||||
.createToken(asList, nameOfToken, "this is a test token created by a unit test", () -> {
|
||||
.createToken(asList, nameOfToken, "https://localhost/this/is/a/test/token", () -> {
|
||||
String data = "111878";
|
||||
// TO UPDATE run this in debugger mode, put a breakpoint here, and enter the OTP you get into the
|
||||
// value of Data
|
||||
return data;
|
||||
});
|
||||
assert token != null;
|
||||
|
||||
assertThat(token, notNullValue());
|
||||
|
||||
for (int i = 0; i < asList.size(); i++) {
|
||||
assertTrue(token.getScopes().get(i).contentEquals(asList.get(i)));
|
||||
}
|
||||
|
||||
String p = token.getToken();
|
||||
assertThat(token.getToken(), equalTo("63042a99d88bf138e6d6cf5788e0dc4e7a5d7309"));
|
||||
assertThat(token.getTokenLastEight(), equalTo("7a5d7309"));
|
||||
assertThat(token.getHashedToken(), equalTo("12b727a23cad7c5a5caabb806d88e722794dede98464aed7f77cbc00dbf031a2"));
|
||||
assertThat(token.getNote(), equalTo("Test2faTokenCreate"));
|
||||
assertThat(token.getNoteUrl().toString(), equalTo("https://localhost/this/is/a/test/token"));
|
||||
assertThat(token.getAppUrl().toString(), equalTo("https://localhost/this/is/a/test/app/token"));
|
||||
assertThat(token.getFingerprint(), nullValue());
|
||||
assertThat(token.getHtmlUrl(), nullValue());
|
||||
|
||||
assert p != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
|
||||
public class LifecycleTest extends AbstractGitHubWireMockTest {
|
||||
@@ -61,6 +61,13 @@ public class LifecycleTest extends AbstractGitHubWireMockTest {
|
||||
List<GHAsset> assets = release.getAssets();
|
||||
assertEquals(1, assets.size());
|
||||
assertEquals("LICENSE.txt", assets.get(0).getName());
|
||||
assertThat(assets.get(0).getSize(), equalTo(1104L));
|
||||
assertThat(assets.get(0).getContentType(), equalTo("application/text"));
|
||||
assertThat(assets.get(0).getState(), equalTo("uploaded"));
|
||||
assertThat(assets.get(0).getDownloadCount(), equalTo(0L));
|
||||
assertThat(assets.get(0).getOwner(), sameInstance(release.getOwner()));
|
||||
assertThat(assets.get(0).getBrowserDownloadUrl(),
|
||||
containsString("/temp-testCreateRepository/releases/download/release_tag/LICENSE.txt"));
|
||||
|
||||
return asset;
|
||||
}
|
||||
@@ -74,6 +81,16 @@ public class LifecycleTest extends AbstractGitHubWireMockTest {
|
||||
assertEquals(1, releases.size());
|
||||
GHRelease release = releases.get(0);
|
||||
assertEquals("Test Release", release.getName());
|
||||
assertThat(release.getBody(), startsWith("How exciting!"));
|
||||
assertThat(release.getOwner(), sameInstance(repository));
|
||||
assertThat(release.getZipballUrl(),
|
||||
endsWith("/repos/hub4j-test-org/temp-testCreateRepository/zipball/release_tag"));
|
||||
assertThat(release.getTarballUrl(),
|
||||
endsWith("/repos/hub4j-test-org/temp-testCreateRepository/tarball/release_tag"));
|
||||
assertThat(release.getTargetCommitish(), equalTo("master"));
|
||||
assertThat(release.getHtmlUrl().toString(),
|
||||
endsWith("/hub4j-test-org/temp-testCreateRepository/releases/tag/release_tag"));
|
||||
|
||||
return release;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,16 @@ package org.kohsuke.github.extras.authorization;
|
||||
import org.junit.Test;
|
||||
import org.kohsuke.github.AbstractGitHubWireMockTest;
|
||||
import org.kohsuke.github.GitHub;
|
||||
import org.kohsuke.github.HttpException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
/*
|
||||
* This test will request an application ensuring that the header for the "Authorization" matches a valid JWT token.
|
||||
* A JWT token in the Authorization header will always start with "ey" which is always the start of the base64
|
||||
@@ -33,6 +39,9 @@ public class JWTTokenProviderTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
@Test
|
||||
public void testAuthorizationHeaderPattern() throws GeneralSecurityException, IOException {
|
||||
// authorization header check is custom
|
||||
snapshotNotAllowed();
|
||||
|
||||
JWTTokenProvider jwtTokenProvider = new JWTTokenProvider(TEST_APP_ID_2,
|
||||
new File(this.getClass().getResource(PRIVATE_KEY_FILE_APP_2).getFile()));
|
||||
GitHub gh = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl())
|
||||
@@ -44,4 +53,35 @@ public class JWTTokenProviderTest extends AbstractGitHubWireMockTest {
|
||||
gh.getApp();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIssuedAtSkew() throws GeneralSecurityException, IOException {
|
||||
// TODO: This isn't a great test as it doesn't really check anything in CI
|
||||
// This test was accurate when recorded but it doesn't verify that the jwt token is different
|
||||
// or accurate in anyway.
|
||||
|
||||
JWTTokenProvider jwtTokenProvider = new JWTTokenProvider(TEST_APP_ID_2,
|
||||
new File(this.getClass().getResource(PRIVATE_KEY_FILE_APP_2).getFile())) {
|
||||
|
||||
@Override
|
||||
Instant getIssuedAt(Instant now) {
|
||||
return now.plus(Duration.ofMinutes(2));
|
||||
}
|
||||
};
|
||||
GitHub gh = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl())
|
||||
.withAuthorizationProvider(jwtTokenProvider)
|
||||
.build();
|
||||
|
||||
try {
|
||||
// Request the application, the wiremock matcher will ensure that the header
|
||||
// for the authorization is present and has a the format of a valid JWT token
|
||||
gh.getApp();
|
||||
fail();
|
||||
} catch (HttpException e) {
|
||||
assertThat(e.getResponseCode(), equalTo(401));
|
||||
assertThat(e.getMessage(),
|
||||
containsString(
|
||||
"'Issued at' claim ('iat') must be an Integer representing the time that the assertion was issued"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
23
src/test/java/org/kohsuke/github/internal/EnumUtilsTest.java
Normal file
23
src/test/java/org/kohsuke/github/internal/EnumUtilsTest.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package org.kohsuke.github.internal;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
public class EnumUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testGetEnum() {
|
||||
assertNull(EnumUtils.getNullableEnumOrDefault(TestEnum.class, null, TestEnum.UNKNOWN));
|
||||
assertEquals(TestEnum.UNKNOWN, EnumUtils.getNullableEnumOrDefault(TestEnum.class, "foobar", TestEnum.UNKNOWN));
|
||||
assertEquals(TestEnum.VALUE_1, EnumUtils.getNullableEnumOrDefault(TestEnum.class, "VALUE_1", TestEnum.UNKNOWN));
|
||||
assertEquals(TestEnum.VALUE_1, EnumUtils.getNullableEnumOrDefault(TestEnum.class, "value_1", TestEnum.UNKNOWN));
|
||||
assertEquals(TestEnum.VALUE_2, EnumUtils.getNullableEnumOrDefault(TestEnum.class, "VALUE_2", TestEnum.UNKNOWN));
|
||||
assertEquals(TestEnum.VALUE_2, EnumUtils.getNullableEnumOrDefault(TestEnum.class, "value_2", TestEnum.UNKNOWN));
|
||||
}
|
||||
|
||||
private enum TestEnum {
|
||||
VALUE_1, VALUE_2, UNKNOWN;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import com.github.tomakehurst.wiremock.extension.ResponseTransformer;
|
||||
import com.github.tomakehurst.wiremock.http.*;
|
||||
import com.github.tomakehurst.wiremock.matching.RequestPatternBuilder;
|
||||
import com.google.gson.*;
|
||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -64,6 +65,14 @@ public class GitHubWireMockRule extends WireMockMultiServerRule {
|
||||
return servers.get("uploads");
|
||||
}
|
||||
|
||||
public WireMockServer codeloadServer() {
|
||||
return servers.get("codeload");
|
||||
}
|
||||
|
||||
public WireMockServer actionsUserContentServer() {
|
||||
return servers.get("actions-user-content");
|
||||
}
|
||||
|
||||
public boolean isUseProxy() {
|
||||
return GitHubWireMockRule.useProxy;
|
||||
}
|
||||
@@ -88,6 +97,15 @@ public class GitHubWireMockRule extends WireMockMultiServerRule {
|
||||
if (new File(apiServer().getOptions().filesRoot().getPath() + "_uploads").exists() || isUseProxy()) {
|
||||
initializeServer("uploads");
|
||||
}
|
||||
|
||||
if (new File(apiServer().getOptions().filesRoot().getPath() + "_codeload").exists() || isUseProxy()) {
|
||||
initializeServer("codeload");
|
||||
}
|
||||
|
||||
if (new File(apiServer().getOptions().filesRoot().getPath() + "_actions-user-content").exists()
|
||||
|| isUseProxy()) {
|
||||
initializeServer("actions-user-content");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,6 +124,16 @@ public class GitHubWireMockRule extends WireMockMultiServerRule {
|
||||
if (this.uploadsServer() != null) {
|
||||
this.uploadsServer().stubFor(proxyAllTo("https://uploads.github.com").atPriority(100));
|
||||
}
|
||||
|
||||
if (this.codeloadServer() != null) {
|
||||
this.codeloadServer().stubFor(proxyAllTo("https://codeload.github.com").atPriority(100));
|
||||
}
|
||||
|
||||
if (this.actionsUserContentServer() != null) {
|
||||
this.actionsUserContentServer()
|
||||
.stubFor(proxyAllTo("https://pipelines.actions.githubusercontent.com").atPriority(100));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -121,6 +149,10 @@ public class GitHubWireMockRule extends WireMockMultiServerRule {
|
||||
recordSnapshot(this.rawServer(), "https://raw.githubusercontent.com", true);
|
||||
|
||||
recordSnapshot(this.uploadsServer(), "https://uploads.github.com", false);
|
||||
|
||||
recordSnapshot(this.codeloadServer(), "https://codeload.github.com", true);
|
||||
|
||||
recordSnapshot(this.actionsUserContentServer(), "https://pipelines.actions.githubusercontent.com", true);
|
||||
}
|
||||
|
||||
private void recordSnapshot(WireMockServer server, String target, boolean isRawServer) {
|
||||
@@ -141,7 +173,7 @@ public class GitHubWireMockRule extends WireMockMultiServerRule {
|
||||
.extractTextBodiesOver(255));
|
||||
|
||||
// After taking the snapshot, format the output
|
||||
formatTestResources(new File(this.apiServer().getOptions().filesRoot().getPath()).toPath(), false);
|
||||
formatTestResources(new File(server.getOptions().filesRoot().getPath()).toPath(), isRawServer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,6 +245,15 @@ public class GitHubWireMockRule extends WireMockMultiServerRule {
|
||||
fileText = fileText.replace(this.uploadsServer().baseUrl(), "https://uploads.github.com");
|
||||
}
|
||||
|
||||
if (this.codeloadServer() != null) {
|
||||
fileText = fileText.replace(this.codeloadServer().baseUrl(), "https://codeload.github.com");
|
||||
}
|
||||
|
||||
if (this.actionsUserContentServer() != null) {
|
||||
fileText = fileText.replace(this.actionsUserContentServer().baseUrl(),
|
||||
"https://pipelines.actions.githubusercontent.com");
|
||||
}
|
||||
|
||||
// point bodyFile in the mapping to the renamed body file
|
||||
if (entry != null && filePath.toString().contains("mappings")) {
|
||||
fileText = fileText.replace("-" + entry.getKey(), "-" + entry.getValue());
|
||||
@@ -263,16 +304,28 @@ public class GitHubWireMockRule extends WireMockMultiServerRule {
|
||||
public String mapToMockGitHub(String body) {
|
||||
body = body.replace("https://api.github.com", this.apiServer().baseUrl());
|
||||
|
||||
if (this.rawServer() != null) {
|
||||
body = body.replace("https://raw.githubusercontent.com", this.rawServer().baseUrl());
|
||||
} else {
|
||||
body = body.replace("https://raw.githubusercontent.com", this.apiServer().baseUrl() + "/raw");
|
||||
}
|
||||
body = replaceTargetServerUrl(body, this.rawServer(), "https://raw.githubusercontent.com", "/raw");
|
||||
|
||||
if (this.uploadsServer() != null) {
|
||||
body = body.replace("https://uploads.github.com", this.uploadsServer().baseUrl());
|
||||
body = replaceTargetServerUrl(body, this.uploadsServer(), "https://uploads.github.com", "/uploads");
|
||||
|
||||
body = replaceTargetServerUrl(body, this.codeloadServer(), "https://codeload.github.com", "/codeload");
|
||||
|
||||
body = replaceTargetServerUrl(body,
|
||||
this.actionsUserContentServer(),
|
||||
"https://pipelines.actions.githubusercontent.com",
|
||||
"/actions-user-content");
|
||||
return body;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String replaceTargetServerUrl(String body,
|
||||
WireMockServer wireMockServer,
|
||||
String rawTarget,
|
||||
String inactiveTarget) {
|
||||
if (wireMockServer != null) {
|
||||
body = body.replace(rawTarget, wireMockServer.baseUrl());
|
||||
} else {
|
||||
body = body.replace("https://uploads.github.com", this.apiServer().baseUrl() + "/uploads");
|
||||
body = body.replace(rawTarget, this.apiServer().baseUrl() + inactiveTarget);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
@@ -294,6 +347,7 @@ public class GitHubWireMockRule extends WireMockMultiServerRule {
|
||||
Collection<HttpHeader> headers = response.getHeaders().all();
|
||||
|
||||
fixListTraversalHeader(response, headers);
|
||||
fixLocationHeader(response, headers);
|
||||
|
||||
if ("application/json".equals(response.getHeaders().getContentTypeHeader().mimeTypePart())) {
|
||||
|
||||
@@ -321,11 +375,20 @@ public class GitHubWireMockRule extends WireMockMultiServerRule {
|
||||
}
|
||||
|
||||
private void fixListTraversalHeader(Response response, Collection<HttpHeader> headers) {
|
||||
// Lists are broken up into pages. The Link header contains urls for previous and next pages.
|
||||
HttpHeader linkHeader = response.getHeaders().getHeader("Link");
|
||||
if (linkHeader.isPresent()) {
|
||||
headers.removeIf(item -> item.keyEquals("Link"));
|
||||
headers.add(HttpHeader.httpHeader("Link",
|
||||
linkHeader.firstValue().replace("https://api.github.com", rule.apiServer().baseUrl())));
|
||||
headers.add(HttpHeader.httpHeader("Link", rule.mapToMockGitHub(linkHeader.firstValue())));
|
||||
}
|
||||
}
|
||||
|
||||
private void fixLocationHeader(Response response, Collection<HttpHeader> headers) {
|
||||
// For redirects, the Location header points to the new target.
|
||||
HttpHeader linkHeader = response.getHeaders().getHeader("Location");
|
||||
if (linkHeader.isPresent()) {
|
||||
headers.removeIf(item -> item.keyEquals("Location"));
|
||||
headers.add(HttpHeader.httpHeader("Location", rule.mapToMockGitHub(linkHeader.firstValue())));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": 212656166,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnkyMTI2NTYxNjY=",
|
||||
"id": 332135400,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnkzMzIxMzU0MDA=",
|
||||
"name": "github-api-test",
|
||||
"full_name": "hub4j-test-org/github-api-test",
|
||||
"private": false,
|
||||
@@ -8,7 +8,7 @@
|
||||
"login": "hub4j-test-org",
|
||||
"id": 7544739,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/hub4j-test-org",
|
||||
"html_url": "https://github.com/hub4j-test-org",
|
||||
@@ -25,7 +25,7 @@
|
||||
"site_admin": false
|
||||
},
|
||||
"html_url": "https://github.com/hub4j-test-org/github-api-test",
|
||||
"description": "A test repository for testing the github-api project",
|
||||
"description": "A test repository for testing the github-api project: github-api-test",
|
||||
"fork": false,
|
||||
"url": "https://api.github.com/repos/hub4j-test-org/github-api-test",
|
||||
"forks_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/forks",
|
||||
@@ -64,9 +64,9 @@
|
||||
"labels_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/labels{/name}",
|
||||
"releases_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/releases{/id}",
|
||||
"deployments_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments",
|
||||
"created_at": "2019-10-03T18:57:53Z",
|
||||
"updated_at": "2019-10-03T18:57:57Z",
|
||||
"pushed_at": "2019-10-03T18:57:54Z",
|
||||
"created_at": "2021-01-23T05:30:23Z",
|
||||
"updated_at": "2021-01-23T05:30:27Z",
|
||||
"pushed_at": "2021-01-23T05:30:25Z",
|
||||
"git_url": "git://github.com/hub4j-test-org/github-api-test.git",
|
||||
"ssh_url": "git@github.com:hub4j-test-org/github-api-test.git",
|
||||
"clone_url": "https://github.com/hub4j-test-org/github-api-test.git",
|
||||
@@ -90,20 +90,22 @@
|
||||
"forks": 0,
|
||||
"open_issues": 0,
|
||||
"watchers": 0,
|
||||
"default_branch": "master",
|
||||
"default_branch": "main",
|
||||
"permissions": {
|
||||
"admin": true,
|
||||
"push": true,
|
||||
"pull": true
|
||||
},
|
||||
"temp_clone_token": "",
|
||||
"allow_squash_merge": true,
|
||||
"allow_merge_commit": true,
|
||||
"allow_rebase_merge": true,
|
||||
"delete_branch_on_merge": false,
|
||||
"organization": {
|
||||
"login": "hub4j-test-org",
|
||||
"id": 7544739,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/hub4j-test-org",
|
||||
"html_url": "https://github.com/hub4j-test-org",
|
||||
@@ -120,5 +122,5 @@
|
||||
"site_admin": false
|
||||
},
|
||||
"network_count": 0,
|
||||
"subscribers_count": 2
|
||||
"subscribers_count": 9
|
||||
}
|
||||
@@ -1,38 +1,39 @@
|
||||
{
|
||||
"url": "http://localhost:62379/repos/hub4j-test-org/github-api-test/deployments/173089055",
|
||||
"id": 173089055,
|
||||
"node_id": "MDEwOkRlcGxveW1lbnQxNzMwODkwNTU=",
|
||||
"sha": "a446d9fa5c6f43d5f9333b625606909cd4635071",
|
||||
"ref": "master",
|
||||
"url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601563",
|
||||
"id": 315601563,
|
||||
"node_id": "MDEwOkRlcGxveW1lbnQzMTU2MDE1NjM=",
|
||||
"task": "deploy",
|
||||
"payload": "{\"user\":\"atmos\",\"room_id\":123456}",
|
||||
"original_environment": "unittest",
|
||||
"environment": "unittest",
|
||||
"description": "question",
|
||||
"created_at": "2021-01-23T05:30:28Z",
|
||||
"updated_at": "2021-01-23T05:30:28Z",
|
||||
"statuses_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601563/statuses",
|
||||
"repository_url": "https://api.github.com/repos/hub4j-test-org/github-api-test",
|
||||
"creator": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/1958953?v=4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "http://localhost:62379/users/bitwiseman",
|
||||
"url": "https://api.github.com/users/bitwiseman",
|
||||
"html_url": "https://github.com/bitwiseman",
|
||||
"followers_url": "http://localhost:62379/users/bitwiseman/followers",
|
||||
"following_url": "http://localhost:62379/users/bitwiseman/following{/other_user}",
|
||||
"gists_url": "http://localhost:62379/users/bitwiseman/gists{/gist_id}",
|
||||
"starred_url": "http://localhost:62379/users/bitwiseman/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "http://localhost:62379/users/bitwiseman/subscriptions",
|
||||
"organizations_url": "http://localhost:62379/users/bitwiseman/orgs",
|
||||
"repos_url": "http://localhost:62379/users/bitwiseman/repos",
|
||||
"events_url": "http://localhost:62379/users/bitwiseman/events{/privacy}",
|
||||
"received_events_url": "http://localhost:62379/users/bitwiseman/received_events",
|
||||
"followers_url": "https://api.github.com/users/bitwiseman/followers",
|
||||
"following_url": "https://api.github.com/users/bitwiseman/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/bitwiseman/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/bitwiseman/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/bitwiseman/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/bitwiseman/orgs",
|
||||
"repos_url": "https://api.github.com/users/bitwiseman/repos",
|
||||
"events_url": "https://api.github.com/users/bitwiseman/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/bitwiseman/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"created_at": "2019-10-03T18:57:57Z",
|
||||
"updated_at": "2019-10-03T18:57:57Z",
|
||||
"statuses_url": "http://localhost:62379/repos/hub4j-test-org/github-api-test/deployments/173089055/statuses",
|
||||
"repository_url": "http://localhost:62379/repos/hub4j-test-org/github-api-test",
|
||||
"transient_environment": true,
|
||||
"production_environment": false
|
||||
"sha": "e53a04ca0ba2fbe6ea3fd590e8ea1391ac61630f",
|
||||
"ref": "main",
|
||||
"payload": "{\"user\":\"atmos\",\"room_id\":123456}",
|
||||
"transient_environment": false,
|
||||
"production_environment": false,
|
||||
"performed_via_github_app": null
|
||||
}
|
||||
@@ -1,20 +1,21 @@
|
||||
[
|
||||
{
|
||||
"url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/173089055",
|
||||
"id": 173089055,
|
||||
"node_id": "MDEwOkRlcGxveW1lbnQxNzMwODkwNTU=",
|
||||
"sha": "a446d9fa5c6f43d5f9333b625606909cd4635071",
|
||||
"ref": "master",
|
||||
"url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601563",
|
||||
"id": 315601563,
|
||||
"node_id": "MDEwOkRlcGxveW1lbnQzMTU2MDE1NjM=",
|
||||
"task": "deploy",
|
||||
"payload": "{\"user\":\"atmos\",\"room_id\":123456}",
|
||||
"original_environment": "unittest",
|
||||
"environment": "unittest",
|
||||
"description": "question",
|
||||
"created_at": "2021-01-23T05:30:28Z",
|
||||
"updated_at": "2021-01-23T05:30:28Z",
|
||||
"statuses_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601563/statuses",
|
||||
"repository_url": "https://api.github.com/repos/hub4j-test-org/github-api-test",
|
||||
"creator": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/1958953?v=4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/bitwiseman",
|
||||
"html_url": "https://github.com/bitwiseman",
|
||||
@@ -30,11 +31,11 @@
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"created_at": "2019-10-03T18:57:57Z",
|
||||
"updated_at": "2019-10-03T18:57:57Z",
|
||||
"statuses_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/173089055/statuses",
|
||||
"repository_url": "https://api.github.com/repos/hub4j-test-org/github-api-test",
|
||||
"transient_environment": true,
|
||||
"production_environment": false
|
||||
"sha": "e53a04ca0ba2fbe6ea3fd590e8ea1391ac61630f",
|
||||
"ref": "main",
|
||||
"payload": "{\"user\":\"atmos\",\"room_id\":123456}",
|
||||
"transient_environment": false,
|
||||
"production_environment": false,
|
||||
"performed_via_github_app": null
|
||||
}
|
||||
]
|
||||
@@ -2,7 +2,7 @@
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/1958953?v=4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/bitwiseman",
|
||||
"html_url": "https://github.com/bitwiseman",
|
||||
@@ -23,17 +23,18 @@
|
||||
"location": "Seattle, WA, USA",
|
||||
"email": "bitwiseman@gmail.com",
|
||||
"hireable": null,
|
||||
"bio": "https://twitter.com/bitwiseman",
|
||||
"public_repos": 167,
|
||||
"public_gists": 4,
|
||||
"followers": 136,
|
||||
"following": 9,
|
||||
"bio": null,
|
||||
"twitter_username": "bitwiseman",
|
||||
"public_repos": 201,
|
||||
"public_gists": 7,
|
||||
"followers": 176,
|
||||
"following": 11,
|
||||
"created_at": "2012-07-11T20:38:33Z",
|
||||
"updated_at": "2019-09-24T19:32:29Z",
|
||||
"private_gists": 7,
|
||||
"total_private_repos": 9,
|
||||
"updated_at": "2021-01-22T16:38:42Z",
|
||||
"private_gists": 19,
|
||||
"total_private_repos": 17,
|
||||
"owned_private_repos": 0,
|
||||
"disk_usage": 33697,
|
||||
"disk_usage": 33700,
|
||||
"collaborators": 0,
|
||||
"two_factor_authentication": true,
|
||||
"plan": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"id": "31a86a0d-5120-47b8-a9bc-ec4b34a08080",
|
||||
"id": "b0faf3a5-5d1d-4f5f-bcc0-32f5c182f4c4",
|
||||
"name": "repos_hub4j-test-org_github-api-test",
|
||||
"request": {
|
||||
"url": "/repos/hub4j-test-org/github-api-test",
|
||||
@@ -14,35 +14,35 @@
|
||||
"status": 200,
|
||||
"bodyFileName": "repos_hub4j-test-org_github-api-test-2.json",
|
||||
"headers": {
|
||||
"Date": "Thu, 03 Oct 2019 18:57:57 GMT",
|
||||
"Date": "Sat, 23 Jan 2021 05:30:28 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4750",
|
||||
"X-RateLimit-Reset": "1570132527",
|
||||
"Cache-Control": "private, max-age=60, s-maxage=60",
|
||||
"Vary": [
|
||||
"Accept, Authorization, Cookie, X-GitHub-OTP",
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"ETag": "W/\"65ee4cf55cf4d084267c80a5d39244c6\"",
|
||||
"Last-Modified": "Thu, 03 Oct 2019 18:57:57 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"ETag": "W/\"10026c1f1a22ffaba0888b2d3e2501ab45ade2789609aa725a767f8593b8f060\"",
|
||||
"last-modified": "Sat, 23 Jan 2021 05:30:27 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "repo",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4904",
|
||||
"X-RateLimit-Reset": "1611382753",
|
||||
"x-ratelimit-used": "96",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"X-GitHub-Request-Id": "F3AD:3618:10E8DB:149FB6:5D9644B0"
|
||||
"X-GitHub-Request-Id": "D9F6:8870:9D4A2:B9689:600BB46D"
|
||||
}
|
||||
},
|
||||
"uuid": "31a86a0d-5120-47b8-a9bc-ec4b34a08080",
|
||||
"uuid": "b0faf3a5-5d1d-4f5f-bcc0-32f5c182f4c4",
|
||||
"persistent": true,
|
||||
"insertionIndex": 2
|
||||
}
|
||||
@@ -1,56 +1,56 @@
|
||||
{
|
||||
"id": "702b7123-86c1-41e0-bee7-f3cb89a3236d",
|
||||
"id": "794202d0-93a7-4526-b91b-00059c377ee0",
|
||||
"name": "repos_hub4j-test-org_github-api-test_deployments",
|
||||
"request": {
|
||||
"url": "/repos/hub4j-test-org/github-api-test/deployments",
|
||||
"method": "POST",
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"ref\":\"master\",\"environment\":\"unittest\",\"payload\":\"{\\\"user\\\":\\\"atmos\\\",\\\"room_id\\\":123456}\",\"description\":\"question\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": true
|
||||
}
|
||||
],
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "application/vnd.github.ant-man-preview+json, application/vnd.github.flash-preview+json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"ref\":\"main\",\"environment\":\"unittest\",\"payload\":\"{\\\"user\\\":\\\"atmos\\\",\\\"room_id\\\":123456}\",\"description\":\"question\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 201,
|
||||
"bodyFileName": "repos_hub4j-test-org_github-api-test_deployments-3.json",
|
||||
"headers": {
|
||||
"Date": "Thu, 03 Oct 2019 18:57:57 GMT",
|
||||
"Date": "Sat, 23 Jan 2021 05:30:28 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "201 Created",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4749",
|
||||
"X-RateLimit-Reset": "1570132527",
|
||||
"Cache-Control": "private, max-age=60, s-maxage=60",
|
||||
"Vary": [
|
||||
"Accept, Authorization, Cookie, X-GitHub-OTP",
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"ETag": "\"c76b22eae3a1d091db2c789a39fecda9\"",
|
||||
"Last-Modified": "Thu, 03 Oct 2019 18:57:57 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"ETag": "\"d256e649a7f1dfa04498ff9107cd30d1f42dcf80793952739c20e04436165cf3\"",
|
||||
"last-modified": "Sat, 23 Jan 2021 05:30:28 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "",
|
||||
"Location": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/173089055",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Location": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601563",
|
||||
"X-GitHub-Media-Type": "github.ant-man-preview; format=json, github.flash-preview; format=json",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4903",
|
||||
"X-RateLimit-Reset": "1611382753",
|
||||
"x-ratelimit-used": "97",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"X-GitHub-Request-Id": "F3AD:3618:10E8DF:149FEF:5D9644B5"
|
||||
"X-GitHub-Request-Id": "D9F6:8870:9D4A9:B9794:600BB474"
|
||||
}
|
||||
},
|
||||
"uuid": "702b7123-86c1-41e0-bee7-f3cb89a3236d",
|
||||
"uuid": "794202d0-93a7-4526-b91b-00059c377ee0",
|
||||
"persistent": true,
|
||||
"insertionIndex": 3
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"id": "b4bcdadb-a708-4509-9382-479f300eb172",
|
||||
"id": "ad687411-71ba-4851-91b0-2ace8f6111a2",
|
||||
"name": "repos_hub4j-test-org_github-api-test_deployments",
|
||||
"request": {
|
||||
"url": "/repos/hub4j-test-org/github-api-test/deployments?ref=master&environment=unittest",
|
||||
"url": "/repos/hub4j-test-org/github-api-test/deployments?ref=main&environment=unittest",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
@@ -14,34 +14,34 @@
|
||||
"status": 200,
|
||||
"bodyFileName": "repos_hub4j-test-org_github-api-test_deployments-4.json",
|
||||
"headers": {
|
||||
"Date": "Thu, 03 Oct 2019 18:57:58 GMT",
|
||||
"Date": "Sat, 23 Jan 2021 05:30:29 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4748",
|
||||
"X-RateLimit-Reset": "1570132527",
|
||||
"Cache-Control": "private, max-age=60, s-maxage=60",
|
||||
"Vary": [
|
||||
"Accept, Authorization, Cookie, X-GitHub-OTP",
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"ETag": "W/\"b47f03577f96c1081341944009009f7f\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"ETag": "W/\"37d9142674c76d3eb0593d8a62756ab18011fd64315c81dbfa2c7f7dd7596dd7\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "repo, repo_deployment",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"X-GitHub-Media-Type": "github.ant-man-preview; format=json, github.flash-preview; format=json",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4902",
|
||||
"X-RateLimit-Reset": "1611382753",
|
||||
"x-ratelimit-used": "98",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"X-GitHub-Request-Id": "F3AD:3618:10E8E2:149FF2:5D9644B5"
|
||||
"X-GitHub-Request-Id": "D9F6:8870:9D4AF:B979B:600BB474"
|
||||
}
|
||||
},
|
||||
"uuid": "b4bcdadb-a708-4509-9382-479f300eb172",
|
||||
"uuid": "ad687411-71ba-4851-91b0-2ace8f6111a2",
|
||||
"persistent": true,
|
||||
"insertionIndex": 4
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"id": "3360bee1-e184-49de-8434-9fabafc6e075",
|
||||
"name": "repos_hub4j-test-org_github-api-test_deployments_315601563",
|
||||
"request": {
|
||||
"url": "/repos/hub4j-test-org/github-api-test/deployments/315601563",
|
||||
"method": "DELETE",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 204,
|
||||
"headers": {
|
||||
"Date": "Sat, 23 Jan 2021 05:30:29 GMT",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "204 No Content",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4901",
|
||||
"X-RateLimit-Reset": "1611382753",
|
||||
"x-ratelimit-used": "99",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"Vary": [
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"X-GitHub-Request-Id": "D9F6:8870:9D4B5:B97A0:600BB475"
|
||||
}
|
||||
},
|
||||
"uuid": "3360bee1-e184-49de-8434-9fabafc6e075",
|
||||
"persistent": true,
|
||||
"insertionIndex": 5
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"id": "6d2dcbf4-4abf-4180-9b55-ca2931ca31c5",
|
||||
"id": "9e2336dc-4e61-49ef-a171-2d408b3bf5ac",
|
||||
"name": "user",
|
||||
"request": {
|
||||
"url": "/user",
|
||||
@@ -14,35 +14,35 @@
|
||||
"status": 200,
|
||||
"bodyFileName": "user-1.json",
|
||||
"headers": {
|
||||
"Date": "Thu, 03 Oct 2019 18:57:52 GMT",
|
||||
"Date": "Sat, 23 Jan 2021 05:30:21 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4759",
|
||||
"X-RateLimit-Reset": "1570132527",
|
||||
"Cache-Control": "private, max-age=60, s-maxage=60",
|
||||
"Vary": [
|
||||
"Accept, Authorization, Cookie, X-GitHub-OTP",
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"ETag": "W/\"cf6199fecf47b59c42190e1e11147ee2\"",
|
||||
"Last-Modified": "Tue, 24 Sep 2019 19:32:29 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"ETag": "W/\"c8b61de8f7b00ef1a040d10e88b51dd065defb82f7d94a95a97b3dbab636edbe\"",
|
||||
"last-modified": "Fri, 22 Jan 2021 16:38:42 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4909",
|
||||
"X-RateLimit-Reset": "1611382753",
|
||||
"x-ratelimit-used": "91",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"X-GitHub-Request-Id": "F3AD:3618:10E8AA:149FB4:5D9644B0"
|
||||
"X-GitHub-Request-Id": "D9F6:8870:9D3CD:B9683:600BB46D"
|
||||
}
|
||||
},
|
||||
"uuid": "6d2dcbf4-4abf-4180-9b55-ca2931ca31c5",
|
||||
"uuid": "9e2336dc-4e61-49ef-a171-2d408b3bf5ac",
|
||||
"persistent": true,
|
||||
"insertionIndex": 1
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
"login": "kohsuke",
|
||||
"id": 50003,
|
||||
"node_id": "MDQ6VXNlcjUwMDAz",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/50003?v=4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/50003?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/kohsuke",
|
||||
"html_url": "https://github.com/kohsuke",
|
||||
@@ -96,6 +96,7 @@
|
||||
"push": false,
|
||||
"pull": true
|
||||
},
|
||||
"temp_clone_token": "",
|
||||
"parent": {
|
||||
"id": 3231216,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnkzMjMxMjE2",
|
||||
@@ -106,7 +107,7 @@
|
||||
"login": "kohsuke2",
|
||||
"id": 1329242,
|
||||
"node_id": "MDQ6VXNlcjEzMjkyNDI=",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/1329242?v=4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1329242?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/kohsuke2",
|
||||
"html_url": "https://github.com/kohsuke2",
|
||||
@@ -200,7 +201,7 @@
|
||||
"login": "kohsuke2",
|
||||
"id": 1329242,
|
||||
"node_id": "MDQ6VXNlcjEzMjkyNDI=",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/1329242?v=4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1329242?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/kohsuke2",
|
||||
"html_url": "https://github.com/kohsuke2",
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"url": "https://api.github.com/repos/kohsuke/sandbox-ant/comments/35673784",
|
||||
"html_url": "https://github.com/kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000#commitcomment-35673784",
|
||||
"id": 35673784,
|
||||
"node_id": "MDEzOkNvbW1pdENvbW1lbnQzNTY3Mzc4NA==",
|
||||
"url": "https://api.github.com/repos/kohsuke/sandbox-ant/comments/46267761",
|
||||
"html_url": "https://github.com/kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000#commitcomment-46267761",
|
||||
"id": 46267761,
|
||||
"node_id": "MDEzOkNvbW1pdENvbW1lbnQ0NjI2Nzc2MQ==",
|
||||
"user": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/1958953?v=4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/bitwiseman",
|
||||
"html_url": "https://github.com/bitwiseman",
|
||||
@@ -27,8 +27,8 @@
|
||||
"line": null,
|
||||
"path": null,
|
||||
"commit_id": "8ae38db0ea5837313ab5f39d43a6f73de3bd9000",
|
||||
"created_at": "2019-10-26T01:28:59Z",
|
||||
"updated_at": "2019-10-26T01:28:59Z",
|
||||
"created_at": "2021-01-23T06:39:40Z",
|
||||
"updated_at": "2021-01-23T06:39:40Z",
|
||||
"author_association": "NONE",
|
||||
"body": "updated text"
|
||||
}
|
||||
@@ -33,7 +33,7 @@
|
||||
"login": "kohsuke",
|
||||
"id": 50003,
|
||||
"node_id": "MDQ6VXNlcjUwMDAz",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/50003?v=4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/50003?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/kohsuke",
|
||||
"html_url": "https://github.com/kohsuke",
|
||||
@@ -53,7 +53,7 @@
|
||||
"login": "kohsuke",
|
||||
"id": 50003,
|
||||
"node_id": "MDQ6VXNlcjUwMDAz",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/50003?v=4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/50003?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/kohsuke",
|
||||
"html_url": "https://github.com/kohsuke",
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"url": "https://api.github.com/repos/kohsuke/sandbox-ant/comments/35673784",
|
||||
"html_url": "https://github.com/kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000#commitcomment-35673784",
|
||||
"id": 35673784,
|
||||
"node_id": "MDEzOkNvbW1pdENvbW1lbnQzNTY3Mzc4NA==",
|
||||
"url": "https://api.github.com/repos/kohsuke/sandbox-ant/comments/46267761",
|
||||
"html_url": "https://github.com/kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000#commitcomment-46267761",
|
||||
"id": 46267761,
|
||||
"node_id": "MDEzOkNvbW1pdENvbW1lbnQ0NjI2Nzc2MQ==",
|
||||
"user": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/1958953?v=4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/bitwiseman",
|
||||
"html_url": "https://github.com/bitwiseman",
|
||||
@@ -27,8 +27,8 @@
|
||||
"line": null,
|
||||
"path": null,
|
||||
"commit_id": "8ae38db0ea5837313ab5f39d43a6f73de3bd9000",
|
||||
"created_at": "2019-10-26T01:28:59Z",
|
||||
"updated_at": "2019-10-26T01:28:59Z",
|
||||
"created_at": "2021-01-23T06:39:40Z",
|
||||
"updated_at": "2021-01-23T06:39:40Z",
|
||||
"author_association": "NONE",
|
||||
"body": "[testing](http://kohsuse.org/)"
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/1958953?v=4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/bitwiseman",
|
||||
"html_url": "https://github.com/bitwiseman",
|
||||
@@ -23,17 +23,18 @@
|
||||
"location": "Seattle, WA, USA",
|
||||
"email": "bitwiseman@gmail.com",
|
||||
"hireable": null,
|
||||
"bio": "https://twitter.com/bitwiseman",
|
||||
"public_repos": 169,
|
||||
"bio": null,
|
||||
"twitter_username": "bitwiseman",
|
||||
"public_repos": 201,
|
||||
"public_gists": 7,
|
||||
"followers": 139,
|
||||
"following": 9,
|
||||
"followers": 176,
|
||||
"following": 11,
|
||||
"created_at": "2012-07-11T20:38:33Z",
|
||||
"updated_at": "2019-09-24T19:32:29Z",
|
||||
"private_gists": 7,
|
||||
"total_private_repos": 9,
|
||||
"updated_at": "2021-01-22T16:38:42Z",
|
||||
"private_gists": 19,
|
||||
"total_private_repos": 17,
|
||||
"owned_private_repos": 0,
|
||||
"disk_usage": 33697,
|
||||
"disk_usage": 33700,
|
||||
"collaborators": 0,
|
||||
"two_factor_authentication": true,
|
||||
"plan": {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"login": "kohsuke",
|
||||
"id": 50003,
|
||||
"node_id": "MDQ6VXNlcjUwMDAz",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/50003?v=4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/50003?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/kohsuke",
|
||||
"html_url": "https://github.com/kohsuke",
|
||||
@@ -18,16 +18,17 @@
|
||||
"type": "User",
|
||||
"site_admin": false,
|
||||
"name": "Kohsuke Kawaguchi",
|
||||
"company": "CloudBees, Inc.",
|
||||
"blog": "http://www.kohsuke.org/",
|
||||
"company": "@launchableinc ",
|
||||
"blog": "https://www.kohsuke.org/",
|
||||
"location": "San Jose, California",
|
||||
"email": "kk@kohsuke.org",
|
||||
"hireable": null,
|
||||
"bio": null,
|
||||
"public_repos": 257,
|
||||
"public_gists": 109,
|
||||
"followers": 1692,
|
||||
"twitter_username": null,
|
||||
"public_repos": 262,
|
||||
"public_gists": 113,
|
||||
"followers": 1886,
|
||||
"following": 3,
|
||||
"created_at": "2009-01-28T18:53:21Z",
|
||||
"updated_at": "2019-10-25T16:53:26Z"
|
||||
"updated_at": "2021-01-22T19:41:07Z"
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"id": "3fd5d206-9d71-4f2a-bc95-605c06b6f793",
|
||||
"id": "525a2ad5-8560-42d6-b12d-25fa6d7c2806",
|
||||
"name": "repos_kohsuke_sandbox-ant",
|
||||
"request": {
|
||||
"url": "/repos/kohsuke/sandbox-ant",
|
||||
@@ -14,35 +14,35 @@
|
||||
"status": 200,
|
||||
"bodyFileName": "repos_kohsuke_sandbox-ant-3.json",
|
||||
"headers": {
|
||||
"Date": "Sat, 26 Oct 2019 01:28:58 GMT",
|
||||
"Date": "Sat, 23 Jan 2021 06:39:39 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4242",
|
||||
"X-RateLimit-Reset": "1572055286",
|
||||
"Cache-Control": "private, max-age=60, s-maxage=60",
|
||||
"Vary": [
|
||||
"Accept, Authorization, Cookie, X-GitHub-OTP",
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"ETag": "W/\"6d4495f0d482e4612ed1964d37884bce\"",
|
||||
"Last-Modified": "Tue, 13 Aug 2019 14:56:58 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"ETag": "W/\"7ad6797858a55e4d4576e2481c25ba68b88b778461b12575e2c2702cce47585f\"",
|
||||
"last-modified": "Tue, 13 Aug 2019 14:56:58 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "repo",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4945",
|
||||
"X-RateLimit-Reset": "1611386378",
|
||||
"x-ratelimit-used": "55",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"X-GitHub-Request-Id": "CB24:8340:ED2364:116FE52:5DB3A15A"
|
||||
"X-GitHub-Request-Id": "E9F0:5E21:C00DF:DCE23:600BC4AB"
|
||||
}
|
||||
},
|
||||
"uuid": "3fd5d206-9d71-4f2a-bc95-605c06b6f793",
|
||||
"uuid": "525a2ad5-8560-42d6-b12d-25fa6d7c2806",
|
||||
"persistent": true,
|
||||
"insertionIndex": 3
|
||||
}
|
||||
@@ -1,54 +1,54 @@
|
||||
{
|
||||
"id": "70a63f41-02d3-404e-af0b-8e1c3cd00494",
|
||||
"name": "repos_kohsuke_sandbox-ant_comments_35673784",
|
||||
"id": "4eccc8fc-0026-4272-93b8-76a31a95eeb5",
|
||||
"name": "repos_kohsuke_sandbox-ant_comments_46267761",
|
||||
"request": {
|
||||
"url": "/repos/kohsuke/sandbox-ant/comments/35673784",
|
||||
"url": "/repos/kohsuke/sandbox-ant/comments/46267761",
|
||||
"method": "PATCH",
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"body\":\"updated text\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": true
|
||||
}
|
||||
],
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"body\":\"updated text\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "repos_kohsuke_sandbox-ant_comments_35673784-6.json",
|
||||
"bodyFileName": "repos_kohsuke_sandbox-ant_comments_46267761-7.json",
|
||||
"headers": {
|
||||
"Date": "Sat, 26 Oct 2019 01:28:59 GMT",
|
||||
"Date": "Sat, 23 Jan 2021 06:39:41 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4239",
|
||||
"X-RateLimit-Reset": "1572055286",
|
||||
"Cache-Control": "private, max-age=60, s-maxage=60",
|
||||
"Vary": [
|
||||
"Accept, Authorization, Cookie, X-GitHub-OTP",
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"ETag": "W/\"e22c642208efa831e007ec061a30aae3\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"ETag": "W/\"9e8eb640e5722329d90564fe83bd1f435fc96bb91d69f800343394957c050e78\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4941",
|
||||
"X-RateLimit-Reset": "1611386378",
|
||||
"x-ratelimit-used": "59",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"X-GitHub-Request-Id": "CB24:8340:ED23BA:116FEBA:5DB3A15B"
|
||||
"X-GitHub-Request-Id": "E9F0:5E21:C00FF:DCE46:600BC4AC"
|
||||
}
|
||||
},
|
||||
"uuid": "70a63f41-02d3-404e-af0b-8e1c3cd00494",
|
||||
"uuid": "4eccc8fc-0026-4272-93b8-76a31a95eeb5",
|
||||
"persistent": true,
|
||||
"insertionIndex": 6
|
||||
"insertionIndex": 7
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"id": "88c294c8-e966-4052-a675-7bb9038191e0",
|
||||
"name": "repos_kohsuke_sandbox-ant_comments_46267761",
|
||||
"request": {
|
||||
"url": "/repos/kohsuke/sandbox-ant/comments/46267761",
|
||||
"method": "DELETE",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 204,
|
||||
"headers": {
|
||||
"Date": "Sat, 23 Jan 2021 06:39:41 GMT",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "204 No Content",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4940",
|
||||
"X-RateLimit-Reset": "1611386378",
|
||||
"x-ratelimit-used": "60",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"Vary": [
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"X-GitHub-Request-Id": "E9F0:5E21:C010A:DCE4F:600BC4AD"
|
||||
}
|
||||
},
|
||||
"uuid": "88c294c8-e966-4052-a675-7bb9038191e0",
|
||||
"persistent": true,
|
||||
"insertionIndex": 8
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"id": "caa495ce-fc95-43ae-aa52-4b392bbc8beb",
|
||||
"name": "repos_kohsuke_sandbox-ant_comments_46267761_reactions",
|
||||
"request": {
|
||||
"url": "/repos/kohsuke/sandbox-ant/comments/46267761/reactions",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "application/vnd.github.squirrel-girl-preview+json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": "[]",
|
||||
"headers": {
|
||||
"Date": "Sat, 23 Jan 2021 06:39:40 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"Cache-Control": "private, max-age=60, s-maxage=60",
|
||||
"Vary": [
|
||||
"Accept, Authorization, Cookie, X-GitHub-OTP",
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"ETag": "\"7d0253ca51c378ca4fa4839bfd5bb1ac338f28e5ac8f6810cbdc8553513d942f\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "",
|
||||
"X-GitHub-Media-Type": "github.squirrel-girl-preview; format=json",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4942",
|
||||
"X-RateLimit-Reset": "1611386378",
|
||||
"x-ratelimit-used": "58",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"X-GitHub-Request-Id": "E9F0:5E21:C00FA:DCE40:600BC4AC"
|
||||
}
|
||||
},
|
||||
"uuid": "caa495ce-fc95-43ae-aa52-4b392bbc8beb",
|
||||
"persistent": true,
|
||||
"insertionIndex": 6
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"id": "d1822d1b-5505-42ae-ba1d-ae0496d76c19",
|
||||
"id": "7e297839-c637-4c01-a773-27c649765e10",
|
||||
"name": "repos_kohsuke_sandbox-ant_commits_8ae38db0ea5837313ab5f39d43a6f73de3bd9000",
|
||||
"request": {
|
||||
"url": "/repos/kohsuke/sandbox-ant/commits/8ae38db0ea5837313ab5f39d43a6f73de3bd9000",
|
||||
@@ -14,35 +14,35 @@
|
||||
"status": 200,
|
||||
"bodyFileName": "repos_kohsuke_sandbox-ant_commits_8ae38db0ea5837313ab5f39d43a6f73de3bd9000-4.json",
|
||||
"headers": {
|
||||
"Date": "Sat, 26 Oct 2019 01:28:58 GMT",
|
||||
"Date": "Sat, 23 Jan 2021 06:39:40 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4241",
|
||||
"X-RateLimit-Reset": "1572055286",
|
||||
"Cache-Control": "private, max-age=60, s-maxage=60",
|
||||
"Vary": [
|
||||
"Accept, Authorization, Cookie, X-GitHub-OTP",
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"ETag": "W/\"f7ff477379d3449f082c148579824d0f\"",
|
||||
"Last-Modified": "Tue, 24 Apr 2012 22:54:20 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"ETag": "W/\"139c7c0d228567659135acca1ec295558864e921bd0f87cebb65f72058545d99\"",
|
||||
"last-modified": "Tue, 24 Apr 2012 22:54:20 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4944",
|
||||
"X-RateLimit-Reset": "1611386378",
|
||||
"x-ratelimit-used": "56",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"X-GitHub-Request-Id": "CB24:8340:ED2375:116FE66:5DB3A15A"
|
||||
"X-GitHub-Request-Id": "E9F0:5E21:C00E8:DCE27:600BC4AB"
|
||||
}
|
||||
},
|
||||
"uuid": "d1822d1b-5505-42ae-ba1d-ae0496d76c19",
|
||||
"uuid": "7e297839-c637-4c01-a773-27c649765e10",
|
||||
"persistent": true,
|
||||
"insertionIndex": 4
|
||||
}
|
||||
@@ -1,55 +1,55 @@
|
||||
{
|
||||
"id": "62d11eb1-6045-42a7-988a-aae9d9f3800b",
|
||||
"id": "c0911355-a85d-40b9-b291-e0c098407d2e",
|
||||
"name": "repos_kohsuke_sandbox-ant_commits_8ae38db0ea5837313ab5f39d43a6f73de3bd9000_comments",
|
||||
"request": {
|
||||
"url": "/repos/kohsuke/sandbox-ant/commits/8ae38db0ea5837313ab5f39d43a6f73de3bd9000/comments",
|
||||
"method": "POST",
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"body\":\"[testing](http://kohsuse.org/)\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": true
|
||||
}
|
||||
],
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"body\":\"[testing](http://kohsuse.org/)\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 201,
|
||||
"bodyFileName": "repos_kohsuke_sandbox-ant_commits_8ae38db0ea5837313ab5f39d43a6f73de3bd9000_comments-5.json",
|
||||
"headers": {
|
||||
"Date": "Sat, 26 Oct 2019 01:28:59 GMT",
|
||||
"Date": "Sat, 23 Jan 2021 06:39:40 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "201 Created",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4240",
|
||||
"X-RateLimit-Reset": "1572055286",
|
||||
"Cache-Control": "private, max-age=60, s-maxage=60",
|
||||
"Vary": [
|
||||
"Accept, Authorization, Cookie, X-GitHub-OTP",
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"ETag": "\"1ebfc3d7a9cbe1bfbab78c1636ef102a\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"ETag": "\"de435e64b07783ba615db4fd69d86e8c13c4fe1281f1265937cf7b887dad2579\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "",
|
||||
"Location": "https://api.github.com/repos/kohsuke/sandbox-ant/comments/35673784",
|
||||
"Location": "https://api.github.com/repos/kohsuke/sandbox-ant/comments/46267761",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4943",
|
||||
"X-RateLimit-Reset": "1611386378",
|
||||
"x-ratelimit-used": "57",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"X-GitHub-Request-Id": "CB24:8340:ED2399:116FE83:5DB3A15A"
|
||||
"X-GitHub-Request-Id": "E9F0:5E21:C00ED:DCE30:600BC4AC"
|
||||
}
|
||||
},
|
||||
"uuid": "62d11eb1-6045-42a7-988a-aae9d9f3800b",
|
||||
"uuid": "c0911355-a85d-40b9-b291-e0c098407d2e",
|
||||
"persistent": true,
|
||||
"insertionIndex": 5
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"id": "a9b48b44-c9ff-4434-9f98-64195b0c46ce",
|
||||
"id": "4b33e8fd-7ae4-4141-8bfc-96d62e8361dc",
|
||||
"name": "user",
|
||||
"request": {
|
||||
"url": "/user",
|
||||
@@ -14,35 +14,35 @@
|
||||
"status": 200,
|
||||
"bodyFileName": "user-1.json",
|
||||
"headers": {
|
||||
"Date": "Sat, 26 Oct 2019 01:28:58 GMT",
|
||||
"Date": "Sat, 23 Jan 2021 06:39:39 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4245",
|
||||
"X-RateLimit-Reset": "1572055286",
|
||||
"Cache-Control": "private, max-age=60, s-maxage=60",
|
||||
"Vary": [
|
||||
"Accept, Authorization, Cookie, X-GitHub-OTP",
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"ETag": "W/\"8c3d3dcf6fc5f9edaf26c902295396e5\"",
|
||||
"Last-Modified": "Tue, 24 Sep 2019 19:32:29 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"ETag": "W/\"c8b61de8f7b00ef1a040d10e88b51dd065defb82f7d94a95a97b3dbab636edbe\"",
|
||||
"last-modified": "Fri, 22 Jan 2021 16:38:42 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4948",
|
||||
"X-RateLimit-Reset": "1611386378",
|
||||
"x-ratelimit-used": "52",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"X-GitHub-Request-Id": "CB24:8340:ED234A:116FE30:5DB3A15A"
|
||||
"X-GitHub-Request-Id": "E9F0:5E21:C00C9:DCE0A:600BC4AA"
|
||||
}
|
||||
},
|
||||
"uuid": "a9b48b44-c9ff-4434-9f98-64195b0c46ce",
|
||||
"uuid": "4b33e8fd-7ae4-4141-8bfc-96d62e8361dc",
|
||||
"persistent": true,
|
||||
"insertionIndex": 1
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"id": "a4924f94-0b1c-4cb0-bf1f-595ccb78aa41",
|
||||
"id": "bdde4d6a-6b43-4ee2-8e93-4c4ec59bccf4",
|
||||
"name": "users_kohsuke",
|
||||
"request": {
|
||||
"url": "/users/kohsuke",
|
||||
@@ -14,35 +14,35 @@
|
||||
"status": 200,
|
||||
"bodyFileName": "users_kohsuke-2.json",
|
||||
"headers": {
|
||||
"Date": "Sat, 26 Oct 2019 01:28:58 GMT",
|
||||
"Date": "Sat, 23 Jan 2021 06:39:39 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4243",
|
||||
"X-RateLimit-Reset": "1572055286",
|
||||
"Cache-Control": "private, max-age=60, s-maxage=60",
|
||||
"Vary": [
|
||||
"Accept, Authorization, Cookie, X-GitHub-OTP",
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"ETag": "W/\"99c27226f3b6139ef2af80ccbcd5d252\"",
|
||||
"Last-Modified": "Fri, 25 Oct 2019 16:53:26 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"ETag": "W/\"e41eed9772453b3fbbdb7bba892d24e645750ddd73b3a74c68106566916b3312\"",
|
||||
"last-modified": "Fri, 22 Jan 2021 19:41:07 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4946",
|
||||
"X-RateLimit-Reset": "1611386378",
|
||||
"x-ratelimit-used": "54",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"X-GitHub-Request-Id": "CB24:8340:ED235B:116FE3C:5DB3A15A"
|
||||
"X-GitHub-Request-Id": "E9F0:5E21:C00DB:DCE0C:600BC4AB"
|
||||
}
|
||||
},
|
||||
"uuid": "a4924f94-0b1c-4cb0-bf1f-595ccb78aa41",
|
||||
"uuid": "bdde4d6a-6b43-4ee2-8e93-4c4ec59bccf4",
|
||||
"persistent": true,
|
||||
"insertionIndex": 2
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
{
|
||||
"id": 197345677,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnkxOTczNDU2Nzc=",
|
||||
"name": "lerna",
|
||||
"full_name": "daddyfatstacksBIG/lerna",
|
||||
"private": false,
|
||||
"owner": {
|
||||
"login": "daddyfatstacksBIG",
|
||||
"id": 50436469,
|
||||
"node_id": "MDQ6VXNlcjUwNDM2NDY5",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/50436469?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/daddyfatstacksBIG",
|
||||
"html_url": "https://github.com/daddyfatstacksBIG",
|
||||
"followers_url": "https://api.github.com/users/daddyfatstacksBIG/followers",
|
||||
"following_url": "https://api.github.com/users/daddyfatstacksBIG/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/daddyfatstacksBIG/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/daddyfatstacksBIG/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/daddyfatstacksBIG/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/daddyfatstacksBIG/orgs",
|
||||
"repos_url": "https://api.github.com/users/daddyfatstacksBIG/repos",
|
||||
"events_url": "https://api.github.com/users/daddyfatstacksBIG/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/daddyfatstacksBIG/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"html_url": "https://github.com/daddyfatstacksBIG/lerna",
|
||||
"description": ":dragon: A tool for managing JavaScript projects with multiple packages.",
|
||||
"fork": true,
|
||||
"url": "https://api.github.com/repos/daddyfatstacksBIG/lerna",
|
||||
"forks_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/forks",
|
||||
"keys_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/keys{/key_id}",
|
||||
"collaborators_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/collaborators{/collaborator}",
|
||||
"teams_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/teams",
|
||||
"hooks_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/hooks",
|
||||
"issue_events_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/issues/events{/number}",
|
||||
"events_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/events",
|
||||
"assignees_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/assignees{/user}",
|
||||
"branches_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/branches{/branch}",
|
||||
"tags_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/tags",
|
||||
"blobs_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/git/blobs{/sha}",
|
||||
"git_tags_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/git/tags{/sha}",
|
||||
"git_refs_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/git/refs{/sha}",
|
||||
"trees_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/git/trees{/sha}",
|
||||
"statuses_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/statuses/{sha}",
|
||||
"languages_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/languages",
|
||||
"stargazers_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/stargazers",
|
||||
"contributors_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/contributors",
|
||||
"subscribers_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/subscribers",
|
||||
"subscription_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/subscription",
|
||||
"commits_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/commits{/sha}",
|
||||
"git_commits_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/git/commits{/sha}",
|
||||
"comments_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/comments{/number}",
|
||||
"issue_comment_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/issues/comments{/number}",
|
||||
"contents_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/contents/{+path}",
|
||||
"compare_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/compare/{base}...{head}",
|
||||
"merges_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/merges",
|
||||
"archive_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/{archive_format}{/ref}",
|
||||
"downloads_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/downloads",
|
||||
"issues_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/issues{/number}",
|
||||
"pulls_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/pulls{/number}",
|
||||
"milestones_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/milestones{/number}",
|
||||
"notifications_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/notifications{?since,all,participating}",
|
||||
"labels_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/labels{/name}",
|
||||
"releases_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/releases{/id}",
|
||||
"deployments_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/deployments",
|
||||
"created_at": "2019-07-17T08:14:07Z",
|
||||
"updated_at": "2020-06-09T04:42:07Z",
|
||||
"pushed_at": "2020-06-09T04:42:04Z",
|
||||
"git_url": "git://github.com/daddyfatstacksBIG/lerna.git",
|
||||
"ssh_url": "git@github.com:daddyfatstacksBIG/lerna.git",
|
||||
"clone_url": "https://github.com/daddyfatstacksBIG/lerna.git",
|
||||
"svn_url": "https://github.com/daddyfatstacksBIG/lerna",
|
||||
"homepage": "https://lerna.js.org",
|
||||
"size": 8388,
|
||||
"stargazers_count": 0,
|
||||
"watchers_count": 0,
|
||||
"language": "JavaScript",
|
||||
"has_issues": false,
|
||||
"has_projects": true,
|
||||
"has_downloads": true,
|
||||
"has_wiki": false,
|
||||
"has_pages": false,
|
||||
"forks_count": 0,
|
||||
"mirror_url": null,
|
||||
"archived": false,
|
||||
"disabled": false,
|
||||
"open_issues_count": 1,
|
||||
"license": {
|
||||
"key": "mit",
|
||||
"name": "MIT License",
|
||||
"spdx_id": "MIT",
|
||||
"url": "https://api.github.com/licenses/mit",
|
||||
"node_id": "MDc6TGljZW5zZTEz"
|
||||
},
|
||||
"forks": 0,
|
||||
"open_issues": 1,
|
||||
"watchers": 0,
|
||||
"default_branch": "master",
|
||||
"permissions": {
|
||||
"admin": false,
|
||||
"push": false,
|
||||
"pull": true
|
||||
},
|
||||
"temp_clone_token": "",
|
||||
"parent": {
|
||||
"id": 47394776,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnk0NzM5NDc3Ng==",
|
||||
"name": "lerna",
|
||||
"full_name": "lerna/lerna",
|
||||
"private": false,
|
||||
"owner": {
|
||||
"login": "lerna",
|
||||
"id": 19333396,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE5MzMzMzk2",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/19333396?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/lerna",
|
||||
"html_url": "https://github.com/lerna",
|
||||
"followers_url": "https://api.github.com/users/lerna/followers",
|
||||
"following_url": "https://api.github.com/users/lerna/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/lerna/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/lerna/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/lerna/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/lerna/orgs",
|
||||
"repos_url": "https://api.github.com/users/lerna/repos",
|
||||
"events_url": "https://api.github.com/users/lerna/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/lerna/received_events",
|
||||
"type": "Organization",
|
||||
"site_admin": false
|
||||
},
|
||||
"html_url": "https://github.com/lerna/lerna",
|
||||
"description": ":dragon: A tool for managing JavaScript projects with multiple packages.",
|
||||
"fork": false,
|
||||
"url": "https://api.github.com/repos/lerna/lerna",
|
||||
"forks_url": "https://api.github.com/repos/lerna/lerna/forks",
|
||||
"keys_url": "https://api.github.com/repos/lerna/lerna/keys{/key_id}",
|
||||
"collaborators_url": "https://api.github.com/repos/lerna/lerna/collaborators{/collaborator}",
|
||||
"teams_url": "https://api.github.com/repos/lerna/lerna/teams",
|
||||
"hooks_url": "https://api.github.com/repos/lerna/lerna/hooks",
|
||||
"issue_events_url": "https://api.github.com/repos/lerna/lerna/issues/events{/number}",
|
||||
"events_url": "https://api.github.com/repos/lerna/lerna/events",
|
||||
"assignees_url": "https://api.github.com/repos/lerna/lerna/assignees{/user}",
|
||||
"branches_url": "https://api.github.com/repos/lerna/lerna/branches{/branch}",
|
||||
"tags_url": "https://api.github.com/repos/lerna/lerna/tags",
|
||||
"blobs_url": "https://api.github.com/repos/lerna/lerna/git/blobs{/sha}",
|
||||
"git_tags_url": "https://api.github.com/repos/lerna/lerna/git/tags{/sha}",
|
||||
"git_refs_url": "https://api.github.com/repos/lerna/lerna/git/refs{/sha}",
|
||||
"trees_url": "https://api.github.com/repos/lerna/lerna/git/trees{/sha}",
|
||||
"statuses_url": "https://api.github.com/repos/lerna/lerna/statuses/{sha}",
|
||||
"languages_url": "https://api.github.com/repos/lerna/lerna/languages",
|
||||
"stargazers_url": "https://api.github.com/repos/lerna/lerna/stargazers",
|
||||
"contributors_url": "https://api.github.com/repos/lerna/lerna/contributors",
|
||||
"subscribers_url": "https://api.github.com/repos/lerna/lerna/subscribers",
|
||||
"subscription_url": "https://api.github.com/repos/lerna/lerna/subscription",
|
||||
"commits_url": "https://api.github.com/repos/lerna/lerna/commits{/sha}",
|
||||
"git_commits_url": "https://api.github.com/repos/lerna/lerna/git/commits{/sha}",
|
||||
"comments_url": "https://api.github.com/repos/lerna/lerna/comments{/number}",
|
||||
"issue_comment_url": "https://api.github.com/repos/lerna/lerna/issues/comments{/number}",
|
||||
"contents_url": "https://api.github.com/repos/lerna/lerna/contents/{+path}",
|
||||
"compare_url": "https://api.github.com/repos/lerna/lerna/compare/{base}...{head}",
|
||||
"merges_url": "https://api.github.com/repos/lerna/lerna/merges",
|
||||
"archive_url": "https://api.github.com/repos/lerna/lerna/{archive_format}{/ref}",
|
||||
"downloads_url": "https://api.github.com/repos/lerna/lerna/downloads",
|
||||
"issues_url": "https://api.github.com/repos/lerna/lerna/issues{/number}",
|
||||
"pulls_url": "https://api.github.com/repos/lerna/lerna/pulls{/number}",
|
||||
"milestones_url": "https://api.github.com/repos/lerna/lerna/milestones{/number}",
|
||||
"notifications_url": "https://api.github.com/repos/lerna/lerna/notifications{?since,all,participating}",
|
||||
"labels_url": "https://api.github.com/repos/lerna/lerna/labels{/name}",
|
||||
"releases_url": "https://api.github.com/repos/lerna/lerna/releases{/id}",
|
||||
"deployments_url": "https://api.github.com/repos/lerna/lerna/deployments",
|
||||
"created_at": "2015-12-04T09:36:55Z",
|
||||
"updated_at": "2021-01-14T22:58:27Z",
|
||||
"pushed_at": "2021-01-09T20:24:41Z",
|
||||
"git_url": "git://github.com/lerna/lerna.git",
|
||||
"ssh_url": "git@github.com:lerna/lerna.git",
|
||||
"clone_url": "https://github.com/lerna/lerna.git",
|
||||
"svn_url": "https://github.com/lerna/lerna",
|
||||
"homepage": "https://lerna.js.org",
|
||||
"size": 10634,
|
||||
"stargazers_count": 26245,
|
||||
"watchers_count": 26245,
|
||||
"language": "JavaScript",
|
||||
"has_issues": true,
|
||||
"has_projects": true,
|
||||
"has_downloads": true,
|
||||
"has_wiki": false,
|
||||
"has_pages": false,
|
||||
"forks_count": 1674,
|
||||
"mirror_url": null,
|
||||
"archived": false,
|
||||
"disabled": false,
|
||||
"open_issues_count": 564,
|
||||
"license": {
|
||||
"key": "mit",
|
||||
"name": "MIT License",
|
||||
"spdx_id": "MIT",
|
||||
"url": "https://api.github.com/licenses/mit",
|
||||
"node_id": "MDc6TGljZW5zZTEz"
|
||||
},
|
||||
"forks": 1674,
|
||||
"open_issues": 564,
|
||||
"watchers": 26245,
|
||||
"default_branch": "main"
|
||||
},
|
||||
"source": {
|
||||
"id": 47394776,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnk0NzM5NDc3Ng==",
|
||||
"name": "lerna",
|
||||
"full_name": "lerna/lerna",
|
||||
"private": false,
|
||||
"owner": {
|
||||
"login": "lerna",
|
||||
"id": 19333396,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE5MzMzMzk2",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/19333396?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/lerna",
|
||||
"html_url": "https://github.com/lerna",
|
||||
"followers_url": "https://api.github.com/users/lerna/followers",
|
||||
"following_url": "https://api.github.com/users/lerna/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/lerna/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/lerna/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/lerna/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/lerna/orgs",
|
||||
"repos_url": "https://api.github.com/users/lerna/repos",
|
||||
"events_url": "https://api.github.com/users/lerna/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/lerna/received_events",
|
||||
"type": "Organization",
|
||||
"site_admin": false
|
||||
},
|
||||
"html_url": "https://github.com/lerna/lerna",
|
||||
"description": ":dragon: A tool for managing JavaScript projects with multiple packages.",
|
||||
"fork": false,
|
||||
"url": "https://api.github.com/repos/lerna/lerna",
|
||||
"forks_url": "https://api.github.com/repos/lerna/lerna/forks",
|
||||
"keys_url": "https://api.github.com/repos/lerna/lerna/keys{/key_id}",
|
||||
"collaborators_url": "https://api.github.com/repos/lerna/lerna/collaborators{/collaborator}",
|
||||
"teams_url": "https://api.github.com/repos/lerna/lerna/teams",
|
||||
"hooks_url": "https://api.github.com/repos/lerna/lerna/hooks",
|
||||
"issue_events_url": "https://api.github.com/repos/lerna/lerna/issues/events{/number}",
|
||||
"events_url": "https://api.github.com/repos/lerna/lerna/events",
|
||||
"assignees_url": "https://api.github.com/repos/lerna/lerna/assignees{/user}",
|
||||
"branches_url": "https://api.github.com/repos/lerna/lerna/branches{/branch}",
|
||||
"tags_url": "https://api.github.com/repos/lerna/lerna/tags",
|
||||
"blobs_url": "https://api.github.com/repos/lerna/lerna/git/blobs{/sha}",
|
||||
"git_tags_url": "https://api.github.com/repos/lerna/lerna/git/tags{/sha}",
|
||||
"git_refs_url": "https://api.github.com/repos/lerna/lerna/git/refs{/sha}",
|
||||
"trees_url": "https://api.github.com/repos/lerna/lerna/git/trees{/sha}",
|
||||
"statuses_url": "https://api.github.com/repos/lerna/lerna/statuses/{sha}",
|
||||
"languages_url": "https://api.github.com/repos/lerna/lerna/languages",
|
||||
"stargazers_url": "https://api.github.com/repos/lerna/lerna/stargazers",
|
||||
"contributors_url": "https://api.github.com/repos/lerna/lerna/contributors",
|
||||
"subscribers_url": "https://api.github.com/repos/lerna/lerna/subscribers",
|
||||
"subscription_url": "https://api.github.com/repos/lerna/lerna/subscription",
|
||||
"commits_url": "https://api.github.com/repos/lerna/lerna/commits{/sha}",
|
||||
"git_commits_url": "https://api.github.com/repos/lerna/lerna/git/commits{/sha}",
|
||||
"comments_url": "https://api.github.com/repos/lerna/lerna/comments{/number}",
|
||||
"issue_comment_url": "https://api.github.com/repos/lerna/lerna/issues/comments{/number}",
|
||||
"contents_url": "https://api.github.com/repos/lerna/lerna/contents/{+path}",
|
||||
"compare_url": "https://api.github.com/repos/lerna/lerna/compare/{base}...{head}",
|
||||
"merges_url": "https://api.github.com/repos/lerna/lerna/merges",
|
||||
"archive_url": "https://api.github.com/repos/lerna/lerna/{archive_format}{/ref}",
|
||||
"downloads_url": "https://api.github.com/repos/lerna/lerna/downloads",
|
||||
"issues_url": "https://api.github.com/repos/lerna/lerna/issues{/number}",
|
||||
"pulls_url": "https://api.github.com/repos/lerna/lerna/pulls{/number}",
|
||||
"milestones_url": "https://api.github.com/repos/lerna/lerna/milestones{/number}",
|
||||
"notifications_url": "https://api.github.com/repos/lerna/lerna/notifications{?since,all,participating}",
|
||||
"labels_url": "https://api.github.com/repos/lerna/lerna/labels{/name}",
|
||||
"releases_url": "https://api.github.com/repos/lerna/lerna/releases{/id}",
|
||||
"deployments_url": "https://api.github.com/repos/lerna/lerna/deployments",
|
||||
"created_at": "2015-12-04T09:36:55Z",
|
||||
"updated_at": "2021-01-14T22:58:27Z",
|
||||
"pushed_at": "2021-01-09T20:24:41Z",
|
||||
"git_url": "git://github.com/lerna/lerna.git",
|
||||
"ssh_url": "git@github.com:lerna/lerna.git",
|
||||
"clone_url": "https://github.com/lerna/lerna.git",
|
||||
"svn_url": "https://github.com/lerna/lerna",
|
||||
"homepage": "https://lerna.js.org",
|
||||
"size": 10634,
|
||||
"stargazers_count": 26245,
|
||||
"watchers_count": 26245,
|
||||
"language": "JavaScript",
|
||||
"has_issues": true,
|
||||
"has_projects": true,
|
||||
"has_downloads": true,
|
||||
"has_wiki": false,
|
||||
"has_pages": false,
|
||||
"forks_count": 1674,
|
||||
"mirror_url": null,
|
||||
"archived": false,
|
||||
"disabled": false,
|
||||
"open_issues_count": 564,
|
||||
"license": {
|
||||
"key": "mit",
|
||||
"name": "MIT License",
|
||||
"spdx_id": "MIT",
|
||||
"url": "https://api.github.com/licenses/mit",
|
||||
"node_id": "MDc6TGljZW5zZTEz"
|
||||
},
|
||||
"forks": 1674,
|
||||
"open_issues": 564,
|
||||
"watchers": 26245,
|
||||
"default_branch": "main"
|
||||
},
|
||||
"network_count": 1674,
|
||||
"subscribers_count": 0
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"id": "c536ef14-9fde-4a95-ae89-43f6753e4f2a",
|
||||
"name": "repos_daddyfatstacksbig_lerna",
|
||||
"request": {
|
||||
"url": "/repos/daddyfatstacksBIG/lerna",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "repos_daddyfatstacksbig_lerna-12.json",
|
||||
"headers": {
|
||||
"Date": "Fri, 15 Jan 2021 02:18:27 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"Cache-Control": "private, max-age=60, s-maxage=60",
|
||||
"Vary": [
|
||||
"Accept, Authorization, Cookie, X-GitHub-OTP",
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"ETag": "W/\"a9b6035f2bfdf3830acbea545b9a837965158f59ac8cf616563e29681b0f0098\"",
|
||||
"last-modified": "Tue, 09 Jun 2020 04:42:07 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "repo",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4777",
|
||||
"X-RateLimit-Reset": "1610678593",
|
||||
"x-ratelimit-used": "223",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"X-GitHub-Request-Id": "D91F:62A3:2C8A07:3712B1:6000FB73"
|
||||
}
|
||||
},
|
||||
"uuid": "c536ef14-9fde-4a95-ae89-43f6753e4f2a",
|
||||
"persistent": true,
|
||||
"insertionIndex": 12
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
{
|
||||
"id": 332135466,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnkzMzIxMzU0NjY=",
|
||||
"name": "github-api-test",
|
||||
"full_name": "hub4j-test-org/github-api-test",
|
||||
"private": false,
|
||||
"owner": {
|
||||
"login": "hub4j-test-org",
|
||||
"id": 7544739,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/hub4j-test-org",
|
||||
"html_url": "https://github.com/hub4j-test-org",
|
||||
"followers_url": "https://api.github.com/users/hub4j-test-org/followers",
|
||||
"following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/hub4j-test-org/orgs",
|
||||
"repos_url": "https://api.github.com/users/hub4j-test-org/repos",
|
||||
"events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/hub4j-test-org/received_events",
|
||||
"type": "Organization",
|
||||
"site_admin": false
|
||||
},
|
||||
"html_url": "https://github.com/hub4j-test-org/github-api-test",
|
||||
"description": "A test repository for testing the github-api project: github-api-test",
|
||||
"fork": false,
|
||||
"url": "https://api.github.com/repos/hub4j-test-org/github-api-test",
|
||||
"forks_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/forks",
|
||||
"keys_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/keys{/key_id}",
|
||||
"collaborators_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/collaborators{/collaborator}",
|
||||
"teams_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/teams",
|
||||
"hooks_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/hooks",
|
||||
"issue_events_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/issues/events{/number}",
|
||||
"events_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/events",
|
||||
"assignees_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/assignees{/user}",
|
||||
"branches_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/branches{/branch}",
|
||||
"tags_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/tags",
|
||||
"blobs_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/git/blobs{/sha}",
|
||||
"git_tags_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/git/tags{/sha}",
|
||||
"git_refs_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/git/refs{/sha}",
|
||||
"trees_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/git/trees{/sha}",
|
||||
"statuses_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/statuses/{sha}",
|
||||
"languages_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/languages",
|
||||
"stargazers_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/stargazers",
|
||||
"contributors_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/contributors",
|
||||
"subscribers_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/subscribers",
|
||||
"subscription_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/subscription",
|
||||
"commits_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/commits{/sha}",
|
||||
"git_commits_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/git/commits{/sha}",
|
||||
"comments_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/comments{/number}",
|
||||
"issue_comment_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/issues/comments{/number}",
|
||||
"contents_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/contents/{+path}",
|
||||
"compare_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/compare/{base}...{head}",
|
||||
"merges_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/merges",
|
||||
"archive_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/{archive_format}{/ref}",
|
||||
"downloads_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/downloads",
|
||||
"issues_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/issues{/number}",
|
||||
"pulls_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/pulls{/number}",
|
||||
"milestones_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/milestones{/number}",
|
||||
"notifications_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/notifications{?since,all,participating}",
|
||||
"labels_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/labels{/name}",
|
||||
"releases_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/releases{/id}",
|
||||
"deployments_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments",
|
||||
"created_at": "2021-01-23T05:30:48Z",
|
||||
"updated_at": "2021-01-23T05:30:52Z",
|
||||
"pushed_at": "2021-01-23T05:30:50Z",
|
||||
"git_url": "git://github.com/hub4j-test-org/github-api-test.git",
|
||||
"ssh_url": "git@github.com:hub4j-test-org/github-api-test.git",
|
||||
"clone_url": "https://github.com/hub4j-test-org/github-api-test.git",
|
||||
"svn_url": "https://github.com/hub4j-test-org/github-api-test",
|
||||
"homepage": "http://github-api.kohsuke.org/",
|
||||
"size": 0,
|
||||
"stargazers_count": 0,
|
||||
"watchers_count": 0,
|
||||
"language": null,
|
||||
"has_issues": true,
|
||||
"has_projects": true,
|
||||
"has_downloads": true,
|
||||
"has_wiki": true,
|
||||
"has_pages": false,
|
||||
"forks_count": 0,
|
||||
"mirror_url": null,
|
||||
"archived": false,
|
||||
"disabled": false,
|
||||
"open_issues_count": 0,
|
||||
"license": null,
|
||||
"forks": 0,
|
||||
"open_issues": 0,
|
||||
"watchers": 0,
|
||||
"default_branch": "main",
|
||||
"permissions": {
|
||||
"admin": true,
|
||||
"push": true,
|
||||
"pull": true
|
||||
},
|
||||
"temp_clone_token": "",
|
||||
"allow_squash_merge": true,
|
||||
"allow_merge_commit": true,
|
||||
"allow_rebase_merge": true,
|
||||
"delete_branch_on_merge": false,
|
||||
"organization": {
|
||||
"login": "hub4j-test-org",
|
||||
"id": 7544739,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/hub4j-test-org",
|
||||
"html_url": "https://github.com/hub4j-test-org",
|
||||
"followers_url": "https://api.github.com/users/hub4j-test-org/followers",
|
||||
"following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/hub4j-test-org/orgs",
|
||||
"repos_url": "https://api.github.com/users/hub4j-test-org/repos",
|
||||
"events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/hub4j-test-org/received_events",
|
||||
"type": "Organization",
|
||||
"site_admin": false
|
||||
},
|
||||
"network_count": 0,
|
||||
"subscribers_count": 9
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601644",
|
||||
"id": 315601644,
|
||||
"node_id": "MDEwOkRlcGxveW1lbnQzMTU2MDE2NDQ=",
|
||||
"task": "deploy",
|
||||
"original_environment": "production",
|
||||
"environment": "production",
|
||||
"description": "question",
|
||||
"created_at": "2021-01-23T05:30:54Z",
|
||||
"updated_at": "2021-01-23T05:30:54Z",
|
||||
"statuses_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601644/statuses",
|
||||
"repository_url": "https://api.github.com/repos/hub4j-test-org/github-api-test",
|
||||
"creator": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/bitwiseman",
|
||||
"html_url": "https://github.com/bitwiseman",
|
||||
"followers_url": "https://api.github.com/users/bitwiseman/followers",
|
||||
"following_url": "https://api.github.com/users/bitwiseman/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/bitwiseman/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/bitwiseman/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/bitwiseman/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/bitwiseman/orgs",
|
||||
"repos_url": "https://api.github.com/users/bitwiseman/repos",
|
||||
"events_url": "https://api.github.com/users/bitwiseman/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/bitwiseman/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"sha": "3ca6395616e9decaba9f350f59eb5b007462e2e7",
|
||||
"ref": "main",
|
||||
"payload": "{\"user\":\"atmos\",\"room_id\":123456}",
|
||||
"transient_environment": false,
|
||||
"production_environment": false,
|
||||
"performed_via_github_app": null
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601644/statuses/466129562",
|
||||
"id": 466129562,
|
||||
"node_id": "MDE2OkRlcGxveW1lbnRTdGF0dXM0NjYxMjk1NjI=",
|
||||
"state": "queued",
|
||||
"creator": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/bitwiseman",
|
||||
"html_url": "https://github.com/bitwiseman",
|
||||
"followers_url": "https://api.github.com/users/bitwiseman/followers",
|
||||
"following_url": "https://api.github.com/users/bitwiseman/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/bitwiseman/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/bitwiseman/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/bitwiseman/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/bitwiseman/orgs",
|
||||
"repos_url": "https://api.github.com/users/bitwiseman/repos",
|
||||
"events_url": "https://api.github.com/users/bitwiseman/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/bitwiseman/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"description": "success",
|
||||
"environment": "new-ci-env",
|
||||
"target_url": "http://www.github.com/logurl",
|
||||
"created_at": "2021-01-23T05:30:54Z",
|
||||
"updated_at": "2021-01-23T05:30:55Z",
|
||||
"deployment_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601644",
|
||||
"repository_url": "https://api.github.com/repos/hub4j-test-org/github-api-test",
|
||||
"environment_url": "http://www.github.com/envurl",
|
||||
"log_url": "http://www.github.com/logurl",
|
||||
"performed_via_github_app": null
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
[
|
||||
{
|
||||
"url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601644/statuses/466129562",
|
||||
"id": 466129562,
|
||||
"node_id": "MDE2OkRlcGxveW1lbnRTdGF0dXM0NjYxMjk1NjI=",
|
||||
"state": "queued",
|
||||
"creator": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/bitwiseman",
|
||||
"html_url": "https://github.com/bitwiseman",
|
||||
"followers_url": "https://api.github.com/users/bitwiseman/followers",
|
||||
"following_url": "https://api.github.com/users/bitwiseman/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/bitwiseman/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/bitwiseman/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/bitwiseman/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/bitwiseman/orgs",
|
||||
"repos_url": "https://api.github.com/users/bitwiseman/repos",
|
||||
"events_url": "https://api.github.com/users/bitwiseman/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/bitwiseman/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"description": "success",
|
||||
"environment": "new-ci-env",
|
||||
"target_url": "http://www.github.com/logurl",
|
||||
"created_at": "2021-01-23T05:30:54Z",
|
||||
"updated_at": "2021-01-23T05:30:55Z",
|
||||
"deployment_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601644",
|
||||
"repository_url": "https://api.github.com/repos/hub4j-test-org/github-api-test",
|
||||
"environment_url": "http://www.github.com/envurl",
|
||||
"log_url": "http://www.github.com/logurl",
|
||||
"performed_via_github_app": null
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,38 @@
|
||||
[
|
||||
{
|
||||
"url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601644/statuses/466129562",
|
||||
"id": 466129562,
|
||||
"node_id": "MDE2OkRlcGxveW1lbnRTdGF0dXM0NjYxMjk1NjI=",
|
||||
"state": "queued",
|
||||
"creator": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/bitwiseman",
|
||||
"html_url": "https://github.com/bitwiseman",
|
||||
"followers_url": "https://api.github.com/users/bitwiseman/followers",
|
||||
"following_url": "https://api.github.com/users/bitwiseman/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/bitwiseman/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/bitwiseman/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/bitwiseman/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/bitwiseman/orgs",
|
||||
"repos_url": "https://api.github.com/users/bitwiseman/repos",
|
||||
"events_url": "https://api.github.com/users/bitwiseman/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/bitwiseman/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"description": "success",
|
||||
"environment": "new-ci-env",
|
||||
"target_url": "http://www.github.com/logurl",
|
||||
"created_at": "2021-01-23T05:30:54Z",
|
||||
"updated_at": "2021-01-23T05:30:55Z",
|
||||
"deployment_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601644",
|
||||
"repository_url": "https://api.github.com/repos/hub4j-test-org/github-api-test",
|
||||
"environment_url": "http://www.github.com/envurl",
|
||||
"log_url": "http://www.github.com/logurl",
|
||||
"performed_via_github_app": null
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/bitwiseman",
|
||||
"html_url": "https://github.com/bitwiseman",
|
||||
"followers_url": "https://api.github.com/users/bitwiseman/followers",
|
||||
"following_url": "https://api.github.com/users/bitwiseman/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/bitwiseman/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/bitwiseman/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/bitwiseman/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/bitwiseman/orgs",
|
||||
"repos_url": "https://api.github.com/users/bitwiseman/repos",
|
||||
"events_url": "https://api.github.com/users/bitwiseman/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/bitwiseman/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false,
|
||||
"name": "Liam Newman",
|
||||
"company": "Cloudbees, Inc.",
|
||||
"blog": "",
|
||||
"location": "Seattle, WA, USA",
|
||||
"email": "bitwiseman@gmail.com",
|
||||
"hireable": null,
|
||||
"bio": null,
|
||||
"twitter_username": "bitwiseman",
|
||||
"public_repos": 201,
|
||||
"public_gists": 7,
|
||||
"followers": 176,
|
||||
"following": 11,
|
||||
"created_at": "2012-07-11T20:38:33Z",
|
||||
"updated_at": "2021-01-22T16:38:42Z",
|
||||
"private_gists": 19,
|
||||
"total_private_repos": 17,
|
||||
"owned_private_repos": 0,
|
||||
"disk_usage": 33700,
|
||||
"collaborators": 0,
|
||||
"two_factor_authentication": true,
|
||||
"plan": {
|
||||
"name": "free",
|
||||
"space": 976562499,
|
||||
"collaborators": 0,
|
||||
"private_repos": 10000
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"id": "ee5eaa4c-2198-4866-9907-c45dc471ccb1",
|
||||
"name": "repos_hub4j-test-org_github-api-test",
|
||||
"request": {
|
||||
"url": "/repos/hub4j-test-org/github-api-test",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "repos_hub4j-test-org_github-api-test-2.json",
|
||||
"headers": {
|
||||
"Date": "Sat, 23 Jan 2021 05:30:54 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"Cache-Control": "private, max-age=60, s-maxage=60",
|
||||
"Vary": [
|
||||
"Accept, Authorization, Cookie, X-GitHub-OTP",
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"ETag": "W/\"92c703ce3aa8785f4b7b9690174f87593bcf624a3363400ae4820270d5ffa36d\"",
|
||||
"last-modified": "Sat, 23 Jan 2021 05:30:52 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "repo",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4893",
|
||||
"X-RateLimit-Reset": "1611382753",
|
||||
"x-ratelimit-used": "107",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"X-GitHub-Request-Id": "DA01:86BF:FC55C:128201:600BB487"
|
||||
}
|
||||
},
|
||||
"uuid": "ee5eaa4c-2198-4866-9907-c45dc471ccb1",
|
||||
"persistent": true,
|
||||
"insertionIndex": 2
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"id": "33e256b4-e4f3-4cf8-8085-d58dd8b6ff48",
|
||||
"name": "repos_hub4j-test-org_github-api-test_deployments",
|
||||
"request": {
|
||||
"url": "/repos/hub4j-test-org/github-api-test/deployments",
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "application/vnd.github.ant-man-preview+json, application/vnd.github.flash-preview+json"
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"ref\":\"main\",\"payload\":\"{\\\"user\\\":\\\"atmos\\\",\\\"room_id\\\":123456}\",\"description\":\"question\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 201,
|
||||
"bodyFileName": "repos_hub4j-test-org_github-api-test_deployments-3.json",
|
||||
"headers": {
|
||||
"Date": "Sat, 23 Jan 2021 05:30:54 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "201 Created",
|
||||
"Cache-Control": "private, max-age=60, s-maxage=60",
|
||||
"Vary": [
|
||||
"Accept, Authorization, Cookie, X-GitHub-OTP",
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"ETag": "\"97fe2f224099c43ac13e32503d65c8a24665a79e620f11e4fe5c8a3185da75b3\"",
|
||||
"last-modified": "Sat, 23 Jan 2021 05:30:54 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "",
|
||||
"Location": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601644",
|
||||
"X-GitHub-Media-Type": "github.ant-man-preview; format=json, github.flash-preview; format=json",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4892",
|
||||
"X-RateLimit-Reset": "1611382753",
|
||||
"x-ratelimit-used": "108",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"X-GitHub-Request-Id": "DA01:86BF:FC56F:128397:600BB48E"
|
||||
}
|
||||
},
|
||||
"uuid": "33e256b4-e4f3-4cf8-8085-d58dd8b6ff48",
|
||||
"persistent": true,
|
||||
"insertionIndex": 3
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"id": "1e9db334-efda-432b-890e-c9b513935a0b",
|
||||
"name": "repos_kohsuke_sandbox-ant_comments_35673784",
|
||||
"id": "a7a78388-4c8f-4b5d-8eb3-c1bf881b3227",
|
||||
"name": "repos_hub4j-test-org_github-api-test_deployments_315601644",
|
||||
"request": {
|
||||
"url": "/repos/kohsuke/sandbox-ant/comments/35673784",
|
||||
"url": "/repos/hub4j-test-org/github-api-test/deployments/315601644",
|
||||
"method": "DELETE",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
@@ -13,28 +13,30 @@
|
||||
"response": {
|
||||
"status": 204,
|
||||
"headers": {
|
||||
"Date": "Sat, 26 Oct 2019 01:29:00 GMT",
|
||||
"Date": "Sat, 23 Jan 2021 05:30:55 GMT",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "204 No Content",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4238",
|
||||
"X-RateLimit-Reset": "1572055286",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4888",
|
||||
"X-RateLimit-Reset": "1611382753",
|
||||
"x-ratelimit-used": "112",
|
||||
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
|
||||
"X-Frame-Options": "deny",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
|
||||
"Content-Security-Policy": "default-src 'none'",
|
||||
"Vary": "Accept-Encoding",
|
||||
"X-GitHub-Request-Id": "CB24:8340:ED23D1:116FED8:5DB3A15B"
|
||||
"Vary": [
|
||||
"Accept-Encoding, Accept, X-Requested-With",
|
||||
"Accept-Encoding"
|
||||
],
|
||||
"X-GitHub-Request-Id": "DA01:86BF:FC594:1283D2:600BB48F"
|
||||
}
|
||||
},
|
||||
"uuid": "1e9db334-efda-432b-890e-c9b513935a0b",
|
||||
"uuid": "a7a78388-4c8f-4b5d-8eb3-c1bf881b3227",
|
||||
"persistent": true,
|
||||
"insertionIndex": 7
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user