diff options
Diffstat (limited to 'buildSrc/src/main/java')
7 files changed, 307 insertions, 0 deletions
diff --git a/buildSrc/src/main/java/deployment/DeploymentCommandLineArgs.java b/buildSrc/src/main/java/deployment/DeploymentCommandLineArgs.java new file mode 100644 index 000000000..26418e8d0 --- /dev/null +++ b/buildSrc/src/main/java/deployment/DeploymentCommandLineArgs.java @@ -0,0 +1,13 @@ +package deployment; + +class DeploymentCommandLineArgs { + final String sha; + final String apiUsername; + final String apiUserToken; + + DeploymentCommandLineArgs(String sha, String apiUsername, String apiUserToken) { + this.sha = sha; + this.apiUsername = apiUsername; + this.apiUserToken = apiUserToken; + } +} diff --git a/buildSrc/src/main/java/deployment/DeploymentPlugin.java b/buildSrc/src/main/java/deployment/DeploymentPlugin.java new file mode 100644 index 000000000..954d24eae --- /dev/null +++ b/buildSrc/src/main/java/deployment/DeploymentPlugin.java @@ -0,0 +1,47 @@ +package deployment; + +import java.util.ArrayList; +import java.util.Locale; +import org.gradle.api.NamedDomainObjectContainer; +import org.gradle.api.Plugin; +import org.gradle.api.Project; + +public class DeploymentPlugin implements Plugin<Project> { + + @Override + public void apply(Project project) { + final NamedDomainObjectContainer<DeploymentProcessConfiguration> configs = + project.container(DeploymentProcessConfiguration.class); + configs.all( + config -> { + config.environmentSteps = new ArrayList<>(); + }); + project.getExtensions().add("deployments", configs); + + project.afterEvaluate(this::createDeployTasks); + } + + private void createDeployTasks(Project project) { + final NamedDomainObjectContainer<DeploymentProcessConfiguration> configs = + (NamedDomainObjectContainer<DeploymentProcessConfiguration>) + project.getExtensions().findByName("deployments"); + configs.all( + config -> { + for (int stepIndex = 0; + stepIndex < config.environmentSteps.size(); + stepIndex++) { + final String stepName = config.environmentSteps.get(stepIndex); + project.getTasks() + .register( + String.format( + Locale.ROOT, + "deploymentRequest_%s_%s", + config.name, + stepName), + DeploymentRequestProcessTask.class, + config, + stepIndex); + } + }); + } +} diff --git a/buildSrc/src/main/java/deployment/DeploymentProcessConfiguration.java b/buildSrc/src/main/java/deployment/DeploymentProcessConfiguration.java new file mode 100644 index 000000000..4663d4551 --- /dev/null +++ b/buildSrc/src/main/java/deployment/DeploymentProcessConfiguration.java @@ -0,0 +1,14 @@ +package deployment; + +import java.util.ArrayList; +import java.util.List; + +public class DeploymentProcessConfiguration { + public final String name; + + public List<String> environmentSteps = new ArrayList<>(); + + public DeploymentProcessConfiguration(String name) { + this.name = name; + } +} diff --git a/buildSrc/src/main/java/deployment/DeploymentRequestProcessTask.java b/buildSrc/src/main/java/deployment/DeploymentRequestProcessTask.java new file mode 100644 index 000000000..a9da0040b --- /dev/null +++ b/buildSrc/src/main/java/deployment/DeploymentRequestProcessTask.java @@ -0,0 +1,105 @@ +package deployment; + +import github.Deployment; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Map; +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 class DeploymentRequestProcessTask extends DefaultTask { + + private final DeploymentProcessConfiguration mConfiguration; + private final int mStepIndex; + + @Input + public String getEnvironmentKey() { + return getEnvironmentName(mConfiguration, mStepIndex); + } + + @Inject + public DeploymentRequestProcessTask( + DeploymentProcessConfiguration configuration, int stepIndex) { + mConfiguration = configuration; + mStepIndex = stepIndex; + setGroup("Publishing"); + setDescription("Request deployment of " + getEnvironmentName(configuration, stepIndex)); + } + + @TaskAction + public void deploymentRequestAction() { + try { + deploymentRequest(getProject().getProperties(), mConfiguration, mStepIndex); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static void deploymentRequest( + Map<String, ?> properties, DeploymentProcessConfiguration configuration, int stepIndex) + throws Exception { + final DeploymentCommandLineArgs data = + new DeploymentCommandLineArgs( + properties.get("requestDeploy.sha").toString(), + properties.get("requestDeploy.api_user_name").toString(), + properties.get("requestDeploy.api_user_token").toString()); + + Deployment deployment = new Deployment(data.apiUsername, data.apiUserToken); + if (stepIndex == 0) { + requestNewDeploy(deployment, data, configuration); + } else { + throw new UnsupportedOperationException( + "step " + stepIndex + " for " + configuration.name + " is not implemented!"); + } + } + + private static void requestNewDeploy( + Deployment deployment, + DeploymentCommandLineArgs data, + DeploymentProcessConfiguration environment) + throws Exception { + final String environmentToDeploy = getEnvironmentName(environment, 0); + final List<String> environmentsToKill = + environment.environmentSteps.stream() + .map(name -> getEnvironmentName(environment.name, name)) + .filter(env -> !env.equals(environmentToDeploy)) + .collect(Collectors.toList()); + + final Deployment.Response response = + deployment.requestDeployment( + new Deployment.Request( + data.sha, + "deploy", + false, + environmentToDeploy, + String.format( + Locale.ROOT, + "Deployment for '%s' request by '%s'.", + environmentToDeploy, + data.apiUsername), + Collections.singletonList("master-green-requirement"), + new Deployment.RequestPayloadField(environmentsToKill))); + + System.out.println( + String.format( + Locale.ROOT, + "Deploy request response: id %s, sha %s, environment %s, task %s.", + response.id, + response.sha, + response.environment, + response.task)); + } + + private static String getEnvironmentName(String environmentName, String stepName) { + return String.format(Locale.ROOT, "%s_%s", environmentName, stepName); + } + + private static String getEnvironmentName( + DeploymentProcessConfiguration environment, int index) { + return getEnvironmentName(environment.name, environment.environmentSteps.get(index)); + } +} diff --git a/buildSrc/src/main/java/github/Deployment.java b/buildSrc/src/main/java/github/Deployment.java new file mode 100644 index 000000000..985e6ed01 --- /dev/null +++ b/buildSrc/src/main/java/github/Deployment.java @@ -0,0 +1,103 @@ +package github; + +import com.google.gson.Gson; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.List; +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.setHeader("Accept", "application/json"); + httpPost.setHeader("Content-type", "application/json"); + httpPost.setEntity(new StringEntity(requestJson, StandardCharsets.UTF_8)); + try (CloseableHttpResponse httpResponse = client.execute(httpPost)) { + System.out.println("Response status: " + httpResponse.getStatusLine()); + return mGson.fromJson( + new InputStreamReader(httpResponse.getEntity().getContent()), + 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/GsonCreator.java b/buildSrc/src/main/java/github/GsonCreator.java new file mode 100644 index 000000000..c5b4077c9 --- /dev/null +++ b/buildSrc/src/main/java/github/GsonCreator.java @@ -0,0 +1,10 @@ +package github; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +class GsonCreator { + public static Gson create() { + return new GsonBuilder().create(); + } +} diff --git a/buildSrc/src/main/java/github/HttpClientCreator.java b/buildSrc/src/main/java/github/HttpClientCreator.java new file mode 100644 index 000000000..86a2b1a34 --- /dev/null +++ b/buildSrc/src/main/java/github/HttpClientCreator.java @@ -0,0 +1,15 @@ +package github; + +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; + +class HttpClientCreator { + public static CloseableHttpClient create(String username, String password) { + BasicCredentialsProvider creds = new BasicCredentialsProvider(); + creds.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password)); + return HttpClientBuilder.create().setDefaultCredentialsProvider(creds).build(); + } +} |
