Merge remote-tracking branch 'upstream/master' into download-repository-archives

This commit is contained in:
Liam Newman
2021-02-11 17:12:11 -08:00
325 changed files with 50554 additions and 2448 deletions

64
pom.xml
View File

@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.kohsuke</groupId>
<artifactId>github-api</artifactId>
<version>1.119-SNAPSHOT</version>
<version>1.123-SNAPSHOT</version>
<name>GitHub API for Java</name>
<url>https://github-api.kohsuke.org/</url>
<description>GitHub API for Java</description>
@@ -33,7 +33,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spotbugs-maven-plugin.version>4.1.4</spotbugs-maven-plugin.version>
<spotbugs-maven-plugin.version>4.2.0</spotbugs-maven-plugin.version>
<spotbugs.version>4.1.3</spotbugs.version>
<spotbugs-maven-plugin.failOnError>true</spotbugs-maven-plugin.failOnError>
<hamcrest.version>2.2</hamcrest.version>
@@ -41,10 +41,11 @@
<okio.version>2.5.0</okio.version>
<spotless-maven-plugin.goal>apply</spotless-maven-plugin.goal>
<!-- Using this as the minimum bar for code coverage. Adding methods without covering them will fail this. -->
<jacoco.coverage.target.bundle.method>0.60</jacoco.coverage.target.bundle.method>
<jacoco.coverage.target.class.method>0.25</jacoco.coverage.target.class.method>
<jacoco.coverage.target.bundle.method>0.70</jacoco.coverage.target.bundle.method>
<jacoco.coverage.target.class.method>0.50</jacoco.coverage.target.class.method>
<!-- For non-ci builds we'd like the build to still complete if jacoco metrics aren't met. -->
<jacoco.haltOnFailure>false</jacoco.haltOnFailure>
<jjwt.suite.version>0.11.2</jjwt.suite.version>
</properties>
<build>
@@ -152,59 +153,39 @@
<!-- Sample only -->
<exclude>org.kohsuke.github.example.*</exclude>
<!-- No methods -->
<exclude>org.kohsuke.github.Previews</exclude>
<!-- Deprecated -->
<exclude>org.kohsuke.github.extras.OkHttp3Connector</exclude>
<exclude>org.kohsuke.github.EnforcementLevel</exclude>
<exclude>org.kohsuke.github.GHPerson.1</exclude>
<!-- These fail coverage on windows because tests are disabled -->
<exclude>org.kohsuke.github.GHAsset</exclude>
<exclude>org.kohsuke.github.GHReleaseBuilder</exclude>
<exclude>org.kohsuke.github.GHRelease</exclude>
<!-- TODO: Some coverage, but more needed -->
<exclude>org.kohsuke.github.GHPullRequestReviewBuilder.DraftReviewComment</exclude>
<exclude>org.kohsuke.github.GHIssue.PullRequest</exclude>
<exclude>org.kohsuke.github.GHCommitSearchBuilder</exclude>
<exclude>org.kohsuke.github.GHRepositorySearchBuilder</exclude>
<exclude>org.kohsuke.github.GHUserSearchBuilder</exclude>
<!-- TODO: These still need test coverage -->
<exclude>org.kohsuke.github.GHBranchProtection.RequiredSignatures</exclude>
<exclude>org.kohsuke.github.GHBranchProtectionBuilder.Restrictions</exclude>
<exclude>org.kohsuke.github.GHBranchProtection.Restrictions</exclude>
<exclude>org.kohsuke.github.GHCommentAuthorAssociation</exclude>
<exclude>org.kohsuke.github.GHCommitBuilder.UserInfo</exclude>
<exclude>org.kohsuke.github.GHCommitState</exclude>
<exclude>org.kohsuke.github.GHCompare.Commit</exclude>
<exclude>org.kohsuke.github.GHCompare.InnerCommit</exclude>
<exclude>org.kohsuke.github.GHCompare.Status</exclude>
<exclude>org.kohsuke.github.GHCompare.Tree</exclude>
<exclude>org.kohsuke.github.GHCompare.User</exclude>
<exclude>org.kohsuke.github.GHCompare</exclude>
<exclude>org.kohsuke.github.GHDeployKey</exclude>
<exclude>org.kohsuke.github.GHDeploymentStatusBuilder</exclude>
<exclude>org.kohsuke.github.GHDirection</exclude>
<exclude>org.kohsuke.github.GHEmail</exclude>
<exclude>org.kohsuke.github.GHEventPayload.Ping</exclude>
<exclude>org.kohsuke.github.GHEventPayload.Release</exclude>
<exclude>org.kohsuke.github.GHException</exclude>
<exclude>org.kohsuke.github.GHHook</exclude>
<exclude>org.kohsuke.github.GHHooks.OrgContext</exclude>
<exclude>org.kohsuke.github.GHInvitation</exclude>
<exclude>org.kohsuke.github.GHMilestoneState</exclude>
<exclude>org.kohsuke.github.GHOrgHook</exclude>
<exclude>org.kohsuke.github.GHProject.ProjectStateFilter</exclude>
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.Authorship</exclude>
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.Commit</exclude>
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.CommitPointer</exclude>
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.Tree</exclude>
<exclude>org.kohsuke.github.GHPullRequestCommitDetail</exclude>
<exclude>org.kohsuke.github.GHPullRequestFileDetail</exclude>
<exclude>org.kohsuke.github.GHPullRequestQueryBuilder.Sort</exclude>
<exclude>org.kohsuke.github.GHReleaseUpdater</exclude>
<exclude>org.kohsuke.github.GHRepository.ForkSort</exclude>
<exclude>org.kohsuke.github.GHRequestedAction</exclude>
<exclude>org.kohsuke.github.GHStargazer</exclude>
<exclude>org.kohsuke.github.GHTagObject</exclude>
<exclude>org.kohsuke.github.GHTeam.Role</exclude>
<exclude>org.kohsuke.github.GHUserSearchBuilder.Sort</exclude>
<exclude>org.kohsuke.github.GHVerifiedKey</exclude>
</excludes>
</rule>
@@ -344,7 +325,7 @@
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>2.6.1</version>
<version>2.7.0</version>
<executions>
<execution>
<id>spotless-check</id>
@@ -409,7 +390,7 @@
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit</artifactId>
<version>0.15.0</version>
<version>0.16.0</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -489,20 +470,20 @@
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
<scope>test</scope>
<version>${jjwt.suite.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
<scope>test</scope>
<version>${jjwt.suite.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.2</version>
<scope>test</scope>
<version>${jjwt.suite.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.squareup.okio</groupId>
@@ -539,7 +520,7 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.6.28</version>
<version>3.7.7</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -591,6 +572,8 @@
</os>
</activation>
<properties>
<!-- Only fail code coverage on non-windows machines -->
<jacoco.haltOnFailure>true</jacoco.haltOnFailure>
<spotless-maven-plugin.goal>check</spotless-maven-plugin.goal>
</properties>
</profile>
@@ -601,9 +584,6 @@
<name>enable-ci</name>
</property>
</activation>
<properties>
<jacoco.haltOnFailure>true</jacoco.haltOnFailure>
</properties>
<build>
<plugins>
<plugin>

View File

@@ -5,7 +5,7 @@ import java.net.URL;
import java.util.List;
import java.util.Map;
import static org.kohsuke.github.Previews.MACHINE_MAN;
import static org.kohsuke.github.internal.Previews.MACHINE_MAN;
/**
* A Github App.

View File

@@ -5,7 +5,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.kohsuke.github.Previews.MACHINE_MAN;
import static org.kohsuke.github.internal.Previews.MACHINE_MAN;
/**
* Creates a access token for a GitHub App Installation

View File

@@ -8,8 +8,8 @@ import java.net.URL;
import java.util.List;
import java.util.Map;
import static org.kohsuke.github.Previews.GAMBIT;
import static org.kohsuke.github.Previews.MACHINE_MAN;
import static org.kohsuke.github.internal.Previews.GAMBIT;
import static org.kohsuke.github.internal.Previews.MACHINE_MAN;
/**
* A Github App Installation.

View File

@@ -3,6 +3,7 @@ package org.kohsuke.github;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.kohsuke.github.internal.Previews;
import java.io.IOException;
import java.net.URL;

View File

@@ -6,7 +6,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.IOException;
import java.util.Collection;
import static org.kohsuke.github.Previews.ZZZAX;
import static org.kohsuke.github.internal.Previews.ZZZAX;
/**
* The type GHBranchProtection.

View File

@@ -12,7 +12,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.kohsuke.github.Previews.*;
import static org.kohsuke.github.internal.Previews.LUKE_CAGE;
/**
* Builder to configure the branch protection settings.

View File

@@ -3,6 +3,7 @@ package org.kohsuke.github;
import com.fasterxml.jackson.annotation.JsonProperty;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.kohsuke.github.internal.Previews;
import java.io.IOException;
import java.net.URL;

View File

@@ -28,6 +28,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.kohsuke.github.internal.Previews;
import java.io.IOException;
import java.util.Collections;
@@ -151,7 +152,7 @@ public final class GHCheckRunBuilder {
}
GHCheckRun run = requester.with("output", output).with("actions", actions).fetch(GHCheckRun.class).wrap(repo);
while (!extraAnnotations.isEmpty()) {
Output output2 = new Output(output.title, output.summary);
Output output2 = new Output(output.title, output.summary).withText(output.text);
int i = Math.min(extraAnnotations.size(), MAX_ANNOTATIONS);
output2.annotations = extraAnnotations.subList(0, i);
extraAnnotations = extraAnnotations.subList(i, extraAnnotations.size());

View File

@@ -11,8 +11,8 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
import static org.kohsuke.github.Previews.ANTIOPE;
import static org.kohsuke.github.Previews.GROOT;
import static org.kohsuke.github.internal.Previews.ANTIOPE;
import static org.kohsuke.github.internal.Previews.GROOT;
/**
* A commit in a repository.

View File

@@ -5,7 +5,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.IOException;
import java.net.URL;
import static org.kohsuke.github.Previews.*;
import static org.kohsuke.github.internal.Previews.SQUIRREL_GIRL;
/**
* A comment attached to a commit (or a specific line in a specific file of a commit.)

View File

@@ -1,6 +1,7 @@
package org.kohsuke.github;
import org.apache.commons.lang3.StringUtils;
import org.kohsuke.github.internal.Previews;
import java.io.IOException;

View File

@@ -2,7 +2,7 @@ package org.kohsuke.github;
import java.io.IOException;
import static org.kohsuke.github.Previews.BAPTISTE;
import static org.kohsuke.github.internal.Previews.BAPTISTE;
/**
* Creates a repository

View File

@@ -1,5 +1,7 @@
package org.kohsuke.github;
import org.kohsuke.github.internal.Previews;
import java.io.IOException;
import java.net.URL;
import java.util.Map;

View File

@@ -1,5 +1,7 @@
package org.kohsuke.github;
import org.kohsuke.github.internal.Previews;
import java.io.IOException;
import java.util.List;

View File

@@ -1,5 +1,7 @@
package org.kohsuke.github;
import org.kohsuke.github.internal.Previews;
/**
* Represents the state of deployment
*/

View File

@@ -1,5 +1,7 @@
package org.kohsuke.github;
import org.kohsuke.github.internal.Previews;
import java.net.URL;
import java.util.Locale;

View File

@@ -1,5 +1,7 @@
package org.kohsuke.github;
import org.kohsuke.github.internal.Previews;
import java.io.IOException;
/**

View File

@@ -1,6 +1,7 @@
package org.kohsuke.github;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.kohsuke.github.internal.Previews;
import java.io.IOException;
import java.net.URL;

View File

@@ -12,6 +12,7 @@ import java.util.Locale;
public enum GHEvent {
CHECK_RUN,
CHECK_SUITE,
CODE_SCANNING_ALERT,
COMMIT_COMMENT,
CONTENT_REFERENCE,
CREATE,

View File

@@ -5,6 +5,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.IOException;
import java.io.Reader;
import java.util.Date;
import java.util.List;
/**
@@ -1067,7 +1068,7 @@ public class GHEventPayload extends GitHubInteractiveObject {
public static class PushCommit {
private GitUser author;
private GitUser committer;
private String url, sha, message;
private String url, sha, message, timestamp;
private boolean distinct;
private List<String> added, removed, modified;
@@ -1156,6 +1157,15 @@ public class GHEventPayload extends GitHubInteractiveObject {
public List<String> getModified() {
return modified;
}
/**
* Obtains the timestamp of the commit
*
* @return the timestamp
*/
public Date getTimestamp() {
return GitHubClient.parseDate(timestamp);
}
}
}

View File

@@ -39,7 +39,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Objects;
import static org.kohsuke.github.Previews.SQUIRREL_GIRL;
import static org.kohsuke.github.internal.Previews.SQUIRREL_GIRL;
/**
* Represents an issue on GitHub.

View File

@@ -26,7 +26,7 @@ package org.kohsuke.github;
import java.io.IOException;
import java.net.URL;
import static org.kohsuke.github.Previews.*;
import static org.kohsuke.github.internal.Previews.SQUIRREL_GIRL;
/**
* Comment to the issue

View File

@@ -10,7 +10,7 @@ import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import static org.kohsuke.github.Previews.INERTIA;
import static org.kohsuke.github.internal.Previews.INERTIA;
/**
* The type GHOrganization.

View File

@@ -28,7 +28,7 @@ import java.io.IOException;
import java.net.URL;
import java.util.Locale;
import static org.kohsuke.github.Previews.INERTIA;
import static org.kohsuke.github.internal.Previews.INERTIA;
/**
* A GitHub project.

View File

@@ -6,7 +6,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import static org.kohsuke.github.Previews.INERTIA;
import static org.kohsuke.github.internal.Previews.INERTIA;
/**
* The type GHProjectCard.

View File

@@ -4,7 +4,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import static org.kohsuke.github.Previews.INERTIA;
import static org.kohsuke.github.internal.Previews.INERTIA;
/**
* The type GHProjectColumn.

View File

@@ -36,8 +36,8 @@ import java.util.Objects;
import javax.annotation.CheckForNull;
import static org.kohsuke.github.Previews.LYDIAN;
import static org.kohsuke.github.Previews.SHADOW_CAT;
import static org.kohsuke.github.internal.Previews.LYDIAN;
import static org.kohsuke.github.internal.Previews.SHADOW_CAT;
/**
* A pull request.

View File

@@ -1,6 +1,6 @@
package org.kohsuke.github;
import static org.kohsuke.github.Previews.SHADOW_CAT;
import static org.kohsuke.github.internal.Previews.SHADOW_CAT;
/**
* Lists up pull requests with some filtering and sorting.

View File

@@ -28,7 +28,7 @@ import java.net.URL;
import javax.annotation.CheckForNull;
import static org.kohsuke.github.Previews.*;
import static org.kohsuke.github.internal.Previews.SQUIRREL_GIRL;
/**
* Review comment to the pull request
@@ -153,7 +153,20 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
* @return the api route
*/
protected String getApiRoute() {
return "/repos/" + owner.getRepository().getFullName() + "/pulls/comments/" + getId();
return getApiRoute(false);
}
/**
* Gets api route.
*
* @param includePullNumber
* if true, includes the owning pull request's number in the route.
*
* @return the api route
*/
protected String getApiRoute(boolean includePullNumber) {
return "/repos/" + owner.getRepository().getFullName() + "/pulls"
+ (includePullNumber ? "/" + owner.getNumber() : "") + "/comments/" + getId();
}
/**
@@ -192,8 +205,7 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
return owner.root.createRequest()
.method("POST")
.with("body", body)
.with("in_reply_to", getId())
.withUrlPath(getApiRoute() + "/comments")
.withUrlPath(getApiRoute(true) + "/replies")
.fetch(GHPullRequestReviewComment.class)
.wrapUp(owner);
}

View File

@@ -3,7 +3,7 @@ package org.kohsuke.github;
import java.io.IOException;
import java.net.URL;
import static org.kohsuke.github.Previews.*;
import static org.kohsuke.github.internal.Previews.SQUIRREL_GIRL;
/**
* Reaction to issue, comment, PR, and so on.

View File

@@ -58,7 +58,7 @@ import javax.annotation.Nonnull;
import static java.util.Arrays.*;
import static java.util.Objects.requireNonNull;
import static org.kohsuke.github.Previews.*;
import static org.kohsuke.github.internal.Previews.*;
/**
* A repository on GitHub.

View File

@@ -3,7 +3,7 @@ package org.kohsuke.github;
import java.io.IOException;
import java.net.URL;
import static org.kohsuke.github.Previews.BAPTISTE;
import static org.kohsuke.github.internal.Previews.BAPTISTE;
abstract class GHRepositoryBuilder<S> extends AbstractBuilder<GHRepository, S> {

View File

@@ -26,6 +26,8 @@ package org.kohsuke.github;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import org.kohsuke.github.authorization.AuthorizationProvider;
import org.kohsuke.github.internal.Previews;
import java.io.*;
import java.util.*;
@@ -37,8 +39,8 @@ import java.util.logging.Logger;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import static org.kohsuke.github.Previews.INERTIA;
import static org.kohsuke.github.Previews.MACHINE_MAN;
import static org.kohsuke.github.internal.Previews.INERTIA;
import static org.kohsuke.github.internal.Previews.MACHINE_MAN;
/**
* Root of the GitHub API.
@@ -93,39 +95,112 @@ public class GitHub {
* "http://ghe.acme.com/api/v3". Note that GitHub Enterprise has <code>/api/v3</code> in the URL. For
* historical reasons, this parameter still accepts the bare domain name, but that's considered
* deprecated. Password is also considered deprecated as it is no longer required for api usage.
* @param login
* The user ID on GitHub that you are logging in as. Can be omitted if the OAuth token is provided or if
* logging in anonymously. Specifying this would save one API call.
* @param oauthAccessToken
* Secret OAuth token.
* @param password
* User's password. Always used in conjunction with the {@code login} parameter
* @param connector
* HttpConnector to use. Pass null to use default connector.
* a connector
* @param rateLimitHandler
* rateLimitHandler
* @param abuseLimitHandler
* abuseLimitHandler
* @param rateLimitChecker
* rateLimitChecker
* @param authorizationProvider
* a authorization provider
*/
GitHub(String apiUrl,
String login,
String oauthAccessToken,
String jwtToken,
String password,
HttpConnector connector,
RateLimitHandler rateLimitHandler,
AbuseLimitHandler abuseLimitHandler,
GitHubRateLimitChecker rateLimitChecker) throws IOException {
GitHubRateLimitChecker rateLimitChecker,
AuthorizationProvider authorizationProvider) throws IOException {
if (authorizationProvider instanceof DependentAuthorizationProvider) {
((DependentAuthorizationProvider) authorizationProvider).bind(this);
}
this.client = new GitHubHttpUrlConnectionClient(apiUrl,
login,
oauthAccessToken,
jwtToken,
password,
connector,
rateLimitHandler,
abuseLimitHandler,
rateLimitChecker,
(myself) -> setMyself(myself));
(myself) -> setMyself(myself),
authorizationProvider);
users = new ConcurrentHashMap<>();
orgs = new ConcurrentHashMap<>();
}
private GitHub(GitHubClient client) {
this.client = client;
users = new ConcurrentHashMap<>();
orgs = new ConcurrentHashMap<>();
}
public static abstract class DependentAuthorizationProvider implements AuthorizationProvider {
private GitHub baseGitHub;
private GitHub gitHub;
private final AuthorizationProvider authorizationProvider;
/**
* An AuthorizationProvider that requires an authenticated GitHub instance to provide its authorization.
*
* @param authorizationProvider
* A authorization provider to be used when refreshing this authorization provider.
*/
@BetaApi
@Deprecated
protected DependentAuthorizationProvider(AuthorizationProvider authorizationProvider) {
this.authorizationProvider = authorizationProvider;
}
/**
* Binds this authorization provider to a github instance.
*
* Only needs to be implemented by dynamic credentials providers that use a github instance in order to refresh.
*
* @param github
* The github instance to be used for refreshing dynamic credentials
*/
synchronized void bind(GitHub github) {
if (baseGitHub != null) {
throw new IllegalStateException("Already bound to another GitHub instance.");
}
this.baseGitHub = github;
}
protected synchronized final GitHub gitHub() {
if (gitHub == null) {
gitHub = new GitHub.AuthorizationRefreshGitHubWrapper(this.baseGitHub, authorizationProvider);
}
return gitHub;
}
}
private static class AuthorizationRefreshGitHubWrapper extends GitHub {
private final AuthorizationProvider authorizationProvider;
AuthorizationRefreshGitHubWrapper(GitHub github, AuthorizationProvider authorizationProvider) {
super(github.client);
this.authorizationProvider = authorizationProvider;
// no dependent authorization providers nest like this currently, but they might in future
if (authorizationProvider instanceof DependentAuthorizationProvider) {
((DependentAuthorizationProvider) authorizationProvider).bind(this);
}
}
@Nonnull
@Override
Requester createRequest() {
try {
// Override
return super.createRequest().setHeader("Authorization", authorizationProvider.getEncodedAuthorization())
.rateLimit(RateLimitTarget.NONE);
} catch (IOException e) {
throw new GHException("Failed to create requester to refresh credentials", e);
}
}
}
/**
* Obtains the credential from "~/.github" or from the System Environment Properties.
*

View File

@@ -1,6 +1,8 @@
package org.kohsuke.github;
import org.apache.commons.io.IOUtils;
import org.kohsuke.github.authorization.AuthorizationProvider;
import org.kohsuke.github.authorization.ImmutableAuthorizationProvider;
import org.kohsuke.github.extras.ImpatientHttpConnector;
import java.io.File;
@@ -24,16 +26,13 @@ public class GitHubBuilder implements Cloneable {
// default scoped so unit tests can read them.
/* private */ String endpoint = GitHubClient.GITHUB_URL;
/* private */ String user;
/* private */ String password;
/* private */ String oauthToken;
/* private */ String jwtToken;
private HttpConnector connector;
private RateLimitHandler rateLimitHandler = RateLimitHandler.WAIT;
private AbuseLimitHandler abuseLimitHandler = AbuseLimitHandler.WAIT;
private GitHubRateLimitChecker rateLimitChecker = new GitHubRateLimitChecker();
/* private */ AuthorizationProvider authorizationProvider = AuthorizationProvider.ANONYMOUS;
/**
* Instantiates a new Git hub builder.
@@ -61,13 +60,13 @@ public class GitHubBuilder implements Cloneable {
builder = fromEnvironment();
if (builder.oauthToken != null || builder.user != null || builder.jwtToken != null)
if (builder.authorizationProvider != null)
return builder;
try {
builder = fromPropertyFile();
if (builder.oauthToken != null || builder.user != null || builder.jwtToken != null)
if (builder.authorizationProvider != null)
return builder;
} catch (FileNotFoundException e) {
// fall through
@@ -215,9 +214,20 @@ public class GitHubBuilder implements Cloneable {
*/
public static GitHubBuilder fromProperties(Properties props) {
GitHubBuilder self = new GitHubBuilder();
self.withOAuthToken(props.getProperty("oauth"), props.getProperty("login"));
self.withJwtToken(props.getProperty("jwt"));
self.withPassword(props.getProperty("login"), props.getProperty("password"));
String oauth = props.getProperty("oauth");
String jwt = props.getProperty("jwt");
String login = props.getProperty("login");
String password = props.getProperty("password");
if (oauth != null) {
self.withOAuthToken(oauth, login);
}
if (jwt != null) {
self.withJwtToken(jwt);
}
if (password != null) {
self.withPassword(login, password);
}
self.withEndpoint(props.getProperty("endpoint", GitHubClient.GITHUB_URL));
return self;
}
@@ -247,9 +257,7 @@ public class GitHubBuilder implements Cloneable {
* @return the git hub builder
*/
public GitHubBuilder withPassword(String user, String password) {
this.user = user;
this.password = password;
return this;
return withAuthorizationProvider(ImmutableAuthorizationProvider.fromLoginAndPassword(user, password));
}
/**
@@ -260,7 +268,7 @@ public class GitHubBuilder implements Cloneable {
* @return the git hub builder
*/
public GitHubBuilder withOAuthToken(String oauthToken) {
return withOAuthToken(oauthToken, null);
return withAuthorizationProvider(ImmutableAuthorizationProvider.fromOauthToken(oauthToken));
}
/**
@@ -273,8 +281,21 @@ public class GitHubBuilder implements Cloneable {
* @return the git hub builder
*/
public GitHubBuilder withOAuthToken(String oauthToken, String user) {
this.oauthToken = oauthToken;
this.user = user;
return withAuthorizationProvider(ImmutableAuthorizationProvider.fromOauthToken(oauthToken, user));
}
/**
* Configures a {@link AuthorizationProvider} for this builder
*
* There can be only one authorization provider per client instance.
*
* @param authorizationProvider
* the authorization provider
* @return the git hub builder
*
*/
public GitHubBuilder withAuthorizationProvider(final AuthorizationProvider authorizationProvider) {
this.authorizationProvider = authorizationProvider;
return this;
}
@@ -287,7 +308,7 @@ public class GitHubBuilder implements Cloneable {
* @see GHAppInstallation#createToken(java.util.Map) GHAppInstallation#createToken(java.util.Map)
*/
public GitHubBuilder withAppInstallationToken(String appInstallationToken) {
return withOAuthToken(appInstallationToken, "");
return withAuthorizationProvider(ImmutableAuthorizationProvider.fromAppInstallationToken(appInstallationToken));
}
/**
@@ -298,8 +319,7 @@ public class GitHubBuilder implements Cloneable {
* @return the git hub builder
*/
public GitHubBuilder withJwtToken(String jwtToken) {
this.jwtToken = jwtToken;
return this;
return withAuthorizationProvider(ImmutableAuthorizationProvider.fromJwtToken(jwtToken));
}
/**
@@ -421,14 +441,11 @@ public class GitHubBuilder implements Cloneable {
*/
public GitHub build() throws IOException {
return new GitHub(endpoint,
user,
oauthToken,
jwtToken,
password,
connector,
rateLimitHandler,
abuseLimitHandler,
rateLimitChecker);
rateLimitChecker,
authorizationProvider);
}
@Override

View File

@@ -1,33 +1,19 @@
package org.kohsuke.github;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
import org.apache.commons.io.IOUtils;
import org.kohsuke.github.authorization.AuthorizationProvider;
import org.kohsuke.github.authorization.UserAuthorizationProvider;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.net.*;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.function.Consumer;
import java.util.logging.Logger;
@@ -56,17 +42,13 @@ abstract class GitHubClient {
static final int retryTimeoutMillis = 100;
/* private */ final String login;
/**
* Value of the authorization header to be sent with the request.
*/
/* private */ final String encodedAuthorization;
// Cache of myself object.
private final String apiUrl;
protected final RateLimitHandler rateLimitHandler;
protected final AbuseLimitHandler abuseLimitHandler;
private final GitHubRateLimitChecker rateLimitChecker;
private final AuthorizationProvider authorizationProvider;
private HttpConnector connector;
@@ -91,15 +73,12 @@ abstract class GitHubClient {
}
GitHubClient(String apiUrl,
String login,
String oauthAccessToken,
String jwtToken,
String password,
HttpConnector connector,
RateLimitHandler rateLimitHandler,
AbuseLimitHandler abuseLimitHandler,
GitHubRateLimitChecker rateLimitChecker,
Consumer<GHMyself> myselfConsumer) throws IOException {
Consumer<GHMyself> myselfConsumer,
AuthorizationProvider authorizationProvider) throws IOException {
if (apiUrl.endsWith("/")) {
apiUrl = apiUrl.substring(0, apiUrl.length() - 1); // normalize
@@ -111,33 +90,38 @@ abstract class GitHubClient {
this.apiUrl = apiUrl;
this.connector = connector;
if (oauthAccessToken != null) {
encodedAuthorization = "token " + oauthAccessToken;
} else {
if (jwtToken != null) {
encodedAuthorization = "Bearer " + jwtToken;
} else if (password != null) {
String authorization = (login + ':' + password);
String charsetName = StandardCharsets.UTF_8.name();
encodedAuthorization = "Basic "
+ Base64.getEncoder().encodeToString(authorization.getBytes(charsetName));
} else {// anonymous access
encodedAuthorization = null;
}
}
// Prefer credential configuration via provider
this.authorizationProvider = authorizationProvider;
this.rateLimitHandler = rateLimitHandler;
this.abuseLimitHandler = abuseLimitHandler;
this.rateLimitChecker = rateLimitChecker;
if (login == null && encodedAuthorization != null && jwtToken == null) {
GHMyself myself = fetch(GHMyself.class, "/user");
login = myself.getLogin();
if (myselfConsumer != null) {
myselfConsumer.accept(myself);
this.login = getCurrentUser(myselfConsumer);
}
private String getCurrentUser(Consumer<GHMyself> myselfConsumer) throws IOException {
String login = null;
if (this.authorizationProvider instanceof UserAuthorizationProvider
&& this.authorizationProvider.getEncodedAuthorization() != null) {
UserAuthorizationProvider userAuthorizationProvider = (UserAuthorizationProvider) this.authorizationProvider;
login = userAuthorizationProvider.getLogin();
if (login == null) {
try {
GHMyself myself = fetch(GHMyself.class, "/user");
if (myselfConsumer != null) {
myselfConsumer.accept(myself);
}
login = myself.getLogin();
} catch (IOException e) {
return null;
}
}
}
this.login = login;
return login;
}
private <T> T fetch(Class<T> type, String urlPath) throws IOException {
@@ -202,7 +186,13 @@ abstract class GitHubClient {
* @return {@code true} if operations that require authentication will fail.
*/
public boolean isAnonymous() {
return login == null && encodedAuthorization == null;
try {
return login == null && this.authorizationProvider.getEncodedAuthorization() == null;
} catch (IOException e) {
// An exception here means that the provider failed to provide authorization parameters,
// basically meaning the same as "no auth"
return false;
}
}
/**
@@ -224,6 +214,11 @@ abstract class GitHubClient {
return getRateLimit(RateLimitTarget.NONE);
}
@CheckForNull
protected String getEncodedAuthorization() throws IOException {
return authorizationProvider.getEncodedAuthorization();
}
@Nonnull
GHRateLimit getRateLimit(@Nonnull RateLimitTarget rateLimitTarget) throws IOException {
GHRateLimit result;
@@ -394,7 +389,6 @@ abstract class GitHubClient {
"GitHub API request [" + (login == null ? "anonymous" : login) + "]: "
+ request.method() + " " + request.url().toString());
}
rateLimitChecker.checkRateLimit(this, request);
responseInfo = getResponseInfo(request);

View File

@@ -1,6 +1,7 @@
package org.kohsuke.github;
import org.apache.commons.io.IOUtils;
import org.kohsuke.github.authorization.AuthorizationProvider;
import java.io.IOException;
import java.io.InputStream;
@@ -33,25 +34,19 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
class GitHubHttpUrlConnectionClient extends GitHubClient {
GitHubHttpUrlConnectionClient(String apiUrl,
String login,
String oauthAccessToken,
String jwtToken,
String password,
HttpConnector connector,
RateLimitHandler rateLimitHandler,
AbuseLimitHandler abuseLimitHandler,
GitHubRateLimitChecker rateLimitChecker,
Consumer<GHMyself> myselfConsumer) throws IOException {
Consumer<GHMyself> myselfConsumer,
AuthorizationProvider authorizationProvider) throws IOException {
super(apiUrl,
login,
oauthAccessToken,
jwtToken,
password,
connector,
rateLimitHandler,
abuseLimitHandler,
rateLimitChecker,
myselfConsumer);
myselfConsumer,
authorizationProvider);
}
@Nonnull
@@ -114,8 +109,12 @@ class GitHubHttpUrlConnectionClient extends GitHubClient {
// if the authentication is needed but no credential is given, try it anyway (so that some calls
// that do work with anonymous access in the reduced form should still work.)
if (client.encodedAuthorization != null)
connection.setRequestProperty("Authorization", client.encodedAuthorization);
if (!request.headers().containsKey("Authorization")) {
String authorization = client.getEncodedAuthorization();
if (authorization != null) {
connection.setRequestProperty("Authorization", client.getEncodedAuthorization());
}
}
setRequestMethod(request.method(), connection);
buildRequest(request, connection);

View File

@@ -20,4 +20,8 @@ abstract class GitHubInteractiveObject {
GitHubInteractiveObject(GitHub root) {
this.root = root;
}
GitHub getRoot() {
return root;
}
}

View File

@@ -2,6 +2,7 @@ package org.kohsuke.github;
import edu.umd.cs.findbugs.annotations.NonNull;
import org.apache.commons.lang3.StringUtils;
import org.kohsuke.github.internal.Previews;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

View File

@@ -1,5 +1,7 @@
package org.kohsuke.github;
import org.kohsuke.github.internal.Previews;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

View File

@@ -2,7 +2,7 @@ package org.kohsuke.github;
import java.io.IOException;
import static org.kohsuke.github.Previews.SQUIRREL_GIRL;
import static org.kohsuke.github.internal.Previews.SQUIRREL_GIRL;
/**
* Those {@link GHObject}s that can have {@linkplain GHReaction reactions}.

View File

@@ -0,0 +1,43 @@
package org.kohsuke.github.authorization;
import java.io.IOException;
/**
* Provides a functional interface that returns a valid encodedAuthorization. This strategy allows for a provider that
* dynamically changes the credentials. Each request will request the credentials from the provider.
*/
public interface AuthorizationProvider {
/**
* An static instance for an ANONYMOUS authorization provider
*/
AuthorizationProvider ANONYMOUS = new AnonymousAuthorizationProvider();
/**
* Returns the credentials to be used with a given request. As an example, a authorization provider for a bearer
* token will return something like:
*
* <pre>
* {@code
* &#64;Override
* public String getEncodedAuthorization() {
* return "Bearer myBearerToken";
* }
* }
* </pre>
*
* @return encoded authorization string, can be null
* @throws IOException
* on any error that prevents the provider from getting a valid authorization
*/
String getEncodedAuthorization() throws IOException;
/**
* A {@link AuthorizationProvider} that ensures that no credentials are returned
*/
class AnonymousAuthorizationProvider implements AuthorizationProvider {
@Override
public String getEncodedAuthorization() throws IOException {
return null;
}
}
}

View File

@@ -0,0 +1,123 @@
package org.kohsuke.github.authorization;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.annotation.CheckForNull;
/**
* A {@link AuthorizationProvider} that always returns the same credentials
*/
public class ImmutableAuthorizationProvider implements AuthorizationProvider {
private final String authorization;
public ImmutableAuthorizationProvider(String authorization) {
this.authorization = authorization;
}
/**
* Builds and returns a {@link AuthorizationProvider} from a given oauthAccessToken
*
* @param oauthAccessToken
* The token
* @return a correctly configured {@link AuthorizationProvider} that will always return the same provided
* oauthAccessToken
*/
public static AuthorizationProvider fromOauthToken(String oauthAccessToken) {
return new UserProvider(String.format("token %s", oauthAccessToken));
}
/**
* Builds and returns a {@link AuthorizationProvider} from a given oauthAccessToken
*
* @param oauthAccessToken
* The token
* @param login
* The login for this token
*
* @return a correctly configured {@link AuthorizationProvider} that will always return the same provided
* oauthAccessToken
*/
public static AuthorizationProvider fromOauthToken(String oauthAccessToken, String login) {
return new UserProvider(String.format("token %s", oauthAccessToken), login);
}
/**
* Builds and returns a {@link AuthorizationProvider} from a given App Installation Token
*
* @param appInstallationToken
* A string containing the GitHub App installation token
* @return the configured Builder from given GitHub App installation token.
*/
public static AuthorizationProvider fromAppInstallationToken(String appInstallationToken) {
return fromOauthToken(appInstallationToken, "");
}
/**
* Builds and returns a {@link AuthorizationProvider} from a given jwtToken
*
* @param jwtToken
* The JWT token
* @return a correctly configured {@link AuthorizationProvider} that will always return the same provided jwtToken
*/
public static AuthorizationProvider fromJwtToken(String jwtToken) {
return new ImmutableAuthorizationProvider(String.format("Bearer %s", jwtToken));
}
/**
* Builds and returns a {@link AuthorizationProvider} from the given user/password pair
*
* @param login
* The login for the user, usually the same as the username
* @param password
* The password for the associated user
* @return a correctly configured {@link AuthorizationProvider} that will always return the credentials for the same
* user and password combo
* @deprecated Login with password credentials are no longer supported by GitHub
*/
@Deprecated
public static AuthorizationProvider fromLoginAndPassword(String login, String password) {
try {
String authorization = (String.format("%s:%s", login, password));
String charsetName = StandardCharsets.UTF_8.name();
String b64encoded = Base64.getEncoder().encodeToString(authorization.getBytes(charsetName));
String encodedAuthorization = String.format("Basic %s", b64encoded);
return new UserProvider(encodedAuthorization, login);
} catch (UnsupportedEncodingException e) {
// If UTF-8 isn't supported, there are bigger problems
throw new IllegalStateException("Could not generate encoded authorization", e);
}
}
@Override
public String getEncodedAuthorization() {
return this.authorization;
}
/**
* An internal class representing all user-related credentials, which are credentials that have a login or should
* query the user endpoint for the login matching this credential.
*/
private static class UserProvider extends ImmutableAuthorizationProvider implements UserAuthorizationProvider {
private final String login;
UserProvider(String authorization) {
this(authorization, null);
}
UserProvider(String authorization, String login) {
super(authorization);
this.login = login;
}
@CheckForNull
@Override
public String getLogin() {
return login;
}
}
}

View File

@@ -0,0 +1,63 @@
package org.kohsuke.github.authorization;
import org.kohsuke.github.BetaApi;
import org.kohsuke.github.GHAppInstallation;
import org.kohsuke.github.GHAppInstallationToken;
import org.kohsuke.github.GitHub;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.Objects;
import javax.annotation.Nonnull;
/**
* Provides an AuthorizationProvider that performs automatic token refresh.
*/
public class OrgAppInstallationAuthorizationProvider extends GitHub.DependentAuthorizationProvider {
private final String organizationName;
private String latestToken;
@Nonnull
private Instant validUntil = Instant.MIN;
/**
* Provides an AuthorizationProvider that performs automatic token refresh, based on an previously authenticated
* github client.
*
* @param organizationName
* The name of the organization where the application is installed
* @param authorizationProvider
* A authorization provider that returns a JWT token that can be used to refresh the App Installation
* token from GitHub.
*/
@BetaApi
@Deprecated
public OrgAppInstallationAuthorizationProvider(String organizationName,
AuthorizationProvider authorizationProvider) {
super(authorizationProvider);
this.organizationName = organizationName;
}
@Override
public String getEncodedAuthorization() throws IOException {
synchronized (this) {
if (latestToken == null || Instant.now().isAfter(this.validUntil)) {
refreshToken();
}
return String.format("token %s", latestToken);
}
}
private void refreshToken() throws IOException {
GitHub gitHub = this.gitHub();
GHAppInstallation installationByOrganization = gitHub.getApp()
.getInstallationByOrganization(this.organizationName);
GHAppInstallationToken ghAppInstallationToken = installationByOrganization.createToken().create();
this.validUntil = ghAppInstallationToken.getExpiresAt().toInstant().minus(Duration.ofMinutes(5));
this.latestToken = Objects.requireNonNull(ghAppInstallationToken.getToken());
}
}

View File

@@ -0,0 +1,22 @@
package org.kohsuke.github.authorization;
import javax.annotation.CheckForNull;
/**
* Interface for all user-related authorization providers.
*
* {@link AuthorizationProvider}s can apply to a number of different account types. This interface applies to providers
* for user accounts, ones that have a login or should query the "/user" endpoint for the login matching this
* credential.
*/
public interface UserAuthorizationProvider extends AuthorizationProvider {
/**
* Gets the user login name.
*
* @return the user login for this provider, or {@code null} if the login value should be queried from the "/user"
* endpoint.
*/
@CheckForNull
String getLogin();
}

View File

@@ -0,0 +1,122 @@
package org.kohsuke.github.extras.authorization;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.kohsuke.github.authorization.AuthorizationProvider;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.time.Duration;
import java.time.Instant;
import java.util.Base64;
import java.util.Date;
import javax.annotation.Nonnull;
/**
* A authorization provider that gives valid JWT tokens. These tokens are then used to create a time-based token to
* authenticate as an application. This token provider does not provide any kind of caching, and will always request a
* new token to the API.
*/
public class JWTTokenProvider implements AuthorizationProvider {
private final PrivateKey privateKey;
@Nonnull
private Instant validUntil = Instant.MIN;
private String token;
/**
* The identifier for the application
*/
private final String applicationId;
public JWTTokenProvider(String applicationId, File keyFile) throws GeneralSecurityException, IOException {
this(applicationId, keyFile.toPath());
}
public JWTTokenProvider(String applicationId, Path keyPath) throws GeneralSecurityException, IOException {
this(applicationId, new String(Files.readAllBytes(keyPath), StandardCharsets.UTF_8));
}
public JWTTokenProvider(String applicationId, String keyString) throws GeneralSecurityException {
this(applicationId, getPrivateKeyFromString(keyString));
}
public JWTTokenProvider(String applicationId, PrivateKey privateKey) {
this.privateKey = privateKey;
this.applicationId = applicationId;
}
@Override
public String getEncodedAuthorization() throws IOException {
synchronized (this) {
if (Instant.now().isAfter(validUntil)) {
token = refreshJWT();
}
return String.format("Bearer %s", token);
}
}
/**
* Convert a PKCS#8 formatted private key in string format into a java PrivateKey
*
* @param key
* PCKS#8 string
* @return private key
* @throws GeneralSecurityException
* if we couldn't parse the string
*/
private static PrivateKey getPrivateKeyFromString(final String key) throws GeneralSecurityException {
if (key.contains(" RSA ")) {
throw new InvalidKeySpecException(
"Private key must be a PKCS#8 formatted string, to convert it from PKCS#1 use: "
+ "openssl pkcs8 -topk8 -inform PEM -outform PEM -in current-key.pem -out new-key.pem -nocrypt");
}
// Remove all comments and whitespace from PEM
// such as "-----BEGIN PRIVATE KEY-----" and newlines
String privateKeyContent = key.replaceAll("(?m)^--.*", "").replaceAll("\\s", "");
KeyFactory kf = KeyFactory.getInstance("RSA");
try {
byte[] decode = Base64.getDecoder().decode(privateKeyContent);
PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(decode);
return kf.generatePrivate(keySpecPKCS8);
} catch (IllegalArgumentException e) {
throw new InvalidKeySpecException("Failed to decode private key: " + e.getMessage(), e);
}
}
private String refreshJWT() {
Instant now = Instant.now();
// Token expires in 10 minutes
Instant expiration = Instant.now().plus(Duration.ofMinutes(10));
// Let's set the JWT Claims
JwtBuilder builder = Jwts.builder()
.setIssuedAt(Date.from(now))
.setExpiration(Date.from(expiration))
.setIssuer(this.applicationId)
.signWith(privateKey, SignatureAlgorithm.RS256);
// Token will refresh after 8 minutes
validUntil = expiration.minus(Duration.ofMinutes(2));
// Builds the JWT and serializes it to a compact, URL-safe string
return builder.compact();
}
}

View File

@@ -1,4 +1,4 @@
package org.kohsuke.github;
package org.kohsuke.github.internal;
/**
* Provides the media type strings for GitHub API previews
@@ -7,7 +7,7 @@ package org.kohsuke.github;
*
* @author Kohsuke Kawaguchi
*/
enum Previews {
public enum Previews {
/**
* Check-runs and check-suites

View File

@@ -2,8 +2,14 @@ package org.kohsuke.github;
import io.jsonwebtoken.Jwts;
import org.apache.commons.io.IOUtils;
import org.kohsuke.github.authorization.AuthorizationProvider;
import org.kohsuke.github.extras.authorization.JWTTokenProvider;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
@@ -21,6 +27,26 @@ public class AbstractGHAppInstallationTest extends AbstractGitHubWireMockTest {
private static String PRIVATE_KEY_FILE_APP_2 = "/ghapi-test-app-2.private-key.pem";
private static String PRIVATE_KEY_FILE_APP_3 = "/ghapi-test-app-3.private-key.pem";
private static AuthorizationProvider JWT_PROVIDER_1;
private static AuthorizationProvider JWT_PROVIDER_2;
private static AuthorizationProvider JWT_PROVIDER_3;
AbstractGHAppInstallationTest() {
try {
JWT_PROVIDER_1 = new JWTTokenProvider(TEST_APP_ID_1,
new File(this.getClass().getResource(PRIVATE_KEY_FILE_APP_1).getFile()));
JWT_PROVIDER_2 = new JWTTokenProvider(TEST_APP_ID_2,
new File(this.getClass().getResource(PRIVATE_KEY_FILE_APP_2).getFile()).toPath());
JWT_PROVIDER_3 = new JWTTokenProvider(TEST_APP_ID_3,
new String(
Files.readAllBytes(
new File(this.getClass().getResource(PRIVATE_KEY_FILE_APP_3).getFile()).toPath()),
StandardCharsets.UTF_8));
} catch (GeneralSecurityException | IOException e) {
throw new RuntimeException("These should never fail", e);
}
}
private String createJwtToken(String keyFileResouceName, String appId) {
try {
String keyPEM = IOUtils.toString(this.getClass().getResource(keyFileResouceName), "US-ASCII")
@@ -54,24 +80,25 @@ public class AbstractGHAppInstallationTest extends AbstractGitHubWireMockTest {
.findFirst()
.get();
appInstallation
.setRoot(getGitHubBuilder().withAppInstallationToken(appInstallation.createToken().create().getToken())
.withEndpoint(mockGitHub.apiServer().baseUrl())
.build());
// TODO: this is odd
// appInstallation
// .setRoot(getGitHubBuilder().withAppInstallationToken(appInstallation.createToken().create().getToken())
// .withEndpoint(mockGitHub.apiServer().baseUrl())
// .build());
return appInstallation;
}
protected GHAppInstallation getAppInstallationWithTokenApp1() throws IOException {
return getAppInstallationWithToken(createJwtToken(PRIVATE_KEY_FILE_APP_1, TEST_APP_ID_1));
return getAppInstallationWithToken(JWT_PROVIDER_1.getEncodedAuthorization());
}
protected GHAppInstallation getAppInstallationWithTokenApp2() throws IOException {
return getAppInstallationWithToken(createJwtToken(PRIVATE_KEY_FILE_APP_2, TEST_APP_ID_2));
return getAppInstallationWithToken(JWT_PROVIDER_2.getEncodedAuthorization());
}
protected GHAppInstallation getAppInstallationWithTokenApp3() throws IOException {
return getAppInstallationWithToken(createJwtToken(PRIVATE_KEY_FILE_APP_3, TEST_APP_ID_3));
return getAppInstallationWithToken(JWT_PROVIDER_3.getEncodedAuthorization());
}
}

View File

@@ -100,7 +100,6 @@ public abstract class AbstractGitHubWireMockTest extends Assert {
// This sets the user and password to a placeholder for wiremock testing
// This makes the tests believe they are running with permissions
// The recorded stubs will behave like they running with permissions
builder.oauthToken = null;
builder.withPassword(STUBBED_USER_LOGIN, STUBBED_USER_PASSWORD);
}

View File

@@ -19,10 +19,7 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.oneOf;
import static org.hamcrest.Matchers.*;
/**
* Unit test for simple App.
@@ -37,10 +34,11 @@ public class AppTest extends AbstractGitHubWireMockTest {
cleanupUserRepository("github-api-test-rename");
cleanupUserRepository(targetName);
GHRepository r = gitHub.createRepository("github-api-test-rename",
"a test repository",
"http://github-api.kohsuke.org/",
true);
GHRepository r = gitHub.createRepository("github-api-test-rename")
.description("a test repository")
.homepage("http://github-api.kohsuke.org/")
.private_(false)
.create();
assertThat(r.hasIssues(), is(true));
assertThat(r.hasWiki(), is(true));
@@ -137,13 +135,36 @@ public class AppTest extends AbstractGitHubWireMockTest {
@Test
public void testIssueWithNoComment() throws IOException {
GHRepository repository = gitHub.getRepository("kohsuke/test");
List<GHIssueComment> v = repository.getIssue(4).getComments();
GHIssue i = repository.getIssue(4);
List<GHIssueComment> v = i.getComments();
// System.out.println(v);
assertTrue(v.isEmpty());
v = repository.getIssue(3).getComments();
i = repository.getIssue(3);
v = i.getComments();
// System.out.println(v);
assertTrue(v.size() == 3);
assertThat(v.size(), equalTo(3));
assertThat(v.get(0).getHtmlUrl().toString(),
equalTo("https://github.com/kohsuke/test/issues/3#issuecomment-8547249"));
assertThat(v.get(0).getUrl().toString(), endsWith("/repos/kohsuke/test/issues/comments/8547249"));
assertThat(v.get(0).getNodeId(), equalTo("MDEyOklzc3VlQ29tbWVudDg1NDcyNDk="));
assertThat(v.get(0).getParent().getNumber(), equalTo(3));
assertThat(v.get(0).getParent().getId(), equalTo(6863845L));
assertThat(v.get(0).getUser().getLogin(), equalTo("kohsuke"));
assertThat(v.get(0).listReactions().toList().size(), equalTo(0));
assertThat(v.get(1).getHtmlUrl().toString(),
equalTo("https://github.com/kohsuke/test/issues/3#issuecomment-8547251"));
assertThat(v.get(1).getUrl().toString(), endsWith("/repos/kohsuke/test/issues/comments/8547251"));
assertThat(v.get(1).getNodeId(), equalTo("MDEyOklzc3VlQ29tbWVudDg1NDcyNTE="));
assertThat(v.get(1).getParent().getNumber(), equalTo(3));
assertThat(v.get(1).getUser().getLogin(), equalTo("kohsuke"));
List<GHReaction> reactions = v.get(1).listReactions().toList();
assertThat(reactions.size(), equalTo(3));
// TODO: Add comment CRUD test
// TODO: Add reactions CRUD test
}
@Test
@@ -165,49 +186,60 @@ public class AppTest extends AbstractGitHubWireMockTest {
@Test
public void testCreateAndListDeployments() throws IOException {
GHRepository repository = getTestRepository();
GHDeployment deployment = repository.createDeployment("master")
GHDeployment deployment = repository.createDeployment("main")
.payload("{\"user\":\"atmos\",\"room_id\":123456}")
.description("question")
.environment("unittest")
.create();
assertNotNull(deployment.getCreator());
assertNotNull(deployment.getId());
List<GHDeployment> deployments = repository.listDeployments(null, "master", null, "unittest").toList();
assertNotNull(deployments);
assertFalse(Iterables.isEmpty(deployments));
GHDeployment unitTestDeployment = deployments.get(0);
assertEquals("unittest", unitTestDeployment.getEnvironment());
assertEquals("unittest", unitTestDeployment.getOriginalEnvironment());
assertEquals(false, unitTestDeployment.isProductionEnvironment());
assertEquals(true, unitTestDeployment.isTransientEnvironment());
assertEquals("master", unitTestDeployment.getRef());
try {
assertNotNull(deployment.getCreator());
assertNotNull(deployment.getId());
List<GHDeployment> deployments = repository.listDeployments(null, "main", null, "unittest").toList();
assertNotNull(deployments);
assertFalse(Iterables.isEmpty(deployments));
GHDeployment unitTestDeployment = deployments.get(0);
assertEquals("unittest", unitTestDeployment.getEnvironment());
assertEquals("unittest", unitTestDeployment.getOriginalEnvironment());
assertEquals(false, unitTestDeployment.isProductionEnvironment());
assertEquals(false, unitTestDeployment.isTransientEnvironment());
assertEquals("main", unitTestDeployment.getRef());
} finally {
// deployment.delete();
assert true;
}
}
@Ignore("Needs mocking check")
@Test
public void testGetDeploymentStatuses() throws IOException {
GHRepository repository = getTestRepository();
GHDeployment deployment = repository.createDeployment("master")
GHDeployment deployment = repository.createDeployment("main")
.description("question")
.payload("{\"user\":\"atmos\",\"room_id\":123456}")
.create();
GHDeploymentStatus ghDeploymentStatus = deployment.createStatus(GHDeploymentState.QUEUED)
.description("success")
.targetUrl("http://www.github.com")
.logUrl("http://www.github.com/logurl")
.environmentUrl("http://www.github.com/envurl")
.environment("new-ci-env")
.create();
Iterable<GHDeploymentStatus> deploymentStatuses = deployment.listStatuses();
assertNotNull(deploymentStatuses);
assertEquals(1, Iterables.size(deploymentStatuses));
GHDeploymentStatus actualStatus = Iterables.get(deploymentStatuses, 0);
assertEquals(ghDeploymentStatus.getId(), actualStatus.getId());
assertEquals(ghDeploymentStatus.getState(), actualStatus.getState());
assertEquals(ghDeploymentStatus.getLogUrl(), actualStatus.getLogUrl());
// Target url was deprecated and replaced with log url. The gh api will
// prefer the log url value and return it in place of target url.
assertEquals(ghDeploymentStatus.getTargetUrl(), actualStatus.getLogUrl());
try {
GHDeploymentStatus ghDeploymentStatus = deployment.createStatus(GHDeploymentState.QUEUED)
.description("success")
.targetUrl("http://www.github.com")
.logUrl("http://www.github.com/logurl")
.environmentUrl("http://www.github.com/envurl")
.environment("new-ci-env")
.create();
Iterable<GHDeploymentStatus> deploymentStatuses = deployment.listStatuses();
assertNotNull(deploymentStatuses);
assertEquals(1, Iterables.size(deploymentStatuses));
GHDeploymentStatus actualStatus = Iterables.get(deploymentStatuses, 0);
assertEquals(ghDeploymentStatus.getId(), actualStatus.getId());
assertEquals(ghDeploymentStatus.getState(), actualStatus.getState());
assertEquals(ghDeploymentStatus.getLogUrl(), actualStatus.getLogUrl());
// Target url was deprecated and replaced with log url. The gh api will
// prefer the log url value and return it in place of target url.
assertEquals(ghDeploymentStatus.getTargetUrl(), actualStatus.getLogUrl());
assertThat(ghDeploymentStatus.getDeploymentUrl(), equalTo(deployment.getUrl()));
assertThat(ghDeploymentStatus.getRepositoryUrl(), equalTo(repository.getUrl()));
} finally {
// deployment.delete();
assert true;
}
}
@Test
@@ -324,7 +356,7 @@ public class AppTest extends AbstractGitHubWireMockTest {
assertEquals(teamByName.getId(), teamById.getId());
assertEquals(teamByName.getDescription(), teamById.getDescription());
GHTeam teamById2 = organization.getTeam((int) teamByName.getId());
GHTeam teamById2 = organization.getTeam(teamByName.getId());
assertNotNull(teamById2);
assertEquals(teamByName.getId(), teamById2.getId());
@@ -445,6 +477,16 @@ public class AppTest extends AbstractGitHubWireMockTest {
File f = commit.getFiles().get(0);
assertEquals(48, f.getLinesChanged());
assertThat(f.getLinesAdded(), equalTo(40));
assertThat(f.getLinesDeleted(), equalTo(8));
assertThat(f.getPreviousFilename(), nullValue());
assertThat(f.getPatch(), startsWith("@@ -54,6 +54,14 @@\n"));
assertThat(f.getSha(), equalTo("04d3e54017542ad0ff46355eababacd4850ccba5"));
assertThat(f.getBlobUrl().toString(),
equalTo("https://github.com/jenkinsci/jenkins/blob/08c1c9970af4d609ae754fbe803e06186e3206f7/changelog.html"));
assertThat(f.getRawUrl().toString(),
equalTo("https://github.com/jenkinsci/jenkins/raw/08c1c9970af4d609ae754fbe803e06186e3206f7/changelog.html"));
assertEquals("modified", f.getStatus());
assertEquals("changelog.html", f.getFileName());
@@ -464,22 +506,6 @@ public class AppTest extends AbstractGitHubWireMockTest {
assertEquals(1, sha1.size());
}
public void testQueryCommits() throws Exception {
List<String> sha1 = new ArrayList<String>();
for (GHCommit c : gitHub.getUser("jenkinsci")
.getRepository("jenkins")
.queryCommits()
.since(new Date(1199174400000L))
.until(1201852800000L)
.path("pom.xml")
.list()) {
// System.out.println(c.getSHA1());
sha1.add(c.getSHA1());
}
assertEquals("1cccddb22e305397151b2b7b87b4b47d74ca337b", sha1.get(0));
assertEquals(29, sha1.size());
}
@Ignore("Needs mocking check")
@Test
public void testBranches() throws Exception {
@@ -504,23 +530,65 @@ public class AppTest extends AbstractGitHubWireMockTest {
.getRepository("sandbox-ant")
.getCommit("8ae38db0ea5837313ab5f39d43a6f73de3bd9000");
GHCommitComment c = commit.createComment("[testing](http://kohsuse.org/)");
// System.out.println(c);
c.update("updated text");
// System.out.println(c);
c.delete();
try {
assertThat(c.getPath(), nullValue());
assertThat(c.getLine(), equalTo(-1));
assertThat(c.getHtmlUrl().toString(),
containsString(
"kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000#commitcomment-"));
assertThat(c.listReactions().toList(), is(empty()));
c.update("updated text");
assertThat(c.getBody(), equalTo("updated text"));
} finally {
c.delete();
}
}
@Test
public void tryHook() throws Exception {
kohsuke();
GHRepository r = gitHub.getOrganization(GITHUB_API_TEST_ORG).getRepository("github-api");
GHHook hook = r.createWebHook(new URL("http://www.google.com/"));
// System.out.println(hook);
GHOrganization o = gitHub.getOrganization(GITHUB_API_TEST_ORG);
GHRepository r = o.getRepository("github-api");
try {
GHHook hook = r.createWebHook(new URL("http://www.google.com/"));
assertThat(hook.getName(), equalTo("web"));
assertThat(hook.getEvents().size(), equalTo(1));
assertThat(hook.getEvents(), contains(GHEvent.PUSH));
assertThat(hook.getConfig().size(), equalTo(3));
assertThat(hook.isActive(), equalTo(true));
if (mockGitHub.isUseProxy()) {
r = getGitHubBeforeAfter().getOrganization(GITHUB_API_TEST_ORG).getRepository("github-api");
for (GHHook h : r.getHooks()) {
h.delete();
GHHook hook2 = r.getHook((int) hook.getId());
assertThat(hook2.getName(), equalTo("web"));
assertThat(hook2.getEvents().size(), equalTo(1));
assertThat(hook2.getEvents(), contains(GHEvent.PUSH));
assertThat(hook2.getConfig().size(), equalTo(3));
assertThat(hook2.isActive(), equalTo(true));
hook2.ping();
hook2.delete();
hook = o.createWebHook(new URL("http://www.google.com/"));
assertThat(hook.getName(), equalTo("web"));
assertThat(hook.getEvents().size(), equalTo(1));
assertThat(hook.getEvents(), contains(GHEvent.PUSH));
assertThat(hook.getConfig().size(), equalTo(3));
assertThat(hook.isActive(), equalTo(true));
hook2 = o.getHook((int) hook.getId());
assertThat(hook2.getName(), equalTo("web"));
assertThat(hook2.getEvents().size(), equalTo(1));
assertThat(hook2.getEvents(), contains(GHEvent.PUSH));
assertThat(hook2.getConfig().size(), equalTo(3));
assertThat(hook2.isActive(), equalTo(true));
hook2.ping();
hook2.delete();
// System.out.println(hook);
} finally {
if (mockGitHub.isUseProxy()) {
r = getGitHubBeforeAfter().getOrganization(GITHUB_API_TEST_ORG).getRepository("github-api");
for (GHHook h : r.getHooks()) {
h.delete();
}
}
}
}
@@ -529,6 +597,14 @@ public class AppTest extends AbstractGitHubWireMockTest {
public void testEventApi() throws Exception {
for (GHEventInfo ev : gitHub.getEvents()) {
if (ev.getType() == GHEvent.PULL_REQUEST) {
if (ev.getId() == 10680625394L) {
assertThat(ev.getActorLogin(), equalTo("pull[bot]"));
assertThat(ev.getOrganization(), nullValue());
assertThat(ev.getRepository().getFullName(), equalTo("daddyfatstacksBIG/lerna"));
assertThat(ev.getCreatedAt(), equalTo(GitHubClient.parseDate("2019-10-21T21:54:52Z")));
assertThat(ev.getType(), equalTo(GHEvent.PULL_REQUEST));
}
GHEventPayload.PullRequest pr = ev.getPayload(GHEventPayload.PullRequest.class);
assertThat(pr.getNumber(), is(pr.getPullRequest().getNumber()));
}
@@ -859,8 +935,18 @@ public class AppTest extends AbstractGitHubWireMockTest {
for (GHTreeEntry e : masterTree.getTree()) {
if (e.getPath().endsWith(AppTest.class.getSimpleName() + ".java")) {
foundThisFile = true;
assertThat(e.getPath(), equalTo("src/test/java/org/kohsuke/github/AppTest.java"));
assertThat(e.getSha(), equalTo("baad7a7c4cf409f610a0e8c7eba17664eb655c44"));
assertThat(e.getMode(), equalTo("100755"));
assertThat(e.getSize(), greaterThan(30000L));
assertThat(e.getUrl().toString(),
containsString("/repos/hub4j/github-api/git/blobs/baad7a7c4cf409f610a0e8c7eba17664eb655c44"));
GHBlob blob = e.asBlob();
assertThat(e.asBlob().getUrl().toString(),
containsString("/repos/hub4j/github-api/git/blobs/baad7a7c4cf409f610a0e8c7eba17664eb655c44"));
break;
}
}
assertTrue(foundThisFile);
}

View File

@@ -4,7 +4,9 @@ import com.google.common.collect.Iterables;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import static org.hamcrest.Matchers.equalTo;
@@ -29,6 +31,85 @@ public class CommitTest extends AbstractGitHubWireMockTest {
}
}
@Test
public void testQueryCommits() throws Exception {
List<String> sha1 = new ArrayList<String>();
List<GHCommit> commits = gitHub.getUser("jenkinsci")
.getRepository("jenkins")
.queryCommits()
.since(1199174400000L)
.until(1201852800000L)
.path("pom.xml")
.pageSize(100)
.list()
.toList();
assertThat(commits.get(0).getSHA1(), equalTo("1cccddb22e305397151b2b7b87b4b47d74ca337b"));
assertThat(commits.size(), equalTo(29));
commits = gitHub.getUser("jenkinsci")
.getRepository("jenkins")
.queryCommits()
.since(new Date(1199174400000L))
.until(new Date(1201852800000L))
.path("pom.xml")
.pageSize(100)
.list()
.toList();
assertThat(commits.get(0).getSHA1(), equalTo("1cccddb22e305397151b2b7b87b4b47d74ca337b"));
assertThat(commits.get(15).getSHA1(), equalTo("a5259970acaec9813e2a12a91f37dfc7871a5ef5"));
assertThat(commits.size(), equalTo(29));
commits = gitHub.getUser("jenkinsci")
.getRepository("jenkins")
.queryCommits()
.since(new Date(1199174400000L))
.until(new Date(1201852800000L))
.path("pom.xml")
.from("a5259970acaec9813e2a12a91f37dfc7871a5ef5")
.list()
.toList();
assertThat(commits.get(0).getSHA1(), equalTo("a5259970acaec9813e2a12a91f37dfc7871a5ef5"));
assertThat(commits.size(), equalTo(14));
commits = gitHub.getUser("jenkinsci")
.getRepository("jenkins")
.queryCommits()
.until(new Date(1201852800000L))
.path("pom.xml")
.author("kohsuke")
.list()
.toList();
assertThat(commits.size(), equalTo(0));
commits = gitHub.getUser("jenkinsci")
.getRepository("jenkins")
.queryCommits()
.until(new Date(1201852800000L))
.path("pom.xml")
.pageSize(100)
.author("kohsuke@71c3de6d-444a-0410-be80-ed276b4c234a")
.list()
.toList();
assertThat(commits.size(), equalTo(266));
commits = gitHub.getUser("jenkinsci")
.getRepository("jenkins")
.queryCommits()
.path("pom.xml")
.pageSize(100)
.author("kohsuke@71c3de6d-444a-0410-be80-ed276b4c234a")
.list()
.toList();
assertThat(commits.size(), equalTo(648));
}
@Test
public void listPullRequestsOfNotIncludedCommit() throws Exception {
GHRepository repo = gitHub.getOrganization("hub4j-test-org").getRepository("listPrsListHeads");

View File

@@ -0,0 +1,84 @@
package org.kohsuke.github;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.*;
/**
* Unit test for {@link GitHub} static helpers.
*
* @author Liam Newman
*/
public class EnumTest extends AbstractGitHubWireMockTest {
@Test
public void touchEnums() {
assertThat(GHCheckRun.AnnotationLevel.values().length, equalTo(3));
assertThat(GHCheckRun.Conclusion.values().length, equalTo(7));
assertThat(GHCheckRun.Status.values().length, equalTo(3));
assertThat(GHCommentAuthorAssociation.values().length, equalTo(7));
assertThat(GHCommitState.values().length, equalTo(4));
assertThat(GHCompare.Status.values().length, equalTo(4));
assertThat(GHDeploymentState.values().length, equalTo(7));
assertThat(GHDirection.values().length, equalTo(2));
assertThat(GHEvent.values().length, equalTo(56));
assertThat(GHEvent.ALL.symbol(), equalTo("*"));
assertThat(GHEvent.PULL_REQUEST.symbol(), equalTo(GHEvent.PULL_REQUEST.toString().toLowerCase()));
assertThat(GHIssueSearchBuilder.Sort.values().length, equalTo(3));
assertThat(GHIssueState.values().length, equalTo(3));
assertThat(GHMarketplaceAccountType.values().length, equalTo(2));
assertThat(GHMarketplaceListAccountBuilder.Sort.values().length, equalTo(2));
assertThat(GHMarketplacePriceModel.values().length, equalTo(3));
assertThat(GHMembership.Role.values().length, equalTo(2));
assertThat(GHMilestoneState.values().length, equalTo(2));
assertThat(GHMyself.RepositoryListFilter.values().length, equalTo(5));
assertThat(GHOrganization.Role.values().length, equalTo(2));
assertThat(GHOrganization.Permission.values().length, equalTo(5));
assertThat(GHPermissionType.values().length, equalTo(4));
assertThat(GHProject.ProjectState.values().length, equalTo(2));
assertThat(GHProject.ProjectStateFilter.values().length, equalTo(3));
assertThat(GHPullRequest.MergeMethod.values().length, equalTo(3));
assertThat(GHPullRequestQueryBuilder.Sort.values().length, equalTo(4));
assertThat(GHPullRequestReviewEvent.values().length, equalTo(4));
assertThat(GHPullRequestReviewEvent.PENDING.toState(), equalTo(GHPullRequestReviewState.PENDING));
assertThat(GHPullRequestReviewEvent.PENDING.action(), nullValue());
assertThat(GHPullRequestReviewState.values().length, equalTo(6));
assertThat(GHPullRequestReviewState.PENDING.toEvent(), equalTo(GHPullRequestReviewEvent.PENDING));
assertThat(GHPullRequestReviewState.APPROVED.action(), equalTo(GHPullRequestReviewEvent.APPROVE.action()));
assertThat(GHPullRequestReviewState.DISMISSED.toEvent(), nullValue());
assertThat(GHRepository.CollaboratorAffiliation.values().length, equalTo(3));
assertThat(GHRepository.ForkSort.values().length, equalTo(3));
assertThat(GHRepositorySearchBuilder.Sort.values().length, equalTo(3));
assertThat(GHRepositorySelection.values().length, equalTo(2));
assertThat(GHTeam.Role.values().length, equalTo(2));
assertThat(GHTeam.Privacy.values().length, equalTo(2));
assertThat(GHUserSearchBuilder.Sort.values().length, equalTo(3));
}
}

View File

@@ -103,7 +103,8 @@ public class GHAppTest extends AbstractGitHubWireMockTest {
permissions.put("metadata", GHPermissionType.READ);
// Create token specifying both permissions and repository ids
GHAppInstallationToken installationToken = installation.createToken(permissions)
GHAppInstallationToken installationToken = installation.createToken()
.permissions(permissions)
.repositoryIds(Collections.singletonList((long) 111111111))
.create();

View File

@@ -30,6 +30,7 @@ import java.io.IOException;
import java.util.Date;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
@SuppressWarnings("deprecation") // preview
public class GHCheckRunBuilderTest extends AbstractGHAppInstallationTest {
@@ -48,7 +49,7 @@ public class GHCheckRunBuilderTest extends AbstractGHAppInstallationTest {
.withExternalID("whatever")
.withStartedAt(new Date(999_999_000))
.withCompletedAt(new Date(999_999_999))
.add(new GHCheckRunBuilder.Output("Some Title", "what happened…")
.add(new GHCheckRunBuilder.Output("Some Title", "what happened…").withText("Hello Text!")
.add(new GHCheckRunBuilder.Annotation("stuff.txt",
1,
GHCheckRun.AnnotationLevel.NOTICE,
@@ -61,11 +62,14 @@ public class GHCheckRunBuilderTest extends AbstractGHAppInstallationTest {
assertEquals("completed", checkRun.getStatus());
assertEquals(1, checkRun.getOutput().getAnnotationsCount());
assertEquals(1424883286, checkRun.getId());
assertEquals("Hello Text!", checkRun.getOutput().getText());
}
@Test
public void createCheckRunManyAnnotations() throws Exception {
GHCheckRunBuilder.Output output = new GHCheckRunBuilder.Output("Big Run", "Lots of stuff here »");
GHCheckRunBuilder.Output output = new GHCheckRunBuilder.Output("Big Run", "Lots of stuff here »")
.withText("Hello Text!");
for (int i = 0; i < 101; i++) {
output.add(
new GHCheckRunBuilder.Annotation("stuff.txt", 1, GHCheckRun.AnnotationLevel.NOTICE, "hello #" + i));
@@ -79,6 +83,7 @@ public class GHCheckRunBuilderTest extends AbstractGHAppInstallationTest {
assertEquals("Big Run", checkRun.getOutput().getTitle());
assertEquals("Lots of stuff here »", checkRun.getOutput().getSummary());
assertEquals(101, checkRun.getOutput().getAnnotationsCount());
assertEquals("Hello Text!", checkRun.getOutput().getText());
assertEquals(1424883599, checkRun.getId());
}
@@ -116,6 +121,8 @@ public class GHCheckRunBuilderTest extends AbstractGHAppInstallationTest {
} catch (HttpException x) {
assertEquals(422, x.getResponseCode());
assertThat(x.getMessage(), containsString("\\\"conclusion\\\" wasn't supplied"));
assertThat(x.getUrl(), containsString("/repos/hub4j-test-org/test-checks/check-runs"));
assertThat(x.getResponseMessage(), equalTo("422 Unprocessable Entity"));
}
}

View File

@@ -361,6 +361,9 @@ public class GHEventPayloadTest extends AbstractGitHubWireMockTest {
assertThat(event.getCommits().get(0).getRemoved().size(), is(0));
assertThat(event.getCommits().get(0).getModified().size(), is(1));
assertThat(event.getCommits().get(0).getModified().get(0), is("README.md"));
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
assertThat(formatter.format(event.getCommits().get(0).getTimestamp()), is("2015-05-05T23:40:15Z"));
assertThat(event.getRepository().getName(), is("public-repo"));
assertThat(event.getRepository().getOwnerName(), is("baxterthehacker"));
assertThat(event.getRepository().getUrl().toExternalForm(),
@@ -515,6 +518,7 @@ public class GHEventPayloadTest extends AbstractGitHubWireMockTest {
assertThat(event.getRepository().getName(), is("Hello-World"));
assertThat(event.getRepository().getOwner().getLogin(), is("Codertocat"));
assertThat(event.getAction(), is("created"));
assertThat(event.getRequestedAction(), nullValue());
// Checks the deserialization of check_run
GHCheckRun checkRun = event.getCheckRun();

View File

@@ -79,9 +79,19 @@ public class GHLicenseTest extends AbstractGitHubWireMockTest {
String key = "mit";
GHLicense license = gitHub.getLicense(key);
assertNotNull(license);
assertTrue("The name is correct", license.getName().equals("MIT License"));
assertTrue("The HTML URL is correct",
license.getHtmlUrl().equals(new URL("http://choosealicense.com/licenses/mit/")));
assertThat("The name is correct", license.getName(), equalTo("MIT License"));
assertThat("The HTML URL is correct",
license.getHtmlUrl(),
equalTo(new URL("http://choosealicense.com/licenses/mit/")));
assertThat(license.getBody(), startsWith("MIT License\n" + "\n" + "Copyright (c) [year] [fullname]\n\n"));
assertThat(license.getForbidden().size(), equalTo(0));
assertThat(license.getPermitted().size(), equalTo(0));
assertThat(license.getImplementation(),
equalTo("Create a text file (typically named LICENSE or LICENSE.txt) in the root of your source code and copy the text of the license into the file. Replace [year] with the current year and [fullname] with the name (or names) of the copyright holders."));
assertThat(license.getCategory(), nullValue());
assertThat(license.isFeatured(), equalTo(true));
assertThat(license.equals(null), equalTo(false));
assertThat(license.equals(gitHub.getLicense(key)), equalTo(true));
}
/**

View File

@@ -36,11 +36,12 @@ public class GHOrganizationTest extends AbstractGitHubWireMockTest {
cleanupRepository(GITHUB_API_TEST_ORG + '/' + GITHUB_API_TEST);
GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG);
GHRepository repository = org.createRepository(GITHUB_API_TEST,
"a test repository used to test kohsuke's github-api",
"http://github-api.kohsuke.org/",
"Core Developers",
true);
GHRepository repository = org.createRepository(GITHUB_API_TEST)
.description("a test repository used to test kohsuke's github-api")
.homepage("http://github-api.kohsuke.org/")
.team(org.getTeamByName("Core Developers"))
.private_(false)
.create();
Assert.assertNotNull(repository);
}
@@ -72,7 +73,7 @@ public class GHOrganizationTest extends AbstractGitHubWireMockTest {
.homepage("http://github-api.kohsuke.org/")
.team(team)
.autoInit(true)
.templateRepository(true)
.isTemplate(true)
.create();
Assert.assertNotNull(repository);
assertThat(mockGitHub.getRequestCount(), equalTo(requestCount + 1));
@@ -136,7 +137,7 @@ public class GHOrganizationTest extends AbstractGitHubWireMockTest {
public void testListMembersWithFilter() throws IOException {
GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG);
List<GHUser> admins = org.listMembersWithFilter("all").asList();
List<GHUser> admins = org.listMembersWithFilter("all").toList();
assertNotNull(admins);
assertTrue(admins.size() >= 12); // In case more are added in the future
@@ -158,7 +159,7 @@ public class GHOrganizationTest extends AbstractGitHubWireMockTest {
public void testListMembersWithRole() throws IOException {
GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG);
List<GHUser> admins = org.listMembersWithRole("admin").asList();
List<GHUser> admins = org.listMembersWithRole("admin").toList();
assertNotNull(admins);
assertTrue(admins.size() >= 12); // In case more are added in the future

View File

@@ -0,0 +1,21 @@
package org.kohsuke.github;
import org.junit.Test;
import java.io.IOException;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class GHPullRequestMockTest {
@Test
public void shouldMockGHPullRequest() throws IOException {
GHPullRequest pullRequest = mock(GHPullRequest.class);
when(pullRequest.isDraft()).thenReturn(true);
assertTrue("Mock should return true", pullRequest.isDraft());
}
}

View File

@@ -5,7 +5,6 @@ import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -112,28 +111,52 @@ public class GHPullRequestTest extends AbstractGitHubWireMockTest {
public void pullRequestReviewComments() throws Exception {
String name = "pullRequestReviewComments";
GHPullRequest p = getRepository().createPullRequest(name, "test/stable", "master", "## test");
// System.out.println(p.getUrl());
assertTrue(p.listReviewComments().toList().isEmpty());
p.createReviewComment("Sample review comment", p.getHead().getSha(), "README.md", 1);
List<GHPullRequestReviewComment> comments = p.listReviewComments().toList();
assertEquals(1, comments.size());
GHPullRequestReviewComment comment = comments.get(0);
assertEquals("Sample review comment", comment.getBody());
try {
// System.out.println(p.getUrl());
assertTrue(p.listReviewComments().toList().isEmpty());
p.createReviewComment("Sample review comment", p.getHead().getSha(), "README.md", 1);
List<GHPullRequestReviewComment> comments = p.listReviewComments().toList();
assertEquals(1, comments.size());
GHPullRequestReviewComment comment = comments.get(0);
assertEquals("Sample review comment", comment.getBody());
assertThat(comment.getInReplyToId(), equalTo(-1L));
assertThat(comment.getPath(), equalTo("README.md"));
assertThat(comment.getPosition(), equalTo(1));
assertThat(comment.getUser(), notNullValue());
// Assert htmlUrl is not null
assertThat(comment.getHtmlUrl(), notNullValue());
assertThat(comment.getHtmlUrl().toString(),
containsString("hub4j-test-org/github-api/pull/" + p.getNumber()));
// Assert htmlUrl is not null
assertNotNull(comment.getHtmlUrl());
assertEquals(new URL("https://github.com/hub4j-test-org/github-api/pull/266#discussion_r321995146"),
comment.getHtmlUrl());
List<GHReaction> reactions = comment.listReactions().toList();
assertThat(reactions.size(), equalTo(0));
comment.update("Updated review comment");
comments = p.listReviewComments().toList();
assertEquals(1, comments.size());
comment = comments.get(0);
assertEquals("Updated review comment", comment.getBody());
GHReaction reaction = comment.createReaction(ReactionContent.CONFUSED);
assertThat(reaction.getContent(), equalTo(ReactionContent.CONFUSED));
comment.delete();
comments = p.listReviewComments().toList();
assertTrue(comments.isEmpty());
reactions = comment.listReactions().toList();
assertThat(reactions.size(), equalTo(1));
GHPullRequestReviewComment reply = comment.reply("This is a reply.");
assertThat(reply.getInReplyToId(), equalTo(comment.getId()));
comments = p.listReviewComments().toList();
assertEquals(2, comments.size());
comment.update("Updated review comment");
comments = p.listReviewComments().toList();
comment = comments.get(0);
assertEquals("Updated review comment", comment.getBody());
comment.delete();
comments = p.listReviewComments().toList();
// Reply is still present after delete of original comment, but no longer has replyToId
assertThat(comments.size(), equalTo(1));
assertThat(comments.get(0).getId(), equalTo(reply.getId()));
assertThat(comments.get(0).getInReplyToId(), equalTo(-1L));
} finally {
p.close();
}
}
@Test
@@ -412,15 +435,15 @@ public class GHPullRequestTest extends AbstractGitHubWireMockTest {
public void getUserTest() throws IOException {
GHPullRequest p = getRepository().createPullRequest("getUserTest", "test/stable", "master", "## test");
GHPullRequest prSingle = getRepository().getPullRequest(p.getNumber());
assertNotNull(prSingle.getUser().root);
assertNotNull(prSingle.getUser().getRoot());
prSingle.getMergeable();
assertNotNull(prSingle.getUser().root);
assertNotNull(prSingle.getUser().getRoot());
PagedIterable<GHPullRequest> ghPullRequests = getRepository().listPullRequests(GHIssueState.OPEN);
for (GHPullRequest pr : ghPullRequests) {
assertNotNull(pr.getUser().root);
assertNotNull(pr.getUser().getRoot());
pr.getMergeable();
assertNotNull(pr.getUser().root);
assertNotNull(pr.getUser().getRoot());
}
}

View File

@@ -312,9 +312,6 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
// Give this a moment
Thread.sleep(1500);
// lastRateLimit the same as rateLimit
assertThat(gitHub.lastRateLimit(), sameInstance(rateLimit));
// ratelimit() tries not to make additional requests, uses queried rate limit since header not available
Thread.sleep(1500);
assertThat(gitHub.rateLimit(), sameInstance(rateLimit));
@@ -490,9 +487,6 @@ public class GHRateLimitTest extends AbstractGitHubWireMockTest {
assertThat("rateLimit() selects header instance when not expired, does not ask server",
gitHub.rateLimit(),
sameInstance(headerRateLimit));
assertThat("lastRateLimit() always selects header instance, does not ask server",
gitHub.lastRateLimit(),
sameInstance(headerRateLimit));
assertThat(mockGitHub.getRequestCount(), equalTo(1));

View File

@@ -34,6 +34,7 @@ public class GHRepositoryStatisticsTest extends AbstractGitHubWireMockTest {
for (GHRepositoryStatistics.ContributorStats statsForAuthor : list) {
if (authorLogin.equals(statsForAuthor.getAuthor().getLogin())) {
assertEquals(715, statsForAuthor.getTotal());
assertEquals("kohsuke made 715 contributions over 494 weeks", statsForAuthor.toString());
List<GHRepositoryStatistics.ContributorStats.Week> weeks = statsForAuthor.getWeeks();
assertEquals(494, weeks.size());
@@ -46,6 +47,8 @@ public class GHRepositoryStatisticsTest extends AbstractGitHubWireMockTest {
assertEquals(63, week.getNumberOfAdditions());
assertEquals(56, week.getNumberOfDeletions());
assertEquals(5, week.getNumberOfCommits());
assertEquals("Week starting 1541289600 - Additions: 63, Deletions: 56, Commits: 5",
week.toString());
} catch (NoSuchElementException e) {
fail("Did not find week 1546128000");
}
@@ -131,6 +134,7 @@ public class GHRepositoryStatisticsTest extends AbstractGitHubWireMockTest {
if (item.getWeekTimestamp() == 1535241600) {
assertEquals(185, item.getAdditions());
assertEquals(-243, item.getDeletions());
assertEquals("Week starting 1535241600 has 185 additions and 243 deletions", item.toString());
foundWeek = true;
break;
}
@@ -196,6 +200,7 @@ public class GHRepositoryStatisticsTest extends AbstractGitHubWireMockTest {
// TODO: Make an easier access method. Perhaps wrap in an
// object and have a method such as GetCommits(1, 16).
assertEquals(16, item.getNumberOfCommits());
assertEquals("Day 2 Hour 10: 16 commits", item.toString());
hourFound = true;
break;
}

View File

@@ -10,6 +10,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
@@ -126,6 +127,19 @@ public class GHRepositoryTest extends AbstractGitHubWireMockTest {
assertEquals(UNKNOWN_SIGNATURE_TYPE, verification.getReason());
}
@Test
public void listStargazers() throws IOException {
GHRepository repository = getRepository();
assertThat(repository.listStargazers2().toList(), empty());
repository = gitHub.getOrganization("hub4j").getRepository("github-api");
Iterable<GHStargazer> stargazers = repository.listStargazers2();
GHStargazer stargazer = stargazers.iterator().next();
assertThat(stargazer.getStarredAt(), equalTo(new Date(1271650383000L)));
assertThat(stargazer.getUser().getLogin(), equalTo("nielswind"));
assertThat(stargazer.getRepository(), sameInstance(repository));
}
// Issue #607
@Test
public void getBranchNonExistentBut200Status() throws Exception {
@@ -151,11 +165,20 @@ public class GHRepositoryTest extends AbstractGitHubWireMockTest {
public void subscription() throws Exception {
GHRepository r = getRepository();
assertNull(r.getSubscription());
GHSubscription s = r.subscribe(true, false);
assertEquals(s.getRepository(), r);
try {
s.delete();
assertEquals(s.getRepository(), r);
assertThat(s.isIgnored(), equalTo(false));
assertThat(s.isSubscribed(), equalTo(true));
assertThat(s.getRepositoryUrl().toString(), containsString("/repos/hub4j-test-org/github-api"));
assertThat(s.getUrl().toString(), containsString("/repos/hub4j-test-org/github-api/subscription"));
assertThat(s.getReason(), nullValue());
assertThat(s.getCreatedAt(), equalTo(new Date(1611377286000L)));
} finally {
s.delete();
}
assertNull(r.getSubscription());
}
@@ -657,17 +680,6 @@ public class GHRepositoryTest extends AbstractGitHubWireMockTest {
assertThat(e, instanceOf(GHFileNotFoundException.class));
assertThat(e.getMessage(), containsString("/repos/hub4j-test-org/temp-listRefsEmptyTags/git/refs/tags"));
}
try {
GHRepository repo = getTempRepository();
repo.listRefs("tags").asList();
fail();
} catch (Exception e) {
assertThat(e, instanceOf(GHException.class));
assertThat(e.getMessage(), containsString("Failed to retrieve "));
assertThat(e.getMessage(), containsString("/repos/hub4j-test-org/temp-listRefsEmptyTags/git/refs/tags"));
assertThat(e.getCause(), instanceOf(GHFileNotFoundException.class));
}
}
@Test

View File

@@ -6,6 +6,7 @@ import org.junit.Test;
import java.io.IOException;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -49,6 +50,10 @@ public class GHTagTest extends AbstractGitHubWireMockTest {
assertEquals(commitSha, tag.getObject().getSha());
assertFalse(tag.getVerification().isVerified());
assertEquals(tag.getVerification().getReason(), GHVerification.Reason.UNSIGNED);
assertThat(tag.getUrl(),
containsString("/repos/hub4j-test-org/github-api/git/tags/e7aa6d4afbaa48669f0bbe11ca3c4d787b2b153c"));
assertThat(tag.getOwner().getId(), equalTo(repo.getId()));
assertThat(tag.getTagger().getEmail(), equalTo("martin.vanzijl@gmail.com"));
// Make a reference to the newly created tag.
GHRef ref = repo.createRef("refs/tags/" + tagName, tag.getSha());

View File

@@ -41,7 +41,7 @@ public class GHTeamTest extends AbstractGitHubWireMockTest {
GHTeam team = gitHub.getOrganization(GITHUB_API_TEST_ORG).getTeamBySlug(teamSlug);
List<GHUser> admins = team.listMembers("admin").asList();
List<GHUser> admins = team.listMembers("admin").toList();
assertNotNull(admins);
assertThat("One admin in dummy team", admins.size() == 1);
@@ -55,7 +55,7 @@ public class GHTeamTest extends AbstractGitHubWireMockTest {
GHTeam team = gitHub.getOrganization(GITHUB_API_TEST_ORG).getTeamBySlug(teamSlug);
List<GHUser> justMembers = team.listMembers("member").asList();
List<GHUser> justMembers = team.listMembers("member").toList();
assertThat("No regular members in team", justMembers.isEmpty());
}

View File

@@ -7,7 +7,9 @@ import org.junit.Test;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertEquals;
public class GHTreeBuilderTest extends AbstractGitHubWireMockTest {
@@ -87,22 +89,30 @@ public class GHTreeBuilderTest extends AbstractGitHubWireMockTest {
treeBuilder.add(PATH_DATA1, CONTENT_DATA1, false);
treeBuilder.add(PATH_DATA2, CONTENT_DATA2, false);
updateTree();
GHCommit commit = updateTree();
assertEquals(CONTENT_SCRIPT.length(), getFileSize(PATH_SCRIPT));
assertEquals(CONTENT_README.length(), getFileSize(PATH_README));
assertEquals(CONTENT_DATA1.length, getFileSize(PATH_DATA1));
assertEquals(CONTENT_DATA2.length, getFileSize(PATH_DATA2));
assertThat(commit.getCommitShortInfo().getAuthor().getEmail(), equalTo("author@author.com"));
assertThat(commit.getCommitShortInfo().getCommitter().getEmail(), equalTo("committer@committer.com"));
}
private void updateTree() throws IOException {
private GHCommit updateTree() throws IOException {
String treeSha = treeBuilder.create().getSha();
String commitSha = new GHCommitBuilder(repo).message("Add files")
GHCommit commit = new GHCommitBuilder(repo).message("Add files")
.tree(treeSha)
.author("author", "author@author.com", new Date(1611433225969L))
.committer("committer", "committer@committer.com", new Date(1611433225968L))
.parent(masterRef.getObject().getSha())
.create()
.getSHA1();
.create();
String commitSha = commit.getSHA1();
masterRef.updateTo(commitSha);
return commit;
}
private long getFileSize(String path) throws IOException {

View File

@@ -39,14 +39,27 @@ public class GHUserTest extends AbstractGitHubWireMockTest {
}
});
assertEquals(1066173, ghKeys.get(0).getId());
assertThat(ghKeys.get(0).getTitle(), nullValue());
assertThat(ghKeys.get(0).getUrl(), nullValue());
assertThat(ghKeys.get(0).isVerified(), equalTo(false));
assertThat(ghKeys.get(0).toString(),
containsString(
"title=<null>,id=1066173,key=ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAueiy12T5bvFhsc9YjfLc3aVIxgySd3gDxQWy/bletIoZL8omKmzocBYJ7F58U1asoyfWsy2ToTOY8jJp1eToXmbD6L5+xvHba0A7djYh9aQRrFam7doKQ0zp0ZSUF6+R1v0OM4nnWqK4n2ECIYd+Bdzrp+xA5+XlW3ZSNzlnW2BeWznzmgRMcp6wI+zQ9GMHWviR1cxpml5Z6wrxTZ0aX91btvnNPqoOGva976B6e6403FOEkkIFTk6CC1TFKwc/VjbqxYBg4kU0JhiTP+iEZibcQrYjWdYUgAotYbFVe5/DneHMLNsMPdeihba4PUwt62rXyNegenuCRmCntLcaFQ=="));
assertEquals(
"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAueiy12T5bvFhsc9YjfLc3aVIxgySd3gDxQWy/bletIoZL8omKmzocBYJ7F58U1asoyfWsy2ToTOY8jJp1eToXmbD6L5+xvHba0A7djYh9aQRrFam7doKQ0zp0ZSUF6+R1v0OM4nnWqK4n2ECIYd+Bdzrp+xA5+XlW3ZSNzlnW2BeWznzmgRMcp6wI+zQ9GMHWviR1cxpml5Z6wrxTZ0aX91btvnNPqoOGva976B6e6403FOEkkIFTk6CC1TFKwc/VjbqxYBg4kU0JhiTP+iEZibcQrYjWdYUgAotYbFVe5/DneHMLNsMPdeihba4PUwt62rXyNegenuCRmCntLcaFQ==",
ghKeys.get(0).getKey());
assertEquals(28136459, ghKeys.get(1).getId());
assertThat(ghKeys.get(1).getTitle(), nullValue());
assertThat(ghKeys.get(1).getUrl(), nullValue());
assertThat(ghKeys.get(1).isVerified(), equalTo(false));
assertEquals(
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDTU0s5OKCC6VpKZGL9NJD4mNLY0AtujkVB1JkkuQ4OkMi2YGUHJtGhTbTwEVhNxpm0x2dM5KSzse6MLDYuGBW0qkE/VVuD9+9I73hbq461KqP0+WlupNh+Qc86kbiLBDv64+vWc+50mp1dbINpoM5xvaPYxgjnemydPv7vu5bhCHBugW7aN8VcLgfFgcp8vZCEanMtd3hIRjRU8v8Skk233ZGu1bXkG8iIOBQPabvEtZ0VDMg9pT3Q1R6lnnKqfCwHXd6zP6uAtejFSxvKRGKpu3OLGQMHwk7NlImVuhkVdaEFBq7pQtpOaGuP2eLKcN1wy5jsTYE+ZB6pvHCi2ecb",
ghKeys.get(1).getKey());
assertEquals(31452581, ghKeys.get(2).getId());
assertThat(ghKeys.get(2).getTitle(), nullValue());
assertThat(ghKeys.get(2).getUrl(), nullValue());
assertThat(ghKeys.get(2).isVerified(), equalTo(false));
assertEquals(
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC3JhH2FZBDmHLjXTcBoV6tdcYKmsQ7sgu8k1RsUhwxGsXm65+Cuas6GcMVoA1DncKfJGQkulHDFiTxIROIBmedh9/otHWBlZ4HqYZ4MQ1A8W5quULkXwX/kF+UdRBUxFvjigibEbuHB+LARVxRRzFlPnTSE9rAfAv8OOEsb3lNUGT/IGhN8w1vwe8GclB90tgqN1RBDgrVqwLFwn5AfrW9kUIa2f2oT4RjYu1OrhKhVIIzfHADo85aD+s8wEhqwI96BCJG3qTWrypoHwBUoj1O6Ak5CGc1iKz9o8XyTMjudRt2ddCjfOtxsuwSlTbVtQXJGIpgKviX1sgh4pPvGh7BVAFP+mdAK4F+mEugDnuj47GO/K5KGGDRCL56kh9+h28l4q/+fZvp7DhtmSN2EzrVAdQFskF8yY/6Xit/aAvjeKm03DcjbylSXbG26EJefaLHlwYFq2mUFRMak25wuuCZS71GF3RC3Sl/bMoxBKRYkyfYtGafeaYTFNGn8Dbd+hfVUCz31ebI8cvmlQR5b5AbCre3T7HTVgw8FKbAxWRf1Fio56PnqHsj+sT1KVj255Zo1F8iD9GrgERSVAlkh5bY/CKszQ8ZSd01c9Qp2a47/gR7XAAbxhzGHP+cSOlrqDlJ24fbPtcpVsM0llqKUcxpmoOBFNboRmE1QqnSmAf9ww==",
ghKeys.get(2).getKey());
@@ -109,5 +122,11 @@ public class GHUserTest extends AbstractGitHubWireMockTest {
assertThat(u.getBio(), equalTo("I like to program things and I hope to program something cool one day :D"));
assertTrue(u.isHireable());
assertNotNull(u.getTwitterUsername());
assertThat(u.getBlog(), equalTo("https://chew.pw"));
assertThat(u.getCompany(), equalTo("@Memerator"));
assertThat(u.getFollowersCount(), equalTo(29));
assertThat(u.getFollowingCount(), equalTo(3));
assertThat(u.getPublicGistCount(), equalTo(4));
assertThat(u.getPublicRepoCount(), equalTo(96));
}
}

View File

@@ -1,11 +1,14 @@
package org.kohsuke.github;
import org.junit.Test;
import org.kohsuke.github.authorization.UserAuthorizationProvider;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
import static org.hamcrest.CoreMatchers.*;
/**
* Unit test for {@link GitHub}.
*/
@@ -56,19 +59,40 @@ public class GitHubConnectionTest extends AbstractGitHubWireMockTest {
Map<String, String> props = new HashMap<String, String>();
props.put("login", "bogus");
props.put("oauth", "bogus");
props.put("password", "bogus");
props.put("jwt", "bogus");
props.put("endpoint", "bogus endpoint url");
props.put("oauth", "bogus oauth token string");
setupEnvironment(props);
GitHubBuilder builder = GitHubBuilder.fromEnvironment();
assertEquals("bogus", builder.user);
assertEquals("bogus", builder.oauthToken);
assertEquals("bogus", builder.password);
assertEquals("bogus", builder.jwtToken);
assertThat(builder.endpoint, equalTo("bogus endpoint url"));
assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class));
assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("token bogus oauth token string"));
assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), nullValue());
props.put("login", "bogus login");
setupEnvironment(props);
builder = GitHubBuilder.fromEnvironment();
assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class));
assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("token bogus oauth token string"));
assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login"));
props.put("jwt", "bogus jwt token string");
setupEnvironment(props);
builder = GitHubBuilder.fromEnvironment();
assertThat(builder.authorizationProvider, not(instanceOf(UserAuthorizationProvider.class)));
assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("Bearer bogus jwt token string"));
props.put("password", "bogus weak password");
setupEnvironment(props);
builder = GitHubBuilder.fromEnvironment();
assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class));
assertThat(builder.authorizationProvider.getEncodedAuthorization(),
equalTo("Basic Ym9ndXMgbG9naW46Ym9ndXMgd2VhayBwYXNzd29yZA=="));
assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login"));
}
@@ -76,32 +100,48 @@ public class GitHubConnectionTest extends AbstractGitHubWireMockTest {
public void testGitHubBuilderFromCustomEnvironment() throws IOException {
Map<String, String> props = new HashMap<String, String>();
props.put("customLogin", "bogusLogin");
props.put("customOauth", "bogusOauth");
props.put("customPassword", "bogusPassword");
props.put("customEndpoint", "bogusEndpoint");
props.put("customEndpoint", "bogus endpoint url");
props.put("customOauth", "bogus oauth token string");
setupEnvironment(props);
GitHubBuilder builder = GitHubBuilder
.fromEnvironment("customLogin", "customPassword", "customOauth", "customEndpoint");
assertEquals("bogusLogin", builder.user);
assertEquals("bogusOauth", builder.oauthToken);
assertEquals("bogusPassword", builder.password);
assertEquals("bogusEndpoint", builder.endpoint);
assertThat(builder.endpoint, equalTo("bogus endpoint url"));
assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class));
assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("token bogus oauth token string"));
assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), nullValue());
props.put("customLogin", "bogus login");
setupEnvironment(props);
builder = GitHubBuilder.fromEnvironment("customLogin", "customPassword", "customOauth", "customEndpoint");
assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class));
assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("token bogus oauth token string"));
assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login"));
props.put("customPassword", "bogus weak password");
setupEnvironment(props);
builder = GitHubBuilder.fromEnvironment("customLogin", "customPassword", "customOauth", "customEndpoint");
assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class));
assertThat(builder.authorizationProvider.getEncodedAuthorization(),
equalTo("Basic Ym9ndXMgbG9naW46Ym9ndXMgd2VhayBwYXNzd29yZA=="));
assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login"));
}
@Test
public void testGithubBuilderWithAppInstallationToken() throws Exception {
GitHubBuilder builder = new GitHubBuilder().withAppInstallationToken("bogus");
assertEquals("bogus", builder.oauthToken);
assertEquals("", builder.user);
GitHubBuilder builder = new GitHubBuilder().withAppInstallationToken("bogus app token");
assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class));
assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("token bogus app token"));
assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo(""));
// test authorization header is set as in the RFC6749
GitHub github = builder.build();
// change this to get a request
assertEquals("token bogus", github.getClient().encodedAuthorization);
assertEquals("token bogus app token", github.getClient().getEncodedAuthorization());
assertEquals("", github.getClient().login);
}

View File

@@ -2,7 +2,9 @@ package org.kohsuke.github;
import org.junit.Test;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit;
@@ -10,6 +12,9 @@ import java.util.Date;
import java.util.TimeZone;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.junit.Assert.fail;
/**
@@ -19,6 +24,34 @@ import static org.junit.Assert.fail;
*/
public class GitHubStaticTest extends AbstractGitHubWireMockTest {
@Test
public void testParseURL() throws Exception {
assertThat(GitHubClient.parseURL("https://api.github.com"), equalTo(new URL("https://api.github.com")));
assertThat(GitHubClient.parseURL(null), nullValue());
try {
GitHubClient.parseURL("bogus");
fail();
} catch (IllegalStateException e) {
assertThat(e.getMessage(), equalTo("Invalid URL: bogus"));
}
}
@Test
public void testParseInstant() throws Exception {
assertThat(GitHubClient.parseInstant(null), nullValue());
}
@Test
public void testRawUrlPathInvalid() throws Exception {
try {
gitHub.createRequest().setRawUrlPath("invalid.path.com");
fail();
} catch (GHException e) {
assertThat(e.getMessage(), equalTo("Raw URL must start with 'http'"));
}
}
@Test
public void timeRoundTrip() throws Exception {
final long stableInstantEpochMilli = 1533721222255L;
@@ -78,6 +111,62 @@ public class GitHubStaticTest extends AbstractGitHubWireMockTest {
}
}
@Test
public void testFromRecord() throws Exception {
final long stableInstantEpochSeconds = 11610674762L;
GHRateLimit rateLimit_none = GHRateLimit.fromRecord(new GHRateLimit.Record(9876,
5432,
(stableInstantEpochSeconds + Duration.ofMinutes(30).toMillis()) / 1000L), RateLimitTarget.NONE);
GHRateLimit rateLimit_core = GHRateLimit.fromRecord(new GHRateLimit.Record(9876,
5432,
(stableInstantEpochSeconds + Duration.ofMinutes(30).toMillis()) / 1000L), RateLimitTarget.CORE);
GHRateLimit rateLimit_search = GHRateLimit.fromRecord(new GHRateLimit.Record(19876,
15432,
(stableInstantEpochSeconds + Duration.ofHours(1).toMillis()) / 1000L), RateLimitTarget.SEARCH);
GHRateLimit rateLimit_graphql = GHRateLimit.fromRecord(new GHRateLimit.Record(29876,
25432,
(stableInstantEpochSeconds + Duration.ofHours(2).toMillis()) / 1000L), RateLimitTarget.GRAPHQL);
GHRateLimit rateLimit_integration = GHRateLimit.fromRecord(
new GHRateLimit.Record(39876,
35432,
(stableInstantEpochSeconds + Duration.ofHours(3).toMillis()) / 1000L),
RateLimitTarget.INTEGRATION_MANIFEST);
assertThat(rateLimit_none, equalTo(rateLimit_core));
assertThat(rateLimit_none, not(sameInstance(rateLimit_core)));
assertTrue(rateLimit_none.hashCode() == rateLimit_core.hashCode());
assertTrue(rateLimit_none.equals(rateLimit_core));
assertThat(rateLimit_none, not(equalTo(rateLimit_search)));
assertThat(rateLimit_none.getCore(), not(sameInstance(rateLimit_core.getCore())));
assertThat(rateLimit_core.getRecord(RateLimitTarget.NONE), instanceOf(GHRateLimit.UnknownLimitRecord.class));
assertThat(rateLimit_core.getRecord(RateLimitTarget.NONE),
sameInstance(rateLimit_none.getRecord(RateLimitTarget.NONE)));
assertThat(rateLimit_core.getRecord(RateLimitTarget.SEARCH), sameInstance(rateLimit_search.getGraphQL()));
assertThat(rateLimit_search.getRecord(RateLimitTarget.GRAPHQL),
sameInstance(rateLimit_graphql.getIntegrationManifest()));
assertThat(rateLimit_graphql.getRecord(RateLimitTarget.INTEGRATION_MANIFEST),
sameInstance(rateLimit_integration.getCore()));
assertThat(rateLimit_integration.getRecord(RateLimitTarget.CORE), sameInstance(rateLimit_core.getSearch()));
assertThat(rateLimit_none.getRecord(RateLimitTarget.CORE).getLimit(), equalTo(9876));
assertThat(rateLimit_core.getRecord(RateLimitTarget.CORE).getLimit(), equalTo(9876));
assertThat(rateLimit_search.getRecord(RateLimitTarget.SEARCH).getLimit(), equalTo(19876));
assertThat(rateLimit_graphql.getRecord(RateLimitTarget.GRAPHQL).getLimit(), equalTo(29876));
assertThat(rateLimit_integration.getRecord(RateLimitTarget.INTEGRATION_MANIFEST).getLimit(), equalTo(39876));
assertThat(rateLimit_core.toString(), containsString("GHRateLimit {core {remaining=5432, limit=9876"));
assertThat(rateLimit_core.toString(), containsString("search {remaining=999999, limit=1000000"));
}
@Test
public void testGitHubRateLimitShouldReplaceRateLimit() throws Exception {
@@ -225,7 +314,7 @@ public class GitHubStaticTest extends AbstractGitHubWireMockTest {
// this makes sure they don't break.
GHRepository repo = getTempRepository();
assertThat(repo.root, not(nullValue()));
assertThat(repo.getRoot(), not(nullValue()));
assertThat(repo.getResponseHeaderFields(), not(nullValue()));
String repoString = GitHub.getMappingObjectWriter().writeValueAsString(repo);
@@ -237,13 +326,13 @@ public class GitHubStaticTest extends AbstractGitHubWireMockTest {
.readValue(repoString);
// This should never happen if the internal method isn't used
assertThat(readRepo.root, nullValue());
assertThat(readRepo.getRoot(), nullValue());
assertThat(readRepo.getResponseHeaderFields(), nullValue());
readRepo = GitHub.getMappingObjectReader().forType(GHRepository.class).readValue(repoString);
// This should never happen if the internal method isn't used
assertThat(readRepo.root.getConnector(), equalTo(HttpConnector.OFFLINE));
assertThat(readRepo.getRoot().getConnector(), equalTo(HttpConnector.OFFLINE));
assertThat(readRepo.getResponseHeaderFields(), nullValue());
String readRepoString = GitHub.getMappingObjectWriter().writeValueAsString(readRepo);

View File

@@ -25,6 +25,22 @@ public class GitHubTest extends AbstractGitHubWireMockTest {
}
}
@Test
public void getRepository() throws IOException {
GHRepository repo = gitHub.getRepository("hub4j/github-api");
assertThat(repo.getFullName(), equalTo("hub4j/github-api"));
GHRepository repo2 = gitHub.getRepositoryById(Long.toString(repo.getId()));
assertThat(repo2.getFullName(), equalTo("hub4j/github-api"));
try {
gitHub.getRepository("hub4j_github-api");
} catch (IllegalArgumentException e) {
assertThat(e.getMessage(), equalTo("Repository name must be in format owner/repo"));
}
}
@Test
public void getOrgs() throws IOException {
int iterations = 10;
@@ -34,6 +50,18 @@ public class GitHubTest extends AbstractGitHubWireMockTest {
// System.out.println(org.getName());
}
assertThat(orgIds.size(), equalTo(iterations));
GHOrganization org = gitHub.getOrganization("hub4j");
GHOrganization org2 = gitHub.getOrganization("hub4j");
assertThat(org.getLogin(), equalTo("hub4j"));
// caching
assertThat(org, sameInstance(org2));
gitHub.refreshCache();
org2 = gitHub.getOrganization("hub4j");
assertThat(org2.getLogin(), equalTo("hub4j"));
// cache cleared
assertThat(org, not(sameInstance(org2)));
}
@Test

View File

@@ -6,6 +6,7 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -24,19 +25,27 @@ public class Github2faTest extends AbstractGitHubWireMockTest {
// collide with older tokens
GHAuthorization token = gitHub
.createToken(asList, nameOfToken, "this is a test token created by a unit test", () -> {
.createToken(asList, nameOfToken, "https://localhost/this/is/a/test/token", () -> {
String data = "111878";
// TO UPDATE run this in debugger mode, put a breakpoint here, and enter the OTP you get into the
// value of Data
return data;
});
assert token != null;
assertThat(token, notNullValue());
for (int i = 0; i < asList.size(); i++) {
assertTrue(token.getScopes().get(i).contentEquals(asList.get(i)));
}
String p = token.getToken();
assertThat(token.getToken(), equalTo("63042a99d88bf138e6d6cf5788e0dc4e7a5d7309"));
assertThat(token.getTokenLastEight(), equalTo("7a5d7309"));
assertThat(token.getHashedToken(), equalTo("12b727a23cad7c5a5caabb806d88e722794dede98464aed7f77cbc00dbf031a2"));
assertThat(token.getNote(), equalTo("Test2faTokenCreate"));
assertThat(token.getNoteUrl().toString(), equalTo("https://localhost/this/is/a/test/token"));
assertThat(token.getAppUrl().toString(), equalTo("https://localhost/this/is/a/test/app/token"));
assertThat(token.getFingerprint(), nullValue());
assertThat(token.getHtmlUrl(), nullValue());
assert p != null;
}
}

View File

@@ -10,7 +10,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.core.Is.is;
public class LifecycleTest extends AbstractGitHubWireMockTest {
@@ -61,6 +61,13 @@ public class LifecycleTest extends AbstractGitHubWireMockTest {
List<GHAsset> assets = release.getAssets();
assertEquals(1, assets.size());
assertEquals("LICENSE.txt", assets.get(0).getName());
assertThat(assets.get(0).getSize(), equalTo(1104L));
assertThat(assets.get(0).getContentType(), equalTo("application/text"));
assertThat(assets.get(0).getState(), equalTo("uploaded"));
assertThat(assets.get(0).getDownloadCount(), equalTo(0L));
assertThat(assets.get(0).getOwner(), sameInstance(release.getOwner()));
assertThat(assets.get(0).getBrowserDownloadUrl(),
containsString("/temp-testCreateRepository/releases/download/release_tag/LICENSE.txt"));
return asset;
}
@@ -74,6 +81,16 @@ public class LifecycleTest extends AbstractGitHubWireMockTest {
assertEquals(1, releases.size());
GHRelease release = releases.get(0);
assertEquals("Test Release", release.getName());
assertThat(release.getBody(), startsWith("How exciting!"));
assertThat(release.getOwner(), sameInstance(repository));
assertThat(release.getZipballUrl(),
endsWith("/repos/hub4j-test-org/temp-testCreateRepository/zipball/release_tag"));
assertThat(release.getTarballUrl(),
endsWith("/repos/hub4j-test-org/temp-testCreateRepository/tarball/release_tag"));
assertThat(release.getTargetCommitish(), equalTo("master"));
assertThat(release.getHtmlUrl().toString(),
endsWith("/hub4j-test-org/temp-testCreateRepository/releases/tag/release_tag"));
return release;
}

View File

@@ -0,0 +1,43 @@
package org.kohsuke.github;
import org.junit.Test;
import org.kohsuke.github.authorization.ImmutableAuthorizationProvider;
import org.kohsuke.github.authorization.OrgAppInstallationAuthorizationProvider;
import java.io.IOException;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
public class OrgAppInstallationAuthorizationProviderTest extends AbstractGHAppInstallationTest {
public OrgAppInstallationAuthorizationProviderTest() {
useDefaultGitHub = false;
}
@Test(expected = HttpException.class)
public void invalidJWTTokenRaisesException() throws IOException {
OrgAppInstallationAuthorizationProvider provider = new OrgAppInstallationAuthorizationProvider(
"testOrganization",
ImmutableAuthorizationProvider.fromJwtToken("myToken"));
gitHub = getGitHubBuilder().withAuthorizationProvider(provider)
.withEndpoint(mockGitHub.apiServer().baseUrl())
.build();
provider.getEncodedAuthorization();
}
@Test
public void validJWTTokenAllowsOauthTokenRequest() throws IOException {
OrgAppInstallationAuthorizationProvider provider = new OrgAppInstallationAuthorizationProvider("hub4j-test-org",
ImmutableAuthorizationProvider.fromJwtToken("bogus-valid-token"));
gitHub = getGitHubBuilder().withAuthorizationProvider(provider)
.withEndpoint(mockGitHub.apiServer().baseUrl())
.build();
String encodedAuthorization = provider.getEncodedAuthorization();
assertThat(encodedAuthorization, notNullValue());
assertThat(encodedAuthorization, equalTo("token v1.9a12d913f980a45a16ac9c3a9d34d9b7sa314cb6"));
}
}

View File

@@ -0,0 +1,47 @@
package org.kohsuke.github.extras.authorization;
import org.junit.Test;
import org.kohsuke.github.AbstractGitHubWireMockTest;
import org.kohsuke.github.GitHub;
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
/*
* This test will request an application ensuring that the header for the "Authorization" matches a valid JWT token.
* A JWT token in the Authorization header will always start with "ey" which is always the start of the base64
* encoding of the JWT Header , so a valid header will look like this:
*
* <pre>
* Authorization: Bearer ey{rest of the header}.{payload}.{signature}
* </pre>
*
* Matched by the regular expression:
*
* <pre>
* ^Bearer (?<JWTHeader>ey\S*)\.(?<JWTPayload>\S*)\.(?<JWTSignature>\S*)$
* </pre>
*
* Which is present in the wiremock matcher. Note that we need to use a matcher because the JWT token is encoded
* with a private key and a random nonce, so it will never be the same (under normal conditions). For more
* information on the format of a JWT token, see: https://jwt.io/introduction/
*/
public class JWTTokenProviderTest extends AbstractGitHubWireMockTest {
private static String TEST_APP_ID_2 = "83009";
private static String PRIVATE_KEY_FILE_APP_2 = "/ghapi-test-app-2.private-key.pem";
@Test
public void testAuthorizationHeaderPattern() throws GeneralSecurityException, IOException {
JWTTokenProvider jwtTokenProvider = new JWTTokenProvider(TEST_APP_ID_2,
new File(this.getClass().getResource(PRIVATE_KEY_FILE_APP_2).getFile()));
GitHub gh = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl())
.withAuthorizationProvider(jwtTokenProvider)
.build();
// Request the application, the wiremock matcher will ensure that the header
// for the authorization is present and has a the format of a valid JWT token
gh.getApp();
}
}

View File

@@ -1,6 +1,6 @@
{
"id": 212656166,
"node_id": "MDEwOlJlcG9zaXRvcnkyMTI2NTYxNjY=",
"id": 332135400,
"node_id": "MDEwOlJlcG9zaXRvcnkzMzIxMzU0MDA=",
"name": "github-api-test",
"full_name": "hub4j-test-org/github-api-test",
"private": false,
@@ -8,7 +8,7 @@
"login": "hub4j-test-org",
"id": 7544739,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
"avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/hub4j-test-org",
"html_url": "https://github.com/hub4j-test-org",
@@ -25,7 +25,7 @@
"site_admin": false
},
"html_url": "https://github.com/hub4j-test-org/github-api-test",
"description": "A test repository for testing the github-api project",
"description": "A test repository for testing the github-api project: github-api-test",
"fork": false,
"url": "https://api.github.com/repos/hub4j-test-org/github-api-test",
"forks_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/forks",
@@ -64,9 +64,9 @@
"labels_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/labels{/name}",
"releases_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/releases{/id}",
"deployments_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments",
"created_at": "2019-10-03T18:57:53Z",
"updated_at": "2019-10-03T18:57:57Z",
"pushed_at": "2019-10-03T18:57:54Z",
"created_at": "2021-01-23T05:30:23Z",
"updated_at": "2021-01-23T05:30:27Z",
"pushed_at": "2021-01-23T05:30:25Z",
"git_url": "git://github.com/hub4j-test-org/github-api-test.git",
"ssh_url": "git@github.com:hub4j-test-org/github-api-test.git",
"clone_url": "https://github.com/hub4j-test-org/github-api-test.git",
@@ -90,20 +90,22 @@
"forks": 0,
"open_issues": 0,
"watchers": 0,
"default_branch": "master",
"default_branch": "main",
"permissions": {
"admin": true,
"push": true,
"pull": true
},
"temp_clone_token": "",
"allow_squash_merge": true,
"allow_merge_commit": true,
"allow_rebase_merge": true,
"delete_branch_on_merge": false,
"organization": {
"login": "hub4j-test-org",
"id": 7544739,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
"avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/hub4j-test-org",
"html_url": "https://github.com/hub4j-test-org",
@@ -120,5 +122,5 @@
"site_admin": false
},
"network_count": 0,
"subscribers_count": 2
"subscribers_count": 9
}

View File

@@ -1,38 +1,39 @@
{
"url": "http://localhost:62379/repos/hub4j-test-org/github-api-test/deployments/173089055",
"id": 173089055,
"node_id": "MDEwOkRlcGxveW1lbnQxNzMwODkwNTU=",
"sha": "a446d9fa5c6f43d5f9333b625606909cd4635071",
"ref": "master",
"url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601563",
"id": 315601563,
"node_id": "MDEwOkRlcGxveW1lbnQzMTU2MDE1NjM=",
"task": "deploy",
"payload": "{\"user\":\"atmos\",\"room_id\":123456}",
"original_environment": "unittest",
"environment": "unittest",
"description": "question",
"created_at": "2021-01-23T05:30:28Z",
"updated_at": "2021-01-23T05:30:28Z",
"statuses_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601563/statuses",
"repository_url": "https://api.github.com/repos/hub4j-test-org/github-api-test",
"creator": {
"login": "bitwiseman",
"id": 1958953,
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
"avatar_url": "https://avatars3.githubusercontent.com/u/1958953?v=4",
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
"gravatar_id": "",
"url": "http://localhost:62379/users/bitwiseman",
"url": "https://api.github.com/users/bitwiseman",
"html_url": "https://github.com/bitwiseman",
"followers_url": "http://localhost:62379/users/bitwiseman/followers",
"following_url": "http://localhost:62379/users/bitwiseman/following{/other_user}",
"gists_url": "http://localhost:62379/users/bitwiseman/gists{/gist_id}",
"starred_url": "http://localhost:62379/users/bitwiseman/starred{/owner}{/repo}",
"subscriptions_url": "http://localhost:62379/users/bitwiseman/subscriptions",
"organizations_url": "http://localhost:62379/users/bitwiseman/orgs",
"repos_url": "http://localhost:62379/users/bitwiseman/repos",
"events_url": "http://localhost:62379/users/bitwiseman/events{/privacy}",
"received_events_url": "http://localhost:62379/users/bitwiseman/received_events",
"followers_url": "https://api.github.com/users/bitwiseman/followers",
"following_url": "https://api.github.com/users/bitwiseman/following{/other_user}",
"gists_url": "https://api.github.com/users/bitwiseman/gists{/gist_id}",
"starred_url": "https://api.github.com/users/bitwiseman/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/bitwiseman/subscriptions",
"organizations_url": "https://api.github.com/users/bitwiseman/orgs",
"repos_url": "https://api.github.com/users/bitwiseman/repos",
"events_url": "https://api.github.com/users/bitwiseman/events{/privacy}",
"received_events_url": "https://api.github.com/users/bitwiseman/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2019-10-03T18:57:57Z",
"updated_at": "2019-10-03T18:57:57Z",
"statuses_url": "http://localhost:62379/repos/hub4j-test-org/github-api-test/deployments/173089055/statuses",
"repository_url": "http://localhost:62379/repos/hub4j-test-org/github-api-test",
"transient_environment": true,
"production_environment": false
"sha": "e53a04ca0ba2fbe6ea3fd590e8ea1391ac61630f",
"ref": "main",
"payload": "{\"user\":\"atmos\",\"room_id\":123456}",
"transient_environment": false,
"production_environment": false,
"performed_via_github_app": null
}

View File

@@ -1,20 +1,21 @@
[
{
"url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/173089055",
"id": 173089055,
"node_id": "MDEwOkRlcGxveW1lbnQxNzMwODkwNTU=",
"sha": "a446d9fa5c6f43d5f9333b625606909cd4635071",
"ref": "master",
"url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601563",
"id": 315601563,
"node_id": "MDEwOkRlcGxveW1lbnQzMTU2MDE1NjM=",
"task": "deploy",
"payload": "{\"user\":\"atmos\",\"room_id\":123456}",
"original_environment": "unittest",
"environment": "unittest",
"description": "question",
"created_at": "2021-01-23T05:30:28Z",
"updated_at": "2021-01-23T05:30:28Z",
"statuses_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601563/statuses",
"repository_url": "https://api.github.com/repos/hub4j-test-org/github-api-test",
"creator": {
"login": "bitwiseman",
"id": 1958953,
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
"avatar_url": "https://avatars3.githubusercontent.com/u/1958953?v=4",
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/bitwiseman",
"html_url": "https://github.com/bitwiseman",
@@ -30,11 +31,11 @@
"type": "User",
"site_admin": false
},
"created_at": "2019-10-03T18:57:57Z",
"updated_at": "2019-10-03T18:57:57Z",
"statuses_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/173089055/statuses",
"repository_url": "https://api.github.com/repos/hub4j-test-org/github-api-test",
"transient_environment": true,
"production_environment": false
"sha": "e53a04ca0ba2fbe6ea3fd590e8ea1391ac61630f",
"ref": "main",
"payload": "{\"user\":\"atmos\",\"room_id\":123456}",
"transient_environment": false,
"production_environment": false,
"performed_via_github_app": null
}
]

View File

@@ -2,7 +2,7 @@
"login": "bitwiseman",
"id": 1958953,
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
"avatar_url": "https://avatars3.githubusercontent.com/u/1958953?v=4",
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/bitwiseman",
"html_url": "https://github.com/bitwiseman",
@@ -23,17 +23,18 @@
"location": "Seattle, WA, USA",
"email": "bitwiseman@gmail.com",
"hireable": null,
"bio": "https://twitter.com/bitwiseman",
"public_repos": 167,
"public_gists": 4,
"followers": 136,
"following": 9,
"bio": null,
"twitter_username": "bitwiseman",
"public_repos": 201,
"public_gists": 7,
"followers": 176,
"following": 11,
"created_at": "2012-07-11T20:38:33Z",
"updated_at": "2019-09-24T19:32:29Z",
"private_gists": 7,
"total_private_repos": 9,
"updated_at": "2021-01-22T16:38:42Z",
"private_gists": 19,
"total_private_repos": 17,
"owned_private_repos": 0,
"disk_usage": 33697,
"disk_usage": 33700,
"collaborators": 0,
"two_factor_authentication": true,
"plan": {

View File

@@ -1,5 +1,5 @@
{
"id": "31a86a0d-5120-47b8-a9bc-ec4b34a08080",
"id": "b0faf3a5-5d1d-4f5f-bcc0-32f5c182f4c4",
"name": "repos_hub4j-test-org_github-api-test",
"request": {
"url": "/repos/hub4j-test-org/github-api-test",
@@ -14,35 +14,35 @@
"status": 200,
"bodyFileName": "repos_hub4j-test-org_github-api-test-2.json",
"headers": {
"Date": "Thu, 03 Oct 2019 18:57:57 GMT",
"Date": "Sat, 23 Jan 2021 05:30:28 GMT",
"Content-Type": "application/json; charset=utf-8",
"Server": "GitHub.com",
"Status": "200 OK",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4750",
"X-RateLimit-Reset": "1570132527",
"Cache-Control": "private, max-age=60, s-maxage=60",
"Vary": [
"Accept, Authorization, Cookie, X-GitHub-OTP",
"Accept-Encoding, Accept, X-Requested-With",
"Accept-Encoding"
],
"ETag": "W/\"65ee4cf55cf4d084267c80a5d39244c6\"",
"Last-Modified": "Thu, 03 Oct 2019 18:57:57 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
"ETag": "W/\"10026c1f1a22ffaba0888b2d3e2501ab45ade2789609aa725a767f8593b8f060\"",
"last-modified": "Sat, 23 Jan 2021 05:30:27 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
"X-Accepted-OAuth-Scopes": "repo",
"X-GitHub-Media-Type": "unknown, github.v3",
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
"Access-Control-Allow-Origin": "*",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4904",
"X-RateLimit-Reset": "1611382753",
"x-ratelimit-used": "96",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "F3AD:3618:10E8DB:149FB6:5D9644B0"
"X-GitHub-Request-Id": "D9F6:8870:9D4A2:B9689:600BB46D"
}
},
"uuid": "31a86a0d-5120-47b8-a9bc-ec4b34a08080",
"uuid": "b0faf3a5-5d1d-4f5f-bcc0-32f5c182f4c4",
"persistent": true,
"insertionIndex": 2
}

View File

@@ -1,56 +1,56 @@
{
"id": "702b7123-86c1-41e0-bee7-f3cb89a3236d",
"id": "794202d0-93a7-4526-b91b-00059c377ee0",
"name": "repos_hub4j-test-org_github-api-test_deployments",
"request": {
"url": "/repos/hub4j-test-org/github-api-test/deployments",
"method": "POST",
"bodyPatterns": [
{
"equalToJson": "{\"ref\":\"master\",\"environment\":\"unittest\",\"payload\":\"{\\\"user\\\":\\\"atmos\\\",\\\"room_id\\\":123456}\",\"description\":\"question\"}",
"ignoreArrayOrder": true,
"ignoreExtraElements": true
}
],
"headers": {
"Accept": {
"equalTo": "application/vnd.github.ant-man-preview+json, application/vnd.github.flash-preview+json"
}
}
},
"bodyPatterns": [
{
"equalToJson": "{\"ref\":\"main\",\"environment\":\"unittest\",\"payload\":\"{\\\"user\\\":\\\"atmos\\\",\\\"room_id\\\":123456}\",\"description\":\"question\"}",
"ignoreArrayOrder": true,
"ignoreExtraElements": false
}
]
},
"response": {
"status": 201,
"bodyFileName": "repos_hub4j-test-org_github-api-test_deployments-3.json",
"headers": {
"Date": "Thu, 03 Oct 2019 18:57:57 GMT",
"Date": "Sat, 23 Jan 2021 05:30:28 GMT",
"Content-Type": "application/json; charset=utf-8",
"Server": "GitHub.com",
"Status": "201 Created",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4749",
"X-RateLimit-Reset": "1570132527",
"Cache-Control": "private, max-age=60, s-maxage=60",
"Vary": [
"Accept, Authorization, Cookie, X-GitHub-OTP",
"Accept-Encoding, Accept, X-Requested-With",
"Accept-Encoding"
],
"ETag": "\"c76b22eae3a1d091db2c789a39fecda9\"",
"Last-Modified": "Thu, 03 Oct 2019 18:57:57 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
"ETag": "\"d256e649a7f1dfa04498ff9107cd30d1f42dcf80793952739c20e04436165cf3\"",
"last-modified": "Sat, 23 Jan 2021 05:30:28 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
"X-Accepted-OAuth-Scopes": "",
"Location": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/173089055",
"X-GitHub-Media-Type": "unknown, github.v3",
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
"Access-Control-Allow-Origin": "*",
"Location": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601563",
"X-GitHub-Media-Type": "github.ant-man-preview; format=json, github.flash-preview; format=json",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4903",
"X-RateLimit-Reset": "1611382753",
"x-ratelimit-used": "97",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "F3AD:3618:10E8DF:149FEF:5D9644B5"
"X-GitHub-Request-Id": "D9F6:8870:9D4A9:B9794:600BB474"
}
},
"uuid": "702b7123-86c1-41e0-bee7-f3cb89a3236d",
"uuid": "794202d0-93a7-4526-b91b-00059c377ee0",
"persistent": true,
"insertionIndex": 3
}

View File

@@ -1,8 +1,8 @@
{
"id": "b4bcdadb-a708-4509-9382-479f300eb172",
"id": "ad687411-71ba-4851-91b0-2ace8f6111a2",
"name": "repos_hub4j-test-org_github-api-test_deployments",
"request": {
"url": "/repos/hub4j-test-org/github-api-test/deployments?ref=master&environment=unittest",
"url": "/repos/hub4j-test-org/github-api-test/deployments?ref=main&environment=unittest",
"method": "GET",
"headers": {
"Accept": {
@@ -14,34 +14,34 @@
"status": 200,
"bodyFileName": "repos_hub4j-test-org_github-api-test_deployments-4.json",
"headers": {
"Date": "Thu, 03 Oct 2019 18:57:58 GMT",
"Date": "Sat, 23 Jan 2021 05:30:29 GMT",
"Content-Type": "application/json; charset=utf-8",
"Server": "GitHub.com",
"Status": "200 OK",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4748",
"X-RateLimit-Reset": "1570132527",
"Cache-Control": "private, max-age=60, s-maxage=60",
"Vary": [
"Accept, Authorization, Cookie, X-GitHub-OTP",
"Accept-Encoding, Accept, X-Requested-With",
"Accept-Encoding"
],
"ETag": "W/\"b47f03577f96c1081341944009009f7f\"",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
"ETag": "W/\"37d9142674c76d3eb0593d8a62756ab18011fd64315c81dbfa2c7f7dd7596dd7\"",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
"X-Accepted-OAuth-Scopes": "repo, repo_deployment",
"X-GitHub-Media-Type": "unknown, github.v3",
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
"Access-Control-Allow-Origin": "*",
"X-GitHub-Media-Type": "github.ant-man-preview; format=json, github.flash-preview; format=json",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4902",
"X-RateLimit-Reset": "1611382753",
"x-ratelimit-used": "98",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "F3AD:3618:10E8E2:149FF2:5D9644B5"
"X-GitHub-Request-Id": "D9F6:8870:9D4AF:B979B:600BB474"
}
},
"uuid": "b4bcdadb-a708-4509-9382-479f300eb172",
"uuid": "ad687411-71ba-4851-91b0-2ace8f6111a2",
"persistent": true,
"insertionIndex": 4
}

View File

@@ -0,0 +1,42 @@
{
"id": "3360bee1-e184-49de-8434-9fabafc6e075",
"name": "repos_hub4j-test-org_github-api-test_deployments_315601563",
"request": {
"url": "/repos/hub4j-test-org/github-api-test/deployments/315601563",
"method": "DELETE",
"headers": {
"Accept": {
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
}
}
},
"response": {
"status": 204,
"headers": {
"Date": "Sat, 23 Jan 2021 05:30:29 GMT",
"Server": "GitHub.com",
"Status": "204 No Content",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
"X-Accepted-OAuth-Scopes": "",
"X-GitHub-Media-Type": "unknown, github.v3",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4901",
"X-RateLimit-Reset": "1611382753",
"x-ratelimit-used": "99",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"Vary": [
"Accept-Encoding, Accept, X-Requested-With",
"Accept-Encoding"
],
"X-GitHub-Request-Id": "D9F6:8870:9D4B5:B97A0:600BB475"
}
},
"uuid": "3360bee1-e184-49de-8434-9fabafc6e075",
"persistent": true,
"insertionIndex": 5
}

View File

@@ -1,5 +1,5 @@
{
"id": "6d2dcbf4-4abf-4180-9b55-ca2931ca31c5",
"id": "9e2336dc-4e61-49ef-a171-2d408b3bf5ac",
"name": "user",
"request": {
"url": "/user",
@@ -14,35 +14,35 @@
"status": 200,
"bodyFileName": "user-1.json",
"headers": {
"Date": "Thu, 03 Oct 2019 18:57:52 GMT",
"Date": "Sat, 23 Jan 2021 05:30:21 GMT",
"Content-Type": "application/json; charset=utf-8",
"Server": "GitHub.com",
"Status": "200 OK",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4759",
"X-RateLimit-Reset": "1570132527",
"Cache-Control": "private, max-age=60, s-maxage=60",
"Vary": [
"Accept, Authorization, Cookie, X-GitHub-OTP",
"Accept-Encoding, Accept, X-Requested-With",
"Accept-Encoding"
],
"ETag": "W/\"cf6199fecf47b59c42190e1e11147ee2\"",
"Last-Modified": "Tue, 24 Sep 2019 19:32:29 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
"ETag": "W/\"c8b61de8f7b00ef1a040d10e88b51dd065defb82f7d94a95a97b3dbab636edbe\"",
"last-modified": "Fri, 22 Jan 2021 16:38:42 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
"X-Accepted-OAuth-Scopes": "",
"X-GitHub-Media-Type": "unknown, github.v3",
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
"Access-Control-Allow-Origin": "*",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4909",
"X-RateLimit-Reset": "1611382753",
"x-ratelimit-used": "91",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "F3AD:3618:10E8AA:149FB4:5D9644B0"
"X-GitHub-Request-Id": "D9F6:8870:9D3CD:B9683:600BB46D"
}
},
"uuid": "6d2dcbf4-4abf-4180-9b55-ca2931ca31c5",
"uuid": "9e2336dc-4e61-49ef-a171-2d408b3bf5ac",
"persistent": true,
"insertionIndex": 1
}

View File

@@ -8,7 +8,7 @@
"login": "kohsuke",
"id": 50003,
"node_id": "MDQ6VXNlcjUwMDAz",
"avatar_url": "https://avatars1.githubusercontent.com/u/50003?v=4",
"avatar_url": "https://avatars.githubusercontent.com/u/50003?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/kohsuke",
"html_url": "https://github.com/kohsuke",
@@ -96,6 +96,7 @@
"push": false,
"pull": true
},
"temp_clone_token": "",
"parent": {
"id": 3231216,
"node_id": "MDEwOlJlcG9zaXRvcnkzMjMxMjE2",
@@ -106,7 +107,7 @@
"login": "kohsuke2",
"id": 1329242,
"node_id": "MDQ6VXNlcjEzMjkyNDI=",
"avatar_url": "https://avatars2.githubusercontent.com/u/1329242?v=4",
"avatar_url": "https://avatars.githubusercontent.com/u/1329242?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/kohsuke2",
"html_url": "https://github.com/kohsuke2",
@@ -200,7 +201,7 @@
"login": "kohsuke2",
"id": 1329242,
"node_id": "MDQ6VXNlcjEzMjkyNDI=",
"avatar_url": "https://avatars2.githubusercontent.com/u/1329242?v=4",
"avatar_url": "https://avatars.githubusercontent.com/u/1329242?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/kohsuke2",
"html_url": "https://github.com/kohsuke2",

View File

@@ -1,13 +1,13 @@
{
"url": "https://api.github.com/repos/kohsuke/sandbox-ant/comments/35673784",
"html_url": "https://github.com/kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000#commitcomment-35673784",
"id": 35673784,
"node_id": "MDEzOkNvbW1pdENvbW1lbnQzNTY3Mzc4NA==",
"url": "https://api.github.com/repos/kohsuke/sandbox-ant/comments/46267761",
"html_url": "https://github.com/kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000#commitcomment-46267761",
"id": 46267761,
"node_id": "MDEzOkNvbW1pdENvbW1lbnQ0NjI2Nzc2MQ==",
"user": {
"login": "bitwiseman",
"id": 1958953,
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
"avatar_url": "https://avatars3.githubusercontent.com/u/1958953?v=4",
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/bitwiseman",
"html_url": "https://github.com/bitwiseman",
@@ -27,8 +27,8 @@
"line": null,
"path": null,
"commit_id": "8ae38db0ea5837313ab5f39d43a6f73de3bd9000",
"created_at": "2019-10-26T01:28:59Z",
"updated_at": "2019-10-26T01:28:59Z",
"created_at": "2021-01-23T06:39:40Z",
"updated_at": "2021-01-23T06:39:40Z",
"author_association": "NONE",
"body": "updated text"
}

View File

@@ -33,7 +33,7 @@
"login": "kohsuke",
"id": 50003,
"node_id": "MDQ6VXNlcjUwMDAz",
"avatar_url": "https://avatars1.githubusercontent.com/u/50003?v=4",
"avatar_url": "https://avatars.githubusercontent.com/u/50003?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/kohsuke",
"html_url": "https://github.com/kohsuke",
@@ -53,7 +53,7 @@
"login": "kohsuke",
"id": 50003,
"node_id": "MDQ6VXNlcjUwMDAz",
"avatar_url": "https://avatars1.githubusercontent.com/u/50003?v=4",
"avatar_url": "https://avatars.githubusercontent.com/u/50003?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/kohsuke",
"html_url": "https://github.com/kohsuke",

View File

@@ -1,13 +1,13 @@
{
"url": "https://api.github.com/repos/kohsuke/sandbox-ant/comments/35673784",
"html_url": "https://github.com/kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000#commitcomment-35673784",
"id": 35673784,
"node_id": "MDEzOkNvbW1pdENvbW1lbnQzNTY3Mzc4NA==",
"url": "https://api.github.com/repos/kohsuke/sandbox-ant/comments/46267761",
"html_url": "https://github.com/kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000#commitcomment-46267761",
"id": 46267761,
"node_id": "MDEzOkNvbW1pdENvbW1lbnQ0NjI2Nzc2MQ==",
"user": {
"login": "bitwiseman",
"id": 1958953,
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
"avatar_url": "https://avatars3.githubusercontent.com/u/1958953?v=4",
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/bitwiseman",
"html_url": "https://github.com/bitwiseman",
@@ -27,8 +27,8 @@
"line": null,
"path": null,
"commit_id": "8ae38db0ea5837313ab5f39d43a6f73de3bd9000",
"created_at": "2019-10-26T01:28:59Z",
"updated_at": "2019-10-26T01:28:59Z",
"created_at": "2021-01-23T06:39:40Z",
"updated_at": "2021-01-23T06:39:40Z",
"author_association": "NONE",
"body": "[testing](http://kohsuse.org/)"
}

View File

@@ -2,7 +2,7 @@
"login": "bitwiseman",
"id": 1958953,
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
"avatar_url": "https://avatars3.githubusercontent.com/u/1958953?v=4",
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/bitwiseman",
"html_url": "https://github.com/bitwiseman",
@@ -23,17 +23,18 @@
"location": "Seattle, WA, USA",
"email": "bitwiseman@gmail.com",
"hireable": null,
"bio": "https://twitter.com/bitwiseman",
"public_repos": 169,
"bio": null,
"twitter_username": "bitwiseman",
"public_repos": 201,
"public_gists": 7,
"followers": 139,
"following": 9,
"followers": 176,
"following": 11,
"created_at": "2012-07-11T20:38:33Z",
"updated_at": "2019-09-24T19:32:29Z",
"private_gists": 7,
"total_private_repos": 9,
"updated_at": "2021-01-22T16:38:42Z",
"private_gists": 19,
"total_private_repos": 17,
"owned_private_repos": 0,
"disk_usage": 33697,
"disk_usage": 33700,
"collaborators": 0,
"two_factor_authentication": true,
"plan": {

View File

@@ -2,7 +2,7 @@
"login": "kohsuke",
"id": 50003,
"node_id": "MDQ6VXNlcjUwMDAz",
"avatar_url": "https://avatars1.githubusercontent.com/u/50003?v=4",
"avatar_url": "https://avatars.githubusercontent.com/u/50003?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/kohsuke",
"html_url": "https://github.com/kohsuke",
@@ -18,16 +18,17 @@
"type": "User",
"site_admin": false,
"name": "Kohsuke Kawaguchi",
"company": "CloudBees, Inc.",
"blog": "http://www.kohsuke.org/",
"company": "@launchableinc ",
"blog": "https://www.kohsuke.org/",
"location": "San Jose, California",
"email": "kk@kohsuke.org",
"hireable": null,
"bio": null,
"public_repos": 257,
"public_gists": 109,
"followers": 1692,
"twitter_username": null,
"public_repos": 262,
"public_gists": 113,
"followers": 1886,
"following": 3,
"created_at": "2009-01-28T18:53:21Z",
"updated_at": "2019-10-25T16:53:26Z"
"updated_at": "2021-01-22T19:41:07Z"
}

View File

@@ -1,5 +1,5 @@
{
"id": "3fd5d206-9d71-4f2a-bc95-605c06b6f793",
"id": "525a2ad5-8560-42d6-b12d-25fa6d7c2806",
"name": "repos_kohsuke_sandbox-ant",
"request": {
"url": "/repos/kohsuke/sandbox-ant",
@@ -14,35 +14,35 @@
"status": 200,
"bodyFileName": "repos_kohsuke_sandbox-ant-3.json",
"headers": {
"Date": "Sat, 26 Oct 2019 01:28:58 GMT",
"Date": "Sat, 23 Jan 2021 06:39:39 GMT",
"Content-Type": "application/json; charset=utf-8",
"Server": "GitHub.com",
"Status": "200 OK",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4242",
"X-RateLimit-Reset": "1572055286",
"Cache-Control": "private, max-age=60, s-maxage=60",
"Vary": [
"Accept, Authorization, Cookie, X-GitHub-OTP",
"Accept-Encoding, Accept, X-Requested-With",
"Accept-Encoding"
],
"ETag": "W/\"6d4495f0d482e4612ed1964d37884bce\"",
"Last-Modified": "Tue, 13 Aug 2019 14:56:58 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
"ETag": "W/\"7ad6797858a55e4d4576e2481c25ba68b88b778461b12575e2c2702cce47585f\"",
"last-modified": "Tue, 13 Aug 2019 14:56:58 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
"X-Accepted-OAuth-Scopes": "repo",
"X-GitHub-Media-Type": "unknown, github.v3",
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
"Access-Control-Allow-Origin": "*",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4945",
"X-RateLimit-Reset": "1611386378",
"x-ratelimit-used": "55",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "CB24:8340:ED2364:116FE52:5DB3A15A"
"X-GitHub-Request-Id": "E9F0:5E21:C00DF:DCE23:600BC4AB"
}
},
"uuid": "3fd5d206-9d71-4f2a-bc95-605c06b6f793",
"uuid": "525a2ad5-8560-42d6-b12d-25fa6d7c2806",
"persistent": true,
"insertionIndex": 3
}

View File

@@ -1,54 +1,54 @@
{
"id": "70a63f41-02d3-404e-af0b-8e1c3cd00494",
"name": "repos_kohsuke_sandbox-ant_comments_35673784",
"id": "4eccc8fc-0026-4272-93b8-76a31a95eeb5",
"name": "repos_kohsuke_sandbox-ant_comments_46267761",
"request": {
"url": "/repos/kohsuke/sandbox-ant/comments/35673784",
"url": "/repos/kohsuke/sandbox-ant/comments/46267761",
"method": "PATCH",
"bodyPatterns": [
{
"equalToJson": "{\"body\":\"updated text\"}",
"ignoreArrayOrder": true,
"ignoreExtraElements": true
}
],
"headers": {
"Accept": {
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
}
}
},
"bodyPatterns": [
{
"equalToJson": "{\"body\":\"updated text\"}",
"ignoreArrayOrder": true,
"ignoreExtraElements": false
}
]
},
"response": {
"status": 200,
"bodyFileName": "repos_kohsuke_sandbox-ant_comments_35673784-6.json",
"bodyFileName": "repos_kohsuke_sandbox-ant_comments_46267761-7.json",
"headers": {
"Date": "Sat, 26 Oct 2019 01:28:59 GMT",
"Date": "Sat, 23 Jan 2021 06:39:41 GMT",
"Content-Type": "application/json; charset=utf-8",
"Server": "GitHub.com",
"Status": "200 OK",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4239",
"X-RateLimit-Reset": "1572055286",
"Cache-Control": "private, max-age=60, s-maxage=60",
"Vary": [
"Accept, Authorization, Cookie, X-GitHub-OTP",
"Accept-Encoding, Accept, X-Requested-With",
"Accept-Encoding"
],
"ETag": "W/\"e22c642208efa831e007ec061a30aae3\"",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
"ETag": "W/\"9e8eb640e5722329d90564fe83bd1f435fc96bb91d69f800343394957c050e78\"",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
"X-Accepted-OAuth-Scopes": "",
"X-GitHub-Media-Type": "unknown, github.v3",
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
"Access-Control-Allow-Origin": "*",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4941",
"X-RateLimit-Reset": "1611386378",
"x-ratelimit-used": "59",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "CB24:8340:ED23BA:116FEBA:5DB3A15B"
"X-GitHub-Request-Id": "E9F0:5E21:C00FF:DCE46:600BC4AC"
}
},
"uuid": "70a63f41-02d3-404e-af0b-8e1c3cd00494",
"uuid": "4eccc8fc-0026-4272-93b8-76a31a95eeb5",
"persistent": true,
"insertionIndex": 6
"insertionIndex": 7
}

View File

@@ -0,0 +1,42 @@
{
"id": "88c294c8-e966-4052-a675-7bb9038191e0",
"name": "repos_kohsuke_sandbox-ant_comments_46267761",
"request": {
"url": "/repos/kohsuke/sandbox-ant/comments/46267761",
"method": "DELETE",
"headers": {
"Accept": {
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
}
}
},
"response": {
"status": 204,
"headers": {
"Date": "Sat, 23 Jan 2021 06:39:41 GMT",
"Server": "GitHub.com",
"Status": "204 No Content",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
"X-Accepted-OAuth-Scopes": "",
"X-GitHub-Media-Type": "unknown, github.v3",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4940",
"X-RateLimit-Reset": "1611386378",
"x-ratelimit-used": "60",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"Vary": [
"Accept-Encoding, Accept, X-Requested-With",
"Accept-Encoding"
],
"X-GitHub-Request-Id": "E9F0:5E21:C010A:DCE4F:600BC4AD"
}
},
"uuid": "88c294c8-e966-4052-a675-7bb9038191e0",
"persistent": true,
"insertionIndex": 8
}

View File

@@ -0,0 +1,47 @@
{
"id": "caa495ce-fc95-43ae-aa52-4b392bbc8beb",
"name": "repos_kohsuke_sandbox-ant_comments_46267761_reactions",
"request": {
"url": "/repos/kohsuke/sandbox-ant/comments/46267761/reactions",
"method": "GET",
"headers": {
"Accept": {
"equalTo": "application/vnd.github.squirrel-girl-preview+json"
}
}
},
"response": {
"status": 200,
"body": "[]",
"headers": {
"Date": "Sat, 23 Jan 2021 06:39:40 GMT",
"Content-Type": "application/json; charset=utf-8",
"Server": "GitHub.com",
"Status": "200 OK",
"Cache-Control": "private, max-age=60, s-maxage=60",
"Vary": [
"Accept, Authorization, Cookie, X-GitHub-OTP",
"Accept-Encoding, Accept, X-Requested-With",
"Accept-Encoding"
],
"ETag": "\"7d0253ca51c378ca4fa4839bfd5bb1ac338f28e5ac8f6810cbdc8553513d942f\"",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
"X-Accepted-OAuth-Scopes": "",
"X-GitHub-Media-Type": "github.squirrel-girl-preview; format=json",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4942",
"X-RateLimit-Reset": "1611386378",
"x-ratelimit-used": "58",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "E9F0:5E21:C00FA:DCE40:600BC4AC"
}
},
"uuid": "caa495ce-fc95-43ae-aa52-4b392bbc8beb",
"persistent": true,
"insertionIndex": 6
}

View File

@@ -1,5 +1,5 @@
{
"id": "d1822d1b-5505-42ae-ba1d-ae0496d76c19",
"id": "7e297839-c637-4c01-a773-27c649765e10",
"name": "repos_kohsuke_sandbox-ant_commits_8ae38db0ea5837313ab5f39d43a6f73de3bd9000",
"request": {
"url": "/repos/kohsuke/sandbox-ant/commits/8ae38db0ea5837313ab5f39d43a6f73de3bd9000",
@@ -14,35 +14,35 @@
"status": 200,
"bodyFileName": "repos_kohsuke_sandbox-ant_commits_8ae38db0ea5837313ab5f39d43a6f73de3bd9000-4.json",
"headers": {
"Date": "Sat, 26 Oct 2019 01:28:58 GMT",
"Date": "Sat, 23 Jan 2021 06:39:40 GMT",
"Content-Type": "application/json; charset=utf-8",
"Server": "GitHub.com",
"Status": "200 OK",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4241",
"X-RateLimit-Reset": "1572055286",
"Cache-Control": "private, max-age=60, s-maxage=60",
"Vary": [
"Accept, Authorization, Cookie, X-GitHub-OTP",
"Accept-Encoding, Accept, X-Requested-With",
"Accept-Encoding"
],
"ETag": "W/\"f7ff477379d3449f082c148579824d0f\"",
"Last-Modified": "Tue, 24 Apr 2012 22:54:20 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
"ETag": "W/\"139c7c0d228567659135acca1ec295558864e921bd0f87cebb65f72058545d99\"",
"last-modified": "Tue, 24 Apr 2012 22:54:20 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
"X-Accepted-OAuth-Scopes": "",
"X-GitHub-Media-Type": "unknown, github.v3",
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
"Access-Control-Allow-Origin": "*",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4944",
"X-RateLimit-Reset": "1611386378",
"x-ratelimit-used": "56",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "CB24:8340:ED2375:116FE66:5DB3A15A"
"X-GitHub-Request-Id": "E9F0:5E21:C00E8:DCE27:600BC4AB"
}
},
"uuid": "d1822d1b-5505-42ae-ba1d-ae0496d76c19",
"uuid": "7e297839-c637-4c01-a773-27c649765e10",
"persistent": true,
"insertionIndex": 4
}

View File

@@ -1,55 +1,55 @@
{
"id": "62d11eb1-6045-42a7-988a-aae9d9f3800b",
"id": "c0911355-a85d-40b9-b291-e0c098407d2e",
"name": "repos_kohsuke_sandbox-ant_commits_8ae38db0ea5837313ab5f39d43a6f73de3bd9000_comments",
"request": {
"url": "/repos/kohsuke/sandbox-ant/commits/8ae38db0ea5837313ab5f39d43a6f73de3bd9000/comments",
"method": "POST",
"bodyPatterns": [
{
"equalToJson": "{\"body\":\"[testing](http://kohsuse.org/)\"}",
"ignoreArrayOrder": true,
"ignoreExtraElements": true
}
],
"headers": {
"Accept": {
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
}
}
},
"bodyPatterns": [
{
"equalToJson": "{\"body\":\"[testing](http://kohsuse.org/)\"}",
"ignoreArrayOrder": true,
"ignoreExtraElements": false
}
]
},
"response": {
"status": 201,
"bodyFileName": "repos_kohsuke_sandbox-ant_commits_8ae38db0ea5837313ab5f39d43a6f73de3bd9000_comments-5.json",
"headers": {
"Date": "Sat, 26 Oct 2019 01:28:59 GMT",
"Date": "Sat, 23 Jan 2021 06:39:40 GMT",
"Content-Type": "application/json; charset=utf-8",
"Server": "GitHub.com",
"Status": "201 Created",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4240",
"X-RateLimit-Reset": "1572055286",
"Cache-Control": "private, max-age=60, s-maxage=60",
"Vary": [
"Accept, Authorization, Cookie, X-GitHub-OTP",
"Accept-Encoding, Accept, X-Requested-With",
"Accept-Encoding"
],
"ETag": "\"1ebfc3d7a9cbe1bfbab78c1636ef102a\"",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
"ETag": "\"de435e64b07783ba615db4fd69d86e8c13c4fe1281f1265937cf7b887dad2579\"",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
"X-Accepted-OAuth-Scopes": "",
"Location": "https://api.github.com/repos/kohsuke/sandbox-ant/comments/35673784",
"Location": "https://api.github.com/repos/kohsuke/sandbox-ant/comments/46267761",
"X-GitHub-Media-Type": "unknown, github.v3",
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
"Access-Control-Allow-Origin": "*",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4943",
"X-RateLimit-Reset": "1611386378",
"x-ratelimit-used": "57",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "CB24:8340:ED2399:116FE83:5DB3A15A"
"X-GitHub-Request-Id": "E9F0:5E21:C00ED:DCE30:600BC4AC"
}
},
"uuid": "62d11eb1-6045-42a7-988a-aae9d9f3800b",
"uuid": "c0911355-a85d-40b9-b291-e0c098407d2e",
"persistent": true,
"insertionIndex": 5
}

View File

@@ -1,5 +1,5 @@
{
"id": "a9b48b44-c9ff-4434-9f98-64195b0c46ce",
"id": "4b33e8fd-7ae4-4141-8bfc-96d62e8361dc",
"name": "user",
"request": {
"url": "/user",
@@ -14,35 +14,35 @@
"status": 200,
"bodyFileName": "user-1.json",
"headers": {
"Date": "Sat, 26 Oct 2019 01:28:58 GMT",
"Date": "Sat, 23 Jan 2021 06:39:39 GMT",
"Content-Type": "application/json; charset=utf-8",
"Server": "GitHub.com",
"Status": "200 OK",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4245",
"X-RateLimit-Reset": "1572055286",
"Cache-Control": "private, max-age=60, s-maxage=60",
"Vary": [
"Accept, Authorization, Cookie, X-GitHub-OTP",
"Accept-Encoding, Accept, X-Requested-With",
"Accept-Encoding"
],
"ETag": "W/\"8c3d3dcf6fc5f9edaf26c902295396e5\"",
"Last-Modified": "Tue, 24 Sep 2019 19:32:29 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
"ETag": "W/\"c8b61de8f7b00ef1a040d10e88b51dd065defb82f7d94a95a97b3dbab636edbe\"",
"last-modified": "Fri, 22 Jan 2021 16:38:42 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
"X-Accepted-OAuth-Scopes": "",
"X-GitHub-Media-Type": "unknown, github.v3",
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
"Access-Control-Allow-Origin": "*",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4948",
"X-RateLimit-Reset": "1611386378",
"x-ratelimit-used": "52",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "CB24:8340:ED234A:116FE30:5DB3A15A"
"X-GitHub-Request-Id": "E9F0:5E21:C00C9:DCE0A:600BC4AA"
}
},
"uuid": "a9b48b44-c9ff-4434-9f98-64195b0c46ce",
"uuid": "4b33e8fd-7ae4-4141-8bfc-96d62e8361dc",
"persistent": true,
"insertionIndex": 1
}

View File

@@ -1,5 +1,5 @@
{
"id": "a4924f94-0b1c-4cb0-bf1f-595ccb78aa41",
"id": "bdde4d6a-6b43-4ee2-8e93-4c4ec59bccf4",
"name": "users_kohsuke",
"request": {
"url": "/users/kohsuke",
@@ -14,35 +14,35 @@
"status": 200,
"bodyFileName": "users_kohsuke-2.json",
"headers": {
"Date": "Sat, 26 Oct 2019 01:28:58 GMT",
"Date": "Sat, 23 Jan 2021 06:39:39 GMT",
"Content-Type": "application/json; charset=utf-8",
"Server": "GitHub.com",
"Status": "200 OK",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4243",
"X-RateLimit-Reset": "1572055286",
"Cache-Control": "private, max-age=60, s-maxage=60",
"Vary": [
"Accept, Authorization, Cookie, X-GitHub-OTP",
"Accept-Encoding, Accept, X-Requested-With",
"Accept-Encoding"
],
"ETag": "W/\"99c27226f3b6139ef2af80ccbcd5d252\"",
"Last-Modified": "Fri, 25 Oct 2019 16:53:26 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
"ETag": "W/\"e41eed9772453b3fbbdb7bba892d24e645750ddd73b3a74c68106566916b3312\"",
"last-modified": "Fri, 22 Jan 2021 19:41:07 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
"X-Accepted-OAuth-Scopes": "",
"X-GitHub-Media-Type": "unknown, github.v3",
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
"Access-Control-Allow-Origin": "*",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4946",
"X-RateLimit-Reset": "1611386378",
"x-ratelimit-used": "54",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "CB24:8340:ED235B:116FE3C:5DB3A15A"
"X-GitHub-Request-Id": "E9F0:5E21:C00DB:DCE0C:600BC4AB"
}
},
"uuid": "a4924f94-0b1c-4cb0-bf1f-595ccb78aa41",
"uuid": "bdde4d6a-6b43-4ee2-8e93-4c4ec59bccf4",
"persistent": true,
"insertionIndex": 2
}

View File

@@ -0,0 +1,308 @@
{
"id": 197345677,
"node_id": "MDEwOlJlcG9zaXRvcnkxOTczNDU2Nzc=",
"name": "lerna",
"full_name": "daddyfatstacksBIG/lerna",
"private": false,
"owner": {
"login": "daddyfatstacksBIG",
"id": 50436469,
"node_id": "MDQ6VXNlcjUwNDM2NDY5",
"avatar_url": "https://avatars3.githubusercontent.com/u/50436469?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/daddyfatstacksBIG",
"html_url": "https://github.com/daddyfatstacksBIG",
"followers_url": "https://api.github.com/users/daddyfatstacksBIG/followers",
"following_url": "https://api.github.com/users/daddyfatstacksBIG/following{/other_user}",
"gists_url": "https://api.github.com/users/daddyfatstacksBIG/gists{/gist_id}",
"starred_url": "https://api.github.com/users/daddyfatstacksBIG/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/daddyfatstacksBIG/subscriptions",
"organizations_url": "https://api.github.com/users/daddyfatstacksBIG/orgs",
"repos_url": "https://api.github.com/users/daddyfatstacksBIG/repos",
"events_url": "https://api.github.com/users/daddyfatstacksBIG/events{/privacy}",
"received_events_url": "https://api.github.com/users/daddyfatstacksBIG/received_events",
"type": "User",
"site_admin": false
},
"html_url": "https://github.com/daddyfatstacksBIG/lerna",
"description": ":dragon: A tool for managing JavaScript projects with multiple packages.",
"fork": true,
"url": "https://api.github.com/repos/daddyfatstacksBIG/lerna",
"forks_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/forks",
"keys_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/teams",
"hooks_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/hooks",
"issue_events_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/issues/events{/number}",
"events_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/events",
"assignees_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/assignees{/user}",
"branches_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/branches{/branch}",
"tags_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/tags",
"blobs_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/statuses/{sha}",
"languages_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/languages",
"stargazers_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/stargazers",
"contributors_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/contributors",
"subscribers_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/subscribers",
"subscription_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/subscription",
"commits_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/contents/{+path}",
"compare_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/merges",
"archive_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/downloads",
"issues_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/issues{/number}",
"pulls_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/pulls{/number}",
"milestones_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/milestones{/number}",
"notifications_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/labels{/name}",
"releases_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/releases{/id}",
"deployments_url": "https://api.github.com/repos/daddyfatstacksBIG/lerna/deployments",
"created_at": "2019-07-17T08:14:07Z",
"updated_at": "2020-06-09T04:42:07Z",
"pushed_at": "2020-06-09T04:42:04Z",
"git_url": "git://github.com/daddyfatstacksBIG/lerna.git",
"ssh_url": "git@github.com:daddyfatstacksBIG/lerna.git",
"clone_url": "https://github.com/daddyfatstacksBIG/lerna.git",
"svn_url": "https://github.com/daddyfatstacksBIG/lerna",
"homepage": "https://lerna.js.org",
"size": 8388,
"stargazers_count": 0,
"watchers_count": 0,
"language": "JavaScript",
"has_issues": false,
"has_projects": true,
"has_downloads": true,
"has_wiki": false,
"has_pages": false,
"forks_count": 0,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 1,
"license": {
"key": "mit",
"name": "MIT License",
"spdx_id": "MIT",
"url": "https://api.github.com/licenses/mit",
"node_id": "MDc6TGljZW5zZTEz"
},
"forks": 0,
"open_issues": 1,
"watchers": 0,
"default_branch": "master",
"permissions": {
"admin": false,
"push": false,
"pull": true
},
"temp_clone_token": "",
"parent": {
"id": 47394776,
"node_id": "MDEwOlJlcG9zaXRvcnk0NzM5NDc3Ng==",
"name": "lerna",
"full_name": "lerna/lerna",
"private": false,
"owner": {
"login": "lerna",
"id": 19333396,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE5MzMzMzk2",
"avatar_url": "https://avatars2.githubusercontent.com/u/19333396?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/lerna",
"html_url": "https://github.com/lerna",
"followers_url": "https://api.github.com/users/lerna/followers",
"following_url": "https://api.github.com/users/lerna/following{/other_user}",
"gists_url": "https://api.github.com/users/lerna/gists{/gist_id}",
"starred_url": "https://api.github.com/users/lerna/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/lerna/subscriptions",
"organizations_url": "https://api.github.com/users/lerna/orgs",
"repos_url": "https://api.github.com/users/lerna/repos",
"events_url": "https://api.github.com/users/lerna/events{/privacy}",
"received_events_url": "https://api.github.com/users/lerna/received_events",
"type": "Organization",
"site_admin": false
},
"html_url": "https://github.com/lerna/lerna",
"description": ":dragon: A tool for managing JavaScript projects with multiple packages.",
"fork": false,
"url": "https://api.github.com/repos/lerna/lerna",
"forks_url": "https://api.github.com/repos/lerna/lerna/forks",
"keys_url": "https://api.github.com/repos/lerna/lerna/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/lerna/lerna/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/lerna/lerna/teams",
"hooks_url": "https://api.github.com/repos/lerna/lerna/hooks",
"issue_events_url": "https://api.github.com/repos/lerna/lerna/issues/events{/number}",
"events_url": "https://api.github.com/repos/lerna/lerna/events",
"assignees_url": "https://api.github.com/repos/lerna/lerna/assignees{/user}",
"branches_url": "https://api.github.com/repos/lerna/lerna/branches{/branch}",
"tags_url": "https://api.github.com/repos/lerna/lerna/tags",
"blobs_url": "https://api.github.com/repos/lerna/lerna/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/lerna/lerna/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/lerna/lerna/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/lerna/lerna/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/lerna/lerna/statuses/{sha}",
"languages_url": "https://api.github.com/repos/lerna/lerna/languages",
"stargazers_url": "https://api.github.com/repos/lerna/lerna/stargazers",
"contributors_url": "https://api.github.com/repos/lerna/lerna/contributors",
"subscribers_url": "https://api.github.com/repos/lerna/lerna/subscribers",
"subscription_url": "https://api.github.com/repos/lerna/lerna/subscription",
"commits_url": "https://api.github.com/repos/lerna/lerna/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/lerna/lerna/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/lerna/lerna/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/lerna/lerna/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/lerna/lerna/contents/{+path}",
"compare_url": "https://api.github.com/repos/lerna/lerna/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/lerna/lerna/merges",
"archive_url": "https://api.github.com/repos/lerna/lerna/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/lerna/lerna/downloads",
"issues_url": "https://api.github.com/repos/lerna/lerna/issues{/number}",
"pulls_url": "https://api.github.com/repos/lerna/lerna/pulls{/number}",
"milestones_url": "https://api.github.com/repos/lerna/lerna/milestones{/number}",
"notifications_url": "https://api.github.com/repos/lerna/lerna/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/lerna/lerna/labels{/name}",
"releases_url": "https://api.github.com/repos/lerna/lerna/releases{/id}",
"deployments_url": "https://api.github.com/repos/lerna/lerna/deployments",
"created_at": "2015-12-04T09:36:55Z",
"updated_at": "2021-01-14T22:58:27Z",
"pushed_at": "2021-01-09T20:24:41Z",
"git_url": "git://github.com/lerna/lerna.git",
"ssh_url": "git@github.com:lerna/lerna.git",
"clone_url": "https://github.com/lerna/lerna.git",
"svn_url": "https://github.com/lerna/lerna",
"homepage": "https://lerna.js.org",
"size": 10634,
"stargazers_count": 26245,
"watchers_count": 26245,
"language": "JavaScript",
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": false,
"has_pages": false,
"forks_count": 1674,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 564,
"license": {
"key": "mit",
"name": "MIT License",
"spdx_id": "MIT",
"url": "https://api.github.com/licenses/mit",
"node_id": "MDc6TGljZW5zZTEz"
},
"forks": 1674,
"open_issues": 564,
"watchers": 26245,
"default_branch": "main"
},
"source": {
"id": 47394776,
"node_id": "MDEwOlJlcG9zaXRvcnk0NzM5NDc3Ng==",
"name": "lerna",
"full_name": "lerna/lerna",
"private": false,
"owner": {
"login": "lerna",
"id": 19333396,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE5MzMzMzk2",
"avatar_url": "https://avatars2.githubusercontent.com/u/19333396?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/lerna",
"html_url": "https://github.com/lerna",
"followers_url": "https://api.github.com/users/lerna/followers",
"following_url": "https://api.github.com/users/lerna/following{/other_user}",
"gists_url": "https://api.github.com/users/lerna/gists{/gist_id}",
"starred_url": "https://api.github.com/users/lerna/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/lerna/subscriptions",
"organizations_url": "https://api.github.com/users/lerna/orgs",
"repos_url": "https://api.github.com/users/lerna/repos",
"events_url": "https://api.github.com/users/lerna/events{/privacy}",
"received_events_url": "https://api.github.com/users/lerna/received_events",
"type": "Organization",
"site_admin": false
},
"html_url": "https://github.com/lerna/lerna",
"description": ":dragon: A tool for managing JavaScript projects with multiple packages.",
"fork": false,
"url": "https://api.github.com/repos/lerna/lerna",
"forks_url": "https://api.github.com/repos/lerna/lerna/forks",
"keys_url": "https://api.github.com/repos/lerna/lerna/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/lerna/lerna/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/lerna/lerna/teams",
"hooks_url": "https://api.github.com/repos/lerna/lerna/hooks",
"issue_events_url": "https://api.github.com/repos/lerna/lerna/issues/events{/number}",
"events_url": "https://api.github.com/repos/lerna/lerna/events",
"assignees_url": "https://api.github.com/repos/lerna/lerna/assignees{/user}",
"branches_url": "https://api.github.com/repos/lerna/lerna/branches{/branch}",
"tags_url": "https://api.github.com/repos/lerna/lerna/tags",
"blobs_url": "https://api.github.com/repos/lerna/lerna/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/lerna/lerna/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/lerna/lerna/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/lerna/lerna/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/lerna/lerna/statuses/{sha}",
"languages_url": "https://api.github.com/repos/lerna/lerna/languages",
"stargazers_url": "https://api.github.com/repos/lerna/lerna/stargazers",
"contributors_url": "https://api.github.com/repos/lerna/lerna/contributors",
"subscribers_url": "https://api.github.com/repos/lerna/lerna/subscribers",
"subscription_url": "https://api.github.com/repos/lerna/lerna/subscription",
"commits_url": "https://api.github.com/repos/lerna/lerna/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/lerna/lerna/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/lerna/lerna/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/lerna/lerna/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/lerna/lerna/contents/{+path}",
"compare_url": "https://api.github.com/repos/lerna/lerna/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/lerna/lerna/merges",
"archive_url": "https://api.github.com/repos/lerna/lerna/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/lerna/lerna/downloads",
"issues_url": "https://api.github.com/repos/lerna/lerna/issues{/number}",
"pulls_url": "https://api.github.com/repos/lerna/lerna/pulls{/number}",
"milestones_url": "https://api.github.com/repos/lerna/lerna/milestones{/number}",
"notifications_url": "https://api.github.com/repos/lerna/lerna/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/lerna/lerna/labels{/name}",
"releases_url": "https://api.github.com/repos/lerna/lerna/releases{/id}",
"deployments_url": "https://api.github.com/repos/lerna/lerna/deployments",
"created_at": "2015-12-04T09:36:55Z",
"updated_at": "2021-01-14T22:58:27Z",
"pushed_at": "2021-01-09T20:24:41Z",
"git_url": "git://github.com/lerna/lerna.git",
"ssh_url": "git@github.com:lerna/lerna.git",
"clone_url": "https://github.com/lerna/lerna.git",
"svn_url": "https://github.com/lerna/lerna",
"homepage": "https://lerna.js.org",
"size": 10634,
"stargazers_count": 26245,
"watchers_count": 26245,
"language": "JavaScript",
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": false,
"has_pages": false,
"forks_count": 1674,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 564,
"license": {
"key": "mit",
"name": "MIT License",
"spdx_id": "MIT",
"url": "https://api.github.com/licenses/mit",
"node_id": "MDc6TGljZW5zZTEz"
},
"forks": 1674,
"open_issues": 564,
"watchers": 26245,
"default_branch": "main"
},
"network_count": 1674,
"subscribers_count": 0
}

View File

@@ -0,0 +1,48 @@
{
"id": "c536ef14-9fde-4a95-ae89-43f6753e4f2a",
"name": "repos_daddyfatstacksbig_lerna",
"request": {
"url": "/repos/daddyfatstacksBIG/lerna",
"method": "GET",
"headers": {
"Accept": {
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
}
}
},
"response": {
"status": 200,
"bodyFileName": "repos_daddyfatstacksbig_lerna-12.json",
"headers": {
"Date": "Fri, 15 Jan 2021 02:18:27 GMT",
"Content-Type": "application/json; charset=utf-8",
"Server": "GitHub.com",
"Status": "200 OK",
"Cache-Control": "private, max-age=60, s-maxage=60",
"Vary": [
"Accept, Authorization, Cookie, X-GitHub-OTP",
"Accept-Encoding, Accept, X-Requested-With",
"Accept-Encoding"
],
"ETag": "W/\"a9b6035f2bfdf3830acbea545b9a837965158f59ac8cf616563e29681b0f0098\"",
"last-modified": "Tue, 09 Jun 2020 04:42:07 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, workflow, write:discussion",
"X-Accepted-OAuth-Scopes": "repo",
"X-GitHub-Media-Type": "unknown, github.v3",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4777",
"X-RateLimit-Reset": "1610678593",
"x-ratelimit-used": "223",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "D91F:62A3:2C8A07:3712B1:6000FB73"
}
},
"uuid": "c536ef14-9fde-4a95-ae89-43f6753e4f2a",
"persistent": true,
"insertionIndex": 12
}

View File

@@ -0,0 +1,126 @@
{
"id": 332135466,
"node_id": "MDEwOlJlcG9zaXRvcnkzMzIxMzU0NjY=",
"name": "github-api-test",
"full_name": "hub4j-test-org/github-api-test",
"private": false,
"owner": {
"login": "hub4j-test-org",
"id": 7544739,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
"avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/hub4j-test-org",
"html_url": "https://github.com/hub4j-test-org",
"followers_url": "https://api.github.com/users/hub4j-test-org/followers",
"following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}",
"gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}",
"starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions",
"organizations_url": "https://api.github.com/users/hub4j-test-org/orgs",
"repos_url": "https://api.github.com/users/hub4j-test-org/repos",
"events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}",
"received_events_url": "https://api.github.com/users/hub4j-test-org/received_events",
"type": "Organization",
"site_admin": false
},
"html_url": "https://github.com/hub4j-test-org/github-api-test",
"description": "A test repository for testing the github-api project: github-api-test",
"fork": false,
"url": "https://api.github.com/repos/hub4j-test-org/github-api-test",
"forks_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/forks",
"keys_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/teams",
"hooks_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/hooks",
"issue_events_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/issues/events{/number}",
"events_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/events",
"assignees_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/assignees{/user}",
"branches_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/branches{/branch}",
"tags_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/tags",
"blobs_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/statuses/{sha}",
"languages_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/languages",
"stargazers_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/stargazers",
"contributors_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/contributors",
"subscribers_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/subscribers",
"subscription_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/subscription",
"commits_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/contents/{+path}",
"compare_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/merges",
"archive_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/downloads",
"issues_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/issues{/number}",
"pulls_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/pulls{/number}",
"milestones_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/milestones{/number}",
"notifications_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/labels{/name}",
"releases_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/releases{/id}",
"deployments_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments",
"created_at": "2021-01-23T05:30:48Z",
"updated_at": "2021-01-23T05:30:52Z",
"pushed_at": "2021-01-23T05:30:50Z",
"git_url": "git://github.com/hub4j-test-org/github-api-test.git",
"ssh_url": "git@github.com:hub4j-test-org/github-api-test.git",
"clone_url": "https://github.com/hub4j-test-org/github-api-test.git",
"svn_url": "https://github.com/hub4j-test-org/github-api-test",
"homepage": "http://github-api.kohsuke.org/",
"size": 0,
"stargazers_count": 0,
"watchers_count": 0,
"language": null,
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": false,
"forks_count": 0,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 0,
"license": null,
"forks": 0,
"open_issues": 0,
"watchers": 0,
"default_branch": "main",
"permissions": {
"admin": true,
"push": true,
"pull": true
},
"temp_clone_token": "",
"allow_squash_merge": true,
"allow_merge_commit": true,
"allow_rebase_merge": true,
"delete_branch_on_merge": false,
"organization": {
"login": "hub4j-test-org",
"id": 7544739,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
"avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/hub4j-test-org",
"html_url": "https://github.com/hub4j-test-org",
"followers_url": "https://api.github.com/users/hub4j-test-org/followers",
"following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}",
"gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}",
"starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions",
"organizations_url": "https://api.github.com/users/hub4j-test-org/orgs",
"repos_url": "https://api.github.com/users/hub4j-test-org/repos",
"events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}",
"received_events_url": "https://api.github.com/users/hub4j-test-org/received_events",
"type": "Organization",
"site_admin": false
},
"network_count": 0,
"subscribers_count": 9
}

View File

@@ -0,0 +1,39 @@
{
"url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601644",
"id": 315601644,
"node_id": "MDEwOkRlcGxveW1lbnQzMTU2MDE2NDQ=",
"task": "deploy",
"original_environment": "production",
"environment": "production",
"description": "question",
"created_at": "2021-01-23T05:30:54Z",
"updated_at": "2021-01-23T05:30:54Z",
"statuses_url": "https://api.github.com/repos/hub4j-test-org/github-api-test/deployments/315601644/statuses",
"repository_url": "https://api.github.com/repos/hub4j-test-org/github-api-test",
"creator": {
"login": "bitwiseman",
"id": 1958953,
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
"avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/bitwiseman",
"html_url": "https://github.com/bitwiseman",
"followers_url": "https://api.github.com/users/bitwiseman/followers",
"following_url": "https://api.github.com/users/bitwiseman/following{/other_user}",
"gists_url": "https://api.github.com/users/bitwiseman/gists{/gist_id}",
"starred_url": "https://api.github.com/users/bitwiseman/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/bitwiseman/subscriptions",
"organizations_url": "https://api.github.com/users/bitwiseman/orgs",
"repos_url": "https://api.github.com/users/bitwiseman/repos",
"events_url": "https://api.github.com/users/bitwiseman/events{/privacy}",
"received_events_url": "https://api.github.com/users/bitwiseman/received_events",
"type": "User",
"site_admin": false
},
"sha": "3ca6395616e9decaba9f350f59eb5b007462e2e7",
"ref": "main",
"payload": "{\"user\":\"atmos\",\"room_id\":123456}",
"transient_environment": false,
"production_environment": false,
"performed_via_github_app": null
}

Some files were not shown because too many files have changed in this diff Show More