Skip to content

Commit e43db33

Browse files
authored
implementation of backend based locks (#1524)
* implementation of backend based locks
1 parent 40a31d0 commit e43db33

File tree

13 files changed

+292
-62
lines changed

13 files changed

+292
-62
lines changed

backend/controllers/github.go

Lines changed: 89 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import (
55
"encoding/base64"
66
"encoding/json"
77
"fmt"
8+
"github.com/diggerhq/digger/backend/locking"
89
"github.com/diggerhq/digger/backend/segment"
910
"github.com/diggerhq/digger/backend/services"
1011
comment_updater "github.com/diggerhq/digger/libs/comment_utils/reporting"
12+
dg_locking "github.com/diggerhq/digger/libs/locking"
1113
orchestrator_scheduler "github.com/diggerhq/digger/libs/orchestrator/scheduler"
1214
"github.com/google/uuid"
1315
"log"
@@ -24,7 +26,7 @@ import (
2426
"github.com/diggerhq/digger/backend/models"
2527
"github.com/diggerhq/digger/backend/utils"
2628
dg_configuration "github.com/diggerhq/digger/libs/digger_config"
27-
orchestrator "github.com/diggerhq/digger/libs/orchestrator"
29+
"github.com/diggerhq/digger/libs/orchestrator"
2830
dg_github "github.com/diggerhq/digger/libs/orchestrator/github"
2931
"github.com/dominikbraun/graph"
3032
"github.com/gin-gonic/gin"
@@ -469,12 +471,45 @@ func handlePullRequestEvent(gh utils.GithubClientProvider, payload *github.PullR
469471
return nil
470472
}
471473

474+
diggerCommand, err := orchestrator.GetCommandFromJob(jobsForImpactedProjects[0])
475+
if err != nil {
476+
log.Printf("could not determine digger command from job: %v", jobsForImpactedProjects[0].Commands)
477+
utils.InitCommentReporter(ghService, prNumber, fmt.Sprintf(":x: could not determine digger command from job: %v", err))
478+
return fmt.Errorf("unkown digger command in comment %v", err)
479+
}
480+
472481
commentReporter, err := utils.InitCommentReporter(ghService, prNumber, ":construction_worker: Digger starting...")
473482
if err != nil {
474483
log.Printf("Error initializing comment reporter: %v", err)
475484
return fmt.Errorf("error initializing comment reporter")
476485
}
477486

487+
// perform locking/unlocking in backend
488+
for _, project := range impactedProjects {
489+
prLock := dg_locking.PullRequestLock{
490+
InternalLock: locking.BackendDBLock{
491+
OrgId: organisationId,
492+
},
493+
CIService: ghService,
494+
Reporter: comment_updater.NoopReporter{},
495+
ProjectName: project.Name,
496+
ProjectNamespace: repoFullName,
497+
PrNumber: prNumber,
498+
}
499+
err = PerformLockingActionFromCommand(prLock, *diggerCommand)
500+
if err != nil {
501+
utils.InitCommentReporter(ghService, prNumber, fmt.Sprintf(":x: Failed perform lock action on project: %v %v", project.Name, err))
502+
return fmt.Errorf("failed to perform lock action on project: %v, %v", project.Name, err)
503+
}
504+
}
505+
506+
// if commands are locking or unlocking we don't need to trigger any jobs
507+
if *diggerCommand == orchestrator.DiggerCommandUnlock ||
508+
*diggerCommand == orchestrator.DiggerCommandLock {
509+
utils.InitCommentReporter(ghService, prNumber, fmt.Sprintf(":white_check_mark: Command %v completed successfully", *diggerCommand))
510+
return nil
511+
}
512+
478513
err = utils.ReportInitialJobsStatus(commentReporter, jobsForImpactedProjects)
479514
if err != nil {
480515
log.Printf("Failed to comment initial status for jobs: %v", err)
@@ -499,7 +534,7 @@ func handlePullRequestEvent(gh utils.GithubClientProvider, payload *github.PullR
499534
impactedJobsMap[j.ProjectName] = j
500535
}
501536

502-
batchId, _, err := utils.ConvertJobsToDiggerJobs(orchestrator.DiggerCommandPlan, organisationId, impactedJobsMap, impactedProjectsMap, projectsGraph, installationId, *branch, prNumber, repoOwner, repoName, repoFullName, commentReporter.CommentId, diggerYmlStr)
537+
batchId, _, err := utils.ConvertJobsToDiggerJobs(*diggerCommand, organisationId, impactedJobsMap, impactedProjectsMap, projectsGraph, installationId, *branch, prNumber, repoOwner, repoName, repoFullName, commentReporter.CommentId, diggerYmlStr)
503538
if err != nil {
504539
log.Printf("ConvertJobsToDiggerJobs error: %v", err)
505540
utils.InitCommentReporter(ghService, prNumber, fmt.Sprintf(":x: ConvertJobsToDiggerJobs error: %v", err))
@@ -664,7 +699,7 @@ func handleIssueCommentEvent(gh utils.GithubClientProvider, payload *github.Issu
664699
}
665700

666701
if !config.AllowDraftPRs && isDraft {
667-
log.Printf("AllowDraftPRs is enabled, skipping PR: %v", issueNumber)
702+
log.Printf("AllowDraftPRs is disabled, skipping PR: %v", issueNumber)
668703
return nil
669704
}
670705

@@ -696,9 +731,30 @@ func handleIssueCommentEvent(gh utils.GithubClientProvider, payload *github.Issu
696731
}
697732
log.Printf("GitHub IssueComment event processed successfully\n")
698733

699-
if err != nil {
700-
log.Printf("GetGithubService error: %v", err)
701-
return fmt.Errorf("error getting github prservice")
734+
// perform unlocking in backend
735+
for _, project := range impactedProjects {
736+
prLock := dg_locking.PullRequestLock{
737+
InternalLock: locking.BackendDBLock{
738+
OrgId: orgId,
739+
},
740+
CIService: ghService,
741+
Reporter: comment_updater.NoopReporter{},
742+
ProjectName: project.Name,
743+
ProjectNamespace: repoFullName,
744+
PrNumber: issueNumber,
745+
}
746+
err = PerformLockingActionFromCommand(prLock, *diggerCommand)
747+
if err != nil {
748+
utils.InitCommentReporter(ghService, issueNumber, fmt.Sprintf(":x: Failed perform lock action on project: %v %v", project.Name, err))
749+
return fmt.Errorf("failed perform lock action on project: %v %v", project.Name, err)
750+
}
751+
}
752+
753+
// if commands are locking or unlocking we don't need to trigger any jobs
754+
if *diggerCommand == orchestrator.DiggerCommandUnlock ||
755+
*diggerCommand == orchestrator.DiggerCommandLock {
756+
utils.InitCommentReporter(ghService, issueNumber, fmt.Sprintf(":white_check_mark: Command %v completed successfully", *diggerCommand))
757+
return nil
702758
}
703759

704760
jobs, _, err := dg_github.ConvertGithubIssueCommentEventToJobs(payload, impactedProjects, requestedProject, config.Workflows, prBranchName)
@@ -787,6 +843,33 @@ func handleIssueCommentEvent(gh utils.GithubClientProvider, payload *github.Issu
787843
return nil
788844
}
789845

846+
func PerformLockingActionFromCommand(prLock dg_locking.PullRequestLock, command orchestrator.DiggerCommand) error {
847+
var err error
848+
switch command {
849+
case orchestrator.DiggerCommandUnlock:
850+
_, err = prLock.Unlock()
851+
if err != nil {
852+
err = fmt.Errorf("failed to unlock project: %v", err)
853+
}
854+
case orchestrator.DiggerCommandPlan:
855+
_, err = prLock.Lock()
856+
if err != nil {
857+
err = fmt.Errorf("failed to lock project: %v", err)
858+
}
859+
case orchestrator.DiggerCommandApply:
860+
_, err = prLock.Lock()
861+
if err != nil {
862+
err = fmt.Errorf("failed to lock project: %v", err)
863+
}
864+
case orchestrator.DiggerCommandLock:
865+
_, err = prLock.Lock()
866+
if err != nil {
867+
err = fmt.Errorf("failed to lock project: %v", err)
868+
}
869+
}
870+
return err
871+
}
872+
790873
func TriggerDiggerJobs(client *github.Client, repoOwner string, repoName string, batchId *uuid.UUID, prNumber int, prService *dg_github.GithubService) error {
791874
_, err := models.DB.GetDiggerBatch(batchId)
792875
if err != nil {

backend/controllers/locking.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package controllers

backend/go.mod

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ require (
1919
github.com/go-git/go-git/v5 v5.12.0
2020
github.com/golang-jwt/jwt v3.2.2+incompatible
2121
github.com/google/go-github/v61 v61.0.0
22-
github.com/google/go-github/v62 v62.0.0
2322
github.com/google/uuid v1.6.0
2423
github.com/migueleliasweb/go-github-mock v0.0.23
2524
github.com/robfig/cron v1.2.0
@@ -43,6 +42,10 @@ require (
4342
dario.cat/mergo v1.0.0 // indirect
4443
filippo.io/age v1.0.0 // indirect
4544
github.com/Azure/azure-sdk-for-go v63.3.0+incompatible // indirect
45+
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.0 // indirect
46+
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 // indirect
47+
github.com/Azure/azure-sdk-for-go/sdk/data/aztables v1.2.0 // indirect
48+
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect
4649
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
4750
github.com/Azure/go-autorest/autorest v0.11.26 // indirect
4851
github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect
@@ -53,6 +56,7 @@ require (
5356
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
5457
github.com/Azure/go-autorest/logger v0.2.1 // indirect
5558
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
59+
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
5660
github.com/Masterminds/semver/v3 v3.2.1 // indirect
5761
github.com/Microsoft/go-winio v0.6.1 // indirect
5862
github.com/ProtonMail/go-crypto v1.0.0 // indirect
@@ -63,18 +67,23 @@ require (
6367
github.com/armon/go-metrics v0.4.1 // indirect
6468
github.com/armon/go-radix v1.0.0 // indirect
6569
github.com/aws/aws-sdk-go v1.51.21 // indirect
66-
github.com/aws/aws-sdk-go-v2 v1.26.1 // indirect
67-
github.com/aws/aws-sdk-go-v2/config v1.27.12 // indirect
68-
github.com/aws/aws-sdk-go-v2/credentials v1.17.12 // indirect
69-
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 // indirect
70-
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 // indirect
71-
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 // indirect
70+
github.com/aws/aws-sdk-go-v2 v1.27.0 // indirect
71+
github.com/aws/aws-sdk-go-v2/config v1.27.16 // indirect
72+
github.com/aws/aws-sdk-go-v2/credentials v1.17.16 // indirect
73+
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.13.15 // indirect
74+
github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.7.15 // indirect
75+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.3 // indirect
76+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.7 // indirect
77+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.7 // indirect
7278
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
79+
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.32.1 // indirect
80+
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.20.5 // indirect
7381
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 // indirect
74-
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 // indirect
75-
github.com/aws/aws-sdk-go-v2/service/sso v1.20.6 // indirect
76-
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.5 // indirect
77-
github.com/aws/aws-sdk-go-v2/service/sts v1.28.7 // indirect
82+
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.9.6 // indirect
83+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.9 // indirect
84+
github.com/aws/aws-sdk-go-v2/service/sso v1.20.9 // indirect
85+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.3 // indirect
86+
github.com/aws/aws-sdk-go-v2/service/sts v1.28.10 // indirect
7887
github.com/aws/smithy-go v1.20.2 // indirect
7988
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
8089
github.com/blang/semver v3.5.1+incompatible // indirect
@@ -91,7 +100,6 @@ require (
91100
github.com/creack/pty v1.1.17 // indirect
92101
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
93102
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
94-
github.com/diggerhq/digger/cli v0.0.0-20240524095424-de040e7a4485 // indirect
95103
github.com/dimchansky/utfbom v1.1.1 // indirect
96104
github.com/dineshba/tf-summarize v0.3.10 // indirect
97105
github.com/emirpasic/gods v1.18.1 // indirect
@@ -111,6 +119,7 @@ require (
111119
github.com/go-sql-driver/mysql v1.7.0 // indirect
112120
github.com/goccy/go-json v0.10.2 // indirect
113121
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
122+
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
114123
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
115124
github.com/golang-sql/sqlexp v0.1.0 // indirect
116125
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
@@ -154,7 +163,7 @@ require (
154163
github.com/hashicorp/hcl/v2 v2.20.1 // indirect
155164
github.com/hashicorp/logutils v1.0.0 // indirect
156165
github.com/hashicorp/terraform v0.15.3 // indirect
157-
github.com/hashicorp/terraform-config-inspect v0.0.0-20231204233900-a34142ec2a72 // indirect
166+
github.com/hashicorp/terraform-config-inspect v0.0.0-20240509232506-4708120f8f30 // indirect
158167
github.com/hashicorp/terraform-json v0.22.1 // indirect
159168
github.com/hashicorp/terraform-registry-address v0.2.0 // indirect
160169
github.com/hashicorp/terraform-svchost v0.0.1 // indirect
@@ -176,6 +185,7 @@ require (
176185
github.com/kevinburke/ssh_config v1.2.0 // indirect
177186
github.com/klauspost/compress v1.17.7 // indirect
178187
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
188+
github.com/kylelemons/godebug v1.1.0 // indirect
179189
github.com/leodido/go-urn v1.4.0 // indirect
180190
github.com/lib/pq v1.10.9 // indirect
181191
github.com/m1gwings/treedrawer v0.3.3-beta // indirect
@@ -202,6 +212,7 @@ require (
202212
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
203213
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
204214
github.com/pjbgf/sha1cd v0.3.0 // indirect
215+
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
205216
github.com/pkg/errors v0.9.1 // indirect
206217
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
207218
github.com/posener/complete v1.2.3 // indirect
@@ -231,6 +242,7 @@ require (
231242
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
232243
github.com/wader/gormstore/v2 v2.0.3 // indirect
233244
github.com/xanzy/ssh-agent v0.3.3 // indirect
245+
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
234246
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
235247
github.com/zclconf/go-cty v1.14.4 // indirect
236248
github.com/zclconf/go-cty-yaml v1.0.3 // indirect

0 commit comments

Comments
 (0)