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