Skip to content

Commit

Permalink
Merge pull request #1 from ChrisStatham/APPSEC-1108
Browse files Browse the repository at this point in the history
Adding support to the GH API
  • Loading branch information
ChrisStatham authored Jul 17, 2024
2 parents cb65177 + 891b12d commit b4ed9a9
Show file tree
Hide file tree
Showing 7 changed files with 378 additions and 3 deletions.
3 changes: 3 additions & 0 deletions cmd/cmd-run.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Available values:
_ = cmd.RegisterFlagCompletionFunc("conflict-strategy", func(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return []string{"skip", "replace"}, cobra.ShellCompDirectiveNoFileComp
})
cmd.Flags().BoolP("use-gh-api", "", false, "Attempt to commit and push through the Github API, rather than pushing through the git client.")
cmd.Flags().StringSliceP("labels", "", nil, "Labels to be added to any created pull request.")
cmd.Flags().StringP("author-name", "", "", "Name of the committer. If not set, the global git config setting will be used.")
cmd.Flags().StringP("author-email", "", "", "Email of the committer. If not set, the global git config setting will be used.")
Expand Down Expand Up @@ -92,6 +93,7 @@ func run(cmd *cobra.Command, _ []string) error {
concurrent, _ := flag.GetInt("concurrent")
skipPullRequest, _ := flag.GetBool("skip-pr")
pushOnly, _ := flag.GetBool("push-only")
useGHAPI, _ := flag.GetBool("use-gh-api")
skipRepository, _ := flag.GetStringSlice("skip-repo")
interactive, _ := flag.GetBool("interactive")
dryRun, _ := flag.GetBool("dry-run")
Expand Down Expand Up @@ -241,6 +243,7 @@ func run(cmd *cobra.Command, _ []string) error {
ForkOwner: forkOwner,
SkipPullRequest: skipPullRequest,
PushOnly: pushOnly,
UseGHAPI: useGHAPI,
SkipRepository: skipRepository,
CommitAuthor: commitAuthor,
BaseBranch: baseBranchName,
Expand Down
12 changes: 12 additions & 0 deletions internal/git/cmdgit/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,15 @@ func (g *Git) AddRemote(name, url string) error {
_, err := g.run(cmd)
return err
}

func (g *Git) Additions() map[string]string {
return make(map[string]string)
}

func (g *Git) Deletions() []string {
return make([]string, 0)
}

func (g *Git) OldHash() string {
return ""
}
58 changes: 56 additions & 2 deletions internal/git/gogit/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package gogit
import (
"bytes"
"context"
"encoding/base64"
"os"
"time"

"github.com/go-git/go-git/v5/config"
Expand All @@ -22,6 +24,10 @@ type Git struct {
FetchDepth int // Limit fetching to the specified number of commits

repo *git.Repository // The repository after the clone has been made

additions map[string]string // Files being added (used for GHAPI)
deletions []string // Files being remove (used for GHAPI)
oldHash plumbing.Hash
}

// Clone a repository
Expand Down Expand Up @@ -75,6 +81,37 @@ func (g *Git) Changes() (bool, error) {
return !status.IsClean(), nil
}

func (g *Git) GetFileChangesAsBase64(w git.Worktree) error {
treeStatus, err := w.Status()

if err != nil {
return err
}

g.additions = make(map[string]string)

for path, status := range treeStatus {
s := status.Worktree

if s == git.Deleted || s == git.Renamed || s == git.Copied {
g.deletions = append(g.deletions, path)
} else if s == git.Added || s == git.Modified || s == git.Untracked {
data, err := os.ReadFile(g.Directory + "/" + path)

if err != nil {
return err
}

output := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
base64.StdEncoding.Encode(output, data)

g.additions[path] = string(output)
}
}

return nil
}

// Commit and push all changes
func (g *Git) Commit(commitAuthor *internalgit.CommitAuthor, commitMessage string) error {
w, err := g.repo.Worktree()
Expand All @@ -89,6 +126,11 @@ func (g *Git) Commit(commitAuthor *internalgit.CommitAuthor, commitMessage strin
}
w.Excludes = patterns

err = g.GetFileChangesAsBase64(*w)
if err != nil {
return err
}

err = w.AddWithOptions(&git.AddOptions{
All: true,
})
Expand Down Expand Up @@ -117,7 +159,7 @@ func (g *Git) Commit(commitAuthor *internalgit.CommitAuthor, commitMessage strin
if err != nil {
return err
}
oldHash := oldHead.Hash()
g.oldHash = oldHead.Hash()

var author *object.Signature
if commitAuthor != nil {
Expand All @@ -140,7 +182,7 @@ func (g *Git) Commit(commitAuthor *internalgit.CommitAuthor, commitMessage strin
return err
}

_ = g.logDiff(oldHash, commit.Hash)
_ = g.logDiff(g.oldHash, commit.Hash)

return nil
}
Expand Down Expand Up @@ -210,6 +252,18 @@ func (g *Git) Push(ctx context.Context, remoteName string, force bool) error {
})
}

func (g *Git) Additions() map[string]string {
return g.additions
}

func (g *Git) Deletions() []string {
return g.deletions
}

func (g *Git) OldHash() string {
return g.oldHash.String()
}

// AddRemote adds a new remote
func (g *Git) AddRemote(name, url string) error {
_, err := g.repo.CreateRemote(&config.RemoteConfig{
Expand Down
34 changes: 33 additions & 1 deletion internal/multigitter/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type Runner struct {
ForkOwner string // The owner of the new fork. If empty, the fork should happen on the logged in user

ConflictStrategy ConflictStrategy // Defines what will happen if a branch already exists
UseGHAPI bool

Draft bool // If set, creates Pull Requests as draft

Expand Down Expand Up @@ -338,7 +339,38 @@ func (r *Runner) runSingleRepo(ctx context.Context, repo scm.Repository) (scm.Pu

log.Info("Pushing changes to remote")
forcePush := featureBranchExist && r.ConflictStrategy == ConflictStrategyReplace
err = sourceController.Push(ctx, remoteName, forcePush)
if r.UseGHAPI {
if ghapi, ok := r.VersionController.(interface {
CommitAndPushThoughGraphQL(ctx context.Context,
headline string,
featureBranch string,
cloneURL string,
oldHash string,
additions map[string]string,
deletions []string,
forcePush bool,
branchExist bool) error
}); ok {
err = ghapi.CommitAndPushThoughGraphQL(ctx,
r.CommitMessage,
r.FeatureBranch,
repo.CloneURL(),
sourceController.OldHash(),
sourceController.Additions(),
sourceController.Deletions(),
forcePush,
featureBranchExist)
if err != nil {
return nil, err
}
} else {
log.Info("Could not find CommitThroughAPI, falling back on default push")
err = sourceController.Push(ctx, remoteName, forcePush)
}
} else {
err = sourceController.Push(ctx, remoteName, forcePush)
}

if err != nil {
return nil, errors.Wrap(err, "could not push changes")
}
Expand Down
3 changes: 3 additions & 0 deletions internal/multigitter/shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ type Git interface {
BranchExist(remoteName, branchName string) (bool, error)
Push(ctx context.Context, remoteName string, force bool) error
AddRemote(name, url string) error
Additions() map[string]string
Deletions() []string
OldHash() string
}

type stackTracer interface {
Expand Down
Loading

0 comments on commit b4ed9a9

Please sign in to comment.