Skip to content

Commit cb4697c

Browse files
Merge pull request #7 from Harry-Moore-dev/dev
Improved handling multiple commits from the same checkout
2 parents f27071c + e61ad96 commit cb4697c

3 files changed

Lines changed: 179 additions & 139 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ Help Options:
2929

3030
```
3131
github-committer -r Harry-Moore-dev/github-committer -b branchname -m 'example commit' -p
32-
```
32+
```

gh-graphql.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"log"
6+
"strings"
7+
8+
"github.com/go-git/go-git/v5/plumbing"
9+
"github.com/shurcooL/githubv4"
10+
)
11+
12+
func DoCommit(ctx context.Context, client *githubv4.Client, changes *[]githubv4.FileAddition, opts Opts, revision *plumbing.Reference) error {
13+
var mutation struct {
14+
CreateCommitOnBranch struct {
15+
Commit struct {
16+
Url githubv4.ID
17+
}
18+
} `graphql:"createCommitOnBranch(input: $input)"`
19+
}
20+
input := githubv4.CreateCommitOnBranchInput{
21+
Branch: githubv4.CommittableBranch{
22+
RepositoryNameWithOwner: githubv4.NewString(githubv4.String(opts.Repository)),
23+
BranchName: githubv4.NewString(githubv4.String(opts.BranchName)),
24+
},
25+
Message: githubv4.CommitMessage{Headline: githubv4.String(opts.Message)},
26+
FileChanges: &githubv4.FileChanges{
27+
Additions: changes,
28+
},
29+
ExpectedHeadOid: githubv4.GitObjectID(revision.Hash().String()),
30+
}
31+
32+
err := client.Mutate(ctx, &mutation, input, nil)
33+
if err != nil {
34+
return err
35+
}
36+
log.Printf("mutation complete: %s", mutation.CreateCommitOnBranch.Commit.Url)
37+
return nil
38+
}
39+
40+
func CheckBranchExists(ctx context.Context, client *githubv4.Client, opts Opts) (bool, error) {
41+
var query struct {
42+
Repository struct {
43+
Ref struct {
44+
Name string
45+
} `graphql:"ref(qualifiedName: $branchName)"`
46+
} `graphql:"repository(owner: $owner, name: $name)"`
47+
}
48+
variables := map[string]interface{}{
49+
"owner": githubv4.String(strings.Split(opts.Repository, "/")[0]),
50+
"name": githubv4.String(strings.Split(opts.Repository, "/")[1]),
51+
"branchName": githubv4.String("refs/heads/" + opts.BranchName),
52+
}
53+
54+
err := client.Query(ctx, &query, variables)
55+
if err != nil {
56+
return false, err
57+
}
58+
59+
if query.Repository.Ref.Name != "" {
60+
log.Printf("branch found: %s", query.Repository.Ref.Name)
61+
return true, nil
62+
} else {
63+
log.Printf("a branch with the name %s was not found", opts.BranchName)
64+
return false, nil
65+
}
66+
}
67+
68+
func getMainOid(ctx context.Context, client *githubv4.Client, opts Opts) (githubv4.GitObjectID, githubv4.ID, error) {
69+
var query struct {
70+
Repository struct {
71+
ID githubv4.ID
72+
Ref struct {
73+
Target struct {
74+
Oid githubv4.GitObjectID
75+
}
76+
} `graphql:"ref(qualifiedName: \"refs/heads/main\")"`
77+
} `graphql:"repository(owner: $owner, name: $name)"`
78+
}
79+
variables := map[string]interface{}{
80+
"owner": githubv4.String(strings.Split(opts.Repository, "/")[0]),
81+
"name": githubv4.String(strings.Split(opts.Repository, "/")[1]),
82+
}
83+
84+
err := client.Query(ctx, &query, variables)
85+
if err != nil {
86+
return "", "", err
87+
}
88+
return query.Repository.Ref.Target.Oid, query.Repository.ID, nil
89+
}
90+
91+
func CreateBranch(ctx context.Context, client *githubv4.Client, opts Opts, repoId githubv4.ID, oid githubv4.GitObjectID) error {
92+
var mutation struct {
93+
CreateRef struct {
94+
ClientMutationID githubv4.String
95+
} `graphql:"createRef(input: $input)"`
96+
}
97+
input := githubv4.CreateRefInput{
98+
RepositoryID: repoId,
99+
Name: githubv4.String("refs/heads/" + opts.BranchName),
100+
Oid: oid,
101+
}
102+
103+
err := client.Mutate(ctx, &mutation, input, nil)
104+
if err != nil {
105+
return err
106+
}
107+
log.Printf("%s branch created\n", opts.BranchName)
108+
return nil
109+
}
110+
111+
func CreatePullRequest(ctx context.Context, client *githubv4.Client, opts Opts, repoId githubv4.ID) error {
112+
var mutation struct {
113+
CreatePullRequest struct {
114+
PullRequest struct {
115+
ID githubv4.ID
116+
}
117+
} `graphql:"createPullRequest(input: $input)"`
118+
}
119+
input := githubv4.CreatePullRequestInput{
120+
RepositoryID: repoId,
121+
BaseRefName: "main",
122+
HeadRefName: githubv4.String(opts.BranchName),
123+
Title: githubv4.String(opts.Message),
124+
}
125+
126+
err := client.Mutate(ctx, &mutation, input, nil)
127+
if err != nil {
128+
return err
129+
}
130+
log.Printf("pull request created %s\n", opts.BranchName)
131+
return nil
132+
}

main.go

Lines changed: 46 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"encoding/base64"
66
"log"
77
"os"
8-
"strings"
98

109
"github.com/go-git/go-git/v5"
1110
"github.com/go-git/go-git/v5/plumbing"
@@ -40,23 +39,11 @@ func main() {
4039
log.Fatal(err)
4140
}
4241

43-
repo, err := git.PlainOpen(".")
44-
if err != nil {
45-
log.Fatalf("unable to open repository: %s", err)
46-
}
47-
worktree, err := repo.Worktree()
48-
if err != nil {
49-
log.Fatalf("unable to open repository: %s", err)
50-
}
51-
revision, err := repo.Head()
52-
if err != nil {
53-
log.Fatalf("unable to find HEAD revision: %s", err)
54-
}
55-
status, err := worktree.Status()
42+
repo, status, err := openRepository()
5643
if err != nil {
5744
log.Fatalf("unable to open repository: %s", err)
5845
}
59-
changes := AddChanges(status)
46+
changes := addChanges(status)
6047

6148
client := createGhClient()
6249

@@ -70,11 +57,26 @@ func main() {
7057
log.Fatalf("unable to lookup branch: %s", err)
7158
}
7259

60+
var revision *plumbing.Reference
7361
if !branchExists {
7462
err = CreateBranch(ctx, client, opts, repoId, oid)
7563
if err != nil {
7664
log.Fatalf("unable to create branch: %s", err)
7765
}
66+
revision, err = repo.Head()
67+
if err != nil {
68+
log.Fatalf("unable to find HEAD revision: %s", err)
69+
}
70+
} else {
71+
err = fetchRemote(repo)
72+
if err != nil {
73+
log.Printf("unable to fetch remote: %s", err)
74+
}
75+
refName := plumbing.ReferenceName("refs/remotes/origin/" + opts.BranchName)
76+
revision, err = repo.Reference(refName, true)
77+
if err != nil {
78+
log.Fatalf("unable to find HEAD for branch %s: %s", opts.BranchName, err)
79+
}
7880
}
7981

8082
err = DoCommit(ctx, client, changes, opts, revision)
@@ -90,7 +92,35 @@ func main() {
9092
}
9193
}
9294

93-
func AddChanges(status git.Status) *[]githubv4.FileAddition {
95+
func openRepository() (*git.Repository, git.Status, error) {
96+
repo, err := git.PlainOpen(".")
97+
if err != nil {
98+
return nil, nil, err
99+
}
100+
worktree, err := repo.Worktree()
101+
if err != nil {
102+
return nil, nil, err
103+
}
104+
status, err := worktree.Status()
105+
if err != nil {
106+
return nil, nil, err
107+
}
108+
return repo, status, nil
109+
}
110+
111+
func fetchRemote(repo *git.Repository) error {
112+
remote, err := repo.Remote("origin")
113+
if err != nil {
114+
return err
115+
}
116+
err = remote.Fetch(&git.FetchOptions{})
117+
if err != nil {
118+
return err
119+
}
120+
return nil
121+
}
122+
123+
func addChanges(status git.Status) *[]githubv4.FileAddition {
94124
changes := &[]githubv4.FileAddition{}
95125
for name, status := range status {
96126
if status.Worktree == git.Modified || status.Staging == git.Added || status.Staging == git.Modified {
@@ -119,125 +149,3 @@ func createGhClient() *githubv4.Client {
119149
client := githubv4.NewClient(httpClient)
120150
return client
121151
}
122-
123-
func DoCommit(ctx context.Context, client *githubv4.Client, changes *[]githubv4.FileAddition, opts Opts, revision *plumbing.Reference) error {
124-
var mutation struct {
125-
CreateCommitOnBranch struct {
126-
Commit struct {
127-
Url githubv4.ID
128-
}
129-
} `graphql:"createCommitOnBranch(input: $input)"`
130-
}
131-
input := githubv4.CreateCommitOnBranchInput{
132-
Branch: githubv4.CommittableBranch{
133-
RepositoryNameWithOwner: githubv4.NewString(githubv4.String(opts.Repository)),
134-
BranchName: githubv4.NewString(githubv4.String(opts.BranchName)),
135-
},
136-
Message: githubv4.CommitMessage{Headline: githubv4.String(opts.Message)},
137-
FileChanges: &githubv4.FileChanges{
138-
Additions: changes,
139-
},
140-
ExpectedHeadOid: githubv4.GitObjectID(revision.Hash().String()),
141-
}
142-
143-
err := client.Mutate(ctx, &mutation, input, nil)
144-
if err != nil {
145-
return err
146-
}
147-
log.Printf("mutation complete: %s", mutation.CreateCommitOnBranch.Commit.Url)
148-
return nil
149-
}
150-
151-
func CheckBranchExists(ctx context.Context, client *githubv4.Client, opts Opts) (bool, error) {
152-
var query struct {
153-
Repository struct {
154-
Ref struct {
155-
Name string
156-
} `graphql:"ref(qualifiedName: $branchName)"`
157-
} `graphql:"repository(owner: $owner, name: $name)"`
158-
}
159-
variables := map[string]interface{}{
160-
"owner": githubv4.String(strings.Split(opts.Repository, "/")[0]),
161-
"name": githubv4.String(strings.Split(opts.Repository, "/")[1]),
162-
"branchName": githubv4.String("refs/heads/" + opts.BranchName),
163-
}
164-
165-
err := client.Query(ctx, &query, variables)
166-
if err != nil {
167-
return false, err
168-
}
169-
170-
if query.Repository.Ref.Name != "" {
171-
log.Printf("branch found: %s", query.Repository.Ref.Name)
172-
return true, nil
173-
} else {
174-
log.Printf("a branch with the name %s was not found", opts.BranchName)
175-
return false, nil
176-
}
177-
}
178-
179-
func getMainOid(ctx context.Context, client *githubv4.Client, opts Opts) (githubv4.GitObjectID, githubv4.ID, error) {
180-
var query struct {
181-
Repository struct {
182-
ID githubv4.ID
183-
Ref struct {
184-
Target struct {
185-
Oid githubv4.GitObjectID
186-
}
187-
} `graphql:"ref(qualifiedName: \"refs/heads/main\")"`
188-
} `graphql:"repository(owner: $owner, name: $name)"`
189-
}
190-
variables := map[string]interface{}{
191-
"owner": githubv4.String(strings.Split(opts.Repository, "/")[0]),
192-
"name": githubv4.String(strings.Split(opts.Repository, "/")[1]),
193-
}
194-
195-
err := client.Query(ctx, &query, variables)
196-
if err != nil {
197-
return "", "", err
198-
}
199-
return query.Repository.Ref.Target.Oid, query.Repository.ID, nil
200-
}
201-
202-
func CreateBranch(ctx context.Context, client *githubv4.Client, opts Opts, repoId githubv4.ID, oid githubv4.GitObjectID) error {
203-
var mutation struct {
204-
CreateRef struct {
205-
ClientMutationID githubv4.String
206-
} `graphql:"createRef(input: $input)"`
207-
}
208-
input := githubv4.CreateRefInput{
209-
RepositoryID: repoId,
210-
Name: githubv4.String("refs/heads/" + opts.BranchName),
211-
Oid: oid,
212-
}
213-
214-
err := client.Mutate(ctx, &mutation, input, nil)
215-
if err != nil {
216-
return err
217-
}
218-
log.Printf("%s branch created\n", opts.BranchName)
219-
return nil
220-
}
221-
222-
func CreatePullRequest(ctx context.Context, client *githubv4.Client, opts Opts, repoId githubv4.ID) error {
223-
var mutation struct {
224-
CreatePullRequest struct {
225-
PullRequest struct {
226-
ID githubv4.ID
227-
}
228-
} `graphql:"createPullRequest(input: $input)"`
229-
}
230-
input := githubv4.CreatePullRequestInput{
231-
RepositoryID: repoId,
232-
BaseRefName: "main",
233-
HeadRefName: githubv4.String(opts.BranchName),
234-
Title: githubv4.String(opts.Message),
235-
}
236-
237-
err := client.Mutate(ctx, &mutation, input, nil)
238-
if err != nil {
239-
return err
240-
}
241-
log.Printf("pull request created %s\n", opts.BranchName)
242-
return nil
243-
}

0 commit comments

Comments
 (0)