From 4626cd7061025ce644ab6c7001ae35de009d76e6 Mon Sep 17 00:00:00 2001 From: Murad Iusufov Date: Thu, 11 Sep 2025 09:54:40 +0100 Subject: [PATCH 1/4] feat: provide git metadata env vars to buildpacks --- pkg/apis/build/v1alpha2/build_pod.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkg/apis/build/v1alpha2/build_pod.go b/pkg/apis/build/v1alpha2/build_pod.go index 870a6cfa6..a7b29ad27 100644 --- a/pkg/apis/build/v1alpha2/build_pod.go +++ b/pkg/apis/build/v1alpha2/build_pod.go @@ -191,6 +191,14 @@ func (b *Build) BuildPod(images BuildPodImages, buildContext BuildContext) (*cor dnsProbeHost := ref.Context().RegistryStr() buildEnv := b.Spec.Source.Source().BuildEnvVars() + var platformProjectMetadataGitEnv []corev1.EnvVar + if b.Spec.Source.Git != nil { + platformProjectMetadataGitEnv = []corev1.EnvVar{ + {Name: PlatformEnvVarPrefix + "PROJECT_METADATA_GIT_URL", Value: b.Spec.Source.Git.URL}, + {Name: PlatformEnvVarPrefix + "PROJECT_METADATA_GIT_REVISION", Value: b.Spec.Source.Git.Revision}, + } + } + buildEnv = append(buildEnv, platformProjectMetadataGitEnv...) for _, envVar := range b.Spec.Env { envVar.Name = PlatformEnvVarPrefix + envVar.Name buildEnv = append(buildEnv, envVar) From a5b6d3253d6cd78a42930c33b77eabbe9f3f802f Mon Sep 17 00:00:00 2001 From: Murad Iusufov Date: Thu, 11 Sep 2025 11:32:09 +0100 Subject: [PATCH 2/4] feat: set BP and BPE instead to be used with paketo buildpacks --- pkg/apis/build/v1alpha2/build_pod.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/apis/build/v1alpha2/build_pod.go b/pkg/apis/build/v1alpha2/build_pod.go index a7b29ad27..c8bbf7db2 100644 --- a/pkg/apis/build/v1alpha2/build_pod.go +++ b/pkg/apis/build/v1alpha2/build_pod.go @@ -191,14 +191,14 @@ func (b *Build) BuildPod(images BuildPodImages, buildContext BuildContext) (*cor dnsProbeHost := ref.Context().RegistryStr() buildEnv := b.Spec.Source.Source().BuildEnvVars() - var platformProjectMetadataGitEnv []corev1.EnvVar + var gitMetadataEnv []corev1.EnvVar if b.Spec.Source.Git != nil { - platformProjectMetadataGitEnv = []corev1.EnvVar{ - {Name: PlatformEnvVarPrefix + "PROJECT_METADATA_GIT_URL", Value: b.Spec.Source.Git.URL}, - {Name: PlatformEnvVarPrefix + "PROJECT_METADATA_GIT_REVISION", Value: b.Spec.Source.Git.Revision}, + gitMetadataEnv = []corev1.EnvVar{ + {Name: PlatformEnvVarPrefix + "BPE_GIT_REVISION", Value: b.Spec.Source.Git.Revision}, + {Name: PlatformEnvVarPrefix + "BP_OCI_REVISION", Value: b.Spec.Source.Git.Revision}, } } - buildEnv = append(buildEnv, platformProjectMetadataGitEnv...) + buildEnv = append(buildEnv, gitMetadataEnv...) for _, envVar := range b.Spec.Env { envVar.Name = PlatformEnvVarPrefix + envVar.Name buildEnv = append(buildEnv, envVar) From 1ed47c36ec47e27ce23a9b1a3d0e9f5e2a7ada62 Mon Sep 17 00:00:00 2001 From: Murad Iusufov Date: Fri, 19 Sep 2025 15:17:42 +0100 Subject: [PATCH 3/4] feat: additionally tag images with git sha --- pkg/apis/build/v1alpha2/image_builds.go | 48 +++++++++++++++++++- pkg/apis/build/v1alpha2/image_builds_test.go | 26 +++++++---- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/pkg/apis/build/v1alpha2/image_builds.go b/pkg/apis/build/v1alpha2/image_builds.go index d45a56ca4..f12158f3b 100644 --- a/pkg/apis/build/v1alpha2/image_builds.go +++ b/pkg/apis/build/v1alpha2/image_builds.go @@ -2,6 +2,7 @@ package v1alpha2 import ( "fmt" + "slices" "strconv" "time" @@ -37,6 +38,14 @@ type BuildReason string func (im *Image) Build(sourceResolver *SourceResolver, builder BuilderResource, latestBuild *Build, reasons, changes string, nextBuildNumber int64, priorityClass string) *Build { buildNumber := strconv.Itoa(int(nextBuildNumber)) + tags := im.generateTags(buildNumber) + + if resolvedGit := im.resolvedGitSource(sourceResolver); resolvedGit != nil { + if shaTag, err := im.gitRevisionTag(resolvedGit.Revision); err == nil && shaTag != "" { + tags = appendIfMissing(tags, shaTag) + } + } + return &Build{ ObjectMeta: metav1.ObjectMeta{ Namespace: im.Namespace, @@ -57,7 +66,7 @@ func (im *Image) Build(sourceResolver *SourceResolver, builder BuilderResource, }), }, Spec: BuildSpec{ - Tags: im.generateTags(buildNumber), + Tags: tags, Builder: builder.BuildBuilderSpec(), RunImage: BuildSpecImage{ Image: builder.RunImage(), @@ -277,6 +286,43 @@ func (im *Image) generateTags(buildNumber string) []string { ) } +func (im *Image) resolvedGitSource(sourceResolver *SourceResolver) *corev1alpha1.ResolvedGitSource { + if sourceResolver == nil { + return nil + } + + gitSource := sourceResolver.Status.Source.Git + if gitSource == nil { + return nil + } + + if gitSource.Type != corev1alpha1.Commit { + return nil + } + + return gitSource +} + +func (im *Image) gitRevisionTag(revision string) (string, error) { + if revision == "" { + return "", nil + } + + tag, err := name.NewTag(im.Spec.Tag, name.WeakValidation) + if err != nil { + return "", err + } + + return fmt.Sprintf("%s:%s", tag.Context().Name(), revision), nil +} + +func appendIfMissing(tags []string, candidate string) []string { + if slices.Contains(tags, candidate) { + return tags + } + return append(tags, candidate) +} + func (im *Image) generateBuildName(buildNumber string) string { return kmeta.ChildName(im.Name, "-build-"+buildNumber) } diff --git a/pkg/apis/build/v1alpha2/image_builds_test.go b/pkg/apis/build/v1alpha2/image_builds_test.go index caa934c08..af861fce4 100644 --- a/pkg/apis/build/v1alpha2/image_builds_test.go +++ b/pkg/apis/build/v1alpha2/image_builds_test.go @@ -18,6 +18,8 @@ func TestImageBuilds(t *testing.T) { } func testImageBuilds(t *testing.T, when spec.G, it spec.S) { + const gitRevision = "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b" + image := &Image{ ObjectMeta: metav1.ObjectMeta{ Name: "image-name", @@ -99,7 +101,7 @@ func testImageBuilds(t *testing.T, when spec.G, it spec.S) { sourceResolver.Status.Source = corev1alpha1.ResolvedSourceConfig{ Git: &corev1alpha1.ResolvedGitSource{ URL: "https://some.git/url", - Revision: "revision", + Revision: gitRevision, Type: corev1alpha1.Commit, }, } @@ -107,7 +109,7 @@ func testImageBuilds(t *testing.T, when spec.G, it spec.S) { latestBuild.Spec.Source = corev1alpha1.SourceConfig{ Git: &corev1alpha1.Git{ URL: "https://some.git/url", - Revision: "revision", + Revision: gitRevision, }, } @@ -147,11 +149,17 @@ func testImageBuilds(t *testing.T, when spec.G, it spec.S) { it("sets git url and git revision when image source is git", func() { build := image.Build(sourceResolver, builder, latestBuild, "", "", 27, "") assert.Contains(t, build.Spec.Source.Git.URL, "https://some.git/url") - assert.Contains(t, build.Spec.Source.Git.Revision, "revision") + assert.Equal(t, gitRevision, build.Spec.Source.Git.Revision) assert.Nil(t, build.Spec.Source.Blob) assert.Nil(t, build.Spec.Source.Registry) }) + it("appends the git sha tag when a git source is present", func() { + image.Spec.Tag = "gcr.io/imagename/foo:test" + build := image.Build(sourceResolver, builder, latestBuild, "", "", 12, "") + assert.Contains(t, build.Spec.Tags, "gcr.io/imagename/foo:"+gitRevision) + }) + it("sets blob url when image source is blob", func() { sourceResolver.Status.Source = corev1alpha1.ResolvedSourceConfig{ Blob: &corev1alpha1.ResolvedBlobSource{ @@ -180,7 +188,7 @@ func testImageBuilds(t *testing.T, when spec.G, it spec.S) { image.Spec.Tag = "imagename/foo:test" image.Spec.ImageTaggingStrategy = corev1alpha1.None build := image.Build(sourceResolver, builder, latestBuild, "", "", 1, "") - require.Len(t, build.Spec.Tags, 1) + require.Len(t, build.Spec.Tags, 2) }) it("with adds additional tags names", func() { @@ -188,7 +196,7 @@ func testImageBuilds(t *testing.T, when spec.G, it spec.S) { image.Spec.AdditionalTags = []string{"imagename/foo:test2", "anotherimage/foo:test3"} image.Spec.ImageTaggingStrategy = corev1alpha1.None build := image.Build(sourceResolver, builder, latestBuild, "", "", 1, "") - require.Len(t, build.Spec.Tags, 3) + require.Len(t, build.Spec.Tags, 4) }) it("generates a build with default process when set", func() { @@ -202,14 +210,14 @@ func testImageBuilds(t *testing.T, when spec.G, it spec.S) { it("with tag prefix if image name has a tag", func() { image.Spec.Tag = "gcr.io/imagename/foo:test" build := image.Build(sourceResolver, builder, latestBuild, "", "", 45, "") - require.Len(t, build.Spec.Tags, 2) + require.Len(t, build.Spec.Tags, 3) require.Regexp(t, "gcr.io/imagename/foo:test-b45\\.\\d{8}\\.\\d{6}", build.Spec.Tags[1]) }) it("without tag prefix if image name has no provided tag", func() { image.Spec.Tag = "gcr.io/imagename/notags" build := image.Build(sourceResolver, builder, latestBuild, "", "", 1, "") - require.Len(t, build.Spec.Tags, 2) + require.Len(t, build.Spec.Tags, 3) require.Regexp(t, "gcr.io/imagename/notags:b1\\.\\d{8}\\.\\d{6}", build.Spec.Tags[1]) }) @@ -217,14 +225,14 @@ func testImageBuilds(t *testing.T, when spec.G, it spec.S) { image.Spec.Tag = "gcr.io/imagename/tagged:latest" image.Spec.AdditionalTags = []string{"imagename/foo:test2", "anotherimage/foo:test3"} build := image.Build(sourceResolver, builder, latestBuild, "", "", 1, "") - require.Len(t, build.Spec.Tags, 4) + require.Len(t, build.Spec.Tags, 5) require.Regexp(t, "gcr.io/imagename/tagged:b1\\.\\d{8}\\.\\d{6}", build.Spec.Tags[1]) }) it("without tag prefix if image name has the tag 'latest' provided", func() { image.Spec.Tag = "gcr.io/imagename/tagged:latest" build := image.Build(sourceResolver, builder, latestBuild, "", "", 1, "") - require.Len(t, build.Spec.Tags, 2) + require.Len(t, build.Spec.Tags, 3) require.Regexp(t, "gcr.io/imagename/tagged:b1\\.\\d{8}\\.\\d{6}", build.Spec.Tags[1]) }) }) From 70179a09a103402b1296c16753490b30cabf0b71 Mon Sep 17 00:00:00 2001 From: Murad Iusufov Date: Fri, 19 Sep 2025 15:57:08 +0100 Subject: [PATCH 4/4] feat: add sha tag when pointing to branch --- pkg/apis/build/v1alpha2/image_builds.go | 4 ---- pkg/apis/build/v1alpha2/image_builds_test.go | 10 ++++++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pkg/apis/build/v1alpha2/image_builds.go b/pkg/apis/build/v1alpha2/image_builds.go index f12158f3b..12f80ddeb 100644 --- a/pkg/apis/build/v1alpha2/image_builds.go +++ b/pkg/apis/build/v1alpha2/image_builds.go @@ -296,10 +296,6 @@ func (im *Image) resolvedGitSource(sourceResolver *SourceResolver) *corev1alpha1 return nil } - if gitSource.Type != corev1alpha1.Commit { - return nil - } - return gitSource } diff --git a/pkg/apis/build/v1alpha2/image_builds_test.go b/pkg/apis/build/v1alpha2/image_builds_test.go index af861fce4..60711e0b0 100644 --- a/pkg/apis/build/v1alpha2/image_builds_test.go +++ b/pkg/apis/build/v1alpha2/image_builds_test.go @@ -160,6 +160,16 @@ func testImageBuilds(t *testing.T, when spec.G, it spec.S) { assert.Contains(t, build.Spec.Tags, "gcr.io/imagename/foo:"+gitRevision) }) + it("appends the git sha tag even when the resolved git source is not marked as a commit", func() { + image.Spec.Tag = "gcr.io/imagename/foo:test" + previousType := sourceResolver.Status.Source.Git.Type + sourceResolver.Status.Source.Git.Type = corev1alpha1.Branch + defer func() { sourceResolver.Status.Source.Git.Type = previousType }() + + build := image.Build(sourceResolver, builder, latestBuild, "", "", 12, "") + assert.Contains(t, build.Spec.Tags, "gcr.io/imagename/foo:"+gitRevision) + }) + it("sets blob url when image source is blob", func() { sourceResolver.Status.Source = corev1alpha1.ResolvedSourceConfig{ Blob: &corev1alpha1.ResolvedBlobSource{