diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index a1a8e0e0..8d927c94 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -7,9 +7,6 @@ jobs: build: name: Build runs-on: ubuntu-latest - strategy: - matrix: - arch: [arm64] steps: - uses: actions/checkout@v4 - name: Build docker image @@ -18,9 +15,6 @@ jobs: lint: name: Lint runs-on: ubuntu-latest - strategy: - matrix: - arch: [arm64] steps: - uses: actions/checkout@v4 with: @@ -36,9 +30,6 @@ jobs: test: name: Unit Test runs-on: ubuntu-latest - strategy: - matrix: - arch: [arm64] steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 @@ -52,9 +43,6 @@ jobs: verify-code-generation: name: Verify Code Generation runs-on: ubuntu-latest - strategy: - matrix: - arch: [arm64] steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 @@ -67,9 +55,6 @@ jobs: report-swagger-changes: name: Report Changes In Swagger Spec runs-on: ubuntu-latest - strategy: - matrix: - arch: [arm64] steps: - uses: actions/checkout@v4 - run: git fetch --no-tags --no-recurse-submodules --depth=1 origin master:master @@ -94,9 +79,6 @@ jobs: validate-radixconfig: name: Test RadixConfig runs-on: ubuntu-latest - strategy: - matrix: - arch: [arm64] steps: - name: 'Fake TOKEN FOR RADIX CLI' run: echo "APP_SERVICE_ACCOUNT_TOKEN=dummy" >> $GITHUB_ENV diff --git a/Dockerfile b/Dockerfile index b37c37a8..34f2c381 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,10 @@ # Build stage -FROM docker.io/golang:1.22-alpine3.20 as builder +FROM --platform=$BUILDPLATFORM docker.io/golang:1.22.5-alpine3.20 AS builder +ARG TARGETARCH ENV CGO_ENABLED=0 \ - GOOS=linux + GOOS=linux \ + GOARCH=${TARGETARCH} + WORKDIR /src COPY go.mod go.sum ./ RUN go mod download diff --git a/api/applications/applications_controller_test.go b/api/applications/applications_controller_test.go index 4a1008e7..4ca72971 100644 --- a/api/applications/applications_controller_test.go +++ b/api/applications/applications_controller_test.go @@ -1623,7 +1623,6 @@ func TestHandleTriggerPipeline_Deploy_JobHasCorrectParameters(t *testing.T) { } func TestHandleTriggerPipeline_Promote_JobHasCorrectParameters(t *testing.T) { - commonTestUtils, controllerTestUtils, _, radixclient, _, _, _, _ := setupTest(t, true, true) const ( appName = "an-app" @@ -1633,36 +1632,88 @@ func TestHandleTriggerPipeline_Promote_JobHasCorrectParameters(t *testing.T) { toEnvironment = "target" ) - parameters := applicationModels.PipelineParametersPromote{ - FromEnvironment: fromEnvironment, - ToEnvironment: toEnvironment, - DeploymentName: deploymentName, + type scenario struct { + name string + existingDeploymentName string + requestedDeploymentName string + expectedDeploymentName string + expectedResponseBodyError string + expectedResponseCode int + } + scenarios := []scenario{ + { + name: "existing full deployment name", + existingDeploymentName: "abc-deployment", + requestedDeploymentName: "abc-deployment", + expectedDeploymentName: "abc-deployment", + expectedResponseCode: 200, + }, + { + name: "existing short deployment name", + existingDeploymentName: "abc-deployment", + requestedDeploymentName: "deployment", + expectedDeploymentName: "abc-deployment", + expectedResponseCode: 200, + }, + { + name: "non existing short deployment name", + existingDeploymentName: "abc-deployment", + requestedDeploymentName: "other-name", + expectedDeploymentName: "", + expectedResponseBodyError: "invalid or not existing deployment name", + expectedResponseCode: 400, + }, } - _, err := commonTestUtils.ApplyDeployment( - context.Background(), - builders. - ARadixDeployment(). - WithAppName(appName). - WithDeploymentName(deploymentName). - WithEnvironment(fromEnvironment). - WithLabel(kube.RadixCommitLabel, commitId). - WithCondition(v1.DeploymentInactive)) - require.NoError(t, err) - registerAppParam := buildApplicationRegistrationRequest(anApplicationRegistration().WithName(appName).Build(), false) - <-controllerTestUtils.ExecuteRequestWithParameters("POST", "/api/v1/applications", registerAppParam) - responseChannel := controllerTestUtils.ExecuteRequestWithParameters("POST", fmt.Sprintf("/api/v1/applications/%s/pipelines/%s", appName, v1.Promote), parameters) - <-responseChannel + for _, ts := range scenarios { + t.Run(ts.name, func(t *testing.T) { + commonTestUtils, controllerTestUtils, _, radixclient, _, _, _, _ := setupTest(t, true, true) + _, err := commonTestUtils.ApplyDeployment( + context.Background(), + builders. + ARadixDeployment(). + WithAppName(appName). + WithDeploymentName(ts.existingDeploymentName). + WithEnvironment(fromEnvironment). + WithLabel(kube.RadixCommitLabel, commitId). + WithCondition(v1.DeploymentInactive)) + require.NoError(t, err) - appNamespace := fmt.Sprintf("%s-app", appName) - jobs, err := getJobsInNamespace(radixclient, appNamespace) - require.NoError(t, err) + parameters := applicationModels.PipelineParametersPromote{ + FromEnvironment: fromEnvironment, + ToEnvironment: toEnvironment, + DeploymentName: ts.requestedDeploymentName, + } + + registerAppParam := buildApplicationRegistrationRequest(anApplicationRegistration().WithName(appName).Build(), false) + <-controllerTestUtils.ExecuteRequestWithParameters("POST", "/api/v1/applications", registerAppParam) + responseChannel := controllerTestUtils.ExecuteRequestWithParameters("POST", fmt.Sprintf("/api/v1/applications/%s/pipelines/%s", appName, v1.Promote), parameters) + response := <-responseChannel + assert.Equal(t, ts.expectedResponseCode, response.Code) + if ts.expectedResponseCode != 200 { + assert.NotNil(t, response.Body, "Empty respond body") + type RespondBody struct { + Type string `json:"type"` + Message string `json:"message"` + Error string `json:"error"` + } + body := RespondBody{} + err = json.Unmarshal(response.Body.Bytes(), &body) + require.NoError(t, err) + require.Equal(t, ts.expectedResponseBodyError, body.Error, "invalid respond error") - require.Len(t, jobs, 1) - assert.Equal(t, jobs[0].Spec.Promote.FromEnvironment, fromEnvironment) - assert.Equal(t, jobs[0].Spec.Promote.ToEnvironment, toEnvironment) - assert.Equal(t, jobs[0].Spec.Promote.DeploymentName, deploymentName) - assert.Equal(t, jobs[0].Spec.Promote.CommitID, commitId) + } else { + appNamespace := fmt.Sprintf("%s-app", appName) + jobs, err := getJobsInNamespace(radixclient, appNamespace) + require.NoError(t, err) + require.Len(t, jobs, 1) + assert.Equal(t, jobs[0].Spec.Promote.FromEnvironment, fromEnvironment) + assert.Equal(t, jobs[0].Spec.Promote.ToEnvironment, toEnvironment) + assert.Equal(t, ts.expectedDeploymentName, jobs[0].Spec.Promote.DeploymentName) + assert.Equal(t, jobs[0].Spec.Promote.CommitID, commitId) + } + }) + } } func TestDeleteApplication_ApplicationIsDeleted(t *testing.T) { diff --git a/api/applications/applications_handler.go b/api/applications/applications_handler.go index 3005fef8..a983d179 100644 --- a/api/applications/applications_handler.go +++ b/api/applications/applications_handler.go @@ -434,21 +434,18 @@ func (ah *ApplicationHandler) TriggerPipelinePromote(ctx context.Context, appNam log.Ctx(ctx).Info().Msgf("Creating promote pipeline job for %s using deployment %s from environment %s into environment %s", appName, deploymentName, fromEnvironment, toEnvironment) - jobParameters := pipelineParameters.MapPipelineParametersPromoteToJobParameter() - pipeline, err := jobPipeline.GetPipelineFromName("promote") if err != nil { return nil, err } - radixDeployment, err := kubequery.GetRadixDeploymentByName(ctx, ah.accounts.UserAccount.RadixClient, appName, fromEnvironment, deploymentName) + radixDeployment, err := ah.getRadixDeploymentForPromotePipeline(ctx, appName, fromEnvironment, deploymentName) if err != nil { - if k8serrors.IsNotFound(err) { - return nil, fmt.Errorf("deployment %s not found in the app %s, environment %s", deploymentName, appName, fromEnvironment) - } - return nil, fmt.Errorf("failed to get deployment %s for the app %s, environment %s: %v", deploymentName, appName, fromEnvironment, err) + return nil, err } + pipelineParameters.DeploymentName = radixDeployment.GetName() + jobParameters := pipelineParameters.MapPipelineParametersPromoteToJobParameter() jobParameters.CommitID = radixDeployment.GetLabels()[kube.RadixCommitLabel] jobSummary, err := ah.jobHandler.HandleStartPipelineJob(ctx, appName, pipeline, jobParameters) if err != nil { @@ -458,6 +455,25 @@ func (ah *ApplicationHandler) TriggerPipelinePromote(ctx context.Context, appNam return jobSummary, nil } +func (ah *ApplicationHandler) getRadixDeploymentForPromotePipeline(ctx context.Context, appName string, envName, deploymentName string) (*v1.RadixDeployment, error) { + radixDeployment, err := kubequery.GetRadixDeploymentByName(ctx, ah.accounts.UserAccount.RadixClient, appName, envName, deploymentName) + if err == nil { + return radixDeployment, nil + } + if !k8serrors.IsNotFound(err) { + return nil, fmt.Errorf("failed to get deployment %s for the app %s, environment %s: %v", deploymentName, appName, envName, err) + } + envRadixDeployments, err := kubequery.GetRadixDeploymentsForEnvironment(ctx, ah.accounts.UserAccount.RadixClient, appName, envName) + if err != nil { + return nil, err + } + radixDeployments := slice.FindAll(envRadixDeployments, func(rd v1.RadixDeployment) bool { return strings.HasSuffix(rd.Name, deploymentName) }) + if len(radixDeployments) != 1 { + return nil, errors.New("invalid or not existing deployment name") + } + return &radixDeployments[0], nil +} + // TriggerPipelineDeploy Triggers deploy pipeline for an application func (ah *ApplicationHandler) TriggerPipelineDeploy(ctx context.Context, appName string, r *http.Request) (*jobModels.JobSummary, error) { var pipelineParameters applicationModels.PipelineParametersDeploy diff --git a/go.mod b/go.mod index fd1df12c..f335c80f 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/cert-manager/cert-manager v1.15.0 github.com/equinor/radix-common v1.9.3 github.com/equinor/radix-job-scheduler v1.10.2 - github.com/equinor/radix-operator v1.57.4 + github.com/equinor/radix-operator v1.57.8 github.com/evanphx/json-patch/v5 v5.9.0 github.com/felixge/httpsnoop v1.0.4 github.com/golang-jwt/jwt/v5 v5.2.1 diff --git a/go.sum b/go.sum index 143984d6..e037401a 100644 --- a/go.sum +++ b/go.sum @@ -87,8 +87,8 @@ github.com/equinor/radix-common v1.9.3 h1:dLKFzYy8/XyEG9Zygi0rMWIYGCddai/ILwUqjB github.com/equinor/radix-common v1.9.3/go.mod h1:+g0Wj0D40zz29DjNkYKVmCVeYy4OsFWKI7Qi9rA6kpY= github.com/equinor/radix-job-scheduler v1.10.2 h1:Ea/gmSQjVdomC3XzkqJdR1TGQ9Bvq8ZJOKUfwYY3Ask= github.com/equinor/radix-job-scheduler v1.10.2/go.mod h1:cnVXZ09D0rAPTZrcgWynL/txMQnpYmPSPyzfKfTYlec= -github.com/equinor/radix-operator v1.57.4 h1:Rr/bjxU+ABWyk1UM9QknMmOHQxiwHi/HHjeA+50fUNU= -github.com/equinor/radix-operator v1.57.4/go.mod h1:zCdAiP/wxyvlUO4qGoJuLW3O+ZSt9kTyHMnjmsR3fCU= +github.com/equinor/radix-operator v1.57.8 h1:fvXky2aZmKcre2X54R9hL5sl9gK19RGfFY9Q2Gn3IQg= +github.com/equinor/radix-operator v1.57.8/go.mod h1:zCdAiP/wxyvlUO4qGoJuLW3O+ZSt9kTyHMnjmsR3fCU= github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg=