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.
This commit is contained in:
@@ -24,6 +24,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
@@ -202,6 +203,7 @@ func answer(ctx context.Context, channel *amqp.Channel, publisher builder.Publis
|
||||
// not after a clone that then fails at npm ci.
|
||||
built, err = builder.Build(ctx, builder.Command, publisher,
|
||||
request.Repository, request.Path, request.Ref, workspace, request.Held, npmrc,
|
||||
forgeFrom(),
|
||||
func(step, message string) {
|
||||
fmt.Fprintf(os.Stderr, " [%s] %s\n", step, message)
|
||||
})
|
||||
@@ -367,6 +369,53 @@ func packagesFrom() (builder.Npmrc, error) {
|
||||
return builder.Npmrc{Scope: scope, Registry: registry, Token: secret}, nil
|
||||
}
|
||||
|
||||
// forgeFrom is the git credential this builder may offer a clone, composed from the same binding
|
||||
// and sealed secret its package-registry half already reads: the forge that answers npm is the
|
||||
// forge that hosts the repositories, and its provisioner applies one password to one user for
|
||||
// both. Anything missing means no credential, and every clone stays anonymous — which is all a
|
||||
// mesh of public repositories ever needs.
|
||||
//
|
||||
// The URL names the binding's own address — the machine the mesh says the forge is on — so a
|
||||
// private repository is registered and built by that address, and a clone of anything else is
|
||||
// never shown this credential (git's credential store matches the whole origin).
|
||||
func forgeFrom() builder.GitCredential {
|
||||
path := strings.TrimSpace(os.Getenv("MESH_PACKAGE_BINDING"))
|
||||
if path == "" {
|
||||
return builder.GitCredential{}
|
||||
}
|
||||
raw, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return builder.GitCredential{}
|
||||
}
|
||||
var told struct {
|
||||
At string `json:"at"`
|
||||
As string `json:"as"`
|
||||
Serves map[string]any `json:"serves"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &told); err != nil || told.At == "" || told.As == "" {
|
||||
return builder.GitCredential{}
|
||||
}
|
||||
secret := strings.TrimSpace(os.Getenv("MESH_NPM_TOKEN"))
|
||||
if file := strings.TrimSpace(os.Getenv("MESH_NPM_TOKEN_FILE")); file != "" {
|
||||
if raw, err := os.ReadFile(file); err == nil {
|
||||
secret = strings.TrimSpace(string(raw))
|
||||
}
|
||||
}
|
||||
if secret == "" {
|
||||
return builder.GitCredential{}
|
||||
}
|
||||
scheme := "https"
|
||||
if s, ok := told.Serves["scheme"]; ok {
|
||||
scheme = fmt.Sprintf("%v", s)
|
||||
}
|
||||
host := told.At
|
||||
if port, ok := told.Serves["port"]; ok {
|
||||
host = fmt.Sprintf("%s:%v", told.At, port)
|
||||
}
|
||||
made := url.URL{Scheme: scheme, User: url.UserPassword(told.As, secret), Host: host}
|
||||
return builder.GitCredential{URL: made.String()}
|
||||
}
|
||||
|
||||
func short(commit string) string {
|
||||
if len(commit) > 8 {
|
||||
return commit[:8]
|
||||
|
||||
@@ -89,6 +89,7 @@ func buildOnce(ctx context.Context, args []string) error {
|
||||
return err
|
||||
}
|
||||
built, buildErr := builder.Build(ctx, builder.Command, publisher, repository, *path, *ref, where, bases, npmrc,
|
||||
forgeFrom(),
|
||||
func(step, message string) { fmt.Fprintf(os.Stderr, " [%s] %s\n", step, message) })
|
||||
if buildErr != nil {
|
||||
return buildErr
|
||||
|
||||
Reference in New Issue
Block a user