package link import ( "encoding/json" ) // Asking a machine to build a module, and hearing what came out. // // **A build is work, not state.** Everything else the control plane sends a node is a declaration // — *this is what you should be* — and the node reconciles toward it forever. A build happens // once, produces something, and is finished. Putting it in a declaration would mean a machine // rebuilding on every reconcile, or the declaration carrying "and I already did this", which is // state about an event rather than about the machine. // // So it travels on its own queue, and the reply comes back correlated. That is also why the // builder is a **separate consumer** rather than the host: the host applies declarations and // holds no opinion about what they contain, and a host that also built things would be a host // with a container runtime requirement and a git dependency (novox/hq ADR 0005). // BuildRequest is one module to build. type BuildRequest struct { // ID correlates the answer with the asking. Not the module name: two builds of one module can // be in flight, and the second answer is not the first one's. ID string `json:"id"` // Repository is where the source is, as git would clone it. Repository string `json:"repository"` // Ref is the branch, tag or commit. Empty means whatever the repository's default is, which // is the only case where the mesh does not know what it built until it has built it. Ref string `json:"ref,omitempty"` // Path is the module's directory inside that repository (novox/hq ADR 0069). Empty means the // repository root, which is the ordinary case; a repository holding several modules names // each by its own directory. Path string `json:"path,omitempty"` // Held is every artifact this mesh has built, keyed "/". // // **Sent with the asking rather than fetched by the builder** (novox/hq issue 044). A module // says which module's artifact its build stands on; only the mesh knows which copy of that // artifact *this* mesh holds, and the builder is deliberately a thing that clones, runs a // build and answers — giving it a way to ask the mesh questions would make it something else. // So the answer travels with the question. // // It is everything rather than only what this module needs, because what this module needs is // written in a manifest the mesh has not read: it is inside the repository, and reading it is // the build's first act. Held map[string]string `json:"held,omitempty"` } // BuildResult is what a builder says back. // // **Failure is a result, not an absence.** A build that fails and says nothing is // indistinguishable from a builder that is not running, and those want completely different // responses — the same rule the host follows about a service that does not exist. type BuildResult struct { ID string `json:"id"` Repository string `json:"repository"` // Path is echoed back, so what the mesh records as this module's source is what was actually // built rather than what the asker meant (novox/hq ADR 0069). Path string `json:"path,omitempty"` Ref string `json:"ref,omitempty"` // On is the machine that did it, so a failure that is about one machine can be told from one // about the source. On string `json:"on"` // Module is what was built, read out of the manifest — the only place it is authoritative, since // a request names a repository and a path. // // **Here because one message now reaches three audiences** (novox/hq ADR 0121). On the bus the // mesh runs on today the answer and the announcement were two publishes to two topologies, so a // result needed no module name and the announcement carried one. On the bus being built the // outcome is the role's own event, and the catalogue reading it needs to know what was built. // Empty on a failed build, which produced no module version. Module string `json:"module,omitempty"` // Commit is what was actually built. The mesh records it, which is what makes "is this // current?" answerable without building again. Commit string `json:"commit,omitempty"` // Manifest is the module as the mesh should hold it, artifacts resolved to digests. Raw, // because the control plane parses it with the same parser it uses for one handed over by // hand — a second path would be a second thing to disagree. Manifest json.RawMessage `json:"manifest,omitempty"` // Made is each artifact, for reporting. Made []MadeArtifact `json:"made,omitempty"` // Against is every pinned image this was built on top of, read out of the build's own inputs // (novox/hq ADR 0009). The catalogue turns these into edges; nothing else need care. Against []string `json:"against,omitempty"` // Failed is why, when it did. Failed string `json:"failed,omitempty"` } // MadeArtifact is one thing a build produced, as a person would want it reported. type MadeArtifact struct { Name string `json:"name"` Kind string `json:"kind"` Reference string `json:"reference"` }