diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/student_teams/UpdateBranchProtection.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/student_teams/UpdateBranchProtection.java new file mode 100644 index 0000000..41636b0 --- /dev/null +++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/student_teams/UpdateBranchProtection.java @@ -0,0 +1,51 @@ +package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.student_teams; + +import nl.andrewlalis.teaching_assistant_assistant.model.Course; +import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam; +import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository; +import nl.andrewlalis.teaching_assistant_assistant.util.github.GithubManager; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; + +import java.io.IOException; +import java.util.Optional; + +/** + * Updates branch protection for all student repositories in a given course. + */ +@Controller +public class UpdateBranchProtection { + + private CourseRepository courseRepository; + + protected UpdateBranchProtection(CourseRepository courseRepository) { + this.courseRepository = courseRepository; + } + + @GetMapping("/courses/{code}/student_teams/branch_protection_update") + public String get(@PathVariable String code) { + Optional optionalCourse = this.courseRepository.findByCode(code); + optionalCourse.ifPresent(course -> { + GithubManager manager; + try { + manager = new GithubManager(course.getApiKey()); + } catch (IOException e) { + e.printStackTrace(); + return; + } + + for (StudentTeam team : course.getStudentTeams()) { + try { + manager.updateBranchProtection(course.getGithubOrganizationName(), team.getGithubRepositoryName(), team.getAssignedTeachingAssistantTeam().getGithubTeamName()); + System.out.println("Updated branch protection for repository " + team.getGithubRepositoryName()); + } catch (IOException e) { + e.printStackTrace(); + System.err.println("Error occurred while trying to enable branch protection for repository " + team.getId()); + } + } + }); + + return "redirect:/courses/{code}/student_teams"; + } +} diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/students/InviteAllToRepository.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/students/InviteAllToRepository.java index 4a791d3..bfa2703 100644 --- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/students/InviteAllToRepository.java +++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/students/InviteAllToRepository.java @@ -96,7 +96,7 @@ public class InviteAllToRepository { System.out.println("\tInvited " + username); } catch (IOException e) { //e.printStackTrace(); - System.err.println("Could not add " + username + " to repository " + fullRepositoryName); + System.err.println("Could not add " + username + " to repository " + fullRepositoryName + ": " + e.getMessage()); failedNames.add(username); } } diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/github/GithubManager.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/github/GithubManager.java index 98ab14a..0d84d88 100644 --- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/github/GithubManager.java +++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/github/GithubManager.java @@ -12,12 +12,11 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.kohsuke.github.*; -import java.io.File; -import java.io.IOException; -import java.io.UnsupportedEncodingException; +import java.io.*; import java.net.URL; import java.nio.file.Files; import java.util.Calendar; +import java.util.stream.Collectors; /** * Encapsulates much of the github functionality that is needed. @@ -159,7 +158,7 @@ public class GithubManager { protectionBuilder.includeAdmins(false); protectionBuilder.restrictPushAccess(); protectionBuilder.teamPushAccess(adminTeam); - protectionBuilder.addRequiredChecks("ci/circleci"); + protectionBuilder.addRequiredChecks("ci/circleci: build"); protectionBuilder.enable(); } @@ -188,7 +187,9 @@ public class GithubManager { HttpResponse response = client.execute(put); if (response.getStatusLine().getStatusCode() != 201) { - throw new IOException("Error adding collaborator via url " + url + " : " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); + String content = new BufferedReader(new InputStreamReader(response.getEntity().getContent())) + .lines().collect(Collectors.joining("\n")); + throw new IOException("Error adding collaborator via url " + url + " : " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase() + "\n" + content); } } catch (JsonProcessingException | UnsupportedEncodingException e) { e.printStackTrace(); @@ -199,4 +200,26 @@ public class GithubManager { team.add(repository, GHOrganization.Permission.ADMIN); } + /** + * Updates branch protection for a given repository. That is, removes old branch protection and reinstates it to + * follow updated circleci conventions. + * @param organizationName The name of the organization. + * @param repositoryName The name of the repository. + * @param teamName The name of the team responsible for this repository. + * @throws IOException If an error occurs with any actions. + */ + public void updateBranchProtection(String organizationName, String repositoryName, String teamName) throws IOException { + GHOrganization organization = this.github.getOrganization(organizationName); + GHRepository repository = organization.getRepository(repositoryName); + GHTeam team = organization.getTeamByName(teamName); + + repository.getBranch("master").disableProtection(); + GHBranchProtectionBuilder builder = repository.getBranch("master").enableProtection(); + builder.includeAdmins(false); + builder.restrictPushAccess(); + builder.teamPushAccess(team); + builder.addRequiredChecks("ci/circleci: build"); + builder.enable(); + } + } diff --git a/src/main/resources/templates/courses/entity/student_teams.html b/src/main/resources/templates/courses/entity/student_teams.html index 12dcbab..1f0c2b3 100644 --- a/src/main/resources/templates/courses/entity/student_teams.html +++ b/src/main/resources/templates/courses/entity/student_teams.html @@ -57,6 +57,9 @@ +