Added some package-info files, added a method to archive repositories which contain a substring, and did some more testing. Will add a user interface soon.
This commit is contained in:
parent
46757539a1
commit
e901b0affd
6
pom.xml
6
pom.xml
|
@ -73,6 +73,12 @@
|
|||
<artifactId>github-api</artifactId>
|
||||
<version>1.93</version>
|
||||
</dependency>
|
||||
<!-- SQLite JDBC Driver -->
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.23.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -56,8 +56,8 @@ public class Main {
|
|||
);
|
||||
|
||||
try {
|
||||
githubManager.initializeGithubRepos(studentTeams);
|
||||
//githubManager.deleteAllRepositories();
|
||||
//githubManager.initializeGithubRepos(studentTeams);
|
||||
//githubManager.archiveAllRepositories("team");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
package nl.andrewlalis.git_api;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import nl.andrewlalis.model.Student;
|
||||
import nl.andrewlalis.model.StudentTeam;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpPatch;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.kohsuke.github.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -15,16 +22,6 @@ import java.util.logging.Logger;
|
|||
*/
|
||||
public class GithubManager {
|
||||
|
||||
/**
|
||||
* The name of the organization to operate on.
|
||||
*/
|
||||
private String organizationName;
|
||||
|
||||
/**
|
||||
* The object which simplifies creating REST URL's for most of the requests.
|
||||
*/
|
||||
private URLBuilder urlBuilder;
|
||||
|
||||
/**
|
||||
* The assignments repository where students will get assignments from.
|
||||
*/
|
||||
|
@ -47,6 +44,7 @@ public class GithubManager {
|
|||
*/
|
||||
private GitHub github;
|
||||
private GHOrganization organization;
|
||||
private String accessToken;
|
||||
|
||||
/**
|
||||
* The logger for outputting debug info.
|
||||
|
@ -57,15 +55,14 @@ public class GithubManager {
|
|||
}
|
||||
|
||||
public GithubManager(String organizationName, String accessToken, String assignmentsRepo, String teachingAssistantsTeamName, String studentRepoPrefix) {
|
||||
this.organizationName = organizationName;
|
||||
this.assignmentsRepoName = assignmentsRepo;
|
||||
this.teachingAssistantsTeamName = teachingAssistantsTeamName;
|
||||
this.studentRepoPrefix = studentRepoPrefix;
|
||||
this.urlBuilder = new URLBuilder(organizationName, accessToken);
|
||||
this.accessToken = accessToken;
|
||||
|
||||
try {
|
||||
this.github = GitHub.connectUsingOAuth(accessToken);
|
||||
this.organization = this.github.getOrganization(this.organizationName);
|
||||
this.organization = this.github.getOrganization(organizationName);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -104,6 +101,13 @@ public class GithubManager {
|
|||
* @throws IOException If an HTTP request failed.
|
||||
*/
|
||||
private void setupAssignmentsRepo(GHTeam allTeachingAssistants) throws IOException {
|
||||
// Check if the repository already exists.
|
||||
GHRepository existingRepo = this.organization.getRepository(this.assignmentsRepoName);
|
||||
if (existingRepo != null) {
|
||||
existingRepo.delete();
|
||||
logger.fine("Deleted pre-existing assignments repository.");
|
||||
}
|
||||
|
||||
// Create the repository.
|
||||
GHCreateRepositoryBuilder builder = this.organization.createRepository(this.assignmentsRepoName);
|
||||
builder.description("Assignments repository for Advanced Object Oriented Programming");
|
||||
|
@ -113,6 +117,7 @@ public class GithubManager {
|
|||
builder.team(allTeachingAssistants);
|
||||
builder.gitignoreTemplate("Java");
|
||||
this.assignmentsRepo = builder.create();
|
||||
logger.info("Created assignments repository.");
|
||||
|
||||
// Protect the master branch.
|
||||
GHBranchProtectionBuilder protectionBuilder = this.assignmentsRepo.getBranch("master").enableProtection();
|
||||
|
@ -121,9 +126,11 @@ public class GithubManager {
|
|||
protectionBuilder.teamPushAccess(allTeachingAssistants);
|
||||
protectionBuilder.addRequiredChecks("ci/circleci");
|
||||
protectionBuilder.enable();
|
||||
logger.fine("Protected master branch of assignments repository.");
|
||||
|
||||
// Grant all teaching assistants write access.
|
||||
allTeachingAssistants.add(this.assignmentsRepo, GHOrganization.Permission.ADMIN);
|
||||
logger.fine("Gave admin rights to all teaching assistants in team: " + allTeachingAssistants.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,9 +192,9 @@ public class GithubManager {
|
|||
* @throws IOException if an error occurs with sending requests.
|
||||
*/
|
||||
public void deleteAllRepositories() throws IOException {
|
||||
Map<String, GHRepository> repoMap = this.organization.getRepositories();
|
||||
for (Map.Entry<String, GHRepository> repoEntry : repoMap.entrySet()) {
|
||||
repoEntry.getValue().delete();
|
||||
List<GHRepository> repositories = this.organization.listRepositories().asList();
|
||||
for (GHRepository repo : repositories) {
|
||||
repo.delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,8 +202,25 @@ public class GithubManager {
|
|||
* Archives all repositories whose name contains the given substring.
|
||||
* @param sub Any repository containing this substring will be archived.
|
||||
*/
|
||||
public void archiveAllRepositories(String sub) {
|
||||
|
||||
public void archiveAllRepositories(String sub) throws IOException {
|
||||
List<GHRepository> repositories = this.organization.listRepositories().asList();
|
||||
for (GHRepository repo : repositories) {
|
||||
if (repo.getName().contains(sub)) {
|
||||
HttpPatch patch = new HttpPatch("https://api.github.com/repos/" + repo.getFullName() + "?access_token=" + this.accessToken);
|
||||
CloseableHttpClient client = HttpClientBuilder.create().build();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
ObjectNode root = mapper.createObjectNode();
|
||||
root.put("archived", true);
|
||||
String json = mapper.writeValueAsString(root);
|
||||
patch.setEntity(new StringEntity(json));
|
||||
HttpResponse response = client.execute(patch);
|
||||
if (response.getStatusLine().getStatusCode() != 200) {
|
||||
throw new IOException("Could not archive repository: " + repo.getName() + ". Code: " + response.getStatusLine().getStatusCode());
|
||||
}
|
||||
logger.info("Archived repository: " + repo.getFullName());
|
||||
// TODO: archive repository using Github Java API, instead of Apache HttpUtils.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,140 +0,0 @@
|
|||
package nl.andrewlalis.git_api;
|
||||
|
||||
public class URLBuilder {
|
||||
|
||||
/**
|
||||
* The main URL from which all requests must be formed.
|
||||
*/
|
||||
private static final String baseURL = "https://api.github.com";
|
||||
|
||||
/**
|
||||
* The name of the github organization in which to create repositories.
|
||||
*/
|
||||
private String organizationName;
|
||||
|
||||
/**
|
||||
* The token needed to use the API.
|
||||
*/
|
||||
private String accessToken;
|
||||
|
||||
public URLBuilder(String organizationName, String accessToken) {
|
||||
this.organizationName = organizationName;
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The URL for adding a repository.
|
||||
*/
|
||||
public String buildRepoURL() {
|
||||
return baseURL
|
||||
+ "/orgs/"
|
||||
+ this.organizationName
|
||||
+ "/repos?access_token="
|
||||
+ this.accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param repoName The name of the repository.
|
||||
* @param branch The name of the branch in the repository above.
|
||||
* @return The URL for setting branch protection.
|
||||
*/
|
||||
public String buildBranchProtectionURL(String repoName, String branch) {
|
||||
return baseURL
|
||||
+ "/repos/"
|
||||
+ this.organizationName
|
||||
+ '/'
|
||||
+ repoName
|
||||
+ "/branches/"
|
||||
+ branch
|
||||
+ "/protection?access_token="
|
||||
+ this.accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param repoName The name of the repository the branch is in.
|
||||
* @return The URL for getting a branch reference.
|
||||
*/
|
||||
public String buildReferenceGetURL(String repoName) {
|
||||
return baseURL
|
||||
+ "/repos/"
|
||||
+ this.organizationName
|
||||
+ '/'
|
||||
+ repoName
|
||||
+ "/git/refs/heads/master?access_token="
|
||||
+ this.accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param repoName The repository name.
|
||||
* @return The URL for creating a new branch, once a reference has been obtained.
|
||||
*/
|
||||
public String buildReferencePostURL(String repoName) {
|
||||
return baseURL
|
||||
+ "/repos/"
|
||||
+ this.organizationName
|
||||
+ '/'
|
||||
+ repoName
|
||||
+ "/git/refs?access_token="
|
||||
+ this.accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param repoName The name of the repository.
|
||||
* @param collaborator The collaborator's name.
|
||||
* @return The URL for adding a collaborator to a repository.
|
||||
*/
|
||||
public String buildCollaboratorURL(String repoName, String collaborator) {
|
||||
return baseURL
|
||||
+ "/repos/"
|
||||
+ this.organizationName
|
||||
+ '/'
|
||||
+ repoName
|
||||
+ "/collaborators/"
|
||||
+ collaborator
|
||||
+ "?access_token="
|
||||
+ this.accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The URL for obtaining the teams.
|
||||
*/
|
||||
public String buildTeamURL() {
|
||||
return baseURL
|
||||
+ "/orgs/"
|
||||
+ this.organizationName
|
||||
+ "/teams?access_token="
|
||||
+ this.accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param repoName The name of the repository.
|
||||
* @param teamName The name of the team to set permissions for.
|
||||
* @return The URL for setting team permissions of a repository.
|
||||
*/
|
||||
public String buildTeamPermissionsURL(String repoName, String teamName) {
|
||||
return baseURL
|
||||
+ "/teams/"
|
||||
+ teamName
|
||||
+ "/repos/"
|
||||
+ this.organizationName
|
||||
+ '/'
|
||||
+ repoName
|
||||
+ "?access_token="
|
||||
+ this.accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param repoName The name of the repository.
|
||||
* @return The URL for archiving a repository.
|
||||
*/
|
||||
public String buildArchiveRepoURL(String repoName) {
|
||||
return baseURL
|
||||
+ "/repos/"
|
||||
+ this.organizationName
|
||||
+ '/'
|
||||
+ repoName
|
||||
+ "?access_token="
|
||||
+ this.accessToken;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
/**
|
||||
* Contains all logic which directly interacts with the Github API. All methods which need to perform an action on a
|
||||
* repository or team should find it within this package.
|
||||
*
|
||||
* @author Andrew Lalis
|
||||
*/
|
||||
package nl.andrewlalis.git_api;
|
|
@ -1,7 +1,5 @@
|
|||
package nl.andrewlalis.model;
|
||||
|
||||
import org.kohsuke.github.GHTeam;
|
||||
|
||||
public class TeachingAssistant extends Person {
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
/**
|
||||
* Contains all objects which form the conceptual basis for this application, such as Students, Teams, and any other
|
||||
* abstract data containers.
|
||||
*
|
||||
* @author Andrew Lalis
|
||||
*/
|
||||
package nl.andrewlalis.model;
|
Loading…
Reference in New Issue