All checks were successful
Build, test and publish / verify (push) Successful in 6m34s
81 lines
3.4 KiB
Java
81 lines
3.4 KiB
Java
import java.util.LinkedHashMap;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
|
|
/** Successful deployment state is separate from immutable allocated version tags. */
|
|
record ReleaseState(ReleaseState.Deployment current, ReleaseState.Deployment previous, ReleaseVersion highest) {
|
|
record Deployment(
|
|
ReleaseVersion version, String sha, String backend, String frontend, String directory, String build) {
|
|
Deployment {
|
|
ReleaseApi.sha(sha);
|
|
Pipeline.check(directory.matches("[a-zA-Z0-9-]+"), "Invalid retained release directory");
|
|
for (String image : new String[] {backend, frontend})
|
|
Pipeline.check(image.matches("[a-zA-Z0-9.:/_-]+@sha256:[0-9a-f]{64}"), "Invalid retained image digest");
|
|
}
|
|
|
|
Map<String, Object> json() {
|
|
return Map.of(
|
|
"version",
|
|
version.toString(),
|
|
"sha",
|
|
sha,
|
|
"backend",
|
|
backend,
|
|
"frontend",
|
|
frontend,
|
|
"directory",
|
|
directory,
|
|
"build",
|
|
build);
|
|
}
|
|
|
|
static Deployment parse(Object value) {
|
|
if (value == null) return null;
|
|
var data = Json.object(value);
|
|
return new Deployment(
|
|
ReleaseVersion.parse(text(data, "version")),
|
|
text(data, "sha"),
|
|
text(data, "backend"),
|
|
text(data, "frontend"),
|
|
text(data, "directory"),
|
|
text(data, "build"));
|
|
}
|
|
}
|
|
|
|
static String text(Map<String, Object> data, String key) {
|
|
return Objects.toString(data.get(key), "");
|
|
}
|
|
|
|
static ReleaseState parse(String value) {
|
|
var data = Json.object(Json.parse(value));
|
|
if (data.isEmpty()) return new ReleaseState(null, null, null);
|
|
Pipeline.check("1".equals(text(data, "schema")), "Unsupported deployment state schema");
|
|
Deployment current = Deployment.parse(data.get("current"));
|
|
Deployment previous = Deployment.parse(data.get("previous"));
|
|
ReleaseVersion highest = ReleaseVersion.parse(text(data, "highest"));
|
|
Pipeline.check(
|
|
current != null
|
|
&& highest.compareTo(current.version()) >= 0
|
|
&& (previous == null || highest.compareTo(previous.version()) >= 0),
|
|
"Inconsistent successful release state");
|
|
return new ReleaseState(current, previous, highest);
|
|
}
|
|
|
|
String json() {
|
|
var data = new LinkedHashMap<String, Object>();
|
|
data.put("schema", "1");
|
|
data.put("current", current == null ? null : current.json());
|
|
data.put("previous", previous == null ? null : previous.json());
|
|
data.put("highest", highest == null ? null : highest.toString());
|
|
return Json.write(data) + "\n";
|
|
}
|
|
|
|
ReleaseState success(Deployment selected) {
|
|
ReleaseVersion watermark =
|
|
highest == null || selected.version().compareTo(highest) > 0 ? selected.version() : highest;
|
|
// A redeploy of the same release must not discard the distinct rollback target.
|
|
Deployment fallback = current != null && current.version().equals(selected.version()) ? previous : current;
|
|
return new ReleaseState(selected, fallback, watermark);
|
|
}
|
|
}
|