|
|
|
@@ -27,7 +27,7 @@ import (
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/google/go-github/v86/github"
|
|
|
|
|
"github.com/google/go-github/v88/github"
|
|
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
|
"golang.org/x/oauth2"
|
|
|
|
|
|
|
|
|
@@ -123,7 +123,11 @@ func (c *client) Login(ctx context.Context, req *forge_types.OAuthRequest) (*mod
|
|
|
|
|
return nil, redirectURL, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client := c.newClientToken(ctx, token.AccessToken)
|
|
|
|
|
client, err := c.newClientToken(ctx, token.AccessToken)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, redirectURL, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
user, _, err := client.Users.Get(ctx, "")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, redirectURL, err
|
|
|
|
@@ -178,7 +182,10 @@ func (c *client) Refresh(ctx context.Context, user *model.User) (bool, error) {
|
|
|
|
|
|
|
|
|
|
// Teams returns a list of all team membership for the GitHub account.
|
|
|
|
|
func (c *client) Teams(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Team, error) {
|
|
|
|
|
client := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
client, err := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
list, _, err := client.Organizations.List(ctx, "", &github.ListOptions{
|
|
|
|
|
Page: p.Page,
|
|
|
|
@@ -192,7 +199,10 @@ func (c *client) Teams(ctx context.Context, u *model.User, p *model.ListOptions)
|
|
|
|
|
|
|
|
|
|
// Repo returns the GitHub repository.
|
|
|
|
|
func (c *client) Repo(ctx context.Context, u *model.User, id model.ForgeRemoteID, owner, name string) (*model.Repo, error) {
|
|
|
|
|
client := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
client, err := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if id.IsValid() {
|
|
|
|
|
intID, err := strconv.ParseInt(string(id), 10, 64)
|
|
|
|
@@ -227,7 +237,10 @@ func (c *client) Repos(ctx context.Context, u *model.User, p *model.ListOptions)
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
client, err := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
opts := new(github.RepositoryListByAuthenticatedUserOptions)
|
|
|
|
|
opts.PerPage = 100
|
|
|
|
@@ -252,7 +265,10 @@ func (c *client) Repos(ctx context.Context, u *model.User, p *model.ListOptions)
|
|
|
|
|
|
|
|
|
|
// File fetches the file from the GitHub repository and returns its contents.
|
|
|
|
|
func (c *client) File(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, f string) ([]byte, error) {
|
|
|
|
|
client := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
client, err := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
opts := new(github.RepositoryContentGetOptions)
|
|
|
|
|
opts.Ref = b.Commit
|
|
|
|
@@ -271,7 +287,10 @@ func (c *client) File(ctx context.Context, u *model.User, r *model.Repo, b *mode
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *client) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, f string) ([]*forge_types.FileMeta, error) {
|
|
|
|
|
client := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
client, err := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
opts := new(github.RepositoryContentGetOptions)
|
|
|
|
|
opts.Ref = b.Commit
|
|
|
|
@@ -322,7 +341,10 @@ func (c *client) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model
|
|
|
|
|
|
|
|
|
|
func (c *client) PullRequests(ctx context.Context, u *model.User, r *model.Repo, p *model.ListOptions) ([]*model.PullRequest, error) {
|
|
|
|
|
token := common.UserToken(ctx, r, u)
|
|
|
|
|
client := c.newClientToken(ctx, token)
|
|
|
|
|
client, err := c.newClientToken(ctx, token)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pullRequests, _, err := client.PullRequests.List(ctx, r.Owner, r.Name, &github.PullRequestListOptions{
|
|
|
|
|
ListOptions: github.ListOptions{
|
|
|
|
@@ -373,7 +395,10 @@ func (c *client) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
|
|
|
|
// Deactivate deactivates the repository be removing registered push hooks from
|
|
|
|
|
// the GitHub repository.
|
|
|
|
|
func (c *client) Deactivate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
|
|
|
|
client := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
client, err := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// make sure a repo rename does not trick us
|
|
|
|
|
forgeRepo, err := c.Repo(ctx, u, r.ForgeRemoteID, r.Owner, r.Name)
|
|
|
|
@@ -396,7 +421,10 @@ func (c *client) Deactivate(ctx context.Context, u *model.User, r *model.Repo, l
|
|
|
|
|
// OrgMembership returns if user is member of organization and if user
|
|
|
|
|
// is admin/owner in this organization.
|
|
|
|
|
func (c *client) OrgMembership(ctx context.Context, u *model.User, owner string) (*model.OrgPerm, error) {
|
|
|
|
|
client := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
client, err := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
org, _, err := client.Organizations.GetOrgMembership(ctx, u.Login, owner)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
@@ -406,7 +434,10 @@ func (c *client) OrgMembership(ctx context.Context, u *model.User, owner string)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *client) Org(ctx context.Context, u *model.User, owner string) (*model.Org, error) {
|
|
|
|
|
client := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
client, err := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
org, _, err := client.Organizations.Get(ctx, owner)
|
|
|
|
|
log.Trace().Msgf("GitHub organization for owner %s = %v", owner, org)
|
|
|
|
@@ -473,10 +504,10 @@ func (c *client) newConfig() *oauth2.Config {
|
|
|
|
|
|
|
|
|
|
// newClientToken returns the GitHub oauth2 client.
|
|
|
|
|
// It first checks if a client is available in the context, otherwise creates a new one.
|
|
|
|
|
func (c *client) newClientToken(ctx context.Context, token string) *github.Client {
|
|
|
|
|
func (c *client) newClientToken(ctx context.Context, token string) (*github.Client, error) {
|
|
|
|
|
// Check if a client is already in the context
|
|
|
|
|
if ctxClient, ok := ctx.Value(githubClientKey).(*github.Client); ok {
|
|
|
|
|
return ctxClient
|
|
|
|
|
return ctxClient, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ts := oauth2.StaticTokenSource(
|
|
|
|
@@ -499,9 +530,7 @@ func (c *client) newClientToken(ctx context.Context, token string) *github.Clien
|
|
|
|
|
// Wrap the base transport with User-Agent support
|
|
|
|
|
tp.Base = httputil.NewUserAgentRoundTripper(baseTransport, "forge-github")
|
|
|
|
|
|
|
|
|
|
client := github.NewClient(tc)
|
|
|
|
|
client.BaseURL, _ = url.Parse(c.API)
|
|
|
|
|
return client
|
|
|
|
|
return github.NewClient(github.WithURLs(github.Ptr(c.API), nil), github.WithHTTPClient(tc))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// matchingEmail returns matching user email.
|
|
|
|
@@ -545,7 +574,10 @@ var reDeploy = regexp.MustCompile(`.+/deployments/(\d+)`)
|
|
|
|
|
// Status sends the commit status to the forge.
|
|
|
|
|
// An example would be the GitHub pull request status.
|
|
|
|
|
func (c *client) Status(ctx context.Context, user *model.User, repo *model.Repo, pipeline *model.Pipeline, workflow *model.Workflow) error {
|
|
|
|
|
client := c.newClientToken(ctx, user.AccessToken)
|
|
|
|
|
client, err := c.newClientToken(ctx, user.AccessToken)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if pipeline.Event == model.EventDeploy {
|
|
|
|
|
// Get id from url. If not found, skip.
|
|
|
|
@@ -564,7 +596,7 @@ func (c *client) Status(ctx context.Context, user *model.User, repo *model.Repo,
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_, _, err := client.Repositories.CreateStatus(ctx, repo.Owner, repo.Name, pipeline.Commit, github.RepoStatus{
|
|
|
|
|
_, _, err = client.Repositories.CreateStatus(ctx, repo.Owner, repo.Name, pipeline.Commit, github.RepoStatus{
|
|
|
|
|
Context: github.Ptr(common.GetPipelineStatusContext(repo, pipeline, workflow)),
|
|
|
|
|
State: github.Ptr(convertStatus(workflow.State)),
|
|
|
|
|
Description: github.Ptr(common.GetPipelineStatusDescription(workflow.State)),
|
|
|
|
@@ -579,7 +611,10 @@ func (c *client) Activate(ctx context.Context, u *model.User, r *model.Repo, lin
|
|
|
|
|
if err := c.Deactivate(ctx, u, r, link); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
client := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
client, err := c.newClientToken(ctx, u.AccessToken)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
hook := &github.Hook{
|
|
|
|
|
Name: github.Ptr("web"),
|
|
|
|
|
Events: []string{
|
|
|
|
@@ -593,14 +628,17 @@ func (c *client) Activate(ctx context.Context, u *model.User, r *model.Repo, lin
|
|
|
|
|
ContentType: github.Ptr("form"),
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
_, _, err := client.Repositories.CreateHook(ctx, r.Owner, r.Name, hook)
|
|
|
|
|
_, _, err = client.Repositories.CreateHook(ctx, r.Owner, r.Name, hook)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Branches returns the names of all branches for the named repository.
|
|
|
|
|
func (c *client) Branches(ctx context.Context, u *model.User, r *model.Repo, p *model.ListOptions) ([]string, error) {
|
|
|
|
|
token := common.UserToken(ctx, r, u)
|
|
|
|
|
client := c.newClientToken(ctx, token)
|
|
|
|
|
client, err := c.newClientToken(ctx, token)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
githubBranches, _, err := client.Repositories.ListBranches(ctx, r.Owner, r.Name, &github.BranchListOptions{
|
|
|
|
|
ListOptions: github.ListOptions{
|
|
|
|
@@ -622,7 +660,11 @@ func (c *client) Branches(ctx context.Context, u *model.User, r *model.Repo, p *
|
|
|
|
|
// BranchHead returns the sha of the head (latest commit) of the specified branch.
|
|
|
|
|
func (c *client) BranchHead(ctx context.Context, u *model.User, r *model.Repo, branch string) (*model.Commit, error) {
|
|
|
|
|
token := common.UserToken(ctx, r, u)
|
|
|
|
|
b, _, err := c.newClientToken(ctx, token).Repositories.GetBranch(ctx, r.Owner, r.Name, branch, 1)
|
|
|
|
|
client, err := c.newClientToken(ctx, token)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
b, _, err := client.Repositories.GetBranch(ctx, r.Owner, r.Name, branch, 1)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@@ -687,7 +729,10 @@ func (c *client) loadChangedFilesFromPullRequest(ctx context.Context, pull *gith
|
|
|
|
|
// would fail with an authentication error.
|
|
|
|
|
forge.Refresh(ctx, c, _store, user)
|
|
|
|
|
|
|
|
|
|
gh := c.newClientToken(ctx, user.AccessToken)
|
|
|
|
|
gh, err := c.newClientToken(ctx, user.AccessToken)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
fileList := make([]string, 0, 16)
|
|
|
|
|
|
|
|
|
|
opts := &github.ListOptions{Page: 1}
|
|
|
|
@@ -730,7 +775,10 @@ func (c *client) getTagCommitSHA(ctx context.Context, repo *model.Repo, tagName
|
|
|
|
|
// would fail with an authentication error.
|
|
|
|
|
forge.Refresh(ctx, c, _store, user)
|
|
|
|
|
|
|
|
|
|
gh := c.newClientToken(ctx, user.AccessToken)
|
|
|
|
|
gh, err := c.newClientToken(ctx, user.AccessToken)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
page := 1
|
|
|
|
|
var tag *github.RepositoryTag
|
|
|
|
@@ -790,7 +838,10 @@ func (c *client) loadChangedFilesFromCommits(ctx context.Context, tmpRepo *model
|
|
|
|
|
// would fail with an authentication error.
|
|
|
|
|
forge.Refresh(ctx, c, _store, user)
|
|
|
|
|
|
|
|
|
|
gh := c.newClientToken(ctx, user.AccessToken)
|
|
|
|
|
gh, err := c.newClientToken(ctx, user.AccessToken)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
fileList := make([]string, 0, 16)
|
|
|
|
|
|
|
|
|
|
if prev == "" {
|
|
|
|
|