From 7159dc23002121026a30148ee757081a16f182da Mon Sep 17 00:00:00 2001 From: Billy Lynch Date: Mon, 28 Aug 2023 16:28:13 -0400 Subject: [PATCH] Add support for SOURCE_DATE_EPOCH This is implemented in build only, since this behavior is already present in resolve via goBuildOptions: https://github.com/ko-build/ko/blob/ec46995eadb9d617942803731afb0687b5a18121/pkg/commands/resolver.go#L48-L51 --- internal/provider/resource_ko_build.go | 14 +++++++++++ internal/provider/resource_ko_build_test.go | 27 +++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/internal/provider/resource_ko_build.go b/internal/provider/resource_ko_build.go index 18d7875b..4d1a33f5 100644 --- a/internal/provider/resource_ko_build.go +++ b/internal/provider/resource_ko_build.go @@ -6,13 +6,17 @@ import ( "fmt" "io" "log" + "os" + "strconv" "sync" + "time" "github.com/awslabs/amazon-ecr-credential-helper/ecr-login" "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/authn/github" "github.com/google/go-containerregistry/pkg/name" + v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/google" "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/google/ko/pkg/build" @@ -178,6 +182,16 @@ func (o *buildOptions) makeBuilder(ctx context.Context) (*build.Caching, error) return nil, fmt.Errorf("unknown sbom type: %q", o.sbom) } + // We read the environment variable directly here instead of plumbing it through as a provider option to keep the behavior consistent with resolve. + // While CreationTime is a build.Option, it is not a field in options.BuildOptions and is inferred from the environment variable when a new resolver is created. + if epoch := os.Getenv("SOURCE_DATE_EPOCH"); epoch != "" { + s, err := strconv.ParseInt(epoch, 10, 64) + if err != nil { + return nil, fmt.Errorf("the environment variable %s should be the number of seconds since January 1st 1970, 00:00 UTC, got: %w", epoch, err) + } + bo = append(bo, build.WithCreationTime(v1.Time{Time: time.Unix(s, 0)})) + } + b, err := build.NewGo(ctx, o.workingDir, bo...) if err != nil { return nil, fmt.Errorf("NewGo: %w", err) diff --git a/internal/provider/resource_ko_build_test.go b/internal/provider/resource_ko_build_test.go index 8a92e0de..fff3505b 100644 --- a/internal/provider/resource_ko_build_test.go +++ b/internal/provider/resource_ko_build_test.go @@ -128,6 +128,33 @@ func TestAccResourceKoBuild(t *testing.T) { }}, }) } + + t.Run("SOURCE_DATE_EPOCH", func(t *testing.T) { + t.Setenv("SOURCE_DATE_EPOCH", "1234567890") + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories, + Steps: []resource.TestStep{{ + Config: `resource "ko_build" "foo" { + importpath = "github.com/ko-build/terraform-provider-ko/cmd/test" + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestMatchResourceAttr("ko_build.foo", "image_ref", imageRefRE), + ), + }}, + }) + }) + t.Run("SOURCE_DATE_EPOCH_failure", func(t *testing.T) { + t.Setenv("SOURCE_DATE_EPOCH", "abc123") + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories, + Steps: []resource.TestStep{{ + Config: `resource "ko_build" "foo" { + importpath = "github.com/ko-build/terraform-provider-ko/cmd/test" + }`, + ExpectError: regexp.MustCompile("should be the number of seconds since"), + }}, + }) + }) } func TestAccResourceKoBuild_ImageRepo(t *testing.T) {