A definition names no installation: the check, an operator's value, a context on the git seat
InstallationProblems judges every value the mesh acts on for a name under a public top-level domain
or a public address, with prose, the world's registries, resolvers and certificate authorities
exempt, and a name a resource means on purpose declared with its reason (names-on-purpose). Run by
module check and a catalogue-wide test, not yet at registration, while the declared list shrinks.
${setting:<key>} fills a file from the assignment's settings and is refused when nothing set it.
A build context may live on the git seat; the request carries the seat's clone base (novox/hq ADR
0112, ADR 0155, issues 122 and 134).
This commit is contained in:
@@ -90,7 +90,13 @@ type GitCredential struct {
|
||||
// records — reachable, unreferenced, and indistinguishable from something in use.
|
||||
func Build(ctx context.Context, run Runner, publish Publisher,
|
||||
repository, path, ref, workspace string, held map[string]string, npmrc Npmrc,
|
||||
forge GitCredential, log Log) (Result, error) {
|
||||
forge GitCredential, log Log, seats ...map[string]string) (Result, error) {
|
||||
// The clone base of each seat a context may name (novox/hq ADR 0155); variadic so the callers
|
||||
// that hand none — tests of everything but contexts — read as they did.
|
||||
var seatBases map[string]string
|
||||
if len(seats) > 0 {
|
||||
seatBases = seats[0]
|
||||
}
|
||||
|
||||
say := logging(log)
|
||||
say("clone", "%s%s at %s", repository, describePath(path), refOrHead(ref))
|
||||
@@ -209,7 +215,7 @@ func Build(ctx context.Context, run Runner, publish Publisher,
|
||||
sort.Slice(artifacts, func(i, j int) bool { return artifacts[i].Name < artifacts[j].Name })
|
||||
for _, a := range artifacts {
|
||||
say("artifact", "%s (%s%s) — starting", a.Name, a.Kind, langSuffix(a))
|
||||
made, err := one(ctx, run, publish, manifest.Module, within, workspace, commit, credentials, a, args, held, npmrcPath, say)
|
||||
made, err := one(ctx, run, publish, manifest.Module, within, workspace, commit, credentials, a, args, held, npmrcPath, seatBases, say)
|
||||
if err != nil {
|
||||
say("artifact", "%s FAILED: %v", a.Name, err)
|
||||
return Result{}, err
|
||||
@@ -246,14 +252,18 @@ func logging(log Log) func(step, format string, args ...any) {
|
||||
// module's own repository — a fresh tree, the same way the module's own is, keyed by artifact
|
||||
// name so two artifacts of one module naming different contexts do not collide.
|
||||
func contextFrom(ctx context.Context, run Runner, workspace, artifact, credentials string,
|
||||
from catalogue.ArtifactContext, say func(step, format string, args ...any)) (string, error) {
|
||||
say("context", "cloning %s at %s for %s", from.Repository, refOrHead(from.Ref), artifact)
|
||||
from catalogue.ArtifactContext, seats map[string]string, say func(step, format string, args ...any)) (string, error) {
|
||||
url, err := contextURL(from, seats)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
say("context", "cloning %s at %s for %s", url, refOrHead(from.Ref), artifact)
|
||||
dir := filepath.Join(workspace, "context-"+artifact)
|
||||
if err := os.RemoveAll(dir); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if _, err := run(ctx, workspace, "git", cloneWith(credentials, "clone", "--quiet", from.Repository, dir)...); err != nil {
|
||||
return "", fmt.Errorf("cannot clone %s: %w", from.Repository, err)
|
||||
if _, err := run(ctx, workspace, "git", cloneWith(credentials, "clone", "--quiet", url, dir)...); err != nil {
|
||||
return "", fmt.Errorf("cannot clone %s: %w", url, err)
|
||||
}
|
||||
if from.Ref != "" {
|
||||
if _, err := run(ctx, dir, "git", "checkout", "--quiet", from.Ref); err != nil {
|
||||
@@ -264,6 +274,23 @@ func contextFrom(ctx context.Context, run Runner, workspace, artifact, credentia
|
||||
return dir, nil
|
||||
}
|
||||
|
||||
// contextURL is what a context is cloned from: its URL, or — for a context on a seat — the seat's
|
||||
// clone base the mesh sent with the request joined to the repository's path (novox/hq ADR 0155).
|
||||
// Refused, never guessed, when the mesh sent no base for that seat: a builder that guessed a forge
|
||||
// would be the literal this removes, one layer down.
|
||||
func contextURL(from catalogue.ArtifactContext, seats map[string]string) (string, error) {
|
||||
if from.Seat == "" {
|
||||
return from.Repository, nil
|
||||
}
|
||||
base, told := seats[from.Seat]
|
||||
if !told || base == "" {
|
||||
return "", fmt.Errorf("the context is %s on the %s seat, and this build was told no clone "+
|
||||
"base for that seat — nothing holds it in this mesh, or the control plane predates the word",
|
||||
from.Repository, from.Seat)
|
||||
}
|
||||
return strings.TrimRight(base, "/") + "/" + strings.TrimSuffix(strings.Trim(from.Repository, "/"), ".git") + ".git", nil
|
||||
}
|
||||
|
||||
// cloneWith is a git invocation that may offer a stored credential.
|
||||
//
|
||||
// The first `-c credential.helper=` clears every helper the environment might carry, so exactly
|
||||
@@ -416,7 +443,8 @@ func wantsPackages(manifest catalogue.Manifest, within string) bool {
|
||||
|
||||
func one(ctx context.Context, run Runner, publish Publisher,
|
||||
module, tree, workspace, commit, credentials string, a catalogue.Artifact, args []string,
|
||||
held map[string]string, npmrc string, say func(step, format string, args ...any)) (catalogue.Built, error) {
|
||||
held map[string]string, npmrc string, seats map[string]string,
|
||||
say func(step, format string, args ...any)) (catalogue.Built, error) {
|
||||
|
||||
switch a.Kind {
|
||||
case catalogue.ArtifactUpstream:
|
||||
@@ -493,7 +521,7 @@ func one(ctx context.Context, run Runner, publish Publisher,
|
||||
recipePath := a.From
|
||||
buildDir := tree
|
||||
if a.Context != nil {
|
||||
cloned, err := contextFrom(ctx, run, workspace, a.Name, credentials, *a.Context, say)
|
||||
cloned, err := contextFrom(ctx, run, workspace, a.Name, credentials, *a.Context, seats, say)
|
||||
if err != nil {
|
||||
return catalogue.Built{}, fmt.Errorf("%s: %s's context: %w", module, a.Name, err)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/novox/mesh-controller/internal/catalogue"
|
||||
)
|
||||
|
||||
// A context on a seat is cloned from the base the mesh sent, joined to the repository's path; a
|
||||
// context by URL is itself; a seat the mesh sent no base for is refused by name (novox/hq ADR 0155).
|
||||
func TestAContextOnASeatIsClonedFromTheBaseTheMeshSent(t *testing.T) {
|
||||
seats := map[string]string{"git": "http://forge.example.tld:3000"}
|
||||
got, err := contextURL(catalogue.ArtifactContext{Seat: "git", Repository: "org/controller"}, seats)
|
||||
if err != nil || got != "http://forge.example.tld:3000/org/controller.git" {
|
||||
t.Fatalf("got %q, %v", got, err)
|
||||
}
|
||||
got, err = contextURL(catalogue.ArtifactContext{Repository: "https://elsewhere.example/x.git"}, seats)
|
||||
if err != nil || got != "https://elsewhere.example/x.git" {
|
||||
t.Fatalf("a URL context was changed: %q, %v", got, err)
|
||||
}
|
||||
_, err = contextURL(catalogue.ArtifactContext{Seat: "git", Repository: "org/controller"}, nil)
|
||||
if err == nil || !strings.Contains(err.Error(), "git seat") {
|
||||
t.Fatalf("a seat with no base was not refused by name: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user