Fix issues

This commit is contained in:
2025-12-24 11:39:34 +03:00
parent dc05c68ee2
commit 56848c73fd
3 changed files with 101 additions and 31 deletions

View File

@@ -1,6 +1,7 @@
package main
import (
"fmt"
"log"
"os"
"strings"
@@ -8,6 +9,7 @@ import (
git "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
)
@@ -27,6 +29,22 @@ func normalizePath(p string) string {
return p
}
func pushRefSpec(headRef *plumbing.Reference) (config.RefSpec, error) {
if headRef == nil || !headRef.Name().IsBranch() {
return "", fmt.Errorf("cannot determine branch to push from HEAD")
}
branch := headRef.Name().String()
return config.RefSpec(branch + ":" + branch), nil
}
func signatureFromEnv() *object.Signature {
return &object.Signature{
Name: getenvDefault("GIT_USERNAME", "bumpversion"),
Email: getenvDefault("GIT_EMAIL", "bumpversion@deploy"),
When: time.Now().UTC(),
}
}
// gitCommit выполняет коммит с внесёнными изменениями
func gitCommit(bc *BumpConfig, newVersion string, configPath string) {
// Открываем локальный репозиторий (предполагается, что он существует в папке ".")
@@ -90,11 +108,7 @@ func gitCommit(bc *BumpConfig, newVersion string, configPath string) {
"{new_version}", newVersion,
).Replace(bc.Message)
author := &object.Signature{
Name: getenvDefault("GIT_USERNAME", "bumpversion"),
Email: getenvDefault("GIT_EMAIL", "bumpversion@deploy"),
When: time.Now().UTC(),
}
author := signatureFromEnv()
hash, err := worktree.Commit(commitMsg, &git.CommitOptions{
Author: author,
@@ -132,11 +146,7 @@ func gitTag(bc *BumpConfig, newVersion string) {
commitMsg = strings.ReplaceAll(commitMsg, "{new_version}", newVersion)
tagName := strings.ReplaceAll(bc.TagName, "{new_version}", newVersion)
_, err = repo.CreateTag(tagName, headRef.Hash(), &git.CreateTagOptions{
Tagger: &object.Signature{
Name: os.Getenv("GIT_USERNAME"),
Email: os.Getenv("GIT_EMAIL"),
When: time.Now(),
},
Tagger: signatureFromEnv(),
Message: commitMsg,
})
if err != nil {
@@ -154,12 +164,22 @@ func gitPush(bc *BumpConfig, newVersion string) {
tagName := strings.ReplaceAll(bc.TagName, "{new_version}", newVersion)
headRef, err := repo.Head()
if err != nil {
log.Fatalf("HEAD open error: %v", err)
}
branchSpec, err := pushRefSpec(headRef)
if err != nil {
log.Fatalf("Push branch detection error: %v", err)
}
// (Опционально) Выполняем push на удаленный репозиторий
tagSpec := config.RefSpec("refs/tags/" + tagName + ":refs/tags/" + tagName)
err = repo.Push(&git.PushOptions{
RemoteName: "origin",
RefSpecs: []config.RefSpec{
"refs/heads/master:refs/heads/master",
branchSpec,
tagSpec,
},
})

View File

@@ -6,6 +6,9 @@ import (
"reflect"
"strings"
"testing"
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
)
func TestGetBumpConfig(t *testing.T) {
@@ -129,6 +132,57 @@ func TestBumpVersionInvalidCurrent(t *testing.T) {
}
}
func TestBumpVersionMissingGroups(t *testing.T) {
bc := &BumpConfig{
CurrentVersion: "1.2.3",
Parse: `^(?P<major>\d+)\.(?P<minor>\d+)$`,
Serialize: "{major}.{minor}.{patch}",
}
if _, err := bumpVersion(bc, "patch"); err == nil {
t.Fatalf("expected error when parse pattern misses patch group")
}
}
func TestGetBumpConfigMissingFile(t *testing.T) {
tmpDir := t.TempDir()
if _, err := getBumpConfig(filepath.Join(tmpDir, "missing.cfg")); err == nil {
t.Fatalf("expected error for missing config file")
}
}
func TestSignatureFromEnvDefaults(t *testing.T) {
prevUser := os.Getenv("GIT_USERNAME")
prevEmail := os.Getenv("GIT_EMAIL")
t.Cleanup(func() {
_ = os.Setenv("GIT_USERNAME", prevUser)
_ = os.Setenv("GIT_EMAIL", prevEmail)
})
_ = os.Unsetenv("GIT_USERNAME")
_ = os.Unsetenv("GIT_EMAIL")
sig := signatureFromEnv()
if sig.Name != "bumpversion" || sig.Email != "bumpversion@deploy" {
t.Fatalf("signatureFromEnv defaults = %s %s, want bumpversion bumpversion@deploy", sig.Name, sig.Email)
}
}
func TestPushRefSpec(t *testing.T) {
head := plumbing.NewHashReference(plumbing.NewBranchReferenceName("main"), plumbing.ZeroHash)
spec, err := pushRefSpec(head)
if err != nil {
t.Fatalf("pushRefSpec returned error: %v", err)
}
want := config.RefSpec("refs/heads/main:refs/heads/main")
if spec != want {
t.Fatalf("pushRefSpec = %q, want %q", spec, want)
}
_, err = pushRefSpec(plumbing.NewHashReference(plumbing.HEAD, plumbing.ZeroHash))
if err == nil {
t.Fatalf("expected error for non-branch HEAD")
}
}
func TestUpdateFiles(t *testing.T) {
tmpDir := t.TempDir()
oldV := "1.2.3"
@@ -168,7 +222,7 @@ func TestResolveFlag(t *testing.T) {
negative *bool
defaultValue bool
want bool
wantPanic bool
wantErr bool
}{
{
name: "positive wins",
@@ -192,26 +246,21 @@ func TestResolveFlag(t *testing.T) {
want: true,
},
{
name: "panic on conflict",
name: "error on conflict",
positive: boolPtr(true),
negative: boolPtr(true),
defaultValue: false,
wantPanic: true,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
if r := recover(); tt.wantPanic && r == nil {
t.Fatalf("expected panic but function returned")
} else if !tt.wantPanic && r != nil {
t.Fatalf("unexpected panic: %v", r)
}
}()
got := resolveFlag(tt.positive, tt.negative, tt.defaultValue)
if tt.wantPanic {
got, err := resolveFlag(tt.positive, tt.negative, tt.defaultValue)
if (err != nil) != tt.wantErr {
t.Fatalf("resolveFlag error = %v, wantErr %v", err, tt.wantErr)
}
if tt.wantErr {
return
}
if got != tt.want {