Collin J. Doering
913c2f0e67
* .drone.yml: Update file after updates to .drone.jsonnet * .drone.jsonnet: Relocate guix_pipeline, guix_step, and deployStep to .drone/ci.libsonnet library. Adjust existing function names to match new names in library. Explicitly pass PLAN environment variable to ci.awsDeployStep for plan and apply stages
196 lines
5.3 KiB
Plaintext
196 lines
5.3 KiB
Plaintext
{
|
|
local ci = self,
|
|
local droneStatus = ['success', 'failure'],
|
|
|
|
pipeline:: {
|
|
new()::
|
|
self.withKind("pipeline"),
|
|
|
|
withName(name)::
|
|
self + { name: name },
|
|
|
|
withKind(kind)::
|
|
self + { kind: kind },
|
|
|
|
withType(type)::
|
|
self + { type: type },
|
|
|
|
withNode(node)::
|
|
self + { node: node },
|
|
|
|
withTrigger(trigger)::
|
|
self + { trigger: trigger },
|
|
|
|
withDependsOn(n)::
|
|
self + { depends_on: n },
|
|
|
|
withNodeSelector(ns)::
|
|
self + { node_selector: ns },
|
|
|
|
withSteps(steps)::
|
|
self + if std.type(steps) == 'array'
|
|
then { steps: steps }
|
|
else { steps: [steps] },
|
|
|
|
step:: {
|
|
new(name='', image='')::
|
|
self.withName(name).withImage(image).withPullIfNotExists(),
|
|
|
|
withName(name)::
|
|
self + { name: name },
|
|
|
|
withImage(image)::
|
|
self + if image != '' then { image: image } else {},
|
|
|
|
withAlwaysPull()::
|
|
self + { pull: 'always' },
|
|
|
|
withPullIfNotExists()::
|
|
self + { pull: 'if-not-exists' },
|
|
|
|
withCommands(commands)::
|
|
self + if std.type(commands) == 'array'
|
|
then { commands: commands }
|
|
else { commands: [commands] },
|
|
|
|
withTrigger(trigger)::
|
|
self + { trigger: trigger }, // TODO: this is duplicated in pipeline object
|
|
|
|
withEnv(envs)::
|
|
self + { environment+: envs },
|
|
|
|
withRuntimeEnvVar(envs)::
|
|
local existingCmds = if std.objectHas(self, "commands") then self.commands else [];
|
|
self + {
|
|
commands: std.map(function (i) std.format('export %s="%s"', [i, envs[i]]),
|
|
std.objectFields(envs)) + existingCmds
|
|
},
|
|
|
|
withWhen(when)::
|
|
self + { when: when },
|
|
|
|
withSettings(settings)::
|
|
self + { settings: settings },
|
|
},
|
|
|
|
when:: {
|
|
new()::
|
|
self + {},
|
|
|
|
withBranch(branch)::
|
|
self + if std.type(branch) == 'array'
|
|
then { branch: branch }
|
|
else { branch: [branch] },
|
|
|
|
withEvent(e)::
|
|
self + if std.type(e) == 'array'
|
|
then { event: e }
|
|
else { event: [e] },
|
|
|
|
withStatus(s)::
|
|
self + if std.type(s) == 'array'
|
|
then { status: s }
|
|
else { status: [s] },
|
|
|
|
withStatusAll()::
|
|
self.withStatus(droneStatus),
|
|
},
|
|
},
|
|
|
|
trigger:: {
|
|
new()::
|
|
self + {},
|
|
|
|
withBranch(branch)::
|
|
self + if std.type(branch) == 'array'
|
|
then { branch: branch }
|
|
else { branch: [branch] },
|
|
|
|
withEvent(e)::
|
|
self + if std.type(e) == 'array'
|
|
then { event: e }
|
|
else { event: [e] },
|
|
|
|
withStatus(s)::
|
|
self + if std.type(s) == 'array'
|
|
then { status: s }
|
|
else { status: [s] },
|
|
|
|
withStatusAll()::
|
|
self.withStatus(droneStatus),
|
|
},
|
|
|
|
env_from_secret(dict):: {
|
|
[key]: {
|
|
from_secret: dict[key],
|
|
}
|
|
for key in std.objectFields(dict)
|
|
},
|
|
|
|
guix:: {
|
|
pipeline(name)::
|
|
ci.pipeline.new()
|
|
.withName(name)
|
|
.withType("docker")
|
|
.withNode({ "guix": "on"}),
|
|
|
|
step(name, commands, image="docker.nexus.home.rekahsoft.ca/guix:latest")::
|
|
ci.pipeline.step.new(name, image).withPullIfNotExists().withCommands(commands),
|
|
|
|
stepTimeMachine(name, commands, cwd=".", channels="channels.scm", image="docker.nexus.home.rekahsoft.ca/guix:latest")::
|
|
ci.pipeline.step.new(name, image).withPullIfNotExists().withCommands(
|
|
// Conditionally change directory
|
|
(if cwd == "."
|
|
then [] else [std.format("cd %s", cwd)]) +
|
|
// Expand provide guix commands into executable shell
|
|
std.map(function(i) std.format("guix time-machine -C %s -- %s", [channels, i]),
|
|
if std.type(commands) == 'array' then commands else [commands])),
|
|
},
|
|
|
|
promoteStep(env,
|
|
secret_name_drone_token="drone_token",
|
|
image="docker.nexus.home.rekahsoft.ca/drone/cli:1.4-alpine")::
|
|
local dronePromoteCmd(env) = [
|
|
"export DRONE_SERVER=\"${DRONE_SYSTEM_PROTO}://${DRONE_SYSTEM_HOST}\"",
|
|
"export DRONE_TOKEN",
|
|
std.format('DRONE_PROMOTED_PIPELINE_ID=$(drone build promote --format \'{{ .Number }}\' "$DRONE_REPO" "$DRONE_BUILD_NUMBER" "%s")', env),
|
|
'while status="$(drone build info --format \'{{ .Status }}\' $DRONE_REPO $DRONE_PROMOTED_PIPELINE_ID)"; do
|
|
case "$status" in
|
|
pending|running)
|
|
sleep 30s
|
|
;;
|
|
success)
|
|
break
|
|
;;
|
|
failure|error|killed)
|
|
echo "Promoted job with id $DRONE_PROMOTED_PIPELINE_ID failed with status \'$status\'."
|
|
exit 1
|
|
;;
|
|
*)
|
|
echo "Unknown pipeline status \'$status\'."
|
|
exit 1
|
|
esac
|
|
done',
|
|
];
|
|
|
|
ci.pipeline.step.new(std.format("promote-%s", env), image)
|
|
.withWhen(ci.pipeline.when.new()
|
|
.withBranch("master")
|
|
.withEvent("push"))
|
|
.withCommands(dronePromoteCmd(env))
|
|
.withEnv(ci.env_from_secret({
|
|
DRONE_TOKEN: "drone_token"
|
|
})),
|
|
|
|
awsDeployStep(name, target=name, args=[])::
|
|
ci.guix.stepTimeMachine(
|
|
name,
|
|
std.format('shell -m manifest.scm -- make %s ENV="${DRONE_DEPLOY_TO}" %s', [target, std.join(" ", args)]),
|
|
cwd="infra",
|
|
channels="../channels.scm")
|
|
.withEnv(ci.env_from_secret({
|
|
AWS_ACCESS_KEY_ID: "aws_access_key_id",
|
|
AWS_SECRET_ACCESS_KEY: "aws_secret_access_key",
|
|
})),
|
|
}
|