Skip to content

Instantly share code, notes, and snippets.

@Skarlso
Created May 24, 2022 17:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Skarlso/5d579d6e236a694b11dcf49b75201776 to your computer and use it in GitHub Desktop.
Save Skarlso/5d579d6e236a694b11dcf49b75201776 to your computer and use it in GitHub Desktop.
package main
import (
"context"
"fmt"
"io/ioutil"
"log"
"os"
"time"
"github.com/google/go-github/v43/github"
"golang.org/x/oauth2"
)
// Bundle performs the action which bundles together dependabot PRs.
func main() {
args := os.Args
if len(args) < 3 {
log.Fatal("Usage: script owner repo")
}
owner, repo := args[1], args[2]
// update here
token := os.Getenv("GITHUB_TOKEN")
ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: token},
)
tc := oauth2.NewClient(ctx, ts)
client := github.NewClient(tc)
branch, ref, err := getRef(client, owner, repo, "main")
if err != nil {
log.Fatal("failed to create ref: ", err)
}
if err := os.WriteFile("file.txt", []byte("garbage"), 0766); err != nil {
log.Fatal("failed to write file: ", err)
}
tree, err := getTree(client, owner, repo, []string{"file.txt"}, ref)
if err != nil {
log.Fatal("failed to get tree: ", err)
}
if err := pushCommit(client, ref, tree, repo, owner); err != nil {
log.Fatal("failed to push commit: ", err)
}
if _, err = createPR(client, branch, "main", "Description", "test PR", owner, repo); err != nil {
log.Fatal("failed to create PR: ", err)
}
fmt.Println("PR opened. Thank you for using Bundler, goodbye.")
}
func getRef(client *github.Client, owner, repo, targetBranch string) (branch string, ref *github.Reference, err error) {
var baseRef *github.Reference
if baseRef, _, err = client.Git.GetRef(context.Background(), owner, repo, "refs/heads/"+targetBranch); err != nil {
return "", nil, err
}
// random generate commit Branch
commitBranch := generateCommitBranch()
newRef := &github.Reference{Ref: github.String("refs/heads/" + commitBranch), Object: &github.GitObject{SHA: baseRef.Object.SHA}}
ref, _, err = client.Git.CreateRef(context.Background(), owner, repo, newRef)
return commitBranch, ref, err
}
func generateCommitBranch() string {
return fmt.Sprintf("bundler-%d", time.Now().UTC().Unix())
}
func getTree(client *github.Client, owner, repo string, files []string, ref *github.Reference) (*github.Tree, error) {
// Create a tree with what to commit.
var entries []*github.TreeEntry
for _, file := range files {
b, err := ioutil.ReadFile(file)
if err != nil {
return nil, err
}
entries = append(
entries,
&github.TreeEntry{
Path: github.String(file),
Type: github.String("blob"),
Content: github.String(string(b)),
Mode: github.String("100644"),
},
)
}
tree, _, err := client.Git.CreateTree(context.Background(), owner, repo, *ref.Object.SHA, entries)
return tree, err
}
// pushCommit creates the commit in the given reference using the given tree.
func pushCommit(client *github.Client, ref *github.Reference, tree *github.Tree, repo, owner string) (err error) {
// Get the parent commit to attach the commit to.
parent, _, err := client.Repositories.GetCommit(context.Background(), owner, repo, *ref.Object.SHA, nil)
if err != nil {
return err
}
// This is not always populated, but is needed.
parent.Commit.SHA = parent.SHA
// Create the commit using the tree.
date := time.Now()
commitMessage := "Bundling updated dependencies."
name := "Github Action"
email := "41898282+github-actions[bot]@users.noreply.github.com"
author := &github.CommitAuthor{Date: &date, Name: &name, Email: &email}
commit := &github.Commit{Author: author, Message: &commitMessage, Tree: tree, Parents: []*github.Commit{parent.Commit}}
newCommit, _, err := client.Git.CreateCommit(context.Background(), owner, repo, commit)
if err != nil {
return err
}
ref.Object.SHA = newCommit.SHA
_, _, err = client.Git.UpdateRef(context.Background(), owner, repo, ref, false)
return err
}
func createPR(client *github.Client, commitBranch, targetBranch, description, title, owner, repo string) (*int, error) {
newPR := &github.NewPullRequest{
Title: &title,
Head: &commitBranch,
Base: &targetBranch,
Body: &description,
MaintainerCanModify: github.Bool(true),
}
pr, _, err := client.PullRequests.Create(context.Background(), owner, repo, newPR)
if err != nil {
return nil, err
}
fmt.Printf("PR created: %s\n", pr.GetHTMLURL())
return pr.Number, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment