Просмотр исходного кода

Merge branch 'nafees/hotfixes' into dev

Mohammed Nafees 3 лет назад
Родитель
Сommit
f5ece065ec

+ 17 - 6
api/client/environment.go

@@ -7,6 +7,21 @@ import (
 	"github.com/porter-dev/porter/api/types"
 )
 
+func (c *Client) ListEnvironments(
+	ctx context.Context,
+	projID, clusterID uint,
+) ([]*types.Environment, error) {
+	var resp []*types.Environment
+
+	err := c.postRequest(
+		fmt.Sprintf("/projects/%d/clusters/%d/environments", projID, clusterID),
+		nil,
+		resp,
+	)
+
+	return resp, err
+}
+
 func (c *Client) CreateDeployment(
 	ctx context.Context,
 	projID, gitInstallationID, clusterID uint,
@@ -29,17 +44,13 @@ func (c *Client) CreateDeployment(
 
 func (c *Client) GetDeployment(
 	ctx context.Context,
-	projID, gitInstallationID, clusterID uint,
-	gitRepoOwner, gitRepoName string,
+	projID, clusterID, envID uint,
 	req *types.GetDeploymentRequest,
 ) (*types.Deployment, error) {
 	resp := &types.Deployment{}
 
 	err := c.getRequest(
-		fmt.Sprintf(
-			"/projects/%d/gitrepos/%d/%s/%s/clusters/%d/deployment",
-			projID, gitInstallationID, gitRepoOwner, gitRepoName, clusterID,
-		),
+		fmt.Sprintf("/projects/%d/clusters/%d/environments/%d/deployment", projID, clusterID, envID),
 		req,
 		resp,
 	)

+ 16 - 9
api/server/handlers/environment/get_deployment_by_env.go

@@ -15,21 +15,21 @@ import (
 	"gorm.io/gorm"
 )
 
-type GetDeploymentByClusterHandler struct {
+type GetDeploymentByEnvironmentHandler struct {
 	handlers.PorterHandlerReadWriter
 }
 
-func NewGetDeploymentByClusterHandler(
+func NewGetDeploymentByEnvironmentHandler(
 	config *config.Config,
 	decoderValidator shared.RequestDecoderValidator,
 	writer shared.ResultWriter,
-) *GetDeploymentByClusterHandler {
-	return &GetDeploymentByClusterHandler{
+) *GetDeploymentByEnvironmentHandler {
+	return &GetDeploymentByEnvironmentHandler{
 		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
 	}
 }
 
-func (c *GetDeploymentByClusterHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+func (c *GetDeploymentByEnvironmentHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	project, _ := r.Context().Value(types.ProjectScope).(*models.Project)
 	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
 
@@ -48,10 +48,12 @@ func (c *GetDeploymentByClusterHandler) ServeHTTP(w http.ResponseWriter, r *http
 
 	_, err := c.Repo().Environment().ReadEnvironmentByID(project.ID, cluster.ID, envID)
 
-	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
-		c.HandleAPIError(w, r, apierrors.NewErrForbidden(fmt.Errorf("environment with id %d not found", envID)))
-		return
-	} else if err != nil {
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			c.HandleAPIError(w, r, apierrors.NewErrNotFound(fmt.Errorf("environment with id %d not found", envID)))
+			return
+		}
+
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return
 	}
@@ -59,6 +61,11 @@ func (c *GetDeploymentByClusterHandler) ServeHTTP(w http.ResponseWriter, r *http
 	depl, err := c.Repo().Environment().ReadDeployment(envID, request.Namespace)
 
 	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			c.HandleAPIError(w, r, apierrors.NewErrNotFound(fmt.Errorf("deployment not found for namespace: %s", request.Namespace)))
+			return
+		}
+
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return
 	}

+ 7 - 7
api/server/handlers/infra/forms.go

@@ -412,14 +412,14 @@ tabs:
       label: EKS control plane version
       variable: cluster_version
       settings:
-        default: 1.20
+        default: "1.20"
         options:
-        - label: 1.20
-          value: 1.20
-        - label: 1.21
-          value: 1.21
-        - label: 1.22
-          value: 1.22
+        - label: "1.20"
+          value: "1.20"
+        - label: "1.21"
+          value: "1.21"
+        - label: "1.22"
+          value: "1.22"
     - type: number-input
       label: Minimum number of EC2 instances to create in the application autoscaling group.
       variable: min_instances

+ 1 - 15
api/server/handlers/release/update_git_action_config.go

@@ -7,7 +7,6 @@ import (
 	"github.com/porter-dev/porter/api/server/shared"
 	"github.com/porter-dev/porter/api/server/shared/apierrors"
 	"github.com/porter-dev/porter/api/server/shared/config"
-	"github.com/porter-dev/porter/api/server/shared/requestutils"
 	"github.com/porter-dev/porter/api/types"
 	"github.com/porter-dev/porter/internal/models"
 	"gorm.io/gorm"
@@ -28,9 +27,7 @@ func NewUpdateGitActionConfigHandler(
 }
 
 func (c *UpdateGitActionConfigHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
-	name, _ := requestutils.GetURLParamString(r, types.URLParamReleaseName)
-	namespace := r.Context().Value(types.NamespaceScope).(string)
+	release, _ := r.Context().Value(types.ReleaseScope).(*models.Release)
 
 	request := &types.UpdateGitActionConfigRequest{}
 
@@ -38,17 +35,6 @@ func (c *UpdateGitActionConfigHandler) ServeHTTP(w http.ResponseWriter, r *http.
 		return
 	}
 
-	release, err := c.Repo().Release().ReadRelease(cluster.ID, name, namespace)
-
-	if err != nil {
-		if err == gorm.ErrRecordNotFound {
-			w.WriteHeader(http.StatusNotFound)
-			return
-		}
-
-		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	}
-
 	actionConfig, err := c.Repo().GitActionConfig().ReadGitActionConfig(release.GitActionConfig.ID)
 
 	if err != nil {

+ 3 - 3
api/server/router/cluster.go

@@ -348,14 +348,14 @@ func getClusterRoutes(
 			Router:   r,
 		})
 
-		// GET /api/projects/{project_id}/clusters/{cluster_id}/{environment_id}/deployment -> environment.NewGetDeploymentByClusterHandler
+		// GET /api/projects/{project_id}/clusters/{cluster_id}/environments/{environment_id}/deployment -> environment.NewGetDeploymentByClusterHandler
 		getDeploymentEndpoint := factory.NewAPIEndpoint(
 			&types.APIRequestMetadata{
 				Verb:   types.APIVerbGet,
 				Method: types.HTTPVerbGet,
 				Path: &types.Path{
 					Parent:       basePath,
-					RelativePath: relPath + "/{environment_id}/deployment",
+					RelativePath: relPath + "/environments/{environment_id}/deployment",
 				},
 				Scopes: []types.PermissionScope{
 					types.UserScope,
@@ -365,7 +365,7 @@ func getClusterRoutes(
 			},
 		)
 
-		getDeploymentHandler := environment.NewGetDeploymentByClusterHandler(
+		getDeploymentHandler := environment.NewGetDeploymentByEnvironmentHandler(
 			config,
 			factory.GetDecoderValidator(),
 			factory.GetResultWriter(),

+ 3 - 2
api/server/router/release.go

@@ -815,20 +815,21 @@ func getReleaseRoutes(
 		Router:   r,
 	})
 
-	// PATCH /api/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/releases/{name}/git_action_config -> release.NewUpdateGitActionConfigHandler
+	// PATCH /api/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/releases/{name}/{version}/git_action_config -> release.NewUpdateGitActionConfigHandler
 	updateGitActionConfigEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbUpdate,
 			Method: types.HTTPVerbPatch,
 			Path: &types.Path{
 				Parent:       basePath,
-				RelativePath: "/releases/{name}/git_action_config",
+				RelativePath: "/releases/{name}/{version}/git_action_config",
 			},
 			Scopes: []types.PermissionScope{
 				types.UserScope,
 				types.ProjectScope,
 				types.ClusterScope,
 				types.NamespaceScope,
+				types.ReleaseScope,
 			},
 		},
 	)

+ 7 - 1
api/types/release.go

@@ -194,6 +194,12 @@ type PatchUpdateReleaseTags struct {
 	Tags []string `json:"tags"`
 }
 
+type PartialGitActionConfig struct {
+	// The branch to use for the git repository
+	// required: true
+	GitBranch string `json:"branch" form:"required"`
+}
+
 type UpdateGitActionConfigRequest struct {
-	GitActionConfig *GitActionConfig `json:"git_action_config"`
+	GitActionConfig *PartialGitActionConfig `json:"git_action_config"`
 }

+ 37 - 21
cli/cmd/apply.go

@@ -405,22 +405,20 @@ func (d *Driver) applyApplication(resource *models.Resource, client *api.Client,
 			Name:      resource.Name,
 		})
 
-		if err != nil {
-			if appConfig.OnlyCreate {
-				err = client.DeleteRelease(
-					context.Background(),
-					d.target.Project,
-					d.target.Cluster,
-					d.target.Namespace,
-					resource.Name,
-				)
+		if err != nil && appConfig.OnlyCreate {
+			deleteJobErr := client.DeleteRelease(
+				context.Background(),
+				d.target.Project,
+				d.target.Cluster,
+				d.target.Namespace,
+				resource.Name,
+			)
 
-				if err != nil {
-					return nil, fmt.Errorf("error deleting job %s with waitForJob and onlyCreate set to true: %w",
-						resource.Name, err)
-				}
+			if deleteJobErr != nil {
+				return nil, fmt.Errorf("error deleting job %s with waitForJob and onlyCreate set to true: %w",
+					resource.Name, deleteJobErr)
 			}
-
+		} else if err != nil {
 			return nil, fmt.Errorf("error waiting for job %s: %w", resource.Name, err)
 		}
 	}
@@ -638,7 +636,7 @@ func (d *Driver) getAddonConfig(resource *models.Resource) (map[string]interface
 type DeploymentHook struct {
 	client                                                                    *api.Client
 	resourceGroup                                                             *switchboardTypes.ResourceGroup
-	gitInstallationID, projectID, clusterID, prID, actionID                   uint
+	gitInstallationID, projectID, clusterID, prID, actionID, envID            uint
 	branchFrom, branchInto, namespace, repoName, repoOwner, prName, commitSHA string
 }
 
@@ -715,18 +713,37 @@ func NewDeploymentHook(client *api.Client, resourceGroup *switchboardTypes.Resou
 }
 
 func (t *DeploymentHook) PreApply() error {
+	envList, err := t.client.ListEnvironments(
+		context.Background(), t.projectID, t.clusterID,
+	)
+
+	if err != nil {
+		return err
+	}
+
+	for _, env := range envList {
+		fmt.Println(env)
+		if env.GitRepoOwner == t.repoOwner && env.GitRepoName == t.repoName && env.GitInstallationID == t.gitInstallationID {
+			t.envID = env.ID
+			break
+		}
+	}
+
+	if t.envID == 0 {
+		return fmt.Errorf("could not find environment for deployment")
+	}
+
 	// attempt to read the deployment -- if it doesn't exist, create it
-	_, err := t.client.GetDeployment(
+	_, err = t.client.GetDeployment(
 		context.Background(),
-		t.projectID, t.gitInstallationID, t.clusterID,
-		t.repoOwner, t.repoName,
+		t.projectID, t.clusterID, t.envID,
 		&types.GetDeploymentRequest{
 			Namespace: t.namespace,
 		},
 	)
 
 	// TODO: case this on the response status code rather than text
-	if err != nil && strings.Contains(err.Error(), "deployment not found") {
+	if err != nil && strings.Contains(err.Error(), "not found") {
 		// in this case, create the deployment
 		_, err = t.client.CreateDeployment(
 			context.Background(),
@@ -860,8 +877,7 @@ func (t *DeploymentHook) OnError(err error) {
 	// if the deployment exists, throw an error for that deployment
 	_, getDeplErr := t.client.GetDeployment(
 		context.Background(),
-		t.projectID, t.gitInstallationID, t.clusterID,
-		t.repoOwner, t.repoName,
+		t.projectID, t.clusterID, t.envID,
 		&types.GetDeploymentRequest{
 			Namespace: t.namespace,
 		},

+ 18 - 2
cli/cmd/docker/builder.go

@@ -12,6 +12,7 @@ import (
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/pkg/archive"
+	"github.com/moby/buildkit/frontend/dockerfile/dockerignore"
 	"github.com/moby/moby/pkg/jsonmessage"
 	"github.com/moby/moby/pkg/stringid"
 	"github.com/moby/term"
@@ -31,9 +32,24 @@ type BuildOpts struct {
 }
 
 // BuildLocal
-func (a *Agent) BuildLocal(opts *BuildOpts) error {
+func (a *Agent) BuildLocal(opts *BuildOpts) (err error) {
 	dockerfilePath := opts.DockerfilePath
-	tar, err := archive.TarWithOptions(opts.BuildContext, &archive.TarOptions{})
+
+	// attempt to read dockerignore file and paths
+	dockerIgnoreBytes, _ := ioutil.ReadFile(".dockerignore")
+	var excludes []string
+
+	if len(dockerIgnoreBytes) != 0 {
+		excludes, err = dockerignore.ReadAll(bytes.NewBuffer(dockerIgnoreBytes))
+
+		if err != nil {
+			return err
+		}
+	}
+
+	tar, err := archive.TarWithOptions(opts.BuildContext, &archive.TarOptions{
+		ExcludePatterns: excludes,
+	})
 
 	if err != nil {
 		return err

+ 1 - 1
dashboard/src/main/home/cluster-dashboard/preview-environments/deployments/DeploymentDetail.tsx

@@ -31,7 +31,7 @@ const DeploymentDetail = () => {
     let environment_id = parseInt(searchParams.get("environment_id"));
     setEnvironmentId(searchParams.get("environment_id"));
     api
-      .getPRDeploymentByCluster(
+      .getPRDeploymentByEnvironment(
         "<token>",
         {
           namespace: params.namespace,

+ 9 - 6
dashboard/src/shared/api.tsx

@@ -359,7 +359,7 @@ const getPRDeploymentList = baseApi<
   return `/api/projects/${project_id}/clusters/${cluster_id}/deployments`;
 });
 
-const getPRDeploymentByCluster = baseApi<
+const getPRDeploymentByEnvironment = baseApi<
   {
     namespace: string;
   },
@@ -371,7 +371,7 @@ const getPRDeploymentByCluster = baseApi<
 >("GET", (pathParams) => {
   const { cluster_id, project_id, environment_id } = pathParams;
 
-  return `/api/projects/${project_id}/clusters/${cluster_id}/${environment_id}/deployment`;
+  return `/api/projects/${project_id}/clusters/${cluster_id}/environments/${environment_id}/deployment`;
 });
 
 const getPRDeployment = baseApi<
@@ -1808,18 +1808,21 @@ const updateBuildConfig = baseApi<
 
 const updateGitActionConfig = baseApi<
   {
-    git_action_config: FullActionConfigType;
+    git_action_config: {
+      git_branch: string;
+    };
   },
   {
     project_id: number;
     cluster_id: number;
     namespace: string;
     release_name: string;
+    revision?: 0; // Always update latest
   }
 >(
   "PATCH",
-  ({ project_id, cluster_id, namespace, release_name }) =>
-    `/api/projects/${project_id}/clusters/${cluster_id}/namespaces/${namespace}/releases/${release_name}/git_action_config`
+  ({ project_id, cluster_id, namespace, release_name, revision = 0 }) =>
+    `/api/projects/${project_id}/clusters/${cluster_id}/namespaces/${namespace}/releases/${release_name}/${revision}/git_action_config`
 );
 
 const reRunGHWorkflow = baseApi<
@@ -2086,7 +2089,7 @@ export default {
   getClusterNode,
   getConfigMap,
   getPRDeploymentList,
-  getPRDeploymentByCluster,
+  getPRDeploymentByEnvironment,
   getPRDeployment,
   getGHAWorkflowTemplate,
   getGitRepoList,

+ 4 - 3
go.mod

@@ -154,7 +154,7 @@ require (
 	github.com/google/go-querystring v1.1.0 // indirect
 	github.com/google/gofuzz v1.2.0 // indirect
 	github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
-	github.com/google/uuid v1.2.0 // indirect
+	github.com/google/uuid v1.3.0 // indirect
 	github.com/googleapis/gax-go/v2 v2.1.1 // indirect
 	github.com/googleapis/gnostic v0.5.5 // indirect
 	github.com/gorilla/mux v1.8.0 // indirect
@@ -205,6 +205,7 @@ require (
 	github.com/mitchellh/go-wordwrap v1.0.0 // indirect
 	github.com/mitchellh/ioprogress v0.0.0-20180201004757-6a23b12fa88e // indirect
 	github.com/mitchellh/reflectwalk v1.0.2 // indirect
+	github.com/moby/buildkit v0.10.3
 	github.com/moby/locker v1.0.1 // indirect
 	github.com/moby/spdystream v0.2.0 // indirect
 	github.com/moby/sys/mount v0.3.2 // indirect
@@ -220,9 +221,9 @@ require (
 	github.com/pelletier/go-toml v1.9.5 // indirect
 	github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/prometheus/client_golang v1.11.1 // indirect
+	github.com/prometheus/client_golang v1.12.1 // indirect
 	github.com/prometheus/client_model v0.2.0 // indirect
-	github.com/prometheus/common v0.30.0 // indirect
+	github.com/prometheus/common v0.32.1 // indirect
 	github.com/prometheus/procfs v0.7.3 // indirect
 	github.com/rivo/tview v0.0.0-20220307222120-9994674d60a8 // indirect
 	github.com/rivo/uniseg v0.2.0 // indirect

+ 9 - 0
go.sum

@@ -827,6 +827,8 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
 github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
@@ -1230,6 +1232,8 @@ github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx
 github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
 github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
 github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/moby/buildkit v0.10.3 h1:/dGykD8FW+H4p++q5+KqKEo6gAkYKyBQHdawdjVwVAU=
+github.com/moby/buildkit v0.10.3/go.mod h1:jxeOuly98l9gWHai0Ojrbnczrk/rf+o9/JqNhY+UCSo=
 github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
 github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
 github.com/moby/moby v20.10.6+incompatible h1:3wn5wW3KwjAv8Z36VHdbvaqvY273JiWUDFuudH0z5Vs=
@@ -1398,6 +1402,8 @@ github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP
 github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
 github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s=
 github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
+github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk=
+github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
 github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -1416,6 +1422,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9
 github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
 github.com/prometheus/common v0.30.0 h1:JEkYlQnpzrzQFxi6gnukFPdQ+ac82oRhzMcIduJu/Ug=
 github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
+github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
+github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
 github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
@@ -2044,6 +2052,7 @@ golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220318055525-2edf467146b5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc=

+ 14 - 0
internal/repository/test/git_action_config.go

@@ -46,3 +46,17 @@ func (repo *GitActionConfigRepository) ReadGitActionConfig(id uint) (*models.Git
 	index := int(id - 1)
 	return repo.gitActionConfigs[index], nil
 }
+
+func (repo *GitActionConfigRepository) UpdateGitActionConfig(gac *models.GitActionConfig) error {
+	if !repo.canQuery {
+		return errors.New("Cannot write database")
+	}
+
+	if int(gac.ID-1) >= len(repo.gitActionConfigs) || repo.gitActionConfigs[gac.ID-1] == nil {
+		return gorm.ErrRecordNotFound
+	}
+
+	index := int(gac.ID - 1)
+	repo.gitActionConfigs[index] = gac
+	return nil
+}