diff --git a/build.gradle b/build.gradle
index 4b8d445..b5b032e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -43,7 +43,7 @@ publishing {
}
tasks.create('pipeline', UploadPipeline) {
- replace true
+ replace = true
commandStep {
label ':junit: Unit tests'
@@ -57,7 +57,7 @@ tasks.create('pipeline', UploadPipeline) {
commandStep {
label ':maven: Publish JARs'
- command './gradlew publish --continue ${GRADLE_SWITCHES}'
+ command './gradlew publish --continue $${GRADLE_SWITCHES}'
branch '*.*.*'
agentQueue 'builder'
dockerComposeContainer 'gradle'
diff --git a/buildSrc/src/main/groovy/com/widen/plugins/UploadPipeline.groovy b/buildSrc/src/main/groovy/com/widen/plugins/UploadPipeline.groovy
index f9f553a..ed4a4ed 100644
--- a/buildSrc/src/main/groovy/com/widen/plugins/UploadPipeline.groovy
+++ b/buildSrc/src/main/groovy/com/widen/plugins/UploadPipeline.groovy
@@ -6,35 +6,46 @@ import org.gradle.api.tasks.TaskAction
import java.nio.file.Files
+/**
+ * A Gradle task that allows you to define a Buildkite pipeline dynamically and then upload it during a build.
+ */
class UploadPipeline extends DefaultTask {
- private boolean interpolation = true
- private boolean replace = false
- private steps = []
-
- void replace(boolean replace) {
- this.replace = replace
- }
-
- String k8s(String environment, String region) {
- if (environment == 'stage' && region == 'us-east-1') {
- return '***REMOVED***'
- }
- return "***REMOVED***"
- }
-
+ private final List steps = []
+
+ /**
+ * Enable or disable variable interpolation on upload.
+ */
+ boolean interpolate = true
+
+ /**
+ * Replace the rest of the existing pipeline with the steps uploaded. Jobs that are already running are not removed.
+ */
+ boolean replace = false
+
+ /**
+ * Add a command step to the pipeline.
+ *
+ * @param closure
+ */
void commandStep(@DelegatesTo(CommandStep) Closure closure) {
def step = new CommandStep()
closure = closure.rehydrate(step, this, this)
closure.resolveStrategy = Closure.OWNER_FIRST
closure()
-
steps << step.model
}
+ /**
+ * Add a wait step to the pipeline.
+ */
void waitStep() {
steps << 'wait'
}
+ /**
+ * Add a wait step to the pipeline that continues on
+ * failure.
+ */
void waitStepContinueOnFailure() {
steps << [
wait: [
@@ -43,18 +54,40 @@ class UploadPipeline extends DefaultTask {
]
}
+ /**
+ * Helper method to return the correct Widen Kubernetes cluster endpoint for a given environment and region.
+ *
+ * @param environment
+ * @param region
+ * @return
+ */
+ String k8s(String environment, String region) {
+ if (environment == 'stage' && region == 'us-east-1') {
+ return '***REMOVED***'
+ }
+ return "***REMOVED***"
+ }
+
+ /**
+ * Get the JSON representation of the pipeline.
+ *
+ * @return A JSON string.
+ */
String toJson() {
return JsonOutput.toJson([
steps: steps
])
}
+ /**
+ * Upload the pipeline to Buildkite to be executed.
+ */
@TaskAction
void upload() {
if (System.env.BUILDKITE || System.env.CI) {
def cmd = ['buildkite-agent', 'pipeline', 'upload']
- if (!interpolation) {
+ if (!interpolate) {
cmd << '--no-interpolation'
}
@@ -75,26 +108,34 @@ class UploadPipeline extends DefaultTask {
}
}
- class Step {
- protected Map model = [:]
-
+ /**
+ * Base class for Buildkite step types.
+ */
+ abstract class Step {
+ protected final Map model = [:]
+
+ /**
+ * Sets the label that will be displayed in the pipeline visualisation in Buildkite.
+ *
+ * @param label
+ */
void label(String label) {
model.label = label
}
+ /**
+ * The branch pattern defining which branches will include this step in their builds.
+ *
+ * @param branch
+ */
void branch(String branch) {
model.branches = branch
}
-
- void agentQueue(String name) {
- model.get('agents', [:]).queue = name
- }
-
- void agentQueue(String name, String region) {
- agentQueue(region == 'us-east-1' ? name : "$name-$region")
- }
}
+ /**
+ * Configuration for a Buildkite command step.
+ */
class CommandStep extends Step {
void command(String command) {
model.command = command
@@ -108,6 +149,32 @@ class UploadPipeline extends DefaultTask {
model.get('artifact_paths', []) << path
}
+ void agentQueue(String name) {
+ model.get('agents', [:]).queue = name
+ }
+
+ void agentQueue(String name, String region) {
+ agentQueue(region == 'us-east-1' ? name : "$name-$region")
+ }
+
+ void environment(String name, String value) {
+ model.get('env', [:]).put(name, value)
+ }
+
+ void environment(Map variables) {
+ variables.each { name, value ->
+ environment(name, value)
+ }
+ }
+
+ void skip() {
+ model.skip = true
+ }
+
+ void skip(String reason) {
+ model.skip = reason
+ }
+
void plugin(String name, Object config) {
model.get('plugins', []) << [
(name): config