Skip to content

Commit

Permalink
Fetch using short commit SHA (#160)
Browse files Browse the repository at this point in the history
## Description
This relates to woodpecker-ci/woodpecker#3965
and closes woodpecker-ci/woodpecker#3932.

The Bitbucket Pull Request Hook returns a short commit SHA. The git
fetch command requires a full-length SHA. Add a clause to detect when
the SHA1 has less than 40 characters. Fetch & switch the branch to reset
the expected commit.

Raise an error if the branch value is not defined.

## Test

Run script:

```shell
export GOOS=linux
export GOARCH=amd64
export CGO_ENABLED=0
export GO111MODULE=on
export CI_REPO_CLONE_URL=https://{User}:{Token}@bitbucket.org/{Workspace}/{Project}.git
export CI_WORKSPACE=./woodpecker
export CI_BUILD_EVENT=push
export CI_COMMIT_SHA=692972aabfec
export CI_COMMIT_BRANCH=test

./release/linux/amd64/plugin-git
```
Output:

```shell
+ git init -b test
Initialised empty Git repository in /home/pc415/bit2me/plugin-git/woodpecker/.git/
+ git config --global --replace-all safe.directory ./woodpecker
+ git remote add origin https://{User}:{Token}@bitbucket.org/{Workspace}/{Project}.git
+ git fetch --no-tags --depth=1 --filter=tree:0 origin +test:
warning: filtering not recognized by server, ignoring
From https://bitbucket.org/{Workspace}/{Project}.git
 * branch            test       -> FETCH_HEAD
 * [new branch]      test       -> origin/test
+ git switch -q test
+ git reset --hard -q 692972aabfec
+ git submodule update --init --recursive --depth=1 --recommend-shallow
+ git lfs fetch
```
  • Loading branch information
j04n-f authored Jul 25, 2024
1 parent 7ac9615 commit 4dfe5e1
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
19 changes: 19 additions & 0 deletions plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ func (p Plugin) Exec() error {
fmt.Println("using head checkout")
cmds = append(cmds, fetch(p.Pipeline.Ref, p.Config.Tags, p.Config.Depth, p.Config.filter))
cmds = append(cmds, checkoutHead())
} else if len(p.Pipeline.Commit) != 40 && len(p.Pipeline.Commit) != 64 {
// fetch requires full SHA1 (40 chars) or SHA256 (64 chars) commits (unambiguous reference)
// for short SHA1 or SHA256, fetch and switch the branch before commit reset
if p.Config.Branch == "" {
return fmt.Errorf("short commit SHA1 checkout requires a branch")
}
cmds = append(cmds, fetch(p.Config.Branch, p.Config.Tags, p.Config.Depth, p.Config.filter))
cmds = append(cmds, switchBranch(p.Config.Branch))
cmds = append(cmds, checkoutSha(p.Pipeline.Commit))
} else {
// fetch and checkout by commit sha
cmds = append(cmds, fetch(p.Pipeline.Commit, p.Config.Tags, p.Config.Depth, p.Config.filter))
Expand Down Expand Up @@ -256,6 +265,16 @@ func checkoutSha(commit string) *exec.Cmd {
), defaultEnvVars...)
}

// Switch executes a git switch command.
func switchBranch(branch string) *exec.Cmd {
return appendEnv(exec.Command(
"git",
"switch",
"-q",
branch,
), defaultEnvVars...)
}

func fetchLFS() *exec.Cmd {
return appendEnv(exec.Command(
"git", "lfs",
Expand Down
40 changes: 40 additions & 0 deletions plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,17 @@ var commits = []struct {
file: "README",
data: "Hello World!\n\nsomething is changed!\n",
},
// checkout with short SHA!
{
path: "octocat/Hello-World",
clone: "https://github.com/octocat/Hello-World.git",
event: "pull_request",
branch: "test",
commit: "7629413",
ref: "",
file: "README",
data: "Hello World!\n",
},
// ### test lfs, please do not change order, otherwise TestCloneNonEmpty will fail ###
// checkout with lfs skip
{
Expand Down Expand Up @@ -143,6 +154,7 @@ func TestClone(t *testing.T) {
Recursive: c.recursive,
Lfs: c.lfs,
Home: "/tmp",
Branch: c.branch,
},
}

Expand Down Expand Up @@ -190,6 +202,7 @@ func TestCloneNonEmpty(t *testing.T) {
Recursive: c.recursive,
Lfs: c.lfs,
Home: "/tmp",
Branch: c.branch,
},
}

Expand Down Expand Up @@ -372,6 +385,33 @@ func TestCustomCertFile(t *testing.T) {
}
}

func TestSwitchBranch(t *testing.T) {
testdata := []struct {
exp []string
}{
{
[]string{
"git",
"switch",
"-q",
"test",
},
},
}

for _, td := range testdata {
c := switchBranch("test")
if len(c.Args) != len(td.exp) {
t.Errorf("Expected: %s, got %s", td.exp, c.Args)
}
for i := range c.Args {
if c.Args[i] != td.exp[i] {
t.Errorf("Expected: %s, got %s", td.exp, c.Args)
}
}
}
}

// TestUpdateSubmodules tests if the arguments to `git submodule update`
// are constructed properly.
func TestUpdateSubmodulesRemote(t *testing.T) {
Expand Down

0 comments on commit 4dfe5e1

Please sign in to comment.