Skip to content

Commit

Permalink
Sync PR 2 (#14)
Browse files Browse the repository at this point in the history
Sync Changes from upstream


* Document APPROVER_GITHUB_APP_ID and APPROVER_GITHUB_APP_PRIVATE_KEY_PATH env vars (#189)
* Add a Target Description configuration keys to provide control over promotion PR titles (#191)
* Allow skipping upstream TLS server certificate validation for the webhook proxy functionality (#190)
  • Loading branch information
Oded-B authored Jun 19, 2024
1 parent 324e6b0 commit aa5f386
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 17 deletions.
15 changes: 12 additions & 3 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ Environment variables for the webhook process:

`APPROVER_GITHUB_OAUTH_TOKEN` GitHub OAuth token for automatically approving promotion PRs

`APPROVER_GITHUB_APP_ID` is an alternative to `APPROVER_GITHUB_OAUTH_TOKEN`. You can also use GitHub App style of authentication for the automated PR approval process. This variable supplies the Application ID.

`APPROVER_GITHUB_APP_PRIVATE_KEY_PATH` is an alternative to `APPROVER_GITHUB_OAUTH_TOKEN`. You can also use GitHub App style of authentication for the automated PR approval process. This variable supplies the path to the Github Application private key file (in `.pem` format).

`GITHUB_OAUTH_TOKEN` GitHub main OAuth token for all other GH operations

`GITHUB_HOST` Host name for github API, needed for Github Enterprise Server, should not include http scheme and path, e.g. :`my-gh-host.com`
Expand Down Expand Up @@ -114,9 +118,11 @@ Configuration keys:
|`promotionPaths[0].conditions.autoMerge`| Boolean value. If set to true, PR will be automatically merged after it is created.|
|`promotionPaths[0].promotionPrs`| Array of structures, each element represent a PR that will be opened when files are changed under `sourcePath`. Multiple elements means multiple PR will be opened|
|`promotionPaths[0].promotionPrs[0].targetPaths`| Array of strings, each element represent a directory to by synced from the changed component under `sourcePath`. Multiple elements means multiple directories will be synced in a PR|
|`promotionPaths[0].promotionPrs[0].targetDescription`| An optional string that describes the target paths, will be used in the promotion PR titles, for example "All Staging Clusters" or "Production Tier 2 Clusters". If this value is not provided Telefonistka will concatenate all `targetPaths` in the PR title which can make it very long and unreadable. Regardless of this configuration key, the PR titles will always start with the component name, e.g. `🚀 Promotion: nginx ➡️ Production Tier 2 Clusters` |
|`dryRunMode`| if true, the bot will just comment the planned promotion on the merged PR|
|`autoApprovePromotionPrs`| if true the bot will auto-approve all promotion PRs, with the assumption the original PR was peer reviewed and is promoted verbatim. Required additional GH token via APPROVER_GITHUB_OAUTH_TOKEN env variable|
|`toggleCommitStatus`| Map of strings, allow (non-repo-admin) users to change the [Github commit status](https://docs.github.com/en/rest/commits/statuses) state(from failure to success and back). This can be used to continue promotion of a change that doesn't pass repo checks. the keys are strings commented in the PRs, values are [Github commit status context](https://docs.github.com/en/rest/commits/statuses?apiVersion=2022-11-28#create-a-commit-status) to be overridden|
|`whProxtSkipTLSVerifyUpstream`| This disables upstream TLS server certificate validation for the webhook proxy functionality. Default is `false`. |
|`commentArgocdDiffonPR`| Uses ArgoCD API to calculate expected changes to k8s state and comment the resulting "diff" as comment in the PR. Requires ARGOCD_* environment variables, see below. |
|`autoMergeNoDiffPRs`| if true, Telefonistka will **merge** promotion PRs that are not expected to change the target clusters. Requires `commentArgocdDiffonPR` and possibly `autoApprovePromotionPrs`(depending on repo branch protection rules)|
|`useSHALabelForArgoDicovery`| The default method for discovering relevant ArgoCD applications (for a PR) relies on fetching all applications in the repo and checking the `argocd.argoproj.io/manifest-generate-paths` **annotation**, this might cause a performance issue on a repo with a large number of ArgoCD applications. The alternative is to add SHA1 of the application path as a **label** and rely on ArgoCD server-side filtering, label name is `telefonistka.io/component-path-sha1`.|
Expand All @@ -130,7 +136,8 @@ promotionPaths:
conditions:
autoMerge: true
promotionPrs:
- targetPaths:
- targetDescription: "All non-production clusters"
targetPaths:
- "clusters/dev/us-east4/c2"
- "clusters/lab/europe-west4/c1"
- "clusters/staging/us-central1/c1"
Expand All @@ -141,9 +148,11 @@ promotionPaths:
prHasLabels:
- "quick_promotion" # This flow will run only if PR has "quick_promotion" label, see targetPaths below
promotionPrs:
- targetPaths:
- targetDescription: "Production clusters tier 1"
targetPaths:
- "clusters/prod/us-west1/c2" # First PR for only a single cluster
- targetPaths:
- targetDescription: "Production clusters tier 2"
targetPaths:
- "clusters/prod/europe-west3/c2" # 2nd PR will sync all 4 remaining clusters
- "clusters/prod/europe-west4/c2"
- "clusters/prod/us-central1/c2"
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ go 1.22

toolchain go1.22.1

require github.com/alexliesenfeld/health v0.8.0

require (
github.com/alexliesenfeld/health v0.8.0
github.com/argoproj/argo-cd/v2 v2.11.2
github.com/argoproj/gitops-engine v0.7.1-0.20240416142647-fbecbb86e412
github.com/bradleyfalzon/ghinstallation/v2 v2.10.0
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
Expand Down Expand Up @@ -638,6 +639,7 @@ github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/alexliesenfeld/health v0.8.0 h1:lCV0i+ZJPTbqP7LfKG7p3qZBl5VhelwUFCIVWl77fgk=
github.com/alexliesenfeld/health v0.8.0/go.mod h1:TfNP0f+9WQVWMQRzvMUjlws4ceXKEL3WR+6Hp95HUFc=

github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk=
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
github.com/alicebob/miniredis/v2 v2.30.4 h1:8S4/o1/KoUArAGbGwPxcwf0krlzceva2XVOSchFS7Eo=
Expand Down Expand Up @@ -835,6 +837,7 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=

github.com/go-redis/cache/v9 v9.0.0 h1:0thdtFo0xJi0/WXbRVu8B066z8OvVymXTJGaXrVWnN0=
github.com/go-redis/cache/v9 v9.0.0/go.mod h1:cMwi1N8ASBOufbIvk7cdXe2PbPjK/WMRL95FFHWsSgI=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
Expand All @@ -850,6 +853,7 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I=
github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU=

github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
Expand Down Expand Up @@ -932,6 +936,7 @@ github.com/google/go-github/v62 v62.0.0 h1:/6mGCaRywZz9MuHyw9gD1CwsbmBX8GWsbFkwM
github.com/google/go-github/v62 v62.0.0/go.mod h1:EMxeUqGJq2xRu9DYBMwel/mr7kZrzUOfQmmpYrZn2a4=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=

github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
Expand Down Expand Up @@ -1086,6 +1091,7 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=

github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/migueleliasweb/go-github-mock v0.0.22 h1:iUvUKmYd7sFq/wrb9TrbEdvc30NaYxLZNtz7Uv2D+AQ=
github.com/migueleliasweb/go-github-mock v0.0.22/go.mod h1:UVvZ3S9IdTTRqThr1lgagVaua3Jl1bmY4E+C/Vybbn4=
Expand Down Expand Up @@ -1236,6 +1242,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=

github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
Expand Down Expand Up @@ -2023,6 +2030,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
21 changes: 12 additions & 9 deletions internal/pkg/configuration/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ type Condition struct {
}

type PromotionPr struct {
TargetPaths []string `yaml:"targetPaths"`
TargetDescription string `yaml:"targetDescription"`
TargetPaths []string `yaml:"targetPaths"`
}

type PromotionPath struct {
Expand All @@ -35,14 +36,16 @@ type Config struct {
PromotionPaths []PromotionPath `yaml:"promotionPaths"`

// Generic configuration
PromtionPrLables []string `yaml:"promtionPRlables"`
DryRunMode bool `yaml:"dryRunMode"`
AutoApprovePromotionPrs bool `yaml:"autoApprovePromotionPrs"`
ToggleCommitStatus map[string]string `yaml:"toggleCommitStatus"`
WebhookEndpointRegexs []WebhookEndpointRegex `yaml:"webhookEndpointRegexs"`
CommentArgocdDiffonPR bool `yaml:"commentArgocdDiffonPR"`
AutoMergeNoDiffPRs bool `yaml:"autoMergeNoDiffPRs"`
UseSHALabelForArgoDicovery bool `yaml:"useSHALabelForArgoDicovery"`

PromtionPrLables []string `yaml:"promtionPRlables"`
DryRunMode bool `yaml:"dryRunMode"`
AutoApprovePromotionPrs bool `yaml:"autoApprovePromotionPrs"`
ToggleCommitStatus map[string]string `yaml:"toggleCommitStatus"`
WebhookEndpointRegexs []WebhookEndpointRegex `yaml:"webhookEndpointRegexs"`
WhProxtSkipTLSVerifyUpstream bool `yaml:"whProxtSkipTLSVerifyUpstream"`
CommentArgocdDiffonPR bool `yaml:"commentArgocdDiffonPR"`
AutoMergeNoDiffPRs bool `yaml:"autoMergeNoDiffPRs"`
UseSHALabelForArgoDicovery bool `yaml:"useSHALabelForArgoDicovery"`
}

func ParseConfigFromYaml(y string) (*Config, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/githubapi/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ func handleMergedPrEvent(ghPrClientDetails GhPrClientDetails, prApproverGithubCl
}

components := strings.Join(promotion.Metadata.ComponentNames, ",")
newPrTitle := fmt.Sprintf("🚀 Promotion: %s ➡️ %s", components, strings.Join(promotion.Metadata.TargetPaths, " "))
newPrTitle := fmt.Sprintf("🚀 Promotion: %s ➡️ %s", components, promotion.Metadata.TargetDescription)

var originalPrAuthor string
// If the triggering PR was opened manually and it doesn't include in-body metadata, use the PR author
Expand Down
6 changes: 6 additions & 0 deletions internal/pkg/githubapi/promotion.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type PromotionInstance struct {
type PromotionInstanceMetaData struct {
SourcePath string
TargetPaths []string
TargetDescription string
PerComponentSkippedTargetPaths map[string][]string // ComponentName is the key,
ComponentNames []string
AutoMerge bool
Expand Down Expand Up @@ -121,6 +122,7 @@ func generateListOfRelevantComponents(ghPrClientDetails GhPrClientDetails, confi
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 nil, err
}
prFiles = append(prFiles, perPagePrFiles...)
Expand Down Expand Up @@ -208,9 +210,13 @@ func generatePlanBasedOnChangeddComponent(ghPrClientDetails GhPrClientDetails, c
mapKey := configPromotionPath.SourcePath + ">" + strings.Join(ppr.TargetPaths, "|") // This key is used to aggregate the PR based on source and target combination
if entry, ok := promotions[mapKey]; !ok {
ghPrClientDetails.PrLogger.Debugf("Adding key %s", mapKey)
if ppr.TargetDescription == "" {
ppr.TargetDescription = strings.Join(ppr.TargetPaths, " ")
}
promotions[mapKey] = PromotionInstance{
Metadata: PromotionInstanceMetaData{
TargetPaths: ppr.TargetPaths,
TargetDescription: ppr.TargetDescription,
SourcePath: componentToPromote.SourcePath,
ComponentNames: []string{componentToPromote.ComponentName},
PerComponentSkippedTargetPaths: map[string][]string{},
Expand Down
151 changes: 151 additions & 0 deletions internal/pkg/githubapi/promotion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,42 @@ import (
cfg "github.com/wayfair-incubator/telefonistka/internal/pkg/configuration"
)

func generatePromotionPlanMetadataTestHelper(t *testing.T, config *cfg.Config, expectedPromotion map[string]PromotionInstance, mockedHTTPClient *http.Client) {
t.Helper()
ctx := context.Background()
ghClientPair := GhClientPair{v3Client: github.NewClient(mockedHTTPClient)}
labelName := "fast-promotion"

ghPrClientDetails := GhPrClientDetails{
Ctx: ctx,
GhClientPair: &ghClientPair,
Owner: "AnOwner",
Repo: "Arepo",
PrNumber: 120,
Ref: "Abranch",
PrLogger: log.WithFields(log.Fields{
"repo": "AnOwner/Arepo",
"prNumber": 120,
}),
Labels: []*github.Label{
{Name: &labelName},
},
}

promotionPlan, err := GeneratePromotionPlan(ghPrClientDetails, config, "main")
if err != nil {
t.Fatalf("Failed to generate promotion plan: err=%s", err)
}

// Just check the metadata, this can ignore issues with promotion logic itself
// Like if a whole element is missing from the generated promotion plan.
for k, v := range expectedPromotion {
if diff := deep.Equal(v.Metadata, promotionPlan[k].Metadata); diff != nil {
t.Error(diff)
}
}
}

func generatePromotionPlanTestHelper(t *testing.T, config *cfg.Config, expectedPromotion map[string]PromotionInstance, mockedHTTPClient *http.Client) {
t.Helper()
ctx := context.Background()
Expand Down Expand Up @@ -533,3 +569,118 @@ func TestGeneratePromotionPlanWithPagination(t *testing.T) {
)
generatePromotionPlanTestHelper(t, config, expectedPromotion, mockedHTTPClient)
}

// TestGeneratePromotionMetadataWithOutDesc tests the case where the target description is set
func TestGeneratePromotionMetadataWithDesc(t *testing.T) {
t.Parallel()
config := &cfg.Config{
PromotionPaths: []cfg.PromotionPath{
{
SourcePath: "prod/us-east-4/",
PromotionPrs: []cfg.PromotionPr{
{
TargetDescription: "foobar2", // This is tested config key
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",
},
Metadata: PromotionInstanceMetaData{
SourcePath: "prod/us-east-4/",
TargetDescription: "foobar2", // This is tested config key
TargetPaths: []string{"prod/eu-east-1/", "prod/eu-west-1/"},
PerComponentSkippedTargetPaths: map[string][]string{},
ComponentNames: []string{"componentA"},
},
},
}
mockedHTTPClient := mock.NewMockedHTTPClient(
mock.WithRequestMatch(
mock.GetReposPullsFilesByOwnerByRepoByPullNumber,
[]github.CommitFile{
{Filename: github.String("prod/us-east-4/componentA/file.yaml")},
{Filename: github.String("prod/us-east-4/componentA/file2.yaml")},
{Filename: github.String("prod/us-east-4/componentA/aSubDir/file3.yaml")},
{Filename: github.String(".ci-config/random-file.json")},
},
),
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",
)
}),
),
)
generatePromotionPlanMetadataTestHelper(t, config, expectedPromotion, mockedHTTPClient)
}

// This test is similar to the previous one, but the TargetDescription is not set in the config
func TestGeneratePromotionMetadataWithOutDesc(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/",
}, // TargetDescription is not set in this case
},
},
},
},
}
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",
},
Metadata: PromotionInstanceMetaData{
SourcePath: "prod/us-east-4/",
TargetDescription: "prod/eu-east-1/ prod/eu-west-1/", // This is tested config key
TargetPaths: []string{"prod/eu-east-1/", "prod/eu-west-1/"},
PerComponentSkippedTargetPaths: map[string][]string{},
ComponentNames: []string{"componentA"},
},
},
}
mockedHTTPClient := mock.NewMockedHTTPClient(
mock.WithRequestMatch(
mock.GetReposPullsFilesByOwnerByRepoByPullNumber,
[]github.CommitFile{
{Filename: github.String("prod/us-east-4/componentA/file.yaml")},
{Filename: github.String("prod/us-east-4/componentA/file2.yaml")},
{Filename: github.String("prod/us-east-4/componentA/aSubDir/file3.yaml")},
{Filename: github.String(".ci-config/random-file.json")},
},
),
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",
)
}),
),
)
generatePromotionPlanMetadataTestHelper(t, config, expectedPromotion, mockedHTTPClient)
}
Loading

0 comments on commit aa5f386

Please sign in to comment.