diff options
11 files changed, 310 insertions, 188 deletions
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5515be668..8becd5cbb 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -42,7 +42,7 @@ jobs: api_user: ${{ secrets.BOT_MASTER_RW_GITHUB_USERNAME }} api_token: ${{ secrets.BOT_MASTER_RW_GITHUB_TOKEN }} - name: status-success - run: ./gradlew --stacktrace :deployment:updateDeploymentState -PRequest.apiUsername="${{ secrets.BOT_MASTER_RW_GITHUB_USERNAME }}" -PRequest.apiUserToken="${{ secrets.BOT_MASTER_RW_GITHUB_TOKEN }}" -PrequestStatus.environment="${{ github.event.deployment.environment }}" -PrequestStatus.deployment_id="${{ github.event.deployment.id }}" -PrequestStatus.deployment_state="success" + run: ./gradlew --stacktrace :deployment:updateDeploymentSuccess -PRequest.apiUsername="${{ secrets.BOT_MASTER_RW_GITHUB_USERNAME }}" -PRequest.apiUserToken="${{ secrets.BOT_MASTER_RW_GITHUB_TOKEN }}" -PrequestStatus.environment="${{ github.event.deployment.environment }}" -PrequestStatus.deployment_id="${{ github.event.deployment.id }}" -PrequestStatus.environment="${{ github.event.deployment.environment }}" -PrequestStatus.sha="${{ github.event.deployment.sha }}" - name: status-failure if: failure() run: ./gradlew --stacktrace :deployment:updateDeploymentState -PRequest.apiUsername="${{ secrets.BOT_MASTER_RW_GITHUB_USERNAME }}" -PRequest.apiUserToken="${{ secrets.BOT_MASTER_RW_GITHUB_TOKEN }}" -PrequestStatus.environment="${{ github.event.deployment.environment }}" -PrequestStatus.deployment_id="${{ github.event.deployment.id }}" -PrequestStatus.deployment_state="failure" diff --git a/buildSrc/src/main/java/deployment/DeploymentPlugin.java b/buildSrc/src/main/java/deployment/DeploymentPlugin.java index ccc41fa3d..a29645543 100644 --- a/buildSrc/src/main/java/deployment/DeploymentPlugin.java +++ b/buildSrc/src/main/java/deployment/DeploymentPlugin.java @@ -43,6 +43,15 @@ public class DeploymentPlugin implements Plugin<Project> { propertyOrDefault( project, "requestStatus.deployment_state", "")); }); + project.getTasks() + .register( + "updateDeploymentSuccess", + DeploymentSuccessRequestTask.class, + task -> { + task.setEnvironmentName( + propertyOrDefault(project, "requestStatus.environment", "")); + task.setSha(propertyOrDefault(project, "requestStatus.sha", "")); + }); } private void createDeployTasks(Project project) { diff --git a/buildSrc/src/main/java/deployment/DeploymentRequestProcessTask.java b/buildSrc/src/main/java/deployment/DeploymentRequestProcessTask.java index 8d2f9a86d..57ee6b2f7 100644 --- a/buildSrc/src/main/java/deployment/DeploymentRequestProcessTask.java +++ b/buildSrc/src/main/java/deployment/DeploymentRequestProcessTask.java @@ -1,6 +1,6 @@ package deployment; -import github.Deployment; +import github.DeploymentCreate; import java.util.Collections; import java.util.List; import java.util.Locale; @@ -58,12 +58,13 @@ public class DeploymentRequestProcessTask extends DefaultTask { int stepIndex) throws Exception { - Deployment deployment = new Deployment(data.apiUsername, data.apiUserToken); - requestDeploymentAction(deployment, data, configuration, stepIndex); + DeploymentCreate deploymentCreate = + new DeploymentCreate(data.apiUsername, data.apiUserToken); + requestDeploymentAction(deploymentCreate, data, configuration, stepIndex); } private static void requestDeploymentAction( - Deployment deployment, + DeploymentCreate deploymentCreate, DeploymentCommandLineArgs data, DeploymentProcessConfiguration environment, int stepIndex) @@ -75,9 +76,9 @@ public class DeploymentRequestProcessTask extends DefaultTask { .filter(env -> !env.equals(environmentToDeploy)) .collect(Collectors.toList()); - final Deployment.Response response = - deployment.requestDeployment( - new Deployment.Request( + final DeploymentCreate.Response response = + deploymentCreate.request( + new DeploymentCreate.Request( data.sha, stepIndex == 0 ? "deploy" : "deploy:migration", false, @@ -88,7 +89,7 @@ public class DeploymentRequestProcessTask extends DefaultTask { environmentToDeploy, data.apiUsername), Collections.singletonList("master-green-requirement"), - new Deployment.RequestPayloadField(environmentsToKill))); + new DeploymentCreate.RequestPayloadField(environmentsToKill))); System.out.println( String.format( diff --git a/buildSrc/src/main/java/deployment/DeploymentStatusRequestTask.java b/buildSrc/src/main/java/deployment/DeploymentStatusRequestTask.java index 19beacc5e..c4d8c1760 100644 --- a/buildSrc/src/main/java/deployment/DeploymentStatusRequestTask.java +++ b/buildSrc/src/main/java/deployment/DeploymentStatusRequestTask.java @@ -2,20 +2,12 @@ package deployment; import github.DeploymentStatus; import java.util.Locale; -import java.util.Map; import javax.inject.Inject; import org.gradle.api.DefaultTask; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.TaskAction; public abstract class DeploymentStatusRequestTask extends DefaultTask { - static class StatusCommandLineArgs extends RequestCommandLineArgs { - - StatusCommandLineArgs(Map<String, ?> properties) { - super(properties); - } - } - private String mEnvironmentName; private String mDeploymentId; private String mDeploymentState; @@ -57,7 +49,7 @@ public abstract class DeploymentStatusRequestTask extends DefaultTask { public void statusAction() { try { statusRequest( - new StatusCommandLineArgs(getProject().getProperties()), + new RequestCommandLineArgs(getProject().getProperties()), mEnvironmentName, mDeploymentId, mDeploymentState); @@ -66,14 +58,13 @@ public abstract class DeploymentStatusRequestTask extends DefaultTask { } } - private static void statusRequest( - StatusCommandLineArgs data, String environment, String deploymentId, String newStatus) + static void statusRequest( + RequestCommandLineArgs data, String environment, String deploymentId, String newStatus) throws Exception { DeploymentStatus status = new DeploymentStatus(data.apiUsername, data.apiUserToken); final DeploymentStatus.Response response = - status.requestDeploymentStatus( - deploymentId, new DeploymentStatus.Request(environment, newStatus)); + status.request(new DeploymentStatus.Request(deploymentId, environment, newStatus)); System.out.println( String.format( diff --git a/buildSrc/src/main/java/deployment/DeploymentSuccessRequestTask.java b/buildSrc/src/main/java/deployment/DeploymentSuccessRequestTask.java new file mode 100644 index 000000000..798951636 --- /dev/null +++ b/buildSrc/src/main/java/deployment/DeploymentSuccessRequestTask.java @@ -0,0 +1,92 @@ +package deployment; + +import github.DeploymentsList; +import java.util.Arrays; +import java.util.Locale; +import java.util.stream.Collectors; +import javax.inject.Inject; +import org.gradle.api.DefaultTask; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.TaskAction; + +public abstract class DeploymentSuccessRequestTask extends DefaultTask { + + private String mEnvironmentSha; + private String mEnvironmentName; + + @Inject + public DeploymentSuccessRequestTask() { + setGroup("Publishing"); + setDescription( + "Request to set status to success for " + + mEnvironmentName + + " with sha " + + mEnvironmentSha); + } + + @Input + public String getEnvironmentName() { + return mEnvironmentName; + } + + public void setEnvironmentName(String environmentName) { + this.mEnvironmentName = environmentName; + } + + @Input + public String getSha() { + return mEnvironmentSha; + } + + public void setSha(String sha) { + this.mEnvironmentSha = sha; + } + + @TaskAction + public void statusAction() { + final String processName = mEnvironmentName.substring(0, mEnvironmentName.indexOf('_') + 1); + try { + final RequestCommandLineArgs data = + new RequestCommandLineArgs(getProject().getProperties()); + final DeploymentsList.Response[] responses = listRequest(data, mEnvironmentSha); + for (DeploymentsList.Response response : responses) { + if (response.environment.startsWith(processName)) { + final String status = + response.environment.equals(mEnvironmentName) ? "success" : "inactive"; + System.out.println( + "Will change environment " + + response.environment + + " with id " + + response.id + + " to status " + + status); + DeploymentStatusRequestTask.statusRequest( + data, response.environment, response.id, status); + } else { + System.out.println( + "Skipping " + + response.environment + + " since it's not in the same process."); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static DeploymentsList.Response[] listRequest(RequestCommandLineArgs data, String sha) + throws Exception { + + DeploymentsList list = new DeploymentsList(data.apiUsername, data.apiUserToken); + final DeploymentsList.Response[] response = list.request(new DeploymentsList.Request(sha)); + + System.out.println( + String.format( + Locale.ROOT, + "Deployment-status request response: length %d, environments %s.", + response.length, + Arrays.stream(response).map(r -> r.id).collect(Collectors.joining(",")))); + + return response; + } +} diff --git a/buildSrc/src/main/java/github/Deployment.java b/buildSrc/src/main/java/github/Deployment.java deleted file mode 100644 index e48ec952a..000000000 --- a/buildSrc/src/main/java/github/Deployment.java +++ /dev/null @@ -1,116 +0,0 @@ -package github; - -import com.google.gson.Gson; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.Locale; -import java.util.Scanner; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; - -public class Deployment { - - private final Gson mGson; - - private final String username; - private final String password; - - public Deployment(String username, String password) { - this.username = username; - this.password = password; - mGson = GsonCreator.create(); - } - - public Response requestDeployment(Request request) throws Exception { - final String requestJson = mGson.toJson(request); - System.out.println("Request: " + requestJson); - - try (CloseableHttpClient client = HttpClientCreator.create(username, password)) { - HttpPost httpPost = - new HttpPost( - "https://api.github.com/repos/AnySoftKeyboard/AnySoftKeyboard/deployments"); - httpPost.setEntity(new StringEntity(requestJson, StandardCharsets.UTF_8)); - try (CloseableHttpResponse httpResponse = - client.execute(httpPost, HttpClientCreator.createContext(username, password))) { - System.out.println("Response status: " + httpResponse.getStatusLine()); - final Scanner scanner = - new Scanner(httpResponse.getEntity().getContent(), StandardCharsets.UTF_8) - .useDelimiter("\\A"); - final String responseString = scanner.hasNext() ? scanner.next() : ""; - System.out.println("Response content: " + responseString); - if (httpResponse.getStatusLine().getStatusCode() > 299 - || httpResponse.getStatusLine().getStatusCode() < 200) { - throw new IOException( - String.format( - Locale.ROOT, - "Got non-OK response status '%s' with content: %s", - httpResponse.getStatusLine(), - responseString)); - } - return mGson.fromJson(responseString, Response.class); - } - } - } - - public static class Request { - public final String ref; - public final String task; - public final boolean auto_merge; - public final String environment; - public final String description; - public final List<String> required_contexts; - public final RequestPayloadField payload; - - public Request( - String ref, - String task, - boolean auto_merge, - String environment, - String description, - List<String> required_contexts, - RequestPayloadField payload) { - this.ref = ref; - this.task = task; - this.auto_merge = auto_merge; - this.environment = environment; - this.description = description; - this.required_contexts = required_contexts; - this.payload = payload; - } - } - - public static class RequestPayloadField { - public final List<String> environments_to_kill; - - public RequestPayloadField(List<String> environmentsToKill) { - environments_to_kill = environmentsToKill; - } - } - - public static class Response { - public final String id; - public final String sha; - public final String ref; - public final String task; - public final RequestPayloadField payload; - public final String environment; - - public Response( - String id, - String sha, - String ref, - String task, - RequestPayloadField payload, - String environment) { - this.id = id; - this.sha = sha; - this.ref = ref; - this.task = task; - this.payload = payload; - this.environment = environment; - } - } -} diff --git a/buildSrc/src/main/java/github/DeploymentCreate.java b/buildSrc/src/main/java/github/DeploymentCreate.java new file mode 100644 index 000000000..f7be57955 --- /dev/null +++ b/buildSrc/src/main/java/github/DeploymentCreate.java @@ -0,0 +1,83 @@ +package github; + +import java.nio.charset.StandardCharsets; +import java.util.List; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.entity.StringEntity; + +public class DeploymentCreate + extends RestRequestPerformer<DeploymentCreate.Request, DeploymentCreate.Response> { + + public DeploymentCreate(String username, String password) { + super(username, password, DeploymentCreate.Response.class); + } + + @Override + protected HttpUriRequest createHttpRequest(Request request, String requestJsonAsString) { + final HttpPost httpPost = + new HttpPost( + "https://api.github.com/repos/AnySoftKeyboard/AnySoftKeyboard/deployments"); + httpPost.setEntity(new StringEntity(requestJsonAsString, StandardCharsets.UTF_8)); + return httpPost; + } + + public static class Request { + public final String ref; + public final String task; + public final boolean auto_merge; + public final String environment; + public final String description; + public final List<String> required_contexts; + public final RequestPayloadField payload; + + public Request( + String ref, + String task, + boolean auto_merge, + String environment, + String description, + List<String> required_contexts, + RequestPayloadField payload) { + this.ref = ref; + this.task = task; + this.auto_merge = auto_merge; + this.environment = environment; + this.description = description; + this.required_contexts = required_contexts; + this.payload = payload; + } + } + + public static class RequestPayloadField { + public final List<String> environments_to_kill; + + public RequestPayloadField(List<String> environmentsToKill) { + environments_to_kill = environmentsToKill; + } + } + + public static class Response { + public final String id; + public final String sha; + public final String ref; + public final String task; + public final RequestPayloadField payload; + public final String environment; + + public Response( + String id, + String sha, + String ref, + String task, + RequestPayloadField payload, + String environment) { + this.id = id; + this.sha = sha; + this.ref = ref; + this.task = task; + this.payload = payload; + this.environment = environment; + } + } +} diff --git a/buildSrc/src/main/java/github/DeploymentStatus.java b/buildSrc/src/main/java/github/DeploymentStatus.java index 2548d6864..a0c7e21a0 100644 --- a/buildSrc/src/main/java/github/DeploymentStatus.java +++ b/buildSrc/src/main/java/github/DeploymentStatus.java @@ -1,69 +1,38 @@ package github; -import com.google.gson.Gson; -import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.util.Locale; -import java.util.Scanner; -import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -public class DeploymentStatus { - - private final Gson mGson; - - private final String username; - private final String password; +public class DeploymentStatus + extends RestRequestPerformer<DeploymentStatus.Request, DeploymentStatus.Response> { public DeploymentStatus(String username, String password) { - this.username = username; - this.password = password; - mGson = GsonCreator.create(); + super(username, password, Response.class); } - public Response requestDeploymentStatus(String deploymentId, Request request) throws Exception { - final String requestJson = mGson.toJson(request); - System.out.println("Request: " + requestJson); - - try (CloseableHttpClient client = HttpClientCreator.create(username, password)) { - HttpPost httpPost = - new HttpPost( - "https://api.github.com/repos/AnySoftKeyboard/AnySoftKeyboard/deployments/" - + deploymentId - + "/statuses"); - httpPost.setEntity(new StringEntity(requestJson, StandardCharsets.UTF_8)); - httpPost.addHeader("Accept", "application/vnd.github.flash-preview+json"); - httpPost.addHeader("Accept", "application/vnd.github.ant-man-preview+json"); - try (CloseableHttpResponse httpResponse = - client.execute(httpPost, HttpClientCreator.createContext(username, password))) { - System.out.println("Response status: " + httpResponse.getStatusLine()); - final Scanner scanner = - new Scanner(httpResponse.getEntity().getContent(), StandardCharsets.UTF_8) - .useDelimiter("\\A"); - final String responseString = scanner.hasNext() ? scanner.next() : ""; - System.out.println("Response content: " + responseString); - if (httpResponse.getStatusLine().getStatusCode() > 299 - || httpResponse.getStatusLine().getStatusCode() < 200) { - throw new IOException( - String.format( - Locale.ROOT, - "Got non-OK response status '%s' with content: %s", - httpResponse.getStatusLine(), - responseString)); - } - return mGson.fromJson(responseString, Response.class); - } - } + @Override + protected HttpUriRequest createHttpRequest(Request request, String requestJsonAsString) { + final HttpPost httpPost = + new HttpPost( + "https://api.github.com/repos/AnySoftKeyboard/AnySoftKeyboard/deployments/" + + request.id + + "/statuses"); + httpPost.setEntity(new StringEntity(requestJsonAsString, StandardCharsets.UTF_8)); + httpPost.addHeader("Accept", "application/vnd.github.flash-preview+json"); + httpPost.addHeader("Accept", "application/vnd.github.ant-man-preview+json"); + return httpPost; } public static class Request { + public final String id; public final String environment; public final String state; public final boolean auto_inactive; - public Request(String environment, String state) { + public Request(String id, String environment, String state) { + this.id = id; this.environment = environment; this.state = state; this.auto_inactive = "success".equals(state); diff --git a/buildSrc/src/main/java/github/DeploymentsList.java b/buildSrc/src/main/java/github/DeploymentsList.java new file mode 100644 index 000000000..f581488bb --- /dev/null +++ b/buildSrc/src/main/java/github/DeploymentsList.java @@ -0,0 +1,37 @@ +package github; + +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; + +public class DeploymentsList + extends RestRequestPerformer<DeploymentsList.Request, DeploymentsList.Response[]> { + + public DeploymentsList(String username, String password) { + super(username, password, Response[].class); + } + + @Override + protected HttpUriRequest createHttpRequest(Request request, String requestJsonAsString) { + return new HttpGet( + "https://api.github.com/repos/AnySoftKeyboard/AnySoftKeyboard/deployments?sha=" + + request.sha); + } + + public static class Request { + public final String sha; + + public Request(String sha) { + this.sha = sha; + } + } + + public static class Response { + public final String id; + public final String environment; + + public Response(String id, String environment) { + this.id = id; + this.environment = environment; + } + } +} diff --git a/buildSrc/src/main/java/github/HttpClientCreator.java b/buildSrc/src/main/java/github/HttpClientCreator.java index e2795364b..9f70c6897 100644 --- a/buildSrc/src/main/java/github/HttpClientCreator.java +++ b/buildSrc/src/main/java/github/HttpClientCreator.java @@ -23,7 +23,7 @@ class HttpClientCreator { .build(); } - public static HttpClientContext createContext(String username, String password) { + static HttpClientContext createContext(String username, String password) { BasicCredentialsProvider creds = new BasicCredentialsProvider(); creds.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password)); diff --git a/buildSrc/src/main/java/github/RestRequestPerformer.java b/buildSrc/src/main/java/github/RestRequestPerformer.java new file mode 100644 index 000000000..9aebf98f1 --- /dev/null +++ b/buildSrc/src/main/java/github/RestRequestPerformer.java @@ -0,0 +1,56 @@ +package github; + +import com.google.gson.Gson; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Locale; +import java.util.Scanner; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.CloseableHttpClient; + +public abstract class RestRequestPerformer<R, A> { + private final Gson mGson; + + private final String username; + private final String password; + private final Class<A> responseClass; + + public RestRequestPerformer(String username, String password, Class<A> responseClass) { + this.username = username; + this.password = password; + this.responseClass = responseClass; + mGson = GsonCreator.create(); + } + + public A request(R request) throws IOException { + final String requestAsJsonString = mGson.toJson(request); + System.out.println("Request: " + requestAsJsonString); + + try (CloseableHttpClient client = HttpClientCreator.create(username, password)) { + HttpUriRequest httpRequest = createHttpRequest(request, requestAsJsonString); + try (CloseableHttpResponse httpResponse = + client.execute( + httpRequest, HttpClientCreator.createContext(username, password))) { + System.out.println("Response status: " + httpResponse.getStatusLine()); + final Scanner scanner = + new Scanner(httpResponse.getEntity().getContent(), StandardCharsets.UTF_8) + .useDelimiter("\\A"); + final String responseString = scanner.hasNext() ? scanner.next() : ""; + System.out.println("Response content: " + responseString); + if (httpResponse.getStatusLine().getStatusCode() > 299 + || httpResponse.getStatusLine().getStatusCode() < 200) { + throw new IOException( + String.format( + Locale.ROOT, + "Got non-OK response status '%s' with content: %s", + httpResponse.getStatusLine(), + responseString)); + } + return mGson.fromJson(responseString, responseClass); + } + } + } + + protected abstract HttpUriRequest createHttpRequest(R request, String requestJsonAsString); +} |
