Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions server/api/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,25 @@ func CreatePipeline(c *gin.Context) {

func createTmpPipeline(event model.WebhookEvent, commit *model.Commit, user *model.User, opts *model.PipelineOptions) *model.Pipeline {
return &model.Pipeline{
Event: event,
Commit: commit.SHA,
Branch: opts.Branch,
Timestamp: time.Now().UTC().Unix(),

Avatar: user.Avatar,
Message: "MANUAL PIPELINE @ " + opts.Branch,
Event: event,
Commit: &model.Commit{
SHA: commit.SHA,
Message: "MANUAL PIPELINE @ " + opts.Branch,
ForgeURL: commit.ForgeURL,
Author: model.CommitAuthor{
Name: user.Login,
Email: user.Email,
},
Timestamp: time.Now().UTC().Unix(),

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we must use commit timestamp

},
Branch: opts.Branch,

Avatar: user.Avatar,

Ref: opts.Branch,
AdditionalVariables: opts.Variables,

Author: user.Login,
Email: user.Email,

ForgeURL: commit.ForgeURL,
}
Expand Down
6 changes: 5 additions & 1 deletion server/api/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ func GetFeed(c *gin.Context) {
if err != nil {
c.String(http.StatusInternalServerError, "Error fetching feed. %s", err)
} else {
c.JSON(http.StatusOK, feed)
fs := make([]*model.APIFeed, 0, len(feed))
for _, f := range feed {
fs = append(fs, f.ToAPIModel())
}
c.JSON(http.StatusOK, fs)
}
return
}
Expand Down
9 changes: 6 additions & 3 deletions server/cron/cron.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,14 @@ func CreatePipeline(ctx context.Context, store store.Store, cron *model.Cron) (*
}

return repo, &model.Pipeline{
Event: model.EventCron,
Commit: commit.SHA,
Event: model.EventCron,
Commit: &model.Commit{
SHA: commit.SHA,
ForgeURL: commit.ForgeURL,
Timestamp: cron.NextExec,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

},
Ref: "refs/heads/" + cron.Branch,
Branch: cron.Branch,
Timestamp: cron.NextExec,
Cron: cron.Name,
ForgeURL: commit.ForgeURL,
AdditionalVariables: cron.Variables,
Expand Down
2 changes: 1 addition & 1 deletion server/cron/cron_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func TestCreatePipeline(t *testing.T) {
assert.NoError(t, err)
assert.EqualValues(t, &model.Pipeline{
Branch: "default",
Commit: "sha1",
Commit: &model.Commit{SHA: "sha1", ForgeURL: "https://example.com/sha1"},
Event: "cron",
ForgeURL: "https://example.com/sha1",
Ref: "refs/heads/default",
Expand Down
10 changes: 5 additions & 5 deletions server/forge/bitbucket/bitbucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ func (c *config) Repos(ctx context.Context, u *model.User, p *model.ListOptions)

// File fetches the file from the Bitbucket repository and returns its contents.
func (c *config) File(ctx context.Context, u *model.User, r *model.Repo, p *model.Pipeline, f string) ([]byte, error) {
config, err := c.newClient(ctx, u).FindSource(r.Owner, r.Name, p.Commit, f)
config, err := c.newClient(ctx, u).FindSource(r.Owner, r.Name, p.Commit.SHA, f)
if err != nil {
var rspErr internal.Error
if ok := errors.As(err, &rspErr); ok && rspErr.Status == http.StatusNotFound {
Expand All @@ -261,7 +261,7 @@ func (c *config) Dir(ctx context.Context, u *model.User, r *model.Repo, p *model
repoPathFiles := []*forge_types.FileMeta{}
client := c.newClient(ctx, u)
for {
filesResp, err := client.GetRepoFiles(r.Owner, r.Name, p.Commit, f, page)
filesResp, err := client.GetRepoFiles(r.Owner, r.Name, p.Commit.SHA, f, page)
if err != nil {
var rspErr internal.Error
if ok := errors.As(err, &rspErr); ok && rspErr.Status == http.StatusNotFound {
Expand All @@ -277,7 +277,7 @@ func (c *config) Dir(ctx context.Context, u *model.User, r *model.Repo, p *model
Name: filename,
}
if file.Type == "commit_file" {
fileData, err := c.newClient(ctx, u).FindSource(r.Owner, r.Name, p.Commit, file.Path)
fileData, err := c.newClient(ctx, u).FindSource(r.Owner, r.Name, p.Commit.SHA, file.Path)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -322,7 +322,7 @@ func (c *config) Status(ctx context.Context, user *model.User, repo *model.Repo,
status.Refname = pipeline.Branch
}

return c.newClient(ctx, user).CreateStatus(repo.Owner, repo.Name, pipeline.Commit, &status)
return c.newClient(ctx, user).CreateStatus(repo.Owner, repo.Name, pipeline.Commit.SHA, &status)
}

// Activate activates the repository by registering repository push hooks with
Expand Down Expand Up @@ -454,7 +454,7 @@ func (c *config) Hook(ctx context.Context, req *http.Request) (*model.Repo, *mod
switch pl.Event {
case model.EventPush:
// List only the latest push changes
pl.ChangedFiles, err = c.newClient(ctx, u).ListChangedFiles(repo.Owner, repo.Name, pl.Commit)
pl.ChangedFiles, err = c.newClient(ctx, u).ListChangedFiles(repo.Owner, repo.Name, pl.Commit.SHA)
if err != nil {
return nil, nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions server/forge/bitbucket/bitbucket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ func TestBitbucket(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, "martinherren1984/publictestrepo", r.FullName)
assert.Equal(t, "master", r.Branch)
assert.Equal(t, "c14c1bb05dfb1fdcdf06b31485fff61b0ea44277", b.Commit)
assert.Equal(t, "c14c1bb05dfb1fdcdf06b31485fff61b0ea44277", b.Commit.SHA)
assert.Equal(t, []string{"main.go"}, b.ChangedFiles)
}

Expand Down Expand Up @@ -276,7 +276,7 @@ var (
}

fakePipeline = &model.Pipeline{
Commit: "9ecad50",
Commit: &model.Commit{SHA: "9ecad50"},
}

fakeWorkflow = &model.Workflow{
Expand Down
54 changes: 33 additions & 21 deletions server/forge/bitbucket/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,26 +166,32 @@ func convertPullHook(from *internal.PullRequestHook) *model.Pipeline {
}

pipeline := &model.Pipeline{
Event: event,
Commit: from.PullRequest.Source.Commit.Hash,
Ref: fmt.Sprintf("refs/pull-requests/%d/from", from.PullRequest.ID),
Event: event,
Commit: &model.Commit{
SHA: from.PullRequest.Source.Commit.Hash,
Message: from.PullRequest.Title,
ForgeURL: from.PullRequest.Links.HTML.Href,
Author: model.CommitAuthor{
Name: from.Actor.Login,
},
Timestamp: from.PullRequest.Updated.UTC().Unix(),
},
Ref: fmt.Sprintf("refs/pull-requests/%d/from", from.PullRequest.ID),
Refspec: fmt.Sprintf(
"%s:%s",
from.PullRequest.Source.Branch.Name,
from.PullRequest.Dest.Branch.Name,
),
ForgeURL: from.PullRequest.Links.HTML.Href,
Branch: from.PullRequest.Source.Branch.Name,
Message: from.PullRequest.Title,
Avatar: from.Actor.Links.Avatar.Href,
Author: from.Actor.Login,
Sender: from.Actor.Login,
Timestamp: from.PullRequest.Updated.UTC().Unix(),
FromFork: from.PullRequest.Source.Repo.UUID != from.PullRequest.Dest.Repo.UUID,
ForgeURL: from.PullRequest.Links.HTML.Href,
Branch: from.PullRequest.Source.Branch.Name,
Avatar: from.Actor.Links.Avatar.Href,
Author: from.Actor.Login,
Sender: from.Actor.Login,
FromFork: from.PullRequest.Source.Repo.UUID != from.PullRequest.Dest.Repo.UUID,
}

if from.PullRequest.State == stateClosed {
pipeline.Commit = from.PullRequest.MergeCommit.Hash
pipeline.Commit.SHA = from.PullRequest.MergeCommit.Hash
pipeline.Ref = fmt.Sprintf("refs/heads/%s", from.PullRequest.Dest.Branch.Name)
pipeline.Branch = from.PullRequest.Dest.Branch.Name
}
Expand All @@ -197,14 +203,20 @@ func convertPullHook(from *internal.PullRequestHook) *model.Pipeline {
// hook to the Woodpecker pipeline struct holding commit information.
func convertPushHook(hook *internal.PushHook, change *internal.Change) *model.Pipeline {
pipeline := &model.Pipeline{
Commit: change.New.Target.Hash,
ForgeURL: change.New.Target.Links.HTML.Href,
Branch: change.New.Name,
Message: change.New.Target.Message,
Avatar: hook.Actor.Links.Avatar.Href,
Author: hook.Actor.Login,
Sender: hook.Actor.Login,
Timestamp: change.New.Target.Date.UTC().Unix(),
Commit: &model.Commit{
SHA: change.New.Target.Hash,
Message: change.New.Target.Message,
ForgeURL: change.New.Target.Links.HTML.Href,
Author: model.CommitAuthor{
Name: hook.Actor.Login,
},
Timestamp: change.New.Target.Date.UTC().Unix(),
},
ForgeURL: change.New.Target.Links.HTML.Href,
Branch: change.New.Name,
Avatar: hook.Actor.Links.Avatar.Href,
Author: hook.Actor.Login,
Sender: hook.Actor.Login,
}
switch change.New.Type {
case "tag", "annotated_tag", "bookmark":
Expand All @@ -216,7 +228,7 @@ func convertPushHook(hook *internal.PushHook, change *internal.Change) *model.Pi
pipeline.Ref = fmt.Sprintf("refs/heads/%s", change.New.Name)
}
if len(change.New.Target.Author.Raw) != 0 {
pipeline.Email = extractEmail(change.New.Target.Author.Raw)
pipeline.Commit.Author.Email = extractEmail(change.New.Target.Author.Raw)
}
return pipeline
}
Expand Down
14 changes: 7 additions & 7 deletions server/forge/bitbucket/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,13 @@ func Test_convertPullHook(t *testing.T) {
assert.Equal(t, model.EventPull, pipeline.Event)
assert.Equal(t, hook.Actor.Login, pipeline.Author)
assert.Equal(t, hook.Actor.Links.Avatar.Href, pipeline.Avatar)
assert.Equal(t, hook.PullRequest.Source.Commit.Hash, pipeline.Commit)
assert.Equal(t, hook.PullRequest.Source.Commit.Hash, pipeline.Commit.SHA)
assert.Equal(t, hook.PullRequest.Source.Branch.Name, pipeline.Branch)
assert.Equal(t, hook.PullRequest.Links.HTML.Href, pipeline.ForgeURL)
assert.Equal(t, "refs/pull-requests/1/from", pipeline.Ref)
assert.Equal(t, "change:main", pipeline.Refspec)
assert.Equal(t, hook.PullRequest.Title, pipeline.Message)
assert.Equal(t, hook.PullRequest.Updated.Unix(), pipeline.Timestamp)
assert.Equal(t, hook.PullRequest.Title, pipeline.Commit.Message)
assert.Equal(t, hook.PullRequest.Updated.Unix(), pipeline.Commit.Timestamp)
}

func Test_convertPushHook(t *testing.T) {
Expand All @@ -153,15 +153,15 @@ func Test_convertPushHook(t *testing.T) {

pipeline := convertPushHook(&hook, &change)
assert.Equal(t, model.EventPush, pipeline.Event)
assert.Equal(t, "test@domain.tld", pipeline.Email)
assert.Equal(t, "test@domain.tld", pipeline.Commit.Author.Email)
assert.Equal(t, hook.Actor.Login, pipeline.Author)
assert.Equal(t, hook.Actor.Links.Avatar.Href, pipeline.Avatar)
assert.Equal(t, change.New.Target.Hash, pipeline.Commit)
assert.Equal(t, change.New.Target.Hash, pipeline.Commit.SHA)
assert.Equal(t, change.New.Name, pipeline.Branch)
assert.Equal(t, change.New.Target.Links.HTML.Href, pipeline.ForgeURL)
assert.Equal(t, "refs/heads/main", pipeline.Ref)
assert.Equal(t, change.New.Target.Message, pipeline.Message)
assert.Equal(t, change.New.Target.Date.Unix(), pipeline.Timestamp)
assert.Equal(t, change.New.Target.Message, pipeline.Commit.Message)
assert.Equal(t, change.New.Target.Date.Unix(), pipeline.Commit.Timestamp)
}

func Test_convertPushHookTag(t *testing.T) {
Expand Down
10 changes: 5 additions & 5 deletions server/forge/bitbucket/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func Test_parseHook(t *testing.T) {
assert.NotNil(t, pr)
assert.Equal(t, "user_name/repo_name", r.FullName)
assert.Equal(t, model.EventPull, b.Event)
assert.Equal(t, "d3022fc0ca3d", b.Commit)
assert.Equal(t, "d3022fc0ca3d", b.Commit.SHA)
})

t.Run("pull-request merged", func(t *testing.T) {
Expand All @@ -74,7 +74,7 @@ func Test_parseHook(t *testing.T) {
assert.NotNil(t, pr)
assert.Equal(t, "anbraten/test-2", r.FullName)
assert.Equal(t, model.EventPullClosed, b.Event)
assert.Equal(t, "006704dbeab2", b.Commit)
assert.Equal(t, "006704dbeab2", b.Commit.SHA)
})

t.Run("pull-request closed", func(t *testing.T) {
Expand All @@ -88,7 +88,7 @@ func Test_parseHook(t *testing.T) {
assert.NotNil(t, pr)
assert.Equal(t, "anbraten/test-2", r.FullName)
assert.Equal(t, model.EventPullClosed, b.Event)
assert.Equal(t, "f90e18fc9d45", b.Commit)
assert.Equal(t, "f90e18fc9d45", b.Commit.SHA)
})

t.Run("malformed push", func(t *testing.T) {
Expand Down Expand Up @@ -124,7 +124,7 @@ func Test_parseHook(t *testing.T) {
assert.Nil(t, pr)
assert.Equal(t, "martinherren1984/publictestrepo", r.FullName)
assert.Equal(t, "https://bitbucket.org/martinherren1984/publictestrepo", r.Clone)
assert.Equal(t, "c14c1bb05dfb1fdcdf06b31485fff61b0ea44277", b.Commit)
assert.Equal(t, "a\n", b.Message)
assert.Equal(t, "c14c1bb05dfb1fdcdf06b31485fff61b0ea44277", b.Commit.SHA)
assert.Equal(t, "a\n", b.Commit.Message)
})
}
18 changes: 11 additions & 7 deletions server/forge/bitbucketdatacenter/bitbucketdatacenter.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ func (c *client) File(ctx context.Context, u *model.User, r *model.Repo, p *mode
return nil, fmt.Errorf("unable to create bitbucket client: %w", err)
}

b, resp, err := bc.Projects.GetTextFileContent(ctx, r.Owner, r.Name, f, p.Commit)
b, resp, err := bc.Projects.GetTextFileContent(ctx, r.Owner, r.Name, f, p.Commit.SHA)
if err != nil {
if resp != nil && resp.StatusCode == http.StatusNotFound {
// requested directory might not exist
Expand All @@ -291,7 +291,7 @@ func (c *client) Dir(ctx context.Context, u *model.User, r *model.Repo, p *model
return nil, fmt.Errorf("unable to create bitbucket client: %w", err)
}

opts := &bitbucket.FilesListOptions{At: p.Commit}
opts := &bitbucket.FilesListOptions{At: p.Commit.SHA}
all := make([]*forge_types.FileMeta, 0)
for {
list, resp, err := bc.Projects.ListFiles(ctx, r.Owner, r.Name, path, opts)
Expand Down Expand Up @@ -335,7 +335,7 @@ func (c *client) Status(ctx context.Context, u *model.User, repo *model.Repo, pi
DateAdded: bitbucket.DateTime(time.Unix(pipeline.Started, 0)),
Ref: fmt.Sprintf("refs/heads/%s", pipeline.Branch),
}
_, err = bc.Projects.CreateBuildStatus(ctx, repo.Owner, repo.Name, pipeline.Commit, status)
_, err = bc.Projects.CreateBuildStatus(ctx, repo.Owner, repo.Name, pipeline.Commit.SHA, status)
return err
}

Expand Down Expand Up @@ -566,19 +566,23 @@ func (c *client) updatePipelineFromCommits(ctx context.Context, u *model.User, r
return nil, fmt.Errorf("unable to create bitbucket client: %w", err)
}

commit, _, err := bc.Projects.GetCommit(ctx, r.Owner, r.Name, p.Commit)
if p.Commit == nil {
p.Commit = &model.Commit{}
}

commit, _, err := bc.Projects.GetCommit(ctx, r.Owner, r.Name, p.Commit.SHA)
if err != nil {
return nil, fmt.Errorf("unable to read commit: %w", err)
}

// In Bitbucket Data Center, when using annotated tags, the webhook's ToHash is the tag object SHA, not the actual commit SHA.
// Update p.Commit so that build statuses are posted to the correct commit SHA.
if p.Event == model.EventTag && commit.ID != "" && commit.ID != p.Commit {
p.Commit = commit.ID
if p.Event == model.EventTag && commit.ID != "" && commit.ID != p.Commit.SHA {
p.Commit.SHA = commit.ID
p.ForgeURL = fmt.Sprintf("%s/projects/%s/repos/%s/commits/%s", c.url, r.Owner, r.Name, commit.ID)
}

p.Message = commit.Message
p.Commit.Message = commit.Message

opts := &bitbucket.CompareChangesOptions{}
if currCommit != "" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ var (
fakePipeline = &model.Pipeline{
ID: 1,
Number: 42,
Commit: "3ce383490b3d90d79460c60f67ba2580acc6cc59",
Commit: &model.Commit{SHA: "3ce383490b3d90d79460c60f67ba2580acc6cc59"},
Started: 1759825800,
Finished: 1759825883,
Branch: "feature-branch",
Expand Down
Loading