Skip to content
This repository was archived by the owner on Jul 15, 2024. It is now read-only.

Commit 3083c51

Browse files
author
Fardin Khanjani
committed
feat: Add pull request support to SCM generator
This commit adds pull request support to SCM generator so the generator can create ArgoCD apps for PRs as well. Fixes #466 Signed-off-by: Fardin Khanjani <[email protected]>
1 parent 5787c33 commit 3083c51

File tree

7 files changed

+85
-12
lines changed

7 files changed

+85
-12
lines changed

api/v1alpha1/applicationset_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ type SCMProviderGeneratorGithub struct {
314314
TokenRef *SecretRef `json:"tokenRef,omitempty"`
315315
// Scan all branches instead of just the default branch.
316316
AllBranches bool `json:"allBranches,omitempty"`
317+
// Scan all pull requests
318+
AllPullRequests bool `json:"allPullRequests,omitempty"`
317319
}
318320

319321
// SCMProviderGeneratorGitlab defines a connection info specific to Gitlab.

manifests/crds/argoproj.io_applicationsets.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2714,6 +2714,8 @@ spec:
27142714
properties:
27152715
allBranches:
27162716
type: boolean
2717+
allPullRequests:
2718+
type: boolean
27172719
api:
27182720
type: string
27192721
organization:
@@ -4800,6 +4802,8 @@ spec:
48004802
properties:
48014803
allBranches:
48024804
type: boolean
4805+
allPullRequests:
4806+
type: boolean
48034807
api:
48044808
type: string
48054809
organization:
@@ -5707,6 +5711,8 @@ spec:
57075711
properties:
57085712
allBranches:
57095713
type: boolean
5714+
allPullRequests:
5715+
type: boolean
57105716
api:
57115717
type: string
57125718
organization:

manifests/install-with-argo-cd.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4531,6 +4531,8 @@ spec:
45314531
properties:
45324532
allBranches:
45334533
type: boolean
4534+
allPullRequests:
4535+
type: boolean
45344536
api:
45354537
type: string
45364538
organization:
@@ -6617,6 +6619,8 @@ spec:
66176619
properties:
66186620
allBranches:
66196621
type: boolean
6622+
allPullRequests:
6623+
type: boolean
66206624
api:
66216625
type: string
66226626
organization:
@@ -7524,6 +7528,8 @@ spec:
75247528
properties:
75257529
allBranches:
75267530
type: boolean
7531+
allPullRequests:
7532+
type: boolean
75277533
api:
75287534
type: string
75297535
organization:

manifests/install.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2713,6 +2713,8 @@ spec:
27132713
properties:
27142714
allBranches:
27152715
type: boolean
2716+
allPullRequests:
2717+
type: boolean
27162718
api:
27172719
type: string
27182720
organization:
@@ -4799,6 +4801,8 @@ spec:
47994801
properties:
48004802
allBranches:
48014803
type: boolean
4804+
allPullRequests:
4805+
type: boolean
48024806
api:
48034807
type: string
48044808
organization:
@@ -5706,6 +5710,8 @@ spec:
57065710
properties:
57075711
allBranches:
57085712
type: boolean
5713+
allPullRequests:
5714+
type: boolean
57095715
api:
57105716
type: string
57115717
organization:

pkg/generators/scm_provider.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha
6464
if err != nil {
6565
return nil, fmt.Errorf("error fetching Github token: %v", err)
6666
}
67-
provider, err = scm_provider.NewGithubProvider(ctx, providerConfig.Github.Organization, token, providerConfig.Github.API, providerConfig.Github.AllBranches)
67+
provider, err = scm_provider.NewGithubProvider(ctx, providerConfig.Github.Organization, token, providerConfig.Github.API, providerConfig.Github.AllBranches, providerConfig.Github.AllPullRequests)
6868
if err != nil {
6969
return nil, fmt.Errorf("error initializing Github service: %v", err)
7070
}

pkg/services/scm_provider/github.go

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,22 @@ import (
44
"context"
55
"fmt"
66
"os"
7+
"strconv"
78

89
"github.com/google/go-github/v35/github"
910
"golang.org/x/oauth2"
1011
)
1112

1213
type GithubProvider struct {
13-
client *github.Client
14-
organization string
15-
allBranches bool
14+
client *github.Client
15+
organization string
16+
allBranches bool
17+
allPullRequests bool
1618
}
1719

1820
var _ SCMProviderService = &GithubProvider{}
1921

