Skip to content

Commit

Permalink
fix(config): handle relative git repos (#4575)
Browse files Browse the repository at this point in the history
## If applied, this commit will...

If applied this change will allow goreleaser to handle relative remotes
when attempting to parse a repo URL from git.

## Why is this change being made? 

To fix the error that I recently came across while trying to test my
goreleaser configuration:

```
% goreleaser check
  • checking                                 path=
  ⨯ configuration is invalid                 error=invalid scm url: .
  ⨯ .goreleaser.yml                                  error=configuration is invalid: invalid scm url: .
  ⨯ command failed                                   error=1 out of 1 configuration file(s) have issues
```

This change happened while on a branch doing some development. As part
of that development I needed to test a change to my goreleaser config.

My git config at the time looked like (repo obfuscated):

```
% cat .git/config
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        url = git@gitlab.com:some/repo
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
        remote = origin
        merge = refs/heads/main
[branch "release_fixes"]
        remote = .
        merge = refs/heads/main
```

It is fairly common for git to add remotes with a `.` when branch
tracking is enabled.

While, in general, there aren't many use cases that require a user to
need to release from a non-primary branch, there are cases where the
user may want to test their configuration with `goreleaser check` and
the error of `invalid scm url: .` isn't very helpful.

---------

Co-authored-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
  • Loading branch information
aauren and caarlos0 committed Jan 29, 2024
1 parent a4ecc87 commit 917cae5
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
20 changes: 20 additions & 0 deletions internal/git/config.go
Expand Up @@ -21,10 +21,30 @@ func ExtractRepoFromConfig(ctx context.Context) (result config.Repo, err error)
if err != nil {
return result, fmt.Errorf("no remote configured to list refs from")
}
// This is a relative remote URL and requires some additional processing
if out == "." {
return extractRelativeRepoFromConfig(ctx)
}
log.WithField("rawurl", out).Debugf("got git url")
return ExtractRepoFromURL(out)
}

func extractRelativeRepoFromConfig(ctx context.Context) (result config.Repo, err error) {
out, err := Clean(Run(ctx, "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"))
if err != nil || out == "" {
return result, fmt.Errorf("unable to get upstream while qualifying relative remote")
}
out, err = Clean(Run(ctx, "config", "--get", fmt.Sprintf("branch.%s.remote", out)))
if err != nil || out == "" {
return result, fmt.Errorf("unable to get upstream's remote while qualifying relative remote")
}
out, err = Clean(Run(ctx, "ls-remote", "--get-url", out))
if err != nil {
return result, fmt.Errorf("unable to get upstream while qualifying relative remote")
}
return ExtractRepoFromURL(out)
}

func ExtractRepoFromURL(rawurl string) (config.Repo, error) {
// removes the .git suffix and any new lines
s := strings.TrimSuffix(strings.TrimSpace(rawurl), ".git")
Expand Down
20 changes: 20 additions & 0 deletions internal/git/config_test.go
Expand Up @@ -2,6 +2,7 @@ package git_test

import (
"context"
"strings"
"testing"

"github.com/goreleaser/goreleaser/internal/git"
Expand All @@ -22,6 +23,25 @@ func TestNoRemote(t *testing.T) {
require.EqualError(t, err, `no remote configured to list refs from`)
}

func TestRelativeRemote(t *testing.T) {
ctx := context.Background()
testlib.Mktmp(t)
testlib.GitInit(t)
testlib.GitRemoteAddWithName(t, "upstream", "https://github.com/goreleaser/goreleaser.git")
_, err := git.Run(ctx, "pull", "upstream", "main")
require.NoError(t, err)
_, err = git.Run(ctx, "branch", "--set-upstream-to", "upstream/main")
require.NoError(t, err)
_, err = git.Run(ctx, "checkout", "--track", "-b", "relative_branch")
require.NoError(t, err)
gitCfg, err := git.Run(ctx, "config", "--local", "--list")
require.NoError(t, err)
require.True(t, strings.Contains(gitCfg, "branch.relative_branch.remote=."))
repo, err := git.ExtractRepoFromConfig(ctx)
require.NoError(t, err)
require.Equal(t, "goreleaser/goreleaser", repo.String())
}

func TestRepoName(t *testing.T) {
testlib.Mktmp(t)
testlib.GitInit(t)
Expand Down

0 comments on commit 917cae5

Please sign in to comment.