Skip to content

Commit

Permalink
changes to support new app revision statuses on front end (#4050)
Browse files Browse the repository at this point in the history
  • Loading branch information
Feroze Mohideen authored Dec 7, 2023
1 parent fc7740c commit d0816dc
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 41 deletions.
32 changes: 20 additions & 12 deletions api/server/handlers/porter_app/create_and_update_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (p *CreateUpdatePorterAppEventHandler) ServeHTTP(w http.ResponseWriter, r *
return
}
} 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 {
e := telemetry.Error(ctx, span, err, "error creating new app event")
p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(e, http.StatusBadRequest))
Expand Down Expand Up @@ -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
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")
defer span.End()

Expand Down Expand Up @@ -193,17 +193,25 @@ func (p *CreateUpdatePorterAppEventHandler) createNewAppEvent(ctx context.Contex
}
return event, nil
} 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
}
}
Expand Down
4 changes: 2 additions & 2 deletions api/server/handlers/porter_app/report_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,9 @@ func writePRComment(ctx context.Context, inp writePRCommentInput) error {
switch inp.revision.Status {
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)
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)
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)
default:
return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func (c *UpdateAppRevisionStatusHandler) ServeHTTP(w http.ResponseWriter, r *htt
switch request.Status {
case models.AppRevisionStatus_BuildFailed:
statusProto = porterv1.EnumRevisionStatus_ENUM_REVISION_STATUS_BUILD_FAILED
case models.AppRevisionStatus_DeployFailed:
case models.AppRevisionStatus_InstallFailed:
statusProto = porterv1.EnumRevisionStatus_ENUM_REVISION_STATUS_DEPLOY_FAILED
case models.AppRevisionStatus_PredeployFailed:
statusProto = porterv1.EnumRevisionStatus_ENUM_REVISION_STATUS_PREDEPLOY_FAILED
Expand Down
9 changes: 7 additions & 2 deletions cli/cmd/v2/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,12 @@ func Update(ctx context.Context, inp UpdateInput) error {
}
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
}
if status == models.AppRevisionStatus_AwaitingPredeploy {
Expand All @@ -234,7 +239,7 @@ func Update(ctx context.Context, inp UpdateInput) error {
CommitSHA: commitSHA,
})

if status == models.AppRevisionStatus_DeployFailed {
if status == models.AppRevisionStatus_InstallFailed {
return errors.New("app failed to deploy")
}
if status == models.AppRevisionStatus_PredeployFailed {
Expand Down
3 changes: 3 additions & 0 deletions dashboard/src/lib/revisions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ export const appRevisionValidator = z.object({
"DEPLOY_FAILED",
"APPLY_FAILED",
"UPDATE_FAILED",
"DEPLOYMENT_PROGRESSING",
"DEPLOYMENT_SUCCESSFUL",
"DEPLOYMENT_FAILED",
]),
b64_app_proto: z.string(),
revision_number: z.number(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ const GHStatusBanner: React.FC = () => {
const previouslyBuilt = useMemo(() => {
if (revisions.length === 1) {
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
) {
return false;
Expand All @@ -76,6 +79,9 @@ const GHStatusBanner: React.FC = () => {
"DEPLOY_FAILED",
"BUILD_FAILED",
"IMAGE_AVAILABLE",
"DEPLOYMENT_PROGRESSING",
"DEPLOYMENT_SUCCESSFUL",
"DEPLOYMENT_FAILED",
() => true
)
.otherwise(() => false)
Expand Down
32 changes: 18 additions & 14 deletions internal/models/app_revision.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,34 @@ const (
AppRevisionStatus_ImageAvailable AppRevisionStatus = "IMAGE_AVAILABLE"
// AppRevisionStatus_AwaitingBuild is the status for a revision that still needs to be built
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 AppRevisionStatus = "BUILD_CANCELED"
// AppRevisionStatus_BuildFailed is the status for a revision that failed to build
AppRevisionStatus_BuildFailed AppRevisionStatus = "BUILD_FAILED"
// AppRevisionStatus_BuildSuccessful is the status for a revision that successfully built
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 AppRevisionStatus = "PREDEPLOY_FAILED"
// AppRevisionStatus_PredeploySuccessful is the status for a revision that successfully ran a predeploy
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 AppRevisionStatus = "APPLY_FAILED"
// AppRevisionStatus_UpdateFailed is the status for a revision that failed due to an internal system error
Expand Down
23 changes: 14 additions & 9 deletions internal/porter_app/revisions.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,12 +217,12 @@ func appRevisionStatusFromProto(status string) (models.AppRevisionStatus, error)
appRevisionStatus = models.AppRevisionStatus_AwaitingBuild
case string(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):
appRevisionStatus = models.AppRevisionStatus_BuildCanceled
case string(models.AppRevisionStatus_BuildFailed):
Expand All @@ -233,8 +233,8 @@ func appRevisionStatusFromProto(status string) (models.AppRevisionStatus, error)
appRevisionStatus = models.AppRevisionStatus_PredeploySuccessful
case string(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):
appRevisionStatus = models.AppRevisionStatus_Created
case string(models.AppRevisionStatus_BuildSuccessful):
Expand All @@ -243,7 +243,12 @@ func appRevisionStatusFromProto(status string) (models.AppRevisionStatus, error)
appRevisionStatus = models.AppRevisionStatus_ApplyFailed
case string(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:
return appRevisionStatus, errors.New("unknown app revision status")
}
Expand Down

0 comments on commit d0816dc

Please sign in to comment.