Skip to content

Commit

Permalink
Merge branch 'main' into fix-client
Browse files Browse the repository at this point in the history
  • Loading branch information
6543 authored Aug 3, 2023
2 parents 6c0ccaa + 0314cb5 commit db075d3
Show file tree
Hide file tree
Showing 12 changed files with 211 additions and 131 deletions.
2 changes: 1 addition & 1 deletion docs/docs/30-administration/11-forges/10-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
| Event: Tag | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| Event: Pull-Request | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Event: Deploy | :white_check_mark: | :x: | :x: | :x: |
| [Multiple workflows](../../20-usage/25-workflows.md) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| [Multiple workflows](../../20-usage/25-workflows.md) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| [when.path filter](../../20-usage/20-pipeline-syntax.md#path) | :white_check_mark: | :white_check_mark:¹ | :white_check_mark: | :x: |

¹ for pull requests at least Gitea version 1.17 is required
2 changes: 2 additions & 0 deletions docs/docs/92-awesome.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ If you have some missing resources, please feel free to [open a pull-request](ht
- [Woodpecker CI @ Codeberg](https://www.sarkasti.eu/articles/post/woodpecker/)
- [Deploy Docker/Compose using Woodpecker CI](https://hinty.io/vverenko/deploy-docker-compose-using-woodpecker-ci/)
- [Installing Woodpecker CI in your personal homelab](https://pwa.io/articles/installing-woodpecker-in-your-homelab/)
- [Locally Cached Nix CI with Woodpecker](https://blog.kotatsu.dev/posts/2023-04-21-woodpecker-nix-caching/)
- [How to run Cypress auto-tests on Woodpecker CI and report results to Slack](https://devforth.io/blog/how-to-run-cypress-auto-tests-on-woodpecker-ci-and-report-results-to-slack/)

## Videos

Expand Down
52 changes: 48 additions & 4 deletions server/forge/bitbucket/bitbucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ import (
"fmt"
"net/http"
"net/url"
"path/filepath"

"golang.org/x/oauth2"

shared_utils "github.com/woodpecker-ci/woodpecker/shared/utils"

"github.com/woodpecker-ci/woodpecker/server"
"github.com/woodpecker-ci/woodpecker/server/forge"
"github.com/woodpecker-ci/woodpecker/server/forge/bitbucket/internal"
"github.com/woodpecker-ci/woodpecker/server/forge/common"
forge_types "github.com/woodpecker-ci/woodpecker/server/forge/types"
"github.com/woodpecker-ci/woodpecker/server/model"
shared_utils "github.com/woodpecker-ci/woodpecker/shared/utils"
)

// Bitbucket cloud endpoints.
Expand Down Expand Up @@ -223,8 +223,52 @@ func (c *config) File(ctx context.Context, u *model.User, r *model.Repo, p *mode
return []byte(*config), err
}

func (c *config) Dir(_ context.Context, _ *model.User, _ *model.Repo, _ *model.Pipeline, _ string) ([]*forge_types.FileMeta, error) {
return nil, forge_types.ErrNotImplemented
// Dir fetches a folder from the bitbucket repository
func (c *config) Dir(ctx context.Context, u *model.User, r *model.Repo, p *model.Pipeline, f string) ([]*forge_types.FileMeta, error) {
var page *string
repoPathFiles := []*forge_types.FileMeta{}
client := c.newClient(ctx, u)
for {
filesResp, err := client.GetRepoFiles(r.Owner, r.Name, p.Commit, f, page)
if err != nil {
return nil, err
}
for _, file := range filesResp.Values {
_, filename := filepath.Split(file.Path)
repoFile := forge_types.FileMeta{
Name: filename,
}
if file.Type == "commit_file" {
fileData, err := c.newClient(ctx, u).FindSource(r.Owner, r.Name, p.Commit, file.Path)
if err != nil {
return nil, err
}
if fileData != nil {
repoFile.Data = []byte(*fileData)
}
}
repoPathFiles = append(repoPathFiles, &repoFile)
}

// Check for more results page
if filesResp.Next == nil {
break
}
nextPageURL, err := url.Parse(*filesResp.Next)
if err != nil {
return nil, err
}
params, err := url.ParseQuery(nextPageURL.RawQuery)
if err != nil {
return nil, err
}
nextPage := params.Get("page")
if len(nextPage) == 0 {
break
}
page = &nextPage
}
return repoPathFiles, nil
}

// Status creates a pipeline status for the Bitbucket commit.
Expand Down
44 changes: 44 additions & 0 deletions server/forge/bitbucket/bitbucket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,50 @@ func Test_bitbucket(t *testing.T) {
})
})

g.Describe("When requesting repo branch HEAD", func() {
g.It("Should return the details", func() {
branchHead, err := c.BranchHead(ctx, fakeUser, fakeRepo, "branch_name")
g.Assert(err).IsNil()
g.Assert(branchHead).Equal("branch_head_name")
})
g.It("Should handle not found errors", func() {
_, err := c.BranchHead(ctx, fakeUser, fakeRepo, "branch_not_found")
g.Assert(err).IsNotNil()
})
})

g.Describe("When requesting repo pull requests", func() {
listOpts := model.ListOptions{
All: false,
Page: 1,
PerPage: 10,
}
g.It("Should return the details", func() {
repoPRs, err := c.PullRequests(ctx, fakeUser, fakeRepo, &listOpts)
g.Assert(err).IsNil()
g.Assert(repoPRs[0].Title).Equal("PRs title")
g.Assert(repoPRs[0].Index).Equal(int64(123))
})
g.It("Should handle not found errors", func() {
_, err := c.PullRequests(ctx, fakeUser, fakeRepoNotFound, &listOpts)
g.Assert(err).IsNotNil()
})
})

g.Describe("When requesting repo directory contents", func() {
g.It("Should return the details", func() {
files, err := c.Dir(ctx, fakeUser, fakeRepo, fakePipeline, "/dir")
g.Assert(err).IsNil()
g.Assert(len(files)).Equal(3)
g.Assert(files[0].Name).Equal("README.md")
g.Assert(string(files[0].Data)).Equal("dummy payload")
})
g.It("Should handle not found errors", func() {
_, err := c.Dir(ctx, fakeUser, fakeRepo, fakePipeline, "/dir_not_found")
g.Assert(err).IsNotNil()
})
})

g.Describe("When activating a repository", func() {
g.It("Should error when malformed hook", func() {
err := c.Activate(ctx, fakeUser, fakeRepo, "%gh&%ij")
Expand Down
80 changes: 79 additions & 1 deletion server/forge/bitbucket/fixtures/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ func Handler() http.Handler {
e.GET("/2.0/repositories/:owner", getUserRepos)
e.GET("/2.0/user/", getUser)
e.GET("/2.0/user/permissions/repositories", getPermissions)

e.GET("/2.0/repositories/:owner/:name/commits/:commit", getBranchHead)
e.GET("/2.0/repositories/:owner/:name/pullrequests", getPullRequests)
return e
}

Expand Down Expand Up @@ -108,13 +109,35 @@ func getRepoHooks(c *gin.Context) {

func getRepoFile(c *gin.Context) {
switch c.Param("file") {
case "dir":
c.String(200, repoDirPayload)
case "dir_not_found/":
c.String(404, "")
case "file_not_found":
c.String(404, "")
default:
c.String(200, repoFilePayload)
}
}

func getBranchHead(c *gin.Context) {
switch c.Param("commit") {
case "branch_name":
c.String(200, branchCommitsPayload)
default:
c.String(404, "")
}
}

func getPullRequests(c *gin.Context) {
switch c.Param("name") {
case "repo_name":
c.String(200, pullRequestsPayload)
default:
c.String(404, "")
}
}

func createRepoStatus(c *gin.Context) {
switch c.Param("name") {
case "repo_not_found":
Expand Down Expand Up @@ -223,6 +246,61 @@ const repoHookPayload = `

const repoFilePayload = "dummy payload"

const repoDirPayload = `
{
"pagelen": 10,
"page": 1,
"values": [
{
"path": "README.md",
"type": "commit_file"
},
{
"path": "test",
"type": "commit_directory"
},
{
"path": ".gitignore",
"type": "commit_file"
}
]
}
`

const branchCommitsPayload = `
{
"values": [
{
"hash": "branch_head_name"
},
{
"hash": "random1"
},
{
"hash": "random2"
}
]
}
`

const pullRequestsPayload = `
{
"values": [
{
"id": 123,
"title": "PRs title"
},
{
"id": 456,
"title": "Another PRs title"
}
],
"pagelen": 10,
"size": 2,
"page": 1
}
`

const userPayload = `
{
"username": "superman",
Expand Down
11 changes: 11 additions & 0 deletions server/forge/bitbucket/internal/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const (
pathOrgPerms = "%s/2.0/workspaces/%s/permissions?%s"
pathPullRequests = "%s/2.0/repositories/%s/%s/pullrequests"
pathBranchCommits = "%s/2.0/repositories/%s/%s/commits/%s"
pathDir = "%s/2.0/repositories/%s/%s/src/%s%s"
)

type Client struct {
Expand Down Expand Up @@ -233,6 +234,16 @@ func (c *Client) GetWorkspace(name string) (*Workspace, error) {
return out, err
}

func (c *Client) GetRepoFiles(owner, name, revision, path string, page *string) (*DirResp, error) {
out := new(DirResp)
uri := fmt.Sprintf(pathDir, c.base, owner, name, revision, path)
if page != nil {
uri += "?page=" + *page
}
_, err := c.do(uri, get, nil, out)
return out, err
}

func (c *Client) do(rawurl, method string, in, out interface{}) (*string, error) {
uri, err := url.Parse(rawurl)
if err != nil {
Expand Down
13 changes: 13 additions & 0 deletions server/forge/bitbucket/internal/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,16 @@ type CommitsResp struct {
type Commit struct {
Hash string `json:"hash"`
}

type DirResp struct {
Page uint `json:"page"`
PageLen uint `json:"pagelen"`
Next *string `json:"next"`
Values []*Dir `json:"values"`
}

type Dir struct {
Path string `json:"path"`
Type string `json:"type"`
Size uint `json:"size"`
}
32 changes: 2 additions & 30 deletions web/src/assets/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,45 +161,19 @@
"branches": "Branches",
"build": {
"actions": {
"cancel": "Abbrechen",
"cancel_success": "Pipeline abgebrochen",
"canceled": "Dieser Schritt wurde abgebrochen.",
"log_auto_scroll": "Automatisches folgen",
"log_auto_scroll_off": "Schalte automatisches folgen aus",
"log_download": "Herunterladen",
"restart": "Neustarten",
"restart_success": "Pipeline neu gestartet"
},
"config": "Konfiguration",
"created": "Erstellt",
"event": {
"cron": "Cron",
"deploy": "Deploy",
"manual": "Manuell",
"pr": "Pull-Request",
"push": "Push",
"tag": "Tag"
},
"execution_error": "Ausführungsfehler",
"exit_code": "Exit-Code {exitCode}",
"files": "Geänderte Dateien ({files})",
"loading": "Laden…",
"log_download_error": "Beim Herunterladen der Log-Datei ist ein Fehler aufgetreten.",
"no_files": "Es wurden keine Dateien geändert.",
"no_pipeline_steps": "Keine Schritte in der Pipeline vorhanden!",
"no_pipelines": "Bisher wurden noch keine Pipelines gestartet.",
"pipeline": "Pipeline #{buildId}",
"pipelines_for": "Pipelines für den Branch \"{branch}\"",
"protected": {
"approve": "Genehmigen",
"approve_success": "Pipeline genehmigt",
"awaits": "Diese Pipeline wartet auf die Genehmigung durch einen Maintainer!",
"decline": "Ablehnen",
"decline_success": "Pipeline abgelehnt",
"declined": "Diese Pipeline ist abgelehnt worden!"
},
"step_not_started": "Dieser Schritt hat noch nicht begonnen.",
"tasks": "Vorgänge"
}
},
"deploy_pipeline": {
"enter_target": "Zielumgebung des Deployments",
Expand Down Expand Up @@ -316,12 +290,10 @@
"badge": {
"badge": "Abzeichen",
"branch": "Branch",
"markdown": "Markdown",
"type": "Syntax",
"type_html": "HTML",
"type_markdown": "Markdown",
"type_url": "URL",
"url_branch": "URL für bestimmten Branch"
"type_url": "URL"
},
"crons": {
"add": "Cron hinzufügen",
Expand Down
Loading

0 comments on commit db075d3

Please sign in to comment.