Skip to content

Commit

Permalink
Merge pull request #53 from rajatjindal/update
Browse files Browse the repository at this point in the history
Updates to krew-release-bot
  • Loading branch information
rajatjindal authored Mar 5, 2021
2 parents a222aab + 8bc65e9 commit a0fc101
Show file tree
Hide file tree
Showing 19 changed files with 94 additions and 143 deletions.
2 changes: 1 addition & 1 deletion .go-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.13.9
1.15.8
4 changes: 2 additions & 2 deletions action.Dockerfile → Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
FROM golang:1.13.4-alpine3.10 as builder
FROM golang:1.15.8-alpine3.13 as builder

WORKDIR /go/src/github.com/rajatjindal/krew-release-bot
COPY . .

RUN CGO_ENABLED=0 GOOS=linux go test -mod vendor ./... -cover
RUN CGO_ENABLED=0 GOOS=linux go build -mod vendor --ldflags "-s -w" -o krew-release-bot cmd/action/*

FROM alpine:3.10.3
FROM alpine:3.13.2

RUN mkdir -p /home/app

Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ $ docker run -v /path/to/your/template-file.yaml:/tmp/template-file.yaml rajatji
# Limitations of krew-release-bot
- only works for repos hosted on github right now
- The first version of plugin has to be submitted manually, by plugin author, to the krew-index repo
- The homepage in the plugin spec in krew-index is used to establish ownership. The repo from which the release is published should be the homepage of the plugin in already released plugin-spec.


# Kubernetes CLA
Expand Down
2 changes: 1 addition & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: 'krew-release-bot'
description: 'automatically opens PR for upstream krew-index repo when you publish new release of your awesome plugin'
runs:
using: 'docker'
image: 'docker://rajatjindal/krew-release-bot:v0.0.38'
image: 'docker://rajatjindal/krew-release-bot:v0.0.39'
inputs:
workdir:
description: 'Working directory, defaults to env.GITHUB_WORKSPACE'
Expand Down
11 changes: 1 addition & 10 deletions build-and-push.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,6 @@ if [ "$version" == "" ]; then
exit 1
fi

if [ "$PROJECT_ID" == "" ]; then
echo "cloud run project id not provided"
exit 1
fi

## push for github actions
docker build . -t rajatjindal/krew-release-bot:$version -f action.Dockerfile
docker build . -t rajatjindal/krew-release-bot:$version -f Dockerfile
docker push rajatjindal/krew-release-bot:$version

## push for cloud run
docker build . -t gcr.io/$PROJECT_ID/krew-release-bot:$version -f webhook.Dockerfile
docker push gcr.io/$PROJECT_ID/krew-release-bot:$version
4 changes: 2 additions & 2 deletions examples/circleci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ version: 2
jobs:
update-krew-index:
docker:
- image: circleci/golang:1.13
- image: circleci/golang:1.15
environment:

## KREW_RELEASE_BOT_WEBHOOK_URL env helps you test your setup without actually publishing to kubernetes-sigs/krew-index
## remove this env when you are ready for real release

KREW_RELEASE_BOT_WEBHOOK_URL: https://krew-release-bot-dryrun.rajatjindal.com/github-action-webhook
KREW_RELEASE_BOT_VERSION: v0.0.38
KREW_RELEASE_BOT_VERSION: v0.0.39
steps:
- checkout
- run: |
Expand Down
4 changes: 2 additions & 2 deletions examples/travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ env:
sudo: false

script:
- curl -LO https://github.com/rajatjindal/krew-release-bot/releases/download/v0.0.38/krew-release-bot_v0.0.38_linux_amd64.tar.gz
- tar -xvf krew-release-bot_v0.0.38_linux_amd64.tar.gz
- curl -LO https://github.com/rajatjindal/krew-release-bot/releases/download/v0.0.39/krew-release-bot_v0.0.38_linux_amd64.tar.gz
- tar -xvf krew-release-bot_v0.0.39_linux_amd64.tar.gz
- printenv && pwd && ls -ltr
- ./krew-release-bot action
19 changes: 0 additions & 19 deletions pkg/krew/validations.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,11 @@ package krew
import (
"bytes"
"fmt"
"strings"

"sigs.k8s.io/krew/pkg/index/indexscanner"
"sigs.k8s.io/krew/pkg/index/validation"
)

//ValidateOwnership validates the ownership of the plugin
func ValidateOwnership(file, expectedOwner string) error {
if expectedOwner == "" {
return fmt.Errorf("expectedOwner cannot be empty string")
}

plugin, err := indexscanner.ReadPluginFile(file)
if err != nil {
return err
}

if !strings.HasPrefix(plugin.Spec.Homepage, fmt.Sprintf("https://github.com/%s/", expectedOwner)) {
return fmt.Errorf("plugin homepage %s does not have prefix %s", plugin.Spec.Homepage, fmt.Sprintf("https://github.com/%s/", expectedOwner))
}

return nil
}

//ValidatePlugin validates the plugin spec
func ValidatePlugin(name, file string) error {
plugin, err := indexscanner.ReadPluginFile(file)
Expand Down
62 changes: 0 additions & 62 deletions pkg/krew/validations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,65 +55,3 @@ func TestGetPluginName(t *testing.T) {
})
}
}

func TestValidateOwnership(t *testing.T) {
testcases := []struct {
name string
file string
owner string
expectedError string
}{
{
name: "valid plugin file, owner is empty",
file: "data/valid-file.yaml",
owner: "",
expectedError: "expectedOwner cannot be empty string",
},
{
name: "valid plugin file, owner is incorrect",
file: "data/valid-file.yaml",
owner: "foo-bar",
expectedError: "plugin homepage https://github.com/rajatjindal/kubectl-whoami does not have prefix https://github.com/foo-bar/",
},
{
name: "valid plugin file, owner is substring of actual owner",
file: "data/valid-file.yaml",
owner: "rajatjin",
expectedError: "plugin homepage https://github.com/rajatjindal/kubectl-whoami does not have prefix https://github.com/rajatjin/",
},
{
name: "valid plugin file, owner is correct",
file: "data/valid-file.yaml",
owner: "rajatjindal",
},
{
name: "file does not exist",
file: "data/file-dont-exist.yaml",
owner: "rajatjindal",
expectedError: "open data/file-dont-exist.yaml: no such file or directory",
},
{
name: "invalid plugin file",
file: "data/invalid-plugin-file.yaml",
owner: "rajatjindal",
expectedError: "error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go value of type index.Plugin",
},
}

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
err := ValidateOwnership(tc.file, tc.owner)

if tc.expectedError != "" {
assert.NotNil(t, err)
if err != nil {
assert.Equal(t, tc.expectedError, err.Error())
}
}

if tc.expectedError == "" {
assert.Nil(t, err)
}
})
}
}
10 changes: 0 additions & 10 deletions pkg/releaser/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,7 @@ func (releaser *Releaser) Release(request *source.ReleaseRequest) (string, error
return "", err
}

logrus.Info("validating ownership")
existingIndexFile := filepath.Join(tempdir, "plugins", krew.PluginFileName(request.PluginName))
err = krew.ValidateOwnership(existingIndexFile, request.PluginOwner)
if err != nil {
if os.IsNotExist(err) {
return "", fmt.Errorf("plugin %q not found in existing repo. The first release of a new plugin has to be done manually", request.PluginName)
}

return "", fmt.Errorf("failed when validating ownership with error: %s", err.Error())
}

logrus.Info("update plugin manifest with latest release info")
err = krew.ValidatePlugin(request.PluginName, newIndexFile.Name())
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions pkg/source/actions/action_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func TestRunAction(t *testing.T) {
name: "no release info found for the tag",
setup: func() {
gock.New("https://api.github.com").
Times(4).
Get("/repos/foo-bar/my-awesome-plugin/releases/tags/v0.0.2").
Reply(404).
BodyString("no release with tag v0.0.2 found")
Expand Down Expand Up @@ -79,6 +80,7 @@ func TestRunAction(t *testing.T) {
BodyString(releaseWithAssets)

gock.New("https://github.com").
Times(4).
Get("/foo-bar/my-awesome-plugin/releases/download/v0.0.2/darwin-amd64-v0.0.2.tar.gz").
Reply(404).
BodyString("darwin-amd64-v0.0.2.tar.gz not found")
Expand Down Expand Up @@ -112,6 +114,7 @@ func TestRunAction(t *testing.T) {
Post("/github-action-webhook").
Reply(200).
JSON("PR https://github.com/kubernetes-sigs/krew-index/pull/26 opened successfully")

},
},
}
Expand Down
Binary file removed pkg/source/debug.test
Binary file not shown.
59 changes: 59 additions & 0 deletions pkg/source/http.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package source

// this is a very simplified version of https://github.com/hashicorp/go-retryablehttp
// reason we pulled in here is because we use gock for testing this tool, and gock does
// not work very well with go-retryablehttp as gock replaces transport required by go-retryablehttp

import (
"io"
"io/ioutil"
"math"
"net/http"
"time"
)

const (
maxRetries = 4
retryWaitMin = 2 * time.Second
retryWaitMax = 10 * time.Second
)

// getWithRetry is basically http.Get with retries
// we cannot use RoundTripper as gock (lib we use for testing)
// overrides the Transport and thus we cannot test our retryable transport
func getWithRetry(uri string) (*http.Response, error) {
var resp *http.Response
var err error

for i := 0; i < maxRetries; i++ {
resp, err = http.Get(uri)
shouldRetry := checkRetry(resp, err)
if !shouldRetry {
break
}

drainBody(resp.Body)
wait := backoff(retryWaitMin, retryWaitMax, i)
<-time.After(wait)
}

return resp, err
}

func checkRetry(resp *http.Response, err error) bool {
return resp.StatusCode == http.StatusNotFound
}

func drainBody(b io.ReadCloser) {
defer b.Close()
io.Copy(ioutil.Discard, io.LimitReader(b, int64(4096)))
}

func backoff(min, max time.Duration, attemptNum int) time.Duration {
mult := math.Pow(2, float64(attemptNum)) * float64(min)
sleep := time.Duration(mult)
if float64(sleep) != mult || sleep > max {
sleep = max
}
return sleep
}
4 changes: 3 additions & 1 deletion pkg/source/sha256.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import (
"github.com/sirupsen/logrus"
)

const retries = 4

//DownloadFileWithName downloads a file with name
func DownloadFileWithName(uri, name string) (string, error) {
resp, err := http.Get(uri)
resp, err := getWithRetry(uri)
if err != nil {
return "", err
}
Expand Down
18 changes: 18 additions & 0 deletions pkg/source/template_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package source

import (
"net/http"
"net/http/httptest"
"testing"

"io/ioutil"
Expand Down Expand Up @@ -95,3 +97,19 @@ func TestRenderTemplate(t *testing.T) {
})
}
}

func TestRenderTemplateRetry(t *testing.T) {
retries := 0
handler := http.NewServeMux()
handler.HandleFunc("/rajatjindal/kubectl-whoami/releases/download/v0.0.2/kubectl-whoami_v0.0.2_darwin_amd64.tar.gz", func(w http.ResponseWriter, r *http.Request) {
retries++
w.WriteHeader(http.StatusNotFound)
})

srv := httptest.NewServer(handler)
defer srv.Close()

_, err := DownloadFileWithName(srv.URL+"/rajatjindal/kubectl-whoami/releases/download/v0.0.2/kubectl-whoami_v0.0.2_darwin_amd64.tar.gz", "whoami")
assert.NotNil(t, err)
assert.Equal(t, 4, retries)
}
2 changes: 1 addition & 1 deletion template.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#! /bin/bash

VERSION=v0.0.38
VERSION=v0.0.39
docker run --rm -v `pwd`:/home/app rajatjindal/krew-release-bot:$VERSION krew-release-bot template
7 changes: 0 additions & 7 deletions update-deps.sh

This file was deleted.

2 changes: 1 addition & 1 deletion update-krew-index.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

export KREW_RELEASE_BOT_VERSION=v0.0.38
export KREW_RELEASE_BOT_VERSION=v0.0.39

curl -LO https://github.com/rajatjindal/krew-release-bot/releases/download/${KREW_RELEASE_BOT_VERSION}/krew-release-bot_${KREW_RELEASE_BOT_VERSION}_linux_amd64.tar.gz
tar -xvf krew-release-bot_${KREW_RELEASE_BOT_VERSION}_linux_amd64.tar.gz
Expand Down
23 changes: 0 additions & 23 deletions webhook.Dockerfile

This file was deleted.

0 comments on commit a0fc101

Please sign in to comment.