Skip to content
This repository has been archived by the owner on Aug 12, 2020. It is now read-only.

Commit

Permalink
Rewrite (#1)
Browse files Browse the repository at this point in the history
rewrite
  • Loading branch information
rajatjindal committed Oct 5, 2019
1 parent 49c9247 commit eb04c31
Show file tree
Hide file tree
Showing 11 changed files with 647 additions and 644 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v1
- name: Open PR for new release of Krew Plugin
uses: rajatjindal/[email protected].26
uses: rajatjindal/[email protected].27
with:
plugin-name: 'your-plugin-name'
upstream-krew-index-owner: 'kubernetes-sigs'
Expand Down
11 changes: 8 additions & 3 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ inputs:
description: 'plugin-name'
required: true
upstream-krew-index-owner:
description: 'the owner of upstream krew-index repo'
required: true
description: 'the owner of upstream krew-index repo. defaults to kubernetes-sigs'
required: false
upstream-krew-index-repo-name:
description: 'the owner of upstream krew-index repo. defaults to krew-index'
required: false
runs:
using: 'docker'
image: 'docker://rajatjindal/krew-plugin-release:v0.0.26'
image: 'docker://rajatjindal/krew-plugin-release:v0.0.27'
args:
- ${{ inputs.upstream-krew-index-owner }}
- ${{ inputs.upstream-krew-index-repo-name }}
- ${{ inputs.plugin-name }}

179 changes: 179 additions & 0 deletions cmd/helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package cmd

import (
"context"
"fmt"
"os"
"time"

"github.com/google/go-github/github"
"github.com/rajatjindal/krew-plugin-release/pkg/actions"
"github.com/sirupsen/logrus"
"golang.org/x/oauth2"
"gopkg.in/src-d/go-git.v4"
ugit "gopkg.in/src-d/go-git.v4"
"gopkg.in/src-d/go-git.v4/config"
"gopkg.in/src-d/go-git.v4/plumbing"
"gopkg.in/src-d/go-git.v4/plumbing/object"
"gopkg.in/src-d/go-git.v4/plumbing/transport"
githttp "gopkg.in/src-d/go-git.v4/plumbing/transport/http"
)

func cloneRepos(actionData actions.ActionData, dir string) (*ugit.Repository, error) {
logrus.Infof("Cloning %s", actionData.Derived.UpstreamCloneURL)
repo, err := ugit.PlainClone(dir, false, &ugit.CloneOptions{
URL: actionData.Derived.UpstreamCloneURL,
Progress: os.Stdout,
ReferenceName: plumbing.Master,
SingleBranch: true,
Auth: getAuth(actionData),
RemoteName: originNameUpstream,
})
if err != nil {
return nil, err
}

logrus.Infof("Adding remote %s at %s", originNameLocal, actionData.Derived.LocalCloneURL)
_, err = repo.CreateRemote(&config.RemoteConfig{
Name: originNameLocal,
URLs: []string{actionData.Derived.LocalCloneURL},
})
if err != nil {
return nil, err
}

logrus.Infof("creating branch %s", actionData.ReleaseInfo.GetTagName())
err = createBranch(repo, actionData.ReleaseInfo.GetTagName())
if err != nil {
return nil, err
}

return repo, nil
}

//createBranch creates branch
func createBranch(repo *ugit.Repository, branchName string) error {
w, err := repo.Worktree()
if err != nil {
return err
}

// First try to create branch
err = w.Checkout(&git.CheckoutOptions{
Create: true,
Force: false,
Branch: plumbing.NewBranchReferenceName(branchName),
})

if err == nil {
return nil
}

//may be it already exists
return w.Checkout(&git.CheckoutOptions{
Create: false,
Force: false,
Branch: plumbing.NewBranchReferenceName(branchName),
})
}

type commit struct {
msg string
remoteName string
}

//addCommitAndPush commits and push
func addCommitAndPush(repo *ugit.Repository, commit commit, actionData actions.ActionData) error {
w, err := repo.Worktree()
if err != nil {
return err
}

w.Add(".")
_, err = w.Commit(commit.msg, &git.CommitOptions{
Author: &object.Signature{
Name: actionData.Inputs.TokenUserName,
Email: actionData.Inputs.TokenUserEmail,
When: time.Now(),
},
})

return repo.Push(&ugit.PushOptions{
RemoteName: commit.remoteName,
RefSpecs: []config.RefSpec{config.DefaultPushRefSpec},
Auth: getAuth(actionData),
})
}

func submitPR(actionData actions.ActionData) error {
ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: actionData.Inputs.Token})
tc := oauth2.NewClient(context.TODO(), ts)
client := github.NewClient(tc)

