diff --git a/.github/workflows/docker-publish-on-comment.yml b/.github/workflows/docker-publish-on-comment.yml index 50ea0bfd..c0f86e36 100644 --- a/.github/workflows/docker-publish-on-comment.yml +++ b/.github/workflows/docker-publish-on-comment.yml @@ -46,12 +46,12 @@ jobs: # Workaround: https://github.com/docker/build-push-action/issues/461 - name: Setup Docker buildx - uses: docker/setup-buildx-action@edfb0fe6204400c56fbfd3feba3fe9ad1adfa345 + uses: docker/setup-buildx-action@5138f76647652447004da686b2411557eaf65f33 # Login against a Docker registry except on PR # https://github.com/docker/login-action - name: Log into GH registry (ghcr.io) - uses: docker/login-action@3d58c274f17dffee475a5520cbe67f0a882c4dbb + uses: docker/login-action@70fccc794acd729b2b22dd6a326895f286447728 with: registry: ghcr.io username: ${{ github.actor }} @@ -59,7 +59,7 @@ jobs: - name: Log into Docker Hub registry if: env.DOCKERHUB_USERNAME != '' - uses: docker/login-action@3d58c274f17dffee475a5520cbe67f0a882c4dbb + uses: docker/login-action@70fccc794acd729b2b22dd6a326895f286447728 with: username: ${{ env.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} @@ -70,7 +70,7 @@ jobs: # 2nd image name is for DockerHub image - name: Extract Docker metadata id: meta - uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c + uses: docker/metadata-action@f7b4ed12385588c3f9bc252f0a2b520d83b52d48 with: context: git images: | @@ -85,7 +85,7 @@ jobs: # https://github.com/docker/build-push-action - name: Build and push Docker image id: build-and-push - uses: docker/build-push-action@9f6f8c940b91232557f8699b21341a08624a8dce + uses: docker/build-push-action@2a53c6ccda456d31fb62eedc658aae06e238b7bd with: context: . push: true @@ -96,7 +96,7 @@ jobs: - name: Extract Docker metadata - alpine id: meta-alpine - uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c + uses: docker/metadata-action@f7b4ed12385588c3f9bc252f0a2b520d83b52d48 with: context: git images: | @@ -108,7 +108,7 @@ jobs: flavor: prefix=alpine-,onlatest=true - name: Build and push Docker image - alpine id: build-and-push-alpine - uses: docker/build-push-action@9f6f8c940b91232557f8699b21341a08624a8dce + uses: docker/build-push-action@2a53c6ccda456d31fb62eedc658aae06e238b7bd with: context: . target: alpine-release diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 162cd9db..b11a375a 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -47,13 +47,13 @@ jobs: # Workaround: https://github.com/docker/build-push-action/issues/461 - name: Setup Docker buildx - uses: docker/setup-buildx-action@edfb0fe6204400c56fbfd3feba3fe9ad1adfa345 + uses: docker/setup-buildx-action@5138f76647652447004da686b2411557eaf65f33 # Login against a Docker registry except on PR # https://github.com/docker/login-action - name: Log into GH registry (ghcr.io) if: github.event_name != 'pull_request' - uses: docker/login-action@3d58c274f17dffee475a5520cbe67f0a882c4dbb + uses: docker/login-action@70fccc794acd729b2b22dd6a326895f286447728 with: registry: ghcr.io username: ${{ github.actor }} @@ -61,7 +61,7 @@ jobs: - name: Log into Docker Hub registry if: github.event_name != 'pull_request' && env.DOCKERHUB_USERNAME != '' - uses: docker/login-action@3d58c274f17dffee475a5520cbe67f0a882c4dbb + uses: docker/login-action@70fccc794acd729b2b22dd6a326895f286447728 with: username: ${{ env.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} @@ -72,7 +72,7 @@ jobs: # 2nd image name is for DockerHub image - name: Extract Docker metadata id: meta - uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c + uses: docker/metadata-action@f7b4ed12385588c3f9bc252f0a2b520d83b52d48 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} @@ -82,7 +82,7 @@ jobs: # https://github.com/docker/build-push-action - name: Build and push Docker image id: build-and-push - uses: docker/build-push-action@9f6f8c940b91232557f8699b21341a08624a8dce + uses: docker/build-push-action@2a53c6ccda456d31fb62eedc658aae06e238b7bd with: context: . push: ${{ github.event_name != 'pull_request' }} @@ -97,7 +97,7 @@ jobs: # 2nd image name is for DockerHub image - name: Extract Docker metadata - alpine id: meta-alpine - uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c + uses: docker/metadata-action@f7b4ed12385588c3f9bc252f0a2b520d83b52d48 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} @@ -107,7 +107,7 @@ jobs: # https://github.com/docker/build-push-action - name: Build and push Docker image - alpine id: build-and-push-alpine - uses: docker/build-push-action@9f6f8c940b91232557f8699b21341a08624a8dce + uses: docker/build-push-action@2a53c6ccda456d31fb62eedc658aae06e238b7bd with: context: . target: alpine-release diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 8edb4465..c011f0ce 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -35,7 +35,7 @@ jobs: go-version: 1.21 - uses: actions/checkout@v4 - name: golangci-lint - uses: golangci/golangci-lint-action@v4 + uses: golangci/golangci-lint-action@v6 with: # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version version: v1.57.2 diff --git a/Dockerfile b/Dockerfile index 636a31ec..9dd6a8c4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ -FROM golang:1.22.2 as test +FROM golang:1.22.3 as test ARG GOPROXY ENV GOPATH=/go ENV PATH="$PATH:$GOPATH/bin" diff --git a/internal/pkg/githubapi/clients.go b/internal/pkg/githubapi/clients.go index 2f46d4fb..a0bb9cbd 100644 --- a/internal/pkg/githubapi/clients.go +++ b/internal/pkg/githubapi/clients.go @@ -2,13 +2,14 @@ package githubapi import ( "context" + "fmt" "net/http" "os" "strconv" "time" "github.com/bradleyfalzon/ghinstallation/v2" - "github.com/google/go-github/v52/github" + "github.com/google/go-github/v62/github" lru "github.com/hashicorp/golang-lru/v2" "github.com/shurcooL/githubv4" log "github.com/sirupsen/logrus" @@ -41,25 +42,17 @@ func getAppInstallationId(githubAppPrivateKeyPath string, githubAppId int64, git if err != nil { panic(err) } - var tempClient *github.Client + tempClient := github.NewClient( + &http.Client{ + Transport: atr, + Timeout: time.Second * 30, + }) if githubRestAltURL != "" { - tempClient, err = github.NewEnterpriseClient( - githubRestAltURL, - githubRestAltURL, - &http.Client{ - Transport: atr, - Timeout: time.Second * 30, - }) + tempClient, err = tempClient.WithEnterpriseURLs(githubRestAltURL, githubRestAltURL) if err != nil { log.Fatalf("failed to create git client for app: %v\n", err) } - } else { - tempClient = github.NewClient( - &http.Client{ - Transport: atr, - Timeout: time.Second * 30, - }) } installations, _, err := tempClient.Apps.ListInstallations(ctx, &github.ListOptions{}) @@ -88,7 +81,7 @@ func createGithubAppRestClient(githubAppPrivateKeyPath string, githubAppId int64 if githubRestAltURL != "" { itr.BaseURL = githubRestAltURL - client, _ = github.NewEnterpriseClient(githubRestAltURL, githubRestAltURL, &http.Client{Transport: itr}) + client, _ = github.NewClient(&http.Client{Transport: itr}).WithEnterpriseURLs(githubRestAltURL, githubRestAltURL) } else { client = github.NewClient(&http.Client{Transport: itr}) } @@ -100,11 +93,9 @@ func createGithubRestClient(githubOauthToken string, githubRestAltURL string, ct &oauth2.Token{AccessToken: githubOauthToken}, ) tc := oauth2.NewClient(ctx, ts) - var client *github.Client + client := github.NewClient(tc) if githubRestAltURL != "" { - client, _ = github.NewEnterpriseClient(githubRestAltURL, githubRestAltURL, tc) - } else { - client = github.NewClient(tc) + client, _ = client.WithEnterpriseURLs(githubRestAltURL, githubRestAltURL) } return client @@ -147,8 +138,8 @@ func createGhAppClientPair(ctx context.Context, githubAppId int64, owner string, githubAppPrivateKeyPath := getCrucialEnv(ghAppPKeyPathEnvVarName) githubHost := getEnv("GITHUB_HOST", "") if githubHost != "" { - githubRestAltURL = "https://" + githubHost + "/api/v3" - githubGraphqlAltURL = "https://" + githubHost + "/api/graphql" + githubRestAltURL = fmt.Sprintf("https://%s/api/v3", githubHost) + githubGraphqlAltURL = fmt.Sprintf("https://%s/api/graphql", githubHost) log.Infof("Github REST API endpoint is configured to %s", githubRestAltURL) log.Infof("Github graphql API endpoint is configured to %s", githubGraphqlAltURL) } else { @@ -174,8 +165,8 @@ func createGhTokenClientPair(ctx context.Context, ghOauthToken string) GhClientP var githubGraphqlAltURL string githubHost := getEnv("GITHUB_HOST", "") if githubHost != "" { - githubRestAltURL = "https://" + githubHost + "/api/v3" - githubGraphqlAltURL = "https://" + githubHost + "/api/graphql" + githubRestAltURL = fmt.Sprintf("https://%s/api/v3", githubHost) + githubGraphqlAltURL = fmt.Sprintf("https://%s/api/graphql", githubHost) log.Infof("Github REST API endpoint is configured to %s", githubRestAltURL) log.Infof("Github graphql API endpoint is configured to %s", githubGraphqlAltURL) } else { diff --git a/internal/pkg/githubapi/drift_detection.go b/internal/pkg/githubapi/drift_detection.go index ee3a3dbd..8546f575 100644 --- a/internal/pkg/githubapi/drift_detection.go +++ b/internal/pkg/githubapi/drift_detection.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - "github.com/google/go-github/v52/github" + "github.com/google/go-github/v62/github" "github.com/hexops/gotextdiff" "github.com/hexops/gotextdiff/myers" "github.com/hexops/gotextdiff/span" diff --git a/internal/pkg/githubapi/drift_detection_test.go b/internal/pkg/githubapi/drift_detection_test.go index 54b84648..41c93677 100644 --- a/internal/pkg/githubapi/drift_detection_test.go +++ b/internal/pkg/githubapi/drift_detection_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/go-test/deep" - "github.com/google/go-github/v52/github" + "github.com/google/go-github/v62/github" "github.com/hexops/gotextdiff" "github.com/hexops/gotextdiff/myers" "github.com/hexops/gotextdiff/span" diff --git a/internal/pkg/githubapi/github.go b/internal/pkg/githubapi/github.go index 8d91a628..951e7ca0 100644 --- a/internal/pkg/githubapi/github.go +++ b/internal/pkg/githubapi/github.go @@ -3,7 +3,9 @@ package githubapi import ( "bytes" "context" + "crypto/sha1" //nolint:gosec // G505: Blocklisted import crypto/sha1: weak cryptographic primitive (gosec), this is not a cryptographic use case "encoding/base64" + "encoding/hex" "encoding/json" "fmt" "net/http" @@ -13,7 +15,8 @@ import ( "strings" "text/template" - "github.com/google/go-github/v52/github" + "github.com/cenkalti/backoff/v4" + "github.com/google/go-github/v62/github" lru "github.com/hashicorp/golang-lru/v2" log "github.com/sirupsen/logrus" "github.com/wayfair-incubator/telefonistka/internal/pkg/argocd" @@ -400,7 +403,7 @@ func handleMergedPrEvent(ghPrClientDetails GhPrClientDetails, prApproverGithubCl return err } - newBranchName := fmt.Sprintf("promotions/%v-%v-%v8", ghPrClientDetails.PrNumber, strings.Replace(ghPrClientDetails.Ref, "/", "-", -1), strings.Replace(strings.Join(promotion.Metadata.TargetPaths, "_"), "/", "-", -1)) // TODO max branch name length is 250 - make sure this fit + newBranchName := generateSafePromotionBranchName(ghPrClientDetails.PrNumber, ghPrClientDetails.Ref, promotion.Metadata.TargetPaths) newBranchRef, err := createBranch(ghPrClientDetails, commit, newBranchName) if err != nil { @@ -461,15 +464,60 @@ func handleMergedPrEvent(ghPrClientDetails GhPrClientDetails, prApproverGithubCl return nil } +// Creating a unique branch name based on the PR number, PR ref and the promotion target paths +// Max length of branch name is 250 characters +func generateSafePromotionBranchName(prNumber int, originalBranchName string, targetPaths []string) string { + targetPathsBa := []byte(strings.Join(targetPaths, "_")) + hasher := sha1.New() //nolint:gosec // G505: Blocklisted import crypto/sha1: weak cryptographic primitive (gosec), this is not a cryptographic use case + hasher.Write(targetPathsBa) + uniqBranchNameSuffix := firstN(hex.EncodeToString(hasher.Sum(nil)), 12) + safeOriginalBranchName := firstN(strings.Replace(originalBranchName, "/", "-", -1), 200) + return fmt.Sprintf("promotions/%v-%v-%v", prNumber, safeOriginalBranchName, uniqBranchNameSuffix) +} + +func firstN(str string, n int) string { + v := []rune(str) + if n >= len(v) { + return str + } + return string(v[:n]) +} + func MergePr(details GhPrClientDetails, number *int) error { - _, resp, err := details.GhClientPair.v3Client.PullRequests.Merge(details.Ctx, details.Owner, details.Repo, *number, "Auto-merge", nil) - prom.InstrumentGhCall(resp) + operation := func() error { + err := tryMergePR(details, number) + if err != nil { + if isMergeErrorRetryable(err.Error()) { + if err != nil { + details.PrLogger.Warnf("Failed to merge PR: transient err=%v", err) + } + return err + } + details.PrLogger.Errorf("Failed to merge PR: permanent err=%v", err) + return backoff.Permanent(err) + } + return nil + } + + // Using default values, see https://pkg.go.dev/github.com/cenkalti/backoff#pkg-constants + err := backoff.Retry(operation, backoff.NewExponentialBackOff()) if err != nil { - details.PrLogger.Errorf("Failed to merge PR: err=%v", err) + details.PrLogger.Errorf("Failed to merge PR: backoff err=%v", err) } + + return err +} + +func tryMergePR(details GhPrClientDetails, number *int) error { + _, resp, err := details.GhClientPair.v3Client.PullRequests.Merge(details.Ctx, details.Owner, details.Repo, *number, "Auto-merge", nil) + prom.InstrumentGhCall(resp) return err } +func isMergeErrorRetryable(errMessage string) bool { + return strings.Contains(errMessage, "405") && strings.Contains(errMessage, "try the merge again") +} + func (pm *prMetadata) DeSerialize(s string) error { decoded, err := base64.StdEncoding.DecodeString(s) if err != nil { @@ -759,7 +807,7 @@ func createCommit(ghPrClientDetails GhPrClientDetails, treeEntries []*github.Tre Tree: tree, } - commit, resp, err := ghPrClientDetails.GhClientPair.v3Client.Git.CreateCommit(ghPrClientDetails.Ctx, ghPrClientDetails.Owner, ghPrClientDetails.Repo, newCommitConfig) + commit, resp, err := ghPrClientDetails.GhClientPair.v3Client.Git.CreateCommit(ghPrClientDetails.Ctx, ghPrClientDetails.Owner, ghPrClientDetails.Repo, newCommitConfig, nil) prom.InstrumentGhCall(resp) if err != nil { ghPrClientDetails.PrLogger.Errorf("Failed to create Git commit: err=%s\n", err) // TODO comment this error to PR diff --git a/internal/pkg/githubapi/github_test.go b/internal/pkg/githubapi/github_test.go new file mode 100644 index 00000000..84b5c95a --- /dev/null +++ b/internal/pkg/githubapi/github_test.go @@ -0,0 +1,64 @@ +package githubapi + +import ( + "bytes" + "testing" +) + +func TestGenerateSafePromotionBranchName(t *testing.T) { + t.Parallel() + prNumber := 11 + originBranch := "originBranch" + targetPaths := []string{"targetPath1", "targetPath2"} + result := generateSafePromotionBranchName(prNumber, originBranch, targetPaths) + expectedResult := "promotions/11-originBranch-676f02019f18" + if result != expectedResult { + t.Errorf("Expected %s, got %s", expectedResult, result) + } +} + +// TestGenerateSafePromotionBranchNameLongBranchName tests the case where the original branch name is longer than 250 characters +func TestGenerateSafePromotionBranchNameLongBranchName(t *testing.T) { + t.Parallel() + prNumber := 11 + + originBranch := string(bytes.Repeat([]byte("originBranch"), 100)) + targetPaths := []string{"targetPath1", "targetPath2"} + result := generateSafePromotionBranchName(prNumber, originBranch, targetPaths) + if len(result) > 250 { + t.Errorf("Expected branch name to be less than 250 characters, got %d", len(result)) + } +} + +// TestGenerateSafePromotionBranchNameLongTargets tests the case where the target paths are longer than 250 characters +func TestGenerateSafePromotionBranchNameLongTargets(t *testing.T) { + t.Parallel() + prNumber := 11 + originBranch := "originBranch" + targetPaths := []string{ + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/1", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/2", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/3", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/4", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/5", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/6", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/7", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/8", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/9", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/10", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/11", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/12", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/13", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/14", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/15", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/16", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/17", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/18", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/19", + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/target/path/20", + } + result := generateSafePromotionBranchName(prNumber, originBranch, targetPaths) + if len(result) > 250 { + t.Errorf("Expected branch name to be less than 250 characters, got %d", len(result)) + } +} diff --git a/internal/pkg/githubapi/promotion.go b/internal/pkg/githubapi/promotion.go index 12878601..2d020dc3 100644 --- a/internal/pkg/githubapi/promotion.go +++ b/internal/pkg/githubapi/promotion.go @@ -6,7 +6,7 @@ import ( "sort" "strings" - "github.com/google/go-github/v52/github" + "github.com/google/go-github/v62/github" log "github.com/sirupsen/logrus" cfg "github.com/wayfair-incubator/telefonistka/internal/pkg/configuration" prom "github.com/wayfair-incubator/telefonistka/internal/pkg/prometheus" @@ -109,14 +109,26 @@ func getComponentConfig(ghPrClientDetails GhPrClientDetails, componentPath strin return componentConfig, nil } +<<<<<<< HEAD // This function generates a list of "components" that where changed in the PR and are relevant for promotion) func generateListOfRelevantComponents(ghPrClientDetails GhPrClientDetails, config *cfg.Config) (relevantComponents map[relevantComponent]struct{}, err error) { relevantComponents = make(map[relevantComponent]struct{}) - prFiles, resp, err := ghPrClientDetails.GhClientPair.v3Client.PullRequests.ListFiles(ghPrClientDetails.Ctx, ghPrClientDetails.Owner, ghPrClientDetails.Repo, ghPrClientDetails.PrNumber, &github.ListOptions{}) - prom.InstrumentGhCall(resp) - if err != nil { - ghPrClientDetails.PrLogger.Errorf("could not get file list from GH API: err=%s\nresponse=%v", err, resp) - return nil, err + //prFiles, resp, err := ghPrClientDetails.GhClientPair.v3Client.PullRequests.ListFiles(ghPrClientDetails.Ctx, ghPrClientDetails.Owner, ghPrClientDetails.Repo, ghPrClientDetails.PrNumber, &github.ListOptions{}) + + opts := &github.ListOptions{} + prFiles := []*github.CommitFile{} + for { + perPagePrFiles, resp, err := ghPrClientDetails.GhClientPair.v3Client.PullRequests.ListFiles(ghPrClientDetails.Ctx, ghPrClientDetails.Owner, ghPrClientDetails.Repo, ghPrClientDetails.PrNumber, opts) + prom.InstrumentGhCall(resp) + if err != nil { + ghPrClientDetails.PrLogger.Errorf("could not get file list from GH API: err=%s\nstatus code=%v", err, resp.Response.Status) + return promotions, err + } + prFiles = append(prFiles, perPagePrFiles...) + if resp.NextPage == 0 { + break + } + opts.Page = resp.NextPage } for _, changedFile := range prFiles { diff --git a/internal/pkg/githubapi/promotion_test.go b/internal/pkg/githubapi/promotion_test.go index 411171ac..081ecc8a 100644 --- a/internal/pkg/githubapi/promotion_test.go +++ b/internal/pkg/githubapi/promotion_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/go-test/deep" - "github.com/google/go-github/v52/github" + "github.com/google/go-github/v62/github" "github.com/migueleliasweb/go-github-mock/src/mock" log "github.com/sirupsen/logrus" cfg "github.com/wayfair-incubator/telefonistka/internal/pkg/configuration" @@ -481,3 +481,55 @@ func TestGenerateNestedSourceRegexPromotionPlan(t *testing.T) { ) generatePromotionPlanTestHelper(t, config, expectedPromotion, mockedHTTPClient) } + +func TestGeneratePromotionPlanWithPagination(t *testing.T) { + t.Parallel() + config := &cfg.Config{ + PromotionPaths: []cfg.PromotionPath{ + { + SourcePath: "prod/us-east-4/", + PromotionPrs: []cfg.PromotionPr{ + { + TargetPaths: []string{ + "prod/eu-west-1/", + "prod/eu-east-1/", + }, + }, + }, + }, + }, + } + expectedPromotion := map[string]PromotionInstance{ + "prod/us-east-4/>prod/eu-east-1/|prod/eu-west-1/": { + ComputedSyncPaths: map[string]string{ + "prod/eu-east-1/componentA": "prod/us-east-4/componentA", + "prod/eu-west-1/componentA": "prod/us-east-4/componentA", + }, + }, + } + // Note the "relevant" files are in the second page, to ensure pagination is working + mockedHTTPClient := mock.NewMockedHTTPClient( + mock.WithRequestMatchPages( + mock.GetReposPullsFilesByOwnerByRepoByPullNumber, + []github.CommitFile{ + {Filename: github.String(".ci-config/random-file.json")}, + {Filename: github.String(".ci-config/random-file2.json")}, + }, + []github.CommitFile{ + {Filename: github.String("prod/us-east-4/componentA/file.yaml")}, + {Filename: github.String("prod/us-east-4/componentA/file2.yaml")}, + }, + ), + mock.WithRequestMatchHandler( + mock.GetReposContentsByOwnerByRepoByPath, + http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mock.WriteError( + w, + http.StatusNotFound, + "no *optional* in-component telefonistka config file", + ) + }), + ), + ) + generatePromotionPlanTestHelper(t, config, expectedPromotion, mockedHTTPClient) +} diff --git a/internal/pkg/githubapi/webhook_proxy.go b/internal/pkg/githubapi/webhook_proxy.go index 33729f29..3008e951 100644 --- a/internal/pkg/githubapi/webhook_proxy.go +++ b/internal/pkg/githubapi/webhook_proxy.go @@ -9,7 +9,7 @@ import ( "regexp" "strings" - "github.com/google/go-github/v52/github" + "github.com/google/go-github/v62/github" log "github.com/sirupsen/logrus" "github.com/wayfair-incubator/telefonistka/internal/pkg/configuration" prom "github.com/wayfair-incubator/telefonistka/internal/pkg/prometheus" diff --git a/internal/pkg/githubapi/webhook_proxy_test.go b/internal/pkg/githubapi/webhook_proxy_test.go index 2bf0e867..b4523e78 100644 --- a/internal/pkg/githubapi/webhook_proxy_test.go +++ b/internal/pkg/githubapi/webhook_proxy_test.go @@ -9,7 +9,7 @@ import ( "testing" "github.com/go-test/deep" - "github.com/google/go-github/v52/github" + "github.com/google/go-github/v62/github" cfg "github.com/wayfair-incubator/telefonistka/internal/pkg/configuration" ) diff --git a/internal/pkg/prometheus/prometheus.go b/internal/pkg/prometheus/prometheus.go index 3ef4fc6c..6056d49d 100644 --- a/internal/pkg/prometheus/prometheus.go +++ b/internal/pkg/prometheus/prometheus.go @@ -5,7 +5,7 @@ import ( "strconv" "strings" - "github.com/google/go-github/v52/github" + "github.com/google/go-github/v62/github" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" ) diff --git a/internal/pkg/prometheus/prometheus_test.go b/internal/pkg/prometheus/prometheus_test.go index c35e8654..28cae930 100644 --- a/internal/pkg/prometheus/prometheus_test.go +++ b/internal/pkg/prometheus/prometheus_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/go-test/deep" - "github.com/google/go-github/v52/github" + "github.com/google/go-github/v62/github" "github.com/prometheus/client_golang/prometheus" )