mirror of
https://github.com/jlengrand/github-api.git
synced 2026-03-12 08:21:22 +00:00
Compare commits
123 Commits
github-api
...
github-api
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2844542efa | ||
|
|
e3fcae9392 | ||
|
|
c6ccfa91f3 | ||
|
|
b6fcee1cb9 | ||
|
|
9071befb04 | ||
|
|
bdd5fe98f3 | ||
|
|
a3d3e83a49 | ||
|
|
08bde72028 | ||
|
|
108a136368 | ||
|
|
57d87ad6b1 | ||
|
|
0c22815ff7 | ||
|
|
0ca792ecfd | ||
|
|
987c34c69e | ||
|
|
c1c02bc8ab | ||
|
|
4ee369f27c | ||
|
|
c9012efdcb | ||
|
|
41524fc67d | ||
|
|
04ff61e981 | ||
|
|
532468dc67 | ||
|
|
9c9a2dae47 | ||
|
|
c8a868b57f | ||
|
|
4b3f81ee34 | ||
|
|
afa170ba7c | ||
|
|
46e3b2272e | ||
|
|
52472e90ec | ||
|
|
4ef0d00846 | ||
|
|
580f2537f2 | ||
|
|
3d9fd96026 | ||
|
|
f449b92721 | ||
|
|
3b0216b023 | ||
|
|
98cf839737 | ||
|
|
0bb0846505 | ||
|
|
70969400a3 | ||
|
|
147e8d5d12 | ||
|
|
cacc3e6edd | ||
|
|
a284eca147 | ||
|
|
0d3ba9d7f0 | ||
|
|
be8064d642 | ||
|
|
e30dba742d | ||
|
|
44b72ed647 | ||
|
|
666bd77dac | ||
|
|
0a6613e60d | ||
|
|
62e186c123 | ||
|
|
50dd8f5bcc | ||
|
|
d5fcac9c45 | ||
|
|
c2bed85190 | ||
|
|
183b463ef2 | ||
|
|
92fdac44a0 | ||
|
|
12829ecc73 | ||
|
|
51319c3b26 | ||
|
|
8fd827040b | ||
|
|
5ec46eae0d | ||
|
|
32c03301be | ||
|
|
df7f29b2ab | ||
|
|
e863113c36 | ||
|
|
8e2c1d7382 | ||
|
|
ab7b9cccba | ||
|
|
81bf61a161 | ||
|
|
b40f008647 | ||
|
|
734e41702b | ||
|
|
038dd20a91 | ||
|
|
1dd62b8550 | ||
|
|
715deebe05 | ||
|
|
b3fe3d8590 | ||
|
|
f74c3ed3ea | ||
|
|
2c9aebeeed | ||
|
|
7474f1e11f | ||
|
|
dba9c55b64 | ||
|
|
b432364397 | ||
|
|
696967bdd1 | ||
|
|
b76889efc3 | ||
|
|
e6a7b64ebe | ||
|
|
9daa0df311 | ||
|
|
612800bda5 | ||
|
|
a6bbb1dec9 | ||
|
|
873c93ab64 | ||
|
|
d15242e2d2 | ||
|
|
992d2b937c | ||
|
|
1e05ddad4b | ||
|
|
4f8a64610b | ||
|
|
b82366218c | ||
|
|
acbe1f4cb3 | ||
|
|
4c5e018583 | ||
|
|
6c0380e85c | ||
|
|
fde48e604f | ||
|
|
e83a4de5fb | ||
|
|
927d2799dc | ||
|
|
1ad701fe5d | ||
|
|
086425d2da | ||
|
|
beca54416a | ||
|
|
c92f5c5713 | ||
|
|
dee4e6caff | ||
|
|
dd5a39e72e | ||
|
|
e5ed52165c | ||
|
|
9484f8e0f5 | ||
|
|
947caffe0a | ||
|
|
870090e8df | ||
|
|
73f07f13c5 | ||
|
|
d1952bf591 | ||
|
|
5a612e1332 | ||
|
|
b00a9faea6 | ||
|
|
74db42a703 | ||
|
|
ddf625ca04 | ||
|
|
eca2f017d8 | ||
|
|
3190bde343 | ||
|
|
c6ebf42a47 | ||
|
|
c116b60d12 | ||
|
|
5d09e6d9ab | ||
|
|
2613ce0ac9 | ||
|
|
a88e9b28ea | ||
|
|
f0a3c26ee6 | ||
|
|
84c87ecb32 | ||
|
|
6573f44d41 | ||
|
|
3cacbc552c | ||
|
|
343d623e02 | ||
|
|
6b80bb2b11 | ||
|
|
56fe7452eb | ||
|
|
d3a66f6605 | ||
|
|
dd7b4712f1 | ||
|
|
9df5871f6b | ||
|
|
29aab9e9f4 | ||
|
|
af67eb7f0b | ||
|
|
10482c0141 |
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -10,3 +10,7 @@ We love getting PRs, but we hate asking people for the same basic changes every
|
||||
- [ ] 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.
|
||||
|
||||
# When creating a PR:
|
||||
|
||||
- [ ] Fill in the "Description" above.
|
||||
- [ ] Enable "Allow edits from maintainers".
|
||||
|
||||
12
.github/dependabot.yml
vendored
Normal file
12
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "maven"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
time: "02:00"
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
time: "02:00"
|
||||
2
.github/release-drafter.yml
vendored
2
.github/release-drafter.yml
vendored
@@ -1,5 +1,5 @@
|
||||
name-template: 'v$NEXT_PATCH_VERSION 🌈'
|
||||
tag-template: 'v$NEXT_PATCH_VERSION'
|
||||
tag-template: 'github-api-$NEXT_MINOR_VERSION'
|
||||
categories:
|
||||
- title: '🚀 Features'
|
||||
labels:
|
||||
|
||||
6
.github/workflows/maven-build.yml
vendored
6
.github/workflows/maven-build.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
- name: Cached .m2
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
- uses: actions/cache@v1
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
- uses: actions/cache@v1
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
|
||||
56
pom.xml
56
pom.xml
@@ -2,7 +2,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.kohsuke</groupId>
|
||||
<artifactId>github-api</artifactId>
|
||||
<version>1.112</version>
|
||||
<version>1.115</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.112</tag>
|
||||
<tag>github-api-1.115</tag>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
@@ -33,8 +33,8 @@
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<spotbugs-maven-plugin.version>4.0.0</spotbugs-maven-plugin.version>
|
||||
<spotbugs.version>4.0.3</spotbugs.version>
|
||||
<spotbugs-maven-plugin.version>4.0.4</spotbugs-maven-plugin.version>
|
||||
<spotbugs.version>4.0.6</spotbugs.version>
|
||||
<spotbugs-maven-plugin.failOnError>true</spotbugs-maven-plugin.failOnError>
|
||||
<hamcrest.version>2.2</hamcrest.version>
|
||||
<okhttp3.version>4.4.1</okhttp3.version>
|
||||
@@ -79,6 +79,14 @@
|
||||
</testResources>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.2</version>
|
||||
<configuration>
|
||||
<!-- SUREFIRE-1226 workaround -->
|
||||
<trimStackTrace>false</trimStackTrace>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
@@ -233,7 +241,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-site-plugin</artifactId>
|
||||
<version>3.9.0</version>
|
||||
<version>3.9.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@@ -258,7 +266,7 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.bcel</groupId>
|
||||
<artifactId>bcel</artifactId>
|
||||
<version>6.4.1</version>
|
||||
<version>6.5.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
@@ -280,16 +288,31 @@
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.2</version>
|
||||
<configuration>
|
||||
<!-- SUREFIRE-1226 workaround -->
|
||||
<trimStackTrace>false</trimStackTrace>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<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>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>animal-sniffer-maven-plugin</artifactId>
|
||||
<version>1.18</version>
|
||||
<version>1.19</version>
|
||||
<configuration>
|
||||
<signature>
|
||||
<groupId>org.codehaus.mojo.signature</groupId>
|
||||
@@ -322,7 +345,7 @@
|
||||
<plugin>
|
||||
<groupId>net.revelc.code.formatter</groupId>
|
||||
<artifactId>formatter-maven-plugin</artifactId>
|
||||
<version>2.11.0</version>
|
||||
<version>2.12.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
@@ -330,6 +353,7 @@
|
||||
</goals>
|
||||
<configuration>
|
||||
<configFile>src/main/resources/eclipse/formatter.xml</configFile>
|
||||
<cachedir>${project.build.directory}/.cache</cachedir>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
@@ -445,7 +469,7 @@
|
||||
<dependency>
|
||||
<groupId>org.kohsuke.stapler</groupId>
|
||||
<artifactId>stapler</artifactId>
|
||||
<version>1.259</version>
|
||||
<version>1.260</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -495,7 +519,7 @@
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>3.3.3</version>
|
||||
<version>3.4.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -507,7 +531,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.tomakehurst</groupId>
|
||||
<artifactId>wiremock-jre8-standalone</artifactId>
|
||||
<version>2.26.3</version>
|
||||
<version>2.27.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -74,8 +74,14 @@ public class GHCheckRun extends GHObject {
|
||||
return conclusion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Final conclusion of the check.
|
||||
*
|
||||
* From <a href="https://docs.github.com/en/rest/reference/checks#create-a-check-run--parameters">Check Run
|
||||
* Parameters - <code>conclusion</code></a>.
|
||||
*/
|
||||
public static enum Conclusion {
|
||||
SUCCESS, FAILURE, NEUTRAL, CANCELLED, TIMED_OUT, ACTION_REQUIRED
|
||||
SUCCESS, FAILURE, NEUTRAL, CANCELLED, TIMED_OUT, ACTION_REQUIRED, SKIPPED
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,7 @@ public class GHContent implements Refreshable {
|
||||
private String sha;
|
||||
private String name;
|
||||
private String path;
|
||||
private String target;
|
||||
private String content;
|
||||
private String url; // this is the API url
|
||||
private String git_url; // this is the Blob url
|
||||
@@ -99,6 +100,15 @@ public class GHContent implements Refreshable {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets target of a symlink. This will only be set if {@code "symlink".equals(getType())}
|
||||
*
|
||||
* @return the target
|
||||
*/
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the decoded content that is stored at this location.
|
||||
*
|
||||
|
||||
232
src/main/java/org/kohsuke/github/GHDiscussion.java
Normal file
232
src/main/java/org/kohsuke/github/GHDiscussion.java
Normal file
@@ -0,0 +1,232 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonInject;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.CheckForNull;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* A discussion in GitHub Team.
|
||||
*
|
||||
* @author Charles Moulliard
|
||||
* @see <a href="https://developer.github.com/v3/teams/discussions">GitHub Team Discussions</a>
|
||||
*/
|
||||
public class GHDiscussion extends GHObject {
|
||||
|
||||
@JacksonInject
|
||||
private GitHub root;
|
||||
private GHTeam team;
|
||||
private long number;
|
||||
private String body, title, htmlUrl;
|
||||
|
||||
@JsonProperty(value = "private")
|
||||
private boolean isPrivate;
|
||||
|
||||
@Override
|
||||
public URL getHtmlUrl() throws IOException {
|
||||
return GitHubClient.parseURL(htmlUrl);
|
||||
}
|
||||
|
||||
GHDiscussion wrapUp(GHTeam team) {
|
||||
this.team = team;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the team to which this discussion belongs.
|
||||
*
|
||||
* @return the team for this discussion
|
||||
*/
|
||||
@Nonnull
|
||||
public GHTeam getTeam() {
|
||||
return team;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title of the discussion.
|
||||
*
|
||||
* @return the title
|
||||
*/
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* The description of this discussion.
|
||||
*
|
||||
* @return the body
|
||||
*/
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of this discussion.
|
||||
*
|
||||
* @return the number
|
||||
*/
|
||||
public long getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* The id number of this discussion. GitHub discussions have "number" instead of "id". This is provided for
|
||||
* convenience.
|
||||
*
|
||||
* @return the id number for this discussion
|
||||
* @see #getNumber()
|
||||
*/
|
||||
@Override
|
||||
public long getId() {
|
||||
return getNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the discussion is private to the team.
|
||||
*
|
||||
* @return {@code true} if discussion is private.
|
||||
*/
|
||||
public boolean isPrivate() {
|
||||
return isPrivate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins the creation of a new instance.
|
||||
*
|
||||
* Consumer must call {@link GHDiscussion.Creator#done()} to commit changes.
|
||||
*
|
||||
* @param team
|
||||
* the team in which the discussion will be created.
|
||||
* @return a {@link GHLabel.Creator}
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
static GHDiscussion.Creator create(GHTeam team) throws IOException {
|
||||
return new GHDiscussion.Creator(team);
|
||||
}
|
||||
|
||||
static GHDiscussion read(GHTeam team, long discussionNumber) throws IOException {
|
||||
return team.root.createRequest()
|
||||
.setRawUrlPath(getRawUrlPath(team, discussionNumber))
|
||||
.fetch(GHDiscussion.class)
|
||||
.wrapUp(team);
|
||||
}
|
||||
|
||||
static PagedIterable<GHDiscussion> readAll(GHTeam team) throws IOException {
|
||||
return team.root.createRequest()
|
||||
.setRawUrlPath(getRawUrlPath(team, null))
|
||||
.toIterable(GHDiscussion[].class, item -> item.wrapUp(team));
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins a batch update
|
||||
*
|
||||
* Consumer must call {@link GHDiscussion.Updater#done()} to commit changes.
|
||||
*
|
||||
* @return a {@link GHDiscussion.Updater}
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public GHDiscussion.Updater update() {
|
||||
return new GHDiscussion.Updater(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins a single property update.
|
||||
*
|
||||
* @return a {@link GHDiscussion.Setter}
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public GHDiscussion.Setter set() {
|
||||
return new GHDiscussion.Setter(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the discussion
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void delete() throws IOException {
|
||||
team.root.createRequest().method("DELETE").setRawUrlPath(getRawUrlPath(team, number)).send();
|
||||
}
|
||||
|
||||
private static String getRawUrlPath(@Nonnull GHTeam team, @CheckForNull Long discussionNumber) {
|
||||
return team.getUrl().toString() + "/discussions" + (discussionNumber == null ? "" : "/" + discussionNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link GHLabelBuilder} that updates a single property per request
|
||||
*
|
||||
* {@link #done()} is called automatically after the property is set.
|
||||
*/
|
||||
public static class Setter extends GHDiscussionBuilder<GHDiscussion> {
|
||||
private Setter(@Nonnull GHDiscussion base) {
|
||||
super(GHDiscussion.class, base.team, base);
|
||||
requester.method("PATCH").setRawUrlPath(base.getUrl().toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link GHLabelBuilder} that allows multiple properties to be updated per request.
|
||||
*
|
||||
* Consumer must call {@link #done()} to commit changes.
|
||||
*/
|
||||
public static class Updater extends GHDiscussionBuilder<Updater> {
|
||||
private Updater(@Nonnull GHDiscussion base) {
|
||||
super(GHDiscussion.Updater.class, base.team, base);
|
||||
requester.method("PATCH").setRawUrlPath(base.getUrl().toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link GHLabelBuilder} that creates a new {@link GHLabel}
|
||||
*
|
||||
* Consumer must call {@link #done()} to create the new instance.
|
||||
*/
|
||||
public static class Creator extends GHDiscussionBuilder<Creator> {
|
||||
|
||||
private Creator(@Nonnull GHTeam team) {
|
||||
super(GHDiscussion.Creator.class, team, null);
|
||||
requester.method("POST").setRawUrlPath(getRawUrlPath(team, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this discussion is private to this team.
|
||||
*
|
||||
* @param value
|
||||
* privacy of this discussion
|
||||
* @return either a continuing builder or an updated {@link GHDiscussion}
|
||||
* @throws IOException
|
||||
* if there is an I/O Exception
|
||||
*/
|
||||
@Nonnull
|
||||
public Creator private_(boolean value) throws IOException {
|
||||
return with("private", value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
GHDiscussion that = (GHDiscussion) o;
|
||||
return number == that.number && Objects.equals(getUrl(), that.getUrl()) && Objects.equals(team, that.team)
|
||||
&& Objects.equals(body, that.body) && Objects.equals(title, that.title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(team, number, body, title);
|
||||
}
|
||||
}
|
||||
80
src/main/java/org/kohsuke/github/GHDiscussionBuilder.java
Normal file
80
src/main/java/org/kohsuke/github/GHDiscussionBuilder.java
Normal file
@@ -0,0 +1,80 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.annotation.CheckForNull;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Base class for creating or updating a discussion.
|
||||
*
|
||||
* @param <S>
|
||||
* Intermediate return type for this builder returned by calls to {@link #with(String, Object)}. If {@link S}
|
||||
* the same as {@link GHLabel}, this builder will commit changes after each call to
|
||||
* {@link #with(String, Object)}.
|
||||
*/
|
||||
class GHDiscussionBuilder<S> extends AbstractBuilder<GHDiscussion, S> {
|
||||
|
||||
private final GHTeam team;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param intermediateReturnType
|
||||
* Intermediate return type for this builder returned by calls to {@link #with(String, Object)}. If
|
||||
* {@link S} the same as {@link GHDiscussion}, this builder will commit changes after each call to
|
||||
* {@link #with(String, Object)}.
|
||||
* @param team
|
||||
* the GitHub team. Updates will be sent to the root of this team.
|
||||
* @param baseInstance
|
||||
* instance on which to base this builder. If {@code null} a new instance will be created.
|
||||
*/
|
||||
protected GHDiscussionBuilder(@Nonnull Class<S> intermediateReturnType,
|
||||
@Nonnull GHTeam team,
|
||||
@CheckForNull GHDiscussion baseInstance) {
|
||||
super(GHDiscussion.class, intermediateReturnType, team.root, baseInstance);
|
||||
|
||||
this.team = team;
|
||||
|
||||
if (baseInstance != null) {
|
||||
requester.with("title", baseInstance.getTitle());
|
||||
requester.with("body", baseInstance.getBody());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Title for this discussion.
|
||||
*
|
||||
* @param value
|
||||
* title of discussion
|
||||
* @return either a continuing builder or an updated {@link GHDiscussion}
|
||||
* @throws IOException
|
||||
* if there is an I/O Exception
|
||||
*/
|
||||
@Nonnull
|
||||
public S title(String value) throws IOException {
|
||||
return with("title", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Body content for this discussion.
|
||||
*
|
||||
* @param value
|
||||
* body of discussion*
|
||||
* @return either a continuing builder or an updated {@link GHDiscussion}
|
||||
* @throws IOException
|
||||
* if there is an I/O Exception
|
||||
*/
|
||||
@Nonnull
|
||||
public S body(String value) throws IOException {
|
||||
return with("body", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Nonnull
|
||||
@Override
|
||||
public GHDiscussion done() throws IOException {
|
||||
return super.done().wrapUp(team);
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,7 @@ public enum GHEvent {
|
||||
TEAM,
|
||||
TEAM_ADD,
|
||||
WATCH,
|
||||
WORKFLOW_DISPATCH,
|
||||
|
||||
/**
|
||||
* Special event type that means "every possible event"
|
||||
|
||||
@@ -24,10 +24,10 @@ public abstract class GHPerson extends GHObject {
|
||||
protected String login, avatar_url;
|
||||
|
||||
// other fields (that only show up in full data)
|
||||
protected String location, blog, email, name, company, type;
|
||||
protected String location, blog, email, bio, name, company, type, twitter_username;
|
||||
protected String html_url;
|
||||
protected int followers, following, public_repos, public_gists;
|
||||
protected boolean site_admin;
|
||||
protected boolean site_admin, hireable;
|
||||
|
||||
// other fields (that only show up in full data) that require privileged scope
|
||||
protected Integer total_private_repos;
|
||||
@@ -237,6 +237,18 @@ public abstract class GHPerson extends GHObject {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Twitter Username of this user, like "GitHub"
|
||||
*
|
||||
* @return the Twitter username
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public String getTwitterUsername() throws IOException {
|
||||
populate();
|
||||
return twitter_username;
|
||||
}
|
||||
|
||||
public Date getCreatedAt() throws IOException {
|
||||
populate();
|
||||
return super.getCreatedAt();
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
@@ -29,7 +30,7 @@ public class GHRateLimit {
|
||||
/**
|
||||
* Remaining calls that can be made.
|
||||
*
|
||||
* @deprecated This value should never have been made public. Use {@link #getRemaining()}
|
||||
* @deprecated This field should never have been made public. Use {@link #getRemaining()}
|
||||
*/
|
||||
@Deprecated
|
||||
public int remaining;
|
||||
@@ -37,7 +38,7 @@ public class GHRateLimit {
|
||||
/**
|
||||
* Allotted API call per hour.
|
||||
*
|
||||
* @deprecated This value should never have been made public. Use {@link #getLimit()}
|
||||
* @deprecated This field should never have been made public. Use {@link #getLimit()}
|
||||
*/
|
||||
@Deprecated
|
||||
public int limit;
|
||||
@@ -48,7 +49,7 @@ public class GHRateLimit {
|
||||
* date. To use this field in any meaningful way, it must be converted to a long using {@link Date#getTime()}
|
||||
* multiplied by 1000.
|
||||
*
|
||||
* @deprecated This value should never have been made public. Use {@link #getResetDate()}
|
||||
* @deprecated This field should never have been made public. Use {@link #getResetDate()}
|
||||
*/
|
||||
@Deprecated
|
||||
public Date reset;
|
||||
@@ -65,17 +66,58 @@ public class GHRateLimit {
|
||||
@Nonnull
|
||||
private final Record integrationManifest;
|
||||
|
||||
/**
|
||||
* The default GHRateLimit provided to new {@link GitHubClient}s.
|
||||
*
|
||||
* Contains all expired records that will cause {@link GitHubClient#rateLimit(RateLimitTarget)} to refresh with new
|
||||
* data when called.
|
||||
*
|
||||
* Private, but made internal for testing.
|
||||
*/
|
||||
@Nonnull
|
||||
static GHRateLimit Unknown() {
|
||||
return new GHRateLimit(new UnknownLimitRecord(),
|
||||
new UnknownLimitRecord(),
|
||||
new UnknownLimitRecord(),
|
||||
new UnknownLimitRecord());
|
||||
}
|
||||
static final GHRateLimit DEFAULT = new GHRateLimit(UnknownLimitRecord.DEFAULT,
|
||||
UnknownLimitRecord.DEFAULT,
|
||||
UnknownLimitRecord.DEFAULT,
|
||||
UnknownLimitRecord.DEFAULT);
|
||||
|
||||
/**
|
||||
* Creates a new {@link GHRateLimit} from a single record for the specified endpoint with place holders for other
|
||||
* records.
|
||||
*
|
||||
* This is used to create {@link GHRateLimit} instances that can merged with other instances.
|
||||
*
|
||||
* @param record
|
||||
* the rate limit record. Can be a regular {@link Record} constructed from header information or an
|
||||
* {@link UnknownLimitRecord} placeholder.
|
||||
* @param rateLimitTarget
|
||||
* which rate limit record to fill
|
||||
* @return a new {@link GHRateLimit} instance containing the supplied record
|
||||
*/
|
||||
@Nonnull
|
||||
static GHRateLimit fromHeaderRecord(Record header) {
|
||||
return new GHRateLimit(header, new UnknownLimitRecord(), new UnknownLimitRecord(), new UnknownLimitRecord());
|
||||
static GHRateLimit fromRecord(@Nonnull Record record, @Nonnull RateLimitTarget rateLimitTarget) {
|
||||
if (rateLimitTarget == RateLimitTarget.CORE || rateLimitTarget == RateLimitTarget.NONE) {
|
||||
return new GHRateLimit(record,
|
||||
UnknownLimitRecord.DEFAULT,
|
||||
UnknownLimitRecord.DEFAULT,
|
||||
UnknownLimitRecord.DEFAULT);
|
||||
} else if (rateLimitTarget == RateLimitTarget.SEARCH) {
|
||||
return new GHRateLimit(UnknownLimitRecord.DEFAULT,
|
||||
record,
|
||||
UnknownLimitRecord.DEFAULT,
|
||||
UnknownLimitRecord.DEFAULT);
|
||||
} else if (rateLimitTarget == RateLimitTarget.GRAPHQL) {
|
||||
return new GHRateLimit(UnknownLimitRecord.DEFAULT,
|
||||
UnknownLimitRecord.DEFAULT,
|
||||
record,
|
||||
UnknownLimitRecord.DEFAULT);
|
||||
} else if (rateLimitTarget == RateLimitTarget.INTEGRATION_MANIFEST) {
|
||||
return new GHRateLimit(UnknownLimitRecord.DEFAULT,
|
||||
UnknownLimitRecord.DEFAULT,
|
||||
UnknownLimitRecord.DEFAULT,
|
||||
record);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown rate limit target: " + rateLimitTarget.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
@@ -142,7 +184,7 @@ public class GHRateLimit {
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the rate limit reset date for this instance has passed.
|
||||
* Whether the reset date for the Core API rate limit has passed.
|
||||
*
|
||||
* @return true if the rate limit reset date has passed. Otherwise false.
|
||||
* @since 1.100
|
||||
@@ -152,7 +194,7 @@ public class GHRateLimit {
|
||||
}
|
||||
|
||||
/**
|
||||
* The core object provides your rate limit status for all non-search-related resources in the REST API.
|
||||
* The core object provides the rate limit status for all non-search-related resources in the REST API.
|
||||
*
|
||||
* @return a rate limit record
|
||||
* @since 1.100
|
||||
@@ -163,42 +205,43 @@ public class GHRateLimit {
|
||||
}
|
||||
|
||||
/**
|
||||
* The search object provides your rate limit status for the Search API. TODO: integrate with header limit updating.
|
||||
* Issue #605.
|
||||
* The search record provides the rate limit status for the Search API.
|
||||
*
|
||||
* @return a rate limit record
|
||||
* @since 1.115
|
||||
*/
|
||||
@Nonnull
|
||||
Record getSearch() {
|
||||
public Record getSearch() {
|
||||
return search;
|
||||
}
|
||||
|
||||
/**
|
||||
* The graphql object provides your rate limit status for the GraphQL API. TODO: integrate with header limit
|
||||
* updating. Issue #605.
|
||||
* The graphql record provides the rate limit status for the GraphQL API.
|
||||
*
|
||||
* @return a rate limit record
|
||||
* @since 1.115
|
||||
*/
|
||||
@Nonnull
|
||||
Record getGraphQL() {
|
||||
public Record getGraphQL() {
|
||||
return graphql;
|
||||
}
|
||||
|
||||
/**
|
||||
* The integration_manifest object provides your rate limit status for the GitHub App Manifest code conversion
|
||||
* endpoint. TODO: integrate with header limit updating. Issue #605.
|
||||
* The integration manifest record provides the rate limit status for the GitHub App Manifest code conversion
|
||||
* endpoint.
|
||||
*
|
||||
* @return a rate limit record
|
||||
* @since 1.115
|
||||
*/
|
||||
@Nonnull
|
||||
Record getIntegrationManifest() {
|
||||
public Record getIntegrationManifest() {
|
||||
return integrationManifest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GHRateLimit {" + "core " + getCore().toString() + "search " + getSearch().toString() + "graphql "
|
||||
+ getGraphQL().toString() + "integrationManifest " + getIntegrationManifest().toString() + '}';
|
||||
return "GHRateLimit {" + "core " + getCore().toString() + ", search " + getSearch().toString() + ", graphql "
|
||||
+ getGraphQL().toString() + ", integrationManifest " + getIntegrationManifest().toString() + "}";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -221,44 +264,111 @@ public class GHRateLimit {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the appropriate {@link Record} for a particular url path.
|
||||
*
|
||||
* @param urlPath
|
||||
* the url path of the request
|
||||
* @return the {@link Record} for a url path.
|
||||
* Merge a {@link GHRateLimit} with another one to create a new {@link GHRateLimit} keeping the latest
|
||||
* {@link Record}s from each.
|
||||
*
|
||||
* @param newLimit
|
||||
* {@link GHRateLimit} with potentially updated {@link Record}s.
|
||||
* @return a merged {@link GHRateLimit} with the latest {@link Record}s from these two instances. If the merged
|
||||
* instance is equal to the current instance, the current instance is returned.
|
||||
*/
|
||||
@Nonnull
|
||||
Record getRecordForUrlPath(@Nonnull String urlPath) {
|
||||
if (urlPath.equals("/rate_limit")) {
|
||||
return new UnknownLimitRecord();
|
||||
} else if (urlPath.startsWith("/search")) {
|
||||
return getSearch();
|
||||
} else if (urlPath.startsWith("/graphql")) {
|
||||
return getGraphQL();
|
||||
} else if (urlPath.startsWith("/app-manifests")) {
|
||||
return getIntegrationManifest();
|
||||
} else {
|
||||
GHRateLimit getMergedRateLimit(@Nonnull GHRateLimit newLimit) {
|
||||
|
||||
GHRateLimit merged = new GHRateLimit(getCore().currentOrUpdated(newLimit.getCore()),
|
||||
getSearch().currentOrUpdated(newLimit.getSearch()),
|
||||
getGraphQL().currentOrUpdated(newLimit.getGraphQL()),
|
||||
getIntegrationManifest().currentOrUpdated(newLimit.getIntegrationManifest()));
|
||||
|
||||
if (merged.equals(this)) {
|
||||
merged = this;
|
||||
}
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the specified {@link Record}.
|
||||
*
|
||||
* {@link RateLimitTarget#NONE} will return {@link UnknownLimitRecord#DEFAULT} to prevent any clients from
|
||||
* accidentally waiting on that record to reset before continuing.
|
||||
*
|
||||
* @param rateLimitTarget
|
||||
* the target rate limit record
|
||||
* @return the target {@link Record} from this instance.
|
||||
*/
|
||||
@Nonnull
|
||||
Record getRecord(@Nonnull RateLimitTarget rateLimitTarget) {
|
||||
if (rateLimitTarget == RateLimitTarget.CORE) {
|
||||
return getCore();
|
||||
} else if (rateLimitTarget == RateLimitTarget.SEARCH) {
|
||||
return getSearch();
|
||||
} else if (rateLimitTarget == RateLimitTarget.GRAPHQL) {
|
||||
return getGraphQL();
|
||||
} else if (rateLimitTarget == RateLimitTarget.INTEGRATION_MANIFEST) {
|
||||
return getIntegrationManifest();
|
||||
} else if (rateLimitTarget == RateLimitTarget.NONE) {
|
||||
return UnknownLimitRecord.DEFAULT;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown rate limit target: " + rateLimitTarget.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A limit record used as a placeholder when the the actual limit is not known.
|
||||
* <p>
|
||||
* Has a large limit and long duration so that it will doesn't expire too often.
|
||||
*
|
||||
* @since 1.100
|
||||
*/
|
||||
public static class UnknownLimitRecord extends Record {
|
||||
|
||||
// One hour
|
||||
private static final long unknownLimitResetSeconds = 60L * 60L;
|
||||
private static final long defaultUnknownLimitResetSeconds = Duration.ofSeconds(30).getSeconds();
|
||||
|
||||
/**
|
||||
* The number of seconds until a {@link UnknownLimitRecord} will expire.
|
||||
*
|
||||
* This is set to a somewhat short duration, rather than a long one. This avoids
|
||||
* {@link {@link GitHubClient#rateLimit(RateLimitTarget)}} requesting rate limit updates continuously, but also
|
||||
* avoids holding on to stale unknown records indefinitely.
|
||||
*
|
||||
* When merging {@link GHRateLimit} instances, {@link UnknownLimitRecord}s will be superseded by incoming
|
||||
* regular {@link Record}s.
|
||||
*
|
||||
* @see GHRateLimit#getMergedRateLimit(GHRateLimit)
|
||||
*/
|
||||
static long unknownLimitResetSeconds = defaultUnknownLimitResetSeconds;
|
||||
|
||||
static final int unknownLimit = 1000000;
|
||||
static final int unknownRemaining = 999999;
|
||||
|
||||
private UnknownLimitRecord() {
|
||||
super(unknownLimit, unknownRemaining, System.currentTimeMillis() / 1000L + unknownLimitResetSeconds);
|
||||
// The default UnknownLimitRecord is an expired record.
|
||||
private static final UnknownLimitRecord DEFAULT = new UnknownLimitRecord(Long.MIN_VALUE);
|
||||
|
||||
// The starting current UnknownLimitRecord is an expired record.
|
||||
private static UnknownLimitRecord current = DEFAULT;
|
||||
|
||||
/**
|
||||
* Create a new unknown record that resets at the specified time.
|
||||
*
|
||||
* @param resetEpochSeconds
|
||||
* the epoch second time when this record will expire.
|
||||
*/
|
||||
private UnknownLimitRecord(long resetEpochSeconds) {
|
||||
super(unknownLimit, unknownRemaining, resetEpochSeconds);
|
||||
}
|
||||
|
||||
static synchronized Record current() {
|
||||
if (current.isExpired()) {
|
||||
current = new UnknownLimitRecord(System.currentTimeMillis() / 1000L + unknownLimitResetSeconds);
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the current UnknownLimitRecord. For use during testing only.
|
||||
*/
|
||||
static synchronized void reset() {
|
||||
current = DEFAULT;
|
||||
unknownLimitResetSeconds = defaultUnknownLimitResetSeconds;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,14 +384,12 @@ public class GHRateLimit {
|
||||
private final int remaining;
|
||||
|
||||
/**
|
||||
* Allotted API call per hour.
|
||||
* Allotted API call per time period.
|
||||
*/
|
||||
private final int limit;
|
||||
|
||||
/**
|
||||
* The time at which the current rate limit window resets in UTC epoch seconds.
|
||||
*
|
||||
* This is the raw value returned by the server.
|
||||
*/
|
||||
private final long resetEpochSeconds;
|
||||
|
||||
@@ -291,9 +399,11 @@ public class GHRateLimit {
|
||||
private final long createdAtEpochSeconds = System.currentTimeMillis() / 1000;
|
||||
|
||||
/**
|
||||
* The time at which the rate limit will reset. This value is calculated based on
|
||||
* {@link #getResetEpochSeconds()} by calling {@link #calculateResetDate}. If the clock on the local machine not
|
||||
* synchronized with the server clock, this time value will be adjusted to match the local machine's clock.
|
||||
* The date at which the rate limit will reset, adjusted to local machine time if the local machine's clock not
|
||||
* synchronized with to the same clock as the GitHub server.
|
||||
*
|
||||
* @see #calculateResetDate(String)
|
||||
* @see #getResetDate()
|
||||
*/
|
||||
@Nonnull
|
||||
private final Date resetDate;
|
||||
@@ -341,12 +451,58 @@ public class GHRateLimit {
|
||||
this.resetDate = calculateResetDate(updatedAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the current {@link Record} is outdated compared to another. Rate Limit dates are only accurate
|
||||
* to the second, so we look at other information in the record as well.
|
||||
*
|
||||
* {@link Record}s with earlier {@link #getResetEpochSeconds()} are replaced by those with later.
|
||||
* {@link Record}s with the same {@link #getResetEpochSeconds()} are replaced by those with less remaining
|
||||
* count.
|
||||
*
|
||||
* {@link UnknownLimitRecord}s compare with each other like regular {@link Record}s.
|
||||
*
|
||||
* {@link Record}s are replaced by {@link UnknownLimitRecord}s only when the current {@link Record} is expired
|
||||
* and the {@link UnknownLimitRecord} is not. Otherwise Regular {@link Record}s are not replaced by
|
||||
* {@link UnknownLimitRecord}s.
|
||||
*
|
||||
* Expiration is only considered after other checks, meaning expired records may sometimes be replaced by other
|
||||
* expired records.
|
||||
*
|
||||
* @param other
|
||||
* the other {@link Record}
|
||||
* @return the {@link Record} that is most current
|
||||
*/
|
||||
Record currentOrUpdated(@Nonnull Record other) {
|
||||
// This set of checks avoids most calls to isExpired()
|
||||
// Depends on UnknownLimitRecord.current() to prevent continuous updating of GHRateLimit rateLimit()
|
||||
if (getResetEpochSeconds() > other.getResetEpochSeconds()
|
||||
|| (getResetEpochSeconds() == other.getResetEpochSeconds()
|
||||
&& getRemaining() <= other.getRemaining())) {
|
||||
// If the current record has a later reset
|
||||
// or the current record has the same reset and fewer or same requests remaining
|
||||
// Then it is most recent
|
||||
return this;
|
||||
} else if (!(other instanceof UnknownLimitRecord)) {
|
||||
// If the above is not the case that means other has a later reset
|
||||
// or the same resent and fewer requests remaining.
|
||||
// If the other record is not an unknown record, the the other is more recent
|
||||
return other;
|
||||
} else if (this.isExpired() && !other.isExpired()) {
|
||||
// The other is an unknown record.
|
||||
// If the current record has expired and the other hasn't, return the other.
|
||||
return other;
|
||||
}
|
||||
|
||||
// If none of the above, the current record is most valid.
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculates the {@link #resetDate} relative to the local machine clock.
|
||||
* <p>
|
||||
* {@link RateLimitChecker}s and {@link RateLimitHandler}s use {@link #getResetDate()} to make decisions about
|
||||
* how long to wait for until for the rate limit to reset. That means that {@link #getResetDate()} needs to be
|
||||
* accurate to the local machine.
|
||||
* calculated based on the local machine clock.
|
||||
* </p>
|
||||
* <p>
|
||||
* When we say that the clock on two machines is "synchronized", we mean that the UTC time returned from
|
||||
@@ -415,7 +571,7 @@ public class GHRateLimit {
|
||||
* {@link #getResetDate()} or implement a {@link RateLimitChecker} instead.
|
||||
*
|
||||
* @return a long representing the time in epoch seconds when the rate limit will reset
|
||||
* @see #getResetDate() #getResetDate()
|
||||
* @see #getResetDate()
|
||||
*/
|
||||
public long getResetEpochSeconds() {
|
||||
return resetEpochSeconds;
|
||||
@@ -424,6 +580,8 @@ public class GHRateLimit {
|
||||
/**
|
||||
* Whether the rate limit reset date indicated by this instance is expired
|
||||
*
|
||||
* If attempting to wait for the rate limit to reset, consider implementing a {@link RateLimitChecker} instead.
|
||||
*
|
||||
* @return true if the rate limit reset date has passed. Otherwise false.
|
||||
*/
|
||||
public boolean isExpired() {
|
||||
@@ -431,8 +589,8 @@ public class GHRateLimit {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date at which the rate limit will reset, adjusted to local machine time if the local machine's
|
||||
* clock not synchronized with to the same clock as the GitHub server.
|
||||
* The date at which the rate limit will reset, adjusted to local machine time if the local machine's clock not
|
||||
* synchronized with to the same clock as the GitHub server.
|
||||
*
|
||||
* If attempting to wait for the rate limit to reset, consider implementing a {@link RateLimitChecker} instead.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -90,6 +91,78 @@ public class GHRef {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive a ref of the given type for the current GitHub repository.
|
||||
*
|
||||
* @param repository
|
||||
* the repository to read from
|
||||
* @param refName
|
||||
* eg: heads/branch
|
||||
* @return refs matching the request type
|
||||
* @throws IOException
|
||||
* on failure communicating with GitHub, potentially due to an invalid ref type being requested
|
||||
*/
|
||||
static GHRef read(GHRepository repository, String refName) throws IOException {
|
||||
// Also accept e.g. "refs/heads/branch" for consistency with createRef().
|
||||
if (refName.startsWith("refs/")) {
|
||||
refName = refName.replaceFirst("refs/", "");
|
||||
}
|
||||
|
||||
// We would expect this to use `git/ref/%s` but some versions of GHE seem to not support it
|
||||
// Instead use `git/refs/%s` and check the result actually matches the ref
|
||||
GHRef result = null;
|
||||
try {
|
||||
result = repository.root.createRequest()
|
||||
.withUrlPath(repository.getApiTailUrl(String.format("git/refs/%s", refName)))
|
||||
.fetch(GHRef.class)
|
||||
.wrap(repository.root);
|
||||
} catch (IOException e) {
|
||||
// If the parse exception is due to the above returning an array instead of a single ref
|
||||
// that means the individual ref did not exist. Handled by result check below.
|
||||
// Otherwise, rethrow.
|
||||
if (!(e.getCause() instanceof JsonMappingException)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that the ref returned is the one requested
|
||||
// Used .endsWith(refName) instead of .equals("refs/" + refName) to workaround a GitBucket
|
||||
// issue where the "ref" field omits the "refs/" prefix. "endsWith()" is functionally
|
||||
// the same for this scenario - the server refs matching is prefix-based, so
|
||||
// a ref that ends with the correct string will always be the correct one.
|
||||
if (result == null || !result.getRef().endsWith(refName)) {
|
||||
throw new GHFileNotFoundException(String.format("git/refs/%s", refName)
|
||||
+ " {\"message\":\"Not Found\",\"documentation_url\":\"https://developer.github.com/v3/git/refs/#get-a-reference\"}");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all refs of the given type for the current GitHub repository.
|
||||
*
|
||||
* @param repository
|
||||
* the repository to read from
|
||||
* @param refType
|
||||
* the type of reg to search for e.g. <code>tags</code> or <code>commits</code>
|
||||
* @return paged iterable of all refs of the specified type
|
||||
* @throws IOException
|
||||
* on failure communicating with GitHub, potentially due to an invalid ref type being requested
|
||||
*/
|
||||
static PagedIterable<GHRef> readMatching(GHRepository repository, String refType) throws IOException {
|
||||
if (refType.startsWith("refs/")) {
|
||||
refType = refType.replaceFirst("refs/", "");
|
||||
}
|
||||
|
||||
String url = repository.getApiTailUrl(String.format("git/refs/%s", refType));
|
||||
// if no types, do not end with slash just to be safe.
|
||||
if (refType.equals("")) {
|
||||
url = url.substring(0, url.length() - 1);
|
||||
}
|
||||
return repository.root.createRequest()
|
||||
.withUrlPath(url)
|
||||
.toIterable(GHRef[].class, item -> item.wrap(repository.root));
|
||||
}
|
||||
|
||||
/**
|
||||
* The type GHObject.
|
||||
*/
|
||||
|
||||
@@ -1540,8 +1540,7 @@ public class GHRepository extends GHObject {
|
||||
* on failure communicating with GitHub, potentially due to an invalid ref type being requested
|
||||
*/
|
||||
public PagedIterable<GHRef> listRefs() throws IOException {
|
||||
final String url = String.format("/repos/%s/%s/git/refs", getOwnerName(), name);
|
||||
return root.createRequest().withUrlPath(url).toIterable(GHRef[].class, item -> item.wrap(root));
|
||||
return listRefs("");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1567,11 +1566,7 @@ public class GHRepository extends GHObject {
|
||||
* on failure communicating with GitHub, potentially due to an invalid ref type being requested
|
||||
*/
|
||||
public PagedIterable<GHRef> listRefs(String refType) throws IOException {
|
||||
if (refType.startsWith("refs/")) {
|
||||
refType = refType.replaceFirst("refs/", "");
|
||||
}
|
||||
final String url = String.format("/repos/%s/%s/git/refs/%s", getOwnerName(), name, refType);
|
||||
return root.createRequest().withUrlPath(url).toIterable(GHRef[].class, item -> item.wrap(root));
|
||||
return GHRef.readMatching(this, refType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1584,15 +1579,7 @@ public class GHRepository extends GHObject {
|
||||
* on failure communicating with GitHub, potentially due to an invalid ref type being requested
|
||||
*/
|
||||
public GHRef getRef(String refName) throws IOException {
|
||||
// Also accept e.g. "refs/heads/branch" for consistency with createRef().
|
||||
if (refName.startsWith("refs/")) {
|
||||
refName = refName.replaceFirst("refs/", "");
|
||||
}
|
||||
|
||||
return root.createRequest()
|
||||
.withUrlPath(getApiTailUrl(String.format("git/ref/%s", refName)))
|
||||
.fetch(GHRef.class)
|
||||
.wrap(root);
|
||||
return GHRef.read(this, refName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,6 +25,7 @@ public abstract class GHSearchBuilder<T> extends GHQueryBuilder<T> {
|
||||
super(root);
|
||||
this.receiverType = receiverType;
|
||||
req.withUrlPath(getApiUrl());
|
||||
req.rateLimit(RateLimitTarget.SEARCH);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,9 +3,12 @@ package org.kohsuke.github;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* A team in GitHub organization.
|
||||
*
|
||||
@@ -130,6 +133,36 @@ public class GHTeam extends GHObject implements Refreshable {
|
||||
root.createRequest().method("PATCH").with("privacy", privacy).withUrlPath(api("")).send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the discussions.
|
||||
*
|
||||
* @return the paged iterable
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
@Nonnull
|
||||
public PagedIterable<GHDiscussion> listDiscussions() throws IOException {
|
||||
return GHDiscussion.readAll(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a single discussion by ID.
|
||||
*
|
||||
* @param discussionNumber
|
||||
* id of the discussion that we want to query for
|
||||
* @return the discussion
|
||||
* @throws java.io.FileNotFoundException
|
||||
* if the discussion does not exist
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*
|
||||
* @see <a href= "https://developer.github.com/v3/teams/discussions/#get-a-discussion">documentation</a>
|
||||
*/
|
||||
@Nonnull
|
||||
public GHDiscussion getDiscussion(long discussionNumber) throws IOException {
|
||||
return GHDiscussion.read(this, discussionNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current members.
|
||||
*
|
||||
@@ -141,6 +174,19 @@ public class GHTeam extends GHObject implements Refreshable {
|
||||
return root.createRequest().withUrlPath(api("/members")).toIterable(GHUser[].class, item -> item.wrapUp(root));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the teams that are children of this team.
|
||||
*
|
||||
* @return the paged iterable
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public PagedIterable<GHTeam> listChildTeams() throws IOException {
|
||||
return root.createRequest()
|
||||
.withUrlPath(api("/teams"))
|
||||
.toIterable(GHTeam[].class, item -> item.wrapUp(this.organization));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets members.
|
||||
*
|
||||
@@ -297,6 +343,21 @@ public class GHTeam extends GHObject implements Refreshable {
|
||||
return "/teams/" + getId() + tail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins the creation of a new instance.
|
||||
*
|
||||
* Consumer must call {@link GHDiscussion.Creator#done()} to commit changes.
|
||||
*
|
||||
* @param title
|
||||
* title of the discussion to be created
|
||||
* @return a {@link GHDiscussion.Creator}
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public GHDiscussion.Creator createDiscussion(String title) throws IOException {
|
||||
return GHDiscussion.create(this).title(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets organization.
|
||||
*
|
||||
@@ -318,4 +379,23 @@ public class GHTeam extends GHObject implements Refreshable {
|
||||
public URL getHtmlUrl() {
|
||||
return GitHubClient.parseURL(html_url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
GHTeam ghTeam = (GHTeam) o;
|
||||
return Objects.equals(name, ghTeam.name) && Objects.equals(getUrl(), ghTeam.getUrl())
|
||||
&& Objects.equals(permission, ghTeam.permission) && Objects.equals(slug, ghTeam.slug)
|
||||
&& Objects.equals(description, ghTeam.description) && privacy == ghTeam.privacy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name, getUrl(), permission, slug, description, privacy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public class GHTeamBuilder {
|
||||
* parentTeamId of team
|
||||
* @return a builder to continue with building
|
||||
*/
|
||||
public GHTeamBuilder parentTeamId(int parentTeamId) {
|
||||
public GHTeamBuilder parentTeamId(long parentTeamId) {
|
||||
this.builder.with("parent_team_id", parentTeamId);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -173,6 +173,19 @@ public class GHUser extends GHPerson {
|
||||
return org.hasPublicMember(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this user is marked as hireable, false otherwise
|
||||
*
|
||||
* @return if the user is marked as hireable
|
||||
*/
|
||||
public boolean isHireable() {
|
||||
return hireable;
|
||||
}
|
||||
|
||||
public String getBio() {
|
||||
return bio;
|
||||
}
|
||||
|
||||
static GHUser[] wrap(GHUser[] users, GitHub root) {
|
||||
for (GHUser f : users)
|
||||
f.root = root;
|
||||
|
||||
@@ -373,12 +373,20 @@ public class GitHub {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current rate limit.
|
||||
* Gets the current full rate limit information from the server.
|
||||
*
|
||||
* For some versions of GitHub Enterprise, the {@code /rate_limit} endpoint returns a {@code 404 Not Found}. In that
|
||||
* case, the most recent {@link GHRateLimit} information will be returned, including rate limit information returned
|
||||
* in the response header for this request in if was present.
|
||||
*
|
||||
* For most use cases it would be better to implement a {@link RateLimitChecker} and add it via
|
||||
* {@link GitHubBuilder#withRateLimitChecker(RateLimitChecker)}.
|
||||
*
|
||||
* @return the rate limit
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
@Nonnull
|
||||
public GHRateLimit getRateLimit() throws IOException {
|
||||
return client.getRateLimit();
|
||||
}
|
||||
@@ -388,8 +396,11 @@ public class GitHub {
|
||||
* GitHub Enterprise) or if no requests have been made.
|
||||
*
|
||||
* @return the most recently observed rate limit data or {@code null}.
|
||||
* @deprecated implement a {@link RateLimitChecker} and add it via
|
||||
* {@link GitHubBuilder#withRateLimitChecker(RateLimitChecker)}.
|
||||
*/
|
||||
@CheckForNull
|
||||
@Nonnull
|
||||
@Deprecated
|
||||
public GHRateLimit lastRateLimit() {
|
||||
return client.lastRateLimit();
|
||||
}
|
||||
@@ -400,10 +411,13 @@ public class GitHub {
|
||||
* @return the current rate limit data.
|
||||
* @throws IOException
|
||||
* if we couldn't get the current rate limit data.
|
||||
* @deprecated implement a {@link RateLimitChecker} and add it via
|
||||
* {@link GitHubBuilder#withRateLimitChecker(RateLimitChecker)}.
|
||||
*/
|
||||
@Nonnull
|
||||
@Deprecated
|
||||
public GHRateLimit rateLimit() throws IOException {
|
||||
return client.rateLimit();
|
||||
return client.rateLimit(RateLimitTarget.CORE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -358,6 +358,18 @@ public class GitHubBuilder implements Cloneable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link RateLimitChecker} for the Core API for this {@link GitHubBuilder}.
|
||||
*
|
||||
* @param coreRateLimitChecker
|
||||
* the {@link RateLimitChecker} for core GitHub API requests
|
||||
* @return the git hub builder
|
||||
* @see #withRateLimitChecker(RateLimitChecker, RateLimitTarget)
|
||||
*/
|
||||
public GitHubBuilder withRateLimitChecker(@Nonnull RateLimitChecker coreRateLimitChecker) {
|
||||
return withRateLimitChecker(coreRateLimitChecker, RateLimitTarget.CORE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link RateLimitChecker} to this {@link GitHubBuilder}.
|
||||
* <p>
|
||||
@@ -376,15 +388,15 @@ public class GitHubBuilder implements Cloneable {
|
||||
* request.
|
||||
* </p>
|
||||
*
|
||||
* @param coreRateLimitChecker
|
||||
* the {@link RateLimitChecker} for core GitHub API requests
|
||||
* @param rateLimitChecker
|
||||
* the {@link RateLimitChecker} for requests
|
||||
* @param rateLimitTarget
|
||||
* the {@link RateLimitTarget} specifying which rate limit record to check
|
||||
* @return the git hub builder
|
||||
*/
|
||||
public GitHubBuilder withRateLimitChecker(@Nonnull RateLimitChecker coreRateLimitChecker) {
|
||||
this.rateLimitChecker = new GitHubRateLimitChecker(coreRateLimitChecker,
|
||||
RateLimitChecker.NONE,
|
||||
RateLimitChecker.NONE,
|
||||
RateLimitChecker.NONE);
|
||||
public GitHubBuilder withRateLimitChecker(@Nonnull RateLimitChecker rateLimitChecker,
|
||||
@Nonnull RateLimitTarget rateLimitTarget) {
|
||||
this.rateLimitChecker = this.rateLimitChecker.with(rateLimitChecker, rateLimitTarget);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import com.fasterxml.jackson.databind.ObjectReader;
|
||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
@@ -44,7 +44,7 @@ import static java.util.logging.Level.*;
|
||||
* A GitHub API Client
|
||||
* <p>
|
||||
* A GitHubClient can be used to send requests and retrieve their responses. GitHubClient is thread-safe and can be used
|
||||
* to send multiple requests. GitHubClient also track some GitHub API information such as {@link #rateLimit()}.
|
||||
* to send multiple requests. GitHubClient also track some GitHub API information such as {@link GHRateLimit}.
|
||||
* </p>
|
||||
*/
|
||||
abstract class GitHubClient {
|
||||
@@ -70,9 +70,10 @@ abstract class GitHubClient {
|
||||
|
||||
private HttpConnector connector;
|
||||
|
||||
private final Object headerRateLimitLock = new Object();
|
||||
private GHRateLimit headerRateLimit = null;
|
||||
private volatile GHRateLimit rateLimit = null;
|
||||
private final Object rateLimitLock = new Object();
|
||||
|
||||
@Nonnull
|
||||
private GHRateLimit rateLimit = GHRateLimit.DEFAULT;
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(GitHubClient.class.getName());
|
||||
|
||||
@@ -141,10 +142,8 @@ abstract class GitHubClient {
|
||||
}
|
||||
|
||||
private <T> T fetch(Class<T> type, String urlPath) throws IOException {
|
||||
return this
|
||||
.sendRequest(GitHubRequest.newBuilder().withApiUrl(getApiUrl()).withUrlPath(urlPath).build(),
|
||||
(responseInfo) -> GitHubResponse.parseBody(responseInfo, type))
|
||||
.body();
|
||||
GitHubRequest request = GitHubRequest.newBuilder().withApiUrl(getApiUrl()).withUrlPath(urlPath).build();
|
||||
return this.sendRequest(request, (responseInfo) -> GitHubResponse.parseBody(responseInfo, type)).body();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,11 +207,14 @@ abstract class GitHubClient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current rate limit from the server.
|
||||
* Gets the current full rate limit information from the server.
|
||||
*
|
||||
* For some versions of GitHub Enterprise, the {@code /rate_limit} endpoint returns a {@code 404 Not Found}. In
|
||||
* that, if {@link #lastRateLimit()} is not {@code null} and is not expired, it will be returned. Otherwise, a
|
||||
* placeholder {@link GHRateLimit} instance with {@link GHRateLimit.UnknownLimitRecord}s will be returned.
|
||||
* For some versions of GitHub Enterprise, the {@code /rate_limit} endpoint returns a {@code 404 Not Found}. In that
|
||||
* case, the most recent {@link GHRateLimit} information will be returned, including rate limit information returned
|
||||
* in the response header for this request in if was present.
|
||||
*
|
||||
* For most use cases it would be better to implement a {@link RateLimitChecker} and add it via
|
||||
* {@link GitHubBuilder#withRateLimitChecker(RateLimitChecker)}.
|
||||
*
|
||||
* @return the rate limit
|
||||
* @throws IOException
|
||||
@@ -220,59 +222,95 @@ abstract class GitHubClient {
|
||||
*/
|
||||
@Nonnull
|
||||
public GHRateLimit getRateLimit() throws IOException {
|
||||
return getRateLimit(RateLimitTarget.NONE);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
GHRateLimit getRateLimit(@Nonnull RateLimitTarget rateLimitTarget) throws IOException {
|
||||
GHRateLimit result;
|
||||
try {
|
||||
result = fetch(JsonRateLimit.class, "/rate_limit").resources;
|
||||
GitHubRequest request = GitHubRequest.newBuilder()
|
||||
.rateLimit(RateLimitTarget.NONE)
|
||||
.withApiUrl(getApiUrl())
|
||||
.withUrlPath("/rate_limit")
|
||||
.build();
|
||||
result = this
|
||||
.sendRequest(request, (responseInfo) -> GitHubResponse.parseBody(responseInfo, JsonRateLimit.class))
|
||||
.body().resources;
|
||||
} catch (FileNotFoundException e) {
|
||||
// For some versions of GitHub Enterprise, the rate_limit endpoint returns a 404.
|
||||
LOGGER.log(FINE, "/rate_limit returned 404 Not Found.");
|
||||
|
||||
// However some newer versions of GHE include rate limit header information
|
||||
// Use that if available
|
||||
result = lastRateLimit();
|
||||
if (result == null || result.isExpired()) {
|
||||
// return a default rate limit
|
||||
result = GHRateLimit.Unknown();
|
||||
}
|
||||
// If the header info is missing and the endpoint returns 404, fill the rate limit
|
||||
// with unknown
|
||||
result = GHRateLimit.fromRecord(GHRateLimit.UnknownLimitRecord.current(), rateLimitTarget);
|
||||
}
|
||||
|
||||
return rateLimit = result;
|
||||
return updateRateLimit(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the most recently observed rate limit data or {@code null} if either there is no rate limit (for example
|
||||
* GitHub Enterprise) or if no requests have been made.
|
||||
* Returns the most recently observed rate limit data.
|
||||
*
|
||||
* @return the most recently observed rate limit data or {@code null}.
|
||||
* Generally, instead of calling this you should implement a {@link RateLimitChecker} or call
|
||||
*
|
||||
* @return the most recently observed rate limit data. This may include expired or
|
||||
* {@link GHRateLimit.UnknownLimitRecord} entries.
|
||||
* @deprecated implement a {@link RateLimitChecker} and add it via
|
||||
* {@link GitHubBuilder#withRateLimitChecker(RateLimitChecker)}.
|
||||
*/
|
||||
@CheckForNull
|
||||
public GHRateLimit lastRateLimit() {
|
||||
synchronized (headerRateLimitLock) {
|
||||
return headerRateLimit;
|
||||
@Nonnull
|
||||
@Deprecated
|
||||
GHRateLimit lastRateLimit() {
|
||||
synchronized (rateLimitLock) {
|
||||
return rateLimit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current rate limit while trying not to actually make any remote requests unless absolutely necessary.
|
||||
* Gets the current rate limit for an endpoint while trying not to actually make any remote requests unless
|
||||
* absolutely necessary.
|
||||
*
|
||||
* If {@link #lastRateLimit()} is not {@code null} and is not expired, it will be returned. If the information
|
||||
* returned from the last call to {@link #getRateLimit()} is not {@code null} and is not expired, then it will be
|
||||
* returned. Otherwise, the result of a call to {@link #getRateLimit()} will be returned.
|
||||
* If the {@link GHRateLimit.Record} for {@code urlPath} is not expired, it is returned. If the
|
||||
* {@link GHRateLimit.Record} for {@code urlPath} is expired, {@link #getRateLimit()} will be called to get the
|
||||
* current rate limit.
|
||||
*
|
||||
* @return the current rate limit data.
|
||||
* @param rateLimitTarget
|
||||
* the endpoint to get the rate limit for.
|
||||
*
|
||||
* @return the current rate limit data. {@link GHRateLimit.Record}s in this instance may be expired when returned.
|
||||
* @throws IOException
|
||||
* if there was an error getting current rate limit data.
|
||||
*/
|
||||
@Nonnull
|
||||
public GHRateLimit rateLimit() throws IOException {
|
||||
synchronized (headerRateLimitLock) {
|
||||
if (headerRateLimit != null && !headerRateLimit.isExpired()) {
|
||||
return headerRateLimit;
|
||||
GHRateLimit rateLimit(@Nonnull RateLimitTarget rateLimitTarget) throws IOException {
|
||||
synchronized (rateLimitLock) {
|
||||
if (rateLimit.getRecord(rateLimitTarget).isExpired()) {
|
||||
getRateLimit(rateLimitTarget);
|
||||
}
|
||||
return rateLimit;
|
||||
}
|
||||
GHRateLimit result = this.rateLimit;
|
||||
if (result == null || result.isExpired()) {
|
||||
result = getRateLimit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Rate Limit with the latest info from response header.
|
||||
*
|
||||
* Due to multi-threading, requests might complete out of order. This method calls
|
||||
* {@link GHRateLimit#getMergedRateLimit(GHRateLimit)} to ensure the most current records are used.
|
||||
*
|
||||
* @param observed
|
||||
* {@link GHRateLimit.Record} constructed from the response header information
|
||||
*/
|
||||
private GHRateLimit updateRateLimit(@Nonnull GHRateLimit observed) {
|
||||
synchronized (rateLimitLock) {
|
||||
observed = rateLimit.getMergedRateLimit(observed);
|
||||
|
||||
if (rateLimit != observed) {
|
||||
rateLimit = observed;
|
||||
LOGGER.log(FINE, "Rate limit now: {0}", rateLimit);
|
||||
}
|
||||
return rateLimit;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -351,39 +389,43 @@ abstract class GitHubClient {
|
||||
|
||||
GitHubResponse.ResponseInfo responseInfo = null;
|
||||
try {
|
||||
if (LOGGER.isLoggable(FINE)) {
|
||||
LOGGER.log(FINE,
|
||||
"GitHub API request [" + (login == null ? "anonymous" : login) + "]: " + request.method()
|
||||
+ " " + request.url().toString());
|
||||
try {
|
||||
if (LOGGER.isLoggable(FINE)) {
|
||||
LOGGER.log(FINE,
|
||||
"GitHub API request [" + (login == null ? "anonymous" : login) + "]: "
|
||||
+ request.method() + " " + request.url().toString());
|
||||
}
|
||||
|
||||
rateLimitChecker.checkRateLimit(this, request);
|
||||
|
||||
responseInfo = getResponseInfo(request);
|
||||
noteRateLimit(responseInfo);
|
||||
detectOTPRequired(responseInfo);
|
||||
|
||||
if (isInvalidCached404Response(responseInfo)) {
|
||||
// Setting "Cache-Control" to "no-cache" stops the cache from supplying
|
||||
// "If-Modified-Since" or "If-None-Match" values.
|
||||
// This makes GitHub give us current data (not incorrectly cached data)
|
||||
request = request.toBuilder().withHeader("Cache-Control", "no-cache").build();
|
||||
continue;
|
||||
}
|
||||
if (!(isRateLimitResponse(responseInfo) || isAbuseLimitResponse(responseInfo))) {
|
||||
return createResponse(responseInfo, handler);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// For transient errors, retry
|
||||
if (retryConnectionError(e, request.url(), retries)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
throw interpretApiError(e, request, responseInfo);
|
||||
}
|
||||
|
||||
rateLimitChecker.checkRateLimit(this, request);
|
||||
|
||||
responseInfo = getResponseInfo(request);
|
||||
noteRateLimit(responseInfo);
|
||||
detectOTPRequired(responseInfo);
|
||||
|
||||
if (isInvalidCached404Response(responseInfo)) {
|
||||
// Setting "Cache-Control" to "no-cache" stops the cache from supplying
|
||||
// "If-Modified-Since" or "If-None-Match" values.
|
||||
// This makes GitHub give us current data (not incorrectly cached data)
|
||||
request = request.toBuilder().withHeader("Cache-Control", "no-cache").build();
|
||||
continue;
|
||||
}
|
||||
if (!(isRateLimitResponse(responseInfo) || isAbuseLimitResponse(responseInfo))) {
|
||||
return createResponse(responseInfo, handler);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// For transient errors, retry
|
||||
if (retryConnectionError(e, request.url(), retries)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
throw interpretApiError(e, request, responseInfo);
|
||||
handleLimitingErrors(responseInfo);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(responseInfo);
|
||||
}
|
||||
|
||||
handleLimitingErrors(responseInfo);
|
||||
|
||||
} while (--retries >= 0);
|
||||
|
||||
throw new GHIOException("Ran out of retries for URL: " + request.url().toString());
|
||||
@@ -512,58 +554,25 @@ abstract class GitHubClient {
|
||||
}
|
||||
|
||||
private void noteRateLimit(@Nonnull GitHubResponse.ResponseInfo responseInfo) {
|
||||
if (responseInfo.request().urlPath().startsWith("/search")) {
|
||||
// the search API uses a different rate limit
|
||||
return;
|
||||
}
|
||||
|
||||
String limitString = responseInfo.headerField("X-RateLimit-Limit");
|
||||
if (StringUtils.isBlank(limitString)) {
|
||||
// if we are missing a header, return fast
|
||||
return;
|
||||
}
|
||||
String remainingString = responseInfo.headerField("X-RateLimit-Remaining");
|
||||
if (StringUtils.isBlank(remainingString)) {
|
||||
// if we are missing a header, return fast
|
||||
return;
|
||||
}
|
||||
String resetString = responseInfo.headerField("X-RateLimit-Reset");
|
||||
if (StringUtils.isBlank(resetString)) {
|
||||
// if we are missing a header, return fast
|
||||
return;
|
||||
}
|
||||
|
||||
int limit, remaining;
|
||||
long reset;
|
||||
try {
|
||||
String limitString = Objects.requireNonNull(responseInfo.headerField("X-RateLimit-Limit"),
|
||||
"Missing X-RateLimit-Limit");
|
||||
String remainingString = Objects.requireNonNull(responseInfo.headerField("X-RateLimit-Remaining"),
|
||||
"Missing X-RateLimit-Remaining");
|
||||
String resetString = Objects.requireNonNull(responseInfo.headerField("X-RateLimit-Reset"),
|
||||
"Missing X-RateLimit-Reset");
|
||||
int limit, remaining;
|
||||
long reset;
|
||||
limit = Integer.parseInt(limitString);
|
||||
} catch (NumberFormatException e) {
|
||||
if (LOGGER.isLoggable(FINEST)) {
|
||||
LOGGER.log(FINEST, "Malformed X-RateLimit-Limit header value " + limitString, e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
||||
remaining = Integer.parseInt(remainingString);
|
||||
} catch (NumberFormatException e) {
|
||||
if (LOGGER.isLoggable(FINEST)) {
|
||||
LOGGER.log(FINEST, "Malformed X-RateLimit-Remaining header value " + remainingString, e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
reset = Long.parseLong(resetString);
|
||||
} catch (NumberFormatException e) {
|
||||
GHRateLimit.Record observed = new GHRateLimit.Record(limit, remaining, reset, responseInfo);
|
||||
updateRateLimit(GHRateLimit.fromRecord(observed, responseInfo.request().rateLimitTarget()));
|
||||
} catch (NumberFormatException | NullPointerException e) {
|
||||
if (LOGGER.isLoggable(FINEST)) {
|
||||
LOGGER.log(FINEST, "Malformed X-RateLimit-Reset header value " + resetString, e);
|
||||
LOGGER.log(FINEST, "Missing or malformed X-RateLimit header: ", e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
GHRateLimit.Record observed = new GHRateLimit.Record(limit, remaining, reset, responseInfo);
|
||||
|
||||
updateCoreRateLimit(observed);
|
||||
}
|
||||
|
||||
private static void detectOTPRequired(@Nonnull GitHubResponse.ResponseInfo responseInfo) throws GHIOException {
|
||||
@@ -583,23 +592,6 @@ abstract class GitHubClient {
|
||||
"This operation requires a credential but none is given to the GitHub constructor");
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Rate Limit with the latest info from response header. Due to multi-threading requests might complete
|
||||
* out of order, we want to pick the one with the most recent info from the server. Calls
|
||||
* {@link #shouldReplace(GHRateLimit.Record, GHRateLimit.Record)}
|
||||
*
|
||||
* @param observed
|
||||
* {@link GHRateLimit.Record} constructed from the response header information
|
||||
*/
|
||||
private void updateCoreRateLimit(@Nonnull GHRateLimit.Record observed) {
|
||||
synchronized (headerRateLimitLock) {
|
||||
if (headerRateLimit == null || shouldReplace(observed, headerRateLimit.getCore())) {
|
||||
headerRateLimit = GHRateLimit.fromHeaderRecord(observed);
|
||||
LOGGER.log(FINE, "Rate limit now: {0}", headerRateLimit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class GHApiInfo {
|
||||
private String rate_limit_url;
|
||||
|
||||
@@ -649,37 +641,6 @@ abstract class GitHubClient {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if one {@link GHRateLimit.Record} should replace another. Header date is only accurate to the second,
|
||||
* so we look at the information in the record itself.
|
||||
*
|
||||
* {@link GHRateLimit.UnknownLimitRecord}s are always replaced by regular {@link GHRateLimit.Record}s. Regular
|
||||
* {@link GHRateLimit.Record}s are never replaced by {@link GHRateLimit.UnknownLimitRecord}s. Candidates with
|
||||
* resetEpochSeconds later than current record are more recent. Candidates with the same reset and a lower remaining
|
||||
* count are more recent. Candidates with an earlier reset are older.
|
||||
*
|
||||
* @param candidate
|
||||
* {@link GHRateLimit.Record} constructed from the response header information
|
||||
* @param current
|
||||
* the current {@link GHRateLimit.Record} record
|
||||
*/
|
||||
static boolean shouldReplace(@Nonnull GHRateLimit.Record candidate, @Nonnull GHRateLimit.Record current) {
|
||||
if (candidate instanceof GHRateLimit.UnknownLimitRecord
|
||||
&& !(current instanceof GHRateLimit.UnknownLimitRecord)) {
|
||||
// Unknown candidate never replaces a regular record
|
||||
return false;
|
||||
} else if (current instanceof GHRateLimit.UnknownLimitRecord
|
||||
&& !(candidate instanceof GHRateLimit.UnknownLimitRecord)) {
|
||||
// Any real record should replace an unknown Record.
|
||||
return true;
|
||||
} else {
|
||||
// records of the same type compare to each other as normal.
|
||||
return current.getResetEpochSeconds() < candidate.getResetEpochSeconds()
|
||||
|| (current.getResetEpochSeconds() == candidate.getResetEpochSeconds()
|
||||
&& current.getRemaining() > candidate.getRemaining());
|
||||
}
|
||||
}
|
||||
|
||||
static URL parseURL(String s) {
|
||||
try {
|
||||
return s == null ? null : new URL(s);
|
||||
|
||||
@@ -24,7 +24,7 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||
* A GitHub API Client for HttpUrlConnection
|
||||
* <p>
|
||||
* A GitHubClient can be used to send requests and retrieve their responses. GitHubClient is thread-safe and can be used
|
||||
* to send multiple requests. GitHubClient also track some GitHub API information such as {@link #rateLimit()}.
|
||||
* to send multiple requests. GitHubClient also track some GitHub API information such as {@link GHRateLimit}.
|
||||
* </p>
|
||||
* <p>
|
||||
* GitHubHttpUrlConnectionClient gets a new {@link HttpURLConnection} for each call to send.
|
||||
@@ -235,6 +235,10 @@ class GitHubHttpUrlConnectionClient extends GitHubClient {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(GitHubClient.class.getName());
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
IOUtils.closeQuietly(connection.getInputStream());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,26 +3,28 @@ package org.kohsuke.github;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* A GitHub API Rate Limit Checker called before each request. This class provides the basic infrastructure for calling
|
||||
* the appropriate {@link RateLimitChecker} for a request and retrying as many times as needed. This class supports more
|
||||
* complex throttling strategies and polling, but leaves the specifics to the {@link RateLimitChecker} implementations.
|
||||
* A GitHub API Rate Limit Checker called before each request.
|
||||
*
|
||||
* <p>
|
||||
* GitHub allots a certain number of requests to each user or application per period of time (usually per hour). The
|
||||
* number of requests remaining is returned in the response header and can also be requested using
|
||||
* {@link GitHub#getRateLimit()}. This requests per interval is referred to as the "rate limit".
|
||||
* GitHub allots a certain number of requests to each user or application per period of time. The number of requests
|
||||
* remaining and the time when the number will be reset is returned in the response header and can also be requested
|
||||
* using {@link GitHub#getRateLimit()}. The "requests per interval" is referred to as the "rate limit".
|
||||
* </p>
|
||||
* <p>
|
||||
* GitHub prefers that clients stop before exceeding their rate limit rather than stopping after they exceed it. The
|
||||
* {@link RateLimitChecker} is called before each request to check the rate limit and wait if the checker criteria are
|
||||
* met.
|
||||
* Different parts of the GitHub API have separate rate limits, but most of REST API uses {@link RateLimitTarget#CORE}.
|
||||
* Checking your rate limit using {@link GitHub#getRateLimit()} does not effect your rate limit. GitHub prefers that
|
||||
* clients stop before exceeding their rate limit rather than stopping after they exceed it.
|
||||
* </p>
|
||||
* <p>
|
||||
* Checking your rate limit using {@link GitHub#getRateLimit()} does not effect your rate limit, but each {@link GitHub}
|
||||
* instance will attempt to cache and reuse the last see rate limit rather than making a new request.
|
||||
* This class provides the infrastructure for calling the appropriate {@link RateLimitChecker} before each request and
|
||||
* retrying than call many times as needed. Each {@link RateLimitChecker} decides whether to wait and for how long. This
|
||||
* allows for a wide range of {@link RateLimitChecker} implementations, including complex throttling strategies and
|
||||
* polling.
|
||||
* </p>
|
||||
*/
|
||||
class GitHubRateLimitChecker {
|
||||
@@ -39,6 +41,8 @@ class GitHubRateLimitChecker {
|
||||
@Nonnull
|
||||
private final RateLimitChecker integrationManifest;
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(GitHubRateLimitChecker.class.getName());
|
||||
|
||||
GitHubRateLimitChecker() {
|
||||
this(RateLimitChecker.NONE, RateLimitChecker.NONE, RateLimitChecker.NONE, RateLimitChecker.NONE);
|
||||
}
|
||||
@@ -48,40 +52,57 @@ class GitHubRateLimitChecker {
|
||||
@Nonnull RateLimitChecker graphql,
|
||||
@Nonnull RateLimitChecker integrationManifest) {
|
||||
this.core = Objects.requireNonNull(core);
|
||||
|
||||
// for now only support rate limiting on core
|
||||
// remove these asserts when that changes
|
||||
assert search == RateLimitChecker.NONE;
|
||||
assert graphql == RateLimitChecker.NONE;
|
||||
assert integrationManifest == RateLimitChecker.NONE;
|
||||
|
||||
this.search = Objects.requireNonNull(search);
|
||||
this.graphql = Objects.requireNonNull(graphql);
|
||||
this.integrationManifest = Objects.requireNonNull(integrationManifest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link GitHubRateLimitChecker} with a new checker for a particular target.
|
||||
*
|
||||
* Only one {@link RateLimitChecker} is allowed per target.
|
||||
*
|
||||
* @param checker
|
||||
* the {@link RateLimitChecker} to apply.
|
||||
* @param rateLimitTarget
|
||||
* the {@link RateLimitTarget} for this checker. If {@link RateLimitTarget#NONE}, checker will be ignored
|
||||
* and no change will be made.
|
||||
* @return a new {@link GitHubRateLimitChecker}
|
||||
*/
|
||||
GitHubRateLimitChecker with(@Nonnull RateLimitChecker checker, @Nonnull RateLimitTarget rateLimitTarget) {
|
||||
return new GitHubRateLimitChecker(rateLimitTarget == RateLimitTarget.CORE ? checker : core,
|
||||
rateLimitTarget == RateLimitTarget.SEARCH ? checker : search,
|
||||
rateLimitTarget == RateLimitTarget.GRAPHQL ? checker : graphql,
|
||||
rateLimitTarget == RateLimitTarget.INTEGRATION_MANIFEST ? checker : integrationManifest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether there is sufficient requests remaining within this client's rate limit quota to make the current
|
||||
* request.
|
||||
* <p>
|
||||
* This method does not do the actual check. Instead it select the appropriate {@link RateLimitChecker} and
|
||||
* {@link GHRateLimit.Record} for the current request's urlPath. If the {@link RateLimitChecker} for this the
|
||||
* current request's urlPath is {@link RateLimitChecker#NONE} the rate limit is not checked. If not, it calls
|
||||
* {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)}. which decides if the rate limit has been
|
||||
* exceeded and then sleeps for as long is it choose.
|
||||
* This method does not do the actual check. Instead it selects the appropriate {@link RateLimitChecker} and
|
||||
* {@link GHRateLimit.Record} for the current request's {@link RateLimitTarget}. It then calls
|
||||
* {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)}.
|
||||
* </p>
|
||||
* <p>
|
||||
* It is up to the {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)} which decide if the rate limit
|
||||
* has been exceeded. If it has, that method will sleep for as long is it chooses and then return {@code true}. If
|
||||
* not, that method will return {@code false}.
|
||||
* It is up to {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)} to which decide if the rate limit
|
||||
* has been exceeded. If it has, {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)} will sleep for as
|
||||
* long is it chooses and then return {@code true}. If not, that method will return {@code false}.
|
||||
* </p>
|
||||
* <p>
|
||||
* As long as {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)} returns {@code true}, this method
|
||||
* will request updated rate limit information and call
|
||||
* {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)} again. This looping allows implementers of
|
||||
* {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)} to apply any number of strategies to
|
||||
* controlling the speed at which requests are made. When it returns {@code false} this method will return and the
|
||||
* request will be sent.
|
||||
* {@link RateLimitChecker#checkRateLimit(GHRateLimit.Record, long)} again. This looping allows different
|
||||
* {@link RateLimitChecker} implementations to apply any number of strategies to controlling the speed at which
|
||||
* requests are made.
|
||||
* </p>
|
||||
* <p>
|
||||
* When the {@link RateLimitChecker} returns {@code false} this method will return and the request processing will
|
||||
* continue.
|
||||
* </p>
|
||||
* <p>
|
||||
* If the {@link RateLimitChecker} for this the current request's urlPath is {@link RateLimitChecker#NONE} the rate
|
||||
* limit is not checked.
|
||||
* </p>
|
||||
*
|
||||
* @param client
|
||||
@@ -92,14 +113,14 @@ class GitHubRateLimitChecker {
|
||||
* if there is an I/O error
|
||||
*/
|
||||
void checkRateLimit(GitHubClient client, GitHubRequest request) throws IOException {
|
||||
RateLimitChecker guard = selectChecker(request.urlPath());
|
||||
RateLimitChecker guard = selectChecker(request.rateLimitTarget());
|
||||
if (guard == RateLimitChecker.NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For the first rate limit, accept the current limit if a valid one is already present.
|
||||
GHRateLimit rateLimit = client.rateLimit();
|
||||
GHRateLimit.Record rateLimitRecord = rateLimit.getRecordForUrlPath(request.urlPath());
|
||||
GHRateLimit rateLimit = client.rateLimit(request.rateLimitTarget());
|
||||
GHRateLimit.Record rateLimitRecord = rateLimit.getRecord(request.rateLimitTarget());
|
||||
long waitCount = 0;
|
||||
try {
|
||||
while (guard.checkRateLimit(rateLimitRecord, waitCount)) {
|
||||
@@ -112,8 +133,8 @@ class GitHubRateLimitChecker {
|
||||
Thread.sleep(1000);
|
||||
|
||||
// After the first wait, always request a new rate limit from the server.
|
||||
rateLimit = client.getRateLimit();
|
||||
rateLimitRecord = rateLimit.getRecordForUrlPath(request.urlPath());
|
||||
rateLimit = client.getRateLimit(request.rateLimitTarget());
|
||||
rateLimitRecord = rateLimit.getRecord(request.rateLimitTarget());
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw (IOException) new InterruptedIOException(e.getMessage()).initCause(e);
|
||||
@@ -121,25 +142,28 @@ class GitHubRateLimitChecker {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the appropriate {@link RateLimitChecker} for a particular url path. Similar to
|
||||
* {@link GHRateLimit#getRecordForUrlPath(String)}.
|
||||
* Gets the appropriate {@link RateLimitChecker} for a particular target.
|
||||
*
|
||||
* @param urlPath
|
||||
* the url path of the request
|
||||
* @return the {@link RateLimitChecker} for a url path.
|
||||
* Analogous with {@link GHRateLimit#getRecord(RateLimitTarget)}.
|
||||
*
|
||||
* @param rateLimitTarget
|
||||
* the rate limit to check
|
||||
* @return the {@link RateLimitChecker} for a particular target
|
||||
*/
|
||||
@Nonnull
|
||||
private RateLimitChecker selectChecker(@Nonnull String urlPath) {
|
||||
if (urlPath.equals("/rate_limit")) {
|
||||
private RateLimitChecker selectChecker(@Nonnull RateLimitTarget rateLimitTarget) {
|
||||
if (rateLimitTarget == RateLimitTarget.NONE) {
|
||||
return RateLimitChecker.NONE;
|
||||
} else if (urlPath.startsWith("/search")) {
|
||||
} else if (rateLimitTarget == RateLimitTarget.CORE) {
|
||||
return core;
|
||||
} else if (rateLimitTarget == RateLimitTarget.SEARCH) {
|
||||
return search;
|
||||
} else if (urlPath.startsWith("/graphql")) {
|
||||
} else if (rateLimitTarget == RateLimitTarget.GRAPHQL) {
|
||||
return graphql;
|
||||
} else if (urlPath.startsWith("/app-manifests")) {
|
||||
} else if (rateLimitTarget == RateLimitTarget.INTEGRATION_MANIFEST) {
|
||||
return integrationManifest;
|
||||
} else {
|
||||
return core;
|
||||
throw new IllegalArgumentException("Unknown rate limit target: " + rateLimitTarget.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ class GitHubRequest {
|
||||
private final String apiUrl;
|
||||
private final String urlPath;
|
||||
private final String method;
|
||||
private final RateLimitTarget rateLimitTarget;
|
||||
private final InputStream body;
|
||||
private final boolean forceBody;
|
||||
|
||||
@@ -56,6 +57,7 @@ class GitHubRequest {
|
||||
@Nonnull String apiUrl,
|
||||
@Nonnull String urlPath,
|
||||
@Nonnull String method,
|
||||
@Nonnull RateLimitTarget rateLimitTarget,
|
||||
@CheckForNull InputStream body,
|
||||
boolean forceBody) throws MalformedURLException {
|
||||
this.args = Collections.unmodifiableList(new ArrayList<>(args));
|
||||
@@ -64,6 +66,7 @@ class GitHubRequest {
|
||||
this.apiUrl = apiUrl;
|
||||
this.urlPath = urlPath;
|
||||
this.method = method;
|
||||
this.rateLimitTarget = rateLimitTarget;
|
||||
this.body = body;
|
||||
this.forceBody = forceBody;
|
||||
String tailApiUrl = buildTailApiUrl();
|
||||
@@ -119,6 +122,16 @@ class GitHubRequest {
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rate limit target for this request.
|
||||
*
|
||||
* @return the rate limit to use for this request.
|
||||
*/
|
||||
@Nonnull
|
||||
public RateLimitTarget rateLimitTarget() {
|
||||
return rateLimitTarget;
|
||||
}
|
||||
|
||||
/**
|
||||
* The arguments for this request. Depending on the {@link #method()} and {@code #inBody()} these maybe added to the
|
||||
* url or to the request body.
|
||||
@@ -217,7 +230,15 @@ class GitHubRequest {
|
||||
* @return a {@link Builder} based on this request.
|
||||
*/
|
||||
public Builder<?> toBuilder() {
|
||||
return new Builder<>(args, headers, injectedMappingValues, apiUrl, urlPath, method, body, forceBody);
|
||||
return new Builder<>(args,
|
||||
headers,
|
||||
injectedMappingValues,
|
||||
apiUrl,
|
||||
urlPath,
|
||||
method,
|
||||
rateLimitTarget,
|
||||
body,
|
||||
forceBody);
|
||||
}
|
||||
|
||||
private String buildTailApiUrl() {
|
||||
@@ -281,6 +302,10 @@ class GitHubRequest {
|
||||
*/
|
||||
@Nonnull
|
||||
private String method;
|
||||
|
||||
@Nonnull
|
||||
private RateLimitTarget rateLimitTarget;
|
||||
|
||||
private InputStream body;
|
||||
private boolean forceBody;
|
||||
|
||||
@@ -294,6 +319,7 @@ class GitHubRequest {
|
||||
GitHubClient.GITHUB_URL,
|
||||
"/",
|
||||
"GET",
|
||||
RateLimitTarget.CORE,
|
||||
null,
|
||||
false);
|
||||
}
|
||||
@@ -304,6 +330,7 @@ class GitHubRequest {
|
||||
@Nonnull String apiUrl,
|
||||
@Nonnull String urlPath,
|
||||
@Nonnull String method,
|
||||
@Nonnull RateLimitTarget rateLimitTarget,
|
||||
@CheckForNull @WillClose InputStream body,
|
||||
boolean forceBody) {
|
||||
this.args = new ArrayList<>(args);
|
||||
@@ -312,6 +339,7 @@ class GitHubRequest {
|
||||
this.apiUrl = apiUrl;
|
||||
this.urlPath = urlPath;
|
||||
this.method = method;
|
||||
this.rateLimitTarget = rateLimitTarget;
|
||||
this.body = body;
|
||||
this.forceBody = forceBody;
|
||||
}
|
||||
@@ -324,7 +352,15 @@ class GitHubRequest {
|
||||
* if the GitHub API URL cannot be constructed
|
||||
*/
|
||||
public GitHubRequest build() throws MalformedURLException {
|
||||
return new GitHubRequest(args, headers, injectedMappingValues, apiUrl, urlPath, method, body, forceBody);
|
||||
return new GitHubRequest(args,
|
||||
headers,
|
||||
injectedMappingValues,
|
||||
apiUrl,
|
||||
urlPath,
|
||||
method,
|
||||
rateLimitTarget,
|
||||
body,
|
||||
forceBody);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -562,6 +598,18 @@ class GitHubRequest {
|
||||
return (B) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method requester.
|
||||
*
|
||||
* @param rateLimitTarget
|
||||
* the rate limit target for this request. Default is {@link RateLimitTarget#CORE}.
|
||||
* @return the request builder
|
||||
*/
|
||||
public B rateLimit(@Nonnull RateLimitTarget rateLimitTarget) {
|
||||
this.rateLimitTarget = rateLimitTarget;
|
||||
return (B) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Content type requester.
|
||||
*
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.InjectableValues;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
@@ -212,7 +213,7 @@ class GitHubResponse<T> {
|
||||
* Initial response information supplied to a {@link BodyHandler} when a response is initially received and before
|
||||
* the body is processed.
|
||||
*/
|
||||
static abstract class ResponseInfo {
|
||||
static abstract class ResponseInfo implements Closeable {
|
||||
|
||||
private static final Comparator<String> nullableCaseInsensitiveComparator = Comparator
|
||||
.nullsFirst(String.CASE_INSENSITIVE_ORDER);
|
||||
@@ -317,12 +318,8 @@ class GitHubResponse<T> {
|
||||
@Nonnull
|
||||
String getBodyAsString() throws IOException {
|
||||
InputStreamReader r = null;
|
||||
try {
|
||||
r = new InputStreamReader(this.bodyStream(), StandardCharsets.UTF_8);
|
||||
return IOUtils.toString(r);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(r);
|
||||
}
|
||||
r = new InputStreamReader(this.bodyStream(), StandardCharsets.UTF_8);
|
||||
return IOUtils.toString(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,20 +5,17 @@ import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A GitHub API Rate Limit Checker called before each request
|
||||
*
|
||||
* <p>
|
||||
* GitHub allots a certain number of requests to each user or application per period of time (usually per hour). The
|
||||
* number of requests remaining is returned in the response header and can also be requested using
|
||||
* {@link GitHub#getRateLimit()}. This requests per interval is referred to as the "rate limit".
|
||||
* GitHub allots a certain number of requests to each user or application per period of time. The number of requests
|
||||
* remaining and the time when the number will be reset is returned in the response header and can also be requested
|
||||
* using {@link GitHub#getRateLimit()}. The "requests per interval" is referred to as the "rate limit".
|
||||
* </p>
|
||||
* <p>
|
||||
* GitHub prefers that clients stop before exceeding their rate limit rather than stopping after they exceed it. The
|
||||
* {@link RateLimitChecker} is called before each request to check the rate limit and wait if the checker criteria are
|
||||
* met.
|
||||
* </p>
|
||||
* <p>
|
||||
* Checking your rate limit using {@link GitHub#getRateLimit()} does not effect your rate limit, but each {@link GitHub}
|
||||
* instance will attempt to cache and reuse the last see rate limit rather than making a new request.
|
||||
* </p>
|
||||
*/
|
||||
public abstract class RateLimitChecker {
|
||||
|
||||
@@ -33,28 +30,21 @@ public abstract class RateLimitChecker {
|
||||
* free to choose whatever strategy they prefer for what is considered to exceed the budget and how long to sleep.
|
||||
*
|
||||
* <p>
|
||||
* The caller of this method figures out which {@link GHRateLimit.Record} applies for the current request add
|
||||
* The caller of this method figures out which {@link GHRateLimit.Record} applies for the current request and
|
||||
* provides it to this method.
|
||||
* </p>
|
||||
* <p>
|
||||
* It is important to remember that rate limit reset times are only accurate to the second. Trying to sleep to
|
||||
* exactly the reset time would be likely to produce worse behavior rather than better. For this reason
|
||||
* {@link GitHubRateLimitChecker} may choose to add more sleep times when a checker indicates the rate limit was
|
||||
* exceeded.
|
||||
* As long as this method returns {@code true} it is guaranteed that {@link GitHubRateLimitChecker} will retrieve
|
||||
* updated rate limit information and call this method again with {@code count} incremented by one. When this
|
||||
* checker returns {@code false}, the calling {@link GitHubRateLimitChecker} will let the request continue.
|
||||
* </p>
|
||||
* <p>
|
||||
* As long as this method returns {@code true} it is guaranteed that {@link GitHubRateLimitChecker} will get updated
|
||||
* rate limit information and call this method again with {@code count} incremented by one. After this method
|
||||
* returns {@code true} at least once, the calling {@link GitHubRateLimitChecker} may choose to wait some additional
|
||||
* period of time between calls to this checker.
|
||||
* Rate limit reset times are only accurate to the second. Trying to sleep to exactly the reset time could result in
|
||||
* requests being sent before the new rate limit was available. For this reason, if this method returned
|
||||
* {@code true} at least once for a particular request, {@link GitHubRateLimitChecker} may choose to sleep for some
|
||||
* small additional between calls and before letting the request continue.
|
||||
* </p>
|
||||
* <p>
|
||||
* After this checker returns {@code false}, the calling {@link GitHubRateLimitChecker} will let the request
|
||||
* continue. If this method returned {@code true} at least once for a particular request, the calling
|
||||
* {@link GitHubRateLimitChecker} may choose to wait some additional period of time before letting the request be
|
||||
* sent.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param rateLimitRecord
|
||||
* the current {@link GHRateLimit.Record} to check against.
|
||||
* @param count
|
||||
|
||||
36
src/main/java/org/kohsuke/github/RateLimitTarget.java
Normal file
36
src/main/java/org/kohsuke/github/RateLimitTarget.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* Specifies the rate limit record of an operation.
|
||||
*
|
||||
* @see GitHubBuilder#withRateLimitChecker(RateLimitChecker, RateLimitTarget)
|
||||
*/
|
||||
public enum RateLimitTarget {
|
||||
/**
|
||||
* Selects or updates the {@link GHRateLimit#getCore()} record.
|
||||
*/
|
||||
CORE,
|
||||
|
||||
/**
|
||||
* Selects or updates the {@link GHRateLimit#getSearch()} record.
|
||||
*/
|
||||
SEARCH,
|
||||
|
||||
/**
|
||||
* Selects or updates the {@link GHRateLimit#getGraphQL()} record.
|
||||
*/
|
||||
GRAPHQL,
|
||||
|
||||
/**
|
||||
* Selects or updates the {@link GHRateLimit#getIntegrationManifest()} record.
|
||||
*/
|
||||
INTEGRATION_MANIFEST,
|
||||
|
||||
/**
|
||||
* Selects no rate limit.
|
||||
*
|
||||
* This request uses no rate limit. If the response header includes rate limit information, it will apply to
|
||||
* {@link #CORE}.
|
||||
*/
|
||||
NONE
|
||||
}
|
||||
@@ -23,6 +23,9 @@
|
||||
*/
|
||||
package org.kohsuke.github;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
@@ -108,7 +111,10 @@ class Requester extends GitHubRequest.Builder<Requester> {
|
||||
* the io exception
|
||||
*/
|
||||
public InputStream fetchStream() throws IOException {
|
||||
return client.sendRequest(this, (responseInfo) -> responseInfo.bodyStream()).body();
|
||||
return client
|
||||
.sendRequest(this,
|
||||
(responseInfo) -> new ByteArrayInputStream(IOUtils.toByteArray(responseInfo.bodyStream())))
|
||||
.body();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
31
src/site/apt/createorglevelresources.apt
Normal file
31
src/site/apt/createorglevelresources.apt
Normal file
@@ -0,0 +1,31 @@
|
||||
Creating resources at the organization level
|
||||
|
||||
In order to create resources in GitHub for a given organization, you must first create an object of type <<<GHOrganization>>>.
|
||||
As an example:
|
||||
|
||||
+-----+
|
||||
GHOrganization organizationClient(GitHub gitHub, String organizationName) throws IOException {
|
||||
return gitHub.getOrganization(organizationName);
|
||||
}
|
||||
+-----+
|
||||
|
||||
Now you can easily work with the GHOrganization, and all methods that will create resources will create them
|
||||
in the given organization.
|
||||
|
||||
One of the most common use cases is to create a repository in a given organization:
|
||||
|
||||
+-----+
|
||||
void createRepository(GHOrganization organization) {
|
||||
organization.createRepository("repository-name")
|
||||
.private_(true)
|
||||
.wiki(false)
|
||||
.projects(false)
|
||||
.description("Description")
|
||||
.allowMergeCommit(true)
|
||||
.allowSquashMerge(false)
|
||||
.allowRebaseMerge(false)
|
||||
.create()
|
||||
}
|
||||
+-----+
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
<item name="JWT Authentication" href="/githubappjwtauth.html"/>
|
||||
<item name="App Installation Token " href="/githubappappinsttokenauth.html"/>
|
||||
</item>
|
||||
<item name="Working with organizations" href="/createorglevelresources.html"/>
|
||||
</menu>
|
||||
|
||||
<menu name="References">
|
||||
|
||||
@@ -20,6 +20,7 @@ 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;
|
||||
|
||||
@@ -108,7 +109,7 @@ public class AppTest extends AbstractGitHubWireMockTest {
|
||||
gitHub = getGitHubBuilder().withOAuthToken("bogus", "user")
|
||||
.withEndpoint(mockGitHub.apiServer().baseUrl())
|
||||
.build();
|
||||
assertThat(gitHub.lastRateLimit(), nullValue());
|
||||
assertThat(gitHub.lastRateLimit(), sameInstance(GHRateLimit.DEFAULT));
|
||||
assertFalse(gitHub.isCredentialValid());
|
||||
// For invalid credentials, we get a 401 but it includes anonymous rate limit headers
|
||||
assertThat(gitHub.lastRateLimit().getCore(), not(instanceOf(GHRateLimit.UnknownLimitRecord.class)));
|
||||
@@ -118,18 +119,22 @@ public class AppTest extends AbstractGitHubWireMockTest {
|
||||
@Test
|
||||
public void testCredentialValidEnterprise() throws IOException {
|
||||
// Simulated GHE: getRateLimit returns 404
|
||||
assertThat(gitHub.lastRateLimit(), nullValue());
|
||||
assertThat(gitHub.lastRateLimit(), sameInstance(GHRateLimit.DEFAULT));
|
||||
assertThat(gitHub.lastRateLimit().getCore().isExpired(), is(true));
|
||||
assertTrue(gitHub.isCredentialValid());
|
||||
// lastRateLimit stays null when 404 is encountered
|
||||
assertThat(gitHub.lastRateLimit(), nullValue());
|
||||
|
||||
// lastRateLimitUpdates because 404 still includes header rate limit info
|
||||
assertThat(gitHub.lastRateLimit(), notNullValue());
|
||||
assertThat(gitHub.lastRateLimit(), not(equalTo(GHRateLimit.DEFAULT)));
|
||||
assertThat(gitHub.lastRateLimit().getCore().isExpired(), is(false));
|
||||
|
||||
gitHub = getGitHubBuilder().withOAuthToken("bogus", "user")
|
||||
.withEndpoint(mockGitHub.apiServer().baseUrl())
|
||||
.build();
|
||||
assertThat(gitHub.lastRateLimit(), nullValue());
|
||||
assertThat(gitHub.lastRateLimit(), sameInstance(GHRateLimit.DEFAULT));
|
||||
assertFalse(gitHub.isCredentialValid());
|
||||
// Simulated GHE: For invalid credentials, we get a 401 that does not include ratelimit info
|
||||
assertThat(gitHub.lastRateLimit(), nullValue());
|
||||
assertThat(gitHub.lastRateLimit(), sameInstance(GHRateLimit.DEFAULT));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -12,6 +12,7 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.Matchers.hasProperty;
|
||||
|
||||
/**
|
||||
* Integration test for {@link GHContent}.
|
||||
@@ -170,4 +171,24 @@ public class GHContentIntegrationTest extends AbstractGitHubWireMockTest {
|
||||
final GHContent fileContent2 = repo.getFileContent(fileContent.getPath());
|
||||
assertThat(IOUtils.readLines(fileContent2.read(), StandardCharsets.UTF_8), hasItems("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFileContentWithSymlink() throws Exception {
|
||||
final GHRepository repo = gitHub.getRepository("hub4j-test-org/GHContentIntegrationTest");
|
||||
|
||||
final GHContent fileContent = repo.getFileContent("ghcontent-ro/a-symlink-to-a-file");
|
||||
// for whatever reason GH says this is a file :-o
|
||||
assertThat(IOUtils.toString(fileContent.read(), StandardCharsets.UTF_8), is("thanks for reading me\n"));
|
||||
|
||||
final GHContent dirContent = repo.getFileContent("ghcontent-ro/a-symlink-to-a-dir");
|
||||
// but symlinks to directories are symlinks!
|
||||
assertThat(dirContent,
|
||||
allOf(hasProperty("target", is("a-dir-with-3-entries")), hasProperty("type", is("symlink"))));
|
||||
|
||||
// future somehow...
|
||||
|
||||
// final GHContent fileContent2 = repo.getFileContent("ghcontent-ro/a-symlink-to-a-dir/entry-one");
|
||||
// this needs special handling and will 404 from GitHub
|
||||
// assertThat(IOUtils.toString(fileContent.read(), StandardCharsets.UTF_8), is(""));
|
||||
}
|
||||
}
|
||||
|
||||
145
src/test/java/org/kohsuke/github/GHDiscussionTest.java
Normal file
145
src/test/java/org/kohsuke/github/GHDiscussionTest.java
Normal file
@@ -0,0 +1,145 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
/**
|
||||
* @author Charles Moulliard
|
||||
*/
|
||||
public class GHDiscussionTest extends AbstractGitHubWireMockTest {
|
||||
private final String TEAM_SLUG = "dummy-team";
|
||||
private GHTeam team;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
team = gitHub.getOrganization(GITHUB_API_TEST_ORG).getTeamBySlug(TEAM_SLUG);
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanupDiscussions() throws Exception {
|
||||
// only need to clean up if we're pointing to the live site
|
||||
if (mockGitHub.isUseProxy()) {
|
||||
for (GHDiscussion discussion : getGitHubBeforeAfter().getOrganization(GITHUB_API_TEST_ORG)
|
||||
.getTeamBySlug(TEAM_SLUG)
|
||||
.listDiscussions()) {
|
||||
discussion.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatedDiscussion() throws IOException {
|
||||
GHDiscussion discussion = team.createDiscussion("Some Discussion").body("This is a public discussion").done();
|
||||
assertThat(discussion, notNullValue());
|
||||
assertThat(discussion.getTeam(), equalTo(team));
|
||||
assertThat(discussion.getTitle(), equalTo("Some Discussion"));
|
||||
assertThat(discussion.getBody(), equalTo("This is a public discussion"));
|
||||
assertThat(discussion.isPrivate(), is(false));
|
||||
|
||||
discussion = team.createDiscussion("Some Discussion")
|
||||
.body("This is another public discussion")
|
||||
.private_(false)
|
||||
.done();
|
||||
assertThat(discussion, notNullValue());
|
||||
assertThat(discussion.getTeam(), equalTo(team));
|
||||
assertThat(discussion.getTitle(), equalTo("Some Discussion"));
|
||||
assertThat(discussion.getBody(), equalTo("This is another public discussion"));
|
||||
assertThat(discussion.isPrivate(), is(false));
|
||||
|
||||
discussion = team.createDiscussion("Some Discussion")
|
||||
.body("This is a private (secret) discussion")
|
||||
.private_(true)
|
||||
.done();
|
||||
assertThat(discussion, notNullValue());
|
||||
assertThat(discussion.getTeam(), equalTo(team));
|
||||
assertThat(discussion.getTitle(), equalTo("Some Discussion"));
|
||||
assertThat(discussion.getBody(), equalTo("This is a private (secret) discussion"));
|
||||
assertThat(discussion.isPrivate(), is(true));
|
||||
|
||||
try {
|
||||
team.createDiscussion("Some Discussion").done();
|
||||
fail("Body is required.");
|
||||
} catch (HttpException e) {
|
||||
assertThat(e, instanceOf(HttpException.class));
|
||||
assertThat(e.getMessage(),
|
||||
containsString("https://developer.github.com/v3/teams/discussions/#create-a-discussion"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAndEditDiscussion() throws IOException {
|
||||
GHDiscussion created = team.createDiscussion("Some Discussion").body("This is a test discussion").done();
|
||||
|
||||
GHDiscussion discussion = team.getDiscussion(created.getNumber());
|
||||
|
||||
// Test convenience getId() override
|
||||
assertThat(discussion.getNumber(), equalTo(created.getId()));
|
||||
assertThat(discussion.getTeam(), equalTo(team));
|
||||
assertThat(discussion.getTitle(), equalTo("Some Discussion"));
|
||||
assertThat(discussion.getBody(), equalTo("This is a test discussion"));
|
||||
assertThat(discussion.isPrivate(), is(false));
|
||||
|
||||
// Test equality
|
||||
assertThat(discussion, equalTo(created));
|
||||
|
||||
discussion = discussion.set().body("This is a test discussion changed");
|
||||
assertThat(discussion.getTeam(), notNullValue());
|
||||
|
||||
assertThat(discussion.getTitle(), equalTo("Some Discussion"));
|
||||
assertThat(discussion.getBody(), equalTo("This is a test discussion changed"));
|
||||
|
||||
discussion = discussion.set().title("Title changed");
|
||||
|
||||
assertThat(discussion.getTitle(), equalTo("Title changed"));
|
||||
assertThat(discussion.getBody(), equalTo("This is a test discussion changed"));
|
||||
|
||||
GHDiscussion discussion2 = gitHub.getOrganization(GITHUB_API_TEST_ORG)
|
||||
.getTeamBySlug(TEAM_SLUG)
|
||||
.getDiscussion(discussion.getNumber());
|
||||
|
||||
assertThat(discussion2, equalTo(discussion));
|
||||
assertThat(discussion2.getTitle(), equalTo("Title changed"));
|
||||
assertThat(discussion2.getBody(), equalTo("This is a test discussion changed"));
|
||||
|
||||
discussion = discussion.update().body("This is a test discussion updated").title("Title updated").done();
|
||||
|
||||
assertThat(discussion.getTeam(), notNullValue());
|
||||
assertThat(discussion.getTitle(), equalTo("Title updated"));
|
||||
assertThat(discussion.getBody(), equalTo("This is a test discussion updated"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListDiscussion() throws IOException {
|
||||
team.createDiscussion("Some Discussion A").body("This is a test discussion").done();
|
||||
team.createDiscussion("Some Discussion B").body("This is a test discussion").done();
|
||||
team.createDiscussion("Some Discussion C").body("This is a test discussion").done();
|
||||
|
||||
Set<GHDiscussion> all = team.listDiscussions().toSet();
|
||||
assertThat(all.size(), equalTo(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToDeleteDiscussion() throws IOException {
|
||||
GHDiscussion discussion = team.createDiscussion("Some Discussion").body("This is a test discussion").done();
|
||||
|
||||
assertThat(discussion.getTitle(), equalTo("Some Discussion"));
|
||||
|
||||
discussion.delete();
|
||||
try {
|
||||
gitHub.getOrganization(GITHUB_API_TEST_ORG).getTeamBySlug(TEAM_SLUG).getDiscussion(discussion.getNumber());
|
||||
fail();
|
||||
} catch (FileNotFoundException e) {
|
||||
assertThat(e.getMessage(),
|
||||
containsString("https://developer.github.com/v3/teams/discussions/#get-a-single-discussion"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -41,7 +40,6 @@ public class GHIssueEventAttributeTest extends AbstractGitHubWireMockTest {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<GHIssueEvent> listEvents(final Type type) throws IOException {
|
||||
return StreamSupport
|
||||
.stream(gitHub.getRepository("chids/project-milestone-test").getIssue(1).listEvents().spliterator(),
|
||||
|
||||
@@ -11,7 +11,7 @@ public class GHObjectTest extends org.kohsuke.github.AbstractGitHubWireMockTest
|
||||
GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG);
|
||||
assertThat(org.toString(),
|
||||
containsString(
|
||||
"login=hub4j-test-org,location=<null>,blog=<null>,email=<null>,name=<null>,company=<null>,type=Organization,followers=0,following=0"));
|
||||
"login=hub4j-test-org,location=<null>,blog=<null>,email=<null>,bio=<null>,name=<null>,company=<null>,type=Organization,followers=0,following=0,hireable=false"));
|
||||
|
||||
// getResponseHeaderFields is deprecated but we should not break it.
|
||||
assertThat(org.getResponseHeaderFields(), notNullValue());
|
||||
|
||||
@@ -3,13 +3,15 @@ package org.kohsuke.github;
|
||||
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
|
||||
import com.fasterxml.jackson.databind.exc.ValueInstantiationException;
|
||||
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.core.IsInstanceOf.instanceOf;
|
||||
|
||||
@@ -51,13 +53,16 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
public void testGitHubRateLimit() throws Exception {
|
||||
// Customized response that templates the date to keep things working
|
||||
snapshotNotAllowed();
|
||||
GHRateLimit.UnknownLimitRecord.reset();
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(0));
|
||||
|
||||
// 4897 is just the what the limit was when the snapshot was taken
|
||||
previousLimit = GHRateLimit.fromHeaderRecord(new GHRateLimit.Record(5000,
|
||||
4897,
|
||||
(templating.testStartDate.getTime() + Duration.ofHours(1).toMillis()) / 1000L));
|
||||
previousLimit = GHRateLimit.fromRecord(
|
||||
new GHRateLimit.Record(5000,
|
||||
4897,
|
||||
(templating.testStartDate.getTime() + Duration.ofHours(1).toMillis()) / 1000L),
|
||||
RateLimitTarget.CORE);
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// /user gets response with rate limit information
|
||||
@@ -76,8 +81,8 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
// Give this a moment
|
||||
Thread.sleep(1500);
|
||||
|
||||
// ratelimit() uses headerRateLimit if available and headerRateLimit is not expired
|
||||
assertThat(gitHub.rateLimit(), equalTo(headerRateLimit));
|
||||
// ratelimit() uses cached rate limit if available and not expired
|
||||
assertThat(gitHub.rateLimit(), sameInstance(headerRateLimit));
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(1));
|
||||
|
||||
@@ -88,8 +93,13 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
rateLimit = gitHub.getRateLimit();
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(2));
|
||||
|
||||
// Because remaining and reset date are unchanged, the header should be unchanged as well
|
||||
assertThat(gitHub.lastRateLimit(), sameInstance(headerRateLimit));
|
||||
// Because remaining and reset date are unchanged in core, the header should be unchanged as well
|
||||
// But the overall instance has changed because of filling in of unknown data.
|
||||
assertThat(gitHub.lastRateLimit(), not(sameInstance(headerRateLimit)));
|
||||
// Identical Records should be preserved even when GHRateLimit is merged
|
||||
assertThat(gitHub.lastRateLimit().getCore(), sameInstance(headerRateLimit.getCore()));
|
||||
assertThat(gitHub.lastRateLimit().getSearch(), not(sameInstance(headerRateLimit.getSearch())));
|
||||
headerRateLimit = gitHub.lastRateLimit();
|
||||
|
||||
// rate limit request is free, remaining is unchanged
|
||||
verifyRateLimitValues(previousLimit, previousLimit.getRemaining());
|
||||
@@ -141,9 +151,8 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
verifyRateLimitValues(previousLimit, previousLimit.getRemaining(), true);
|
||||
previousLimit = rateLimit;
|
||||
|
||||
// When getRateLimit() succeeds, headerRateLimit updates as usual as well (if needed)
|
||||
// These are separate instances, but should be equal
|
||||
assertThat(gitHub.rateLimit(), not(sameInstance(rateLimit)));
|
||||
// When getRateLimit() succeeds, cached rate limit updates as usual as well (if needed)
|
||||
assertThat(gitHub.rateLimit(), sameInstance(rateLimit));
|
||||
|
||||
// Verify different record instances can be compared
|
||||
assertThat(gitHub.rateLimit().getCore(), equalTo(rateLimit.getCore()));
|
||||
@@ -154,8 +163,43 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
assertThat(gitHub.rateLimit(), not(sameInstance(headerRateLimit)));
|
||||
assertThat(gitHub.rateLimit(), sameInstance(gitHub.lastRateLimit()));
|
||||
headerRateLimit = gitHub.lastRateLimit();
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(5));
|
||||
|
||||
// Verify the requesting a search url updates the search rate limit
|
||||
assertThat(gitHub.lastRateLimit().getSearch().getRemaining(), equalTo(30));
|
||||
|
||||
HashMap<String, Object> searchResult = (HashMap<String, Object>) gitHub.createRequest()
|
||||
.rateLimit(RateLimitTarget.SEARCH)
|
||||
.setRawUrlPath(mockGitHub.apiServer().baseUrl()
|
||||
+ "/search/repositories?q=tetris+language%3Aassembly&sort=stars&order=desc")
|
||||
.fetch(HashMap.class);
|
||||
|
||||
assertThat(searchResult.get("total_count"), equalTo(1918));
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(6));
|
||||
|
||||
assertThat(gitHub.lastRateLimit(), not(sameInstance(headerRateLimit)));
|
||||
assertThat(gitHub.lastRateLimit().getCore(), sameInstance(headerRateLimit.getCore()));
|
||||
assertThat(gitHub.lastRateLimit().getSearch(), not(sameInstance(headerRateLimit.getSearch())));
|
||||
assertThat(gitHub.lastRateLimit().getSearch().getRemaining(), equalTo(29));
|
||||
|
||||
PagedSearchIterable<GHRepository> searchResult2 = gitHub.searchRepositories()
|
||||
.q("tetris")
|
||||
.language("assembly")
|
||||
.sort(GHRepositorySearchBuilder.Sort.STARS)
|
||||
.order(GHDirection.DESC)
|
||||
.list();
|
||||
|
||||
assertThat(searchResult2.getTotalCount(), equalTo(1918));
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(7));
|
||||
|
||||
assertThat(gitHub.lastRateLimit(), not(sameInstance(headerRateLimit)));
|
||||
assertThat(gitHub.lastRateLimit().getCore(), sameInstance(headerRateLimit.getCore()));
|
||||
assertThat(gitHub.lastRateLimit().getSearch(), not(sameInstance(headerRateLimit.getSearch())));
|
||||
assertThat(gitHub.lastRateLimit().getSearch().getRemaining(), equalTo(28));
|
||||
}
|
||||
|
||||
private void verifyRateLimitValues(GHRateLimit previousLimit, int remaining) {
|
||||
@@ -194,6 +238,8 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
public void testGitHubEnterpriseDoesNotHaveRateLimit() throws Exception {
|
||||
// Customized response that results in file not found the same as GitHub Enterprise
|
||||
snapshotNotAllowed();
|
||||
GHRateLimit.UnknownLimitRecord.reset();
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(0));
|
||||
GHRateLimit rateLimit = null;
|
||||
|
||||
@@ -203,13 +249,14 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
Thread.sleep(1500);
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Before any queries, rate limit starts as null but may be requested
|
||||
// Before any queries, rate limit starts as default but may be requested
|
||||
gitHub = GitHub.connectToEnterprise(mockGitHub.apiServer().baseUrl(), "bogus", "bogus");
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(0));
|
||||
|
||||
assertThat(gitHub.lastRateLimit(), CoreMatchers.nullValue());
|
||||
assertThat(gitHub.lastRateLimit(), sameInstance(GHRateLimit.DEFAULT));
|
||||
|
||||
rateLimit = gitHub.rateLimit();
|
||||
assertThat(gitHub.lastRateLimit(), not(equalTo(GHRateLimit.DEFAULT)));
|
||||
assertThat(rateLimit.getCore(), instanceOf(GHRateLimit.UnknownLimitRecord.class));
|
||||
assertThat(rateLimit.getLimit(), equalTo(GHRateLimit.UnknownLimitRecord.unknownLimit));
|
||||
assertThat(rateLimit.getRemaining(), equalTo(GHRateLimit.UnknownLimitRecord.unknownRemaining));
|
||||
@@ -218,8 +265,8 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(1));
|
||||
|
||||
// last is still null, because it actually means lastHeaderRateLimit
|
||||
assertThat(gitHub.lastRateLimit(), CoreMatchers.nullValue());
|
||||
// lastRateLimit the same as rateLimit
|
||||
assertThat(gitHub.lastRateLimit(), sameInstance(rateLimit));
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(1));
|
||||
|
||||
@@ -233,13 +280,14 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
gitHub.getMyself();
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(2));
|
||||
|
||||
assertThat(gitHub.lastRateLimit(), CoreMatchers.nullValue());
|
||||
assertThat(gitHub.lastRateLimit(), sameInstance(GHRateLimit.DEFAULT));
|
||||
|
||||
rateLimit = gitHub.rateLimit();
|
||||
assertThat(rateLimit.getCore(), instanceOf(GHRateLimit.UnknownLimitRecord.class));
|
||||
assertThat(rateLimit.getLimit(), equalTo(GHRateLimit.UnknownLimitRecord.unknownLimit));
|
||||
assertThat(rateLimit.getRemaining(), equalTo(GHRateLimit.UnknownLimitRecord.unknownRemaining));
|
||||
assertThat(rateLimit.getResetDate().compareTo(lastReset), equalTo(1));
|
||||
// Same unknown instance is reused for a while
|
||||
assertThat(rateLimit.getResetDate().compareTo(lastReset), equalTo(0));
|
||||
lastReset = rateLimit.getResetDate();
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(3));
|
||||
@@ -258,17 +306,19 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
assertThat(rateLimit.getCore(), instanceOf(GHRateLimit.UnknownLimitRecord.class));
|
||||
assertThat(rateLimit.getLimit(), equalTo(GHRateLimit.UnknownLimitRecord.unknownLimit));
|
||||
assertThat(rateLimit.getRemaining(), equalTo(GHRateLimit.UnknownLimitRecord.unknownRemaining));
|
||||
assertThat(rateLimit.getResetDate().compareTo(lastReset), equalTo(1));
|
||||
// When not expired, unknowns do not replace each other so last reset remains unchanged
|
||||
assertThat(rateLimit.getResetDate().compareTo(lastReset), equalTo(0));
|
||||
|
||||
// Give this a moment
|
||||
Thread.sleep(1500);
|
||||
|
||||
// last is still null, because it actually means lastHeaderRateLimit
|
||||
assertThat(gitHub.lastRateLimit(), CoreMatchers.nullValue());
|
||||
// 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));
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(4));
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Some versions of GHE include header rate limit information, some do not
|
||||
@@ -282,10 +332,12 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
assertThat(rateLimit, notNullValue());
|
||||
assertThat(rateLimit.getLimit(), equalTo(5000));
|
||||
assertThat(rateLimit.getRemaining(), equalTo(4978));
|
||||
// The previous record was an "Unknown", so even though this records resets sooner we take it
|
||||
assertThat(rateLimit.getResetDate().compareTo(lastReset), equalTo(-1));
|
||||
assertThat(rateLimit.getResetDate().compareTo(lastReset), equalTo(1));
|
||||
lastReset = rateLimit.getResetDate();
|
||||
|
||||
// When getting only header updates, the unknowns are also expired
|
||||
assertThat(rateLimit.getSearch().isExpired(), is(true));
|
||||
|
||||
GHRateLimit headerRateLimit = rateLimit;
|
||||
|
||||
// Give this a moment
|
||||
@@ -320,14 +372,49 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
// getRateLimit() uses headerRateLimit if /rate_limit returns a 404
|
||||
// and headerRateLimit is available and not expired
|
||||
assertThat(rateLimit, sameInstance(gitHub.lastRateLimit()));
|
||||
headerRateLimit = rateLimit;
|
||||
|
||||
// ratelimit() should prefer headerRateLimit when getRateLimit fails and headerRateLimit is not expired
|
||||
assertThat(gitHub.rateLimit(), sameInstance(rateLimit));
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(6));
|
||||
|
||||
// Wait for the header
|
||||
Thread.sleep(1500);
|
||||
// Verify the requesting a search url updates the search rate limit
|
||||
// Core rate limit record should not change while search is updated.
|
||||
assertThat(gitHub.lastRateLimit().getSearch(), instanceOf(GHRateLimit.UnknownLimitRecord.class));
|
||||
assertThat(gitHub.lastRateLimit().getSearch().isExpired(), equalTo(true));
|
||||
|
||||
HashMap<String, Object> searchResult = (HashMap<String, Object>) gitHub.createRequest()
|
||||
.rateLimit(RateLimitTarget.SEARCH)
|
||||
.setRawUrlPath(mockGitHub.apiServer().baseUrl()
|
||||
+ "/search/repositories?q=tetris+language%3Aassembly&sort=stars&order=desc")
|
||||
.fetch(Object.class);
|
||||
|
||||
assertThat(searchResult.get("total_count"), equalTo(1918));
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(7));
|
||||
|
||||
assertThat(gitHub.lastRateLimit(), not(sameInstance(headerRateLimit)));
|
||||
assertThat(gitHub.lastRateLimit().getCore(), sameInstance(headerRateLimit.getCore()));
|
||||
assertThat(gitHub.lastRateLimit().getSearch(), not(sameInstance(headerRateLimit.getSearch())));
|
||||
assertThat(gitHub.lastRateLimit().getSearch().getRemaining(), equalTo(29));
|
||||
|
||||
PagedSearchIterable<GHRepository> searchResult2 = gitHub.searchRepositories()
|
||||
.q("tetris")
|
||||
.language("assembly")
|
||||
.sort(GHRepositorySearchBuilder.Sort.STARS)
|
||||
.order(GHDirection.DESC)
|
||||
.list();
|
||||
|
||||
assertThat(searchResult2.getTotalCount(), equalTo(1918));
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(8));
|
||||
|
||||
assertThat(gitHub.lastRateLimit(), not(sameInstance(headerRateLimit)));
|
||||
assertThat(gitHub.lastRateLimit().getCore(), sameInstance(headerRateLimit.getCore()));
|
||||
assertThat(gitHub.lastRateLimit().getSearch(), not(sameInstance(headerRateLimit.getSearch())));
|
||||
assertThat(gitHub.lastRateLimit().getSearch().getRemaining(), equalTo(28));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -372,6 +459,7 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
private void executeExpirationTest() throws Exception {
|
||||
// Customized response that templates the date to keep things working
|
||||
snapshotNotAllowed();
|
||||
GHRateLimit.UnknownLimitRecord.reset();
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(0));
|
||||
GHRateLimit rateLimit = null;
|
||||
@@ -413,15 +501,15 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
assertThat("Header instance has expired", gitHub.lastRateLimit().isExpired(), is(true));
|
||||
|
||||
assertThat("rateLimit() will ask server when header instance expires and it has not called getRateLimit() yet",
|
||||
assertThat("rateLimit() will ask server when cached instance has expired",
|
||||
gitHub.rateLimit(),
|
||||
not(sameInstance(rateLimit)));
|
||||
|
||||
assertThat("lastRateLimit() (header instance) is populated as part of internal call to getRateLimit()",
|
||||
assertThat("lastRateLimit() is populated as part of internal call to getRateLimit()",
|
||||
gitHub.lastRateLimit(),
|
||||
not(sameInstance(rateLimit)));
|
||||
|
||||
assertThat("After request, rateLimit() selects header instance since it has been refreshed",
|
||||
assertThat("After request, rateLimit() selects cached since it has been refreshed",
|
||||
gitHub.rateLimit(),
|
||||
sameInstance(gitHub.lastRateLimit()));
|
||||
|
||||
@@ -429,27 +517,27 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(2));
|
||||
|
||||
// This time, rateLimit() should find an expired header record, but a valid returned record
|
||||
// During the previous call we returned expired header info but valid returned record
|
||||
// Merging means this has already been merged into a valid cached instance
|
||||
Thread.sleep(4000);
|
||||
|
||||
rateLimit = gitHub.rateLimit();
|
||||
|
||||
// Using custom data to have a header instance that expires before the queried instance
|
||||
assertThat(
|
||||
"if header instance expires but queried instance is valid, ratelimit() uses it without asking server",
|
||||
assertThat("if valid ratelimit() uses it without asking server",
|
||||
gitHub.rateLimit(),
|
||||
not(sameInstance(gitHub.lastRateLimit())));
|
||||
sameInstance(gitHub.lastRateLimit()));
|
||||
|
||||
assertThat("ratelimit() should almost never return a return a GHRateLimit that is already expired",
|
||||
gitHub.rateLimit().isExpired(),
|
||||
is(false));
|
||||
|
||||
assertThat("Header instance hasn't been reloaded", gitHub.lastRateLimit(), sameInstance(headerRateLimit));
|
||||
assertThat("Header instance has expired", gitHub.lastRateLimit().isExpired(), is(true));
|
||||
assertThat("Cached instance hasn't been reloaded", gitHub.lastRateLimit(), sameInstance(headerRateLimit));
|
||||
assertThat("Cached instance has not expired", gitHub.lastRateLimit().isExpired(), is(false));
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(2));
|
||||
|
||||
// Finally they both expire and rateLimit() should find both expired and get a new record
|
||||
// Finally the cached instance expires and rateLimit() should get a new record
|
||||
Thread.sleep(2000);
|
||||
|
||||
headerRateLimit = gitHub.rateLimit();
|
||||
|
||||
@@ -429,7 +429,6 @@ public class GHRepositoryTest extends AbstractGitHubWireMockTest {
|
||||
assertThat(e.getMessage(),
|
||||
containsString(
|
||||
"{\"message\":\"Not Found\",\"documentation_url\":\"https://developer.github.com/v3/git/refs/#get-a-reference\"}"));
|
||||
assertThat(e.getCause(), instanceOf(FileNotFoundException.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,7 +473,6 @@ public class GHRepositoryTest extends AbstractGitHubWireMockTest {
|
||||
assertThat(e.getMessage(),
|
||||
containsString(
|
||||
"{\"message\":\"Not Found\",\"documentation_url\":\"https://developer.github.com/v3/git/refs/#get-a-reference\"}"));
|
||||
assertThat(e.getCause(), instanceOf(FileNotFoundException.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,8 +503,7 @@ public class GHRepositoryTest extends AbstractGitHubWireMockTest {
|
||||
assertThat(e, instanceOf(GHFileNotFoundException.class));
|
||||
assertThat(e.getMessage(),
|
||||
containsString(
|
||||
"{\"message\":\"Not Found\",\"documentation_url\":\"https://developer.github.com/v3/git/refs/#get-a-single-reference\"}"));
|
||||
assertThat(e.getCause(), instanceOf(FileNotFoundException.class));
|
||||
"{\"message\":\"Not Found\",\"documentation_url\":\"https://developer.github.com/v3/git/refs/#get-a-reference\"}"));
|
||||
}
|
||||
|
||||
// git/refs/headz
|
||||
@@ -517,8 +514,7 @@ public class GHRepositoryTest extends AbstractGitHubWireMockTest {
|
||||
assertThat(e, instanceOf(GHFileNotFoundException.class));
|
||||
assertThat(e.getMessage(),
|
||||
containsString(
|
||||
"{\"message\":\"Not Found\",\"documentation_url\":\"https://developer.github.com/v3/git/refs/#get-a-single-reference\"}"));
|
||||
assertThat(e.getCause(), instanceOf(FileNotFoundException.class));
|
||||
"{\"message\":\"Not Found\",\"documentation_url\":\"https://developer.github.com/v3/git/refs/#get-a-reference\"}"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
32
src/test/java/org/kohsuke/github/GHTeamBuilderTest.java
Normal file
32
src/test/java/org/kohsuke/github/GHTeamBuilderTest.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class GHTeamBuilderTest extends AbstractGitHubWireMockTest {
|
||||
|
||||
@Test
|
||||
public void testCreateChildTeam() throws IOException {
|
||||
String parentTeamSlug = "dummy-team";
|
||||
String childTeamSlug = "dummy-team-child";
|
||||
String description = "description";
|
||||
|
||||
// Get the parent team
|
||||
GHTeam parentTeam = gitHub.getOrganization(GITHUB_API_TEST_ORG).getTeamBySlug(parentTeamSlug);
|
||||
|
||||
// Create a child team, using the parent team identifier
|
||||
GHTeam childTeam = gitHub.getOrganization(GITHUB_API_TEST_ORG)
|
||||
.createTeam(childTeamSlug)
|
||||
.description(description)
|
||||
.privacy(GHTeam.Privacy.CLOSED)
|
||||
.parentTeamId(parentTeam.getId())
|
||||
.create();
|
||||
|
||||
assertEquals(description, childTeam.getDescription());
|
||||
assertEquals(childTeamSlug, childTeam.getName());
|
||||
assertEquals(childTeamSlug, childTeam.getSlug());
|
||||
assertEquals(GHTeam.Privacy.CLOSED, childTeam.getPrivacy());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import org.junit.Test;
|
||||
import org.kohsuke.github.GHTeam.Privacy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@@ -56,4 +57,27 @@ public class GHTeamTest extends AbstractGitHubWireMockTest {
|
||||
assertEquals(privacy, team.getPrivacy());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchChildTeams() throws IOException {
|
||||
String teamSlug = "dummy-team";
|
||||
|
||||
GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG);
|
||||
GHTeam team = org.getTeamBySlug(teamSlug);
|
||||
Set<GHTeam> result = team.listChildTeams().toSet();
|
||||
|
||||
assertEquals(1, result.size());
|
||||
assertEquals("child-team-for-dummy", result.toArray(new GHTeam[]{})[0].getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchEmptyChildTeams() throws IOException {
|
||||
String teamSlug = "simple-team";
|
||||
|
||||
GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG);
|
||||
GHTeam team = org.getTeamBySlug(teamSlug);
|
||||
Set<GHTeam> result = team.listChildTeams().toSet();
|
||||
|
||||
assertEquals(0, result.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -102,4 +102,12 @@ public class GHUserTest extends AbstractGitHubWireMockTest {
|
||||
repository.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyBioAndHireable() throws IOException {
|
||||
GHUser u = gitHub.getUser("Chew");
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Unit test for {@link GitHub} static helpers.
|
||||
@@ -65,68 +65,137 @@ public class GitHubStaticTest extends AbstractGitHubWireMockTest {
|
||||
@Test
|
||||
public void testGitHubRateLimitShouldReplaceRateLimit() throws Exception {
|
||||
|
||||
GHRateLimit.Record unknown0 = GHRateLimit.Unknown().getCore();
|
||||
GHRateLimit.Record unknown1 = GHRateLimit.Unknown().getCore();
|
||||
GHRateLimit.UnknownLimitRecord.reset();
|
||||
GHRateLimit.UnknownLimitRecord.unknownLimitResetSeconds = 5;
|
||||
|
||||
GHRateLimit.Record record0 = new GHRateLimit.Record(10, 10, 10L);
|
||||
GHRateLimit.Record record1 = new GHRateLimit.Record(10, 9, 10L);
|
||||
GHRateLimit.Record record2 = new GHRateLimit.Record(10, 2, 10L);
|
||||
GHRateLimit.Record record3 = new GHRateLimit.Record(10, 10, 20L);
|
||||
GHRateLimit.Record record4 = new GHRateLimit.Record(10, 5, 20L);
|
||||
GHRateLimit.Record unknown0 = GHRateLimit.UnknownLimitRecord.current();
|
||||
|
||||
Thread.sleep(2000);
|
||||
Thread.sleep(1500);
|
||||
GHRateLimit.UnknownLimitRecord.reset();
|
||||
GHRateLimit.UnknownLimitRecord.unknownLimitResetSeconds = 5;
|
||||
|
||||
// For testing, we create an new unknown.
|
||||
GHRateLimit.Record unknown1 = GHRateLimit.UnknownLimitRecord.current();
|
||||
|
||||
assertThat("Valid unknown should not replace an existing one, regardless of created or reset time",
|
||||
unknown1.currentOrUpdated(unknown0),
|
||||
sameInstance(unknown1));
|
||||
assertThat("Valid unknown should not replace an existing one, regardless of created or reset time",
|
||||
unknown0.currentOrUpdated(unknown1),
|
||||
sameInstance(unknown0));
|
||||
|
||||
// Sleep to make different created time
|
||||
Thread.sleep(1500);
|
||||
|
||||
// To reduce object creation: There is only one valid Unknown record at a time.
|
||||
assertThat("Unknown current should should limit the creation of new unknown records",
|
||||
unknown1,
|
||||
sameInstance(GHRateLimit.UnknownLimitRecord.current()));
|
||||
|
||||
long epochSeconds = Instant.now().getEpochSecond();
|
||||
|
||||
GHRateLimit.Record record0 = new GHRateLimit.Record(10, 10, epochSeconds + 10L);
|
||||
GHRateLimit.Record record1 = new GHRateLimit.Record(10, 9, epochSeconds + 10L);
|
||||
GHRateLimit.Record record2 = new GHRateLimit.Record(10, 2, epochSeconds + 10L);
|
||||
GHRateLimit.Record record3 = new GHRateLimit.Record(10, 10, epochSeconds + 20L);
|
||||
GHRateLimit.Record record4 = new GHRateLimit.Record(10, 5, epochSeconds + 20L);
|
||||
GHRateLimit.Record recordExpired0 = new GHRateLimit.Record(10, 10, epochSeconds - 1L);
|
||||
GHRateLimit.Record recordExpired1 = new GHRateLimit.Record(10, 10, epochSeconds + 2L);
|
||||
|
||||
// Sleep to make expired and different created time
|
||||
Thread.sleep(4000);
|
||||
|
||||
GHRateLimit.Record recordWorst = new GHRateLimit.Record(Integer.MAX_VALUE, Integer.MAX_VALUE, Long.MIN_VALUE);
|
||||
GHRateLimit.Record record00 = new GHRateLimit.Record(10, 10, 10L);
|
||||
GHRateLimit.Record unknown2 = GHRateLimit.Unknown().getCore();
|
||||
GHRateLimit.Record record00 = new GHRateLimit.Record(10, 10, epochSeconds + 10L);
|
||||
|
||||
GHRateLimit.Record unknownExpired0 = unknown0;
|
||||
GHRateLimit.Record unknownExpired1 = unknown1;
|
||||
unknown0 = GHRateLimit.UnknownLimitRecord.current();
|
||||
|
||||
// Rate-limit records maybe created and returned in different orders.
|
||||
// We should update to the regular records over unknowns.
|
||||
// We should update to the unexpired regular records over unknowns.
|
||||
// After that, we should update to the candidate if its limit is lower or its reset is later.
|
||||
|
||||
assertThat("Equivalent unknown should not replace", GitHubClient.shouldReplace(unknown0, unknown1), is(false));
|
||||
assertThat("Equivalent unknown should not replace", GitHubClient.shouldReplace(unknown1, unknown0), is(false));
|
||||
assertThat("Expired unknowns should not replace another expired one, regardless of created or reset time",
|
||||
unknownExpired0.currentOrUpdated(unknownExpired1),
|
||||
sameInstance(unknownExpired0));
|
||||
assertThat("Expired unknowns should not replace another expired one, regardless of created or reset time",
|
||||
unknownExpired1.currentOrUpdated(unknownExpired0),
|
||||
sameInstance(unknownExpired1));
|
||||
|
||||
assertThat("Later unknown should replace earlier", GitHubClient.shouldReplace(unknown2, unknown0), is(true));
|
||||
assertThat("Earlier unknown should not replace later",
|
||||
GitHubClient.shouldReplace(unknown0, unknown2),
|
||||
is(false));
|
||||
assertThat("Expired unknown should not be replaced by expired earlier normal record",
|
||||
unknownExpired0.currentOrUpdated(recordExpired0),
|
||||
sameInstance(unknownExpired0));
|
||||
assertThat("Expired normal record should not be replaced an expired earlier unknown record",
|
||||
recordExpired0.currentOrUpdated(unknownExpired0),
|
||||
sameInstance(recordExpired0));
|
||||
|
||||
assertThat("Worst record should replace later unknown",
|
||||
GitHubClient.shouldReplace(recordWorst, unknown1),
|
||||
is(true));
|
||||
assertThat("Unknown should not replace worst record",
|
||||
GitHubClient.shouldReplace(unknown1, recordWorst),
|
||||
is(false));
|
||||
assertThat("Expired unknown should be replaced by expired later normal record",
|
||||
unknownExpired0.currentOrUpdated(recordExpired1),
|
||||
sameInstance(recordExpired1));
|
||||
assertThat(
|
||||
"Expired later normal record should not be replaced an expired unknown record, regardless of created or reset time",
|
||||
recordExpired1.currentOrUpdated(unknownExpired0),
|
||||
sameInstance(recordExpired1));
|
||||
|
||||
assertThat("Earlier record should replace later worst",
|
||||
GitHubClient.shouldReplace(record0, recordWorst),
|
||||
is(true));
|
||||
assertThat("Valid unknown should not be replaced by an expired unknown",
|
||||
unknown0.currentOrUpdated(unknownExpired0),
|
||||
sameInstance(unknown0));
|
||||
assertThat("Expired unknown should be replaced by valid unknown",
|
||||
unknownExpired0.currentOrUpdated(unknown0),
|
||||
sameInstance(unknown0));
|
||||
|
||||
assertThat("Valid unknown should replace an expired normal record",
|
||||
recordExpired1.currentOrUpdated(unknown0),
|
||||
sameInstance(unknown0));
|
||||
assertThat("Valid unknown record should not be replaced by expired normal record",
|
||||
unknown0.currentOrUpdated(recordExpired1),
|
||||
sameInstance(unknown0));
|
||||
|
||||
// In normal comparision, expiration doesn't matter
|
||||
assertThat("Expired normal should not be replaced by an earlier expired one",
|
||||
recordExpired1.currentOrUpdated(recordExpired0),
|
||||
sameInstance(recordExpired1));
|
||||
assertThat("Expired normal should be replaced by a later expired one",
|
||||
recordExpired0.currentOrUpdated(recordExpired1),
|
||||
sameInstance(recordExpired1));
|
||||
|
||||
assertThat("Later worst record should be replaced by earlier record",
|
||||
recordWorst.currentOrUpdated(record0),
|
||||
sameInstance(record0));
|
||||
assertThat("Later worst record should not replace earlier",
|
||||
GitHubClient.shouldReplace(recordWorst, record0),
|
||||
is(false));
|
||||
record0.currentOrUpdated(recordWorst),
|
||||
sameInstance(record0));
|
||||
|
||||
assertThat("Equivalent record should not replace", GitHubClient.shouldReplace(record0, record00), is(false));
|
||||
assertThat("Equivalent record should not replace", GitHubClient.shouldReplace(record00, record0), is(false));
|
||||
assertThat("Equivalent record should not replace other",
|
||||
record00.currentOrUpdated(record0),
|
||||
sameInstance(record00));
|
||||
assertThat("Equivalent record should not replace other",
|
||||
record0.currentOrUpdated(record00),
|
||||
sameInstance(record0));
|
||||
|
||||
assertThat("Lower limit record should replace higher", GitHubClient.shouldReplace(record1, record0), is(true));
|
||||
assertThat("Lower limit record should replace higher", GitHubClient.shouldReplace(record2, record1), is(true));
|
||||
assertThat("Higher limit record should be replaced by lower",
|
||||
record0.currentOrUpdated(record1),
|
||||
sameInstance(record1));
|
||||
assertThat("Higher limit record should be replaced by lower",
|
||||
record1.currentOrUpdated(record2),
|
||||
sameInstance(record2));
|
||||
|
||||
assertThat("Higher limit record should not replace lower",
|
||||
GitHubClient.shouldReplace(record1, record2),
|
||||
is(false));
|
||||
assertThat("Lower limit record should not be replaced higher",
|
||||
record2.currentOrUpdated(record1),
|
||||
sameInstance(record2));
|
||||
|
||||
assertThat("Higher limit record with later reset should replace lower",
|
||||
GitHubClient.shouldReplace(record3, record2),
|
||||
is(true));
|
||||
assertThat("Lower limit record should be replaced by higher limit record with later reset",
|
||||
record2.currentOrUpdated(record3),
|
||||
sameInstance(record3));
|
||||
|
||||
assertThat("Lower limit record with later reset should replace higher",
|
||||
GitHubClient.shouldReplace(record4, record1),
|
||||
is(true));
|
||||
assertThat("Higher limit record should be replaced by lower limit record with later reset",
|
||||
record1.currentOrUpdated(record4),
|
||||
sameInstance(record4));
|
||||
|
||||
assertThat("Lower limit record with earlier reset should not replace higher",
|
||||
GitHubClient.shouldReplace(record2, record4),
|
||||
is(false));
|
||||
assertThat("Higher limit record should not be replaced by lower limit record with earlier reset",
|
||||
record4.currentOrUpdated(record2),
|
||||
sameInstance(record4));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ public class RateLimitCheckerTest extends AbstractGitHubWireMockTest {
|
||||
public void testGitHubRateLimit() throws Exception {
|
||||
// Customized response that templates the date to keep things working
|
||||
snapshotNotAllowed();
|
||||
GHRateLimit.UnknownLimitRecord.reset();
|
||||
|
||||
assertThat(mockGitHub.getRequestCount(), equalTo(0));
|
||||
|
||||
@@ -45,7 +46,7 @@ public class RateLimitCheckerTest extends AbstractGitHubWireMockTest {
|
||||
.withEndpoint(mockGitHub.apiServer().baseUrl())
|
||||
.build();
|
||||
|
||||
assertThat(gitHub.lastRateLimit(), nullValue());
|
||||
assertThat(gitHub.lastRateLimit(), sameInstance(GHRateLimit.DEFAULT));
|
||||
|
||||
// Checks the rate limit before getting myself
|
||||
gitHub.getMyself();
|
||||
|
||||
@@ -2,9 +2,13 @@ package org.kohsuke.github;
|
||||
|
||||
import com.github.tomakehurst.wiremock.http.Fault;
|
||||
import com.github.tomakehurst.wiremock.stubbing.Scenario;
|
||||
import okhttp3.ConnectionPool;
|
||||
import okhttp3.OkHttpClient;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.kohsuke.github.extras.ImpatientHttpConnector;
|
||||
import org.kohsuke.github.extras.okhttp3.OkHttpConnector;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -20,6 +24,7 @@ import java.net.URL;
|
||||
import java.security.Permission;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.SimpleFormatter;
|
||||
import java.util.logging.StreamHandler;
|
||||
@@ -57,7 +62,8 @@ public class RequesterRetryTest extends AbstractGitHubWireMockTest {
|
||||
public void attachLogCapturer() {
|
||||
logCapturingStream = new ByteArrayOutputStream();
|
||||
customLogHandler = new StreamHandler(logCapturingStream, new SimpleFormatter());
|
||||
log.addHandler(customLogHandler);
|
||||
Logger.getLogger(GitHubClient.class.getName()).addHandler(customLogHandler);
|
||||
Logger.getLogger(OkHttpClient.class.getName()).addHandler(customLogHandler);
|
||||
}
|
||||
|
||||
public String getTestCapturedLog() throws IOException {
|
||||
@@ -66,11 +72,40 @@ public class RequesterRetryTest extends AbstractGitHubWireMockTest {
|
||||
}
|
||||
|
||||
public void resetTestCapturedLog() throws IOException {
|
||||
log.removeHandler(customLogHandler);
|
||||
Logger.getLogger(GitHubClient.class.getName()).removeHandler(customLogHandler);
|
||||
Logger.getLogger(OkHttpClient.class.getName()).removeHandler(customLogHandler);
|
||||
customLogHandler.close();
|
||||
attachLogCapturer();
|
||||
}
|
||||
|
||||
@Ignore("Used okhttp3 and this to verify connection closing. To variable for CI system.")
|
||||
@Test
|
||||
public void testGitHubIsApiUrlValid() throws Exception {
|
||||
|
||||
OkHttpClient client = new OkHttpClient().newBuilder()
|
||||
.connectionPool(new ConnectionPool(2, 100, TimeUnit.MILLISECONDS))
|
||||
.build();
|
||||
|
||||
OkHttpConnector connector = new OkHttpConnector(client);
|
||||
|
||||
for (int x = 0; x < 100; x++) {
|
||||
|
||||
this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl())
|
||||
.withConnector(connector)
|
||||
.build();
|
||||
|
||||
try {
|
||||
gitHub.checkApiUrlValidity();
|
||||
} catch (IOException ioe) {
|
||||
assertTrue(ioe.getMessage().contains("private mode enabled"));
|
||||
}
|
||||
Thread.sleep(100);
|
||||
}
|
||||
|
||||
String capturedLog = getTestCapturedLog();
|
||||
assertThat(capturedLog, not(containsString("leaked")));
|
||||
}
|
||||
|
||||
// Issue #539
|
||||
@Test
|
||||
public void testSocketConnectionAndRetry() throws Exception {
|
||||
|
||||
@@ -110,43 +110,33 @@ public class GitHubWireMockRule extends WireMockMultiServerRule {
|
||||
return;
|
||||
}
|
||||
|
||||
// "If-None-Match" header used for ETag matching for caching connections
|
||||
// "Accept" header is used to specify previews. If it changes expected data may not be retrieved.
|
||||
this.apiServer()
|
||||
.snapshotRecord(recordSpec().forTarget("https://api.github.com")
|
||||
.captureHeader("If-None-Match")
|
||||
.captureHeader("If-Modified-Since")
|
||||
.captureHeader("Cache-Control")
|
||||
.captureHeader("Accept")
|
||||
.extractTextBodiesOver(255));
|
||||
recordSnapshot(this.apiServer(), "https://api.github.com", false);
|
||||
|
||||
// After taking the snapshot, format the output
|
||||
formatTestResources(new File(this.apiServer().getOptions().filesRoot().getPath()).toPath(), false);
|
||||
// For raw server, only fix up mapping files
|
||||
recordSnapshot(this.rawServer(), "https://raw.githubusercontent.com", true);
|
||||
|
||||
if (this.rawServer() != null) {
|
||||
this.rawServer()
|
||||
.snapshotRecord(recordSpec().forTarget("https://raw.githubusercontent.com")
|
||||
.captureHeader("If-None-Match")
|
||||
.captureHeader("If-Modified-Since")
|
||||
.captureHeader("Cache-Control")
|
||||
.captureHeader("Accept")
|
||||
.extractTextBodiesOver(255));
|
||||
recordSnapshot(this.uploadsServer(), "https://uploads.github.com", false);
|
||||
}
|
||||
|
||||
// For raw server, only fix up mapping files
|
||||
formatTestResources(new File(this.rawServer().getOptions().filesRoot().getPath()).toPath(), true);
|
||||
}
|
||||
private void recordSnapshot(WireMockServer server, String target, boolean isRawServer) {
|
||||
if (server != null) {
|
||||
|
||||
if (this.uploadsServer() != null) {
|
||||
this.uploadsServer()
|
||||
.snapshotRecord(recordSpec().forTarget("https://uploads.github.com")
|
||||
.captureHeader("If-None-Match")
|
||||
.captureHeader("If-Modified-Since")
|
||||
.captureHeader("Cache-Control")
|
||||
.captureHeader("Accept")
|
||||
.extractTextBodiesOver(255));
|
||||
|
||||
formatTestResources(new File(this.uploadsServer().getOptions().filesRoot().getPath()).toPath(), false);
|
||||
server.snapshotRecord(recordSpec().forTarget(target)
|
||||
// "If-None-Match" header used for ETag matching for caching connections
|
||||
.captureHeader("If-None-Match")
|
||||
// "If-Modified-Since" header used for ETag matching for caching connections
|
||||
.captureHeader("If-Modified-Since")
|
||||
.captureHeader("Cache-Control")
|
||||
// "Accept" header is used to specify previews. If it changes expected data may not be retrieved.
|
||||
.captureHeader("Accept")
|
||||
// This is required, or some requests will return data from unexpected stubs
|
||||
// For example, if you update "title" and "body", and then update just "title" to the same value
|
||||
// the mock framework will treat those two requests as equivalent, which we do not want.
|
||||
.chooseBodyMatchTypeAutomatically(true, false, false)
|
||||
.extractTextBodiesOver(255));
|
||||
|
||||
// After taking the snapshot, format the output
|
||||
formatTestResources(new File(this.apiServer().getOptions().filesRoot().getPath()).toPath(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.kohsuke.github.junit;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.admin.model.*;
|
||||
import com.github.tomakehurst.wiremock.client.CountMatchingStrategy;
|
||||
import com.github.tomakehurst.wiremock.client.MappingBuilder;
|
||||
import com.github.tomakehurst.wiremock.client.VerificationException;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
@@ -221,6 +222,10 @@ public class WireMockRule implements MethodRule, TestRule, Container, Stubbing,
|
||||
wireMockServer.verify(count, requestPatternBuilder);
|
||||
}
|
||||
|
||||
public void verify(CountMatchingStrategy countMatchingStrategy, RequestPatternBuilder requestPatternBuilder) {
|
||||
wireMockServer.verify(countMatchingStrategy, requestPatternBuilder);
|
||||
}
|
||||
|
||||
public List<LoggedRequest> findAll(RequestPatternBuilder requestPatternBuilder) {
|
||||
return wireMockServer.findAll(requestPatternBuilder);
|
||||
}
|
||||
|
||||
@@ -109,6 +109,10 @@ public class WireMockRuleConfiguration implements Options {
|
||||
return parent.browserProxyingEnabled();
|
||||
}
|
||||
|
||||
public BrowserProxySettings browserProxySettings() {
|
||||
return parent.browserProxySettings();
|
||||
}
|
||||
|
||||
public ProxySettings proxyVia() {
|
||||
return parent.proxyVia();
|
||||
}
|
||||
@@ -180,4 +184,8 @@ public class WireMockRuleConfiguration implements Options {
|
||||
public boolean getStubRequestLoggingDisabled() {
|
||||
return parent.getStubRequestLoggingDisabled();
|
||||
}
|
||||
|
||||
public boolean getStubCorsEnabled() {
|
||||
return parent.getStubCorsEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"id": "257aa346-b2fa-4808-a587-ce26a6859bf7",
|
||||
"name": "repos_jenkinsci_jenkins_git_refs_heads_master",
|
||||
"request": {
|
||||
"url": "/repos/jenkinsci/jenkins/git/ref/heads/master",
|
||||
"url": "/repos/jenkinsci/jenkins/git/refs/heads/master",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
|
||||
@@ -0,0 +1,305 @@
|
||||
{
|
||||
"id": 40763577,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnk0MDc2MzU3Nw==",
|
||||
"name": "GHContentIntegrationTest",
|
||||
"full_name": "hub4j-test-org/GHContentIntegrationTest",
|
||||
"private": false,
|
||||
"owner": {
|
||||
"login": "hub4j-test-org",
|
||||
"id": 7544739,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
|
||||
"avatar_url": "https://avatars3.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/GHContentIntegrationTest",
|
||||
"description": "Repository used for integration test of github-api",
|
||||
"fork": true,
|
||||
"url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest",
|
||||
"forks_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/forks",
|
||||
"keys_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/keys{/key_id}",
|
||||
"collaborators_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/collaborators{/collaborator}",
|
||||
"teams_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/teams",
|
||||
"hooks_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/hooks",
|
||||
"issue_events_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/issues/events{/number}",
|
||||
"events_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/events",
|
||||
"assignees_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/assignees{/user}",
|
||||
"branches_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/branches{/branch}",
|
||||
"tags_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/tags",
|
||||
"blobs_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/git/blobs{/sha}",
|
||||
"git_tags_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/git/tags{/sha}",
|
||||
"git_refs_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/git/refs{/sha}",
|
||||
"trees_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/git/trees{/sha}",
|
||||
"statuses_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/statuses/{sha}",
|
||||
"languages_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/languages",
|
||||
"stargazers_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/stargazers",
|
||||
"contributors_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/contributors",
|
||||
"subscribers_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/subscribers",
|
||||
"subscription_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/subscription",
|
||||
"commits_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/commits{/sha}",
|
||||
"git_commits_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/git/commits{/sha}",
|
||||
"comments_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/comments{/number}",
|
||||
"issue_comment_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/issues/comments{/number}",
|
||||
"contents_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/contents/{+path}",
|
||||
"compare_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/compare/{base}...{head}",
|
||||
"merges_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/merges",
|
||||
"archive_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/{archive_format}{/ref}",
|
||||
"downloads_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/downloads",
|
||||
"issues_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/issues{/number}",
|
||||
"pulls_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/pulls{/number}",
|
||||
"milestones_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/milestones{/number}",
|
||||
"notifications_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/notifications{?since,all,participating}",
|
||||
"labels_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/labels{/name}",
|
||||
"releases_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/releases{/id}",
|
||||
"deployments_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/deployments",
|
||||
"created_at": "2015-08-15T14:14:57Z",
|
||||
"updated_at": "2020-07-02T15:49:49Z",
|
||||
"pushed_at": "2020-07-02T15:49:47Z",
|
||||
"git_url": "git://github.com/hub4j-test-org/GHContentIntegrationTest.git",
|
||||
"ssh_url": "git@github.com:hub4j-test-org/GHContentIntegrationTest.git",
|
||||
"clone_url": "https://github.com/hub4j-test-org/GHContentIntegrationTest.git",
|
||||
"svn_url": "https://github.com/hub4j-test-org/GHContentIntegrationTest",
|
||||
"homepage": null,
|
||||
"size": 54,
|
||||
"stargazers_count": 0,
|
||||
"watchers_count": 0,
|
||||
"language": null,
|
||||
"has_issues": false,
|
||||
"has_projects": true,
|
||||
"has_downloads": true,
|
||||
"has_wiki": true,
|
||||
"has_pages": false,
|
||||
"forks_count": 41,
|
||||
"mirror_url": null,
|
||||
"archived": false,
|
||||
"disabled": false,
|
||||
"open_issues_count": 0,
|
||||
"license": null,
|
||||
"forks": 41,
|
||||
"open_issues": 0,
|
||||
"watchers": 0,
|
||||
"default_branch": "master",
|
||||
"temp_clone_token": null,
|
||||
"organization": {
|
||||
"login": "hub4j-test-org",
|
||||
"id": 7544739,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"parent": {
|
||||
"id": 19653852,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnkxOTY1Mzg1Mg==",
|
||||
"name": "GHContentIntegrationTest",
|
||||
"full_name": "kohsuke2/GHContentIntegrationTest",
|
||||
"private": false,
|
||||
"owner": {
|
||||
"login": "kohsuke2",
|
||||
"id": 1329242,
|
||||
"node_id": "MDQ6VXNlcjEzMjkyNDI=",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/1329242?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/kohsuke2",
|
||||
"html_url": "https://github.com/kohsuke2",
|
||||
"followers_url": "https://api.github.com/users/kohsuke2/followers",
|
||||
"following_url": "https://api.github.com/users/kohsuke2/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/kohsuke2/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/kohsuke2/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/kohsuke2/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/kohsuke2/orgs",
|
||||
"repos_url": "https://api.github.com/users/kohsuke2/repos",
|
||||
"events_url": "https://api.github.com/users/kohsuke2/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/kohsuke2/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"html_url": "https://github.com/kohsuke2/GHContentIntegrationTest",
|
||||
"description": "Repository used for integration test of github-api",
|
||||
"fork": true,
|
||||
"url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest",
|
||||
"forks_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/forks",
|
||||
"keys_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/keys{/key_id}",
|
||||
"collaborators_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/collaborators{/collaborator}",
|
||||
"teams_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/teams",
|
||||
"hooks_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/hooks",
|
||||
"issue_events_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/issues/events{/number}",
|
||||
"events_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/events",
|
||||
"assignees_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/assignees{/user}",
|
||||
"branches_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/branches{/branch}",
|
||||
"tags_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/tags",
|
||||
"blobs_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/git/blobs{/sha}",
|
||||
"git_tags_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/git/tags{/sha}",
|
||||
"git_refs_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/git/refs{/sha}",
|
||||
"trees_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/git/trees{/sha}",
|
||||
"statuses_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/statuses/{sha}",
|
||||
"languages_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/languages",
|
||||
"stargazers_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/stargazers",
|
||||
"contributors_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/contributors",
|
||||
"subscribers_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/subscribers",
|
||||
"subscription_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/subscription",
|
||||
"commits_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/commits{/sha}",
|
||||
"git_commits_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/git/commits{/sha}",
|
||||
"comments_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/comments{/number}",
|
||||
"issue_comment_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/issues/comments{/number}",
|
||||
"contents_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/contents/{+path}",
|
||||
"compare_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/compare/{base}...{head}",
|
||||
"merges_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/merges",
|
||||
"archive_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/{archive_format}{/ref}",
|
||||
"downloads_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/downloads",
|
||||
"issues_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/issues{/number}",
|
||||
"pulls_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/pulls{/number}",
|
||||
"milestones_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/milestones{/number}",
|
||||
"notifications_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/notifications{?since,all,participating}",
|
||||
"labels_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/labels{/name}",
|
||||
"releases_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/releases{/id}",
|
||||
"deployments_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/deployments",
|
||||
"created_at": "2014-05-10T22:50:30Z",
|
||||
"updated_at": "2018-11-07T15:36:19Z",
|
||||
"pushed_at": "2018-11-07T15:36:18Z",
|
||||
"git_url": "git://github.com/kohsuke2/GHContentIntegrationTest.git",
|
||||
"ssh_url": "git@github.com:kohsuke2/GHContentIntegrationTest.git",
|
||||
"clone_url": "https://github.com/kohsuke2/GHContentIntegrationTest.git",
|
||||
"svn_url": "https://github.com/kohsuke2/GHContentIntegrationTest",
|
||||
"homepage": null,
|
||||
"size": 111,
|
||||
"stargazers_count": 0,
|
||||
"watchers_count": 0,
|
||||
"language": null,
|
||||
"has_issues": false,
|
||||
"has_projects": true,
|
||||
"has_downloads": true,
|
||||
"has_wiki": true,
|
||||
"has_pages": false,
|
||||
"forks_count": 1,
|
||||
"mirror_url": null,
|
||||
"archived": false,
|
||||
"disabled": false,
|
||||
"open_issues_count": 0,
|
||||
"license": null,
|
||||
"forks": 1,
|
||||
"open_issues": 0,
|
||||
"watchers": 0,
|
||||
"default_branch": "master"
|
||||
},
|
||||
"source": {
|
||||
"id": 14779458,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnkxNDc3OTQ1OA==",
|
||||
"name": "github-api-test-1",
|
||||
"full_name": "farmdawgnation/github-api-test-1",
|
||||
"private": false,
|
||||
"owner": {
|
||||
"login": "farmdawgnation",
|
||||
"id": 620189,
|
||||
"node_id": "MDQ6VXNlcjYyMDE4OQ==",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/620189?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/farmdawgnation",
|
||||
"html_url": "https://github.com/farmdawgnation",
|
||||
"followers_url": "https://api.github.com/users/farmdawgnation/followers",
|
||||
"following_url": "https://api.github.com/users/farmdawgnation/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/farmdawgnation/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/farmdawgnation/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/farmdawgnation/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/farmdawgnation/orgs",
|
||||
"repos_url": "https://api.github.com/users/farmdawgnation/repos",
|
||||
"events_url": "https://api.github.com/users/farmdawgnation/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/farmdawgnation/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"html_url": "https://github.com/farmdawgnation/github-api-test-1",
|
||||
"description": "Repository used for integration test of github-api",
|
||||
"fork": false,
|
||||
"url": "https://api.github.com/repos/farmdawgnation/github-api-test-1",
|
||||
"forks_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/forks",
|
||||
"keys_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/keys{/key_id}",
|
||||
"collaborators_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/collaborators{/collaborator}",
|
||||
"teams_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/teams",
|
||||
"hooks_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/hooks",
|
||||
"issue_events_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/issues/events{/number}",
|
||||
"events_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/events",
|
||||
"assignees_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/assignees{/user}",
|
||||
"branches_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/branches{/branch}",
|
||||
"tags_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/tags",
|
||||
"blobs_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/git/blobs{/sha}",
|
||||
"git_tags_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/git/tags{/sha}",
|
||||
"git_refs_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/git/refs{/sha}",
|
||||
"trees_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/git/trees{/sha}",
|
||||
"statuses_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/statuses/{sha}",
|
||||
"languages_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/languages",
|
||||
"stargazers_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/stargazers",
|
||||
"contributors_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/contributors",
|
||||
"subscribers_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/subscribers",
|
||||
"subscription_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/subscription",
|
||||
"commits_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/commits{/sha}",
|
||||
"git_commits_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/git/commits{/sha}",
|
||||
"comments_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/comments{/number}",
|
||||
"issue_comment_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/issues/comments{/number}",
|
||||
"contents_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/contents/{+path}",
|
||||
"compare_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/compare/{base}...{head}",
|
||||
"merges_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/merges",
|
||||
"archive_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/{archive_format}{/ref}",
|
||||
"downloads_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/downloads",
|
||||
"issues_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/issues{/number}",
|
||||
"pulls_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/pulls{/number}",
|
||||
"milestones_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/milestones{/number}",
|
||||
"notifications_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/notifications{?since,all,participating}",
|
||||
"labels_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/labels{/name}",
|
||||
"releases_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/releases{/id}",
|
||||
"deployments_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/deployments",
|
||||
"created_at": "2013-11-28T14:46:38Z",
|
||||
"updated_at": "2016-02-05T13:33:23Z",
|
||||
"pushed_at": "2013-11-28T14:55:36Z",
|
||||
"git_url": "git://github.com/farmdawgnation/github-api-test-1.git",
|
||||
"ssh_url": "git@github.com:farmdawgnation/github-api-test-1.git",
|
||||
"clone_url": "https://github.com/farmdawgnation/github-api-test-1.git",
|
||||
"svn_url": "https://github.com/farmdawgnation/github-api-test-1",
|
||||
"homepage": null,
|
||||
"size": 89,
|
||||
"stargazers_count": 0,
|
||||
"watchers_count": 0,
|
||||
"language": null,
|
||||
"has_issues": false,
|
||||
"has_projects": true,
|
||||
"has_downloads": true,
|
||||
"has_wiki": true,
|
||||
"has_pages": false,
|
||||
"forks_count": 59,
|
||||
"mirror_url": null,
|
||||
"archived": false,
|
||||
"disabled": false,
|
||||
"open_issues_count": 0,
|
||||
"license": null,
|
||||
"forks": 59,
|
||||
"open_issues": 0,
|
||||
"watchers": 0,
|
||||
"default_branch": "master"
|
||||
},
|
||||
"network_count": 59,
|
||||
"subscribers_count": 0
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
{
|
||||
"id": 40763577,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnk0MDc2MzU3Nw==",
|
||||
"name": "GHContentIntegrationTest",
|
||||
"full_name": "hub4j-test-org/GHContentIntegrationTest",
|
||||
"private": false,
|
||||
"owner": {
|
||||
"login": "hub4j-test-org",
|
||||
"id": 7544739,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
|
||||
"avatar_url": "https://avatars3.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/GHContentIntegrationTest",
|
||||
"description": "Repository used for integration test of github-api",
|
||||
"fork": true,
|
||||
"url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest",
|
||||
"forks_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/forks",
|
||||
"keys_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/keys{/key_id}",
|
||||
"collaborators_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/collaborators{/collaborator}",
|
||||
"teams_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/teams",
|
||||
"hooks_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/hooks",
|
||||
"issue_events_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/issues/events{/number}",
|
||||
"events_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/events",
|
||||
"assignees_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/assignees{/user}",
|
||||
"branches_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/branches{/branch}",
|
||||
"tags_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/tags",
|
||||
"blobs_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/git/blobs{/sha}",
|
||||
"git_tags_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/git/tags{/sha}",
|
||||
"git_refs_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/git/refs{/sha}",
|
||||
"trees_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/git/trees{/sha}",
|
||||
"statuses_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/statuses/{sha}",
|
||||
"languages_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/languages",
|
||||
"stargazers_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/stargazers",
|
||||
"contributors_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/contributors",
|
||||
"subscribers_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/subscribers",
|
||||
"subscription_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/subscription",
|
||||
"commits_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/commits{/sha}",
|
||||
"git_commits_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/git/commits{/sha}",
|
||||
"comments_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/comments{/number}",
|
||||
"issue_comment_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/issues/comments{/number}",
|
||||
"contents_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/contents/{+path}",
|
||||
"compare_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/compare/{base}...{head}",
|
||||
"merges_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/merges",
|
||||
"archive_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/{archive_format}{/ref}",
|
||||
"downloads_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/downloads",
|
||||
"issues_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/issues{/number}",
|
||||
"pulls_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/pulls{/number}",
|
||||
"milestones_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/milestones{/number}",
|
||||
"notifications_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/notifications{?since,all,participating}",
|
||||
"labels_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/labels{/name}",
|
||||
"releases_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/releases{/id}",
|
||||
"deployments_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/deployments",
|
||||
"created_at": "2015-08-15T14:14:57Z",
|
||||
"updated_at": "2020-07-02T15:49:49Z",
|
||||
"pushed_at": "2020-07-02T15:49:47Z",
|
||||
"git_url": "git://github.com/hub4j-test-org/GHContentIntegrationTest.git",
|
||||
"ssh_url": "git@github.com:hub4j-test-org/GHContentIntegrationTest.git",
|
||||
"clone_url": "https://github.com/hub4j-test-org/GHContentIntegrationTest.git",
|
||||
"svn_url": "https://github.com/hub4j-test-org/GHContentIntegrationTest",
|
||||
"homepage": null,
|
||||
"size": 54,
|
||||
"stargazers_count": 0,
|
||||
"watchers_count": 0,
|
||||
"language": null,
|
||||
"has_issues": false,
|
||||
"has_projects": true,
|
||||
"has_downloads": true,
|
||||
"has_wiki": true,
|
||||
"has_pages": false,
|
||||
"forks_count": 41,
|
||||
"mirror_url": null,
|
||||
"archived": false,
|
||||
"disabled": false,
|
||||
"open_issues_count": 0,
|
||||
"license": null,
|
||||
"forks": 41,
|
||||
"open_issues": 0,
|
||||
"watchers": 0,
|
||||
"default_branch": "master",
|
||||
"temp_clone_token": null,
|
||||
"organization": {
|
||||
"login": "hub4j-test-org",
|
||||
"id": 7544739,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"parent": {
|
||||
"id": 19653852,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnkxOTY1Mzg1Mg==",
|
||||
"name": "GHContentIntegrationTest",
|
||||
"full_name": "kohsuke2/GHContentIntegrationTest",
|
||||
"private": false,
|
||||
"owner": {
|
||||
"login": "kohsuke2",
|
||||
"id": 1329242,
|
||||
"node_id": "MDQ6VXNlcjEzMjkyNDI=",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/1329242?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/kohsuke2",
|
||||
"html_url": "https://github.com/kohsuke2",
|
||||
"followers_url": "https://api.github.com/users/kohsuke2/followers",
|
||||
"following_url": "https://api.github.com/users/kohsuke2/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/kohsuke2/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/kohsuke2/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/kohsuke2/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/kohsuke2/orgs",
|
||||
"repos_url": "https://api.github.com/users/kohsuke2/repos",
|
||||
"events_url": "https://api.github.com/users/kohsuke2/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/kohsuke2/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"html_url": "https://github.com/kohsuke2/GHContentIntegrationTest",
|
||||
"description": "Repository used for integration test of github-api",
|
||||
"fork": true,
|
||||
"url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest",
|
||||
"forks_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/forks",
|
||||
"keys_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/keys{/key_id}",
|
||||
"collaborators_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/collaborators{/collaborator}",
|
||||
"teams_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/teams",
|
||||
"hooks_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/hooks",
|
||||
"issue_events_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/issues/events{/number}",
|
||||
"events_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/events",
|
||||
"assignees_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/assignees{/user}",
|
||||
"branches_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/branches{/branch}",
|
||||
"tags_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/tags",
|
||||
"blobs_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/git/blobs{/sha}",
|
||||
"git_tags_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/git/tags{/sha}",
|
||||
"git_refs_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/git/refs{/sha}",
|
||||
"trees_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/git/trees{/sha}",
|
||||
"statuses_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/statuses/{sha}",
|
||||
"languages_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/languages",
|
||||
"stargazers_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/stargazers",
|
||||
"contributors_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/contributors",
|
||||
"subscribers_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/subscribers",
|
||||
"subscription_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/subscription",
|
||||
"commits_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/commits{/sha}",
|
||||
"git_commits_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/git/commits{/sha}",
|
||||
"comments_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/comments{/number}",
|
||||
"issue_comment_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/issues/comments{/number}",
|
||||
"contents_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/contents/{+path}",
|
||||
"compare_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/compare/{base}...{head}",
|
||||
"merges_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/merges",
|
||||
"archive_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/{archive_format}{/ref}",
|
||||
"downloads_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/downloads",
|
||||
"issues_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/issues{/number}",
|
||||
"pulls_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/pulls{/number}",
|
||||
"milestones_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/milestones{/number}",
|
||||
"notifications_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/notifications{?since,all,participating}",
|
||||
"labels_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/labels{/name}",
|
||||
"releases_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/releases{/id}",
|
||||
"deployments_url": "https://api.github.com/repos/kohsuke2/GHContentIntegrationTest/deployments",
|
||||
"created_at": "2014-05-10T22:50:30Z",
|
||||
"updated_at": "2018-11-07T15:36:19Z",
|
||||
"pushed_at": "2018-11-07T15:36:18Z",
|
||||
"git_url": "git://github.com/kohsuke2/GHContentIntegrationTest.git",
|
||||
"ssh_url": "git@github.com:kohsuke2/GHContentIntegrationTest.git",
|
||||
"clone_url": "https://github.com/kohsuke2/GHContentIntegrationTest.git",
|
||||
"svn_url": "https://github.com/kohsuke2/GHContentIntegrationTest",
|
||||
"homepage": null,
|
||||
"size": 111,
|
||||
"stargazers_count": 0,
|
||||
"watchers_count": 0,
|
||||
"language": null,
|
||||
"has_issues": false,
|
||||
"has_projects": true,
|
||||
"has_downloads": true,
|
||||
"has_wiki": true,
|
||||
"has_pages": false,
|
||||
"forks_count": 1,
|
||||
"mirror_url": null,
|
||||
"archived": false,
|
||||
"disabled": false,
|
||||
"open_issues_count": 0,
|
||||
"license": null,
|
||||
"forks": 1,
|
||||
"open_issues": 0,
|
||||
"watchers": 0,
|
||||
"default_branch": "master"
|
||||
},
|
||||
"source": {
|
||||
"id": 14779458,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnkxNDc3OTQ1OA==",
|
||||
"name": "github-api-test-1",
|
||||
"full_name": "farmdawgnation/github-api-test-1",
|
||||
"private": false,
|
||||
"owner": {
|
||||
"login": "farmdawgnation",
|
||||
"id": 620189,
|
||||
"node_id": "MDQ6VXNlcjYyMDE4OQ==",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/620189?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/farmdawgnation",
|
||||
"html_url": "https://github.com/farmdawgnation",
|
||||
"followers_url": "https://api.github.com/users/farmdawgnation/followers",
|
||||
"following_url": "https://api.github.com/users/farmdawgnation/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/farmdawgnation/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/farmdawgnation/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/farmdawgnation/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/farmdawgnation/orgs",
|
||||
"repos_url": "https://api.github.com/users/farmdawgnation/repos",
|
||||
"events_url": "https://api.github.com/users/farmdawgnation/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/farmdawgnation/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"html_url": "https://github.com/farmdawgnation/github-api-test-1",
|
||||
"description": "Repository used for integration test of github-api",
|
||||
"fork": false,
|
||||
"url": "https://api.github.com/repos/farmdawgnation/github-api-test-1",
|
||||
"forks_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/forks",
|
||||
"keys_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/keys{/key_id}",
|
||||
"collaborators_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/collaborators{/collaborator}",
|
||||
"teams_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/teams",
|
||||
"hooks_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/hooks",
|
||||
"issue_events_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/issues/events{/number}",
|
||||
"events_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/events",
|
||||
"assignees_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/assignees{/user}",
|
||||
"branches_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/branches{/branch}",
|
||||
"tags_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/tags",
|
||||
"blobs_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/git/blobs{/sha}",
|
||||
"git_tags_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/git/tags{/sha}",
|
||||
"git_refs_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/git/refs{/sha}",
|
||||
"trees_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/git/trees{/sha}",
|
||||
"statuses_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/statuses/{sha}",
|
||||
"languages_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/languages",
|
||||
"stargazers_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/stargazers",
|
||||
"contributors_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/contributors",
|
||||
"subscribers_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/subscribers",
|
||||
"subscription_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/subscription",
|
||||
"commits_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/commits{/sha}",
|
||||
"git_commits_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/git/commits{/sha}",
|
||||
"comments_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/comments{/number}",
|
||||
"issue_comment_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/issues/comments{/number}",
|
||||
"contents_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/contents/{+path}",
|
||||
"compare_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/compare/{base}...{head}",
|
||||
"merges_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/merges",
|
||||
"archive_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/{archive_format}{/ref}",
|
||||
"downloads_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/downloads",
|
||||
"issues_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/issues{/number}",
|
||||
"pulls_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/pulls{/number}",
|
||||
"milestones_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/milestones{/number}",
|
||||
"notifications_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/notifications{?since,all,participating}",
|
||||
"labels_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/labels{/name}",
|
||||
"releases_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/releases{/id}",
|
||||
"deployments_url": "https://api.github.com/repos/farmdawgnation/github-api-test-1/deployments",
|
||||
"created_at": "2013-11-28T14:46:38Z",
|
||||
"updated_at": "2016-02-05T13:33:23Z",
|
||||
"pushed_at": "2013-11-28T14:55:36Z",
|
||||
"git_url": "git://github.com/farmdawgnation/github-api-test-1.git",
|
||||
"ssh_url": "git@github.com:farmdawgnation/github-api-test-1.git",
|
||||
"clone_url": "https://github.com/farmdawgnation/github-api-test-1.git",
|
||||
"svn_url": "https://github.com/farmdawgnation/github-api-test-1",
|
||||
"homepage": null,
|
||||
"size": 89,
|
||||
"stargazers_count": 0,
|
||||
"watchers_count": 0,
|
||||
"language": null,
|
||||
"has_issues": false,
|
||||
"has_projects": true,
|
||||
"has_downloads": true,
|
||||
"has_wiki": true,
|
||||
"has_pages": false,
|
||||
"forks_count": 59,
|
||||
"mirror_url": null,
|
||||
"archived": false,
|
||||
"disabled": false,
|
||||
"open_issues_count": 0,
|
||||
"license": null,
|
||||
"forks": 59,
|
||||
"open_issues": 0,
|
||||
"watchers": 0,
|
||||
"default_branch": "master"
|
||||
},
|
||||
"network_count": 59,
|
||||
"subscribers_count": 0
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "a-symlink-to-a-dir",
|
||||
"path": "ghcontent-ro/a-symlink-to-a-dir",
|
||||
"sha": "fba4aa592c12413933e5583d5ac0bdfd3ed4eb73",
|
||||
"size": 20,
|
||||
"url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/contents/ghcontent-ro/a-symlink-to-a-dir?ref=master",
|
||||
"html_url": "https://github.com/hub4j-test-org/GHContentIntegrationTest/blob/master/ghcontent-ro/a-symlink-to-a-dir",
|
||||
"git_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/git/blobs/fba4aa592c12413933e5583d5ac0bdfd3ed4eb73",
|
||||
"download_url": "https://raw.githubusercontent.com/hub4j-test-org/GHContentIntegrationTest/master/ghcontent-ro/a-symlink-to-a-dir",
|
||||
"type": "symlink",
|
||||
"target": "a-dir-with-3-entries",
|
||||
"_links": {
|
||||
"self": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/contents/ghcontent-ro/a-symlink-to-a-dir?ref=master",
|
||||
"git": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/git/blobs/fba4aa592c12413933e5583d5ac0bdfd3ed4eb73",
|
||||
"html": "https://github.com/hub4j-test-org/GHContentIntegrationTest/blob/master/ghcontent-ro/a-symlink-to-a-dir"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "a-symlink-to-a-file",
|
||||
"path": "ghcontent-ro/a-symlink-to-a-file",
|
||||
"sha": "dbb84a81d2b1b5eb4077c9b72b7497eb16ed9bf6",
|
||||
"size": 22,
|
||||
"url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/contents/ghcontent-ro/a-symlink-to-a-file?ref=master",
|
||||
"html_url": "https://github.com/hub4j-test-org/GHContentIntegrationTest/blob/master/ghcontent-ro/a-symlink-to-a-file",
|
||||
"git_url": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/git/blobs/dbb84a81d2b1b5eb4077c9b72b7497eb16ed9bf6",
|
||||
"download_url": "https://raw.githubusercontent.com/hub4j-test-org/GHContentIntegrationTest/master/ghcontent-ro/a-symlink-to-a-file",
|
||||
"type": "file",
|
||||
"content": "dGhhbmtzIGZvciByZWFkaW5nIG1lCg==\n",
|
||||
"encoding": "base64",
|
||||
"_links": {
|
||||
"self": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/contents/ghcontent-ro/a-symlink-to-a-file?ref=master",
|
||||
"git": "https://api.github.com/repos/hub4j-test-org/GHContentIntegrationTest/git/blobs/dbb84a81d2b1b5eb4077c9b72b7497eb16ed9bf6",
|
||||
"html": "https://github.com/hub4j-test-org/GHContentIntegrationTest/blob/master/ghcontent-ro/a-symlink-to-a-file"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"id": "054974d2-b150-4d00-9027-c3ad6bbaf023",
|
||||
"name": "repos_hub4j-test-org_ghcontentintegrationtest",
|
||||
"request": {
|
||||
"url": "/repos/hub4j-test-org/GHContentIntegrationTest",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "repos_hub4j-test-org_ghcontentintegrationtest-054974d2-b150-4d00-9027-c3ad6bbaf023.json",
|
||||
"headers": {
|
||||
"server": "GitHub.com",
|
||||
"date": "Thu, 02 Jul 2020 16:17:31 GMT",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"status": "200 OK",
|
||||
"cache-control": "public, max-age=60, s-maxage=60",
|
||||
"vary": "Accept, Accept-Encoding, Accept, X-Requested-With",
|
||||
"etag": "W/\"8c4b9f7c7b3214f5bd336bb7b8053c36\"",
|
||||
"last-modified": "Thu, 02 Jul 2020 15:49:49 GMT",
|
||||
"x-github-media-type": "unknown, github.v3",
|
||||
"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-Ratelimit-Limit": "60",
|
||||
"X-Ratelimit-Remaining": "47",
|
||||
"X-Ratelimit-Reset": "1593708014",
|
||||
"Accept-Ranges": "bytes",
|
||||
"X-GitHub-Request-Id": "EF84:24F2:A8B982:1A6F1B3:5EFE089B"
|
||||
}
|
||||
},
|
||||
"uuid": "054974d2-b150-4d00-9027-c3ad6bbaf023",
|
||||
"persistent": true,
|
||||
"scenarioName": "scenario-1-repos-hub4j-test-org-GHContentIntegrationTest",
|
||||
"requiredScenarioState": "scenario-1-repos-hub4j-test-org-GHContentIntegrationTest-2",
|
||||
"insertionIndex": 2
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"id": "81f3af1c-4fb1-4e3b-baa0-c682510d1137",
|
||||
"name": "repos_hub4j-test-org_ghcontentintegrationtest",
|
||||
"request": {
|
||||
"url": "/repos/hub4j-test-org/GHContentIntegrationTest",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "repos_hub4j-test-org_ghcontentintegrationtest-81f3af1c-4fb1-4e3b-baa0-c682510d1137.json",
|
||||
"headers": {
|
||||
"server": "GitHub.com",
|
||||
"date": "Thu, 02 Jul 2020 16:17:31 GMT",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"status": "200 OK",
|
||||
"cache-control": "public, max-age=60, s-maxage=60",
|
||||
"vary": "Accept, Accept-Encoding, Accept, X-Requested-With",
|
||||
"etag": "W/\"8c4b9f7c7b3214f5bd336bb7b8053c36\"",
|
||||
"last-modified": "Thu, 02 Jul 2020 15:49:49 GMT",
|
||||
"x-github-media-type": "unknown, github.v3",
|
||||
"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-Ratelimit-Limit": "60",
|
||||
"X-Ratelimit-Remaining": "48",
|
||||
"X-Ratelimit-Reset": "1593708014",
|
||||
"Accept-Ranges": "bytes",
|
||||
"X-GitHub-Request-Id": "EF84:24F2:A8B94F:1A6F198:5EFE089A"
|
||||
}
|
||||
},
|
||||
"uuid": "81f3af1c-4fb1-4e3b-baa0-c682510d1137",
|
||||
"persistent": true,
|
||||
"scenarioName": "scenario-1-repos-hub4j-test-org-GHContentIntegrationTest",
|
||||
"requiredScenarioState": "Started",
|
||||
"newScenarioState": "scenario-1-repos-hub4j-test-org-GHContentIntegrationTest-2",
|
||||
"insertionIndex": 1
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"id": "1baf6207-f25f-4064-af9b-8eb1cb1fe125",
|
||||
"name": "repos_hub4j-test-org_ghcontentintegrationtest_contents_ghcontent-ro_a-symlink-to-a-dir",
|
||||
"request": {
|
||||
"url": "/repos/hub4j-test-org/GHContentIntegrationTest/contents/ghcontent-ro/a-symlink-to-a-dir",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "repos_hub4j-test-org_ghcontentintegrationtest_contents_ghcontent-ro_a-symlink-to-a-dir-4.json",
|
||||
"headers": {
|
||||
"server": "GitHub.com",
|
||||
"date": "Thu, 02 Jul 2020 16:17:32 GMT",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"status": "200 OK",
|
||||
"cache-control": "public, max-age=60, s-maxage=60",
|
||||
"vary": "Accept, Accept-Encoding, Accept, X-Requested-With",
|
||||
"etag": "W/\"fba4aa592c12413933e5583d5ac0bdfd3ed4eb73\"",
|
||||
"last-modified": "Thu, 02 Jul 2020 15:49:45 GMT",
|
||||
"x-github-media-type": "unknown, github.v3",
|
||||
"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-Ratelimit-Limit": "60",
|
||||
"X-Ratelimit-Remaining": "45",
|
||||
"X-Ratelimit-Reset": "1593708014",
|
||||
"Accept-Ranges": "bytes",
|
||||
"X-GitHub-Request-Id": "EF84:24F2:A8B9A5:1A6F235:5EFE089B"
|
||||
}
|
||||
},
|
||||
"uuid": "1baf6207-f25f-4064-af9b-8eb1cb1fe125",
|
||||
"persistent": true,
|
||||
"insertionIndex": 4
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"id": "ed777707-b13d-4d06-885f-529154318f3b",
|
||||
"name": "repos_hub4j-test-org_ghcontentintegrationtest_contents_ghcontent-ro_a-symlink-to-a-file",
|
||||
"request": {
|
||||
"url": "/repos/hub4j-test-org/GHContentIntegrationTest/contents/ghcontent-ro/a-symlink-to-a-file",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "repos_hub4j-test-org_ghcontentintegrationtest_contents_ghcontent-ro_a-symlink-to-a-file-3.json",
|
||||
"headers": {
|
||||
"server": "GitHub.com",
|
||||
"date": "Thu, 02 Jul 2020 16:17:31 GMT",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"status": "200 OK",
|
||||
"cache-control": "public, max-age=60, s-maxage=60",
|
||||
"vary": "Accept, Accept-Encoding, Accept, X-Requested-With",
|
||||
"etag": "W/\"dbb84a81d2b1b5eb4077c9b72b7497eb16ed9bf6\"",
|
||||
"last-modified": "Thu, 02 Jul 2020 15:49:45 GMT",
|
||||
"x-github-media-type": "unknown, github.v3",
|
||||
"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-Ratelimit-Limit": "60",
|
||||
"X-Ratelimit-Remaining": "46",
|
||||
"X-Ratelimit-Reset": "1593708014",
|
||||
"Accept-Ranges": "bytes",
|
||||
"X-GitHub-Request-Id": "EF84:24F2:A8B991:1A6F20E:5EFE089B"
|
||||
}
|
||||
},
|
||||
"uuid": "ed777707-b13d-4d06-885f-529154318f3b",
|
||||
"persistent": true,
|
||||
"insertionIndex": 3
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"author": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"body": "This is a public discussion",
|
||||
"body_html": "<p>This is a public discussion</p>",
|
||||
"body_version": "d1ab9311f2fe800dcd6f9499163d5369",
|
||||
"comments_count": 0,
|
||||
"comments_url": "https://api.github.com/organizations/7544739/team/3451996/discussions/57/comments",
|
||||
"created_at": "2020-06-05T23:08:28Z",
|
||||
"last_edited_at": null,
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team/discussions/57",
|
||||
"node_id": "MDE0OlRlYW1EaXNjdXNzaW9uMTE3ODQ4",
|
||||
"number": 57,
|
||||
"pinned": false,
|
||||
"private": false,
|
||||
"team_url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"title": "Some Discussion",
|
||||
"updated_at": "2020-06-05T23:08:28Z",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996/discussions/57"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"author": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"body": "This is another public discussion",
|
||||
"body_html": "<p>This is another public discussion</p>",
|
||||
"body_version": "611e0dcc600e9915b7d96e4bec2b7b35",
|
||||
"comments_count": 0,
|
||||
"comments_url": "https://api.github.com/organizations/7544739/team/3451996/discussions/58/comments",
|
||||
"created_at": "2020-06-05T23:08:29Z",
|
||||
"last_edited_at": null,
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team/discussions/58",
|
||||
"node_id": "MDE0OlRlYW1EaXNjdXNzaW9uMTE3ODQ5",
|
||||
"number": 58,
|
||||
"pinned": false,
|
||||
"private": false,
|
||||
"team_url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"title": "Some Discussion",
|
||||
"updated_at": "2020-06-05T23:08:29Z",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996/discussions/58"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"author": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"body": "This is a private (secret) discussion",
|
||||
"body_html": "<p>This is a private (secret) discussion</p>",
|
||||
"body_version": "32e9a84be65b3a703f5db5b8635388eb",
|
||||
"comments_count": 0,
|
||||
"comments_url": "https://api.github.com/organizations/7544739/team/3451996/discussions/59/comments",
|
||||
"created_at": "2020-06-05T23:08:29Z",
|
||||
"last_edited_at": null,
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team/discussions/59",
|
||||
"node_id": "MDE0OlRlYW1EaXNjdXNzaW9uMTE3ODUw",
|
||||
"number": 59,
|
||||
"pinned": false,
|
||||
"private": true,
|
||||
"team_url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"title": "Some Discussion",
|
||||
"updated_at": "2020-06-05T23:08:29Z",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996/discussions/59"
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"login": "hub4j-test-org",
|
||||
"id": 7544739,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
|
||||
"url": "https://api.github.com/orgs/hub4j-test-org",
|
||||
"repos_url": "https://api.github.com/orgs/hub4j-test-org/repos",
|
||||
"events_url": "https://api.github.com/orgs/hub4j-test-org/events",
|
||||
"hooks_url": "https://api.github.com/orgs/hub4j-test-org/hooks",
|
||||
"issues_url": "https://api.github.com/orgs/hub4j-test-org/issues",
|
||||
"members_url": "https://api.github.com/orgs/hub4j-test-org/members{/member}",
|
||||
"public_members_url": "https://api.github.com/orgs/hub4j-test-org/public_members{/member}",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
|
||||
"description": "Hub4j Test Org Description (this could be null or blank too)",
|
||||
"name": "Hub4j Test Org Name (this could be null or blank too)",
|
||||
"company": null,
|
||||
"blog": "https://hub4j.url.io/could/be/null",
|
||||
"location": "Hub4j Test Org Location (this could be null or blank too)",
|
||||
"email": "hub4jtestorgemail@could.be.null.com",
|
||||
"twitter_username": null,
|
||||
"is_verified": false,
|
||||
"has_organization_projects": true,
|
||||
"has_repository_projects": true,
|
||||
"public_repos": 15,
|
||||
"public_gists": 0,
|
||||
"followers": 0,
|
||||
"following": 0,
|
||||
"html_url": "https://github.com/hub4j-test-org",
|
||||
"created_at": "2014-05-10T19:39:11Z",
|
||||
"updated_at": "2020-06-04T05:56:10Z",
|
||||
"type": "Organization",
|
||||
"total_private_repos": 0,
|
||||
"owned_private_repos": 0,
|
||||
"private_gists": 0,
|
||||
"disk_usage": 148,
|
||||
"collaborators": 0,
|
||||
"billing_email": "kk@kohsuke.org",
|
||||
"default_repository_permission": "none",
|
||||
"members_can_create_repositories": false,
|
||||
"two_factor_requirement_enabled": false,
|
||||
"plan": {
|
||||
"name": "free",
|
||||
"space": 976562499,
|
||||
"private_repos": 10000,
|
||||
"filled_seats": 18,
|
||||
"seats": 3
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "dummy-team",
|
||||
"id": 3451996,
|
||||
"node_id": "MDQ6VGVhbTM0NTE5OTY=",
|
||||
"slug": "dummy-team",
|
||||
"description": "Updated by API TestModified",
|
||||
"privacy": "closed",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team",
|
||||
"members_url": "https://api.github.com/organizations/7544739/team/3451996/members{/member}",
|
||||
"repositories_url": "https://api.github.com/organizations/7544739/team/3451996/repos",
|
||||
"permission": "pull",
|
||||
"created_at": "2019-10-03T21:46:12Z",
|
||||
"updated_at": "2020-06-02T19:31:50Z",
|
||||
"members_count": 1,
|
||||
"repos_count": 1,
|
||||
"organization": {
|
||||
"login": "hub4j-test-org",
|
||||
"id": 7544739,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
|
||||
"url": "https://api.github.com/orgs/hub4j-test-org",
|
||||
"repos_url": "https://api.github.com/orgs/hub4j-test-org/repos",
|
||||
"events_url": "https://api.github.com/orgs/hub4j-test-org/events",
|
||||
"hooks_url": "https://api.github.com/orgs/hub4j-test-org/hooks",
|
||||
"issues_url": "https://api.github.com/orgs/hub4j-test-org/issues",
|
||||
"members_url": "https://api.github.com/orgs/hub4j-test-org/members{/member}",
|
||||
"public_members_url": "https://api.github.com/orgs/hub4j-test-org/public_members{/member}",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
|
||||
"description": "Hub4j Test Org Description (this could be null or blank too)",
|
||||
"name": "Hub4j Test Org Name (this could be null or blank too)",
|
||||
"company": null,
|
||||
"blog": "https://hub4j.url.io/could/be/null",
|
||||
"location": "Hub4j Test Org Location (this could be null or blank too)",
|
||||
"email": "hub4jtestorgemail@could.be.null.com",
|
||||
"twitter_username": null,
|
||||
"is_verified": false,
|
||||
"has_organization_projects": true,
|
||||
"has_repository_projects": true,
|
||||
"public_repos": 15,
|
||||
"public_gists": 0,
|
||||
"followers": 0,
|
||||
"following": 0,
|
||||
"html_url": "https://github.com/hub4j-test-org",
|
||||
"created_at": "2014-05-10T19:39:11Z",
|
||||
"updated_at": "2020-06-04T05:56:10Z",
|
||||
"type": "Organization"
|
||||
},
|
||||
"parent": null
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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": "https://twitter.com/bitwiseman",
|
||||
"twitter_username": null,
|
||||
"public_repos": 187,
|
||||
"public_gists": 7,
|
||||
"followers": 161,
|
||||
"following": 9,
|
||||
"created_at": "2012-07-11T20:38:33Z",
|
||||
"updated_at": "2020-05-29T18:24:44Z",
|
||||
"private_gists": 19,
|
||||
"total_private_repos": 12,
|
||||
"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,54 @@
|
||||
{
|
||||
"id": "e99eb2d0-5c5d-42f7-a883-546db75493e4",
|
||||
"name": "organizations_7544739_team_3451996_discussions",
|
||||
"request": {
|
||||
"url": "/organizations/7544739/team/3451996/discussions",
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"title\":\"Some Discussion\",\"body\":\"This is a public discussion\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 201,
|
||||
"bodyFileName": "organizations_7544739_team_3451996_discussions-4.json",
|
||||
"headers": {
|
||||
"Date": "Fri, 05 Jun 2020 23:08:28 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "201 Created",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4751",
|
||||
"X-RateLimit-Reset": "1591398936",
|
||||
"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": "\"e54b9b7ddc5c67ae5103fadab8080b1e\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "write:discussion",
|
||||
"Location": "https://api.github.com/organizations/7544739/team/3451996/discussions/57",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "CFF1:24BF:5492EF:64DB5E:5EDAD06C"
|
||||
}
|
||||
},
|
||||
"uuid": "e99eb2d0-5c5d-42f7-a883-546db75493e4",
|
||||
"persistent": true,
|
||||
"insertionIndex": 4
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"id": "838ad222-65d5-47c7-bb86-cd47ba2de6f2",
|
||||
"name": "organizations_7544739_team_3451996_discussions",
|
||||
"request": {
|
||||
"url": "/organizations/7544739/team/3451996/discussions",
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"private\":false,\"title\":\"Some Discussion\",\"body\":\"This is another public discussion\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 201,
|
||||
"bodyFileName": "organizations_7544739_team_3451996_discussions-5.json",
|
||||
"headers": {
|
||||
"Date": "Fri, 05 Jun 2020 23:08:29 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "201 Created",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4750",
|
||||
"X-RateLimit-Reset": "1591398936",
|
||||
"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": "\"bc86e15d1de977f57689648ef418547a\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "write:discussion",
|
||||
"Location": "https://api.github.com/organizations/7544739/team/3451996/discussions/58",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "CFF1:24BF:549306:64DB6F:5EDAD06C"
|
||||
}
|
||||
},
|
||||
"uuid": "838ad222-65d5-47c7-bb86-cd47ba2de6f2",
|
||||
"persistent": true,
|
||||
"insertionIndex": 5
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"id": "d6c070f6-fd08-4b88-a254-d6d35986cb74",
|
||||
"name": "organizations_7544739_team_3451996_discussions",
|
||||
"request": {
|
||||
"url": "/organizations/7544739/team/3451996/discussions",
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"private\":true,\"title\":\"Some Discussion\",\"body\":\"This is a private (secret) discussion\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 201,
|
||||
"bodyFileName": "organizations_7544739_team_3451996_discussions-6.json",
|
||||
"headers": {
|
||||
"Date": "Fri, 05 Jun 2020 23:08:29 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": "1591398936",
|
||||
"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": "\"c4ca8b7d421176c6e80f3c6d00ab6f0b\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "write:discussion",
|
||||
"Location": "https://api.github.com/organizations/7544739/team/3451996/discussions/59",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "CFF1:24BF:54931E:64DB8A:5EDAD06D"
|
||||
}
|
||||
},
|
||||
"uuid": "d6c070f6-fd08-4b88-a254-d6d35986cb74",
|
||||
"persistent": true,
|
||||
"insertionIndex": 6
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"id": "5f6075fe-cdc4-4fb6-a2cb-ee22cb4e85b8",
|
||||
"name": "organizations_7544739_team_3451996_discussions",
|
||||
"request": {
|
||||
"url": "/organizations/7544739/team/3451996/discussions",
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"title\":\"Some Discussion\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 422,
|
||||
"body": "{\"message\":\"Invalid request.\\n\\n\\\"body\\\" wasn't supplied.\",\"documentation_url\":\"https://developer.github.com/v3/teams/discussions/#create-a-discussion\"}",
|
||||
"headers": {
|
||||
"Date": "Fri, 05 Jun 2020 23:08:29 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "422 Unprocessable Entity",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4748",
|
||||
"X-RateLimit-Reset": "1591398936",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "write:discussion",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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",
|
||||
"X-GitHub-Request-Id": "CFF1:24BF:54932E:64DB9C:5EDAD06D"
|
||||
}
|
||||
},
|
||||
"uuid": "5f6075fe-cdc4-4fb6-a2cb-ee22cb4e85b8",
|
||||
"persistent": true,
|
||||
"insertionIndex": 7
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"id": "98208c3a-6b4c-4b98-adb1-b063f7b2c7bf",
|
||||
"name": "orgs_hub4j-test-org",
|
||||
"request": {
|
||||
"url": "/orgs/hub4j-test-org",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "orgs_hub4j-test-org-2.json",
|
||||
"headers": {
|
||||
"Date": "Fri, 05 Jun 2020 23:08:28 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4753",
|
||||
"X-RateLimit-Reset": "1591398936",
|
||||
"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/\"0557d9126fa25140eab7bdf16c451149\"",
|
||||
"Last-Modified": "Thu, 04 Jun 2020 05:56:10 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "admin:org, read:org, repo, user, write:org",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "CFF1:24BF:5492E0:64DB3F:5EDAD06B"
|
||||
}
|
||||
},
|
||||
"uuid": "98208c3a-6b4c-4b98-adb1-b063f7b2c7bf",
|
||||
"persistent": true,
|
||||
"insertionIndex": 2
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"id": "ab3d6c7f-c986-4aa1-abf6-14e27bd88ea5",
|
||||
"name": "orgs_hub4j-test-org_teams_dummy-team",
|
||||
"request": {
|
||||
"url": "/orgs/hub4j-test-org/teams/dummy-team",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "orgs_hub4j-test-org_teams_dummy-team-3.json",
|
||||
"headers": {
|
||||
"Date": "Fri, 05 Jun 2020 23:08:28 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4752",
|
||||
"X-RateLimit-Reset": "1591398936",
|
||||
"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/\"adf552e4a615c271e66b7d2bb00e61c4\"",
|
||||
"Last-Modified": "Tue, 02 Jun 2020 19:31:50 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "admin:org, read:org, repo, user, write:org",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "CFF1:24BF:5492E7:64DB52:5EDAD06C"
|
||||
}
|
||||
},
|
||||
"uuid": "ab3d6c7f-c986-4aa1-abf6-14e27bd88ea5",
|
||||
"persistent": true,
|
||||
"insertionIndex": 3
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"id": "5f43c9c9-2d3d-45cf-9226-a8503c3815ec",
|
||||
"name": "user",
|
||||
"request": {
|
||||
"url": "/user",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "user-1.json",
|
||||
"headers": {
|
||||
"Date": "Fri, 05 Jun 2020 23:08:27 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4755",
|
||||
"X-RateLimit-Reset": "1591398935",
|
||||
"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/\"7e41c6c634de27b9ab8f4e95a42d16db\"",
|
||||
"Last-Modified": "Fri, 29 May 2020 18:24:44 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "CFF1:24BF:5492CD:64DB35:5EDAD06B"
|
||||
}
|
||||
},
|
||||
"uuid": "5f43c9c9-2d3d-45cf-9226-a8503c3815ec",
|
||||
"persistent": true,
|
||||
"insertionIndex": 1
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"author": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"body": "This is a test discussion",
|
||||
"body_html": "<p>This is a test discussion</p>",
|
||||
"body_version": "db8c6cacef3d11b326f87a5f9f7a2df0",
|
||||
"comments_count": 0,
|
||||
"comments_url": "https://api.github.com/organizations/7544739/team/3451996/discussions/64/comments",
|
||||
"created_at": "2020-06-08T18:43:30Z",
|
||||
"last_edited_at": null,
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team/discussions/64",
|
||||
"node_id": "MDE0OlRlYW1EaXNjdXNzaW9uMTE4MzQx",
|
||||
"number": 64,
|
||||
"pinned": false,
|
||||
"private": false,
|
||||
"team_url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"title": "Some Discussion",
|
||||
"updated_at": "2020-06-08T18:43:30Z",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996/discussions/64"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"author": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"body": "This is a test discussion updated",
|
||||
"body_html": "<p>This is a test discussion updated</p>",
|
||||
"body_version": "64d46f79a6f4c3806511b2029154a508",
|
||||
"comments_count": 0,
|
||||
"comments_url": "https://api.github.com/organizations/7544739/team/3451996/discussions/64/comments",
|
||||
"created_at": "2020-06-08T18:43:30Z",
|
||||
"last_edited_at": "2020-06-08T18:43:33Z",
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team/discussions/64",
|
||||
"node_id": "MDE0OlRlYW1EaXNjdXNzaW9uMTE4MzQx",
|
||||
"number": 64,
|
||||
"pinned": false,
|
||||
"private": false,
|
||||
"team_url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"title": "Title updated",
|
||||
"updated_at": "2020-06-08T18:43:33Z",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996/discussions/64"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"author": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"body": "This is a test discussion",
|
||||
"body_html": "<p>This is a test discussion</p>",
|
||||
"body_version": "db8c6cacef3d11b326f87a5f9f7a2df0",
|
||||
"comments_count": 0,
|
||||
"comments_url": "https://api.github.com/organizations/7544739/team/3451996/discussions/64/comments",
|
||||
"created_at": "2020-06-08T18:43:30Z",
|
||||
"last_edited_at": null,
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team/discussions/64",
|
||||
"node_id": "MDE0OlRlYW1EaXNjdXNzaW9uMTE4MzQx",
|
||||
"number": 64,
|
||||
"pinned": false,
|
||||
"private": false,
|
||||
"team_url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"title": "Some Discussion",
|
||||
"updated_at": "2020-06-08T18:43:30Z",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996/discussions/64"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"author": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"body": "This is a test discussion changed",
|
||||
"body_html": "<p>This is a test discussion changed</p>",
|
||||
"body_version": "40d6d08e84d525b5f268b25f5c9b14d1",
|
||||
"comments_count": 0,
|
||||
"comments_url": "https://api.github.com/organizations/7544739/team/3451996/discussions/64/comments",
|
||||
"created_at": "2020-06-08T18:43:30Z",
|
||||
"last_edited_at": "2020-06-08T18:43:31Z",
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team/discussions/64",
|
||||
"node_id": "MDE0OlRlYW1EaXNjdXNzaW9uMTE4MzQx",
|
||||
"number": 64,
|
||||
"pinned": false,
|
||||
"private": false,
|
||||
"team_url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"title": "Some Discussion",
|
||||
"updated_at": "2020-06-08T18:43:31Z",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996/discussions/64"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"author": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"body": "This is a test discussion changed",
|
||||
"body_html": "<p>This is a test discussion changed</p>",
|
||||
"body_version": "40d6d08e84d525b5f268b25f5c9b14d1",
|
||||
"comments_count": 0,
|
||||
"comments_url": "https://api.github.com/organizations/7544739/team/3451996/discussions/64/comments",
|
||||
"created_at": "2020-06-08T18:43:30Z",
|
||||
"last_edited_at": "2020-06-08T18:43:31Z",
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team/discussions/64",
|
||||
"node_id": "MDE0OlRlYW1EaXNjdXNzaW9uMTE4MzQx",
|
||||
"number": 64,
|
||||
"pinned": false,
|
||||
"private": false,
|
||||
"team_url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"title": "Title changed",
|
||||
"updated_at": "2020-06-08T18:43:32Z",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996/discussions/64"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"author": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"body": "This is a test discussion changed",
|
||||
"body_html": "<p>This is a test discussion changed</p>",
|
||||
"body_version": "40d6d08e84d525b5f268b25f5c9b14d1",
|
||||
"comments_count": 0,
|
||||
"comments_url": "https://api.github.com/organizations/7544739/team/3451996/discussions/64/comments",
|
||||
"created_at": "2020-06-08T18:43:30Z",
|
||||
"last_edited_at": "2020-06-08T18:43:31Z",
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team/discussions/64",
|
||||
"node_id": "MDE0OlRlYW1EaXNjdXNzaW9uMTE4MzQx",
|
||||
"number": 64,
|
||||
"pinned": false,
|
||||
"private": false,
|
||||
"team_url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"title": "Title changed",
|
||||
"updated_at": "2020-06-08T18:43:32Z",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996/discussions/64"
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"login": "hub4j-test-org",
|
||||
"id": 7544739,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
|
||||
"url": "https://api.github.com/orgs/hub4j-test-org",
|
||||
"repos_url": "https://api.github.com/orgs/hub4j-test-org/repos",
|
||||
"events_url": "https://api.github.com/orgs/hub4j-test-org/events",
|
||||
"hooks_url": "https://api.github.com/orgs/hub4j-test-org/hooks",
|
||||
"issues_url": "https://api.github.com/orgs/hub4j-test-org/issues",
|
||||
"members_url": "https://api.github.com/orgs/hub4j-test-org/members{/member}",
|
||||
"public_members_url": "https://api.github.com/orgs/hub4j-test-org/public_members{/member}",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
|
||||
"description": "Hub4j Test Org Description (this could be null or blank too)",
|
||||
"name": "Hub4j Test Org Name (this could be null or blank too)",
|
||||
"company": null,
|
||||
"blog": "https://hub4j.url.io/could/be/null",
|
||||
"location": "Hub4j Test Org Location (this could be null or blank too)",
|
||||
"email": "hub4jtestorgemail@could.be.null.com",
|
||||
"twitter_username": null,
|
||||
"is_verified": false,
|
||||
"has_organization_projects": true,
|
||||
"has_repository_projects": true,
|
||||
"public_repos": 15,
|
||||
"public_gists": 0,
|
||||
"followers": 0,
|
||||
"following": 0,
|
||||
"html_url": "https://github.com/hub4j-test-org",
|
||||
"created_at": "2014-05-10T19:39:11Z",
|
||||
"updated_at": "2020-06-04T05:56:10Z",
|
||||
"type": "Organization",
|
||||
"total_private_repos": 0,
|
||||
"owned_private_repos": 0,
|
||||
"private_gists": 0,
|
||||
"disk_usage": 148,
|
||||
"collaborators": 0,
|
||||
"billing_email": "kk@kohsuke.org",
|
||||
"default_repository_permission": "none",
|
||||
"members_can_create_repositories": false,
|
||||
"two_factor_requirement_enabled": false,
|
||||
"plan": {
|
||||
"name": "free",
|
||||
"space": 976562499,
|
||||
"private_repos": 10000,
|
||||
"filled_seats": 18,
|
||||
"seats": 3
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "dummy-team",
|
||||
"id": 3451996,
|
||||
"node_id": "MDQ6VGVhbTM0NTE5OTY=",
|
||||
"slug": "dummy-team",
|
||||
"description": "Updated by API TestModified",
|
||||
"privacy": "closed",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team",
|
||||
"members_url": "https://api.github.com/organizations/7544739/team/3451996/members{/member}",
|
||||
"repositories_url": "https://api.github.com/organizations/7544739/team/3451996/repos",
|
||||
"permission": "pull",
|
||||
"created_at": "2019-10-03T21:46:12Z",
|
||||
"updated_at": "2020-06-02T19:31:50Z",
|
||||
"members_count": 1,
|
||||
"repos_count": 1,
|
||||
"organization": {
|
||||
"login": "hub4j-test-org",
|
||||
"id": 7544739,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
|
||||
"url": "https://api.github.com/orgs/hub4j-test-org",
|
||||
"repos_url": "https://api.github.com/orgs/hub4j-test-org/repos",
|
||||
"events_url": "https://api.github.com/orgs/hub4j-test-org/events",
|
||||
"hooks_url": "https://api.github.com/orgs/hub4j-test-org/hooks",
|
||||
"issues_url": "https://api.github.com/orgs/hub4j-test-org/issues",
|
||||
"members_url": "https://api.github.com/orgs/hub4j-test-org/members{/member}",
|
||||
"public_members_url": "https://api.github.com/orgs/hub4j-test-org/public_members{/member}",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
|
||||
"description": "Hub4j Test Org Description (this could be null or blank too)",
|
||||
"name": "Hub4j Test Org Name (this could be null or blank too)",
|
||||
"company": null,
|
||||
"blog": "https://hub4j.url.io/could/be/null",
|
||||
"location": "Hub4j Test Org Location (this could be null or blank too)",
|
||||
"email": "hub4jtestorgemail@could.be.null.com",
|
||||
"twitter_username": null,
|
||||
"is_verified": false,
|
||||
"has_organization_projects": true,
|
||||
"has_repository_projects": true,
|
||||
"public_repos": 15,
|
||||
"public_gists": 0,
|
||||
"followers": 0,
|
||||
"following": 0,
|
||||
"html_url": "https://github.com/hub4j-test-org",
|
||||
"created_at": "2014-05-10T19:39:11Z",
|
||||
"updated_at": "2020-06-04T05:56:10Z",
|
||||
"type": "Organization"
|
||||
},
|
||||
"parent": null
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "dummy-team",
|
||||
"id": 3451996,
|
||||
"node_id": "MDQ6VGVhbTM0NTE5OTY=",
|
||||
"slug": "dummy-team",
|
||||
"description": "Updated by API TestModified",
|
||||
"privacy": "closed",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team",
|
||||
"members_url": "https://api.github.com/organizations/7544739/team/3451996/members{/member}",
|
||||
"repositories_url": "https://api.github.com/organizations/7544739/team/3451996/repos",
|
||||
"permission": "pull",
|
||||
"created_at": "2019-10-03T21:46:12Z",
|
||||
"updated_at": "2020-06-02T19:31:50Z",
|
||||
"members_count": 1,
|
||||
"repos_count": 1,
|
||||
"organization": {
|
||||
"login": "hub4j-test-org",
|
||||
"id": 7544739,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
|
||||
"url": "https://api.github.com/orgs/hub4j-test-org",
|
||||
"repos_url": "https://api.github.com/orgs/hub4j-test-org/repos",
|
||||
"events_url": "https://api.github.com/orgs/hub4j-test-org/events",
|
||||
"hooks_url": "https://api.github.com/orgs/hub4j-test-org/hooks",
|
||||
"issues_url": "https://api.github.com/orgs/hub4j-test-org/issues",
|
||||
"members_url": "https://api.github.com/orgs/hub4j-test-org/members{/member}",
|
||||
"public_members_url": "https://api.github.com/orgs/hub4j-test-org/public_members{/member}",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
|
||||
"description": "Hub4j Test Org Description (this could be null or blank too)",
|
||||
"name": "Hub4j Test Org Name (this could be null or blank too)",
|
||||
"company": null,
|
||||
"blog": "https://hub4j.url.io/could/be/null",
|
||||
"location": "Hub4j Test Org Location (this could be null or blank too)",
|
||||
"email": "hub4jtestorgemail@could.be.null.com",
|
||||
"twitter_username": null,
|
||||
"is_verified": false,
|
||||
"has_organization_projects": true,
|
||||
"has_repository_projects": true,
|
||||
"public_repos": 15,
|
||||
"public_gists": 0,
|
||||
"followers": 0,
|
||||
"following": 0,
|
||||
"html_url": "https://github.com/hub4j-test-org",
|
||||
"created_at": "2014-05-10T19:39:11Z",
|
||||
"updated_at": "2020-06-04T05:56:10Z",
|
||||
"type": "Organization"
|
||||
},
|
||||
"parent": null
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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": "https://twitter.com/bitwiseman",
|
||||
"twitter_username": null,
|
||||
"public_repos": 187,
|
||||
"public_gists": 7,
|
||||
"followers": 161,
|
||||
"following": 9,
|
||||
"created_at": "2012-07-11T20:38:33Z",
|
||||
"updated_at": "2020-05-29T18:24:44Z",
|
||||
"private_gists": 19,
|
||||
"total_private_repos": 12,
|
||||
"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,54 @@
|
||||
{
|
||||
"id": "d0d593b5-4fec-4e00-97cb-0be87dcf3a65",
|
||||
"name": "organizations_7544739_team_3451996_discussions",
|
||||
"request": {
|
||||
"url": "/organizations/7544739/team/3451996/discussions",
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"title\":\"Some Discussion\",\"body\":\"This is a test discussion\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 201,
|
||||
"bodyFileName": "organizations_7544739_team_3451996_discussions-4.json",
|
||||
"headers": {
|
||||
"Date": "Mon, 08 Jun 2020 18:43:31 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "201 Created",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4957",
|
||||
"X-RateLimit-Reset": "1591642578",
|
||||
"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": "\"fa7ed609b5bcd7cbba13e22df861b688\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "write:discussion",
|
||||
"Location": "https://api.github.com/organizations/7544739/team/3451996/discussions/64",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "E996:682F:301CBD:39F052:5EDE86D2"
|
||||
}
|
||||
},
|
||||
"uuid": "d0d593b5-4fec-4e00-97cb-0be87dcf3a65",
|
||||
"persistent": true,
|
||||
"insertionIndex": 4
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"id": "8e2e62e2-56b6-469c-8f6a-77ba40fc9494",
|
||||
"name": "organizations_7544739_team_3451996_discussions_64",
|
||||
"request": {
|
||||
"url": "/organizations/7544739/team/3451996/discussions/64",
|
||||
"method": "PATCH",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"title\":\"Title updated\",\"body\":\"This is a test discussion updated\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "organizations_7544739_team_3451996_discussions_64-10.json",
|
||||
"headers": {
|
||||
"Date": "Mon, 08 Jun 2020 18:43:33 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4951",
|
||||
"X-RateLimit-Reset": "1591642579",
|
||||
"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/\"0e132309e9aca4393134aa70e222cef9\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "write:discussion",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "E996:682F:301CD8:39F070:5EDE86D4"
|
||||
}
|
||||
},
|
||||
"uuid": "8e2e62e2-56b6-469c-8f6a-77ba40fc9494",
|
||||
"persistent": true,
|
||||
"insertionIndex": 10
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"id": "188c7eef-a962-41af-81be-bb487e44add2",
|
||||
"name": "organizations_7544739_team_3451996_discussions_64",
|
||||
"request": {
|
||||
"url": "/organizations/7544739/team/3451996/discussions/64",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "organizations_7544739_team_3451996_discussions_64-5.json",
|
||||
"headers": {
|
||||
"Date": "Mon, 08 Jun 2020 18:43:31 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4956",
|
||||
"X-RateLimit-Reset": "1591642579",
|
||||
"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/\"fa7ed609b5bcd7cbba13e22df861b688\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "read:discussion, write:discussion",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "E996:682F:301CC2:39F057:5EDE86D3"
|
||||
}
|
||||
},
|
||||
"uuid": "188c7eef-a962-41af-81be-bb487e44add2",
|
||||
"persistent": true,
|
||||
"scenarioName": "scenario-2-organizations-7544739-team-3451996-discussions-64",
|
||||
"requiredScenarioState": "Started",
|
||||
"newScenarioState": "scenario-2-organizations-7544739-team-3451996-discussions-64-2",
|
||||
"insertionIndex": 5
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"id": "faec08a3-a746-45c3-ac33-52d830e37854",
|
||||
"name": "organizations_7544739_team_3451996_discussions_64",
|
||||
"request": {
|
||||
"url": "/organizations/7544739/team/3451996/discussions/64",
|
||||
"method": "PATCH",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"title\":\"Some Discussion\",\"body\":\"This is a test discussion changed\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "organizations_7544739_team_3451996_discussions_64-6.json",
|
||||
"headers": {
|
||||
"Date": "Mon, 08 Jun 2020 18:43:31 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4955",
|
||||
"X-RateLimit-Reset": "1591642578",
|
||||
"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/\"e8f61210b01e7faca044ff4ab01e37c7\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "write:discussion",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "E996:682F:301CC5:39F05B:5EDE86D3"
|
||||
}
|
||||
},
|
||||
"uuid": "faec08a3-a746-45c3-ac33-52d830e37854",
|
||||
"persistent": true,
|
||||
"insertionIndex": 6
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"id": "429533ef-462c-4582-a484-dadcc6c6200c",
|
||||
"name": "organizations_7544739_team_3451996_discussions_64",
|
||||
"request": {
|
||||
"url": "/organizations/7544739/team/3451996/discussions/64",
|
||||
"method": "PATCH",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"title\":\"Title changed\",\"body\":\"This is a test discussion changed\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "organizations_7544739_team_3451996_discussions_64-7.json",
|
||||
"headers": {
|
||||
"Date": "Mon, 08 Jun 2020 18:43:32 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4954",
|
||||
"X-RateLimit-Reset": "1591642579",
|
||||
"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/\"b6481a9983d068bb81f4e85ad321ddd7\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "write:discussion",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "E996:682F:301CCD:39F063:5EDE86D3"
|
||||
}
|
||||
},
|
||||
"uuid": "429533ef-462c-4582-a484-dadcc6c6200c",
|
||||
"persistent": true,
|
||||
"insertionIndex": 7
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"id": "a257d38b-10a3-4d97-a891-8f0772867cfc",
|
||||
"name": "organizations_7544739_team_3451996_discussions_64",
|
||||
"request": {
|
||||
"url": "/organizations/7544739/team/3451996/discussions/64",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "organizations_7544739_team_3451996_discussions_64-9.json",
|
||||
"headers": {
|
||||
"Date": "Mon, 08 Jun 2020 18:43:32 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4952",
|
||||
"X-RateLimit-Reset": "1591642578",
|
||||
"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/\"b6481a9983d068bb81f4e85ad321ddd7\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "read:discussion, write:discussion",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "E996:682F:301CD4:39F06C:5EDE86D4"
|
||||
}
|
||||
},
|
||||
"uuid": "a257d38b-10a3-4d97-a891-8f0772867cfc",
|
||||
"persistent": true,
|
||||
"scenarioName": "scenario-2-organizations-7544739-team-3451996-discussions-64",
|
||||
"requiredScenarioState": "scenario-2-organizations-7544739-team-3451996-discussions-64-2",
|
||||
"insertionIndex": 9
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"id": "bfb96aef-cd13-4870-8345-c2365a5a7feb",
|
||||
"name": "orgs_hub4j-test-org",
|
||||
"request": {
|
||||
"url": "/orgs/hub4j-test-org",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "orgs_hub4j-test-org-2.json",
|
||||
"headers": {
|
||||
"Date": "Mon, 08 Jun 2020 18:43:30 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4959",
|
||||
"X-RateLimit-Reset": "1591642579",
|
||||
"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/\"0557d9126fa25140eab7bdf16c451149\"",
|
||||
"Last-Modified": "Thu, 04 Jun 2020 05:56:10 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "admin:org, read:org, repo, user, write:org",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "E996:682F:301CB4:39F042:5EDE86D1"
|
||||
}
|
||||
},
|
||||
"uuid": "bfb96aef-cd13-4870-8345-c2365a5a7feb",
|
||||
"persistent": true,
|
||||
"insertionIndex": 2
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"id": "9e604f25-f6e6-4a1a-992f-c9aa8bb6d325",
|
||||
"name": "orgs_hub4j-test-org_teams_dummy-team",
|
||||
"request": {
|
||||
"url": "/orgs/hub4j-test-org/teams/dummy-team",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "orgs_hub4j-test-org_teams_dummy-team-3.json",
|
||||
"headers": {
|
||||
"Date": "Mon, 08 Jun 2020 18:43:30 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4958",
|
||||
"X-RateLimit-Reset": "1591642579",
|
||||
"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/\"adf552e4a615c271e66b7d2bb00e61c4\"",
|
||||
"Last-Modified": "Tue, 02 Jun 2020 19:31:50 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "admin:org, read:org, repo, user, write:org",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "E996:682F:301CB8:39F04B:5EDE86D2"
|
||||
}
|
||||
},
|
||||
"uuid": "9e604f25-f6e6-4a1a-992f-c9aa8bb6d325",
|
||||
"persistent": true,
|
||||
"scenarioName": "scenario-1-orgs-hub4j-test-org-teams-dummy-team",
|
||||
"requiredScenarioState": "Started",
|
||||
"newScenarioState": "scenario-1-orgs-hub4j-test-org-teams-dummy-team-2",
|
||||
"insertionIndex": 3
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"id": "b0e9b0f2-422d-4dad-b1a6-1664b039b1f1",
|
||||
"name": "orgs_hub4j-test-org_teams_dummy-team",
|
||||
"request": {
|
||||
"url": "/orgs/hub4j-test-org/teams/dummy-team",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "orgs_hub4j-test-org_teams_dummy-team-8.json",
|
||||
"headers": {
|
||||
"Date": "Mon, 08 Jun 2020 18:43:32 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4953",
|
||||
"X-RateLimit-Reset": "1591642579",
|
||||
"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/\"adf552e4a615c271e66b7d2bb00e61c4\"",
|
||||
"Last-Modified": "Tue, 02 Jun 2020 19:31:50 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "admin:org, read:org, repo, user, write:org",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "E996:682F:301CD2:39F069:5EDE86D4"
|
||||
}
|
||||
},
|
||||
"uuid": "b0e9b0f2-422d-4dad-b1a6-1664b039b1f1",
|
||||
"persistent": true,
|
||||
"scenarioName": "scenario-1-orgs-hub4j-test-org-teams-dummy-team",
|
||||
"requiredScenarioState": "scenario-1-orgs-hub4j-test-org-teams-dummy-team-2",
|
||||
"insertionIndex": 8
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"id": "54a33589-feb1-45e9-b794-967a6d3f5f30",
|
||||
"name": "user",
|
||||
"request": {
|
||||
"url": "/user",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "user-1.json",
|
||||
"headers": {
|
||||
"Date": "Mon, 08 Jun 2020 18:43:29 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4961",
|
||||
"X-RateLimit-Reset": "1591642578",
|
||||
"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/\"7e41c6c634de27b9ab8f4e95a42d16db\"",
|
||||
"Last-Modified": "Fri, 29 May 2020 18:24:44 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "E996:682F:301CAE:39F040:5EDE86D1"
|
||||
}
|
||||
},
|
||||
"uuid": "54a33589-feb1-45e9-b794-967a6d3f5f30",
|
||||
"persistent": true,
|
||||
"insertionIndex": 1
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"author": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"body": "This is a test discussion",
|
||||
"body_html": "<p>This is a test discussion</p>",
|
||||
"body_version": "db8c6cacef3d11b326f87a5f9f7a2df0",
|
||||
"comments_count": 0,
|
||||
"comments_url": "https://api.github.com/organizations/7544739/team/3451996/discussions/61/comments",
|
||||
"created_at": "2020-06-05T23:08:34Z",
|
||||
"last_edited_at": null,
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team/discussions/61",
|
||||
"node_id": "MDE0OlRlYW1EaXNjdXNzaW9uMTE3ODUy",
|
||||
"number": 61,
|
||||
"pinned": false,
|
||||
"private": false,
|
||||
"team_url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"title": "Some Discussion A",
|
||||
"updated_at": "2020-06-05T23:08:34Z",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996/discussions/61"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"author": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"body": "This is a test discussion",
|
||||
"body_html": "<p>This is a test discussion</p>",
|
||||
"body_version": "db8c6cacef3d11b326f87a5f9f7a2df0",
|
||||
"comments_count": 0,
|
||||
"comments_url": "https://api.github.com/organizations/7544739/team/3451996/discussions/62/comments",
|
||||
"created_at": "2020-06-05T23:08:35Z",
|
||||
"last_edited_at": null,
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team/discussions/62",
|
||||
"node_id": "MDE0OlRlYW1EaXNjdXNzaW9uMTE3ODUz",
|
||||
"number": 62,
|
||||
"pinned": false,
|
||||
"private": false,
|
||||
"team_url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"title": "Some Discussion B",
|
||||
"updated_at": "2020-06-05T23:08:35Z",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996/discussions/62"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"author": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"body": "This is a test discussion",
|
||||
"body_html": "<p>This is a test discussion</p>",
|
||||
"body_version": "db8c6cacef3d11b326f87a5f9f7a2df0",
|
||||
"comments_count": 0,
|
||||
"comments_url": "https://api.github.com/organizations/7544739/team/3451996/discussions/63/comments",
|
||||
"created_at": "2020-06-05T23:08:35Z",
|
||||
"last_edited_at": null,
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team/discussions/63",
|
||||
"node_id": "MDE0OlRlYW1EaXNjdXNzaW9uMTE3ODU0",
|
||||
"number": 63,
|
||||
"pinned": false,
|
||||
"private": false,
|
||||
"team_url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"title": "Some Discussion C",
|
||||
"updated_at": "2020-06-05T23:08:35Z",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996/discussions/63"
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
[
|
||||
{
|
||||
"author": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"body": "This is a test discussion",
|
||||
"body_html": "<p>This is a test discussion</p>",
|
||||
"body_version": "db8c6cacef3d11b326f87a5f9f7a2df0",
|
||||
"comments_count": 0,
|
||||
"comments_url": "https://api.github.com/organizations/7544739/team/3451996/discussions/63/comments",
|
||||
"created_at": "2020-06-05T23:08:35Z",
|
||||
"last_edited_at": null,
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team/discussions/63",
|
||||
"node_id": "MDE0OlRlYW1EaXNjdXNzaW9uMTE3ODU0",
|
||||
"number": 63,
|
||||
"pinned": false,
|
||||
"private": false,
|
||||
"team_url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"title": "Some Discussion C",
|
||||
"updated_at": "2020-06-05T23:08:35Z",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996/discussions/63"
|
||||
},
|
||||
{
|
||||
"author": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"body": "This is a test discussion",
|
||||
"body_html": "<p>This is a test discussion</p>",
|
||||
"body_version": "db8c6cacef3d11b326f87a5f9f7a2df0",
|
||||
"comments_count": 0,
|
||||
"comments_url": "https://api.github.com/organizations/7544739/team/3451996/discussions/62/comments",
|
||||
"created_at": "2020-06-05T23:08:35Z",
|
||||
"last_edited_at": null,
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team/discussions/62",
|
||||
"node_id": "MDE0OlRlYW1EaXNjdXNzaW9uMTE3ODUz",
|
||||
"number": 62,
|
||||
"pinned": false,
|
||||
"private": false,
|
||||
"team_url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"title": "Some Discussion B",
|
||||
"updated_at": "2020-06-05T23:08:35Z",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996/discussions/62"
|
||||
},
|
||||
{
|
||||
"author": {
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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
|
||||
},
|
||||
"body": "This is a test discussion",
|
||||
"body_html": "<p>This is a test discussion</p>",
|
||||
"body_version": "db8c6cacef3d11b326f87a5f9f7a2df0",
|
||||
"comments_count": 0,
|
||||
"comments_url": "https://api.github.com/organizations/7544739/team/3451996/discussions/61/comments",
|
||||
"created_at": "2020-06-05T23:08:34Z",
|
||||
"last_edited_at": null,
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team/discussions/61",
|
||||
"node_id": "MDE0OlRlYW1EaXNjdXNzaW9uMTE3ODUy",
|
||||
"number": 61,
|
||||
"pinned": false,
|
||||
"private": false,
|
||||
"team_url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"title": "Some Discussion A",
|
||||
"updated_at": "2020-06-05T23:08:34Z",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996/discussions/61"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"login": "hub4j-test-org",
|
||||
"id": 7544739,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
|
||||
"url": "https://api.github.com/orgs/hub4j-test-org",
|
||||
"repos_url": "https://api.github.com/orgs/hub4j-test-org/repos",
|
||||
"events_url": "https://api.github.com/orgs/hub4j-test-org/events",
|
||||
"hooks_url": "https://api.github.com/orgs/hub4j-test-org/hooks",
|
||||
"issues_url": "https://api.github.com/orgs/hub4j-test-org/issues",
|
||||
"members_url": "https://api.github.com/orgs/hub4j-test-org/members{/member}",
|
||||
"public_members_url": "https://api.github.com/orgs/hub4j-test-org/public_members{/member}",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
|
||||
"description": "Hub4j Test Org Description (this could be null or blank too)",
|
||||
"name": "Hub4j Test Org Name (this could be null or blank too)",
|
||||
"company": null,
|
||||
"blog": "https://hub4j.url.io/could/be/null",
|
||||
"location": "Hub4j Test Org Location (this could be null or blank too)",
|
||||
"email": "hub4jtestorgemail@could.be.null.com",
|
||||
"twitter_username": null,
|
||||
"is_verified": false,
|
||||
"has_organization_projects": true,
|
||||
"has_repository_projects": true,
|
||||
"public_repos": 15,
|
||||
"public_gists": 0,
|
||||
"followers": 0,
|
||||
"following": 0,
|
||||
"html_url": "https://github.com/hub4j-test-org",
|
||||
"created_at": "2014-05-10T19:39:11Z",
|
||||
"updated_at": "2020-06-04T05:56:10Z",
|
||||
"type": "Organization",
|
||||
"total_private_repos": 0,
|
||||
"owned_private_repos": 0,
|
||||
"private_gists": 0,
|
||||
"disk_usage": 148,
|
||||
"collaborators": 0,
|
||||
"billing_email": "kk@kohsuke.org",
|
||||
"default_repository_permission": "none",
|
||||
"members_can_create_repositories": false,
|
||||
"two_factor_requirement_enabled": false,
|
||||
"plan": {
|
||||
"name": "free",
|
||||
"space": 976562499,
|
||||
"private_repos": 10000,
|
||||
"filled_seats": 18,
|
||||
"seats": 3
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "dummy-team",
|
||||
"id": 3451996,
|
||||
"node_id": "MDQ6VGVhbTM0NTE5OTY=",
|
||||
"slug": "dummy-team",
|
||||
"description": "Updated by API TestModified",
|
||||
"privacy": "closed",
|
||||
"url": "https://api.github.com/organizations/7544739/team/3451996",
|
||||
"html_url": "https://github.com/orgs/hub4j-test-org/teams/dummy-team",
|
||||
"members_url": "https://api.github.com/organizations/7544739/team/3451996/members{/member}",
|
||||
"repositories_url": "https://api.github.com/organizations/7544739/team/3451996/repos",
|
||||
"permission": "pull",
|
||||
"created_at": "2019-10-03T21:46:12Z",
|
||||
"updated_at": "2020-06-02T19:31:50Z",
|
||||
"members_count": 1,
|
||||
"repos_count": 1,
|
||||
"organization": {
|
||||
"login": "hub4j-test-org",
|
||||
"id": 7544739,
|
||||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
|
||||
"url": "https://api.github.com/orgs/hub4j-test-org",
|
||||
"repos_url": "https://api.github.com/orgs/hub4j-test-org/repos",
|
||||
"events_url": "https://api.github.com/orgs/hub4j-test-org/events",
|
||||
"hooks_url": "https://api.github.com/orgs/hub4j-test-org/hooks",
|
||||
"issues_url": "https://api.github.com/orgs/hub4j-test-org/issues",
|
||||
"members_url": "https://api.github.com/orgs/hub4j-test-org/members{/member}",
|
||||
"public_members_url": "https://api.github.com/orgs/hub4j-test-org/public_members{/member}",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
|
||||
"description": "Hub4j Test Org Description (this could be null or blank too)",
|
||||
"name": "Hub4j Test Org Name (this could be null or blank too)",
|
||||
"company": null,
|
||||
"blog": "https://hub4j.url.io/could/be/null",
|
||||
"location": "Hub4j Test Org Location (this could be null or blank too)",
|
||||
"email": "hub4jtestorgemail@could.be.null.com",
|
||||
"twitter_username": null,
|
||||
"is_verified": false,
|
||||
"has_organization_projects": true,
|
||||
"has_repository_projects": true,
|
||||
"public_repos": 15,
|
||||
"public_gists": 0,
|
||||
"followers": 0,
|
||||
"following": 0,
|
||||
"html_url": "https://github.com/hub4j-test-org",
|
||||
"created_at": "2014-05-10T19:39:11Z",
|
||||
"updated_at": "2020-06-04T05:56:10Z",
|
||||
"type": "Organization"
|
||||
},
|
||||
"parent": null
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"login": "bitwiseman",
|
||||
"id": 1958953,
|
||||
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
|
||||
"avatar_url": "https://avatars3.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": "https://twitter.com/bitwiseman",
|
||||
"twitter_username": null,
|
||||
"public_repos": 187,
|
||||
"public_gists": 7,
|
||||
"followers": 161,
|
||||
"following": 9,
|
||||
"created_at": "2012-07-11T20:38:33Z",
|
||||
"updated_at": "2020-05-29T18:24:44Z",
|
||||
"private_gists": 19,
|
||||
"total_private_repos": 12,
|
||||
"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,54 @@
|
||||
{
|
||||
"id": "a9fb558a-d4d8-4bdc-90c6-0c69cf0cccab",
|
||||
"name": "organizations_7544739_team_3451996_discussions",
|
||||
"request": {
|
||||
"url": "/organizations/7544739/team/3451996/discussions",
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"title\":\"Some Discussion A\",\"body\":\"This is a test discussion\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 201,
|
||||
"bodyFileName": "organizations_7544739_team_3451996_discussions-4.json",
|
||||
"headers": {
|
||||
"Date": "Fri, 05 Jun 2020 23:08:34 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "201 Created",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4726",
|
||||
"X-RateLimit-Reset": "1591398936",
|
||||
"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": "\"fda6ea6059960017264945de79550718\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "write:discussion",
|
||||
"Location": "https://api.github.com/organizations/7544739/team/3451996/discussions/61",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "CFFB:979C:1DBF93:23C47C:5EDAD072"
|
||||
}
|
||||
},
|
||||
"uuid": "a9fb558a-d4d8-4bdc-90c6-0c69cf0cccab",
|
||||
"persistent": true,
|
||||
"insertionIndex": 4
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"id": "8122b2d7-fb10-4a80-9c90-603a0331c40c",
|
||||
"name": "organizations_7544739_team_3451996_discussions",
|
||||
"request": {
|
||||
"url": "/organizations/7544739/team/3451996/discussions",
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"title\":\"Some Discussion B\",\"body\":\"This is a test discussion\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 201,
|
||||
"bodyFileName": "organizations_7544739_team_3451996_discussions-5.json",
|
||||
"headers": {
|
||||
"Date": "Fri, 05 Jun 2020 23:08:35 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "201 Created",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4725",
|
||||
"X-RateLimit-Reset": "1591398936",
|
||||
"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": "\"4acb1681262e9f89b5516ad5d804aee4\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "write:discussion",
|
||||
"Location": "https://api.github.com/organizations/7544739/team/3451996/discussions/62",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "CFFB:979C:1DBF96:23C482:5EDAD072"
|
||||
}
|
||||
},
|
||||
"uuid": "8122b2d7-fb10-4a80-9c90-603a0331c40c",
|
||||
"persistent": true,
|
||||
"insertionIndex": 5
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"id": "bb49da5d-06ed-4e5a-8df8-45b8c68f723e",
|
||||
"name": "organizations_7544739_team_3451996_discussions",
|
||||
"request": {
|
||||
"url": "/organizations/7544739/team/3451996/discussions",
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": "{\"title\":\"Some Discussion C\",\"body\":\"This is a test discussion\"}",
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 201,
|
||||
"bodyFileName": "organizations_7544739_team_3451996_discussions-6.json",
|
||||
"headers": {
|
||||
"Date": "Fri, 05 Jun 2020 23:08:35 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "201 Created",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4724",
|
||||
"X-RateLimit-Reset": "1591398936",
|
||||
"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": "\"c8879f78bca38d17e39a60ce77710200\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "write:discussion",
|
||||
"Location": "https://api.github.com/organizations/7544739/team/3451996/discussions/63",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "CFFB:979C:1DBF99:23C484:5EDAD073"
|
||||
}
|
||||
},
|
||||
"uuid": "bb49da5d-06ed-4e5a-8df8-45b8c68f723e",
|
||||
"persistent": true,
|
||||
"insertionIndex": 6
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"id": "2b24a93c-7d7e-481e-a3fd-681ff45d09e2",
|
||||
"name": "organizations_7544739_team_3451996_discussions",
|
||||
"request": {
|
||||
"url": "/organizations/7544739/team/3451996/discussions",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "organizations_7544739_team_3451996_discussions-7.json",
|
||||
"headers": {
|
||||
"Date": "Fri, 05 Jun 2020 23:08:35 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4723",
|
||||
"X-RateLimit-Reset": "1591398935",
|
||||
"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/\"06cde48be7ded909e2643d7c62bc1b40\"",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "read:discussion, write:discussion",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "CFFB:979C:1DBF9D:23C489:5EDAD073"
|
||||
}
|
||||
},
|
||||
"uuid": "2b24a93c-7d7e-481e-a3fd-681ff45d09e2",
|
||||
"persistent": true,
|
||||
"insertionIndex": 7
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"id": "0deb7fe4-0390-4fff-a7b3-64ec28d47535",
|
||||
"name": "orgs_hub4j-test-org",
|
||||
"request": {
|
||||
"url": "/orgs/hub4j-test-org",
|
||||
"method": "GET",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"bodyFileName": "orgs_hub4j-test-org-2.json",
|
||||
"headers": {
|
||||
"Date": "Fri, 05 Jun 2020 23:08:34 GMT",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Server": "GitHub.com",
|
||||
"Status": "200 OK",
|
||||
"X-RateLimit-Limit": "5000",
|
||||
"X-RateLimit-Remaining": "4728",
|
||||
"X-RateLimit-Reset": "1591398936",
|
||||
"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/\"0557d9126fa25140eab7bdf16c451149\"",
|
||||
"Last-Modified": "Thu, 04 Jun 2020 05:56:10 GMT",
|
||||
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
|
||||
"X-Accepted-OAuth-Scopes": "admin:org, read:org, repo, user, write:org",
|
||||
"X-GitHub-Media-Type": "unknown, github.v3",
|
||||
"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": "CFFB:979C:1DBF8B:23C473:5EDAD072"
|
||||
}
|
||||
},
|
||||
"uuid": "0deb7fe4-0390-4fff-a7b3-64ec28d47535",
|
||||
"persistent": true,
|
||||
"insertionIndex": 2
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user