prr := &github.NewPullRequest{
Title: getTitle(actionData),
Head: getHead(actionData),
Base: github.String("master"),
Body: getPRBody(actionData),
}

logrus.Infof("creating pr with title %q, \nhead %q, \nbase %q, \nbody %q",
github.Stringify(getTitle(actionData)),
github.Stringify(getHead(actionData)),
"master",
github.Stringify(getPRBody(actionData)),
)

pr, _, err := client.PullRequests.Create(
context.TODO(),
actionData.Inputs.UpstreamKrewIndexOwner,
actionData.Inputs.UpstreamKrewIndexRepoName,
prr,
)
if err != nil {
return err
}

logrus.Infof("pr %q opened for releasing new version", pr.GetHTMLURL())
return nil
}

func getTitle(actionData actions.ActionData) *string {
s := fmt.Sprintf(
"release new version %s of %s",
actionData.ReleaseInfo.GetTagName(),
actionData.Inputs.PluginName,
)

return github.String(s)
}

func getHead(actionData actions.ActionData) *string {
s := fmt.Sprintf("%s:%s", actionData.RepoOwner, actionData.ReleaseInfo.GetTagName())
return github.String(s)
}

func getPRBody(actionData actions.ActionData) *string {
prBody := `hey krew-index team,
I would like to open this PR to publish version %s of %s on behalf of [%s](https://github.com/%s).
Thanks,
[krew-plugin-release](https://github.com/rajatjindal/krew-plugin-release)`

s := fmt.Sprintf(prBody,
fmt.Sprintf("`%s`", actionData.ReleaseInfo.GetTagName()),
fmt.Sprintf("`%s`", actionData.Inputs.PluginName),
actionData.Actor,
actionData.Actor,
)

return github.String(s)
}

func getAuth(actionData actions.ActionData) transport.AuthMethod {
return &githttp.BasicAuth{
Username: actionData.Inputs.TokenUserHandle,
Password: actionData.Inputs.Token,
}
}
121 changes: 21 additions & 100 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,140 +1,77 @@
package cmd

import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"

"github.com/google/go-github/github"
"github.com/rajatjindal/krew-plugin-release/pkg/actions"
"github.com/rajatjindal/krew-plugin-release/pkg/git"
"github.com/rajatjindal/krew-plugin-release/pkg/krew"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"golang.org/x/oauth2"
ugit "gopkg.in/src-d/go-git.v4"
)

const prBody = `hey krew-index team,
I would like to open this PR to release new version %s of %s on behalf of %s.
Thanks,
[krew-plugin-release](https://github.com/rajatjindal/krew-plugin-release)`

