Say which modules wait for a person's push, and announce the files a merge deleted (hq ADR 0236)
With a gate on the first machine and a rollback after it, a module's build rolls out by default. The ones kept back say why: the network path a rollback could not cross, the providers every consumer on a machine drops with, and the stores holding the photos. A merge's deleted files are announced, so a module whose manifest went is forgotten rather than asked to build (the public-acme plan failure).
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"module": "dnsmasq",
|
||||
"version": "1",
|
||||
"upgrade": {
|
||||
"policy": "record",
|
||||
"why": "the mesh's resolver: a build that breaks it can stop a machine resolving the bus, and then neither the gate's rollback nor a push reaches it (hq ADR 0236, issue 260)"
|
||||
},
|
||||
"provides": [
|
||||
{
|
||||
"name": "wildcard-resolution",
|
||||
|
||||
+11
-4
@@ -256,18 +256,25 @@ export class GiteaClient {
|
||||
* whose own files moved was not rebuilt (novox/hq issue 252). Read until a page comes back short; past
|
||||
* `most` files the list is cut and says so, and the mesh then rebuilds everything built from the
|
||||
* repository, the safe direction. */
|
||||
async listPullFiles(owner: string, repo: string, index: number, most = 3000): Promise<{ paths: string[]; truncated: boolean }> {
|
||||
/** Every file a pull request changes, and which of them it deleted: a module whose manifest the merge
|
||||
* deleted is gone from its source, and the mesh forgets it rather than asking its build (novox/hq ADR
|
||||
* 0236). The forge says `deleted`; `removed` is read the same. */
|
||||
async listPullFiles(owner: string, repo: string, index: number, most = 3000): Promise<{ paths: string[]; removed: string[]; truncated: boolean }> {
|
||||
const paths: string[] = [];
|
||||
const removed: string[] = [];
|
||||
let pageSize = 0;
|
||||
for (let page = 1; ; page++) {
|
||||
const files = (await this.request<any[]>(`/repos/${owner}/${repo}/pulls/${index}/files?limit=50&page=${page}`)) ?? [];
|
||||
if (page === 1) pageSize = files.length;
|
||||
for (const f of files) {
|
||||
const name = String(f?.filename ?? "");
|
||||
if (name !== "") paths.push(name);
|
||||
if (name === "") continue;
|
||||
paths.push(name);
|
||||
const status = String(f?.status ?? "");
|
||||
if (status === "deleted" || status === "removed") removed.push(name);
|
||||
}
|
||||
if (files.length === 0 || files.length < pageSize) return { paths, truncated: false };
|
||||
if (paths.length >= most) return { paths, truncated: true };
|
||||
if (files.length === 0 || files.length < pageSize) return { paths, removed, truncated: false };
|
||||
if (paths.length >= most) return { paths, removed, truncated: true };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +120,9 @@ async function pollMerged(client: GiteaClient): Promise<void> {
|
||||
html_url: pull.html_url,
|
||||
paths: changed.paths,
|
||||
paths_truncated: changed.truncated,
|
||||
// Which of them the merge deleted (novox/hq ADR 0236): a module whose manifest went is forgotten,
|
||||
// not built.
|
||||
removed: changed.removed,
|
||||
});
|
||||
// Said, because a trigger that fires silently is indistinguishable from one that did not
|
||||
// fire (novox/hq 04-ISSUES/131) — this line is how an operator knows the mesh was told.
|
||||
|
||||
@@ -9,7 +9,8 @@ test("every page of a pull request's files is read, though the forge caps a page
|
||||
const url = new URL(req.url ?? "", "http://x");
|
||||
const page = Number(url.searchParams.get("page") ?? "1");
|
||||
const start = (page - 1) * 50;
|
||||
const files = Array.from({ length: Math.max(0, Math.min(50, total - start)) }, (_, i) => ({ filename: `modules/m${start + i}/x` }));
|
||||
const files = Array.from({ length: Math.max(0, Math.min(50, total - start)) }, (_, i) => ({
|
||||
filename: `modules/m${start + i}/x`, status: start + i === 3 ? "deleted" : "changed" }));
|
||||
res.setHeader("content-type", "application/json");
|
||||
res.end(JSON.stringify(files));
|
||||
});
|
||||
@@ -21,6 +22,7 @@ test("every page of a pull request's files is read, though the forge caps a page
|
||||
assert.equal(got.paths.length, total);
|
||||
assert.equal(got.truncated, false);
|
||||
assert.equal(new Set(got.paths).size, total);
|
||||
assert.deepEqual(got.removed, ["modules/m3/x"], "a file the merge deleted is said as deleted");
|
||||
});
|
||||
|
||||
test("a pass asks only the repositories that moved since the last look, every one before the first", async () => {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"module": "keycloak",
|
||||
"version": "1",
|
||||
"upgrade": {
|
||||
"policy": "record",
|
||||
"why": "every person's sign-in to every site goes through it, and its new version migrates its database on start: a person takes each build, after a backup (hq ADR 0236)"
|
||||
},
|
||||
"provides": [
|
||||
{
|
||||
"name": "oidc-client",
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"module": "minio",
|
||||
"version": "1",
|
||||
"upgrade": {
|
||||
"policy": "record",
|
||||
"why": "holds the photos themselves (irreplaceable, kept by photos) for its consumers: a person takes each build, after a backup (hq ADR 0236)"
|
||||
},
|
||||
"provides": [
|
||||
{
|
||||
"name": "s3-bucket",
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"module": "mongodb",
|
||||
"version": "1",
|
||||
"upgrade": {
|
||||
"policy": "record",
|
||||
"why": "a provider whose restart drops every consumer on its machine, and which holds the photos' albums (irreplaceable, kept by photos): a person takes each build, after a backup (hq ADR 0236)"
|
||||
},
|
||||
"provides": [
|
||||
{
|
||||
"name": "mongodb-database",
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"module": "mssql",
|
||||
"version": "1",
|
||||
"upgrade": {
|
||||
"policy": "record",
|
||||
"why": "a provider whose restart drops every consumer on its machine, and whose new version may upgrade its databases in place: a person takes each build, after a backup (hq ADR 0236)"
|
||||
},
|
||||
"provides": [
|
||||
{
|
||||
"name": "mssql-database",
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"module": "nats",
|
||||
"version": "1",
|
||||
"upgrade": {
|
||||
"policy": "record",
|
||||
"why": "the bus: replaced only as a planned step a person starts (`bus upgrade`), its streams snapshotted first and checked after (hq ADR 0236); the controller holds this whatever is said here"
|
||||
},
|
||||
"provides": [
|
||||
{
|
||||
"name": "mesh-bus",
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"module": "networkmanager",
|
||||
"version": "1",
|
||||
"upgrade": {
|
||||
"policy": "record",
|
||||
"why": "the machine's network: a build that breaks it can cut the machine off from the bus, and then neither the gate's rollback nor a push reaches it (hq ADR 0236)"
|
||||
},
|
||||
"slug": "nm",
|
||||
"requires": [
|
||||
"wildcard-resolution"
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"module": "nftables",
|
||||
"version": "1",
|
||||
"upgrade": {
|
||||
"policy": "record",
|
||||
"why": "the machine's packet filter: a build that breaks it can cut the machine off from the bus, and then neither the gate's rollback nor a push reaches it (hq ADR 0236)"
|
||||
},
|
||||
"capabilities": [
|
||||
"firewall"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"module": "postgres",
|
||||
"version": "1",
|
||||
"upgrade": {
|
||||
"policy": "record",
|
||||
"why": "a provider whose restart drops every consumer on its machine, and whose new major version changes its data's format: a person takes each build, after a backup (hq ADR 0236)"
|
||||
},
|
||||
"provides": [
|
||||
{
|
||||
"name": "postgres-database",
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"module": "sshd",
|
||||
"version": "1",
|
||||
"upgrade": {
|
||||
"policy": "record",
|
||||
"why": "the operator's way into the machine when the mesh cannot reach it: a build that breaks it is found only when that way is needed, which no gate sees (hq ADR 0236)"
|
||||
},
|
||||
"capabilities": [
|
||||
"package-manager",
|
||||
"service-manager"
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"module": "systemd-networkd",
|
||||
"version": "1",
|
||||
"upgrade": {
|
||||
"policy": "record",
|
||||
"why": "the machine's network: a build that breaks it can cut the machine off from the bus, and then neither the gate's rollback nor a push reaches it (hq ADR 0236)"
|
||||
},
|
||||
"slug": "networkd",
|
||||
"requires": [
|
||||
"wildcard-resolution"
|
||||
|
||||
Reference in New Issue
Block a user