20-
func NewGithubProvider(ctx context.Context, organization string, token string, url string, allBranches bool) (*GithubProvider, error) {
22+
func NewGithubProvider(ctx context.Context, organization string, token string, url string, allBranches bool, allPullRequests bool) (*GithubProvider, error) {
2123
var ts oauth2.TokenSource
2224
// Undocumented environment variable to set a default token, to be used in testing to dodge anonymous rate limits.
2325
if token == "" {
@@ -39,7 +41,8 @@ func NewGithubProvider(ctx context.Context, organization string, token string, u
3941
return nil, err
4042
}
4143
}
42-
return &GithubProvider{client: client, organization: organization, allBranches: allBranches}, nil
44+
45+
return &GithubProvider{client: client, organization: organization, allBranches: allBranches, allPullRequests: allPullRequests}, nil
4346
}
4447

4548
func (g *GithubProvider) ListRepos(ctx context.Context, cloneProtocol string) ([]*Repository, error) {
@@ -79,6 +82,24 @@ func (g *GithubProvider) ListRepos(ctx context.Context, cloneProtocol string) ([
7982
Labels: githubRepo.Topics,
8083
})
8184
}
85+
86+
if g.allPullRequests {
87+
pullRequests, err := g.listPullRequests(ctx, githubRepo)
88+
if err != nil {
89+
return nil, fmt.Errorf("error listing pull requests for %s/%s: %v", githubRepo.Owner.GetLogin(), githubRepo.GetName(), err)
90+
}
91+
92+
for _, pr := range pullRequests {
93+
repos = append(repos, &Repository{
94+
Organization: githubRepo.Owner.GetLogin(),
95+
Repository: githubRepo.GetName(),
96+
URL: url,
97+
Branch: strconv.FormatInt(int64(pr.GetNumber()), 10), // PR number is an int
98+
SHA: pr.GetHead().GetSHA(),
99+
Labels: githubRepo.Topics,
100+
})
101+
}
102+
}
82103
}
83104
if resp.NextPage == 0 {
84105
break
@@ -90,7 +111,7 @@ func (g *GithubProvider) ListRepos(ctx context.Context, cloneProtocol string) ([
90111

91112
func (g *GithubProvider) RepoHasPath(ctx context.Context, repo *Repository, path string) (bool, error) {
92113
_, _, resp, err := g.client.Repositories.GetContents(ctx, repo.Organization, repo.Repository, path, &github.RepositoryContentGetOptions{
93-
Ref: repo.Branch,
114+
Ref: repo.SHA,
94115
})
95116
// 404s are not an error here, just a normal false.
96117
if resp != nil && resp.StatusCode == 404 {
@@ -132,3 +153,29 @@ func (g *GithubProvider) listBranches(ctx context.Context, repo *github.Reposito
132153
}
133154
return branches, nil
134155
}
156+
157+
func (g *GithubProvider) listPullRequests(ctx context.Context, repo *github.Repository) ([]github.PullRequest, error) {
158+
opt := &github.PullRequestListOptions{
159+
ListOptions: github.ListOptions{PerPage: 100},
160+
}
161+
162+
pullRequests := []github.PullRequest{}
163+
164+
for {
165+
allPullRequests, resp, err := g.client.PullRequests.List(ctx, repo.Owner.GetLogin(), repo.GetName(), opt)
166+
if err != nil {
167+
return nil, err
168+
}
169+
170+
for _, pr := range allPullRequests {
171+
pullRequests = append(pullRequests, *pr)
172+
}
173+
174+
if resp.NextPage == 0 {
175+
break
176+
}
177+
opt.Page = resp.NextPage
178+
}
179+
180+
return pullRequests, nil
181+
}

pkg/services/scm_provider/github_test.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ func checkRateLimit(t *testing.T, err error) {
3535

3636
func TestGithubListRepos(t *testing.T) {
3737
cases := []struct {
38-
name, proto, url string
39-
hasError, allBranches bool
40-
branches []string
38+
name, proto, url string
39+
hasError, allBranches, allPullRequests bool
40+
branches []string
4141
}{
4242
{
4343
name: "blank protocol",
@@ -65,11 +65,17 @@ func TestGithubListRepos(t *testing.T) {
6565
url: "[email protected]:argoproj/applicationset.git",
6666
branches: []string{"master", "release-0.1.0"},
6767
},
68+
{
69+
name: "all pull requests",
70+
allPullRequests: true,
71+
url: "[email protected]:argoproj/applicationset.git",
72+
branches: []string{"pr-1", "pr-2"},
73+
},
6874
}
6975

7076
for _, c := range cases {
7177
t.Run(c.name, func(t *testing.T) {
72-
provider, _ := NewGithubProvider(context.Background(), "argoproj", "", "", c.allBranches)
78+
provider, _ := NewGithubProvider(context.Background(), "argoproj", "", "", c.allBranches, c.allPullRequests)
7379
rawRepos, err := provider.ListRepos(context.Background(), c.proto)
7480
if c.hasError {
7581
assert.NotNil(t, err)
@@ -96,7 +102,7 @@ func TestGithubListRepos(t *testing.T) {
96102
}
97103

98104
func TestGithubHasPath(t *testing.T) {
99-
host, _ := NewGithubProvider(context.Background(), "argoproj", "", "", false)
105+
host, _ := NewGithubProvider(context.Background(), "argoproj", "", "", false, false)
100106
repo := &Repository{
101107
Organization: "argoproj",
102108
Repository: "applicationset",

0 commit comments

Comments
 (0)