diff --git a/.github/workflows/nightly-chart-and-image-publish.yaml b/.github/workflows/nightly-chart-and-image-publish.yaml index ae77b511..c0a07205 100644 --- a/.github/workflows/nightly-chart-and-image-publish.yaml +++ b/.github/workflows/nightly-chart-and-image-publish.yaml @@ -31,7 +31,7 @@ jobs: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build docker image + - name: Build and push docker images run: make docker-build-and-push TAG=${{ env.TAG }} ORG=${{ env.PROD_ORG }} publish-helm-chart-ghcr: diff --git a/.github/workflows/release_build/action.yaml b/.github/workflows/release_build/action.yaml index 3faa3482..92eb5831 100644 --- a/.github/workflows/release_build/action.yaml +++ b/.github/workflows/release_build/action.yaml @@ -45,12 +45,11 @@ runs: password: ${{ inputs.password }} - name: Build & Push docker image shell: bash - run: make docker-build-and-push TAG=${{ inputs.tag }} REGISTRY=${{ inputs.registry }} ORG=${{ inputs.org }} - - name: Store image and digest - shell: bash - id: image_info run: | - digest=$( docker images --digests --format "{{.Digest}}" | head -1 ) - image=$( docker images --digests --format "{{.Repository}}" | head -1 ) + IID_FILE=$(mktemp) + make docker-build-and-push TAG=${{ inputs.tag }} REGISTRY=${{ inputs.registry }} ORG=${{ inputs.org }} IID_FILE=${IID_FILE} + + digest=$(head -n 1 ${IID_FILE}) + image=${{ inputs.registry }}/${{ inputs.registry }}/turtles echo "digest=${digest}" >> $GITHUB_OUTPUT echo "image=${image}" >> $GITHUB_OUTPUT diff --git a/.github/workflows/release_sign/action.yaml b/.github/workflows/release_sign/action.yaml index 58d2d6ac..d58b5554 100644 --- a/.github/workflows/release_sign/action.yaml +++ b/.github/workflows/release_sign/action.yaml @@ -44,15 +44,10 @@ runs: username: ${{ inputs.username }} password: ${{ inputs.password }} - uses: sigstore/cosign-installer@v3.4.0 - - name: Sign manifests - shell: bash - env: - COSIGN_EXPERIMENTAL: 1 - run: | - cosign sign --yes ${{ inputs.image }}@${{ inputs.digest }} --oidc-provider=${{ inputs.oidc-provider }} - - name: Verify pushed ghcr images + - name: Sign and verify manifests shell: bash env: COSIGN_EXPERIMENTAL: 1 run: | + cosign sign --yes ${{ inputs.image }}@${{ inputs.digest }} --oidc-provider=${{ inputs.oidc-provider }} --recursive cosign verify ${{ inputs.image }}@${{ inputs.digest }} --certificate-identity=${{ inputs.identity }} --certificate-oidc-issuer=${{ inputs.oids-issuer }} diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index 8ca5d0b1..f902ee79 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -24,11 +24,11 @@ jobs: uses: actions/checkout@v4.1.7 - name: Build an image run: | - TAG=${{ github.sha }} ARCH=amd64 make docker-build + TAG=${{ github.sha }} make docker-build - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@062f2592684a31eb3aa050cc61e7ca1451cecd3d with: - image-ref: 'ghcr.io/rancher/turtles-amd64:${{ github.sha }}' + image-ref: 'ghcr.io/rancher/turtles:${{ github.sha }}' format: 'sarif' output: 'trivy-results.sarif' severity: 'CRITICAL,HIGH' diff --git a/Makefile b/Makefile index b7aa481e..67af789d 100644 --- a/Makefile +++ b/Makefile @@ -159,16 +159,15 @@ NOTES := $(abspath $(TOOLS_BIN_DIR)/$(NOTES_BIN)) # Registry / images TAG ?= dev -ARCH ?= $(shell go env GOARCH) -ALL_ARCH = amd64 arm64 +ARCH ?= linux/$(shell go env GOARCH) TARGET_PLATFORMS := linux/amd64,linux/arm64 MACHINE := rancher-turtles REGISTRY ?= ghcr.io ORG ?= rancher CONTROLLER_IMAGE_NAME ?= turtles CONTROLLER_IMG ?= $(REGISTRY)/$(ORG)/$(CONTROLLER_IMAGE_NAME) -MANIFEST_IMG ?= $(CONTROLLER_IMG)-$(ARCH) CONTROLLER_IMAGE_VERSION ?= $(shell git describe --abbrev=0 2>/dev/null) +IID_FILE ?= $(shell mktemp) # Release RELEASE_TAG ?= $(shell git describe --abbrev=0 2>/dev/null) @@ -348,22 +347,23 @@ docker-build: buildx-machine docker-pull-prerequisites ## Build docker image for --build-arg builder_image=$(GO_CONTAINER_IMAGE) \ --build-arg goproxy=$(GOPROXY) \ --build-arg package=. \ - --build-arg ldflags="$(LDFLAGS)" . -t $(MANIFEST_IMG):$(TAG) + --build-arg ldflags="$(LDFLAGS)" . -t $(CONTROLLER_IMG):$(TAG) .PHONY: docker-build-and-push docker-build-and-push: buildx-machine docker-pull-prerequisites ## Run docker-build-and-push targets for all architectures DOCKER_BUILDKIT=1 BUILDX_BUILDER=$(MACHINE) docker buildx build \ --platform $(TARGET_PLATFORMS) \ --push \ - --attest type=provenance \ + --sbom=true \ + --attest type=provenance,mode=max \ + --iidfile=$(IID_FILE) \ --build-arg builder_image=$(GO_CONTAINER_IMAGE) \ --build-arg goproxy=$(GOPROXY) \ --build-arg package=. \ - --build-arg ldflags="$(LDFLAGS)" . -t $(MANIFEST_IMG):$(TAG) + --build-arg ldflags="$(LDFLAGS)" . -t $(CONTROLLER_IMG):$(TAG) docker-list-all: @echo $(CONTROLLER_IMG):${TAG} - @for arch in $(ALL_ARCH); do echo $(CONTROLLER_IMG)-$${arch}:${TAG}; done ##@ Deployment @@ -546,7 +546,7 @@ test-e2e: $(GINKGO) $(HELM) $(CLUSTERCTL) kubectl e2e-image ## Run the end-to-en .PHONY: e2e-image e2e-image: ## Build the image for e2e tests TAG=v0.0.1 CONTROLLER_IMAGE_NAME=turtles-e2e $(MAKE) docker-build - RELEASE_TAG=v0.0.1 CONTROLLER_IMG=$(REGISTRY)/$(ORG)/turtles-e2e-$(ARCH) CONTROLLER_IMAGE_VERSION=v0.0.1 $(MAKE) build-chart + RELEASE_TAG=v0.0.1 CONTROLLER_IMG=$(REGISTRY)/$(ORG)/turtles-e2e CONTROLLER_IMAGE_VERSION=v0.0.1 $(MAKE) build-chart .PHONY: e2e-image-push e2e-image-push: e2e-image ## Push the image for e2e tests diff --git a/test/e2e/config/operator.yaml b/test/e2e/config/operator.yaml index 0f03bb1c..8455bec2 100644 --- a/test/e2e/config/operator.yaml +++ b/test/e2e/config/operator.yaml @@ -2,7 +2,7 @@ managementClusterName: rancher-turtles-e2e images: # Use local dev images built source tree; -- name: ghcr.io/rancher/turtles-e2e-{ARCH}:v0.0.1 # This should be substituted with operator image +- name: ghcr.io/rancher/turtles-e2e:v0.0.1 # This should be substituted with operator image loadBehavior: tryLoad intervals: diff --git a/test/e2e/specs/migrate_gitops_provv1_mgmtv3.go b/test/e2e/specs/migrate_gitops_provv1_mgmtv3.go index b4457a9e..b54e428c 100644 --- a/test/e2e/specs/migrate_gitops_provv1_mgmtv3.go +++ b/test/e2e/specs/migrate_gitops_provv1_mgmtv3.go @@ -25,7 +25,6 @@ import ( "os" "path" "path/filepath" - "runtime" "strconv" "time" @@ -362,7 +361,7 @@ func MigrateToV3UsingGitOpsSpec(ctx context.Context, inputGetter func() MigrateT BootstrapClusterProxy: input.BootstrapClusterProxy, HelmBinaryPath: input.HelmBinaryPath, Namespace: turtlesframework.DefaultRancherTurtlesNamespace, - Image: fmt.Sprintf("ghcr.io/rancher/turtles-e2e-%s", runtime.GOARCH), + Image: "ghcr.io/rancher/turtles-e2e", Tag: input.E2EConfig.GetVariable(e2e.TurtlesVersionVar), WaitDeploymentsReadyInterval: input.E2EConfig.GetIntervals(input.BootstrapClusterProxy.GetName(), "wait-controllers"), SkipCleanup: true, diff --git a/test/e2e/suites/chart-upgrade/chart_upgrade_test.go b/test/e2e/suites/chart-upgrade/chart_upgrade_test.go index 83b00498..17a7b1fb 100644 --- a/test/e2e/suites/chart-upgrade/chart_upgrade_test.go +++ b/test/e2e/suites/chart-upgrade/chart_upgrade_test.go @@ -21,8 +21,6 @@ package chart_upgrade import ( _ "embed" - "fmt" - "runtime" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -77,7 +75,7 @@ var _ = Describe("Chart upgrade functionality should work", Label(e2e.ShortTestL BootstrapClusterProxy: setupClusterResult.BootstrapClusterProxy, HelmBinaryPath: e2eConfig.GetVariable(e2e.HelmBinaryPathVar), Namespace: framework.DefaultRancherTurtlesNamespace, - Image: fmt.Sprintf("ghcr.io/rancher/turtles-e2e-%s", runtime.GOARCH), + Image: "ghcr.io/rancher/turtles-e2e", Tag: e2eConfig.GetVariable(e2e.TurtlesVersionVar), WaitDeploymentsReadyInterval: e2eConfig.GetIntervals(setupClusterResult.BootstrapClusterProxy.GetName(), "wait-controllers"), AdditionalValues: rtInput.AdditionalValues, diff --git a/test/e2e/suites/embedded-capi-disabled-v3/suite_test.go b/test/e2e/suites/embedded-capi-disabled-v3/suite_test.go index 3cd5c0cd..414f05bc 100644 --- a/test/e2e/suites/embedded-capi-disabled-v3/suite_test.go +++ b/test/e2e/suites/embedded-capi-disabled-v3/suite_test.go @@ -23,7 +23,6 @@ import ( "context" "fmt" "path/filepath" - "runtime" "strconv" "testing" @@ -161,7 +160,7 @@ var _ = BeforeSuite(func() { TurtlesChartPath: e2eConfig.GetVariable(e2e.TurtlesPathVar), CAPIProvidersYAML: e2e.CapiProviders, Namespace: framework.DefaultRancherTurtlesNamespace, - Image: fmt.Sprintf("ghcr.io/rancher/turtles-e2e-%s", runtime.GOARCH), + Image: "ghcr.io/rancher/turtles-e2e", Tag: e2eConfig.GetVariable(e2e.TurtlesVersionVar), WaitDeploymentsReadyInterval: e2eConfig.GetIntervals(setupClusterResult.BootstrapClusterProxy.GetName(), "wait-controllers"), AdditionalValues: map[string]string{ diff --git a/test/e2e/suites/embedded-capi-disabled/suite_test.go b/test/e2e/suites/embedded-capi-disabled/suite_test.go index eaca143b..d1ccb39f 100644 --- a/test/e2e/suites/embedded-capi-disabled/suite_test.go +++ b/test/e2e/suites/embedded-capi-disabled/suite_test.go @@ -23,7 +23,6 @@ import ( "context" "fmt" "path/filepath" - "runtime" "strconv" "testing" @@ -162,7 +161,7 @@ var _ = BeforeSuite(func() { TurtlesChartPath: e2eConfig.GetVariable(e2e.TurtlesPathVar), CAPIProvidersYAML: e2e.CapiProviders, Namespace: framework.DefaultRancherTurtlesNamespace, - Image: fmt.Sprintf("ghcr.io/rancher/turtles-e2e-%s", runtime.GOARCH), + Image: "ghcr.io/rancher/turtles-e2e", Tag: e2eConfig.GetVariable(e2e.TurtlesVersionVar), WaitDeploymentsReadyInterval: e2eConfig.GetIntervals(setupClusterResult.BootstrapClusterProxy.GetName(), "wait-controllers"), AdditionalValues: map[string]string{ diff --git a/test/e2e/suites/import-gitops-v3/suite_test.go b/test/e2e/suites/import-gitops-v3/suite_test.go index ec4d96fb..bae0fb09 100644 --- a/test/e2e/suites/import-gitops-v3/suite_test.go +++ b/test/e2e/suites/import-gitops-v3/suite_test.go @@ -23,7 +23,6 @@ import ( "context" "fmt" "path/filepath" - "runtime" "strconv" "testing" @@ -162,7 +161,7 @@ var _ = BeforeSuite(func() { TurtlesChartPath: e2eConfig.GetVariable(e2e.TurtlesPathVar), CAPIProvidersYAML: e2e.CapiProviders, Namespace: framework.DefaultRancherTurtlesNamespace, - Image: fmt.Sprintf("ghcr.io/rancher/turtles-e2e-%s", runtime.GOARCH), + Image: "ghcr.io/rancher/turtles-e2e", Tag: e2eConfig.GetVariable(e2e.TurtlesVersionVar), WaitDeploymentsReadyInterval: e2eConfig.GetIntervals(setupClusterResult.BootstrapClusterProxy.GetName(), "wait-controllers"), AdditionalValues: map[string]string{ diff --git a/test/e2e/suites/import-gitops/suite_test.go b/test/e2e/suites/import-gitops/suite_test.go index 6c92ccb9..97860fa6 100644 --- a/test/e2e/suites/import-gitops/suite_test.go +++ b/test/e2e/suites/import-gitops/suite_test.go @@ -23,7 +23,6 @@ import ( "context" "fmt" "path/filepath" - "runtime" "strconv" "testing" @@ -170,7 +169,7 @@ var _ = BeforeSuite(func() { TurtlesChartPath: e2eConfig.GetVariable(e2e.TurtlesPathVar), CAPIProvidersYAML: e2e.CapiProviders, Namespace: framework.DefaultRancherTurtlesNamespace, - Image: fmt.Sprintf("ghcr.io/rancher/turtles-e2e-%s", runtime.GOARCH), + Image: "ghcr.io/rancher/turtles-e2e", Tag: e2eConfig.GetVariable(e2e.TurtlesVersionVar), WaitDeploymentsReadyInterval: e2eConfig.GetIntervals(setupClusterResult.BootstrapClusterProxy.GetName(), "wait-controllers"), AdditionalValues: map[string]string{}, @@ -201,7 +200,7 @@ var _ = BeforeSuite(func() { TurtlesChartPath: e2eConfig.GetVariable(e2e.TurtlesPathVar), CAPIProvidersYAML: e2e.CapiProviders, Namespace: framework.DefaultRancherTurtlesNamespace, - Image: fmt.Sprintf("ghcr.io/rancher/turtles-e2e-%s", runtime.GOARCH), + Image: "ghcr.io/rancher/turtles-e2e", Tag: e2eConfig.GetVariable(e2e.TurtlesVersionVar), WaitDeploymentsReadyInterval: e2eConfig.GetIntervals(setupClusterResult.BootstrapClusterProxy.GetName(), "wait-controllers"), AdditionalValues: map[string]string{}, diff --git a/test/e2e/suites/migrate-gitops/suite_test.go b/test/e2e/suites/migrate-gitops/suite_test.go index d35b10b6..b994e9c7 100644 --- a/test/e2e/suites/migrate-gitops/suite_test.go +++ b/test/e2e/suites/migrate-gitops/suite_test.go @@ -23,7 +23,6 @@ import ( "context" "fmt" "path/filepath" - "runtime" "strconv" "testing" @@ -171,7 +170,7 @@ var _ = BeforeSuite(func() { TurtlesChartPath: e2eConfig.GetVariable(e2e.TurtlesPathVar), CAPIProvidersYAML: e2e.CapiProviders, Namespace: framework.DefaultRancherTurtlesNamespace, - Image: fmt.Sprintf("ghcr.io/rancher/turtles-e2e-%s", runtime.GOARCH), + Image: "ghcr.io/rancher/turtles-e2e", Tag: e2eConfig.GetVariable(e2e.TurtlesVersionVar), WaitDeploymentsReadyInterval: e2eConfig.GetIntervals(setupClusterResult.BootstrapClusterProxy.GetName(), "wait-controllers"), AdditionalValues: map[string]string{}, diff --git a/test/e2e/suites/update-labels/suite_test.go b/test/e2e/suites/update-labels/suite_test.go index ff3744b7..8d8b25f1 100644 --- a/test/e2e/suites/update-labels/suite_test.go +++ b/test/e2e/suites/update-labels/suite_test.go @@ -23,7 +23,6 @@ import ( "context" "fmt" "path/filepath" - "runtime" "strconv" "testing" @@ -158,7 +157,7 @@ var _ = BeforeSuite(func() { TurtlesChartPath: e2eConfig.GetVariable(e2e.TurtlesPathVar), CAPIProvidersYAML: e2e.CapiProviders, Namespace: framework.DefaultRancherTurtlesNamespace, - Image: fmt.Sprintf("ghcr.io/rancher/turtles-e2e-%s", runtime.GOARCH), + Image: "ghcr.io/rancher/turtles-e2e", Tag: e2eConfig.GetVariable(e2e.TurtlesVersionVar), WaitDeploymentsReadyInterval: e2eConfig.GetIntervals(setupClusterResult.BootstrapClusterProxy.GetName(), "wait-controllers"), AdditionalValues: map[string]string{ diff --git a/test/e2e/suites/v2prov/suite_test.go b/test/e2e/suites/v2prov/suite_test.go index 17c636c0..30b868d7 100644 --- a/test/e2e/suites/v2prov/suite_test.go +++ b/test/e2e/suites/v2prov/suite_test.go @@ -23,7 +23,6 @@ import ( "context" "fmt" "path/filepath" - "runtime" "strconv" "testing" @@ -160,7 +159,7 @@ var _ = BeforeSuite(func() { TurtlesChartPath: e2eConfig.GetVariable(e2e.TurtlesPathVar), CAPIProvidersYAML: e2e.CapiProviders, Namespace: turtlesframework.DefaultRancherTurtlesNamespace, - Image: fmt.Sprintf("ghcr.io/rancher/turtles-e2e-%s", runtime.GOARCH), + Image: "ghcr.io/rancher/turtles-e2e", Tag: e2eConfig.GetVariable(e2e.TurtlesVersionVar), WaitDeploymentsReadyInterval: e2eConfig.GetIntervals(setupClusterResult.BootstrapClusterProxy.GetName(), "wait-controllers"), AdditionalValues: map[string]string{},