A check's build of the ask's head writes the ask numbered in tag-asks by compare-and-set. An unanswered ask has a key in the new key-ttl state tag-ask-bounds (five minutes); the bus's marker of its end, heard on the watch, narrates the ask with what it waits on (the check's build not claimed, names waiting on their floor) and writes the bound again; no timer (design 51 *Tagged versions*). A restart arms each unanswered ask whose bound ended meanwhile. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
90 lines
3.7 KiB
Go
90 lines
3.7 KiB
Go
package build
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strconv"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/delivery"
|
|
|
|
"mesh-delivery-builder/internal/versions"
|
|
)
|
|
|
|
// Numbers numbers a trunk build at its claim (novox/hq design 51 *The versions*, ADR 0606, ADR 0617 §1) and records the
|
|
// digests it was built with. Nil numbers nothing.
|
|
type Numbers interface {
|
|
// tag is a check's build's tag (TagOf), empty for a trunk build.
|
|
Number(ctx context.Context, module string, m delivery.Module, plan Plan, tag string) (versions.Numbering, error)
|
|
Built(ctx context.Context, module string, m delivery.Module, plan Plan, got versions.Numbering, made []delivery.BuiltArtifact) error
|
|
}
|
|
|
|
// VersionNumbers is Numbers over the builder's state versions.
|
|
type VersionNumbers struct {
|
|
N *versions.Numberer
|
|
// TagNumbered is told the versions a check's build of a tag ask's head was numbered (the ask is then marked numbered
|
|
// in tag-asks, design 51 *Tagged versions*); nil tells nobody.
|
|
TagNumbered func(ctx context.Context, c versions.BuildClaim, got versions.Numbering)
|
|
}
|
|
|
|
// ClaimOf is the claim a module value's trunk build is numbered by: a package per source revision (Src), the rest per
|
|
// fingerprint, in merge order (Src).
|
|
func ClaimOf(module string, m delivery.Module, plan Plan) versions.BuildClaim {
|
|
c := versions.BuildClaim{Module: module, Path: m.Path, Repository: delivery.RepositoryName(m.Repository), Fingerprint: m.FP2,
|
|
Commit: m.Commit, Merge: m.Src}
|
|
if m.Src != 0 {
|
|
c.Revision = strconv.FormatUint(m.Src, 10)
|
|
}
|
|
for _, t := range plan.Tasks {
|
|
c.Artifacts = append(c.Artifacts, versions.ClaimArtifact{Artifact: t.Artifact, Kind: t.Kind, Language: t.Language})
|
|
}
|
|
return c
|
|
}
|
|
|
|
func (v VersionNumbers) Number(ctx context.Context, module string, m delivery.Module, plan Plan, tag string) (versions.Numbering, error) {
|
|
c := ClaimOf(module, m, plan)
|
|
if tag != "" {
|
|
// A check's build of a head a tag ask names: its packages tagged, below the next version (design 51 *Tagged versions*).
|
|
c.Tag, c.Head, c.Revision, c.Merge = tag, m.Commit, "", 0
|
|
}
|
|
got, err := v.N.Number(ctx, c)
|
|
if err == nil && tag != "" && len(got.Versions) > 0 && v.TagNumbered != nil {
|
|
v.TagNumbered(ctx, c, got)
|
|
}
|
|
return got, err
|
|
}
|
|
|
|
func (v VersionNumbers) Built(ctx context.Context, module string, m delivery.Module, plan Plan, got versions.Numbering, made []delivery.BuiltArtifact) error {
|
|
digests := map[string]string{}
|
|
for _, a := range made {
|
|
digests[a.Name] = a.Digest
|
|
}
|
|
return v.N.Built(ctx, ClaimOf(module, m, plan), got, digests)
|
|
}
|
|
|
|
// TagOf answers the cleaned tag a kept tag ask names for a repository's head (the builder's state tag-asks, design 51
|
|
// *Tagged versions*): a check's build of that head numbers its packages tagged at its claim.
|
|
type TagOf func(ctx context.Context, repository, head string) (tag string, ok bool)
|
|
|
|
// number numbers a build before its claim, a trunk build's artifacts or a check's build's packages under its tag: false
|
|
// when it waits for its floor (a package, design 51 *The floor*), and then nothing is claimed; the floor's wake looks at
|
|
// the module again.
|
|
func (b *Builder) number(ctx context.Context, module string, m delivery.Module, plan Plan, tag string) (versions.Numbering, bool) {
|
|
if b.Numbers == nil {
|
|
return versions.Numbering{}, true
|
|
}
|
|
got, err := b.Numbers.Number(ctx, module, m, plan, tag)
|
|
for _, s := range got.Said {
|
|
b.logf("%s at %s: %s", module, m.FP2, s)
|
|
}
|
|
if err != nil {
|
|
// Said, and built as before: an unnumbered build is published by its digest (ADR 0617 §1), numbered at its next look.
|
|
b.logf("%s at %s: %v", module, m.FP2, fmt.Errorf("not numbered, the versions cannot be used: %w", err))
|
|
return versions.Numbering{}, true
|
|
}
|
|
if got.Wait != "" {
|
|
b.logf("%s at %s is not built yet: %s", module, m.FP2, got.Wait)
|
|
return got, false
|
|
}
|
|
return got, true
|
|
}
|