feat: avoid pushing release branch only for rebasing (#114)

Right now releaser-pleaser pushes the branch even if it is only for a "rebase",
this wastes CI resources. Instead, it should only push when there are changes
to the files it owns.

- **Old**: Push when there is a diff origin/release-pr..release-pr
- **New**: Push when the these two diffs are not the same:
  
      origin/main..release-pr
      $(git merge-base origin/main origin/release-pr)..release-pr

Closes #92
This commit is contained in:
Julian Tölle 2025-06-09 10:52:09 +02:00 committed by GitHub
parent 175d6d0633
commit 81a855f5ab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 376 additions and 11 deletions

View file

@ -1,12 +1,15 @@
package git
import (
"context"
"reflect"
"strconv"
"testing"
"time"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/stretchr/testify/assert"
)
func TestAuthor_signature(t *testing.T) {
@ -44,3 +47,126 @@ func TestAuthor_String(t *testing.T) {
})
}
}
const testMainBranch = "main"
const testPRBranch = "releaser-pleaser"
func TestRepository_HasChangesWithRemote(t *testing.T) {
// go-git/v5 has a bug where it tries to delete the repo root dir (".") multiple times if there is no file left in it.
// this happens while switching branches in worktree.go rmFileAndDirsIfEmpty.
// TODO: Fix bug upstream
// For now I just make sure that there is always at least one file left in the dir by adding an empty "README.md" in the test util.
mainBranchRef := plumbing.NewBranchReferenceName(testMainBranch)
localPRBranchRef := plumbing.NewBranchReferenceName(testPRBranch)
remotePRBranchRef := plumbing.NewBranchReferenceName("remote/" + testPRBranch)
tests := []struct {
name string
repo TestRepo
want bool
wantErr assert.ErrorAssertionFunc
}{
{
name: "no remote pr branch",
repo: WithTestRepo(
WithCommit(
"chore: release v1.0.0",
WithFile("VERSION", "v1.0.0"),
),
WithCommit(
"chore: release v1.1.0",
OnBranch(mainBranchRef),
AsNewBranch(localPRBranchRef),
WithFile("VERSION", "v1.1.0"),
),
),
want: true,
wantErr: assert.NoError,
},
{
name: "remote pr branch matches local",
repo: WithTestRepo(
WithCommit(
"chore: release v1.0.0",
WithFile("VERSION", "v1.0.0"),
),
WithCommit(
"chore: release v1.1.0",
OnBranch(mainBranchRef),
AsNewBranch(remotePRBranchRef),
WithFile("VERSION", "v1.1.0"),
),
WithCommit(
"chore: release v1.1.0",
OnBranch(mainBranchRef),
AsNewBranch(localPRBranchRef),
WithFile("VERSION", "v1.1.0"),
),
),
want: false,
wantErr: assert.NoError,
},
{
name: "remote pr only needs rebase",
repo: WithTestRepo(
WithCommit(
"chore: release v1.0.0",
WithFile("VERSION", "v1.0.0"),
),
WithCommit(
"chore: release v1.1.0",
OnBranch(mainBranchRef),
AsNewBranch(remotePRBranchRef),
WithFile("VERSION", "v1.1.0"),
),
WithCommit(
"feat: new feature on remote",
OnBranch(mainBranchRef),
WithFile("feature", "yes"),
),
WithCommit(
"chore: release v1.1.0",
OnBranch(mainBranchRef),
AsNewBranch(localPRBranchRef),
WithFile("VERSION", "v1.1.0"),
),
),
want: false,
wantErr: assert.NoError,
},
{
name: "needs update",
repo: WithTestRepo(
WithCommit(
"chore: release v1.0.0",
WithFile("VERSION", "v1.0.0"),
),
WithCommit(
"chore: release v1.1.0",
OnBranch(mainBranchRef),
AsNewBranch(remotePRBranchRef),
WithFile("VERSION", "v1.1.0"),
),
WithCommit(
"chore: release v1.2.0",
OnBranch(mainBranchRef),
AsNewBranch(localPRBranchRef),
WithFile("VERSION", "v1.2.0"),
),
),
want: false,
wantErr: assert.NoError,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
repo := tt.repo(t)
got, err := repo.hasChangesWithRemote(context.Background(), mainBranchRef, localPRBranchRef, remotePRBranchRef)
if !tt.wantErr(t, err) {
return
}
assert.Equal(t, tt.want, got)
})
}
}