Skip to content

Commit

Permalink
Support bump a non-preRelease version (#83)
Browse files Browse the repository at this point in the history
* Support bump a non-preRelease version

* Remove unused fields

* Setup the gidpod environment
  • Loading branch information
LinuxSuRen authored Apr 13, 2022
1 parent 6ad80da commit 90a51c5
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 28 deletions.
6 changes: 6 additions & 0 deletions .gitpod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
tasks:
- init: |
curl -L https://github.com/linuxsuren/http-downloader/releases/latest/download/hd-linux-amd64.tar.gz | tar xzv
git checkout README.md
sudo install hd /usr/bin
hd install upx
61 changes: 48 additions & 13 deletions controllers/releaser_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
"sigs.k8s.io/yaml"
"time"

"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
Expand All @@ -41,7 +40,6 @@ import (
type ReleaserReconciler struct {
logger logr.Logger
client.Client
Scheme *runtime.Scheme
GitCacheDir string

gitUser string
Expand Down Expand Up @@ -169,18 +167,41 @@ func (r *ReleaserReconciler) SetupWithManager(mgr ctrl.Manager) error {
Complete(r)
}

func (r *ReleaserReconciler) markAsDone(secret *v1.Secret, releaser *devopsv1alpha1.Releaser) (err error) {
gitOps := releaser.Spec.GitOps
if gitOps == nil || !gitOps.Enable {
releaser.Spec.Phase = devopsv1alpha1.PhaseDone
if err = r.Update(context.TODO(), releaser); err == nil {
nextReleaser := releaser.DeepCopy()
bumpReleaser(nextReleaser)
func (r *ReleaserReconciler) bumpResource(releaser *devopsv1alpha1.Releaser) (err error) {
ctx := context.Background()
releaser.Spec.Phase = devopsv1alpha1.PhaseDone
if err = r.Update(context.TODO(), releaser); err == nil {
nextReleaser := releaser.DeepCopy()
isPre := bumpReleaser(nextReleaser, true)

if err = r.Create(ctx, nextReleaser); err != nil {
err = fmt.Errorf("failed to create next releaser: %s, error: %v", nextReleaser.GetName(), err)
}

if err = r.Create(context.TODO(), nextReleaser); err != nil {
err = fmt.Errorf("failed to create next releaser: %s, error: %v", nextReleaser.GetName(), err)
if err == nil && isPre {
nextReleaserWithoutPre := releaser.DeepCopy()
bumpReleaser(nextReleaserWithoutPre, false)

err = r.Get(ctx, types.NamespacedName{
Namespace: nextReleaserWithoutPre.Namespace,
Name: nextReleaserWithoutPre.Name,
}, &devopsv1alpha1.Releaser{})
if err != nil {
if client.IgnoreNotFound(err) == nil {
if err = r.Create(ctx, nextReleaserWithoutPre); err != nil {
err = fmt.Errorf("failed to create next releaser: %s, error: %v", nextReleaserWithoutPre.GetName(), err)
}
}
}
}
}
return
}

func (r *ReleaserReconciler) markAsDone(secret *v1.Secret, releaser *devopsv1alpha1.Releaser) (err error) {
gitOps := releaser.Spec.GitOps
if gitOps == nil || !gitOps.Enable {
err = r.bumpResource(releaser)
return
}

Expand Down Expand Up @@ -219,7 +240,6 @@ func (r *ReleaserReconciler) markAsDone(secret *v1.Secret, releaser *devopsv1alp
copiedReleaser.ObjectMeta.ResourceVersion = ""
data, _ = yaml.Marshal(copiedReleaser)


r.logger.Info("start to commit phase to be done", "name", releaser.Name)
if err = saveAndPush(gitRepo, r.gitUser, currentReleaserPath, data, secret,
fmt.Sprintf("release %s", releaser.Name)); err != nil {
Expand All @@ -229,13 +249,28 @@ func (r *ReleaserReconciler) markAsDone(secret *v1.Secret, releaser *devopsv1alp

r.logger.Info("start to create next release file")
var bumpFilename string
if data, bumpFilename, err = bumpReleaserAsData(data); err != nil {
var isPre bool
if data, bumpFilename, isPre, err = bumpReleaserAsData(data, true); err != nil {
err = fmt.Errorf("failed to bump releaser: %s, error: %v", currentReleaserPath, err)
} else {
bumpFilePath := path.Join(path.Dir(currentReleaserPath), bumpFilename)
err = saveAndPush(gitRepo, r.gitUser, bumpFilePath, data, secret,
fmt.Sprintf("prepare the next release of %s", releaser.Name))
}

// try to prepare the next version which is not a preRlease
if err == nil && isPre {
if data, bumpFilename, _, err = bumpReleaserAsData(data, false); err != nil {
err = fmt.Errorf("failed to bump releaser: %s, error: %v", currentReleaserPath, err)
} else {
bumpFilePath := path.Join(path.Dir(currentReleaserPath), bumpFilename)
if ok, _ := PathExists(bumpFilePath); !ok {
err = saveAndPush(gitRepo, r.gitUser, bumpFilePath, data, secret,
fmt.Sprintf("prepare the next release of %s", releaser.Name))
}
}

}
return
}

Expand Down
93 changes: 93 additions & 0 deletions controllers/releaser_controller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package controllers

import (
"context"
"fmt"
"github.com/go-logr/logr"
devopsv1alpha1 "github.com/kubesphere-sigs/ks-releaser/api/v1alpha1"
"github.com/stretchr/testify/assert"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"testing"
)

func TestReleaserReconciler_bumpResource(t *testing.T) {
schema, err := devopsv1alpha1.SchemeBuilder.Register().Build()
assert.Nil(t, err)

defaultReleaser := &devopsv1alpha1.Releaser{
ObjectMeta: v1.ObjectMeta{
Namespace: "fake",
Name: "fake-v3.3.0-alpha.0",
ResourceVersion: "123",
},
Spec: devopsv1alpha1.ReleaserSpec{
Version: "v3.3.0-alpha.0",
},
}

type fields struct {
logger logr.Logger
Client client.Client
GitCacheDir string
gitUser string
}
type args struct {
releaser *devopsv1alpha1.Releaser
}
tests := []struct {
name string
fields fields
args args
wantErr assert.ErrorAssertionFunc
verify func(t *testing.T, Client client.Client)
}{{
name: "pre-release version",
fields: fields{
Client: fake.NewFakeClientWithScheme(schema, defaultReleaser.DeepCopy()),
},
args: args{
releaser: defaultReleaser.DeepCopy(),
},
wantErr: func(t assert.TestingT, err error, i ...interface{}) bool {
return false
},
verify: func(t *testing.T, Client client.Client) {
item := &devopsv1alpha1.Releaser{}
err := Client.Get(context.Background(), types.NamespacedName{
Namespace: "fake",
Name: "fake-v3.3.0-alpha.0",
}, item)
assert.Nil(t, err)
assert.Equal(t, devopsv1alpha1.PhaseDone, item.Spec.Phase)

err = Client.Get(context.Background(), types.NamespacedName{
Namespace: "fake",
Name: "fake-v3.3.0-alpha.1",
}, item)
assert.Nil(t, err)
assert.Equal(t, devopsv1alpha1.PhaseDraft, item.Spec.Phase)

err = Client.Get(context.Background(), types.NamespacedName{
Namespace: "fake",
Name: "fake-v3.3.0",
}, item)
assert.Nil(t, err)
assert.Equal(t, devopsv1alpha1.PhaseDraft, item.Spec.Phase)
},
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &ReleaserReconciler{
logger: tt.fields.logger,
Client: tt.fields.Client,
GitCacheDir: tt.fields.GitCacheDir,
gitUser: tt.fields.gitUser,
}
tt.wantErr(t, r.bumpResource(tt.args.releaser), fmt.Sprintf("bumpResource(%v)", tt.args.releaser))
tt.verify(t, tt.fields.Client)
})
}
}
34 changes: 23 additions & 11 deletions controllers/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func isPreRelease(versionStr string) bool {
return false
}

func bumpVersion(versionStr string) (nextVersion string, err error) {
func bumpVersionTo(versionStr string, remainPre bool) (nextVersion string, isPre bool, err error) {
nextVersion = versionStr // keep using the old version if there's any problem happened

var version semver.Version
Expand All @@ -25,12 +25,17 @@ func bumpVersion(versionStr string) (nextVersion string, err error) {
}

if preVersionCount := len(version.Pre); preVersionCount > 0 {
for i := preVersionCount - 1; i >= 0; i-- {
preVersion := &version.Pre[i]
if preVersion.IsNumeric() {
preVersion.VersionNum += 1
break
isPre = true
if remainPre {
for i := preVersionCount - 1; i >= 0; i-- {
preVersion := &version.Pre[i]
if preVersion.IsNumeric() {
preVersion.VersionNum += 1
break
}
}
} else {
version.Pre = nil
}
} else {
version.Patch += 1
Expand All @@ -43,9 +48,16 @@ func bumpVersion(versionStr string) (nextVersion string, err error) {
return
}

func bumpReleaser(releaser *devopsv1alpha1.Releaser) {
func bumpVersion(versionStr string) (nextVersion string, isPre bool, err error) {
nextVersion, isPre, err = bumpVersionTo(versionStr, true)
return
}

func bumpReleaser(releaser *devopsv1alpha1.Releaser, remainPre bool) (isPre bool) {
var nextVersion string

currentVersion := releaser.Spec.Version
nextVersion, _ := bumpVersion(currentVersion)
nextVersion, isPre, _ = bumpVersionTo(currentVersion, remainPre)
if strings.HasSuffix(releaser.Name, currentVersion) {
nameWithoutVersion := strings.ReplaceAll(releaser.Name, currentVersion, "")
releaser.Name = nameWithoutVersion + nextVersion
Expand All @@ -62,18 +74,18 @@ func bumpReleaser(releaser *devopsv1alpha1.Releaser) {

for i, _ := range releaser.Spec.Repositories {
repo := &releaser.Spec.Repositories[i]
repo.Version, _ = bumpVersion(repo.Version)
repo.Version, _, _ = bumpVersionTo(repo.Version, remainPre)
}

// remove status
releaser.Status = devopsv1alpha1.ReleaserStatus{}
return
}

func bumpReleaserAsData(data []byte) (result []byte, filename string, err error) {
func bumpReleaserAsData(data []byte, remainPre bool) (result []byte, filename string, isPre bool, err error) {
targetReleaser := &devopsv1alpha1.Releaser{}
if err = yaml.Unmarshal(data, targetReleaser); err == nil {
bumpReleaser(targetReleaser)
isPre = bumpReleaser(targetReleaser, remainPre)
filename = targetReleaser.Name + ".yaml"
result, err = yaml.Marshal(targetReleaser)
}
Expand Down
42 changes: 39 additions & 3 deletions controllers/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func TestVersionBump(t *testing.T) {
for i, _ := range testCases {
caseItem := testCases[i]

nextVersion, err := bumpVersion(caseItem.arg.version)
nextVersion, _, err := bumpVersion(caseItem.arg.version)
if caseItem.wantErr {
assert.NotNil(t, err, fmt.Sprintf("test failed with case[%d]", i))
}
Expand Down Expand Up @@ -137,7 +137,7 @@ func Test_bumpReleaser(t *testing.T) {
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
bumpReleaser(tt.args.releaser)
bumpReleaser(tt.args.releaser, true)
if !reflect.DeepEqual(tt.args.releaser, tt.wantResult) {
t.Errorf("bumpReleaser() gotResult = %v, want %v", tt.args.releaser, tt.wantResult)
}
Expand Down Expand Up @@ -180,7 +180,7 @@ status: {}
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotResult, _, err := bumpReleaserAsData([]byte(tt.args.data))
gotResult, _, _, err := bumpReleaserAsData([]byte(tt.args.data), true)
if (err != nil) != tt.wantErr {
t.Errorf("bumpReleaserAsData() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down Expand Up @@ -239,3 +239,39 @@ func Test_isPreRelease(t *testing.T) {
})
}
}

func Test_bumpVersionTo(t *testing.T) {
type testCase struct {
name string
arg struct {
version string
remainPre bool
}
wantErr bool
wantVersion string
}

testCases := []testCase{{
name: "version with rc tail",
arg: struct {
version string
remainPre bool
}{
version: "v1.2.0-rc.0",
remainPre: false,
},
wantErr: false,
wantVersion: "v1.2.0",
}}

for i, _ := range testCases {
caseItem := testCases[i]

nextVersion, _, err := bumpVersionTo(caseItem.arg.version, caseItem.arg.remainPre)
if caseItem.wantErr {
assert.NotNil(t, err, fmt.Sprintf("test failed with case[%d]", i))
}

assert.Equal(t, caseItem.wantVersion, nextVersion, fmt.Sprintf("test failed with case[%d]", i))
}
}
1 change: 0 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ func main() {

if err = (&controllers.ReleaserReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
GitCacheDir: "tmp",
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Releaser")
Expand Down

0 comments on commit 90a51c5

Please sign in to comment.