A resolved manifest keeps a built reference in the store's own form, never the address it was reached by (hq ADR 0155) #230
@@ -84,8 +84,13 @@ func (m Manifest) Resolve(built []Built) (Manifest, error) {
|
|||||||
if a.Loads == nil && len(m.Tools) > 0 {
|
if a.Loads == nil && len(m.Tools) > 0 {
|
||||||
loads = append([]string(nil), a.Entrypoints...)
|
loads = append([]string(nil), a.Entrypoints...)
|
||||||
}
|
}
|
||||||
|
// **Kept, never routed** (ADR 0155): the builder publishes to the store at the address
|
||||||
|
// it reached it by, and a manifest carrying that address names an installation —
|
||||||
|
// registration refused node-tools for exactly this on 2026-10-02. The build record
|
||||||
|
// already keeps the store-relative form; the resolved manifest keeps the same, and
|
||||||
|
// composition routes it through the store a machine reaches (Routed).
|
||||||
out.Bundles = append(out.Bundles, Bundle{
|
out.Bundles = append(out.Bundles, Bundle{
|
||||||
Name: a.Name, Source: made.Reference, Digest: made.Digest,
|
Name: a.Name, Source: Recorded(made.Reference), Digest: made.Digest,
|
||||||
Language: a.Language, Entrypoints: append([]string(nil), a.Entrypoints...),
|
Language: a.Language, Entrypoints: append([]string(nil), a.Entrypoints...),
|
||||||
Loads: loads,
|
Loads: loads,
|
||||||
})
|
})
|
||||||
@@ -135,7 +140,8 @@ func (m Manifest) Resolve(built []Built) (Manifest, error) {
|
|||||||
// The same on the wire: both are bytes fetched by digest and unpacked. They differ in
|
// The same on the wire: both are bytes fetched by digest and unpacked. They differ in
|
||||||
// how they were made — one packed as it stood, the other compiled first — and a
|
// how they were made — one packed as it stood, the other compiled first — and a
|
||||||
// machine has no reason to care which.
|
// machine has no reason to care which.
|
||||||
filled["source"] = artifact.Reference
|
// Kept, not routed, for the reason the bundles above are (ADR 0155).
|
||||||
|
filled["source"] = Recorded(artifact.Reference)
|
||||||
filled["digest"] = artifact.Digest
|
filled["digest"] = artifact.Digest
|
||||||
// **And `${version}`, so a resource can name a place that is this build's alone**
|
// **And `${version}`, so a resource can name a place that is this build's alone**
|
||||||
// (novox/hq ADR 0141, 04-ISSUES/142). A component is unpacked into a directory named
|
// (novox/hq ADR 0141, 04-ISSUES/142). A component is unpacked into a directory named
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package catalogue
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A resolved manifest keeps a built artifact's reference in the store-relative form, never the
|
||||||
|
// address the builder reached the store by (novox/hq ADR 0155): on 2026-10-02 the first bundle
|
||||||
|
// resolved on the mesh carried the store's host in bundles[0].source and registration refused it
|
||||||
|
// as naming an installation. Archive resources are the same kind of reference and get the same.
|
||||||
|
func TestAResolvedReferenceIsKeptNotRouted(t *testing.T) {
|
||||||
|
m, err := ParseManifest([]byte(`{
|
||||||
|
"module": "sample", "version": "1",
|
||||||
|
"tools": ["one"],
|
||||||
|
"build": {"artifacts": [
|
||||||
|
{"name": "code", "kind": "bundle", "language": "typescript", "entrypoints": ["tools/index.js"]},
|
||||||
|
{"name": "files", "kind": "archive", "from": "files"}
|
||||||
|
]},
|
||||||
|
"resources": [{"id": "packed", "type": "archive", "path": "/opt/sample", "artifact": "files"}]
|
||||||
|
}`))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
digest := "sha256:" + strings.Repeat("ab", 32)
|
||||||
|
resolved, err := m.Resolve([]Built{
|
||||||
|
{Name: "code", Kind: ArtifactBundle, Reference: "http://store.example:5100/v2/sample/code/blobs/" + digest, Digest: digest},
|
||||||
|
{Name: "files", Kind: ArtifactArchive, Reference: "http://store.example:5100/v2/sample/files/blobs/" + digest, Digest: digest},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if got, want := resolved.Bundles[0].Source, ArtifactStoreScheme+"sample/code/blobs/"+digest; got != want {
|
||||||
|
t.Errorf("bundle source %q, want the kept form %q", got, want)
|
||||||
|
}
|
||||||
|
if got, want := resolved.Resources[0]["source"], ArtifactStoreScheme+"sample/files/blobs/"+digest; got != want {
|
||||||
|
t.Errorf("archive source %q, want the kept form %q", got, want)
|
||||||
|
}
|
||||||
|
if problems := InstallationProblems(resolved); len(problems) != 0 {
|
||||||
|
t.Errorf("a resolved manifest names an installation: %v", problems)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user