diff --git a/pom.xml b/pom.xml index 2510ab2..7137563 100644 --- a/pom.xml +++ b/pom.xml @@ -73,6 +73,12 @@ github-api 1.93 + + + org.xerial + sqlite-jdbc + 3.23.1 + \ No newline at end of file diff --git a/src/main/java/nl/andrewlalis/Main.java b/src/main/java/nl/andrewlalis/Main.java index ad58dab..ce4ea6e 100644 --- a/src/main/java/nl/andrewlalis/Main.java +++ b/src/main/java/nl/andrewlalis/Main.java @@ -56,8 +56,8 @@ public class Main { ); try { - githubManager.initializeGithubRepos(studentTeams); - //githubManager.deleteAllRepositories(); + //githubManager.initializeGithubRepos(studentTeams); + //githubManager.archiveAllRepositories("team"); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/java/nl/andrewlalis/git_api/GithubManager.java b/src/main/java/nl/andrewlalis/git_api/GithubManager.java index 011d51d..882658c 100644 --- a/src/main/java/nl/andrewlalis/git_api/GithubManager.java +++ b/src/main/java/nl/andrewlalis/git_api/GithubManager.java @@ -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 repoMap = this.organization.getRepositories(); - for (Map.Entry repoEntry : repoMap.entrySet()) { - repoEntry.getValue().delete(); + List 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 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. + } + } } } diff --git a/src/main/java/nl/andrewlalis/git_api/URLBuilder.java b/src/main/java/nl/andrewlalis/git_api/URLBuilder.java deleted file mode 100644 index 5966224..0000000 --- a/src/main/java/nl/andrewlalis/git_api/URLBuilder.java +++ /dev/null @@ -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; - } - -} diff --git a/src/main/java/nl/andrewlalis/git_api/package-info.java b/src/main/java/nl/andrewlalis/git_api/package-info.java new file mode 100644 index 0000000..097515a --- /dev/null +++ b/src/main/java/nl/andrewlalis/git_api/package-info.java @@ -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; \ No newline at end of file diff --git a/src/main/java/nl/andrewlalis/model/TeachingAssistant.java b/src/main/java/nl/andrewlalis/model/TeachingAssistant.java index f04723f..918bb5c 100644 --- a/src/main/java/nl/andrewlalis/model/TeachingAssistant.java +++ b/src/main/java/nl/andrewlalis/model/TeachingAssistant.java @@ -1,7 +1,5 @@ package nl.andrewlalis.model; -import org.kohsuke.github.GHTeam; - public class TeachingAssistant extends Person { /** diff --git a/src/main/java/nl/andrewlalis/model/package-info.java b/src/main/java/nl/andrewlalis/model/package-info.java new file mode 100644 index 0000000..d8465c9 --- /dev/null +++ b/src/main/java/nl/andrewlalis/model/package-info.java @@ -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; \ No newline at end of file