type actionData struct {
pluginName string
tagName string
token string
localKrewIndexOwner string
localKrewIndexRepo string
localRemoteName string
upstreamKrewIndexRepo string
upstreamKrewIndexOwner string
upstreamRemoteName string
actor string
branchName string
}
const (
originNameUpstream = "upstream"
originNameLocal = "local"
)

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "krew-plugin-release",
Short: "github action to open PR for krew-index on release of new version of krew-plugin",
Run: func(cmd *cobra.Command, args []string) {
action := actions.RealAction{}

data := actionData{
pluginName: action.GetPluginName(),
token: os.Getenv("KREW_PLUGIN_RELEASE_TOKEN"),
upstreamKrewIndexOwner: action.GetInputForAction("upstream-krew-index-owner"),
localKrewIndexOwner: action.GetRepoOwner(),
localKrewIndexRepo: fmt.Sprintf("https://github.com/%s/krew-index.git", action.GetRepoOwner()),
upstreamKrewIndexRepo: fmt.Sprintf("https://github.com/%s/krew-index.git", action.GetInputForAction("upstream-krew-index-owner")),
localRemoteName: "local",
upstreamRemoteName: "upstream",
actor: action.GetActor(),
}

logrus.Info("reading release payload")
releaseInfo, err := actions.GetReleaseInfo(action)
actionData, err := action.GetActionData()
if err != nil {
logrus.Fatal(err)
}

if releaseInfo.GetPrerelease() {
logrus.Infof("%s is a pre-release. not opening the PR", releaseInfo.GetTagName())
logrus.Info(actionData.Inputs, actionData.Derived)
if actionData.ReleaseInfo.GetPrerelease() {
logrus.Infof("%s is a pre-release. not opening the PR", actionData.ReleaseInfo.GetTagName())
logrus.Exit(0)
}
data.tagName = releaseInfo.GetTagName()
data.branchName = releaseInfo.GetTagName()

dir, err := ioutil.TempDir("", "krew-index-")
tempdir, err := ioutil.TempDir("", "krew-index-")
if err != nil {
logrus.Fatal(err)
}

logrus.Infof("will operate in tempdir %s", dir)
repo, err := cloneRepos(data, dir)
if err != nil {
logrus.Fatal(err)
}

logrus.Infof("creating branch %s", releaseInfo.GetTagName())
err = git.CreateBranch(repo, releaseInfo.GetTagName())
logrus.Infof("will operate in tempdir %s", tempdir)
repo, err := cloneRepos(actionData, tempdir)
if err != nil {
logrus.Fatal(err)
}

logrus.Info("update plugin manifest with latest release info")

templateFile := filepath.Join(action.GetWorkspace(), ".krew.yaml")
actualFile := filepath.Join(dir, "plugins", krew.PluginFileName(data.pluginName))
err = krew.UpdatePluginManifest(templateFile, actualFile, releaseInfo)
templateFile := filepath.Join(actionData.Workspace, ".krew.yaml")
actualFile := filepath.Join(tempdir, "plugins", krew.PluginFileName(actionData.Inputs.PluginName))
err = krew.UpdatePluginManifest(templateFile, actualFile, actionData.ReleaseInfo)
if err != nil {
logrus.Fatal(err)
}

logrus.Infof("pushing changes to branch %s", data.tagName)
err = git.AddCommitAndPush(repo, fmt.Sprintf("new version of %s", data.pluginName), data.localRemoteName, data.tagName)
logrus.Infof("pushing changes to branch %s", actionData.ReleaseInfo.GetTagName())
commit := commit{
msg: fmt.Sprintf("new version %s of %s", actionData.ReleaseInfo.GetTagName(), actionData.Inputs.PluginName),
remoteName: originNameLocal,
}
err = addCommitAndPush(repo, commit, actionData)
if err != nil {
logrus.Fatal(err)
}

logrus.Info("submitting the pr")
err = submitPR(data)
err = submitPR(actionData)
if err != nil {
logrus.Fatal(err)
}
},
}

func stringp(s string) *string {
return &s
}

func submitPR(data actionData) error {
ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: os.Getenv("KREW_PLUGIN_RELEASE_TOKEN")})
tc := oauth2.NewClient(context.TODO(), ts)
client := github.NewClient(tc)

prr := &github.NewPullRequest{
Title: stringp(fmt.Sprintf("release new version %s of %s", data.tagName, data.pluginName)),
Head: stringp(fmt.Sprintf("%s:%s", data.localKrewIndexOwner, data.branchName)),
Base: stringp("master"),
Body: stringp(fmt.Sprintf(prBody, data.tagName, data.pluginName, data.actor)),
}

pr, _, err := client.PullRequests.Create(context.TODO(), data.upstreamKrewIndexOwner, "krew-index", prr)
if err != nil {
return err
}

logrus.Infof("pr %q opened for releasing new version", pr.GetHTMLURL())
return nil
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
Expand All @@ -143,19 +80,3 @@ func Execute() {
os.Exit(1)
}
}

func cloneRepos(data actionData, dir string) (*ugit.Repository, error) {
logrus.Infof("Cloning %s", data.upstreamKrewIndexRepo)
repo, err := git.Clone(data.upstreamKrewIndexRepo, data.upstreamRemoteName, git.GetMasterBranchRefs(), dir)
if err != nil {
return nil, err
}

logrus.Infof("Adding remote %s at %s", data.localRemoteName, data.localKrewIndexRepo)
_, err = git.AddUpstream(repo, data.localRemoteName, data.localKrewIndexRepo)
if err != nil {
return nil, err
}

return repo, nil
}
Loading

0 comments on commit eb04c31

Please sign in to comment.