Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clone step checkouts default branch on Pull Request event (Bitbucket) #3932

Closed
3 tasks done
j04n-f opened this issue Jul 18, 2024 · 9 comments · Fixed by woodpecker-ci/plugin-git#160
Closed
3 tasks done
Labels
bug Something isn't working forge/bitbucket bitbucket forge related

Comments

@j04n-f
Copy link
Contributor

j04n-f commented Jul 18, 2024

Component

server

Describe the bug

Goal

Run formatters and tests after pushing a new commit to a pull request.

Forge

Bitbucket Cloud

Issue

The clone step checkouts the default branch and uses the default branch workflow. It should checkout the pull request branch and use the pull request workflow.

Workflow

when:
  event: pull_request

clone:
  git:
    image: woodpeckerci/plugin-git
    settings:
      partial: false

steps:
  echo:
    image: ubuntu
    commands:
      - echo "Hello World"
    when:
      event: pull_request

Logs

+ git init -b master 0s
+ Initialized empty Git repository in /woodpecker/src/**
+ git config --global --replace-all safe.directory /woodpecker/src/**
+ git remote add origin https://bitbucket.org/**
+ git fetch --no-tags --depth=1 --filter=tree:0 origin +a6b5f1dfe5ac:
fatal: couldn't find remote ref a6b5f1dfe5ac
retry in 5s
+ git fetch --no-tags --depth=1 --filter=tree:0 origin +a6b5f1dfe5ac:5s
fatal: couldn't find remote ref a6b5f1dfe5ac
retry in 5s
exit status 128

Additional Information

  • We enabled the Bitbucket webhook pullrequest:updated, it was not enabled by default. Probably because it is not selected by default when Woodpecker creates the webhook:
    Events: []string{"repo:push", "pullrequest:created"},

Steps to reproduce

  1. Create a Bitbucket Cloud repository
  2. Update the Bitbucket webhook: pullrequest:updated
  3. Push a workflow to the main branch
when:
  event: push

clone:
  git:
    image: woodpeckerci/plugin-git
    settings:
      partial: false

steps:
  echo:
    image: ubuntu
    commands:
      - echo "Hello World"
    when:
      event: push
  1. Create a branch containing a change on the workflow
when:
  event: pull_request

clone:
  git:
    image: woodpeckerci/plugin-git
    settings:
      partial: false

steps:
  echo:
    image: ubuntu
    commands:
      - echo "Hello World"
    when:
      event: pull_request
  1. Push the branch changes and open a pull request to the default branch

Expected behavior

The clone step should checkout the Pull Request workflow and code instead of checking out the default branch.

System Info

Version 2.6

Additional context

No response

Validations

  • Read the docs.
  • Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
  • Checked that the bug isn't fixed in the next version already [https://woodpecker-ci.org/faq#which-version-of-woodpecker-should-i-use]
@j04n-f j04n-f added the bug Something isn't working label Jul 18, 2024
@qwerty287 qwerty287 added the forge/bitbucket bitbucket forge related label Jul 19, 2024
@j04n-f
Copy link
Contributor Author

j04n-f commented Jul 19, 2024

We found the issue. The Pull Request hook parser is using the destination information, it should use the source:

diff --git a/server/forge/bitbucket/convert.go b/server/forge/bitbucket/convert.go
index af573cbff..e64522f94 100644
--- a/server/forge/bitbucket/convert.go
+++ b/server/forge/bitbucket/convert.go
@@ -170,14 +170,14 @@ func convertPullHook(from *internal.PullRequestHook) *model.Pipeline {
 
 	return &model.Pipeline{
 		Event:  event,
-		Commit: from.PullRequest.Dest.Commit.Hash,
-		Ref:    fmt.Sprintf("refs/heads/%s", from.PullRequest.Dest.Branch.Name),
+		Commit: from.PullRequest.Source.Commit.Hash,
+		Ref:    fmt.Sprintf("refs/heads/%s", from.PullRequest.Source.Branch.Name),
 		Refspec: fmt.Sprintf("%s:%s",
 			from.PullRequest.Source.Branch.Name,
 			from.PullRequest.Dest.Branch.Name,
 		),
 		ForgeURL:  from.PullRequest.Links.HTML.Href,
-		Branch:    from.PullRequest.Dest.Branch.Name,
+		Branch:    from.PullRequest.Source.Branch.Name,
 		Message:   from.PullRequest.Desc,
 		Avatar:    from.Actor.Links.Avatar.Href,
 		Author:    from.Actor.Login,

Once this is fixed, another issue happens related to how the pipeline pulls the code:

+ git init -b ${Branch}
Initialized empty Git repository in /woodpecker/src/bitbucket.org/**
+ git config --global --replace-all safe.directory /woodpecker/src/bitbucket.org/***
+ git remote add origin https://bitbucket.org/**
+ git fetch --no-tags --depth=1 --filter=tree:0 origin +${Commit}: # Full SHA required
From https://bitbucket.org/**
 * branch            ${Commit} -> FETCH_HEAD # Full SHA required
+ git reset --hard -q ${Commit} # Full SHA required

The problem is that the Bitbucket Webhooks are not consistent. The pull request update webhook returns a short SHA, not the full one: https://jira.atlassian.com/browse/BCLOUD-21201.

We can change the plugin-git to ensure it always uses the full SHA: git rev-parse 3cdd5d -> 3cdd5d19178a54d2e51b5098d43b57571241d0ab

WDYT @qwerty287 ? We can create the PRs.

@qwerty287
Copy link
Contributor

If that fixes the issues, yes, just open the PRs! :)

@zc-devs
Copy link
Contributor

zc-devs commented Jul 19, 2024

The clone step should checkout the pull request branch

Agree.

and (Woodpecker should) use the pull request workflow

Disagree. Everyone can do anything with your pipeline, including secrets.

@qwerty287
Copy link
Contributor

qwerty287 commented Jul 20, 2024

Disagree. Everyone can do anything with your pipeline, including secrets.

No, it should use the PR ones. Currently this is the behavior for all forges and this issue is just about bitbucket, so this is just a bug and the PR one should be used.

However, not running the PR configuration has some disadvantages as you can't test your workflows anymore. You should use protected repos to prevent attacks like this (and yes, this feature needs more improvements to be more flexible).

@j04n-f
Copy link
Contributor Author

j04n-f commented Jul 21, 2024

Jenkins, GitHub and GitLab use the Pull Request branch workflows. Imaging you added a required input to your tests and the Pull Request runs the default branch workflow, it will fail. You will have to merge your changes without testing them.

You are right:

Disagree. Everyone can do anything with your pipeline, including secrets.

They mitigate this issues adding access and execution policies to the workflows (e.g. who can run them or who has access to the secrets).

@zc-devs
Copy link
Contributor

zc-devs commented Jul 21, 2024

  1. I've already thumbed up qwerty (thanks for clarification)
  2. Indeed, it is implemented this way and there is a warning
  3. I stay with my opinion, but it is not related to this issue

So, sorry to bother this thread, go ahead and fix the bug :)

6543 pushed a commit that referenced this issue Jul 23, 2024
)

## Description

This is the first fix for: #3932

Change the Pull Request hook parser to return the source commit, branch, and ref instead of the destination. Right now, the workflow pulls the destination configuration and code. It should pull the source configuration and code to verify that the configuration and code work as expected before merging the changes.

In case of the close event, the hook parser returns the destination branch, ref and merge commit. Usually, the contributor automatically deletes the source branch after merging the changes to the destination branch. Using the source values will cause the workflow to fail.

After the changes, Woodpecker will correctly download the workflow from the source branch (Pull Request commit), but it will fail to clone the repository. This issue is related to the commit format returned by the Bitbucket webhook. This inconsistency has already been reported: https://jira.atlassian.com/browse/BCLOUD-21201. The webhook returns a short SHA. The problem is that the `git fetch` command requires the full SHA. 

A workaround for this issue is to use the ref to fetch the code:

```yaml
clone:
  git:
    image: woodpeckerci/plugin-git
    settings:
      ref: ${CI_COMMIT_REF}
```

This is not ideal, because the Pull Request head won't always match the workflow commit, but it solves 80% of the event use cases (e.g. trigger a pull request workflow on change). This workaround won't work when re-running a previous workflow pointing to another commit, it will pull the last commit, not the previous one.

## Solutions

The solution proposed by the community is to retrieve the full SHA from the Bitbucket API using the short one. This solution has drawbacks:
- The Bitbucket API rate limit is 1000 req/h. This solution will reduce the maximum number of workflow runs per hour.
- It requires a braking change in the forges interface because the ´Hook(...)´ method does not have an instance of the HTTP Client. 

We propose to allow the git plugin to fetch the source code from a URL. The Bitbucket returns a link pointing to the commit. 

This proposal only requires a small change to the git plugin:
- Add a new optional parameter (e.g. CommitLink)
- Add a clause to the following conditional: https://github.com/woodpecker-ci/plugin-git/blob/7ac9615f409b539486b8841bd5ef01ae16bbc434/plugin.go#L79C1-L88C3
```go
if p.Pipeline.CommitLink != "" {...}
```
Git commands:
```shell
$ git fetch --no-tags --depth=1 --filter=tree:0 https://bitbucket.org/workspace/repo/commits/692972aabfec
$ git reset --hard -q 692972aabfec # It works with the short SHA
```
Woodpecker will set CommitLink to a blank string for the other forges, but Bitbuckket will use the one returned by the webhook.
6543 pushed a commit that referenced this issue Jul 23, 2024
)

## Description

This is the first fix for: #3932

Change the Pull Request hook parser to return the source commit, branch, and ref instead of the destination. Right now, the workflow pulls the destination configuration and code. It should pull the source configuration and code to verify that the configuration and code work as expected before merging the changes.

In case of the close event, the hook parser returns the destination branch, ref and merge commit. Usually, the contributor automatically deletes the source branch after merging the changes to the destination branch. Using the source values will cause the workflow to fail.

After the changes, Woodpecker will correctly download the workflow from the source branch (Pull Request commit), but it will fail to clone the repository. This issue is related to the commit format returned by the Bitbucket webhook. This inconsistency has already been reported: https://jira.atlassian.com/browse/BCLOUD-21201. The webhook returns a short SHA. The problem is that the `git fetch` command requires the full SHA. 

A workaround for this issue is to use the ref to fetch the code:

```yaml
clone:
  git:
    image: woodpeckerci/plugin-git
    settings:
      ref: ${CI_COMMIT_REF}
```

This is not ideal, because the Pull Request head won't always match the workflow commit, but it solves 80% of the event use cases (e.g. trigger a pull request workflow on change). This workaround won't work when re-running a previous workflow pointing to another commit, it will pull the last commit, not the previous one.

## Solutions

The solution proposed by the community is to retrieve the full SHA from the Bitbucket API using the short one. This solution has drawbacks:
- The Bitbucket API rate limit is 1000 req/h. This solution will reduce the maximum number of workflow runs per hour.
- It requires a braking change in the forges interface because the ´Hook(...)´ method does not have an instance of the HTTP Client. 

We propose to allow the git plugin to fetch the source code from a URL. The Bitbucket returns a link pointing to the commit. 

This proposal only requires a small change to the git plugin:
- Add a new optional parameter (e.g. CommitLink)
- Add a clause to the following conditional: https://github.com/woodpecker-ci/plugin-git/blob/7ac9615f409b539486b8841bd5ef01ae16bbc434/plugin.go#L79C1-L88C3
```go
if p.Pipeline.CommitLink != "" {...}
```
Git commands:
```shell
$ git fetch --no-tags --depth=1 --filter=tree:0 https://bitbucket.org/workspace/repo/commits/692972aabfec
$ git reset --hard -q 692972aabfec # It works with the short SHA
```
Woodpecker will set CommitLink to a blank string for the other forges, but Bitbuckket will use the one returned by the webhook.
@j04n-f
Copy link
Contributor Author

j04n-f commented Jul 25, 2024

@qwerty287 @6543 Whenever you have a moment, can you review woodpecker-ci/plugin-git#160? This is the last PR to close this issue. Thanks!

@6543
Copy link
Member

6543 commented Jul 26, 2024

woodpecker-ci/plugin-git#161 -> 2.5.2 is available

@j04n-f
Copy link
Contributor Author

j04n-f commented Jul 26, 2024

Pull Request integration for BB is working as expected now. Thanks!

6543 pushed a commit to 6543-forks/woodpecker that referenced this issue Sep 5, 2024
…odpecker-ci#3965)

## Description

This is the first fix for: woodpecker-ci#3932

Change the Pull Request hook parser to return the source commit, branch, and ref instead of the destination. Right now, the workflow pulls the destination configuration and code. It should pull the source configuration and code to verify that the configuration and code work as expected before merging the changes.

In case of the close event, the hook parser returns the destination branch, ref and merge commit. Usually, the contributor automatically deletes the source branch after merging the changes to the destination branch. Using the source values will cause the workflow to fail.

After the changes, Woodpecker will correctly download the workflow from the source branch (Pull Request commit), but it will fail to clone the repository. This issue is related to the commit format returned by the Bitbucket webhook. This inconsistency has already been reported: https://jira.atlassian.com/browse/BCLOUD-21201. The webhook returns a short SHA. The problem is that the `git fetch` command requires the full SHA. 

A workaround for this issue is to use the ref to fetch the code:

```yaml
clone:
  git:
    image: woodpeckerci/plugin-git
    settings:
      ref: ${CI_COMMIT_REF}
```

This is not ideal, because the Pull Request head won't always match the workflow commit, but it solves 80% of the event use cases (e.g. trigger a pull request workflow on change). This workaround won't work when re-running a previous workflow pointing to another commit, it will pull the last commit, not the previous one.

## Solutions

The solution proposed by the community is to retrieve the full SHA from the Bitbucket API using the short one. This solution has drawbacks:
- The Bitbucket API rate limit is 1000 req/h. This solution will reduce the maximum number of workflow runs per hour.
- It requires a braking change in the forges interface because the ´Hook(...)´ method does not have an instance of the HTTP Client. 

We propose to allow the git plugin to fetch the source code from a URL. The Bitbucket returns a link pointing to the commit. 

This proposal only requires a small change to the git plugin:
- Add a new optional parameter (e.g. CommitLink)
- Add a clause to the following conditional: https://github.com/woodpecker-ci/plugin-git/blob/7ac9615f409b539486b8841bd5ef01ae16bbc434/plugin.go#L79C1-L88C3
```go
if p.Pipeline.CommitLink != "" {...}
```
Git commands:
```shell
$ git fetch --no-tags --depth=1 --filter=tree:0 https://bitbucket.org/workspace/repo/commits/692972aabfec
$ git reset --hard -q 692972aabfec # It works with the short SHA
```
Woodpecker will set CommitLink to a blank string for the other forges, but Bitbuckket will use the one returned by the webhook.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working forge/bitbucket bitbucket forge related
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants