Creating a Repo with a Visibility Fails
Describe the bug
When using the GHCreateRepositoryBuilder to create a repo and setting the visibility, the resulting API call fails with the following exception (see below). This happens when any of the Visibility enum values are set (PUBLIC, INTERNAL, or PRIVATE). I'm running this against my company's GitHub instance but I recreated the issue against github.com as well.
To Reproduce Code to re-produce. I am using the latest release of this library; version 1.306:
GitHub.connect(username, token).getOrganization(someOrg).createRepository("a-new-repo").visibility(Visibility.PRIVATE).create();
Error:
Exception in thread "main" org.kohsuke.github.HttpException: {"message":"Invalid visibility. Valid visibilities are: public, private, internal","documentation_url":"https://docs.github.com/rest/reference/repos#create-an-organization-repository"}
at org.kohsuke.github.GitHubConnectorResponseErrorHandler$1.onError(GitHubConnectorResponseErrorHandler.java:56)
at org.kohsuke.github.GitHubClient.detectKnownErrors(GitHubClient.java:424)
at org.kohsuke.github.GitHubClient.sendRequest(GitHubClient.java:386)
at org.kohsuke.github.GitHubClient.sendRequest(GitHubClient.java:355)
at org.kohsuke.github.Requester.fetch(Requester.java:76)
at org.kohsuke.github.AbstractBuilder.done(AbstractBuilder.java:109)
at org.kohsuke.github.GHRepositoryBuilder.done(GHRepositoryBuilder.java:241)
at org.kohsuke.github.GHCreateRepositoryBuilder.done(GHCreateRepositoryBuilder.java:12)
at org.kohsuke.github.GHCreateRepositoryBuilder.create(GHCreateRepositoryBuilder.java:131)
This exception DOES NOT occur when changing the visibility on an existing repo. For example, this works:
someOrganization.getRepository("a-new-repo").setVisibility(Visibility.PRIVATE);
I believe it comes down to how the request is being filled out. When using the builder, the enum is set on the request as an object:
GHRepositoryBuilder calls AbstractBuilder calls GitHubRequest.
In contrast, when setting visibility on an existing repo, a different with overload is eventually invoked that correctly transforms the enum to a lowercase string: GHRepository calls GitHubRequest.
Locally, I changed the GHRepositoryBuilder#visibility method to return with("visibility", visibility.toString()); and the eventual repo creation doesn't fail.
I can try to find some time to work together a patch with the changes but I was having lots of trouble trying to get the project to build on my computer and I'm not quite sure if the above fix is the correct one so I just wanted to open this bug report before doing anything else.
For now, I will just use the "Create" builder to create the repo and then make a separate call afterwards to set the visibility on the newly created Repo with the API that works.
Sorry if this is a bit scatterbrained. Please let me know if there's more info you need from me. Thank you.
What will be the best approach? Calling toString() on the visibility or adding the below method to the AbstractBuilder that will call the proper method in GitHubRequest.
@Nonnull
@BetaApi
protected S with(@Nonnull String name, Enum<?> value) throws IOException {
requester.with(name, value);
return continueOrDone();
}
I will be more than happy to submit a fix for this.
I can be wrong but it looks like GH expects visibility to be lowercase. I think it would be better to use the same approach that is used in the GitHubRequest class: it has overloaded method for enums:
public B with(String key, Enum<?> e) {
if (e == null)
return with(key, (Object) null);
return with(key, transformEnum(e));
}
...
/**
* Transform Java Enum into Github constants given its conventions.
*
* @param en
* Enum to be transformed
* @return a String containing the value of a Github constant
*/
static String transformEnum(Enum<?> en) {
// by convention Java constant names are upper cases, but github uses
// lower-case constants. GitHub also uses '-', which in Java we always
// replace with '_'
return en.toString().toLowerCase(Locale.ENGLISH).replace('_', '-');
}
https://github.com/hub4j/github-api/blob/612f5ec694e2e6c161367259f85e42fb26738631/src/main/java/org/kohsuke/github/GitHubRequest.java#L130
When I try to create a private repo, it is creating as public :(
I have to create it first, then set the visibility to private after.
Basically my experience is consistent with others' above.
@mgroth0 PRs welcome.