Implement manual versioned Synology deployments for S6
All checks were successful
Build, test and publish / verify (push) Successful in 6m34s
All checks were successful
Build, test and publish / verify (push) Successful in 6m34s
This commit is contained in:
80
ci/ReleaseState.java
Normal file
80
ci/ReleaseState.java
Normal file
@@ -0,0 +1,80 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user