Переглянути джерело

changes to support new app revision statuses on front end (#4050)

Feroze Mohideen 2 роки тому
батько
коміт
d0816dc332

+ 20 - 12
api/server/handlers/porter_app/create_and_update_events.go

@@ -86,7 +86,7 @@ func (p *CreateUpdatePorterAppEventHandler) ServeHTTP(w http.ResponseWriter, r *
 				return
 				return
 			}
 			}
 		} else {
 		} else {
-			event, err = p.createNewAppEvent(ctx, *cluster, appName, request.DeploymentTargetID, request.Status, string(request.Type), request.TypeExternalSource, request.Metadata)
+			event, err = p.createNewAppEvent(ctx, *project, *cluster, appName, request.DeploymentTargetID, request.Status, string(request.Type), request.TypeExternalSource, request.Metadata)
 			if err != nil {
 			if err != nil {
 				e := telemetry.Error(ctx, span, err, "error creating new app event")
 				e := telemetry.Error(ctx, span, err, "error creating new app event")
 				p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(e, http.StatusBadRequest))
 				p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(e, http.StatusBadRequest))
@@ -138,7 +138,7 @@ func reportBuildStatus(ctx context.Context, request *types.CreateOrUpdatePorterA
 }
 }
 
 
 // createNewAppEvent will create a new app event for the given porter app name. If the app event is an agent event, then it will be created only if there is no existing event which has the agent ID. In the case that an existing event is found, that will be returned instead
 // createNewAppEvent will create a new app event for the given porter app name. If the app event is an agent event, then it will be created only if there is no existing event which has the agent ID. In the case that an existing event is found, that will be returned instead
-func (p *CreateUpdatePorterAppEventHandler) createNewAppEvent(ctx context.Context, cluster models.Cluster, porterAppName string, deploymentTargetID string, status types.PorterAppEventStatus, eventType string, externalSource string, requestMetadata map[string]any) (types.PorterAppEvent, error) {
+func (p *CreateUpdatePorterAppEventHandler) createNewAppEvent(ctx context.Context, project models.Project, cluster models.Cluster, porterAppName string, deploymentTargetID string, status types.PorterAppEventStatus, eventType string, externalSource string, requestMetadata map[string]any) (types.PorterAppEvent, error) {
 	ctx, span := telemetry.NewSpan(ctx, "create-porter-app-event")
 	ctx, span := telemetry.NewSpan(ctx, "create-porter-app-event")
 	defer span.End()
 	defer span.End()
 
 
@@ -193,17 +193,25 @@ func (p *CreateUpdatePorterAppEventHandler) createNewAppEvent(ctx context.Contex
 				}
 				}
 				return event, nil
 				return event, nil
 			} else {
 			} else {
-				err := p.updateDeployEventV2(ctx, updateDeployEventV2Input{
-					projectID:             cluster.ProjectID,
-					appName:               porterAppName,
-					appID:                 app.ID,
-					deploymentTargetID:    deploymentTargetID,
-					updatedStatusMetadata: requestMetadata,
-				})
-				if err != nil {
-					return types.PorterAppEvent{}, telemetry.Error(ctx, span, err, "error updating v2 deploy event")
+				betaFeaturesEnabled := project.GetFeatureFlag(models.BetaFeaturesEnabled, p.Config().LaunchDarklyClient)
+				telemetry.WithAttributes(span,
+					telemetry.AttributeKV{Key: "beta_features_enabled", Value: betaFeaturesEnabled},
+				)
+				// if beta features are not enabled, then porter makes a request to ccp to update the deploy status
+				// if beta features are enabled, ccp is checking the deploy status, so this request is not necessary
+				// TODO remove this entire branch once beta features are enabled by default
+				if !betaFeaturesEnabled {
+					err := p.updateDeployEventV2(ctx, updateDeployEventV2Input{
+						projectID:             cluster.ProjectID,
+						appName:               porterAppName,
+						appID:                 app.ID,
+						deploymentTargetID:    deploymentTargetID,
+						updatedStatusMetadata: requestMetadata,
+					})
+					if err != nil {
+						return types.PorterAppEvent{}, telemetry.Error(ctx, span, err, "error updating v2 deploy event")
+					}
 				}
 				}
-				// v2 method calls ccp and will not return an event, so we just return an empty event
 				return types.PorterAppEvent{}, nil
 				return types.PorterAppEvent{}, nil
 			}
 			}
 		}
 		}

+ 2 - 2
api/server/handlers/porter_app/report_status.go

@@ -242,9 +242,9 @@ func writePRComment(ctx context.Context, inp writePRCommentInput) error {
 	switch inp.revision.Status {
 	switch inp.revision.Status {
 	case models.AppRevisionStatus_BuildFailed:
 	case models.AppRevisionStatus_BuildFailed:
 		body = fmt.Sprintf("%s❌ The latest deploy failed to build. Check the [Porter Dashboard](%s) or [action logs](https://github.com/%s/actions/runs/) for more information.", body, porterURL, inp.porterApp.RepoName)
 		body = fmt.Sprintf("%s❌ The latest deploy failed to build. Check the [Porter Dashboard](%s) or [action logs](https://github.com/%s/actions/runs/) for more information.", body, porterURL, inp.porterApp.RepoName)
-	case models.AppRevisionStatus_DeployFailed:
+	case models.AppRevisionStatus_InstallFailed:
 		body = fmt.Sprintf("%s❌ The latest SHA ([`%s`](https://github.com/%s/%s/commit/%s)) failed to deploy.\nCheck the [Porter Dashboard](%s) or [action logs](https://github.com/%s/actions/runs/) for more information.\nContact Porter Support if the errors persists", body, inp.commitSha, repoDetails[0], repoDetails[1], inp.commitSha, porterURL, inp.porterApp.RepoName)
 		body = fmt.Sprintf("%s❌ The latest SHA ([`%s`](https://github.com/%s/%s/commit/%s)) failed to deploy.\nCheck the [Porter Dashboard](%s) or [action logs](https://github.com/%s/actions/runs/) for more information.\nContact Porter Support if the errors persists", body, inp.commitSha, repoDetails[0], repoDetails[1], inp.commitSha, porterURL, inp.porterApp.RepoName)
-	case models.AppRevisionStatus_Deployed:
+	case models.AppRevisionStatus_InstallSuccessful:
 		body = fmt.Sprintf("%s✅ The latest SHA ([`%s`](https://github.com/%s/%s/commit/%s)) has been successfully deployed.\nApp details available in the [Porter Dashboard](%s)", body, inp.commitSha, repoDetails[0], repoDetails[1], inp.commitSha, porterURL)
 		body = fmt.Sprintf("%s✅ The latest SHA ([`%s`](https://github.com/%s/%s/commit/%s)) has been successfully deployed.\nApp details available in the [Porter Dashboard](%s)", body, inp.commitSha, repoDetails[0], repoDetails[1], inp.commitSha, porterURL)
 	default:
 	default:
 		return nil
 		return nil

+ 1 - 1
api/server/handlers/porter_app/update_app_revision_status.go

@@ -78,7 +78,7 @@ func (c *UpdateAppRevisionStatusHandler) ServeHTTP(w http.ResponseWriter, r *htt
 	switch request.Status {
 	switch request.Status {
 	case models.AppRevisionStatus_BuildFailed:
 	case models.AppRevisionStatus_BuildFailed:
 		statusProto = porterv1.EnumRevisionStatus_ENUM_REVISION_STATUS_BUILD_FAILED
 		statusProto = porterv1.EnumRevisionStatus_ENUM_REVISION_STATUS_BUILD_FAILED
-	case models.AppRevisionStatus_DeployFailed:
+	case models.AppRevisionStatus_InstallFailed:
 		statusProto = porterv1.EnumRevisionStatus_ENUM_REVISION_STATUS_DEPLOY_FAILED
 		statusProto = porterv1.EnumRevisionStatus_ENUM_REVISION_STATUS_DEPLOY_FAILED
 	case models.AppRevisionStatus_PredeployFailed:
 	case models.AppRevisionStatus_PredeployFailed:
 		statusProto = porterv1.EnumRevisionStatus_ENUM_REVISION_STATUS_PREDEPLOY_FAILED
 		statusProto = porterv1.EnumRevisionStatus_ENUM_REVISION_STATUS_PREDEPLOY_FAILED

+ 7 - 2
cli/cmd/v2/update.go

@@ -215,7 +215,12 @@ func Update(ctx context.Context, inp UpdateInput) error {
 		}
 		}
 		status = revision.AppRevision.Status
 		status = revision.AppRevision.Status
 
 
-		if status == models.AppRevisionStatus_DeployFailed || status == models.AppRevisionStatus_PredeployFailed || status == models.AppRevisionStatus_Deployed {
+		if status == models.AppRevisionStatus_PredeployFailed ||
+			status == models.AppRevisionStatus_InstallFailed ||
+			status == models.AppRevisionStatus_InstallSuccessful ||
+			status == models.AppRevisionStatus_DeploymentSuccessful ||
+			status == models.AppRevisionStatus_DeploymentProgressing ||
+			status == models.AppRevisionStatus_DeploymentFailed {
 			break
 			break
 		}
 		}
 		if status == models.AppRevisionStatus_AwaitingPredeploy {
 		if status == models.AppRevisionStatus_AwaitingPredeploy {
@@ -234,7 +239,7 @@ func Update(ctx context.Context, inp UpdateInput) error {
 		CommitSHA:     commitSHA,
 		CommitSHA:     commitSHA,
 	})
 	})
 
 
-	if status == models.AppRevisionStatus_DeployFailed {
+	if status == models.AppRevisionStatus_InstallFailed {
 		return errors.New("app failed to deploy")
 		return errors.New("app failed to deploy")
 	}
 	}
 	if status == models.AppRevisionStatus_PredeployFailed {
 	if status == models.AppRevisionStatus_PredeployFailed {

+ 3 - 0
dashboard/src/lib/revisions/types.ts

@@ -19,6 +19,9 @@ export const appRevisionValidator = z.object({
     "DEPLOY_FAILED",
     "DEPLOY_FAILED",
     "APPLY_FAILED",
     "APPLY_FAILED",
     "UPDATE_FAILED",
     "UPDATE_FAILED",
+    "DEPLOYMENT_PROGRESSING",
+    "DEPLOYMENT_SUCCESSFUL",
+    "DEPLOYMENT_FAILED",
   ]),
   ]),
   b64_app_proto: z.string(),
   b64_app_proto: z.string(),
   revision_number: z.number(),
   revision_number: z.number(),

+ 7 - 1
dashboard/src/main/home/app-dashboard/validate-apply/revisions-list/GHStatusBanner.tsx

@@ -62,7 +62,10 @@ const GHStatusBanner: React.FC = () => {
   const previouslyBuilt = useMemo(() => {
   const previouslyBuilt = useMemo(() => {
     if (revisions.length === 1) {
     if (revisions.length === 1) {
       if (
       if (
-        revisions[0].status === "DEPLOYED" &&
+        // TODO: remove checking for DEPLOYED status once update flow is released,
+        // because once that happens, the new terminal status will be DEPLOYMENT_SUCCESSFUL
+        (revisions[0].status === "DEPLOYMENT_SUCCESSFUL" ||
+          revisions[0].status === "DEPLOYED") &&
         latestProto.image?.tag === HELLO_PORTER_PLACEHOLDER_TAG
         latestProto.image?.tag === HELLO_PORTER_PLACEHOLDER_TAG
       ) {
       ) {
         return false;
         return false;
@@ -76,6 +79,9 @@ const GHStatusBanner: React.FC = () => {
           "DEPLOY_FAILED",
           "DEPLOY_FAILED",
           "BUILD_FAILED",
           "BUILD_FAILED",
           "IMAGE_AVAILABLE",
           "IMAGE_AVAILABLE",
+          "DEPLOYMENT_PROGRESSING",
+          "DEPLOYMENT_SUCCESSFUL",
+          "DEPLOYMENT_FAILED",
           () => true
           () => true
         )
         )
         .otherwise(() => false)
         .otherwise(() => false)

+ 18 - 14
internal/models/app_revision.go

@@ -17,30 +17,34 @@ const (
 	AppRevisionStatus_ImageAvailable AppRevisionStatus = "IMAGE_AVAILABLE"
 	AppRevisionStatus_ImageAvailable AppRevisionStatus = "IMAGE_AVAILABLE"
 	// AppRevisionStatus_AwaitingBuild is the status for a revision that still needs to be built
 	// AppRevisionStatus_AwaitingBuild is the status for a revision that still needs to be built
 	AppRevisionStatus_AwaitingBuild AppRevisionStatus = "AWAITING_BUILD_ARTIFACT"
 	AppRevisionStatus_AwaitingBuild AppRevisionStatus = "AWAITING_BUILD_ARTIFACT"
-	// AppRevisionStatus_AwaitingPredeploy is the status for a revision that is waiting for a predeploy to be run
-	AppRevisionStatus_AwaitingPredeploy AppRevisionStatus = "AWAITING_PREDEPLOY"
-	// AppRevisionStatus_AwaitingDeploy is the status for a revision that is waiting to be deployed
-	AppRevisionStatus_AwaitingDeploy AppRevisionStatus = "AWAITING_DEPLOY"
-	// AppRevisionStatus_PredeployProgressing is the status for a revision that is currently running a predeploy
-	AppRevisionStatus_PredeployProgressing AppRevisionStatus = "PREDEPLOY_PROGRESSING"
-	// AppRevisionStatus_Deployed is the status for a revision that has been deployed
-	AppRevisionStatus_Deployed AppRevisionStatus = "DEPLOYED"
-	// AppRevisionStatus_Deploying is the status for a revision that is currently deploying
-	AppRevisionStatus_Deploying AppRevisionStatus = "DEPLOYING"
-
 	// AppRevisionStatus_BuildCanceled is the status for a revision that was canceled during the build process
 	// AppRevisionStatus_BuildCanceled is the status for a revision that was canceled during the build process
 	AppRevisionStatus_BuildCanceled AppRevisionStatus = "BUILD_CANCELED"
 	AppRevisionStatus_BuildCanceled AppRevisionStatus = "BUILD_CANCELED"
 	// AppRevisionStatus_BuildFailed is the status for a revision that failed to build
 	// AppRevisionStatus_BuildFailed is the status for a revision that failed to build
 	AppRevisionStatus_BuildFailed AppRevisionStatus = "BUILD_FAILED"
 	AppRevisionStatus_BuildFailed AppRevisionStatus = "BUILD_FAILED"
 	// AppRevisionStatus_BuildSuccessful is the status for a revision that successfully built
 	// AppRevisionStatus_BuildSuccessful is the status for a revision that successfully built
 	AppRevisionStatus_BuildSuccessful AppRevisionStatus = "BUILD_SUCCESSFUL"
 	AppRevisionStatus_BuildSuccessful AppRevisionStatus = "BUILD_SUCCESSFUL"
+	// AppRevisionStatus_AwaitingPredeploy is the status for a revision that is waiting for a predeploy to be run
+	AppRevisionStatus_AwaitingPredeploy AppRevisionStatus = "AWAITING_PREDEPLOY"
+	// AppRevisionStatus_PredeployProgressing is the status for a revision that is currently running a predeploy
+	AppRevisionStatus_PredeployProgressing AppRevisionStatus = "PREDEPLOY_PROGRESSING"
 	// AppRevisionStatus_PredeployFailed is the status for a revision that failed to predeploy
 	// AppRevisionStatus_PredeployFailed is the status for a revision that failed to predeploy
 	AppRevisionStatus_PredeployFailed AppRevisionStatus = "PREDEPLOY_FAILED"
 	AppRevisionStatus_PredeployFailed AppRevisionStatus = "PREDEPLOY_FAILED"
 	// AppRevisionStatus_PredeploySuccessful is the status for a revision that successfully ran a predeploy
 	// AppRevisionStatus_PredeploySuccessful is the status for a revision that successfully ran a predeploy
 	AppRevisionStatus_PredeploySuccessful AppRevisionStatus = "PREDEPLOY_SUCCESSFUL"
 	AppRevisionStatus_PredeploySuccessful AppRevisionStatus = "PREDEPLOY_SUCCESSFUL"
-	// AppRevisionStatus_DeployFailed is the status for a revision that failed to deploy
-	AppRevisionStatus_DeployFailed AppRevisionStatus = "DEPLOY_FAILED"
-
+	// AppRevisionStatus_AwaitingInstall is the status for a revision that is waiting to be installed
+	AppRevisionStatus_AwaitingInstall AppRevisionStatus = "AWAITING_DEPLOY"
+	// AppRevisionStatus_InstallProgressing is the status for a revision that is currently installing
+	AppRevisionStatus_InstallProgressing AppRevisionStatus = "DEPLOYING"
+	// AppRevisionStatus_InstallSuccessful is the status for a revision that has been installed
+	AppRevisionStatus_InstallSuccessful AppRevisionStatus = "DEPLOYED"
+	// AppRevisionStatus_InstallFailed is the status for a revision that failed to install
+	AppRevisionStatus_InstallFailed AppRevisionStatus = "DEPLOY_FAILED"
+	// AppRevisionStatus_DeploymentProgressing is the status for a revision that is currently deploying
+	AppRevisionStatus_DeploymentProgressing AppRevisionStatus = "DEPLOYMENT_PROGRESSING"
+	// AppRevisionStatus_DeploymentSuccessful is the status for a revision that successfully deployed
+	AppRevisionStatus_DeploymentSuccessful AppRevisionStatus = "DEPLOYMENT_SUCCESSFUL"
+	// AppRevisionStatus_DeploymentFailed is the status for a revision that failed to deploy
+	AppRevisionStatus_DeploymentFailed AppRevisionStatus = "DEPLOYMENT_FAILED"
 	// AppRevisionStatus_ApplyFailed is the status for a revision that failed due to an internal system error
 	// AppRevisionStatus_ApplyFailed is the status for a revision that failed due to an internal system error
 	AppRevisionStatus_ApplyFailed AppRevisionStatus = "APPLY_FAILED"
 	AppRevisionStatus_ApplyFailed AppRevisionStatus = "APPLY_FAILED"
 	// AppRevisionStatus_UpdateFailed is the status for a revision that failed due to an internal system error
 	// AppRevisionStatus_UpdateFailed is the status for a revision that failed due to an internal system error

+ 14 - 9
internal/porter_app/revisions.go

@@ -217,12 +217,12 @@ func appRevisionStatusFromProto(status string) (models.AppRevisionStatus, error)
 		appRevisionStatus = models.AppRevisionStatus_AwaitingBuild
 		appRevisionStatus = models.AppRevisionStatus_AwaitingBuild
 	case string(models.AppRevisionStatus_AwaitingPredeploy):
 	case string(models.AppRevisionStatus_AwaitingPredeploy):
 		appRevisionStatus = models.AppRevisionStatus_AwaitingPredeploy
 		appRevisionStatus = models.AppRevisionStatus_AwaitingPredeploy
-	case string(models.AppRevisionStatus_Deployed):
-		appRevisionStatus = models.AppRevisionStatus_Deployed
-	case string(models.AppRevisionStatus_Deploying):
-		appRevisionStatus = models.AppRevisionStatus_Deploying
-	case string(models.AppRevisionStatus_AwaitingDeploy):
-		appRevisionStatus = models.AppRevisionStatus_AwaitingDeploy
+	case string(models.AppRevisionStatus_InstallSuccessful):
+		appRevisionStatus = models.AppRevisionStatus_InstallSuccessful
+	case string(models.AppRevisionStatus_InstallProgressing):
+		appRevisionStatus = models.AppRevisionStatus_InstallProgressing
+	case string(models.AppRevisionStatus_AwaitingInstall):
+		appRevisionStatus = models.AppRevisionStatus_AwaitingInstall
 	case string(models.AppRevisionStatus_BuildCanceled):
 	case string(models.AppRevisionStatus_BuildCanceled):
 		appRevisionStatus = models.AppRevisionStatus_BuildCanceled
 		appRevisionStatus = models.AppRevisionStatus_BuildCanceled
 	case string(models.AppRevisionStatus_BuildFailed):
 	case string(models.AppRevisionStatus_BuildFailed):
@@ -233,8 +233,8 @@ func appRevisionStatusFromProto(status string) (models.AppRevisionStatus, error)
 		appRevisionStatus = models.AppRevisionStatus_PredeploySuccessful
 		appRevisionStatus = models.AppRevisionStatus_PredeploySuccessful
 	case string(models.AppRevisionStatus_PredeployProgressing):
 	case string(models.AppRevisionStatus_PredeployProgressing):
 		appRevisionStatus = models.AppRevisionStatus_PredeployProgressing
 		appRevisionStatus = models.AppRevisionStatus_PredeployProgressing
-	case string(models.AppRevisionStatus_DeployFailed):
-		appRevisionStatus = models.AppRevisionStatus_DeployFailed
+	case string(models.AppRevisionStatus_InstallFailed):
+		appRevisionStatus = models.AppRevisionStatus_InstallFailed
 	case string(models.AppRevisionStatus_Created):
 	case string(models.AppRevisionStatus_Created):
 		appRevisionStatus = models.AppRevisionStatus_Created
 		appRevisionStatus = models.AppRevisionStatus_Created
 	case string(models.AppRevisionStatus_BuildSuccessful):
 	case string(models.AppRevisionStatus_BuildSuccessful):
@@ -243,7 +243,12 @@ func appRevisionStatusFromProto(status string) (models.AppRevisionStatus, error)
 		appRevisionStatus = models.AppRevisionStatus_ApplyFailed
 		appRevisionStatus = models.AppRevisionStatus_ApplyFailed
 	case string(models.AppRevisionStatus_UpdateFailed):
 	case string(models.AppRevisionStatus_UpdateFailed):
 		appRevisionStatus = models.AppRevisionStatus_UpdateFailed
 		appRevisionStatus = models.AppRevisionStatus_UpdateFailed
-
+	case string(models.AppRevisionStatus_DeploymentProgressing):
+		appRevisionStatus = models.AppRevisionStatus_DeploymentProgressing
+	case string(models.AppRevisionStatus_DeploymentSuccessful):
+		appRevisionStatus = models.AppRevisionStatus_DeploymentSuccessful
+	case string(models.AppRevisionStatus_DeploymentFailed):
+		appRevisionStatus = models.AppRevisionStatus_DeploymentFailed
 	default:
 	default:
 		return appRevisionStatus, errors.New("unknown app revision status")
 		return appRevisionStatus, errors.New("unknown app revision status")
 	}
 	}