mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-09-27 06:00:10 +00:00
Compare commits
No commits in common. "69f414546b2f372360ff18783eb80c6564feebde" and "026d1f78194b0f11ffc34ffa4afe9d7240731e57" have entirely different histories.
69f414546b
...
026d1f7819
27 changed files with 1511 additions and 2327 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -13,7 +13,7 @@
|
||||||
*.so
|
*.so
|
||||||
*.dylib
|
*.dylib
|
||||||
vendor/
|
vendor/
|
||||||
__debug_bin*
|
__debug_bin
|
||||||
|
|
||||||
# Test binary, built with `go test -c`
|
# Test binary, built with `go test -c`
|
||||||
*.test
|
*.test
|
||||||
|
|
|
@ -3,7 +3,7 @@ when:
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
- &golang_image 'docker.io/golang:1.22.2'
|
- &golang_image 'docker.io/golang:1.22.2'
|
||||||
- &node_image 'docker.io/node:22-alpine'
|
- &node_image 'docker.io/node:21-alpine'
|
||||||
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.22.1'
|
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.22.1'
|
||||||
- &xgo_version 'go-1.21.2'
|
- &xgo_version 'go-1.21.2'
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
variables:
|
variables:
|
||||||
- &golang_image 'docker.io/golang:1.22.2'
|
- &golang_image 'docker.io/golang:1.22.2'
|
||||||
- &node_image 'docker.io/node:22-alpine'
|
- &node_image 'docker.io/node:21-alpine'
|
||||||
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.22.1'
|
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.22.1'
|
||||||
- &xgo_version 'go-1.21.2'
|
- &xgo_version 'go-1.21.2'
|
||||||
- &buildx_plugin 'docker.io/woodpeckerci/plugin-docker-buildx:3.2.1'
|
- &buildx_plugin 'docker.io/woodpeckerci/plugin-docker-buildx:3.2.1'
|
||||||
|
|
|
@ -13,7 +13,7 @@ steps:
|
||||||
branch: renovate/*
|
branch: renovate/*
|
||||||
|
|
||||||
- name: spellcheck
|
- name: spellcheck
|
||||||
image: docker.io/node:22-alpine
|
image: docker.io/node:21-alpine
|
||||||
depends_on: []
|
depends_on: []
|
||||||
commands:
|
commands:
|
||||||
- corepack enable
|
- corepack enable
|
||||||
|
|
|
@ -6,7 +6,7 @@ when:
|
||||||
- renovate/*
|
- renovate/*
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
- &node_image 'docker.io/node:22-alpine'
|
- &node_image 'docker.io/node:21-alpine'
|
||||||
- &when
|
- &when
|
||||||
path:
|
path:
|
||||||
# related config files
|
# related config files
|
||||||
|
|
31
CHANGELOG.md
31
CHANGELOG.md
|
@ -1,6 +1,6 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## [2.5.0](https://github.com/woodpecker-ci/woodpecker/releases/tag/v2.5.0) - 2024-04-28
|
## [2.5.0](https://github.com/woodpecker-ci/woodpecker/releases/tag/v2.5.0) - 2024-04-26
|
||||||
|
|
||||||
### ❤️ Thanks to all contributors! ❤️
|
### ❤️ Thanks to all contributors! ❤️
|
||||||
|
|
||||||
|
@ -14,23 +14,8 @@
|
||||||
|
|
||||||
- Step logs removing API and Button [[#3451](https://github.com/woodpecker-ci/woodpecker/pull/3451)]
|
- Step logs removing API and Button [[#3451](https://github.com/woodpecker-ci/woodpecker/pull/3451)]
|
||||||
|
|
||||||
### 📚 Documentation
|
|
||||||
|
|
||||||
- chore(deps): update dependency trim to v1 [[#3658](https://github.com/woodpecker-ci/woodpecker/pull/3658)]
|
|
||||||
- chore(deps): update dependency got to v14 [[#3657](https://github.com/woodpecker-ci/woodpecker/pull/3657)]
|
|
||||||
- Fail on broken anchors [[#3644](https://github.com/woodpecker-ci/woodpecker/pull/3644)]
|
|
||||||
- Fix step syntax in docs [[#3635](https://github.com/woodpecker-ci/woodpecker/pull/3635)]
|
|
||||||
- chore(deps): update docs npm deps non-major [[#3632](https://github.com/woodpecker-ci/woodpecker/pull/3632)]
|
|
||||||
- Add Twine plugin [[#3619](https://github.com/woodpecker-ci/woodpecker/pull/3619)]
|
|
||||||
- Fix docs [[#3615](https://github.com/woodpecker-ci/woodpecker/pull/3615)]
|
|
||||||
- Document how to enable parallel step exec for all steps [[#3605](https://github.com/woodpecker-ci/woodpecker/pull/3605)]
|
|
||||||
- Update dependency @types/marked to v6 [[#3544](https://github.com/woodpecker-ci/woodpecker/pull/3544)]
|
|
||||||
- Update docs npm deps non-major [[#3485](https://github.com/woodpecker-ci/woodpecker/pull/3485)]
|
|
||||||
- Docs updates and fixes [[#3535](https://github.com/woodpecker-ci/woodpecker/pull/3535)]
|
|
||||||
|
|
||||||
### 📈 Enhancement
|
### 📈 Enhancement
|
||||||
|
|
||||||
- Split client into multiple files and add more tests [[#3647](https://github.com/woodpecker-ci/woodpecker/pull/3647)]
|
|
||||||
- Add DeletePipeline API [[#3506](https://github.com/woodpecker-ci/woodpecker/pull/3506)]
|
- Add DeletePipeline API [[#3506](https://github.com/woodpecker-ci/woodpecker/pull/3506)]
|
||||||
- Add filter options to GetPipelines API [[#3645](https://github.com/woodpecker-ci/woodpecker/pull/3645)]
|
- Add filter options to GetPipelines API [[#3645](https://github.com/woodpecker-ci/woodpecker/pull/3645)]
|
||||||
- Deprecate environment filter and improve errors [[#3634](https://github.com/woodpecker-ci/woodpecker/pull/3634)]
|
- Deprecate environment filter and improve errors [[#3634](https://github.com/woodpecker-ci/woodpecker/pull/3634)]
|
||||||
|
@ -46,6 +31,18 @@
|
||||||
- Allow separate gitea oauth URL [[#3513](https://github.com/woodpecker-ci/woodpecker/pull/3513)]
|
- Allow separate gitea oauth URL [[#3513](https://github.com/woodpecker-ci/woodpecker/pull/3513)]
|
||||||
- Add option to set the local repository path to the cli command exec. [[#3524](https://github.com/woodpecker-ci/woodpecker/pull/3524)]
|
- Add option to set the local repository path to the cli command exec. [[#3524](https://github.com/woodpecker-ci/woodpecker/pull/3524)]
|
||||||
|
|
||||||
|
### 📚 Documentation
|
||||||
|
|
||||||
|
- Fail on broken anchors [[#3644](https://github.com/woodpecker-ci/woodpecker/pull/3644)]
|
||||||
|
- Fix step syntax in docs [[#3635](https://github.com/woodpecker-ci/woodpecker/pull/3635)]
|
||||||
|
- chore(deps): update docs npm deps non-major [[#3632](https://github.com/woodpecker-ci/woodpecker/pull/3632)]
|
||||||
|
- Add Twine plugin [[#3619](https://github.com/woodpecker-ci/woodpecker/pull/3619)]
|
||||||
|
- Fix docs [[#3615](https://github.com/woodpecker-ci/woodpecker/pull/3615)]
|
||||||
|
- Document how to enable parallel step exec for all steps [[#3605](https://github.com/woodpecker-ci/woodpecker/pull/3605)]
|
||||||
|
- Update dependency @types/marked to v6 [[#3544](https://github.com/woodpecker-ci/woodpecker/pull/3544)]
|
||||||
|
- Update docs npm deps non-major [[#3485](https://github.com/woodpecker-ci/woodpecker/pull/3485)]
|
||||||
|
- Docs updates and fixes [[#3535](https://github.com/woodpecker-ci/woodpecker/pull/3535)]
|
||||||
|
|
||||||
### 🐛 Bug Fixes
|
### 🐛 Bug Fixes
|
||||||
|
|
||||||
- fix cli config loading and correct comment [[#3618](https://github.com/woodpecker-ci/woodpecker/pull/3618)]
|
- fix cli config loading and correct comment [[#3618](https://github.com/woodpecker-ci/woodpecker/pull/3618)]
|
||||||
|
@ -58,8 +55,6 @@
|
||||||
|
|
||||||
### Misc
|
### Misc
|
||||||
|
|
||||||
- chore(deps): update node.js to v22 [[#3659](https://github.com/woodpecker-ci/woodpecker/pull/3659)]
|
|
||||||
- chore(deps): lock file maintenance [[#3656](https://github.com/woodpecker-ci/woodpecker/pull/3656)]
|
|
||||||
- Add make target for spellcheck [[#3648](https://github.com/woodpecker-ci/woodpecker/pull/3648)]
|
- Add make target for spellcheck [[#3648](https://github.com/woodpecker-ci/woodpecker/pull/3648)]
|
||||||
- chore(deps): update woodpeckerci/plugin-ready-release-go docker tag to v1.1.1 [[#3641](https://github.com/woodpecker-ci/woodpecker/pull/3641)]
|
- chore(deps): update woodpeckerci/plugin-ready-release-go docker tag to v1.1.1 [[#3641](https://github.com/woodpecker-ci/woodpecker/pull/3641)]
|
||||||
- chore(deps): update web npm deps non-major [[#3640](https://github.com/woodpecker-ci/woodpecker/pull/3640)]
|
- chore(deps): update web npm deps non-major [[#3640](https://github.com/woodpecker-ci/woodpecker/pull/3640)]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# docker build --rm -f docker/Dockerfile.make -t woodpecker/make:local .
|
# docker build --rm -f docker/Dockerfile.make -t woodpecker/make:local .
|
||||||
FROM docker.io/golang:1.22-alpine3.19 as golang_image
|
FROM docker.io/golang:1.22-alpine3.19 as golang_image
|
||||||
FROM docker.io/node:22-alpine3.19
|
FROM docker.io/node:21-alpine3.19
|
||||||
|
|
||||||
# renovate: datasource=repology depName=alpine_3_19/make versioning=loose
|
# renovate: datasource=repology depName=alpine_3_19/make versioning=loose
|
||||||
ENV MAKE_VERSION="4.4.1-r2"
|
ENV MAKE_VERSION="4.4.1-r2"
|
||||||
|
|
|
@ -53,8 +53,8 @@
|
||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"trim": "^1.0.0",
|
"trim": "^0.0.3",
|
||||||
"got": "^14.0.0"
|
"got": "^11.8.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1045
docs/pnpm-lock.yaml
1045
docs/pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -59,11 +59,11 @@ func (s storage) GetPipelineList(repo *model.Repo, p *model.ListOptions, f *mode
|
||||||
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
if f.After != 0 {
|
if f.After != 0 {
|
||||||
cond = cond.And(builder.Gt{"pipeline_created": f.After})
|
cond = cond.And(builder.Gt{"pipeline_started": f.After})
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.Before != 0 {
|
if f.Before != 0 {
|
||||||
cond = cond.And(builder.Lt{"pipeline_created": f.Before})
|
cond = cond.And(builder.Lt{"pipeline_started": f.Before})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -231,19 +231,21 @@ func TestPipelines(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("Should get filtered pipelines", func() {
|
g.It("Should get filtered pipelines", func() {
|
||||||
|
dt1, _ := time.Parse(time.RFC3339, "2023-01-15T15:00:00Z")
|
||||||
pipeline1 := &model.Pipeline{
|
pipeline1 := &model.Pipeline{
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
|
Started: dt1.Unix(),
|
||||||
}
|
}
|
||||||
|
dt2, _ := time.Parse(time.RFC3339, "2023-01-15T16:30:00Z")
|
||||||
pipeline2 := &model.Pipeline{
|
pipeline2 := &model.Pipeline{
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
|
Started: dt2.Unix(),
|
||||||
}
|
}
|
||||||
err1 := store.CreatePipeline(pipeline1, []*model.Step{}...)
|
err1 := store.CreatePipeline(pipeline1, []*model.Step{}...)
|
||||||
g.Assert(err1).IsNil()
|
g.Assert(err1).IsNil()
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
before := time.Now().Unix()
|
|
||||||
err2 := store.CreatePipeline(pipeline2, []*model.Step{}...)
|
err2 := store.CreatePipeline(pipeline2, []*model.Step{}...)
|
||||||
g.Assert(err2).IsNil()
|
g.Assert(err2).IsNil()
|
||||||
pipelines, err3 := store.GetPipelineList(&model.Repo{ID: 1}, &model.ListOptions{Page: 1, PerPage: 50}, &model.PipelineFilter{Before: before})
|
pipelines, err3 := store.GetPipelineList(&model.Repo{ID: 1}, &model.ListOptions{Page: 1, PerPage: 50}, &model.PipelineFilter{Before: dt2.Unix()})
|
||||||
g.Assert(err3).IsNil()
|
g.Assert(err3).IsNil()
|
||||||
g.Assert(len(pipelines)).Equal(1)
|
g.Assert(len(pipelines)).Equal(1)
|
||||||
g.Assert(pipelines[0].ID).Equal(pipeline1.ID)
|
g.Assert(pipelines[0].ID).Equal(pipeline1.ID)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,50 +0,0 @@
|
||||||
package woodpecker
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
const (
|
|
||||||
pathAgents = "%s/api/agents"
|
|
||||||
pathAgent = "%s/api/agents/%d"
|
|
||||||
pathAgentTasks = "%s/api/agents/%d/tasks"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AgentCreate creates a new agent.
|
|
||||||
func (c *client) AgentCreate(in *Agent) (*Agent, error) {
|
|
||||||
out := new(Agent)
|
|
||||||
uri := fmt.Sprintf(pathAgents, c.addr)
|
|
||||||
return out, c.post(uri, in, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AgentList returns a list of all registered agents.
|
|
||||||
func (c *client) AgentList() ([]*Agent, error) {
|
|
||||||
out := make([]*Agent, 0, 5)
|
|
||||||
uri := fmt.Sprintf(pathAgents, c.addr)
|
|
||||||
return out, c.get(uri, &out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Agent returns an agent by id.
|
|
||||||
func (c *client) Agent(agentID int64) (*Agent, error) {
|
|
||||||
out := new(Agent)
|
|
||||||
uri := fmt.Sprintf(pathAgent, c.addr, agentID)
|
|
||||||
return out, c.get(uri, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AgentUpdate updates the agent with the provided Agent struct.
|
|
||||||
func (c *client) AgentUpdate(in *Agent) (*Agent, error) {
|
|
||||||
out := new(Agent)
|
|
||||||
uri := fmt.Sprintf(pathAgent, c.addr, in.ID)
|
|
||||||
return out, c.patch(uri, in, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AgentDelete deletes the agent with the given id.
|
|
||||||
func (c *client) AgentDelete(agentID int64) error {
|
|
||||||
uri := fmt.Sprintf(pathAgent, c.addr, agentID)
|
|
||||||
return c.delete(uri)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AgentTasksList returns a list of all tasks for the agent with the given id.
|
|
||||||
func (c *client) AgentTasksList(agentID int64) ([]*Task, error) {
|
|
||||||
out := make([]*Task, 0, 5)
|
|
||||||
uri := fmt.Sprintf(pathAgentTasks, c.addr, agentID)
|
|
||||||
return out, c.get(uri, &out)
|
|
||||||
}
|
|
|
@ -1,511 +0,0 @@
|
||||||
package woodpecker
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestClient_AgentCreate(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
handler http.HandlerFunc
|
|
||||||
input *Agent
|
|
||||||
expected *Agent
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "success",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodPost {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusCreated)
|
|
||||||
_, err := fmt.Fprint(w, `{"id":1,"name":"new_agent","backend":"local","capacity":2,"version":"1.0.0"}`)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
},
|
|
||||||
input: &Agent{Name: "new_agent", Backend: "local", Capacity: 2, Version: "1.0.0"},
|
|
||||||
expected: &Agent{ID: 1, Name: "new_agent", Backend: "local", Capacity: 2, Version: "1.0.0"},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "invalid input",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodPost {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
},
|
|
||||||
input: &Agent{},
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "server error",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodPost {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
},
|
|
||||||
input: &Agent{Name: "new_agent", Backend: "local", Capacity: 2, Version: "1.0.0"},
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(tt.handler)
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
client := NewClient(ts.URL, http.DefaultClient)
|
|
||||||
agent, err := client.AgentCreate(tt.input)
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, agent, tt.expected)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_AgentList(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
handler http.HandlerFunc
|
|
||||||
expected []*Agent
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "success",
|
|
||||||
handler: func(w http.ResponseWriter, _ *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
_, err := fmt.Fprint(w, `[
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"name": "agent-1",
|
|
||||||
"backend": "local",
|
|
||||||
"capacity": 2,
|
|
||||||
"version": "1.0.0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 2,
|
|
||||||
"name": "agent-2",
|
|
||||||
"backend": "kubernetes",
|
|
||||||
"capacity": 4,
|
|
||||||
"version": "1.0.0"
|
|
||||||
}
|
|
||||||
]`)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
},
|
|
||||||
expected: []*Agent{
|
|
||||||
{
|
|
||||||
ID: 1,
|
|
||||||
Name: "agent-1",
|
|
||||||
Backend: "local",
|
|
||||||
Capacity: 2,
|
|
||||||
Version: "1.0.0",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 2,
|
|
||||||
Name: "agent-2",
|
|
||||||
Backend: "kubernetes",
|
|
||||||
Capacity: 4,
|
|
||||||
Version: "1.0.0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "server error",
|
|
||||||
handler: func(w http.ResponseWriter, _ *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
},
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "invalid response",
|
|
||||||
handler: func(w http.ResponseWriter, _ *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
_, err := fmt.Fprint(w, `invalid json`)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
},
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(tt.handler)
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
client := NewClient(ts.URL, http.DefaultClient)
|
|
||||||
agents, err := client.AgentList()
|
|
||||||
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, tt.expected, agents)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_Agent(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
handler http.HandlerFunc
|
|
||||||
agentID int64
|
|
||||||
expected *Agent
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "success",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodGet {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
_, err := fmt.Fprint(w, `{"id":1,"name":"agent-1","backend":"local","capacity":2,"version":"1.0.0"}`)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
},
|
|
||||||
agentID: 1,
|
|
||||||
expected: &Agent{ID: 1, Name: "agent-1", Backend: "local", Capacity: 2, Version: "1.0.0"},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "not found",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodGet {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusNotFound)
|
|
||||||
},
|
|
||||||
agentID: 999,
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "server error",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodGet {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
},
|
|
||||||
agentID: 1,
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "invalid response",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodGet {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
_, err := fmt.Fprint(w, `invalid json`)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
},
|
|
||||||
agentID: 1,
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(tt.handler)
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
client := NewClient(ts.URL, http.DefaultClient)
|
|
||||||
agent, err := client.Agent(tt.agentID)
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, tt.expected, agent)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_AgentUpdate(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
handler http.HandlerFunc
|
|
||||||
input *Agent
|
|
||||||
expected *Agent
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "success",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodPatch {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
_, err := fmt.Fprint(w, `{"id":1,"name":"updated_agent"}`)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
},
|
|
||||||
input: &Agent{ID: 1, Name: "existing_agent"},
|
|
||||||
expected: &Agent{ID: 1, Name: "updated_agent"},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "not found",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodPatch {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusNotFound)
|
|
||||||
},
|
|
||||||
input: &Agent{ID: 999, Name: "nonexistent_agent"},
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "invalid input",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodPatch {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
},
|
|
||||||
input: &Agent{},
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "server error",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodPatch {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
},
|
|
||||||
input: &Agent{ID: 1, Name: "existing_agent"},
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(tt.handler)
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
client := NewClient(ts.URL, http.DefaultClient)
|
|
||||||
agent, err := client.AgentUpdate(tt.input)
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, agent, tt.expected)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_AgentDelete(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
handler http.HandlerFunc
|
|
||||||
agentID int64
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "success",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodDelete {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
},
|
|
||||||
agentID: 1,
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "not found",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodDelete {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusNotFound)
|
|
||||||
},
|
|
||||||
agentID: 999,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "server error",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodDelete {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
},
|
|
||||||
agentID: 1,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(tt.handler)
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
client := NewClient(ts.URL, http.DefaultClient)
|
|
||||||
err := client.AgentDelete(tt.agentID)
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_AgentTasksList(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
handler http.HandlerFunc
|
|
||||||
agentID int64
|
|
||||||
expected []*Task
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "success",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodGet {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
_, err := fmt.Fprint(w, `[
|
|
||||||
{
|
|
||||||
"id": "4696",
|
|
||||||
"data": "",
|
|
||||||
"labels": {
|
|
||||||
"platform": "linux/amd64",
|
|
||||||
"repo": "woodpecker-ci/woodpecker"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "4697",
|
|
||||||
"data": "",
|
|
||||||
"labels": {
|
|
||||||
"platform": "linux/arm64",
|
|
||||||
"repo": "woodpecker-ci/woodpecker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]`)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
},
|
|
||||||
agentID: 1,
|
|
||||||
expected: []*Task{
|
|
||||||
{
|
|
||||||
ID: "4696",
|
|
||||||
Data: []byte{},
|
|
||||||
Labels: map[string]string{
|
|
||||||
"platform": "linux/amd64",
|
|
||||||
"repo": "woodpecker-ci/woodpecker",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "4697",
|
|
||||||
Data: []byte{},
|
|
||||||
Labels: map[string]string{
|
|
||||||
"platform": "linux/arm64",
|
|
||||||
"repo": "woodpecker-ci/woodpecker",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "not found",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodGet {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusNotFound)
|
|
||||||
},
|
|
||||||
agentID: 999,
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "server error",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodGet {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
},
|
|
||||||
agentID: 1,
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "invalid response",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodGet {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
_, err := fmt.Fprint(w, `invalid json`)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
},
|
|
||||||
agentID: 1,
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(tt.handler)
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
client := NewClient(ts.URL, http.DefaultClient)
|
|
||||||
tasks, err := client.AgentTasksList(tt.agentID)
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, tt.expected, tasks)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -26,8 +26,41 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
pathLogLevel = "%s/api/log-level"
|
pathSelf = "%s/api/user"
|
||||||
|
pathRepos = "%s/api/user/repos"
|
||||||
|
pathRepoPost = "%s/api/repos?forge_remote_id=%d"
|
||||||
|
pathRepo = "%s/api/repos/%d"
|
||||||
|
pathRepoLookup = "%s/api/repos/lookup/%s"
|
||||||
|
pathRepoMove = "%s/api/repos/%d/move?to=%s"
|
||||||
|
pathChown = "%s/api/repos/%d/chown"
|
||||||
|
pathRepair = "%s/api/repos/%d/repair"
|
||||||
|
pathPipelines = "%s/api/repos/%d/pipelines"
|
||||||
|
pathPipeline = "%s/api/repos/%d/pipelines/%v"
|
||||||
|
pathPipelineLogs = "%s/api/repos/%d/logs/%d"
|
||||||
|
pathStepLogs = "%s/api/repos/%d/logs/%d/%d"
|
||||||
|
pathApprove = "%s/api/repos/%d/pipelines/%d/approve"
|
||||||
|
pathDecline = "%s/api/repos/%d/pipelines/%d/decline"
|
||||||
|
pathStop = "%s/api/repos/%d/pipelines/%d/cancel"
|
||||||
|
pathRepoSecrets = "%s/api/repos/%d/secrets"
|
||||||
|
pathRepoSecret = "%s/api/repos/%d/secrets/%s"
|
||||||
|
pathRepoRegistries = "%s/api/repos/%d/registry"
|
||||||
|
pathRepoRegistry = "%s/api/repos/%d/registry/%s"
|
||||||
|
pathRepoCrons = "%s/api/repos/%d/cron"
|
||||||
|
pathRepoCron = "%s/api/repos/%d/cron/%d"
|
||||||
|
pathOrg = "%s/api/orgs/%d"
|
||||||
|
pathOrgLookup = "%s/api/orgs/lookup/%s"
|
||||||
|
pathOrgSecrets = "%s/api/orgs/%d/secrets"
|
||||||
|
pathOrgSecret = "%s/api/orgs/%d/secrets/%s"
|
||||||
|
pathGlobalSecrets = "%s/api/secrets"
|
||||||
|
pathGlobalSecret = "%s/api/secrets/%s"
|
||||||
|
pathUsers = "%s/api/users"
|
||||||
|
pathUser = "%s/api/users/%s"
|
||||||
|
pathPipelineQueue = "%s/api/pipelines"
|
||||||
|
pathQueue = "%s/api/queue"
|
||||||
|
pathLogLevel = "%s/api/log-level"
|
||||||
|
pathAgents = "%s/api/agents"
|
||||||
|
pathAgent = "%s/api/agents/%d"
|
||||||
|
pathAgentTasks = "%s/api/agents/%d/tasks"
|
||||||
// TODO: implement endpoints
|
// TODO: implement endpoints
|
||||||
// pathFeed = "%s/api/user/feed"
|
// pathFeed = "%s/api/user/feed"
|
||||||
// pathVersion = "%s/version"
|
// pathVersion = "%s/version"
|
||||||
|
@ -58,6 +91,422 @@ func (c *client) SetAddress(addr string) {
|
||||||
c.addr = addr
|
c.addr = addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Self returns the currently authenticated user.
|
||||||
|
func (c *client) Self() (*User, error) {
|
||||||
|
out := new(User)
|
||||||
|
uri := fmt.Sprintf(pathSelf, c.addr)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// User returns a user by login.
|
||||||
|
func (c *client) User(login string) (*User, error) {
|
||||||
|
out := new(User)
|
||||||
|
uri := fmt.Sprintf(pathUser, c.addr, login)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserList returns a list of all registered users.
|
||||||
|
func (c *client) UserList() ([]*User, error) {
|
||||||
|
var out []*User
|
||||||
|
uri := fmt.Sprintf(pathUsers, c.addr)
|
||||||
|
err := c.get(uri, &out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserPost creates a new user account.
|
||||||
|
func (c *client) UserPost(in *User) (*User, error) {
|
||||||
|
out := new(User)
|
||||||
|
uri := fmt.Sprintf(pathUsers, c.addr)
|
||||||
|
err := c.post(uri, in, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserPatch updates a user account.
|
||||||
|
func (c *client) UserPatch(in *User) (*User, error) {
|
||||||
|
out := new(User)
|
||||||
|
uri := fmt.Sprintf(pathUser, c.addr, in.Login)
|
||||||
|
err := c.patch(uri, in, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserDel deletes a user account.
|
||||||
|
func (c *client) UserDel(login string) error {
|
||||||
|
uri := fmt.Sprintf(pathUser, c.addr, login)
|
||||||
|
err := c.delete(uri)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repo returns a repository by id.
|
||||||
|
func (c *client) Repo(repoID int64) (*Repo, error) {
|
||||||
|
out := new(Repo)
|
||||||
|
uri := fmt.Sprintf(pathRepo, c.addr, repoID)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoLookup returns a repository by name.
|
||||||
|
func (c *client) RepoLookup(fullName string) (*Repo, error) {
|
||||||
|
out := new(Repo)
|
||||||
|
uri := fmt.Sprintf(pathRepoLookup, c.addr, fullName)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoList returns a list of all repositories to which
|
||||||
|
// the user has explicit access in the host system.
|
||||||
|
func (c *client) RepoList() ([]*Repo, error) {
|
||||||
|
var out []*Repo
|
||||||
|
uri := fmt.Sprintf(pathRepos, c.addr)
|
||||||
|
err := c.get(uri, &out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoListOpts returns a list of all repositories to which
|
||||||
|
// the user has explicit access in the host system.
|
||||||
|
func (c *client) RepoListOpts(all bool) ([]*Repo, error) {
|
||||||
|
var out []*Repo
|
||||||
|
uri := fmt.Sprintf(pathRepos+"?all=%v", c.addr, all)
|
||||||
|
err := c.get(uri, &out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoPost activates a repository.
|
||||||
|
func (c *client) RepoPost(forgeRemoteID int64) (*Repo, error) {
|
||||||
|
out := new(Repo)
|
||||||
|
uri := fmt.Sprintf(pathRepoPost, c.addr, forgeRemoteID)
|
||||||
|
err := c.post(uri, nil, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoChown updates a repository owner.
|
||||||
|
func (c *client) RepoChown(repoID int64) (*Repo, error) {
|
||||||
|
out := new(Repo)
|
||||||
|
uri := fmt.Sprintf(pathChown, c.addr, repoID)
|
||||||
|
err := c.post(uri, nil, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoRepair repairs the repository hooks.
|
||||||
|
func (c *client) RepoRepair(repoID int64) error {
|
||||||
|
uri := fmt.Sprintf(pathRepair, c.addr, repoID)
|
||||||
|
return c.post(uri, nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoPatch updates a repository.
|
||||||
|
func (c *client) RepoPatch(repoID int64, in *RepoPatch) (*Repo, error) {
|
||||||
|
out := new(Repo)
|
||||||
|
uri := fmt.Sprintf(pathRepo, c.addr, repoID)
|
||||||
|
err := c.patch(uri, in, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoDel deletes a repository.
|
||||||
|
func (c *client) RepoDel(repoID int64) error {
|
||||||
|
uri := fmt.Sprintf(pathRepo, c.addr, repoID)
|
||||||
|
err := c.delete(uri)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoMove moves a repository
|
||||||
|
func (c *client) RepoMove(repoID int64, newFullName string) error {
|
||||||
|
uri := fmt.Sprintf(pathRepoMove, c.addr, repoID, newFullName)
|
||||||
|
return c.post(uri, nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pipeline returns a repository pipeline by pipeline-id.
|
||||||
|
func (c *client) Pipeline(repoID, pipeline int64) (*Pipeline, error) {
|
||||||
|
out := new(Pipeline)
|
||||||
|
uri := fmt.Sprintf(pathPipeline, c.addr, repoID, pipeline)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pipeline returns the latest repository pipeline by branch.
|
||||||
|
func (c *client) PipelineLast(repoID int64, branch string) (*Pipeline, error) {
|
||||||
|
out := new(Pipeline)
|
||||||
|
uri := fmt.Sprintf(pathPipeline, c.addr, repoID, "latest")
|
||||||
|
if len(branch) != 0 {
|
||||||
|
uri += "?branch=" + branch
|
||||||
|
}
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PipelineList returns a list of recent pipelines for the
|
||||||
|
// the specified repository.
|
||||||
|
func (c *client) PipelineList(repoID int64) ([]*Pipeline, error) {
|
||||||
|
var out []*Pipeline
|
||||||
|
uri := fmt.Sprintf(pathPipelines, c.addr, repoID)
|
||||||
|
err := c.get(uri, &out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) PipelineCreate(repoID int64, options *PipelineOptions) (*Pipeline, error) {
|
||||||
|
var out *Pipeline
|
||||||
|
uri := fmt.Sprintf(pathPipelines, c.addr, repoID)
|
||||||
|
err := c.post(uri, options, &out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PipelineQueue returns a list of enqueued pipelines.
|
||||||
|
func (c *client) PipelineQueue() ([]*Feed, error) {
|
||||||
|
var out []*Feed
|
||||||
|
uri := fmt.Sprintf(pathPipelineQueue, c.addr)
|
||||||
|
err := c.get(uri, &out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PipelineStart re-starts a stopped pipeline.
|
||||||
|
func (c *client) PipelineStart(repoID, pipeline int64, params map[string]string) (*Pipeline, error) {
|
||||||
|
out := new(Pipeline)
|
||||||
|
val := mapValues(params)
|
||||||
|
uri := fmt.Sprintf(pathPipeline, c.addr, repoID, pipeline)
|
||||||
|
err := c.post(uri+"?"+val.Encode(), nil, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PipelineStop cancels the running step.
|
||||||
|
func (c *client) PipelineStop(repoID, pipeline int64) error {
|
||||||
|
uri := fmt.Sprintf(pathStop, c.addr, repoID, pipeline)
|
||||||
|
err := c.post(uri, nil, nil)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PipelineApprove approves a blocked pipeline.
|
||||||
|
func (c *client) PipelineApprove(repoID, pipeline int64) (*Pipeline, error) {
|
||||||
|
out := new(Pipeline)
|
||||||
|
uri := fmt.Sprintf(pathApprove, c.addr, repoID, pipeline)
|
||||||
|
err := c.post(uri, nil, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PipelineDecline declines a blocked pipeline.
|
||||||
|
func (c *client) PipelineDecline(repoID, pipeline int64) (*Pipeline, error) {
|
||||||
|
out := new(Pipeline)
|
||||||
|
uri := fmt.Sprintf(pathDecline, c.addr, repoID, pipeline)
|
||||||
|
err := c.post(uri, nil, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PipelineKill force kills the running pipeline.
|
||||||
|
func (c *client) PipelineKill(repoID, pipeline int64) error {
|
||||||
|
uri := fmt.Sprintf(pathPipeline, c.addr, repoID, pipeline)
|
||||||
|
err := c.delete(uri)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogsPurge purges the pipeline all steps logs for the specified pipeline.
|
||||||
|
func (c *client) LogsPurge(repoID, pipeline int64) error {
|
||||||
|
uri := fmt.Sprintf(pathPipelineLogs, c.addr, repoID, pipeline)
|
||||||
|
err := c.delete(uri)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// StepLogEntries returns the pipeline logs for the specified step.
|
||||||
|
func (c *client) StepLogEntries(repoID, num, step int64) ([]*LogEntry, error) {
|
||||||
|
uri := fmt.Sprintf(pathStepLogs, c.addr, repoID, num, step)
|
||||||
|
var out []*LogEntry
|
||||||
|
err := c.get(uri, &out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// StepLogsPurge purges the pipeline logs for the specified step.
|
||||||
|
func (c *client) StepLogsPurge(repoID, pipelineNumber, stepID int64) error {
|
||||||
|
uri := fmt.Sprintf(pathStepLogs, c.addr, repoID, pipelineNumber, stepID)
|
||||||
|
err := c.delete(uri)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deploy triggers a deployment for an existing pipeline using the
|
||||||
|
// specified target environment.
|
||||||
|
func (c *client) Deploy(repoID, pipeline int64, env string, params map[string]string) (*Pipeline, error) {
|
||||||
|
out := new(Pipeline)
|
||||||
|
val := mapValues(params)
|
||||||
|
val.Set("event", EventDeploy)
|
||||||
|
val.Set("deploy_to", env)
|
||||||
|
uri := fmt.Sprintf(pathPipeline, c.addr, repoID, pipeline)
|
||||||
|
err := c.post(uri+"?"+val.Encode(), nil, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registry returns a registry by hostname.
|
||||||
|
func (c *client) Registry(repoID int64, hostname string) (*Registry, error) {
|
||||||
|
out := new(Registry)
|
||||||
|
uri := fmt.Sprintf(pathRepoRegistry, c.addr, repoID, hostname)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegistryList returns a list of all repository registries.
|
||||||
|
func (c *client) RegistryList(repoID int64) ([]*Registry, error) {
|
||||||
|
var out []*Registry
|
||||||
|
uri := fmt.Sprintf(pathRepoRegistries, c.addr, repoID)
|
||||||
|
err := c.get(uri, &out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegistryCreate creates a registry.
|
||||||
|
func (c *client) RegistryCreate(repoID int64, in *Registry) (*Registry, error) {
|
||||||
|
out := new(Registry)
|
||||||
|
uri := fmt.Sprintf(pathRepoRegistries, c.addr, repoID)
|
||||||
|
err := c.post(uri, in, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegistryUpdate updates a registry.
|
||||||
|
func (c *client) RegistryUpdate(repoID int64, in *Registry) (*Registry, error) {
|
||||||
|
out := new(Registry)
|
||||||
|
uri := fmt.Sprintf(pathRepoRegistry, c.addr, repoID, in.Address)
|
||||||
|
err := c.patch(uri, in, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegistryDelete deletes a registry.
|
||||||
|
func (c *client) RegistryDelete(repoID int64, hostname string) error {
|
||||||
|
uri := fmt.Sprintf(pathRepoRegistry, c.addr, repoID, hostname)
|
||||||
|
return c.delete(uri)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Secret returns a secret by name.
|
||||||
|
func (c *client) Secret(repoID int64, secret string) (*Secret, error) {
|
||||||
|
out := new(Secret)
|
||||||
|
uri := fmt.Sprintf(pathRepoSecret, c.addr, repoID, secret)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecretList returns a list of all repository secrets.
|
||||||
|
func (c *client) SecretList(repoID int64) ([]*Secret, error) {
|
||||||
|
var out []*Secret
|
||||||
|
uri := fmt.Sprintf(pathRepoSecrets, c.addr, repoID)
|
||||||
|
err := c.get(uri, &out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecretCreate creates a secret.
|
||||||
|
func (c *client) SecretCreate(repoID int64, in *Secret) (*Secret, error) {
|
||||||
|
out := new(Secret)
|
||||||
|
uri := fmt.Sprintf(pathRepoSecrets, c.addr, repoID)
|
||||||
|
err := c.post(uri, in, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecretUpdate updates a secret.
|
||||||
|
func (c *client) SecretUpdate(repoID int64, in *Secret) (*Secret, error) {
|
||||||
|
out := new(Secret)
|
||||||
|
uri := fmt.Sprintf(pathRepoSecret, c.addr, repoID, in.Name)
|
||||||
|
err := c.patch(uri, in, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecretDelete deletes a secret.
|
||||||
|
func (c *client) SecretDelete(repoID int64, secret string) error {
|
||||||
|
uri := fmt.Sprintf(pathRepoSecret, c.addr, repoID, secret)
|
||||||
|
return c.delete(uri)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Org returns an organization by id.
|
||||||
|
func (c *client) Org(orgID int64) (*Org, error) {
|
||||||
|
out := new(Org)
|
||||||
|
uri := fmt.Sprintf(pathOrg, c.addr, orgID)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrgLookup returns a organization by its name.
|
||||||
|
func (c *client) OrgLookup(name string) (*Org, error) {
|
||||||
|
out := new(Org)
|
||||||
|
uri := fmt.Sprintf(pathOrgLookup, c.addr, name)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrgSecret returns an organization secret by name.
|
||||||
|
func (c *client) OrgSecret(orgID int64, secret string) (*Secret, error) {
|
||||||
|
out := new(Secret)
|
||||||
|
uri := fmt.Sprintf(pathOrgSecret, c.addr, orgID, secret)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrgSecretList returns a list of all organization secrets.
|
||||||
|
func (c *client) OrgSecretList(orgID int64) ([]*Secret, error) {
|
||||||
|
var out []*Secret
|
||||||
|
uri := fmt.Sprintf(pathOrgSecrets, c.addr, orgID)
|
||||||
|
err := c.get(uri, &out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrgSecretCreate creates an organization secret.
|
||||||
|
func (c *client) OrgSecretCreate(orgID int64, in *Secret) (*Secret, error) {
|
||||||
|
out := new(Secret)
|
||||||
|
uri := fmt.Sprintf(pathOrgSecrets, c.addr, orgID)
|
||||||
|
err := c.post(uri, in, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrgSecretUpdate updates an organization secret.
|
||||||
|
func (c *client) OrgSecretUpdate(orgID int64, in *Secret) (*Secret, error) {
|
||||||
|
out := new(Secret)
|
||||||
|
uri := fmt.Sprintf(pathOrgSecret, c.addr, orgID, in.Name)
|
||||||
|
err := c.patch(uri, in, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrgSecretDelete deletes an organization secret.
|
||||||
|
func (c *client) OrgSecretDelete(orgID int64, secret string) error {
|
||||||
|
uri := fmt.Sprintf(pathOrgSecret, c.addr, orgID, secret)
|
||||||
|
return c.delete(uri)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalOrgSecret returns an global secret by name.
|
||||||
|
func (c *client) GlobalSecret(secret string) (*Secret, error) {
|
||||||
|
out := new(Secret)
|
||||||
|
uri := fmt.Sprintf(pathGlobalSecret, c.addr, secret)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalSecretList returns a list of all global secrets.
|
||||||
|
func (c *client) GlobalSecretList() ([]*Secret, error) {
|
||||||
|
var out []*Secret
|
||||||
|
uri := fmt.Sprintf(pathGlobalSecrets, c.addr)
|
||||||
|
err := c.get(uri, &out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalSecretCreate creates a global secret.
|
||||||
|
func (c *client) GlobalSecretCreate(in *Secret) (*Secret, error) {
|
||||||
|
out := new(Secret)
|
||||||
|
uri := fmt.Sprintf(pathGlobalSecrets, c.addr)
|
||||||
|
err := c.post(uri, in, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalSecretUpdate updates a global secret.
|
||||||
|
func (c *client) GlobalSecretUpdate(in *Secret) (*Secret, error) {
|
||||||
|
out := new(Secret)
|
||||||
|
uri := fmt.Sprintf(pathGlobalSecret, c.addr, in.Name)
|
||||||
|
err := c.patch(uri, in, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalSecretDelete deletes a global secret.
|
||||||
|
func (c *client) GlobalSecretDelete(secret string) error {
|
||||||
|
uri := fmt.Sprintf(pathGlobalSecret, c.addr, secret)
|
||||||
|
return c.delete(uri)
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueueInfo returns queue info
|
||||||
|
func (c *client) QueueInfo() (*Info, error) {
|
||||||
|
out := new(Info)
|
||||||
|
uri := fmt.Sprintf(pathQueue+"/info", c.addr)
|
||||||
|
err := c.get(uri, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
// LogLevel returns the current logging level
|
// LogLevel returns the current logging level
|
||||||
func (c *client) LogLevel() (*LogLevel, error) {
|
func (c *client) LogLevel() (*LogLevel, error) {
|
||||||
out := new(LogLevel)
|
out := new(LogLevel)
|
||||||
|
@ -74,31 +523,96 @@ func (c *client) SetLogLevel(in *LogLevel) (*LogLevel, error) {
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *client) CronList(repoID int64) ([]*Cron, error) {
|
||||||
|
out := make([]*Cron, 0, 5)
|
||||||
|
uri := fmt.Sprintf(pathRepoCrons, c.addr, repoID)
|
||||||
|
return out, c.get(uri, &out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) CronCreate(repoID int64, in *Cron) (*Cron, error) {
|
||||||
|
out := new(Cron)
|
||||||
|
uri := fmt.Sprintf(pathRepoCrons, c.addr, repoID)
|
||||||
|
return out, c.post(uri, in, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) CronUpdate(repoID int64, in *Cron) (*Cron, error) {
|
||||||
|
out := new(Cron)
|
||||||
|
uri := fmt.Sprintf(pathRepoCron, c.addr, repoID, in.ID)
|
||||||
|
err := c.patch(uri, in, out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) CronDelete(repoID, cronID int64) error {
|
||||||
|
uri := fmt.Sprintf(pathRepoCron, c.addr, repoID, cronID)
|
||||||
|
return c.delete(uri)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) CronGet(repoID, cronID int64) (*Cron, error) {
|
||||||
|
out := new(Cron)
|
||||||
|
uri := fmt.Sprintf(pathRepoCron, c.addr, repoID, cronID)
|
||||||
|
return out, c.get(uri, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) AgentList() ([]*Agent, error) {
|
||||||
|
out := make([]*Agent, 0, 5)
|
||||||
|
uri := fmt.Sprintf(pathAgents, c.addr)
|
||||||
|
return out, c.get(uri, &out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) Agent(agentID int64) (*Agent, error) {
|
||||||
|
out := new(Agent)
|
||||||
|
uri := fmt.Sprintf(pathAgent, c.addr, agentID)
|
||||||
|
return out, c.get(uri, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) AgentCreate(in *Agent) (*Agent, error) {
|
||||||
|
out := new(Agent)
|
||||||
|
uri := fmt.Sprintf(pathAgents, c.addr)
|
||||||
|
return out, c.post(uri, in, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) AgentUpdate(in *Agent) (*Agent, error) {
|
||||||
|
out := new(Agent)
|
||||||
|
uri := fmt.Sprintf(pathAgent, c.addr, in.ID)
|
||||||
|
return out, c.patch(uri, in, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) AgentDelete(agentID int64) error {
|
||||||
|
uri := fmt.Sprintf(pathAgent, c.addr, agentID)
|
||||||
|
return c.delete(uri)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) AgentTasksList(agentID int64) ([]*Task, error) {
|
||||||
|
out := make([]*Task, 0, 5)
|
||||||
|
uri := fmt.Sprintf(pathAgentTasks, c.addr, agentID)
|
||||||
|
return out, c.get(uri, &out)
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// http request helper functions
|
// http request helper functions
|
||||||
//
|
//
|
||||||
|
|
||||||
// Helper function for making an http GET request.
|
// helper function for making an http GET request.
|
||||||
func (c *client) get(rawurl string, out any) error {
|
func (c *client) get(rawurl string, out any) error {
|
||||||
return c.do(rawurl, http.MethodGet, nil, out)
|
return c.do(rawurl, http.MethodGet, nil, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function for making an http POST request.
|
// helper function for making an http POST request.
|
||||||
func (c *client) post(rawurl string, in, out any) error {
|
func (c *client) post(rawurl string, in, out any) error {
|
||||||
return c.do(rawurl, http.MethodPost, in, out)
|
return c.do(rawurl, http.MethodPost, in, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function for making an http PATCH request.
|
// helper function for making an http PATCH request.
|
||||||
func (c *client) patch(rawurl string, in, out any) error {
|
func (c *client) patch(rawurl string, in, out any) error {
|
||||||
return c.do(rawurl, http.MethodPatch, in, out)
|
return c.do(rawurl, http.MethodPatch, in, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function for making an http DELETE request.
|
// helper function for making an http DELETE request.
|
||||||
func (c *client) delete(rawurl string) error {
|
func (c *client) delete(rawurl string) error {
|
||||||
return c.do(rawurl, http.MethodDelete, nil, nil)
|
return c.do(rawurl, http.MethodDelete, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to make an http request.
|
// helper function to make an http request
|
||||||
func (c *client) do(rawurl, method string, in, out any) error {
|
func (c *client) do(rawurl, method string, in, out any) error {
|
||||||
body, err := c.open(rawurl, method, in)
|
body, err := c.open(rawurl, method, in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -111,7 +625,7 @@ func (c *client) do(rawurl, method string, in, out any) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to open an http request.
|
// helper function to open an http request
|
||||||
func (c *client) open(rawurl, method string, in any) (io.ReadCloser, error) {
|
func (c *client) open(rawurl, method string, in any) (io.ReadCloser, error) {
|
||||||
uri, err := url.Parse(rawurl)
|
uri, err := url.Parse(rawurl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -25,6 +25,44 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func Test_QueueInfo(t *testing.T) {
|
||||||
|
fixtureHandler := func(w http.ResponseWriter, _ *http.Request) {
|
||||||
|
fmt.Fprint(w, `{
|
||||||
|
"pending": null,
|
||||||
|
"running": [
|
||||||
|
{
|
||||||
|
"id": "4696",
|
||||||
|
"data": "",
|
||||||
|
"labels": {
|
||||||
|
"platform": "linux/amd64",
|
||||||
|
"repo": "woodpecker-ci/woodpecker"
|
||||||
|
},
|
||||||
|
"Dependencies": [],
|
||||||
|
"DepStatus": {},
|
||||||
|
"RunOn": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stats": {
|
||||||
|
"worker_count": 3,
|
||||||
|
"pending_count": 0,
|
||||||
|
"waiting_on_deps_count": 0,
|
||||||
|
"running_count": 1,
|
||||||
|
"completed_count": 0
|
||||||
|
},
|
||||||
|
"Paused": false
|
||||||
|
}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
ts := httptest.NewServer(http.HandlerFunc(fixtureHandler))
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
client := NewClient(ts.URL, http.DefaultClient)
|
||||||
|
|
||||||
|
info, err := client.QueueInfo()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 3, info.Stats.Workers)
|
||||||
|
}
|
||||||
|
|
||||||
func Test_LogLevel(t *testing.T) {
|
func Test_LogLevel(t *testing.T) {
|
||||||
logLevel := "warn"
|
logLevel := "warn"
|
||||||
fixtureHandler := func(w http.ResponseWriter, r *http.Request) {
|
fixtureHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
|
@ -49,7 +49,7 @@ const (
|
||||||
LogEntryProgress
|
LogEntryProgress
|
||||||
)
|
)
|
||||||
|
|
||||||
// StepType identifies the type of step.
|
// StepType identifies the type of step
|
||||||
type StepType string
|
type StepType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
package woodpecker
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
const (
|
|
||||||
pathGlobalSecrets = "%s/api/secrets"
|
|
||||||
pathGlobalSecret = "%s/api/secrets/%s"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GlobalOrgSecret returns an global secret by name.
|
|
||||||
func (c *client) GlobalSecret(secret string) (*Secret, error) {
|
|
||||||
out := new(Secret)
|
|
||||||
uri := fmt.Sprintf(pathGlobalSecret, c.addr, secret)
|
|
||||||
err := c.get(uri, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalSecretList returns a list of all global secrets.
|
|
||||||
func (c *client) GlobalSecretList() ([]*Secret, error) {
|
|
||||||
var out []*Secret
|
|
||||||
uri := fmt.Sprintf(pathGlobalSecrets, c.addr)
|
|
||||||
err := c.get(uri, &out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalSecretCreate creates a global secret.
|
|
||||||
func (c *client) GlobalSecretCreate(in *Secret) (*Secret, error) {
|
|
||||||
out := new(Secret)
|
|
||||||
uri := fmt.Sprintf(pathGlobalSecrets, c.addr)
|
|
||||||
err := c.post(uri, in, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalSecretUpdate updates a global secret.
|
|
||||||
func (c *client) GlobalSecretUpdate(in *Secret) (*Secret, error) {
|
|
||||||
out := new(Secret)
|
|
||||||
uri := fmt.Sprintf(pathGlobalSecret, c.addr, in.Name)
|
|
||||||
err := c.patch(uri, in, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalSecretDelete deletes a global secret.
|
|
||||||
func (c *client) GlobalSecretDelete(secret string) error {
|
|
||||||
uri := fmt.Sprintf(pathGlobalSecret, c.addr, secret)
|
|
||||||
return c.delete(uri)
|
|
||||||
}
|
|
|
@ -190,42 +190,42 @@ type Client interface {
|
||||||
// QueueInfo returns the queue state.
|
// QueueInfo returns the queue state.
|
||||||
QueueInfo() (*Info, error)
|
QueueInfo() (*Info, error)
|
||||||
|
|
||||||
// LogLevel returns the current logging level.
|
// LogLevel returns the current logging level
|
||||||
LogLevel() (*LogLevel, error)
|
LogLevel() (*LogLevel, error)
|
||||||
|
|
||||||
// SetLogLevel sets the server's logging level.
|
// SetLogLevel sets the server's logging level
|
||||||
SetLogLevel(logLevel *LogLevel) (*LogLevel, error)
|
SetLogLevel(logLevel *LogLevel) (*LogLevel, error)
|
||||||
|
|
||||||
// CronList list all cron jobs of a repo.
|
// CronList list all cron jobs of a repo
|
||||||
CronList(repoID int64) ([]*Cron, error)
|
CronList(repoID int64) ([]*Cron, error)
|
||||||
|
|
||||||
// CronGet get a specific cron job of a repo by id.
|
// CronGet get a specific cron job of a repo by id
|
||||||
CronGet(repoID, cronID int64) (*Cron, error)
|
CronGet(repoID, cronID int64) (*Cron, error)
|
||||||
|
|
||||||
// CronDelete delete a specific cron job of a repo by id.
|
// CronDelete delete a specific cron job of a repo by id
|
||||||
CronDelete(repoID, cronID int64) error
|
CronDelete(repoID, cronID int64) error
|
||||||
|
|
||||||
// CronCreate create a new cron job in a repo.
|
// CronCreate create a new cron job in a repo
|
||||||
CronCreate(repoID int64, cron *Cron) (*Cron, error)
|
CronCreate(repoID int64, cron *Cron) (*Cron, error)
|
||||||
|
|
||||||
// CronUpdate update an existing cron job of a repo.
|
// CronUpdate update an existing cron job of a repo
|
||||||
CronUpdate(repoID int64, cron *Cron) (*Cron, error)
|
CronUpdate(repoID int64, cron *Cron) (*Cron, error)
|
||||||
|
|
||||||
// AgentList returns a list of all registered agents.
|
// AgentList returns a list of all registered agents
|
||||||
AgentList() ([]*Agent, error)
|
AgentList() ([]*Agent, error)
|
||||||
|
|
||||||
// Agent returns an agent by id.
|
// Agent returns an agent by id
|
||||||
Agent(int64) (*Agent, error)
|
Agent(int64) (*Agent, error)
|
||||||
|
|
||||||
// AgentCreate creates a new agent.
|
// AgentCreate creates a new agent
|
||||||
AgentCreate(*Agent) (*Agent, error)
|
AgentCreate(*Agent) (*Agent, error)
|
||||||
|
|
||||||
// AgentUpdate updates an existing agent.
|
// AgentUpdate updates an existing agent
|
||||||
AgentUpdate(*Agent) (*Agent, error)
|
AgentUpdate(*Agent) (*Agent, error)
|
||||||
|
|
||||||
// AgentDelete deletes an agent.
|
// AgentDelete deletes an agent
|
||||||
AgentDelete(int64) error
|
AgentDelete(int64) error
|
||||||
|
|
||||||
// AgentTasksList returns a list of all tasks executed by an agent.
|
// AgentTasksList returns a list of all tasks executed by an agent
|
||||||
AgentTasksList(int64) ([]*Task, error)
|
AgentTasksList(int64) ([]*Task, error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
package woodpecker
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
const (
|
|
||||||
pathOrg = "%s/api/orgs/%d"
|
|
||||||
pathOrgLookup = "%s/api/orgs/lookup/%s"
|
|
||||||
pathOrgSecrets = "%s/api/orgs/%d/secrets"
|
|
||||||
pathOrgSecret = "%s/api/orgs/%d/secrets/%s"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Org returns an organization by id.
|
|
||||||
func (c *client) Org(orgID int64) (*Org, error) {
|
|
||||||
out := new(Org)
|
|
||||||
uri := fmt.Sprintf(pathOrg, c.addr, orgID)
|
|
||||||
err := c.get(uri, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrgLookup returns a organization by its name.
|
|
||||||
func (c *client) OrgLookup(name string) (*Org, error) {
|
|
||||||
out := new(Org)
|
|
||||||
uri := fmt.Sprintf(pathOrgLookup, c.addr, name)
|
|
||||||
err := c.get(uri, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrgSecret returns an organization secret by name.
|
|
||||||
func (c *client) OrgSecret(orgID int64, secret string) (*Secret, error) {
|
|
||||||
out := new(Secret)
|
|
||||||
uri := fmt.Sprintf(pathOrgSecret, c.addr, orgID, secret)
|
|
||||||
err := c.get(uri, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrgSecretList returns a list of all organization secrets.
|
|
||||||
func (c *client) OrgSecretList(orgID int64) ([]*Secret, error) {
|
|
||||||
var out []*Secret
|
|
||||||
uri := fmt.Sprintf(pathOrgSecrets, c.addr, orgID)
|
|
||||||
err := c.get(uri, &out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrgSecretCreate creates an organization secret.
|
|
||||||
func (c *client) OrgSecretCreate(orgID int64, in *Secret) (*Secret, error) {
|
|
||||||
out := new(Secret)
|
|
||||||
uri := fmt.Sprintf(pathOrgSecrets, c.addr, orgID)
|
|
||||||
err := c.post(uri, in, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrgSecretUpdate updates an organization secret.
|
|
||||||
func (c *client) OrgSecretUpdate(orgID int64, in *Secret) (*Secret, error) {
|
|
||||||
out := new(Secret)
|
|
||||||
uri := fmt.Sprintf(pathOrgSecret, c.addr, orgID, in.Name)
|
|
||||||
err := c.patch(uri, in, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrgSecretDelete deletes an organization secret.
|
|
||||||
func (c *client) OrgSecretDelete(orgID int64, secret string) error {
|
|
||||||
uri := fmt.Sprintf(pathOrgSecret, c.addr, orgID, secret)
|
|
||||||
return c.delete(uri)
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
package woodpecker
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
const pathPipelineQueue = "%s/api/pipelines"
|
|
||||||
|
|
||||||
// PipelineQueue returns a list of enqueued pipelines.
|
|
||||||
func (c *client) PipelineQueue() ([]*Feed, error) {
|
|
||||||
var out []*Feed
|
|
||||||
uri := fmt.Sprintf(pathPipelineQueue, c.addr)
|
|
||||||
err := c.get(uri, &out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
package woodpecker
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
const pathQueue = "%s/api/queue"
|
|
||||||
|
|
||||||
// QueueInfo returns queue info.
|
|
||||||
func (c *client) QueueInfo() (*Info, error) {
|
|
||||||
out := new(Info)
|
|
||||||
uri := fmt.Sprintf(pathQueue+"/info", c.addr)
|
|
||||||
err := c.get(uri, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
package woodpecker
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestClient_QueueInfo(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
handler http.HandlerFunc
|
|
||||||
expected *Info
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "success",
|
|
||||||
handler: func(w http.ResponseWriter, _ *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
_, err := fmt.Fprint(w, `{
|
|
||||||
"pending": null,
|
|
||||||
"running": [
|
|
||||||
{
|
|
||||||
"id": "4696",
|
|
||||||
"data": "",
|
|
||||||
"labels": {
|
|
||||||
"platform": "linux/amd64",
|
|
||||||
"repo": "woodpecker-ci/woodpecker"
|
|
||||||
},
|
|
||||||
"Dependencies": [],
|
|
||||||
"DepStatus": {},
|
|
||||||
"RunOn": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stats": {
|
|
||||||
"worker_count": 2,
|
|
||||||
"pending_count": 0,
|
|
||||||
"waiting_on_deps_count": 0,
|
|
||||||
"running_count": 0,
|
|
||||||
"completed_count": 0
|
|
||||||
},
|
|
||||||
"Paused": false
|
|
||||||
}`)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
},
|
|
||||||
expected: &Info{
|
|
||||||
Running: []Task{
|
|
||||||
{
|
|
||||||
ID: "4696",
|
|
||||||
Data: []byte{},
|
|
||||||
Labels: map[string]string{
|
|
||||||
"platform": "linux/amd64",
|
|
||||||
"repo": "woodpecker-ci/woodpecker",
|
|
||||||
},
|
|
||||||
Dependencies: []string{},
|
|
||||||
DepStatus: nil,
|
|
||||||
RunOn: nil,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Stats: struct {
|
|
||||||
Workers int `json:"worker_count"`
|
|
||||||
Pending int `json:"pending_count"`
|
|
||||||
WaitingOnDeps int `json:"waiting_on_deps_count"`
|
|
||||||
Running int `json:"running_count"`
|
|
||||||
Complete int `json:"completed_count"`
|
|
||||||
}{
|
|
||||||
Workers: 2,
|
|
||||||
Pending: 0,
|
|
||||||
WaitingOnDeps: 0,
|
|
||||||
Running: 0,
|
|
||||||
Complete: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "server error",
|
|
||||||
handler: func(w http.ResponseWriter, _ *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
},
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "invalid response",
|
|
||||||
handler: func(w http.ResponseWriter, _ *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
_, err := fmt.Fprint(w, `invalid json`)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
},
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(tt.handler)
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
client := NewClient(ts.URL, http.DefaultClient)
|
|
||||||
info, err := client.QueueInfo()
|
|
||||||
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, tt.expected, info)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,304 +0,0 @@
|
||||||
package woodpecker
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
const (
|
|
||||||
pathRepoPost = "%s/api/repos?forge_remote_id=%d"
|
|
||||||
pathRepo = "%s/api/repos/%d"
|
|
||||||
pathRepoLookup = "%s/api/repos/lookup/%s"
|
|
||||||
pathRepoMove = "%s/api/repos/%d/move?to=%s"
|
|
||||||
pathChown = "%s/api/repos/%d/chown"
|
|
||||||
pathRepair = "%s/api/repos/%d/repair"
|
|
||||||
pathPipelines = "%s/api/repos/%d/pipelines"
|
|
||||||
pathPipeline = "%s/api/repos/%d/pipelines/%v"
|
|
||||||
pathPipelineLogs = "%s/api/repos/%d/logs/%d"
|
|
||||||
pathStepLogs = "%s/api/repos/%d/logs/%d/%d"
|
|
||||||
pathApprove = "%s/api/repos/%d/pipelines/%d/approve"
|
|
||||||
pathDecline = "%s/api/repos/%d/pipelines/%d/decline"
|
|
||||||
pathStop = "%s/api/repos/%d/pipelines/%d/cancel"
|
|
||||||
pathRepoSecrets = "%s/api/repos/%d/secrets"
|
|
||||||
pathRepoSecret = "%s/api/repos/%d/secrets/%s"
|
|
||||||
pathRepoRegistries = "%s/api/repos/%d/registry"
|
|
||||||
pathRepoRegistry = "%s/api/repos/%d/registry/%s"
|
|
||||||
pathRepoCrons = "%s/api/repos/%d/cron"
|
|
||||||
pathRepoCron = "%s/api/repos/%d/cron/%d"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Repo returns a repository by id.
|
|
||||||
func (c *client) Repo(repoID int64) (*Repo, error) {
|
|
||||||
out := new(Repo)
|
|
||||||
uri := fmt.Sprintf(pathRepo, c.addr, repoID)
|
|
||||||
err := c.get(uri, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RepoLookup returns a repository by name.
|
|
||||||
func (c *client) RepoLookup(fullName string) (*Repo, error) {
|
|
||||||
out := new(Repo)
|
|
||||||
uri := fmt.Sprintf(pathRepoLookup, c.addr, fullName)
|
|
||||||
err := c.get(uri, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RepoPost activates a repository.
|
|
||||||
func (c *client) RepoPost(forgeRemoteID int64) (*Repo, error) {
|
|
||||||
out := new(Repo)
|
|
||||||
uri := fmt.Sprintf(pathRepoPost, c.addr, forgeRemoteID)
|
|
||||||
err := c.post(uri, nil, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RepoChown updates a repository owner.
|
|
||||||
func (c *client) RepoChown(repoID int64) (*Repo, error) {
|
|
||||||
out := new(Repo)
|
|
||||||
uri := fmt.Sprintf(pathChown, c.addr, repoID)
|
|
||||||
err := c.post(uri, nil, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RepoRepair repairs the repository hooks.
|
|
||||||
func (c *client) RepoRepair(repoID int64) error {
|
|
||||||
uri := fmt.Sprintf(pathRepair, c.addr, repoID)
|
|
||||||
return c.post(uri, nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RepoPatch updates a repository.
|
|
||||||
func (c *client) RepoPatch(repoID int64, in *RepoPatch) (*Repo, error) {
|
|
||||||
out := new(Repo)
|
|
||||||
uri := fmt.Sprintf(pathRepo, c.addr, repoID)
|
|
||||||
err := c.patch(uri, in, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RepoDel deletes a repository.
|
|
||||||
func (c *client) RepoDel(repoID int64) error {
|
|
||||||
uri := fmt.Sprintf(pathRepo, c.addr, repoID)
|
|
||||||
err := c.delete(uri)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RepoMove moves a repository.
|
|
||||||
func (c *client) RepoMove(repoID int64, newFullName string) error {
|
|
||||||
uri := fmt.Sprintf(pathRepoMove, c.addr, repoID, newFullName)
|
|
||||||
return c.post(uri, nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Registry returns a registry by hostname.
|
|
||||||
func (c *client) Registry(repoID int64, hostname string) (*Registry, error) {
|
|
||||||
out := new(Registry)
|
|
||||||
uri := fmt.Sprintf(pathRepoRegistry, c.addr, repoID, hostname)
|
|
||||||
err := c.get(uri, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegistryList returns a list of all repository registries.
|
|
||||||
func (c *client) RegistryList(repoID int64) ([]*Registry, error) {
|
|
||||||
var out []*Registry
|
|
||||||
uri := fmt.Sprintf(pathRepoRegistries, c.addr, repoID)
|
|
||||||
err := c.get(uri, &out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegistryCreate creates a registry.
|
|
||||||
func (c *client) RegistryCreate(repoID int64, in *Registry) (*Registry, error) {
|
|
||||||
out := new(Registry)
|
|
||||||
uri := fmt.Sprintf(pathRepoRegistries, c.addr, repoID)
|
|
||||||
err := c.post(uri, in, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegistryUpdate updates a registry.
|
|
||||||
func (c *client) RegistryUpdate(repoID int64, in *Registry) (*Registry, error) {
|
|
||||||
out := new(Registry)
|
|
||||||
uri := fmt.Sprintf(pathRepoRegistry, c.addr, repoID, in.Address)
|
|
||||||
err := c.patch(uri, in, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegistryDelete deletes a registry.
|
|
||||||
func (c *client) RegistryDelete(repoID int64, hostname string) error {
|
|
||||||
uri := fmt.Sprintf(pathRepoRegistry, c.addr, repoID, hostname)
|
|
||||||
return c.delete(uri)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Secret returns a secret by name.
|
|
||||||
func (c *client) Secret(repoID int64, secret string) (*Secret, error) {
|
|
||||||
out := new(Secret)
|
|
||||||
uri := fmt.Sprintf(pathRepoSecret, c.addr, repoID, secret)
|
|
||||||
err := c.get(uri, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SecretList returns a list of all repository secrets.
|
|
||||||
func (c *client) SecretList(repoID int64) ([]*Secret, error) {
|
|
||||||
var out []*Secret
|
|
||||||
uri := fmt.Sprintf(pathRepoSecrets, c.addr, repoID)
|
|
||||||
err := c.get(uri, &out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SecretCreate creates a secret.
|
|
||||||
func (c *client) SecretCreate(repoID int64, in *Secret) (*Secret, error) {
|
|
||||||
out := new(Secret)
|
|
||||||
uri := fmt.Sprintf(pathRepoSecrets, c.addr, repoID)
|
|
||||||
err := c.post(uri, in, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SecretUpdate updates a secret.
|
|
||||||
func (c *client) SecretUpdate(repoID int64, in *Secret) (*Secret, error) {
|
|
||||||
out := new(Secret)
|
|
||||||
uri := fmt.Sprintf(pathRepoSecret, c.addr, repoID, in.Name)
|
|
||||||
err := c.patch(uri, in, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SecretDelete deletes a secret.
|
|
||||||
func (c *client) SecretDelete(repoID int64, secret string) error {
|
|
||||||
uri := fmt.Sprintf(pathRepoSecret, c.addr, repoID, secret)
|
|
||||||
return c.delete(uri)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CronList returns a list of cronjobs for the specified repository.
|
|
||||||
func (c *client) CronList(repoID int64) ([]*Cron, error) {
|
|
||||||
out := make([]*Cron, 0, 5)
|
|
||||||
uri := fmt.Sprintf(pathRepoCrons, c.addr, repoID)
|
|
||||||
return out, c.get(uri, &out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CronCreate creates a new cron job for the specified repository.
|
|
||||||
func (c *client) CronCreate(repoID int64, in *Cron) (*Cron, error) {
|
|
||||||
out := new(Cron)
|
|
||||||
uri := fmt.Sprintf(pathRepoCrons, c.addr, repoID)
|
|
||||||
return out, c.post(uri, in, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CronUpdate updates an existing cron job for the specified repository.
|
|
||||||
func (c *client) CronUpdate(repoID int64, in *Cron) (*Cron, error) {
|
|
||||||
out := new(Cron)
|
|
||||||
uri := fmt.Sprintf(pathRepoCron, c.addr, repoID, in.ID)
|
|
||||||
err := c.patch(uri, in, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// CronDelete deletes a cron job by cron-id for the specified repository.
|
|
||||||
func (c *client) CronDelete(repoID, cronID int64) error {
|
|
||||||
uri := fmt.Sprintf(pathRepoCron, c.addr, repoID, cronID)
|
|
||||||
return c.delete(uri)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CronGet returns a cron job by cron-id for the specified repository.
|
|
||||||
func (c *client) CronGet(repoID, cronID int64) (*Cron, error) {
|
|
||||||
out := new(Cron)
|
|
||||||
uri := fmt.Sprintf(pathRepoCron, c.addr, repoID, cronID)
|
|
||||||
return out, c.get(uri, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pipeline returns a repository pipeline by pipeline-id.
|
|
||||||
func (c *client) Pipeline(repoID, pipeline int64) (*Pipeline, error) {
|
|
||||||
out := new(Pipeline)
|
|
||||||
uri := fmt.Sprintf(pathPipeline, c.addr, repoID, pipeline)
|
|
||||||
err := c.get(uri, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pipeline returns the latest repository pipeline by branch.
|
|
||||||
func (c *client) PipelineLast(repoID int64, branch string) (*Pipeline, error) {
|
|
||||||
out := new(Pipeline)
|
|
||||||
uri := fmt.Sprintf(pathPipeline, c.addr, repoID, "latest")
|
|
||||||
if len(branch) != 0 {
|
|
||||||
uri += "?branch=" + branch
|
|
||||||
}
|
|
||||||
err := c.get(uri, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// PipelineList returns a list of recent pipelines for the
|
|
||||||
// the specified repository.
|
|
||||||
func (c *client) PipelineList(repoID int64) ([]*Pipeline, error) {
|
|
||||||
var out []*Pipeline
|
|
||||||
uri := fmt.Sprintf(pathPipelines, c.addr, repoID)
|
|
||||||
err := c.get(uri, &out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// PipelineCreate creates a new pipeline for the specified repository.
|
|
||||||
func (c *client) PipelineCreate(repoID int64, options *PipelineOptions) (*Pipeline, error) {
|
|
||||||
var out *Pipeline
|
|
||||||
uri := fmt.Sprintf(pathPipelines, c.addr, repoID)
|
|
||||||
err := c.post(uri, options, &out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// PipelineStart re-starts a stopped pipeline.
|
|
||||||
func (c *client) PipelineStart(repoID, pipeline int64, params map[string]string) (*Pipeline, error) {
|
|
||||||
out := new(Pipeline)
|
|
||||||
val := mapValues(params)
|
|
||||||
uri := fmt.Sprintf(pathPipeline, c.addr, repoID, pipeline)
|
|
||||||
err := c.post(uri+"?"+val.Encode(), nil, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// PipelineStop cancels the running step.
|
|
||||||
func (c *client) PipelineStop(repoID, pipeline int64) error {
|
|
||||||
uri := fmt.Sprintf(pathStop, c.addr, repoID, pipeline)
|
|
||||||
err := c.post(uri, nil, nil)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// PipelineApprove approves a blocked pipeline.
|
|
||||||
func (c *client) PipelineApprove(repoID, pipeline int64) (*Pipeline, error) {
|
|
||||||
out := new(Pipeline)
|
|
||||||
uri := fmt.Sprintf(pathApprove, c.addr, repoID, pipeline)
|
|
||||||
err := c.post(uri, nil, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// PipelineDecline declines a blocked pipeline.
|
|
||||||
func (c *client) PipelineDecline(repoID, pipeline int64) (*Pipeline, error) {
|
|
||||||
out := new(Pipeline)
|
|
||||||
uri := fmt.Sprintf(pathDecline, c.addr, repoID, pipeline)
|
|
||||||
err := c.post(uri, nil, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// PipelineKill force kills the running pipeline.
|
|
||||||
func (c *client) PipelineKill(repoID, pipeline int64) error {
|
|
||||||
uri := fmt.Sprintf(pathPipeline, c.addr, repoID, pipeline)
|
|
||||||
err := c.delete(uri)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogsPurge purges the pipeline all steps logs for the specified pipeline.
|
|
||||||
func (c *client) LogsPurge(repoID, pipeline int64) error {
|
|
||||||
uri := fmt.Sprintf(pathPipelineLogs, c.addr, repoID, pipeline)
|
|
||||||
err := c.delete(uri)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deploy triggers a deployment for an existing pipeline using the
|
|
||||||
// specified target environment.
|
|
||||||
func (c *client) Deploy(repoID, pipeline int64, env string, params map[string]string) (*Pipeline, error) {
|
|
||||||
out := new(Pipeline)
|
|
||||||
val := mapValues(params)
|
|
||||||
val.Set("event", EventDeploy)
|
|
||||||
val.Set("deploy_to", env)
|
|
||||||
uri := fmt.Sprintf(pathPipeline, c.addr, repoID, pipeline)
|
|
||||||
err := c.post(uri+"?"+val.Encode(), nil, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// StepLogEntries returns the pipeline logs for the specified step.
|
|
||||||
func (c *client) StepLogEntries(repoID, num, step int64) ([]*LogEntry, error) {
|
|
||||||
uri := fmt.Sprintf(pathStepLogs, c.addr, repoID, num, step)
|
|
||||||
var out []*LogEntry
|
|
||||||
err := c.get(uri, &out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// StepLogsPurge purges the pipeline logs for the specified step.
|
|
||||||
func (c *client) StepLogsPurge(repoID, pipelineNumber, stepID int64) error {
|
|
||||||
uri := fmt.Sprintf(pathStepLogs, c.addr, repoID, pipelineNumber, stepID)
|
|
||||||
err := c.delete(uri)
|
|
||||||
return err
|
|
||||||
}
|
|
|
@ -181,22 +181,12 @@ type (
|
||||||
Commit string `json:"commit,omitempty"`
|
Commit string `json:"commit,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueueStats struct {
|
|
||||||
// Workers int `json:"worker_count"`
|
|
||||||
// Pending int `json:"pending_count"`
|
|
||||||
// WaitingOnDeps int `json:"waiting_on_deps_count"`
|
|
||||||
// Running int `json:"running_count"`
|
|
||||||
// Complete int `json:"completed_count"`
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Info provides queue stats.
|
// Info provides queue stats.
|
||||||
Info struct {
|
Info struct {
|
||||||
Pending []Task `json:"pending"`
|
Pending []Task `json:"pending"`
|
||||||
WaitingOnDeps []Task `json:"waiting_on_deps"`
|
WaitingOnDeps []Task `json:"waiting_on_deps"`
|
||||||
Running []Task `json:"running"`
|
Running []Task `json:"running"`
|
||||||
// TODO use dedicated struct in 3.x
|
Stats struct {
|
||||||
// Stats QueueStats `json:"stats"`
|
|
||||||
Stats struct {
|
|
||||||
Workers int `json:"worker_count"`
|
Workers int `json:"worker_count"`
|
||||||
Pending int `json:"pending_count"`
|
Pending int `json:"pending_count"`
|
||||||
WaitingOnDeps int `json:"waiting_on_deps_count"`
|
WaitingOnDeps int `json:"waiting_on_deps_count"`
|
||||||
|
@ -206,7 +196,7 @@ type (
|
||||||
Paused bool `json:"paused,omitempty"`
|
Paused bool `json:"paused,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogLevel is for checking/setting logging level.
|
// LogLevel is for checking/setting logging level
|
||||||
LogLevel struct {
|
LogLevel struct {
|
||||||
Level string `json:"log-level"`
|
Level string `json:"log-level"`
|
||||||
}
|
}
|
||||||
|
@ -221,7 +211,7 @@ type (
|
||||||
Type LogEntryType `json:"type"`
|
Type LogEntryType `json:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cron is the JSON data of a cron job.
|
// Cron is the JSON data of a cron job
|
||||||
Cron struct {
|
Cron struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
@ -233,13 +223,13 @@ type (
|
||||||
Branch string `json:"branch"`
|
Branch string `json:"branch"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PipelineOptions is the JSON data for creating a new pipeline.
|
// PipelineOptions is the JSON data for creating a new pipeline
|
||||||
PipelineOptions struct {
|
PipelineOptions struct {
|
||||||
Branch string `json:"branch"`
|
Branch string `json:"branch"`
|
||||||
Variables map[string]string `json:"variables"`
|
Variables map[string]string `json:"variables"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Agent is the JSON data for an agent.
|
// Agent is the JSON data for an agent
|
||||||
Agent struct {
|
Agent struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Created int64 `json:"created"`
|
Created int64 `json:"created"`
|
||||||
|
@ -255,7 +245,7 @@ type (
|
||||||
NoSchedule bool `json:"no_schedule"`
|
NoSchedule bool `json:"no_schedule"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Task is the JSON data for a task.
|
// Task is the JSON data for a task
|
||||||
Task struct {
|
Task struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Data []byte `json:"data"`
|
Data []byte `json:"data"`
|
||||||
|
@ -266,7 +256,7 @@ type (
|
||||||
AgentID int64 `json:"agent_id"`
|
AgentID int64 `json:"agent_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Org is the JSON data for an organization.
|
// Org is the JSON data for an organization
|
||||||
Org struct {
|
Org struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
package woodpecker
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
const (
|
|
||||||
pathSelf = "%s/api/user"
|
|
||||||
pathRepos = "%s/api/user/repos"
|
|
||||||
pathUsers = "%s/api/users"
|
|
||||||
pathUser = "%s/api/users/%s"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Self returns the currently authenticated user.
|
|
||||||
func (c *client) Self() (*User, error) {
|
|
||||||
out := new(User)
|
|
||||||
uri := fmt.Sprintf(pathSelf, c.addr)
|
|
||||||
err := c.get(uri, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// User returns a user by login.
|
|
||||||
func (c *client) User(login string) (*User, error) {
|
|
||||||
out := new(User)
|
|
||||||
uri := fmt.Sprintf(pathUser, c.addr, login)
|
|
||||||
err := c.get(uri, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserList returns a list of all registered users.
|
|
||||||
func (c *client) UserList() ([]*User, error) {
|
|
||||||
var out []*User
|
|
||||||
uri := fmt.Sprintf(pathUsers, c.addr)
|
|
||||||
err := c.get(uri, &out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserPost creates a new user account.
|
|
||||||
func (c *client) UserPost(in *User) (*User, error) {
|
|
||||||
out := new(User)
|
|
||||||
uri := fmt.Sprintf(pathUsers, c.addr)
|
|
||||||
err := c.post(uri, in, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserPatch updates a user account.
|
|
||||||
func (c *client) UserPatch(in *User) (*User, error) {
|
|
||||||
out := new(User)
|
|
||||||
uri := fmt.Sprintf(pathUser, c.addr, in.Login)
|
|
||||||
err := c.patch(uri, in, out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserDel deletes a user account.
|
|
||||||
func (c *client) UserDel(login string) error {
|
|
||||||
uri := fmt.Sprintf(pathUser, c.addr, login)
|
|
||||||
err := c.delete(uri)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RepoList returns a list of all repositories to which
|
|
||||||
// the user has explicit access in the host system.
|
|
||||||
func (c *client) RepoList() ([]*Repo, error) {
|
|
||||||
var out []*Repo
|
|
||||||
uri := fmt.Sprintf(pathRepos, c.addr)
|
|
||||||
err := c.get(uri, &out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RepoListOpts returns a list of all repositories to which
|
|
||||||
// the user has explicit access in the host system.
|
|
||||||
func (c *client) RepoListOpts(all bool) ([]*Repo, error) {
|
|
||||||
var out []*Repo
|
|
||||||
uri := fmt.Sprintf(pathRepos+"?all=%v", c.addr, all)
|
|
||||||
err := c.get(uri, &out)
|
|
||||||
return out, err
|
|
||||||
}
|
|
|
@ -1,267 +0,0 @@
|
||||||
package woodpecker
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestClient_UserList(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
handler http.HandlerFunc
|
|
||||||
expected []*User
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "success",
|
|
||||||
handler: func(w http.ResponseWriter, _ *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
_, err := fmt.Fprint(w, `[{"id":1,"login":"user1"},{"id":2,"login":"user2"}]`)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
},
|
|
||||||
expected: []*User{{ID: 1, Login: "user1"}, {ID: 2, Login: "user2"}},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "empty response",
|
|
||||||
handler: func(w http.ResponseWriter, _ *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
_, err := fmt.Fprint(w, `[]`)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
},
|
|
||||||
expected: []*User{},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "server error",
|
|
||||||
handler: func(w http.ResponseWriter, _ *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
},
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(tt.handler)
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
client := NewClient(ts.URL, http.DefaultClient)
|
|
||||||
users, err := client.UserList()
|
|
||||||
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, users, tt.expected)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_UserPost(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
handler http.HandlerFunc
|
|
||||||
input *User
|
|
||||||
expected *User
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "success",
|
|
||||||
handler: func(w http.ResponseWriter, _ *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusCreated)
|
|
||||||
_, err := fmt.Fprint(w, `{"id":1,"login":"new_user"}`)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
},
|
|
||||||
input: &User{Login: "new_user"},
|
|
||||||
expected: &User{ID: 1, Login: "new_user"},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "invalid input",
|
|
||||||
handler: func(w http.ResponseWriter, _ *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
},
|
|
||||||
input: &User{},
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "server error",
|
|
||||||
handler: func(w http.ResponseWriter, _ *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
},
|
|
||||||
input: &User{Login: "new_user"},
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(tt.handler)
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
client := NewClient(ts.URL, http.DefaultClient)
|
|
||||||
user, err := client.UserPost(tt.input)
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, user, tt.expected)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_UserPatch(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
handler http.HandlerFunc
|
|
||||||
input *User
|
|
||||||
expected *User
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "success",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodPatch {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
_, err := fmt.Fprint(w, `{"id":1,"login":"updated_user"}`)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
},
|
|
||||||
input: &User{ID: 1, Login: "existing_user"},
|
|
||||||
expected: &User{ID: 1, Login: "updated_user"},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "not found",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodPatch {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusNotFound)
|
|
||||||
},
|
|
||||||
input: &User{ID: 999, Login: "nonexistent_user"},
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "invalid input",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodPatch {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
},
|
|
||||||
input: &User{},
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "server error",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodPatch {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
},
|
|
||||||
input: &User{ID: 1, Login: "existing_user"},
|
|
||||||
expected: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(tt.handler)
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
client := NewClient(ts.URL, http.DefaultClient)
|
|
||||||
user, err := client.UserPatch(tt.input)
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, user, tt.expected)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_UserDel(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
handler http.HandlerFunc
|
|
||||||
login string
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "success",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodDelete {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
},
|
|
||||||
login: "existing_user",
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "not found",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodDelete {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusNotFound)
|
|
||||||
},
|
|
||||||
login: "nonexistent_user",
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "server error",
|
|
||||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodDelete {
|
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
},
|
|
||||||
login: "existing_user",
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(tt.handler)
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
client := NewClient(ts.URL, http.DefaultClient)
|
|
||||||
err := client.UserDel(tt.login)
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue