ソースを参照

re-enable checking event status for in progress events for backwards compatibility (#3302)

Feroze Mohideen 2 年 前
コミット
fa9a01c766
1 ファイル変更108 行追加5 行削除
  1. 108 5
      api/server/handlers/porter_app/list_events.go

+ 108 - 5
api/server/handlers/porter_app/list_events.go

@@ -3,8 +3,13 @@ package porter_app
 import (
 	"context"
 	"errors"
+	"fmt"
 	"net/http"
+	"reflect"
+	"strconv"
 
+	"github.com/bradleyfalzon/ghinstallation/v2"
+	"github.com/google/go-github/v41/github"
 	"github.com/google/uuid"
 	"github.com/gorilla/schema"
 	"github.com/porter-dev/porter/api/server/handlers"
@@ -75,9 +80,7 @@ func (p *PorterAppEventListHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
 		if appEvent.Status == "PROGRESSING" {
 			pae, err := p.updateExistingAppEvent(ctx, *cluster, stackName, *appEvent, user, project)
 			if err != nil {
-				e := telemetry.Error(ctx, span, nil, "unable to update existing porter app event")
-				p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(e, http.StatusBadRequest))
-				return
+				telemetry.Error(ctx, span, nil, "unable to update existing porter app event")
 			}
 			porterAppEvents[idx] = &pae
 		}
@@ -125,10 +128,16 @@ func (p *PorterAppEventListHandler) updateExistingAppEvent(
 		telemetry.AttributeKV{Key: "porter-app-id", Value: event.PorterAppID},
 		telemetry.AttributeKV{Key: "porter-app-event-id", Value: event.ID.String()},
 		telemetry.AttributeKV{Key: "porter-app-event-status", Value: event.Status},
-		telemetry.AttributeKV{Key: "cluster-id", Value: int(cluster.ID)},
-		telemetry.AttributeKV{Key: "project-id", Value: int(cluster.ProjectID)},
 	)
 
+	// TODO: get rid of this block and related methods if still here after 08-04-2023
+	if appEvent.Type == string(types.PorterAppEventType_Build) && appEvent.TypeExternalSource == "GITHUB" {
+		err = p.updateBuildEvent_Github(ctx, &event, user, project, stackName)
+		if err != nil {
+			return appEvent, telemetry.Error(ctx, span, err, "error updating porter app event for github build")
+		}
+	}
+
 	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "porter-app-event-updated-status", Value: event.Status})
 
 	err = p.Repo().PorterAppEvent().UpdateEvent(ctx, &event)
@@ -142,3 +151,97 @@ func (p *PorterAppEventListHandler) updateExistingAppEvent(
 
 	return event, nil
 }
+
+func (p *PorterAppEventListHandler) updateBuildEvent_Github(
+	ctx context.Context,
+	event *models.PorterAppEvent,
+	user *models.User,
+	project *models.Project,
+	stackName string,
+) error {
+	ctx, span := telemetry.NewSpan(ctx, "update-porter-app-build-event")
+	defer span.End()
+
+	repoOrg, ok := event.Metadata["org"].(string)
+	if !ok {
+		return telemetry.Error(ctx, span, nil, "error retrieving repo org from metadata")
+	}
+
+	repoName, ok := event.Metadata["repo"].(string)
+	if !ok {
+		return telemetry.Error(ctx, span, nil, "error retrieving repo name from metadata")
+	}
+
+	actionRunIDIface, ok := event.Metadata["action_run_id"]
+	if !ok {
+		return telemetry.Error(ctx, span, nil, "error retrieving action run id from metadata")
+	}
+	actionRunID, ok := actionRunIDIface.(float64)
+	if !ok {
+		telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "action-run-id-type", Value: reflect.TypeOf(actionRunIDIface).String()})
+		return telemetry.Error(ctx, span, nil, "error converting action run id to int")
+	}
+
+	accountIDIface, ok := event.Metadata["github_account_id"]
+	if !ok {
+		return telemetry.Error(ctx, span, nil, "error retrieving github account id from metadata")
+	}
+	githubAccountID, ok := accountIDIface.(float64)
+	if !ok {
+		telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "github-account-id-type", Value: reflect.TypeOf(accountIDIface).String()})
+		return telemetry.Error(ctx, span, nil, "error converting github account id to int")
+	}
+
+	// read the environment to get the environment id
+	env, err := p.Repo().GithubAppInstallation().ReadGithubAppInstallationByAccountID(int64(githubAccountID))
+	if err != nil {
+		return telemetry.Error(ctx, span, err, "error reading github environment by owner repo name")
+	}
+	if env == nil {
+		return telemetry.Error(ctx, span, nil, "github environment is nil")
+	}
+
+	ghClient, err := getGithubClientFromEnvironment(p.Config(), env.InstallationID)
+	if err != nil {
+		return telemetry.Error(ctx, span, err, "error getting github client using porter application")
+	}
+	if ghClient == nil {
+		return telemetry.Error(ctx, span, nil, "github client is nil")
+	}
+
+	actionRun, _, err := ghClient.Actions.GetWorkflowRunByID(ctx, repoOrg, repoName, int64(actionRunID))
+	if err != nil {
+		return telemetry.Error(ctx, span, err, "error getting github action run by id")
+	}
+	if actionRun == nil {
+		return telemetry.Error(ctx, span, nil, "github action run is nil")
+	}
+
+	if *actionRun.Status == "completed" {
+		_ = TrackStackBuildStatus(p.Config(), user, project, stackName, "", event.Status)
+		event.Metadata["end_time"] = actionRun.GetUpdatedAt().Time
+	}
+
+	return nil
+}
+
+func getGithubClientFromEnvironment(config *config.Config, installationID int64) (*github.Client, error) {
+	// get the github app client
+	ghAppId, err := strconv.Atoi(config.ServerConf.GithubAppID)
+	if err != nil {
+		return nil, fmt.Errorf("malformed GITHUB_APP_ID in server configuration: %w", err)
+	}
+
+	// authenticate as github app installation
+	itr, err := ghinstallation.New(
+		http.DefaultTransport,
+		int64(ghAppId),
+		installationID,
+		config.ServerConf.GithubAppSecret,
+	)
+	if err != nil {
+		return nil, fmt.Errorf("error in creating github client from preview environment: %w", err)
+	}
+
+	return github.NewClient(&http.Client{Transport: itr}), nil
+}