Files
mesh-controller/internal/builder/packages_test.go
jschoubben 6ac9013d6e builder: a clone may offer the forge's credential, through git's own store
A private repository could not be built: the builder clones anonymously,
and had no way to say who it is. It already holds exactly one credential
to exactly the right place — the package-registry binding and its sealed
secret, one gitea user whose password answers npm and git alike — so a
clone now offers that, and nothing new is minted or carried.

Offered, never pushed: the credential is written as a git
credential-store file (0600, in the workspace, never argv) and named
with -c credential.helper, so git itself decides when it applies — only
on an authentication challenge, and only for the URL it was written
for, scheme, host and port included. A public repository clones exactly
as before; a repository on any other host is never shown it. The same
store rides along on an artifact's own context clone, so a private
module with a private context builds too.
2026-09-25 21:47:32 +02:00

221 lines
8.6 KiB
Go

package builder
import (
"context"
"os"
"path/filepath"
"strings"
"testing"
)
func TestNpmrcRendersRegistryAndTokenForTheScope(t *testing.T) {
n := Npmrc{
Scope: "@novox",
Registry: "https://forge.invalid/api/packages/novox/npm/",
Token: "a-token",
}
got, err := n.File()
if err != nil {
t.Fatalf("a complete credential did not render: %v", err)
}
if !strings.Contains(got, "@novox:registry=https://forge.invalid/api/packages/novox/npm/") {
t.Fatalf("the scope's registry line is missing:\n%s", got)
}
// The auth line is keyed by the URL without its scheme, or npm never sends the token.
if !strings.Contains(got, "//forge.invalid/api/packages/novox/npm/:_authToken=a-token") {
t.Fatalf("the auth line does not match the registry key:\n%s", got)
}
}
func TestNpmrcAddsATrailingSlashSoTheAuthKeyMatches(t *testing.T) {
n := Npmrc{Scope: "@novox", Registry: "https://forge.invalid/api/packages/novox/npm", Token: "t"}
got, err := n.File()
if err != nil {
t.Fatal(err)
}
if !strings.Contains(got, "registry=https://forge.invalid/api/packages/novox/npm/\n") {
t.Fatalf("a missing trailing slash was not normalised:\n%s", got)
}
}
func TestNpmrcRefusesTheHalfConfigured(t *testing.T) {
cases := map[string]Npmrc{
"scope without @": {Scope: "novox", Registry: "https://x.invalid/", Token: "t"},
"registry not http": {Scope: "@novox", Registry: "ftp://x.invalid/", Token: "t"},
"no token": {Scope: "@novox", Registry: "https://x.invalid/", Token: ""},
}
for name, n := range cases {
if _, err := n.File(); err == nil {
t.Fatalf("%s rendered an .npmrc rather than refusing", name)
}
}
}
func TestNpmrcDisabledUntilThereIsARegistry(t *testing.T) {
if (Npmrc{}).Enabled() {
t.Fatal("an empty credential reported itself usable")
}
if (Npmrc{Scope: "@novox"}).Enabled() {
t.Fatal("a scope with no registry reported itself usable")
}
if !(Npmrc{Scope: "@novox", Registry: "https://x.invalid/"}).Enabled() {
t.Fatal("a scope and a registry did not count as usable")
}
}
// The credential reaches an image build as an .npmrc inside the build context — for a Dockerfile to
// COPY in a stage it does not publish — and the build runs on the host network so a RUN resolving the
// registry reaches it where the binding says (novox/hq ADR 0076). Not a buildkit secret, because this
// machine's docker may carry no buildx.
func TestAnImageBuildGetsTheCredentialInTheContextAndHostNetwork(t *testing.T) {
r, workspace := aRepository(t, withBoth, map[string]string{"Dockerfile": "FROM scratch\nCOPY .npmrc ./", "files/x": "y"})
n := Npmrc{Scope: "@novox", Registry: "https://forge.invalid/api/packages/novox/npm/", Token: "t"}
if _, err := Build(context.Background(), r.run, r,
"https://forge.invalid/meshboard.git", "", "", workspace, nil, n, GitCredential{}, nil); err != nil {
t.Fatalf("the build failed: %v", err)
}
var build string
for _, line := range r.ran {
if strings.HasPrefix(line, "docker build") {
build = line
}
}
if build == "" {
t.Fatal("no docker build ran")
}
if strings.Contains(build, "--secret") {
t.Fatalf("the build used a buildkit secret, which this path avoids: %s", build)
}
if !strings.Contains(build, "--network host") {
t.Fatalf("the build was not given the host network to reach the registry: %s", build)
}
// The .npmrc is written into the build context (the source tree), where a Dockerfile COPYs it.
tree := filepath.Join(workspace, "source")
npmrc := filepath.Join(tree, ".npmrc")
if _, err := os.Stat(npmrc); err != nil {
t.Fatalf("the credential was not written into the build context: %v", err)
}
}
func TestAnImageBuildWithoutACredentialGetsNoHostNetwork(t *testing.T) {
r, workspace := aRepository(t, withBoth, map[string]string{"Dockerfile": "FROM scratch", "files/x": "y"})
if _, err := Build(context.Background(), r.run, r,
"https://forge.invalid/meshboard.git", "", "", workspace, nil, Npmrc{}, GitCredential{}, nil); err != nil {
t.Fatalf("the build failed: %v", err)
}
for _, line := range r.ran {
if strings.HasPrefix(line, "docker build") && (strings.Contains(line, "--secret") || strings.Contains(line, "--network host")) {
t.Fatalf("a build with no credential was still given build-network or a secret: %s", line)
}
}
tree := filepath.Join(workspace, "source")
if _, err := os.Stat(filepath.Join(tree, ".npmrc")); err == nil {
t.Fatal("an .npmrc was written into a build that has no credential")
}
}
const aPackage = `{"module":"mesh-sdk","version":"1",
"build":{"artifacts":[{"name":"lib","kind":"package","language":"typescript"}]},
"resources":[]}`
// A package is compiled on a public base and published to the mesh's package registry by version,
// with nothing pushed to the artifact store and the credential mounted, not baked (novox/hq ADR 0076).
func TestAPackageIsBuiltOnAPublicBaseAndPublishedByVersion(t *testing.T) {
r, workspace := aRepository(t, aPackage, map[string]string{
"package.json": `{"name":"@novox/mesh-sdk","version":"0.1.0"}`,
})
n := Npmrc{Scope: "@novox", Registry: "https://forge.invalid/api/packages/novox/npm/", Token: "t"}
got, err := Build(context.Background(), r.run, r,
"https://forge.invalid/mesh-sdk.git", "", "", workspace, nil, n, GitCredential{}, nil)
if err != nil {
t.Fatalf("the package did not build: %v", err)
}
if len(got.Built) != 1 || got.Built[0].Reference != "@novox/mesh-sdk@0.1.0" {
t.Fatalf("a package is published by name and version, got %+v", got.Built)
}
if len(r.images) != 0 || len(r.archives) != 0 {
t.Fatal("a package was pushed to the artifact store, which is not where packages live")
}
var ran string
for _, line := range r.ran {
if strings.HasPrefix(line, "docker run") {
ran = line
}
}
if ran == "" {
t.Fatal("nothing ran to build the package")
}
if !strings.Contains(ran, "node:22-bookworm-slim") {
t.Fatalf("a package was not built on a public base: %s", ran)
}
if !strings.Contains(ran, ":/root/.npmrc:ro") {
t.Fatalf("the credential was not mounted read-only for the publish: %s", ran)
}
}
func TestAPackageWithNoRegistryIsRefused(t *testing.T) {
r, workspace := aRepository(t, aPackage, map[string]string{
"package.json": `{"name":"@novox/mesh-sdk","version":"0.1.0"}`,
})
_, err := Build(context.Background(), r.run, r,
"https://forge.invalid/mesh-sdk.git", "", "", workspace, nil, Npmrc{}, GitCredential{}, nil)
if err == nil {
t.Fatal("a package built with no registry to publish to, silently")
}
}
func TestNpmrcRendersBasicAuthWhenGivenAUserAndPassword(t *testing.T) {
n := Npmrc{
Scope: "@novox",
Registry: "http://forge.invalid:3000/api/packages/novox/npm/",
Username: "mesh_anchor_builder",
Password: "s3cret",
}
got, err := n.File()
if err != nil {
t.Fatalf("basic-auth credential did not render: %v", err)
}
key := "//forge.invalid:3000/api/packages/novox/npm/"
if !strings.Contains(got, key+":username=mesh_anchor_builder\n") {
t.Fatalf("username line missing:\n%s", got)
}
// npm reads the password base64-encoded.
if !strings.Contains(got, key+":_password=czNjcmV0\n") {
t.Fatalf("base64 password line missing or wrong:\n%s", got)
}
if !strings.Contains(got, key+":always-auth=true\n") {
t.Fatalf("always-auth missing, so reads would go unauthenticated:\n%s", got)
}
if strings.Contains(got, "_authToken") {
t.Fatalf("a token line was rendered for a basic-auth credential:\n%s", got)
}
}
func TestNpmrcRefusesWhenGivenNeitherTokenNorPassword(t *testing.T) {
n := Npmrc{Scope: "@novox", Registry: "http://x.invalid/npm/", Username: "u"}
if _, err := n.File(); err == nil {
t.Fatal("a username with no password rendered an .npmrc")
}
}
func TestAnImageThatDoesNotAskForTheCredentialDoesNotGetIt(t *testing.T) {
// A Dockerfile with no .npmrc reference (like the control plane's) must build clean: no .npmrc
// in its context, no host network — so its image stays deterministic and the credential does not
// leak into a build that never resolves a mesh package.
r, workspace := aRepository(t, withBoth, map[string]string{"Dockerfile": "FROM scratch\nCOPY . .", "files/x": "y"})
n := Npmrc{Scope: "@novox", Registry: "https://forge.invalid/api/packages/novox/npm/", Token: "t"}
if _, err := Build(context.Background(), r.run, r,
"https://forge.invalid/meshboard.git", "", "", workspace, nil, n, GitCredential{}, nil); err != nil {
t.Fatalf("the build failed: %v", err)
}
for _, line := range r.ran {
if strings.HasPrefix(line, "docker build") && strings.Contains(line, "--network host") {
t.Fatalf("a build that does not ask for the credential got the host network: %s", line)
}
}
if _, err := os.Stat(filepath.Join(workspace, "source", ".npmrc")); err == nil {
t.Fatal("an .npmrc was written into a build that does not reference it")
}
}