diff --git a/modules/mesh-build-go/cmd/mesh-build-go/archive.go b/modules/mesh-build-go/cmd/mesh-build-go/archive.go index f8e11b65..4807201e 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/archive.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/archive.go @@ -99,7 +99,12 @@ func (m *Module) pinnedArchive(ctx context.Context, workspace, module string, ar if err != nil { return nil, err } - if err := os.WriteFile(filepath.Join(laid, art.File), body, 0o644); err != nil { + kept := filepath.Join(laid, art.File) + if err := os.WriteFile(kept, body, 0o644); err != nil { + return nil, err + } + // The mode is the archive's, never the account's umask: the digest is the same on every build node. + if err := os.Chmod(kept, 0o644); err != nil { return nil, err } } else if err := unpackUpstream(file, laid, art.Within); err != nil { @@ -274,6 +279,10 @@ func untar(stream io.Reader, into, within string) error { if err != nil { return err } + if err := out.Chmod(mode); err != nil { + out.Close() + return err + } if _, err := io.Copy(out, io.LimitReader(reader, header.Size)); err != nil { out.Close() return err diff --git a/modules/mesh-build-go/cmd/mesh-build-go/archive_test.go b/modules/mesh-build-go/cmd/mesh-build-go/archive_test.go index 509668ed..90d75fe4 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/archive_test.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/archive_test.go @@ -43,7 +43,16 @@ func copyTree(t *testing.T, from, to string) { if err != nil { return err } - return os.WriteFile(target, body, info.Mode().Perm()) + // The modes a checkout gives depend on the umask of whoever checked it out; the fixture's are its executable bit + // alone, as git records it, so the digest does not depend on the machine the test runs on. + mode := os.FileMode(0o644) + if info.Mode().Perm()&0o100 != 0 { + mode = 0o755 + } + if err := os.WriteFile(target, body, mode); err != nil { + return err + } + return os.Chmod(target, mode) }) if err != nil { t.Fatal(err)