mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-01-02 21:58:43 +00:00
Update swagger API specification (#1782)
# Summary This PR drops the outdated former swagger.yaml/json and introduced automatic API document generation from Go code. The generated code is also used to generate documentation/markdown for the community page, as well as enable the Woodpecker server to serve a Swagger Web UI for manual tinkering. I did opt-in for gin-swagger, a middleware for the Gin framework, to ease implementation and have a sophisticated output. This middleware only produces Swagger v2 specs. AFAIK the newer OpenApi 3x tooling is not yet that mature, so I guess that's fine for now. ## Implemenation notes - former swagger.json files removed - former // swagger godocs removed - introduced new dependency gin-swagger, which uses godoc annotations on top of Gin Handler functions. - reworked Makefile to automatically generate Go code for the server - introduce new dependency go-swagger, to generate Markdown for documentation purposes - add a Swagger Web UI, incl. capabilities for manual API exploration - consider relative root paths in the implementation - write documentation for all exposed API endpoints - incl. API docs in the community website (auto-generated) - provide developer documentation, for the Woodpecker authors - no other existing logic/code was intentionally changed --------- close #292 --------- Co-authored-by: qwerty287 <80460567+qwerty287@users.noreply.github.com> Co-authored-by: 6543 <6543@obermui.de>
This commit is contained in:
parent
b9731d8da9
commit
14177635b6
49 changed files with 6047 additions and 1153 deletions
1
.ecrc
1
.ecrc
|
@ -8,6 +8,7 @@
|
|||
"node_modules",
|
||||
"server/store/datastore/migration/testfiles/sqlite.db",
|
||||
"server/store/datastore/feed.go",
|
||||
"cmd/server/docs/docs.go",
|
||||
"_test.go",
|
||||
"Makefile"
|
||||
]
|
||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -40,9 +40,6 @@ extras/
|
|||
/build/
|
||||
/dist/
|
||||
|
||||
server/swagger/files/*.json
|
||||
server/swagger/swagger_gen.go
|
||||
|
||||
docs/venv
|
||||
|
||||
# helm charts
|
||||
|
@ -51,3 +48,4 @@ docs/venv
|
|||
|
||||
### Generated by CI ###
|
||||
docs/docs/40-cli.md
|
||||
docs/docs/20-usage/90-rest-api.md
|
||||
|
|
|
@ -40,10 +40,6 @@ run:
|
|||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- path: woodpecker-go/woodpecker/client.go|server/swagger/swagger.go
|
||||
linters:
|
||||
- deadcode
|
||||
- unused
|
||||
# gin force us to use string as context key
|
||||
- path: server/store/context.go
|
||||
linters:
|
||||
|
|
|
@ -45,6 +45,16 @@ pipeline:
|
|||
when:
|
||||
path: *when_path
|
||||
|
||||
check_swagger:
|
||||
image: *golang_image
|
||||
group: test
|
||||
commands:
|
||||
- "make generate-swagger"
|
||||
- "DIFF=$(git diff | head)"
|
||||
- "[ -n \"$DIFF\" ] && { echo \"swagger not up to date, exec 'make generate-swagger' and commit\"; exit 1; } || true"
|
||||
when:
|
||||
path: *when_path
|
||||
|
||||
lint-editorconfig:
|
||||
image: mstruebing/editorconfig-checker
|
||||
group: test
|
||||
|
|
11
Makefile
11
Makefile
|
@ -91,9 +91,12 @@ clean: ## Clean build artifacts
|
|||
@[ "1" != "$(shell docker image ls woodpecker/make:local -a | wc -l)" ] && docker image rm woodpecker/make:local || echo no docker image to clean
|
||||
|
||||
.PHONY: generate
|
||||
generate: ## Run all code generations
|
||||
generate: generate-swagger ## Run all code generations
|
||||
go generate ./...
|
||||
|
||||
generate-swagger: install-tools ## Run swagger code generation
|
||||
swag init -g server/api/ -g cmd/server/swagger.go --outputTypes go -output cmd/server/docs
|
||||
|
||||
check-xgo: ## Check if xgo is installed
|
||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
$(GO) install src.techknowlogick.com/xgo@latest; \
|
||||
|
@ -108,6 +111,9 @@ install-tools: ## Install development tools
|
|||
fi ; \
|
||||
hash gofumpt > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
go install mvdan.cc/gofumpt@latest; \
|
||||
fi ; \
|
||||
hash swag > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
go install github.com/swaggo/swag/cmd/swag@latest; \
|
||||
fi
|
||||
|
||||
ui-dependencies: ## Install UI dependencies
|
||||
|
@ -161,7 +167,7 @@ test: test-agent test-server test-server-datastore test-cli test-lib test-ui ##
|
|||
build-ui: ## Build UI
|
||||
(cd web/; pnpm install --frozen-lockfile; pnpm build)
|
||||
|
||||
build-server: build-ui ## Build server
|
||||
build-server: build-ui generate-swagger ## Build server
|
||||
CGO_ENABLED=${CGO_ENABLED} GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -ldflags '${LDFLAGS}' -o dist/woodpecker-server github.com/woodpecker-ci/woodpecker/cmd/server
|
||||
|
||||
build-agent: ## Build agent
|
||||
|
@ -284,5 +290,6 @@ bundle: bundle-agent bundle-server bundle-cli ## Create all bundles
|
|||
.PHONY: docs
|
||||
docs: ## Generate docs (currently only for the cli)
|
||||
go generate cmd/cli/app.go
|
||||
go generate cmd/server/swagger.go
|
||||
|
||||
endif
|
||||
|
|
4343
cmd/server/docs/docs.go
Normal file
4343
cmd/server/docs/docs.go
Normal file
File diff suppressed because it is too large
Load diff
|
@ -20,6 +20,7 @@ import (
|
|||
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
"github.com/urfave/cli/v2"
|
||||
_ "github.com/woodpecker-ci/woodpecker/cmd/server/docs"
|
||||
|
||||
"github.com/woodpecker-ci/woodpecker/version"
|
||||
)
|
||||
|
@ -32,6 +33,8 @@ func main() {
|
|||
app.Action = run
|
||||
app.Flags = flags
|
||||
|
||||
setupSwaggerStaticConfig()
|
||||
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
_, _ = fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
|
|
38
cmd/server/swagger.go
Normal file
38
cmd/server/swagger.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
// Copyright 2023 Woodpecker Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/woodpecker-ci/woodpecker/cmd/server/docs"
|
||||
"github.com/woodpecker-ci/woodpecker/version"
|
||||
)
|
||||
|
||||
// generate docs/docs/20-usage/90-rest-api.md via:
|
||||
//go:generate go run woodpecker_docs_gen.go swagger.go
|
||||
|
||||
// setupSwaggerStaticConfig initializes static content only (contacts, title and description)
|
||||
// for dynamic configuration of e.g. hostname, etc. see router.setupSwaggerConfigAndRoutes
|
||||
//
|
||||
// @contact.name Woodpecker CI Community
|
||||
// @contact.url https://woodpecker-ci.org/
|
||||
func setupSwaggerStaticConfig() {
|
||||
docs.SwaggerInfo.BasePath = "/api"
|
||||
docs.SwaggerInfo.InfoInstanceName = "api"
|
||||
docs.SwaggerInfo.Title = "Woodpecker CI API"
|
||||
docs.SwaggerInfo.Version = version.String()
|
||||
docs.SwaggerInfo.Description = "Woodpecker is a simple CI engine with great extensibility.\n" +
|
||||
"To get a personal access token (PAT) for authentication, please log in your Woodpecker server,\n" +
|
||||
"and go to you personal profile page, by clicking the user icon at the top right."
|
||||
}
|
134
cmd/server/woodpecker_docs_gen.go
Normal file
134
cmd/server/woodpecker_docs_gen.go
Normal file
|
@ -0,0 +1,134 @@
|
|||
// Copyright 2023 Woodpecker Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// ************************************************************************************************
|
||||
// This is a generator tool, to update the Markdown documentation for the woodpecker-ci.org website
|
||||
// ************************************************************************************************
|
||||
|
||||
//go:build generate
|
||||
// +build generate
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-swagger/go-swagger/generator"
|
||||
|
||||
"github.com/woodpecker-ci/woodpecker/cmd/server/docs"
|
||||
)
|
||||
|
||||
const restApiMarkdownInto = `
|
||||
# REST API
|
||||
|
||||
Woodpecker offers a comprehensive REST API, so you can integrate easily with from and with other tools.
|
||||
|
||||
## API specification
|
||||
|
||||
Starting with Woodpecker v1.0.0 a Swagger v2 API specification is served by the Woodpecker Server.
|
||||
The typical URL looks like "http://woodpecker-host/swagger/doc.json", where you can fetch the API specification.
|
||||
|
||||
## Swagger API UI
|
||||
|
||||
Starting with Woodpecker v1.0.0 a Swagger web user interface (UI) is served by the Woodpecker Server.
|
||||
Typically, you can open "http://woodpecker-host/swagger/index.html" in your browser, to explore the API documentation.
|
||||
|
||||
# API endpoint summary
|
||||
|
||||
This is a summary of available API endpoints.
|
||||
Please, keep in mind this documentation reflects latest development changes
|
||||
and might differ from your used server version.
|
||||
Its recommended to consult the Swagger API UI of your Woodpecker server,
|
||||
where you also have the chance to do manual exploration and live testing.
|
||||
|
||||
`
|
||||
|
||||
func main() {
|
||||
setupSwaggerStaticConfig()
|
||||
|
||||
specFile := createTempFileWithSwaggerSpec()
|
||||
defer os.Remove(specFile)
|
||||
markdown := generateTempMarkdown(specFile)
|
||||
|
||||
f, err := os.Create(path.Join("..", "..", "docs", "docs", "20-usage", "90-rest-api.md"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = f.WriteString(restApiMarkdownInto)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = f.WriteString(readGeneratedMarkdownAndSkipIntro(markdown))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func createTempFileWithSwaggerSpec() string {
|
||||
f, err := os.CreateTemp(os.TempDir(), "swagger.json")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = f.WriteString(docs.SwaggerInfo.ReadDoc())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return f.Name()
|
||||
}
|
||||
|
||||
func generateTempMarkdown(specFile string) string {
|
||||
// HINT: we MUST use underscores, since the library tends to rename things
|
||||
tempFile := fmt.Sprintf("woodpecker_api_%d.md", time.Now().UnixMilli())
|
||||
markdownFile := path.Join(os.TempDir(), tempFile)
|
||||
|
||||
opts := generator.GenOpts{
|
||||
GenOptsCommon: generator.GenOptsCommon{
|
||||
Spec: specFile,
|
||||
},
|
||||
}
|
||||
// TODO: contrib upstream a GenerateMarkdown that use io.Reader and io.Writer
|
||||
err := generator.GenerateMarkdown(markdownFile, []string{}, []string{}, &opts)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(markdownFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer os.Remove(markdownFile)
|
||||
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func readGeneratedMarkdownAndSkipIntro(markdown string) string {
|
||||
scanner := bufio.NewScanner(strings.NewReader(markdown))
|
||||
sb := strings.Builder{}
|
||||
foundActualContentStart := false
|
||||
for scanner.Scan() {
|
||||
text := scanner.Text()
|
||||
foundActualContentStart = foundActualContentStart || (strings.HasPrefix(text, "##") && strings.Contains(strings.ToLower(text), "all endpoints"))
|
||||
if foundActualContentStart {
|
||||
sb.WriteString(text + "\n")
|
||||
}
|
||||
}
|
||||
return sb.String()
|
||||
}
|
76
docs/docs/92-development/08-swagger.md
Normal file
76
docs/docs/92-development/08-swagger.md
Normal file
|
@ -0,0 +1,76 @@
|
|||
# Swagger, API Spec and Code Generation
|
||||
|
||||
Woodpecker uses [gin-swagger](https://github.com/swaggo/gin-swagger) middleware to automatically
|
||||
generate Swagger v2 API specifications and a nice looking Web UI from the source code.
|
||||
Also, the generated spec will be transformed into Markdown, using [go-swagger](https://github.com/go-swagger/go-swagger)
|
||||
and then being using on the community's website documentation.
|
||||
|
||||
It's paramount important to keep the gin handler function's godoc documentation up-to-date,
|
||||
to always have accurate API documentation.
|
||||
Whenever you change, add or enhance an API endpoint, please update the godocs.
|
||||
|
||||
You don't require any extra tools on your machine, all Swagger tooling is automatically fetched by standard Go tools.
|
||||
|
||||
### Gin-Handler API documentation guideline
|
||||
|
||||
Here's a typical example of how annotations for Swagger documentation look like...
|
||||
|
||||
```text
|
||||
--- server/api/user.go ---
|
||||
// @Summary Get a user
|
||||
// @Description Returns a user with the specified login name. Requires admin rights.
|
||||
// @Router /users/{login} [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} User
|
||||
// @Tags Users
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param login path string true "the user's login name"
|
||||
// @Param foobar query string false "optional foobar parameter"
|
||||
// @Param page query int false "for response pagination, page offset number" default(1)
|
||||
// @Param perPage query int false "for response pagination, max items per page" default(50)
|
||||
```
|
||||
|
||||
```text
|
||||
--- server/model/user.go ---
|
||||
type User struct {
|
||||
ID int64 `json:"id" xorm:"pk autoincr 'user_id'"`
|
||||
// ...
|
||||
} // @name User
|
||||
```
|
||||
|
||||
These guidelines aim to have consistent wording in the swagger doc:
|
||||
* first word after `@Summary` and `@Summary` are always uppercase
|
||||
* `@Summary` has no . (dot) at the end of the line
|
||||
* model structs shall use custom short names, to ease life for API consumers, using `@name`
|
||||
* `@Success` object or array declarations shall be short, this means the actual `model.User` struct must have a `@name` annotation, so that the model can be renderend in Swagger
|
||||
* when pagination is used, `@Parame page` and `@Parame perPage` must be added manually
|
||||
* `@Param Authorization` is almost always present, there are just a few un-protected endpoints
|
||||
|
||||
There are many examples in the server/api package, which you can use a blueprint.
|
||||
More enhanced information you can find here https://github.com/swaggo/swag/blob/master/README.md#declarative-comments-format
|
||||
|
||||
### Manual code generation
|
||||
|
||||
##### generate the server's Go code containing the Swagger
|
||||
|
||||
```shell
|
||||
make generate-swagger
|
||||
```
|
||||
|
||||
##### update the Markdown in the ./docs folder
|
||||
|
||||
```shell
|
||||
make docs
|
||||
```
|
||||
|
||||
##### auto-format swagger related godoc
|
||||
|
||||
```shell
|
||||
go run github.com/swaggo/swag/cmd/swag@latest fmt -g server/api/z.go
|
||||
```
|
||||
|
||||
**WARNING, known issue**: using swag v1.18.12 , there's a bug when running the `fmt` command,
|
||||
which makes the swagger generator failing, because it can't find the models/structs/types anymore.
|
||||
To fix it, please replace `// @name\tModelName` with `// @name ModelName`,
|
||||
which means, replace the tab (`\t`) with a space (` `).
|
||||
See https://github.com/swaggo/swag/pull/1594 == once this is merged and released, the mentioned issue is obsolete.
|
40
go.mod
40
go.mod
|
@ -20,6 +20,7 @@ require (
|
|||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/go-ap/httpsig v0.0.0-20221203064646-3647b4d88fdf
|
||||
github.com/go-sql-driver/mysql v1.7.1
|
||||
github.com/go-swagger/go-swagger v0.30.4
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
github.com/google/go-github/v39 v39.2.0
|
||||
github.com/google/tink/go v1.7.0
|
||||
|
@ -38,6 +39,9 @@ require (
|
|||
github.com/robfig/cron v1.2.0
|
||||
github.com/rs/zerolog v1.29.1
|
||||
github.com/stretchr/testify v1.8.3
|
||||
github.com/swaggo/files v1.0.1
|
||||
github.com/swaggo/gin-swagger v1.6.0
|
||||
github.com/swaggo/swag v1.16.1
|
||||
github.com/tevino/abool v1.2.0
|
||||
github.com/urfave/cli/v2 v2.25.3
|
||||
github.com/xanzy/go-gitlab v0.83.0
|
||||
|
@ -59,7 +63,12 @@ require (
|
|||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.2.0 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
|
@ -74,9 +83,17 @@ require (
|
|||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-fed/httpsig v1.1.0 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-openapi/analysis v0.21.4 // indirect
|
||||
github.com/go-openapi/errors v0.20.3 // indirect
|
||||
github.com/go-openapi/inflect v0.19.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.1 // indirect
|
||||
github.com/go-openapi/loads v0.21.2 // indirect
|
||||
github.com/go-openapi/runtime v0.25.0 // indirect
|
||||
github.com/go-openapi/spec v0.20.8 // indirect
|
||||
github.com/go-openapi/strfmt v0.21.3 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/go-openapi/validate v0.22.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||
|
@ -92,43 +109,61 @@ require (
|
|||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
|
||||
github.com/hashicorp/go-version v1.5.0 // indirect
|
||||
github.com/imdario/mergo v0.3.6 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/huandu/xstrings v1.3.3 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/kr/fs v0.1.0 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/libdns/libdns v0.2.1 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mholt/acmez v1.0.4 // indirect
|
||||
github.com/miekg/dns v1.1.50 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||
github.com/pkg/sftp v1.13.5 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/shopspring/decimal v1.2.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/spf13/afero v1.9.2 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.14.0 // indirect
|
||||
github.com/stretchr/objx v0.5.0 // indirect
|
||||
github.com/subosito/gotenv v1.4.1 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
go.mongodb.org/mongo-driver v1.11.1 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
go.uber.org/zap v1.23.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/mod v0.9.0 // indirect
|
||||
|
@ -140,6 +175,7 @@ require (
|
|||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gotest.tools/v3 v3.4.0 // indirect
|
||||
k8s.io/klog/v2 v2.90.1 // indirect
|
||||
|
|
|
@ -28,6 +28,16 @@ import (
|
|||
"github.com/woodpecker-ci/woodpecker/server/store"
|
||||
)
|
||||
|
||||
// GetAgents
|
||||
//
|
||||
// @Summary Get agent list
|
||||
// @Router /agents [get]
|
||||
// @Produce json
|
||||
// @Success 200 {array} Agent
|
||||
// @Tags Agents
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param page query int false "for response pagination, page offset number" default(1)
|
||||
// @Param perPage query int false "for response pagination, max items per page" default(50)
|
||||
func GetAgents(c *gin.Context) {
|
||||
agents, err := store.FromContext(c).AgentList(session.Pagination(c))
|
||||
if err != nil {
|
||||
|
@ -37,6 +47,15 @@ func GetAgents(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, agents)
|
||||
}
|
||||
|
||||
// GetAgent
|
||||
//
|
||||
// @Summary Get agent information
|
||||
// @Router /agents/{agent} [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Agent
|
||||
// @Tags Agents
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param agent path int true "the agent's id"
|
||||
func GetAgent(c *gin.Context) {
|
||||
agentID, err := strconv.ParseInt(c.Param("agent"), 10, 64)
|
||||
if err != nil {
|
||||
|
@ -52,6 +71,15 @@ func GetAgent(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, agent)
|
||||
}
|
||||
|
||||
// GetAgentTasks
|
||||
//
|
||||
// @Summary Get agent tasks
|
||||
// @Router /agents/{agent}/tasks [get]
|
||||
// @Produce json
|
||||
// @Success 200 {array} Task
|
||||
// @Tags Agents
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param agent path int true "the agent's id"
|
||||
func GetAgentTasks(c *gin.Context) {
|
||||
agentID, err := strconv.ParseInt(c.Param("agent"), 10, 64)
|
||||
if err != nil {
|
||||
|
@ -76,6 +104,16 @@ func GetAgentTasks(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, tasks)
|
||||
}
|
||||
|
||||
// PatchAgent
|
||||
//
|
||||
// @Summary Update agent information
|
||||
// @Router /agents/{agent} [patch]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Agent
|
||||
// @Tags Agents
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param agent path int true "the agent's id"
|
||||
// @Param agentData body Agent true "the agent's data"
|
||||
func PatchAgent(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
|
||||
|
@ -109,7 +147,15 @@ func PatchAgent(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, agent)
|
||||
}
|
||||
|
||||
// PostAgent create a new agent with a random token so a new agent can connect to the server
|
||||
// PostAgent
|
||||
//
|
||||
// @Summary Create a new agent with a random token so a new agent can connect to the server
|
||||
// @Router /agents [post]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Agent
|
||||
// @Tags Agents
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param agent body Agent true "the agent's data (only 'name' and 'no_schedule' are read)"
|
||||
func PostAgent(c *gin.Context) {
|
||||
in := &model.Agent{}
|
||||
err := c.Bind(in)
|
||||
|
@ -135,6 +181,15 @@ func PostAgent(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, agent)
|
||||
}
|
||||
|
||||
// DeleteAgent
|
||||
//
|
||||
// @Summary Delete an agent
|
||||
// @Router /agents/{agent} [delete]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Agents
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param agent path int true "the agent's id"
|
||||
func DeleteAgent(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
|
||||
|
|
|
@ -34,6 +34,15 @@ import (
|
|||
"github.com/woodpecker-ci/woodpecker/server/store/types"
|
||||
)
|
||||
|
||||
// GetBadge
|
||||
//
|
||||
// @Summary Get status badge, SVG format
|
||||
// @Router /badges/{owner}/{name}/status.svg [get]
|
||||
// @Produce image/svg+xml
|
||||
// @Success 200
|
||||
// @Tags Badges
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
func GetBadge(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
repo, err := _store.GetRepoName(c.Param("owner") + "/" + c.Param("name"))
|
||||
|
@ -65,6 +74,18 @@ func GetBadge(c *gin.Context) {
|
|||
c.String(http.StatusOK, badges.Generate(pipeline))
|
||||
}
|
||||
|
||||
// GetCC
|
||||
//
|
||||
// @Summary Provide pipeline status information to the CCMenu tool
|
||||
// @Description CCMenu displays the pipeline status of projects on a CI server as an item in the Mac's menu bar.
|
||||
// @Description More details on how to install, you can find at http://ccmenu.org/
|
||||
// @Description The response format adheres to CCTray v1 Specification, https://cctray.org/v1/
|
||||
// @Router /badges/{owner}/{name}/cc.xml [get]
|
||||
// @Produce xml
|
||||
// @Success 200
|
||||
// @Tags Badges
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
func GetCC(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
repo, err := _store.GetRepoName(c.Param("owner") + "/" + c.Param("name"))
|
||||
|
|
|
@ -28,8 +28,17 @@ import (
|
|||
"github.com/woodpecker-ci/woodpecker/server/store"
|
||||
)
|
||||
|
||||
// GetCron gets a cron job by id from the database and writes
|
||||
// to the response in json format.
|
||||
// GetCron
|
||||
//
|
||||
// @Summary Get a cron job by id
|
||||
// @Router /repos/{owner}/{name}/cron/{cron} [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Cron
|
||||
// @Tags Repository cron jobs
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param cron path string true "the cron job id"
|
||||
func GetCron(c *gin.Context) {
|
||||
repo := session.Repo(c)
|
||||
id, err := strconv.ParseInt(c.Param("cron"), 10, 64)
|
||||
|
@ -46,7 +55,17 @@ func GetCron(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, cron)
|
||||
}
|
||||
|
||||
// RunCron starts a cron job now.
|
||||
// RunCron
|
||||
//
|
||||
// @Summary Start a cron job now
|
||||
// @Router /repos/{owner}/{name}/cron/{cron} [post]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Pipeline
|
||||
// @Tags Repository cron jobs
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param cron path string true "the cron job id"
|
||||
func RunCron(c *gin.Context) {
|
||||
repo := session.Repo(c)
|
||||
_store := store.FromContext(c)
|
||||
|
@ -77,7 +96,17 @@ func RunCron(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, pl)
|
||||
}
|
||||
|
||||
// PostCron persists the cron job to the database.
|
||||
// PostCron
|
||||
//
|
||||
// @Summary Persist/creat a cron job
|
||||
// @Router /repos/{owner}/{name}/cron [post]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Cron
|
||||
// @Tags Repository cron jobs
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param cronJob body Cron true "the new cron job"
|
||||
func PostCron(c *gin.Context) {
|
||||
repo := session.Repo(c)
|
||||
user := session.User(c)
|
||||
|
@ -124,7 +153,18 @@ func PostCron(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, cron)
|
||||
}
|
||||
|
||||
// PatchCron updates the cron job in the database.
|
||||
// PatchCron
|
||||
//
|
||||
// @Summary Update a cron job
|
||||
// @Router /repos/{owner}/{name}/cron/{cron} [patch]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Cron
|
||||
// @Tags Repository cron jobs
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param cron path string true "the cron job id"
|
||||
// @Param cronJob body Cron true "the cron job data"
|
||||
func PatchCron(c *gin.Context) {
|
||||
repo := session.Repo(c)
|
||||
user := session.User(c)
|
||||
|
@ -183,8 +223,18 @@ func PatchCron(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, cron)
|
||||
}
|
||||
|
||||
// GetCronList gets the cron job list from the database and writes
|
||||
// to the response in json format.
|
||||
// GetCronList
|
||||
//
|
||||
// @Summary Get the cron job list
|
||||
// @Router /repos/{owner}/{name}/cron [get]
|
||||
// @Produce json
|
||||
// @Success 200 {array} Cron
|
||||
// @Tags Repository cron jobs
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param page query int false "for response pagination, page offset number" default(1)
|
||||
// @Param perPage query int false "for response pagination, max items per page" default(50)
|
||||
func GetCronList(c *gin.Context) {
|
||||
repo := session.Repo(c)
|
||||
list, err := store.FromContext(c).CronList(repo, session.Pagination(c))
|
||||
|
@ -195,7 +245,17 @@ func GetCronList(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, list)
|
||||
}
|
||||
|
||||
// DeleteCron deletes the named cron job from the database.
|
||||
// DeleteCron
|
||||
//
|
||||
// @Summary Delete a cron job by id
|
||||
// @Router /repos/{owner}/{name}/cron/{cron} [delete]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Repository cron jobs
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param cron path string true "the cron job id"
|
||||
func DeleteCron(c *gin.Context) {
|
||||
repo := session.Repo(c)
|
||||
id, err := strconv.ParseInt(c.Param("cron"), 10, 64)
|
||||
|
|
|
@ -20,63 +20,146 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// IndexHandler will pass the call from /debug/pprof to pprof
|
||||
// IndexHandler
|
||||
//
|
||||
// @Summary List available pprof profiles (HTML)
|
||||
// @Description Only available, when server was started with WOODPECKER_LOG_LEVEL=debug
|
||||
// @Router /debug/pprof [get]
|
||||
// @Produce html
|
||||
// @Success 200
|
||||
// @Tags Process profiling and debugging
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func IndexHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
pprof.Index(c.Writer, c.Request)
|
||||
}
|
||||
}
|
||||
|
||||
// HeapHandler will pass the call from /debug/pprof/heap to pprof
|
||||
// HeapHandler
|
||||
//
|
||||
// @Summary Get pprof heap dump, a sampling of memory allocations of live objects
|
||||
// @Description Only available, when server was started with WOODPECKER_LOG_LEVEL=debug
|
||||
// @Router /debug/pprof/heap [get]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Process profiling and debugging
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param gc query string false "You can specify gc=heap to run GC before taking the heap sample" default()
|
||||
func HeapHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
pprof.Handler("heap").ServeHTTP(c.Writer, c.Request)
|
||||
}
|
||||
}
|
||||
|
||||
// GoroutineHandler will pass the call from /debug/pprof/goroutine to pprof
|
||||
// GoroutineHandler
|
||||
//
|
||||
// @Summary Get pprof stack traces of all current goroutines
|
||||
// @Description Only available, when server was started with WOODPECKER_LOG_LEVEL=debug
|
||||
// @Router /debug/pprof/goroutine [get]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Process profiling and debugging
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param debug query int false "Use debug=2 as a query parameter to export in the same format as an un-recovered panic" default(1)
|
||||
func GoroutineHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
pprof.Handler("goroutine").ServeHTTP(c.Writer, c.Request)
|
||||
}
|
||||
}
|
||||
|
||||
// BlockHandler will pass the call from /debug/pprof/block to pprof
|
||||
// BlockHandler
|
||||
//
|
||||
// @Summary Get pprof stack traces that led to blocking on synchronization primitives
|
||||
// @Description Only available, when server was started with WOODPECKER_LOG_LEVEL=debug
|
||||
// @Router /debug/pprof/block [get]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Process profiling and debugging
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func BlockHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
pprof.Handler("block").ServeHTTP(c.Writer, c.Request)
|
||||
}
|
||||
}
|
||||
|
||||
// ThreadCreateHandler will pass the call from /debug/pprof/threadcreate to pprof
|
||||
// ThreadCreateHandler
|
||||
//
|
||||
// @Summary Get pprof stack traces that led to the creation of new OS threads
|
||||
// @Description Only available, when server was started with WOODPECKER_LOG_LEVEL=debug
|
||||
// @Router /debug/pprof/threadcreate [get]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Process profiling and debugging
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func ThreadCreateHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
pprof.Handler("threadcreate").ServeHTTP(c.Writer, c.Request)
|
||||
}
|
||||
}
|
||||
|
||||
// CmdlineHandler will pass the call from /debug/pprof/cmdline to pprof
|
||||
// CmdlineHandler
|
||||
//
|
||||
// @Summary Get the command line invocation of the current program
|
||||
// @Description Only available, when server was started with WOODPECKER_LOG_LEVEL=debug
|
||||
// @Router /debug/pprof/cmdline [get]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Process profiling and debugging
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func CmdlineHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
pprof.Cmdline(c.Writer, c.Request)
|
||||
}
|
||||
}
|
||||
|
||||
// ProfileHandler will pass the call from /debug/pprof/profile to pprof
|
||||
// ProfileHandler
|
||||
//
|
||||
// @Summary Get pprof CPU profile
|
||||
// @Description Only available, when server was started with WOODPECKER_LOG_LEVEL=debug
|
||||
// @Description After you get the profile file, use the go tool pprof command to investigate the profile.
|
||||
// @Router /debug/pprof/profile [get]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Process profiling and debugging
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param seconds query int true "You can specify the duration in the seconds GET parameter." default (30)
|
||||
func ProfileHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
pprof.Profile(c.Writer, c.Request)
|
||||
}
|
||||
}
|
||||
|
||||
// SymbolHandler will pass the call from /debug/pprof/symbol to pprof
|
||||
// SymbolHandler
|
||||
//
|
||||
// @Summary Get pprof program counters mapping to function names
|
||||
// @Description Only available, when server was started with WOODPECKER_LOG_LEVEL=debug
|
||||
// @Description Looks up the program counters listed in the request,
|
||||
// @Description responding with a table mapping program counters to function names.
|
||||
// @Description The requested program counters can be provided via GET + query parameters,
|
||||
// @Description or POST + body parameters. Program counters shall be space delimited.
|
||||
// @Router /debug/pprof/symbol [get]
|
||||
// @Router /debug/pprof/symbol [post]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Process profiling and debugging
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func SymbolHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
pprof.Symbol(c.Writer, c.Request)
|
||||
}
|
||||
}
|
||||
|
||||
// TraceHandler will pass the call from /debug/pprof/trace to pprof
|
||||
// TraceHandler
|
||||
//
|
||||
// @Summary Get a trace of execution of the current program
|
||||
// @Description Only available, when server was started with WOODPECKER_LOG_LEVEL=debug
|
||||
// @Description After you get the profile file, use the go tool pprof command to investigate the profile.
|
||||
// @Router /debug/pprof/trace [get]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Process profiling and debugging
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param seconds query int true "You can specify the duration in the seconds GET parameter." default (30)
|
||||
func TraceHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
pprof.Trace(c.Writer, c.Request)
|
||||
|
|
|
@ -24,8 +24,16 @@ import (
|
|||
"github.com/woodpecker-ci/woodpecker/server/model"
|
||||
)
|
||||
|
||||
// GetGlobalSecretList gets the global secret list from
|
||||
// the database and writes to the response in json format.
|
||||
// GetGlobalSecretList
|
||||
//
|
||||
// @Summary Get the global secret list
|
||||
// @Router /secrets [get]
|
||||
// @Produce json
|
||||
// @Success 200 {array} Secret
|
||||
// @Tags Secrets
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param page query int false "for response pagination, page offset number" default(1)
|
||||
// @Param perPage query int false "for response pagination, max items per page" default(50)
|
||||
func GetGlobalSecretList(c *gin.Context) {
|
||||
list, err := server.Config.Services.Secrets.GlobalSecretList(session.Pagination(c))
|
||||
if err != nil {
|
||||
|
@ -40,8 +48,15 @@ func GetGlobalSecretList(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, list)
|
||||
}
|
||||
|
||||
// GetGlobalSecret gets the named global secret from the database
|
||||
// and writes to the response in json format.
|
||||
// GetGlobalSecret
|
||||
//
|
||||
// @Summary Get a global secret by name
|
||||
// @Router /secrets/{secret} [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Secret
|
||||
// @Tags Secrets
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param secret path string true "the secret's name"
|
||||
func GetGlobalSecret(c *gin.Context) {
|
||||
name := c.Param("secret")
|
||||
secret, err := server.Config.Services.Secrets.GlobalSecretFind(name)
|
||||
|
@ -52,7 +67,15 @@ func GetGlobalSecret(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, secret.Copy())
|
||||
}
|
||||
|
||||
// PostGlobalSecret persists a global secret to the database.
|
||||
// PostGlobalSecret
|
||||
//
|
||||
// @Summary Persist/create a global secret
|
||||
// @Router /secrets [post]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Secret
|
||||
// @Tags Secrets
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param secret body Secret true "the secret object data"
|
||||
func PostGlobalSecret(c *gin.Context) {
|
||||
in := new(model.Secret)
|
||||
if err := c.Bind(in); err != nil {
|
||||
|
@ -77,7 +100,16 @@ func PostGlobalSecret(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, secret.Copy())
|
||||
}
|
||||
|
||||
// PatchGlobalSecret updates a global secret in the database.
|
||||
// PatchGlobalSecret
|
||||
//
|
||||
// @Summary Update a global secret by name
|
||||
// @Router /secrets/{secret} [patch]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Secret
|
||||
// @Tags Secrets
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param secret path string true "the secret's name"
|
||||
// @Param secretData body Secret true "the secret's data"
|
||||
func PatchGlobalSecret(c *gin.Context) {
|
||||
name := c.Param("secret")
|
||||
|
||||
|
@ -115,7 +147,15 @@ func PatchGlobalSecret(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, secret.Copy())
|
||||
}
|
||||
|
||||
// DeleteGlobalSecret deletes the named global secret from the database.
|
||||
// DeleteGlobalSecret
|
||||
//
|
||||
// @Summary Delete a global secret by name
|
||||
// @Router /secrets/{secret} [delete]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Secrets
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param secret path string true "the secret's name"
|
||||
func DeleteGlobalSecret(c *gin.Context) {
|
||||
name := c.Param("secret")
|
||||
if err := server.Config.Services.Secrets.GlobalSecretDelete(name); err != nil {
|
||||
|
|
|
@ -35,22 +35,55 @@ import (
|
|||
|
||||
var skipRe = regexp.MustCompile(`\[(?i:ci *skip|skip *ci)\]`)
|
||||
|
||||
// GetQueueInfo
|
||||
//
|
||||
// @Summary Get pipeline queue information
|
||||
// @Description TODO: link the InfoT response object - this is blocked, until the `swaggo/swag` tool dependency is v1.18.12 or newer
|
||||
// @Router /queue/info [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} map[string]string
|
||||
// @Tags Pipeline queues
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func GetQueueInfo(c *gin.Context) {
|
||||
c.IndentedJSON(http.StatusOK,
|
||||
server.Config.Services.Queue.Info(c),
|
||||
)
|
||||
}
|
||||
|
||||
// PauseQueue
|
||||
//
|
||||
// @Summary Pause a pipeline queue
|
||||
// @Router /queue/pause [post]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Pipeline queues
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func PauseQueue(c *gin.Context) {
|
||||
server.Config.Services.Queue.Pause()
|
||||
c.Status(http.StatusOK)
|
||||
}
|
||||
|
||||
// ResumeQueue
|
||||
//
|
||||
// @Summary Resume a pipeline queue
|
||||
// @Router /queue/resume [post]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Pipeline queues
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func ResumeQueue(c *gin.Context) {
|
||||
server.Config.Services.Queue.Resume()
|
||||
c.Status(http.StatusOK)
|
||||
}
|
||||
|
||||
// BlockTilQueueHasRunningItem
|
||||
//
|
||||
// @Summary Block til pipeline queue has a running item
|
||||
// @Router /queue/norunningpipelines [get]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Pipeline queues
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func BlockTilQueueHasRunningItem(c *gin.Context) {
|
||||
for {
|
||||
info := server.Config.Services.Queue.Info(c)
|
||||
|
@ -61,7 +94,14 @@ func BlockTilQueueHasRunningItem(c *gin.Context) {
|
|||
c.Status(http.StatusOK)
|
||||
}
|
||||
|
||||
// PostHook start a pipeline triggered by a forges post webhook
|
||||
// PostHook
|
||||
//
|
||||
// @Summary Incoming webhook from forge
|
||||
// @Router /hook [post]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags System
|
||||
// @Param hook body object true "the webhook payload; forge is automatically detected"
|
||||
func PostHook(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
forge := server.Config.Services.Forge
|
||||
|
|
|
@ -24,7 +24,15 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// GetOrgPermissions returns the permissions of the current user in the given organization.
|
||||
// GetOrgPermissions
|
||||
//
|
||||
// @Summary Get the permissions of the current user in the given organization
|
||||
// @Router /orgs/{owner}/permissions [get]
|
||||
// @Produce json
|
||||
// @Success 200 {array} OrgPerm
|
||||
// @Tags Organization permissions
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the owner's name"
|
||||
func GetOrgPermissions(c *gin.Context) {
|
||||
var (
|
||||
err error
|
||||
|
|
|
@ -24,8 +24,16 @@ import (
|
|||
"github.com/woodpecker-ci/woodpecker/server/model"
|
||||
)
|
||||
|
||||
// GetOrgSecret gets the named organization secret from the database
|
||||
// and writes to the response in json format.
|
||||
// GetOrgSecret
|
||||
//
|
||||
// @Summary Get the named organization secret
|
||||
// @Router /orgs/{owner}/secrets/{secret} [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Secret
|
||||
// @Tags Organization secrets
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the owner's name"
|
||||
// @Param secret path string true "the secret's name"
|
||||
func GetOrgSecret(c *gin.Context) {
|
||||
var (
|
||||
owner = c.Param("owner")
|
||||
|
@ -39,8 +47,17 @@ func GetOrgSecret(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, secret.Copy())
|
||||
}
|
||||
|
||||
// GetOrgSecretList gets the organization secret list from
|
||||
// the database and writes to the response in json format.
|
||||
// GetOrgSecretList
|
||||
//
|
||||
// @Summary Get the organization secret list
|
||||
// @Router /orgs/{owner}/secrets [get]
|
||||
// @Produce json
|
||||
// @Success 200 {array} Secret
|
||||
// @Tags Organization secrets
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the owner's name"
|
||||
// @Param page query int false "for response pagination, page offset number" default(1)
|
||||
// @Param perPage query int false "for response pagination, max items per page" default(50)
|
||||
func GetOrgSecretList(c *gin.Context) {
|
||||
owner := c.Param("owner")
|
||||
list, err := server.Config.Services.Secrets.OrgSecretList(owner, session.Pagination(c))
|
||||
|
@ -56,7 +73,16 @@ func GetOrgSecretList(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, list)
|
||||
}
|
||||
|
||||
// PostOrgSecret persists an organization secret to the database.
|
||||
// PostOrgSecret
|
||||
//
|
||||
// @Summary Persist/create an organization secret
|
||||
// @Router /orgs/{owner}/secrets [post]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Secret
|
||||
// @Tags Organization secrets
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the owner's name"
|
||||
// @Param secretData body Secret true "the new secret"
|
||||
func PostOrgSecret(c *gin.Context) {
|
||||
owner := c.Param("owner")
|
||||
|
||||
|
@ -84,7 +110,17 @@ func PostOrgSecret(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, secret.Copy())
|
||||
}
|
||||
|
||||
// PatchOrgSecret updates an organization secret in the database.
|
||||
// PatchOrgSecret
|
||||
//
|
||||
// @Summary Update an organization secret
|
||||
// @Router /orgs/{owner}/secrets/{secret} [patch]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Secret
|
||||
// @Tags Organization secrets
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the owner's name"
|
||||
// @Param secret path string true "the secret's name"
|
||||
// @Param secretData body Secret true "the update secret data"
|
||||
func PatchOrgSecret(c *gin.Context) {
|
||||
var (
|
||||
owner = c.Param("owner")
|
||||
|
@ -125,7 +161,16 @@ func PatchOrgSecret(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, secret.Copy())
|
||||
}
|
||||
|
||||
// DeleteOrgSecret deletes the named organization secret from the database.
|
||||
// DeleteOrgSecret
|
||||
//
|
||||
// @Summary Delete the named secret from an organization
|
||||
// @Router /orgs/{owner}/secrets/{secret} [delete]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Organization secrets
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the owner's name"
|
||||
// @Param secret path string true "the secret's name"
|
||||
func DeleteOrgSecret(c *gin.Context) {
|
||||
var (
|
||||
owner = c.Param("owner")
|
||||
|
|
|
@ -39,6 +39,17 @@ import (
|
|||
"github.com/woodpecker-ci/woodpecker/server/store/types"
|
||||
)
|
||||
|
||||
// CreatePipeline
|
||||
//
|
||||
// @Summary Run/trigger a pipelines
|
||||
// @Router /repos/{owner}/{name}/pipelines [post]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Pipeline
|
||||
// @Tags Pipelines
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param options body PipelineOptions true "the options for the pipeline to run"
|
||||
func CreatePipeline(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
repo := session.Repo(c)
|
||||
|
@ -86,6 +97,18 @@ func createTmpPipeline(event model.WebhookEvent, commitSHA string, repo *model.R
|
|||
}
|
||||
}
|
||||
|
||||
// GetPipelines
|
||||
//
|
||||
// @Summary Get pipelines, current running and past ones
|
||||
// @Router /repos/{owner}/{name}/pipelines [get]
|
||||
// @Produce json
|
||||
// @Success 200 {array} Pipeline
|
||||
// @Tags Pipelines
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param page query int false "for response pagination, page offset number" default(1)
|
||||
// @Param perPage query int false "for response pagination, max items per page" default(50)
|
||||
func GetPipelines(c *gin.Context) {
|
||||
repo := session.Repo(c)
|
||||
|
||||
|
@ -101,6 +124,17 @@ func GetPipelines(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, pipelines)
|
||||
}
|
||||
|
||||
// GetPipeline
|
||||
//
|
||||
// @Summary Pipeline information by number
|
||||
// @Router /repos/{owner}/{name}/pipelines/{number} [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Pipeline
|
||||
// @Tags Pipelines
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param number path int true "the number of the pipeline, OR 'latest'"
|
||||
func GetPipeline(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
if c.Param("number") == "latest" {
|
||||
|
@ -156,6 +190,19 @@ func GetPipelineLast(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, pl)
|
||||
}
|
||||
|
||||
// GetPipelineLogs
|
||||
//
|
||||
// @Summary Log information per step
|
||||
// @Router /repos/{owner}/{name}/logs/{number}/{pid}/{step} [get]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Pipeline logs
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param number path int true "the number of the pipeline"
|
||||
// @Param pid path int true "the pipeline id"
|
||||
// @Param step path int true "the step name"
|
||||
func GetPipelineLogs(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
repo := session.Repo(c)
|
||||
|
@ -192,6 +239,18 @@ func GetPipelineLogs(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
// GetStepLogs
|
||||
//
|
||||
// @Summary Log information
|
||||
// @Router /repos/{owner}/{name}/logs/{number}/{pid} [get]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Pipeline logs
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param number path int true "the number of the pipeline"
|
||||
// @Param pid path int true "the pipeline id"
|
||||
func GetStepLogs(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
repo := session.Repo(c)
|
||||
|
@ -227,6 +286,17 @@ func GetStepLogs(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
// GetPipelineConfig
|
||||
//
|
||||
// @Summary Pipeline configuration
|
||||
// @Router /repos/{owner}/{name}/pipelines/{number}/config [get]
|
||||
// @Produce json
|
||||
// @Success 200 {array} Config
|
||||
// @Tags Pipelines
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param number path int true "the number of the pipeline"
|
||||
func GetPipelineConfig(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
repo := session.Repo(c)
|
||||
|
@ -251,7 +321,17 @@ func GetPipelineConfig(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, configs)
|
||||
}
|
||||
|
||||
// CancelPipeline cancels a pipeline
|
||||
// CancelPipeline
|
||||
//
|
||||
// @Summary Cancels a pipeline
|
||||
// @Router /repos/{owner}/{name}/pipelines/{number}/cancel [post]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Pipelines
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param number path int true "the number of the pipeline"
|
||||
func CancelPipeline(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
repo := session.Repo(c)
|
||||
|
@ -271,7 +351,17 @@ func CancelPipeline(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
// PostApproval start pipelines in gated repos
|
||||
// PostApproval
|
||||
//
|
||||
// @Summary Start pipelines in gated repos
|
||||
// @Router /repos/{owner}/{name}/pipelines/{number}/approve [post]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Pipeline
|
||||
// @Tags Pipelines
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param number path int true "the number of the pipeline"
|
||||
func PostApproval(c *gin.Context) {
|
||||
var (
|
||||
_store = store.FromContext(c)
|
||||
|
@ -294,7 +384,17 @@ func PostApproval(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
// PostDecline decline pipelines in gated repos
|
||||
// PostDecline
|
||||
//
|
||||
// @Summary Decline pipelines in gated repos
|
||||
// @Router /repos/{owner}/{name}/pipelines/{number}/decline [post]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Pipeline
|
||||
// @Tags Pipelines
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param number path int true "the number of the pipeline"
|
||||
func PostDecline(c *gin.Context) {
|
||||
var (
|
||||
_store = store.FromContext(c)
|
||||
|
@ -317,6 +417,14 @@ func PostDecline(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
// GetPipelineQueue
|
||||
//
|
||||
// @Summary List pipeline queues
|
||||
// @Router /pipelines [get]
|
||||
// @Produce json
|
||||
// @Success 200 {array} Feed
|
||||
// @Tags Pipeline queues
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func GetPipelineQueue(c *gin.Context) {
|
||||
out, err := store.FromContext(c).GetPipelineQueue()
|
||||
if err != nil {
|
||||
|
@ -326,7 +434,20 @@ func GetPipelineQueue(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, out)
|
||||
}
|
||||
|
||||
// PostPipeline restarts a pipeline optional with altered event, deploy or environment
|
||||
// PostPipeline
|
||||
//
|
||||
// @Summary Restart a pipeline
|
||||
// @Description Restarts a pipeline optional with altered event, deploy or environment
|
||||
// @Router /repos/{owner}/{name}/pipelines/{number} [post]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Pipeline
|
||||
// @Tags Pipelines
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param number path int true "the number of the pipeline"
|
||||
// @Param event query string false "override the event type"
|
||||
// @Param deploy_to query string false "override the target deploy value"
|
||||
func PostPipeline(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
repo := session.Repo(c)
|
||||
|
@ -396,6 +517,17 @@ func PostPipeline(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
// DeletePipelineLogs
|
||||
//
|
||||
// @Summary Deletes log
|
||||
// @Router /repos/{owner}/{name}/logs/{number} [post]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Pipeline logs
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param number path int true "the number of the pipeline"
|
||||
func DeletePipelineLogs(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
|
||||
|
|
|
@ -24,8 +24,17 @@ import (
|
|||
"github.com/woodpecker-ci/woodpecker/server/router/middleware/session"
|
||||
)
|
||||
|
||||
// GetRegistry gets the name registry from the database and writes
|
||||
// to the response in json format.
|
||||
// GetRegistry
|
||||
//
|
||||
// @Summary Get a named registry
|
||||
// @Router /repos/{owner}/{name}/registry/{registry} [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Registry
|
||||
// @Tags Repository registries
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param registry path string true "the registry name"
|
||||
func GetRegistry(c *gin.Context) {
|
||||
var (
|
||||
repo = session.Repo(c)
|
||||
|
@ -39,7 +48,17 @@ func GetRegistry(c *gin.Context) {
|
|||
c.JSON(200, registry.Copy())
|
||||
}
|
||||
|
||||
// PostRegistry persists the registry to the database.
|
||||
// PostRegistry
|
||||
//
|
||||
// @Summary Persist/create a registry
|
||||
// @Router /repos/{owner}/{name}/registry [post]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Registry
|
||||
// @Tags Repository registries
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param registry body Registry true "the new registry data"
|
||||
func PostRegistry(c *gin.Context) {
|
||||
repo := session.Repo(c)
|
||||
|
||||
|
@ -67,7 +86,18 @@ func PostRegistry(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, in.Copy())
|
||||
}
|
||||
|
||||
// PatchRegistry updates the registry in the database.
|
||||
// PatchRegistry
|
||||
//
|
||||
// @Summary Update a named registry
|
||||
// @Router /repos/{owner}/{name}/registry/{registry} [patch]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Registry
|
||||
// @Tags Repository registries
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param registry path string true "the registry name"
|
||||
// @Param registryData body Registry true "the attributes for the registry"
|
||||
func PatchRegistry(c *gin.Context) {
|
||||
var (
|
||||
repo = session.Repo(c)
|
||||
|
@ -110,8 +140,18 @@ func PatchRegistry(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, in.Copy())
|
||||
}
|
||||
|
||||
// GetRegistryList gets the registry list from the database and writes
|
||||
// to the response in json format.
|
||||
// GetRegistryList
|
||||
//
|
||||
// @Summary Get the registry list
|
||||
// @Router /repos/{owner}/{name}/registry [get]
|
||||
// @Produce json
|
||||
// @Success 200 {array} Registry
|
||||
// @Tags Repository registries
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param page query int false "for response pagination, page offset number" default(1)
|
||||
// @Param perPage query int false "for response pagination, max items per page" default(50)
|
||||
func GetRegistryList(c *gin.Context) {
|
||||
repo := session.Repo(c)
|
||||
list, err := server.Config.Services.Registries.RegistryList(repo, session.Pagination(c))
|
||||
|
@ -127,7 +167,17 @@ func GetRegistryList(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, list)
|
||||
}
|
||||
|
||||
// DeleteRegistry deletes the named registry from the database.
|
||||
// DeleteRegistry
|
||||
//
|
||||
// @Summary Delete a named registry
|
||||
// @Router /repos/{owner}/{name}/registry/{registry} [delete]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Repository registries
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param registry path string true "the registry name"
|
||||
func DeleteRegistry(c *gin.Context) {
|
||||
var (
|
||||
repo = session.Repo(c)
|
||||
|
|
|
@ -35,6 +35,16 @@ import (
|
|||
"github.com/woodpecker-ci/woodpecker/shared/token"
|
||||
)
|
||||
|
||||
// PostRepo
|
||||
//
|
||||
// @Summary Activate a repository
|
||||
// @Router /repos/{owner}/{name} [post]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Repo
|
||||
// @Tags Repositories
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
func PostRepo(c *gin.Context) {
|
||||
forge := server.Config.Services.Forge
|
||||
_store := store.FromContext(c)
|
||||
|
@ -134,6 +144,17 @@ func PostRepo(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, repo)
|
||||
}
|
||||
|
||||
// PatchRepo
|
||||
//
|
||||
// @Summary Change a repository
|
||||
// @Router /repos/{owner}/{name} [patch]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Repo
|
||||
// @Tags Repositories
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param repo body RepoPatch true "the repository's information"
|
||||
func PatchRepo(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
repo := session.Repo(c)
|
||||
|
@ -194,6 +215,16 @@ func PatchRepo(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, repo)
|
||||
}
|
||||
|
||||
// ChownRepo
|
||||
//
|
||||
// @Summary Change a repository's owner, to the one holding the access token
|
||||
// @Router /repos/{owner}/{name}/chown [post]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Repo
|
||||
// @Tags Repositories
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
func ChownRepo(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
repo := session.Repo(c)
|
||||
|
@ -208,15 +239,48 @@ func ChownRepo(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, repo)
|
||||
}
|
||||
|
||||
// GetRepo
|
||||
//
|
||||
// @Summary Get repository information
|
||||
// @Router /repos/{owner}/{name} [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Repo
|
||||
// @Tags Repositories
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
func GetRepo(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, session.Repo(c))
|
||||
}
|
||||
|
||||
// GetRepoPermissions
|
||||
//
|
||||
// @Summary Repository permission information
|
||||
// @Description The repository permission, according to the used access token.
|
||||
// @Router /repos/{owner}/{name}/permissions [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Perm
|
||||
// @Tags Repositories
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
func GetRepoPermissions(c *gin.Context) {
|
||||
perm := session.Perm(c)
|
||||
c.JSON(http.StatusOK, perm)
|
||||
}
|
||||
|
||||
// GetRepoBranches
|
||||
//
|
||||
// @Summary Get repository branches
|
||||
// @Router /repos/{owner}/{name}/branches [get]
|
||||
// @Produce json
|
||||
// @Success 200 {array} string
|
||||
// @Tags Repositories
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param page query int false "for response pagination, page offset number" default(1)
|
||||
// @Param perPage query int false "for response pagination, max items per page" default(50)
|
||||
func GetRepoBranches(c *gin.Context) {
|
||||
repo := session.Repo(c)
|
||||
user := session.User(c)
|
||||
|
@ -231,6 +295,18 @@ func GetRepoBranches(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, branches)
|
||||
}
|
||||
|
||||
// GetRepoPullRequests
|
||||
//
|
||||
// @Summary List active pull requests
|
||||
// @Router /repos/{owner}/{name}/pull_requests [get]
|
||||
// @Produce json
|
||||
// @Success 200 {array} PullRequest
|
||||
// @Tags Repositories
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param page query int false "for response pagination, page offset number" default(1)
|
||||
// @Param perPage query int false "for response pagination, max items per page" default(50)
|
||||
func GetRepoPullRequests(c *gin.Context) {
|
||||
repo := session.Repo(c)
|
||||
user := session.User(c)
|
||||
|
@ -245,6 +321,16 @@ func GetRepoPullRequests(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, prs)
|
||||
}
|
||||
|
||||
// DeleteRepo
|
||||
//
|
||||
// @Summary Delete a repository
|
||||
// @Router /repos/{owner}/{name} [delete]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Repo
|
||||
// @Tags Repositories
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
func DeleteRepo(c *gin.Context) {
|
||||
remove, _ := strconv.ParseBool(c.Query("remove"))
|
||||
_store := store.FromContext(c)
|
||||
|
@ -274,6 +360,16 @@ func DeleteRepo(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, repo)
|
||||
}
|
||||
|
||||
// RepairRepo
|
||||
//
|
||||
// @Summary Repair a repository
|
||||
// @Router /repos/{owner}/{name}/repair [post]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Repositories
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
func RepairRepo(c *gin.Context) {
|
||||
forge := server.Config.Services.Forge
|
||||
_store := store.FromContext(c)
|
||||
|
@ -336,6 +432,17 @@ func RepairRepo(c *gin.Context) {
|
|||
c.Writer.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
// MoveRepo
|
||||
//
|
||||
// @Summary Move a repository to a new owner
|
||||
// @Router /repos/{owner}/{name}/move [post]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Repositories
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param to query string true "the username to move the repository to"
|
||||
func MoveRepo(c *gin.Context) {
|
||||
forge := server.Config.Services.Forge
|
||||
_store := store.FromContext(c)
|
||||
|
|
|
@ -25,8 +25,17 @@ import (
|
|||
"github.com/woodpecker-ci/woodpecker/server/router/middleware/session"
|
||||
)
|
||||
|
||||
// GetSecret gets the named secret from the database and writes
|
||||
// to the response in json format.
|
||||
// GetSecret
|
||||
//
|
||||
// @Summary Get a named secret
|
||||
// @Router /repos/{owner}/{name}/secrets/{secretName} [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Secret
|
||||
// @Tags Repository secrets
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param secretName path string true "the secret name"
|
||||
func GetSecret(c *gin.Context) {
|
||||
var (
|
||||
repo = session.Repo(c)
|
||||
|
@ -40,7 +49,17 @@ func GetSecret(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, secret.Copy())
|
||||
}
|
||||
|
||||
// PostSecret persists the secret to the database.
|
||||
// PostSecret
|
||||
//
|
||||
// @Summary Persist/create a secret
|
||||
// @Router /repos/{owner}/{name}/secrets [post]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Secret
|
||||
// @Tags Repository secrets
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param secret body Secret true "the new secret"
|
||||
func PostSecret(c *gin.Context) {
|
||||
repo := session.Repo(c)
|
||||
|
||||
|
@ -68,7 +87,18 @@ func PostSecret(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, secret.Copy())
|
||||
}
|
||||
|
||||
// PatchSecret updates the secret in the database.
|
||||
// PatchSecret
|
||||
//
|
||||
// @Summary Update a named secret
|
||||
// @Router /repos/{owner}/{name}/secrets/{secretName} [patch]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Secret
|
||||
// @Tags Repository secrets
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param secretName path string true "the secret name"
|
||||
// @Param secret body Secret true "the secret itself"
|
||||
func PatchSecret(c *gin.Context) {
|
||||
var (
|
||||
repo = session.Repo(c)
|
||||
|
@ -109,8 +139,18 @@ func PatchSecret(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, secret.Copy())
|
||||
}
|
||||
|
||||
// GetSecretList gets the secret list from the database and writes
|
||||
// to the response in json format.
|
||||
// GetSecretList
|
||||
//
|
||||
// @Summary Get the secret list
|
||||
// @Router /repos/{owner}/{name}/secrets [get]
|
||||
// @Produce json
|
||||
// @Success 200 {array} Secret
|
||||
// @Tags Repository secrets
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param page query int false "for response pagination, page offset number" default(1)
|
||||
// @Param perPage query int false "for response pagination, max items per page" default(50)
|
||||
func GetSecretList(c *gin.Context) {
|
||||
repo := session.Repo(c)
|
||||
list, err := server.Config.Services.Secrets.SecretList(repo, session.Pagination(c))
|
||||
|
@ -126,7 +166,17 @@ func GetSecretList(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, list)
|
||||
}
|
||||
|
||||
// DeleteSecret deletes the named secret from the database.
|
||||
// DeleteSecret
|
||||
//
|
||||
// @Summary Delete a named secret
|
||||
// @Router /repos/{owner}/{name}/secrets/{secretName} [delete]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags Repository secrets
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param owner path string true "the repository owner's name"
|
||||
// @Param name path string true "the repository name"
|
||||
// @Param secretName path string true "the secret name"
|
||||
func DeleteSecret(c *gin.Context) {
|
||||
var (
|
||||
repo = session.Repo(c)
|
||||
|
|
|
@ -24,6 +24,14 @@ import (
|
|||
"github.com/woodpecker-ci/woodpecker/server"
|
||||
)
|
||||
|
||||
// GetSignaturePublicKey
|
||||
//
|
||||
// @Summary Get server's signature public key
|
||||
// @Router /signature/public-key [get]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags System
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func GetSignaturePublicKey(c *gin.Context) {
|
||||
b, err := x509.MarshalPKIXPublicKey(server.Config.Services.SignaturePublicKey)
|
||||
if err != nil {
|
||||
|
|
|
@ -28,10 +28,27 @@ import (
|
|||
"github.com/woodpecker-ci/woodpecker/shared/token"
|
||||
)
|
||||
|
||||
// GetSelf
|
||||
//
|
||||
// @Summary Returns the currently authenticated user.
|
||||
// @Router /user [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} User
|
||||
// @Tags User
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func GetSelf(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, session.User(c))
|
||||
}
|
||||
|
||||
// GetFeed
|
||||
//
|
||||
// @Summary A feed entry for a build.
|
||||
// @Description Feed entries can be used to display information on the latest builds.
|
||||
// @Router /user/feed [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} Feed
|
||||
// @Tags User
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func GetFeed(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
|
||||
|
@ -56,6 +73,15 @@ func GetFeed(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, feed)
|
||||
}
|
||||
|
||||
// GetRepos
|
||||
//
|
||||
// @Summary Get user's repos
|
||||
// @Description Retrieve the currently authenticated User's Repository list
|
||||
// @Router /user/repos [get]
|
||||
// @Produce json
|
||||
// @Success 200 {array} Repo
|
||||
// @Tags User
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func GetRepos(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
_forge := server.Config.Services.Forge
|
||||
|
@ -97,6 +123,14 @@ func GetRepos(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, activeRepos)
|
||||
}
|
||||
|
||||
// PostToken
|
||||
//
|
||||
// @Summary Return the token of the current user as stringª
|
||||
// @Router /user/token [post]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags User
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func PostToken(c *gin.Context) {
|
||||
user := session.User(c)
|
||||
tokenString, err := token.New(token.UserToken, user.Login).Sign(user.Hash)
|
||||
|
@ -107,6 +141,15 @@ func PostToken(c *gin.Context) {
|
|||
c.String(http.StatusOK, tokenString)
|
||||
}
|
||||
|
||||
// DeleteToken
|
||||
//
|
||||
// @Summary Reset a token
|
||||
// @Description Reset's the current personal access token of the user and returns a new one.
|
||||
// @Router /user/token [delete]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Tags User
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
func DeleteToken(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
|
||||
|
|
|
@ -26,6 +26,17 @@ import (
|
|||
"github.com/woodpecker-ci/woodpecker/server/store"
|
||||
)
|
||||
|
||||
// GetUsers
|
||||
//
|
||||
// @Summary Get all users
|
||||
// @Description Returns all registered, active users in the system. Requires admin rights.
|
||||
// @Router /users [get]
|
||||
// @Produce json
|
||||
// @Success 200 {array} User
|
||||
// @Tags Users
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param page query int false "for response pagination, page offset number" default(1)
|
||||
// @Param perPage query int false "for response pagination, max items per page" default(50)
|
||||
func GetUsers(c *gin.Context) {
|
||||
users, err := store.FromContext(c).GetUserList(session.Pagination(c))
|
||||
if err != nil {
|
||||
|
@ -35,6 +46,16 @@ func GetUsers(c *gin.Context) {
|
|||
c.JSON(200, users)
|
||||
}
|
||||
|
||||
// GetUser
|
||||
//
|
||||
// @Summary Get a user
|
||||
// @Description Returns a user with the specified login name. Requires admin rights.
|
||||
// @Router /users/{login} [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} User
|
||||
// @Tags Users
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param login path string true "the user's login name"
|
||||
func GetUser(c *gin.Context) {
|
||||
user, err := store.FromContext(c).GetUserLogin(c.Param("login"))
|
||||
if err != nil {
|
||||
|
@ -44,6 +65,18 @@ func GetUser(c *gin.Context) {
|
|||
c.JSON(200, user)
|
||||
}
|
||||
|
||||
// PatchUser
|
||||
//
|
||||
// @Summary Change a user
|
||||
// @Description Changes the data of an existing user. Requires admin rights.
|
||||
// @Router /users/{login} [patch]
|
||||
// @Produce json
|
||||
// @Accept json
|
||||
// @Success 200 {object} User
|
||||
// @Tags Users
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param login path string true "the user's login name"
|
||||
// @Param user body User true "the user's data"
|
||||
func PatchUser(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
|
||||
|
@ -75,6 +108,16 @@ func PatchUser(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, user)
|
||||
}
|
||||
|
||||
// PostUser
|
||||
//
|
||||
// @Summary Create a user
|
||||
// @Description Creates a new user account with the specified external login. Requires admin rights.
|
||||
// @Router /users [post]
|
||||
// @Produce json
|
||||
// @Success 200 {object} User
|
||||
// @Tags Users
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param user body User true "the user's data"
|
||||
func PostUser(c *gin.Context) {
|
||||
in := &model.User{}
|
||||
err := c.Bind(in)
|
||||
|
@ -101,6 +144,16 @@ func PostUser(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, user)
|
||||
}
|
||||
|
||||
// DeleteUser
|
||||
//
|
||||
// @Summary Delete a user
|
||||
// @Description Deletes the given user. Requires admin rights.
|
||||
// @Router /users/{login} [delete]
|
||||
// @Produce json
|
||||
// @Success 200 {object} User
|
||||
// @Tags Users
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param login path string true "the user's login name"
|
||||
func DeleteUser(c *gin.Context) {
|
||||
_store := store.FromContext(c)
|
||||
|
||||
|
|
|
@ -25,7 +25,15 @@ import (
|
|||
"github.com/woodpecker-ci/woodpecker/version"
|
||||
)
|
||||
|
||||
// Health endpoint returns a 500 if the server state is unhealthy.
|
||||
// Health
|
||||
//
|
||||
// @Summary Health information
|
||||
// @Description If everything is fine, just a 200 will be returned, a 500 signals server state is unhealthy.
|
||||
// @Router /healthz [get]
|
||||
// @Produce plain
|
||||
// @Success 200
|
||||
// @Failure 500
|
||||
// @Tags System
|
||||
func Health(c *gin.Context) {
|
||||
if err := store.FromContext(c).Ping(); err != nil {
|
||||
c.String(http.StatusInternalServerError, err.Error())
|
||||
|
@ -34,7 +42,14 @@ func Health(c *gin.Context) {
|
|||
c.String(http.StatusOK, "")
|
||||
}
|
||||
|
||||
// Version endpoint returns the server version and build information.
|
||||
// Version
|
||||
//
|
||||
// @Summary Get version
|
||||
// @Description Endpoint returns the server version and build information.
|
||||
// @Router /version [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} string{source=string,version=string}
|
||||
// @Tags System
|
||||
func Version(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"source": "https://github.com/woodpecker-ci/woodpecker",
|
||||
|
@ -42,14 +57,30 @@ func Version(c *gin.Context) {
|
|||
})
|
||||
}
|
||||
|
||||
// LogLevel endpoint returns the current logging level
|
||||
// LogLevel
|
||||
//
|
||||
// @Summary Current log level
|
||||
// @Description Endpoint returns the current logging level. Requires admin rights.
|
||||
// @Router /log-level [get]
|
||||
// @Produce json
|
||||
// @Success 200 {object} string{log-level=string}
|
||||
// @Tags System
|
||||
func LogLevel(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"log-level": zerolog.GlobalLevel().String(),
|
||||
})
|
||||
}
|
||||
|
||||
// SetLogLevel endpoint allows setting the logging level via API
|
||||
// SetLogLevel
|
||||
//
|
||||
// @Summary Set log level
|
||||
// @Description Endpoint sets the current logging level. Requires admin rights.
|
||||
// @Router /log-level [post]
|
||||
// @Produce json
|
||||
// @Success 200 {object} string{log-level=string}
|
||||
// @Tags System
|
||||
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
|
||||
// @Param log-level body string{log-level=string} true "the new log level, one of <debug,trace,info,warn,error,fatal,panic,disabled>"
|
||||
func SetLogLevel(c *gin.Context) {
|
||||
logLevel := struct {
|
||||
LogLevel string `json:"log-level"`
|
||||
|
|
|
@ -27,7 +27,7 @@ type Agent struct {
|
|||
Capacity int32 `json:"capacity"`
|
||||
Version string `json:"version"`
|
||||
NoSchedule bool `json:"no_schedule"`
|
||||
}
|
||||
} // @name Agent
|
||||
|
||||
// TableName return database table name for xorm
|
||||
func (Agent) TableName() string {
|
||||
|
|
|
@ -31,7 +31,7 @@ type Config struct {
|
|||
Hash string `json:"hash" xorm:"UNIQUE(s) 'config_hash'"`
|
||||
Name string `json:"name" xorm:"config_name"`
|
||||
Data []byte `json:"data" xorm:"config_data"`
|
||||
}
|
||||
} // @name Config
|
||||
|
||||
// PipelineConfig is the n:n relation between Pipeline and Config
|
||||
type PipelineConfig struct {
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
type WebhookEvent string
|
||||
type WebhookEvent string // @name WebhookEvent
|
||||
|
||||
const (
|
||||
EventPush WebhookEvent = "push"
|
||||
|
@ -49,7 +49,7 @@ func ValidateWebhookEvent(s WebhookEvent) error {
|
|||
}
|
||||
|
||||
// StatusValue represent pipeline states woodpecker know
|
||||
type StatusValue string
|
||||
type StatusValue string // @name StatusValue
|
||||
|
||||
const (
|
||||
StatusSkipped StatusValue = "skipped"
|
||||
|
@ -64,7 +64,7 @@ const (
|
|||
)
|
||||
|
||||
// SCMKind represent different version control systems
|
||||
type SCMKind string
|
||||
type SCMKind string // @name SCMKind
|
||||
|
||||
const (
|
||||
RepoGit SCMKind = "git"
|
||||
|
@ -74,7 +74,7 @@ const (
|
|||
)
|
||||
|
||||
// RepoVisibility represent to wat state a repo in woodpecker is visible to others
|
||||
type RepoVisibility string
|
||||
type RepoVisibility string // @name RepoVisibility
|
||||
|
||||
const (
|
||||
VisibilityPublic RepoVisibility = "public"
|
||||
|
|
|
@ -20,7 +20,6 @@ import (
|
|||
"github.com/robfig/cron"
|
||||
)
|
||||
|
||||
// swagger:model cron
|
||||
type Cron struct {
|
||||
ID int64 `json:"id" xorm:"pk autoincr"`
|
||||
Name string `json:"name" xorm:"UNIQUE(s) INDEX"`
|
||||
|
@ -30,7 +29,7 @@ type Cron struct {
|
|||
Schedule string `json:"schedule" xorm:"NOT NULL"` // @weekly, 3min, ...
|
||||
Created int64 `json:"created_at" xorm:"created NOT NULL DEFAULT 0"`
|
||||
Branch string `json:"branch"`
|
||||
}
|
||||
} // @name Cron
|
||||
|
||||
// TableName returns the database table name for xorm
|
||||
func (Cron) TableName() string {
|
||||
|
|
|
@ -35,7 +35,6 @@ type EnvironStore interface {
|
|||
}
|
||||
|
||||
// Environ represents an environment variable.
|
||||
// swagger:model environ
|
||||
type Environ struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
package model
|
||||
|
||||
// Feed represents an item in the user's feed or timeline.
|
||||
//
|
||||
// swagger:model feed
|
||||
type Feed struct {
|
||||
Owner string `json:"owner" xorm:"feed_repo_owner"`
|
||||
Name string `json:"name" xorm:"feed_repo_name"`
|
||||
|
@ -40,4 +38,4 @@ type Feed struct {
|
|||
Author string `json:"author,omitempty" xorm:"feed_pipeline_author"`
|
||||
Avatar string `json:"author_avatar,omitempty" xorm:"feed_pipeline_avatar"`
|
||||
Email string `json:"author_email,omitempty" xorm:"feed_pipeline_email"`
|
||||
}
|
||||
} // @name Feed
|
||||
|
|
|
@ -34,15 +34,15 @@ type Perm struct {
|
|||
Synced int64 `json:"synced" xorm:"perm_synced"`
|
||||
Created int64 `json:"created" xorm:"created"`
|
||||
Updated int64 `json:"updated" xorm:"updated"`
|
||||
}
|
||||
} // @name Perm
|
||||
|
||||
// TableName return database table name for xorm
|
||||
func (Perm) TableName() string {
|
||||
return "perms"
|
||||
}
|
||||
|
||||
// OrgPerm defines a organization permission for an individual user.
|
||||
// OrgPerm defines an organization permission for an individual user.
|
||||
type OrgPerm struct {
|
||||
Member bool `json:"member"`
|
||||
Admin bool `json:"admin"`
|
||||
}
|
||||
} // @name OrgPerm
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
package model
|
||||
|
||||
// swagger:model pipeline
|
||||
type Pipeline struct {
|
||||
ID int64 `json:"id" xorm:"pk autoincr 'pipeline_id'"`
|
||||
RepoID int64 `json:"-" xorm:"UNIQUE(s) INDEX 'pipeline_repo_id'"`
|
||||
|
@ -52,7 +51,7 @@ type Pipeline struct {
|
|||
ChangedFiles []string `json:"changed_files,omitempty" xorm:"json 'changed_files'"`
|
||||
AdditionalVariables map[string]string `json:"variables,omitempty" xorm:"json 'additional_variables'"`
|
||||
PullRequestLabels []string `json:"pr_labels,omitempty" xorm:"json 'pr_labels'"`
|
||||
}
|
||||
} // @name Pipeline
|
||||
|
||||
// TableName return database table name for xorm
|
||||
func (Pipeline) TableName() string {
|
||||
|
@ -66,4 +65,4 @@ type UpdatePipelineStore interface {
|
|||
type PipelineOptions struct {
|
||||
Branch string `json:"branch"`
|
||||
Variables map[string]string `json:"variables"`
|
||||
}
|
||||
} // @name PipelineOptions
|
||||
|
|
|
@ -3,4 +3,4 @@ package model
|
|||
type PullRequest struct {
|
||||
Index int64 `json:"index"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
} // @name PullRequest
|
||||
|
|
|
@ -51,7 +51,6 @@ type RegistryStore interface {
|
|||
}
|
||||
|
||||
// Registry represents a docker registry with credentials.
|
||||
// swagger:model registry
|
||||
type Registry struct {
|
||||
ID int64 `json:"id" xorm:"pk autoincr 'registry_id'"`
|
||||
RepoID int64 `json:"-" xorm:"UNIQUE(s) INDEX 'registry_repo_id'"`
|
||||
|
@ -60,7 +59,7 @@ type Registry struct {
|
|||
Password string `json:"password" xorm:"TEXT 'registry_password'"`
|
||||
Token string `json:"token" xorm:"TEXT 'registry_token'"`
|
||||
Email string `json:"email" xorm:"varchar(500) 'registry_email'"`
|
||||
}
|
||||
} // @name Registry
|
||||
|
||||
// Validate validates the registry information.
|
||||
func (r *Registry) Validate() error {
|
||||
|
|
|
@ -21,8 +21,6 @@ import (
|
|||
)
|
||||
|
||||
// Repo represents a repository.
|
||||
//
|
||||
// swagger:model repo
|
||||
type Repo struct {
|
||||
ID int64 `json:"id,omitempty" xorm:"pk autoincr 'repo_id'"`
|
||||
UserID int64 `json:"-" xorm:"repo_user_id"`
|
||||
|
@ -48,7 +46,7 @@ type Repo struct {
|
|||
Perm *Perm `json:"-" xorm:"-"`
|
||||
CancelPreviousPipelineEvents []WebhookEvent `json:"cancel_previous_pipeline_events" xorm:"json 'cancel_previous_pipeline_events'"`
|
||||
NetrcOnlyTrusted bool `json:"netrc_only_trusted" xorm:"NOT NULL DEFAULT true 'netrc_only_trusted'"`
|
||||
}
|
||||
} // @name Repo
|
||||
|
||||
// TableName return database table name for xorm
|
||||
func (Repo) TableName() string {
|
||||
|
@ -109,7 +107,7 @@ type RepoPatch struct {
|
|||
AllowPull *bool `json:"allow_pr,omitempty"`
|
||||
CancelPreviousPipelineEvents *[]WebhookEvent `json:"cancel_previous_pipeline_events"`
|
||||
NetrcOnlyTrusted *bool `json:"netrc_only_trusted"`
|
||||
}
|
||||
} // @name RepoPatch
|
||||
|
||||
type ForgeRemoteID string
|
||||
|
||||
|
|
|
@ -68,7 +68,6 @@ type SecretStore interface {
|
|||
}
|
||||
|
||||
// Secret represents a secret variable, such as a password or token.
|
||||
// swagger:model registry
|
||||
type Secret struct {
|
||||
ID int64 `json:"id" xorm:"pk autoincr 'secret_id'"`
|
||||
Owner string `json:"-" xorm:"NOT NULL DEFAULT '' UNIQUE(s) INDEX 'secret_owner'"`
|
||||
|
@ -80,7 +79,7 @@ type Secret struct {
|
|||
Events []WebhookEvent `json:"event" xorm:"json 'secret_events'"`
|
||||
SkipVerify bool `json:"-" xorm:"secret_skip_verify"`
|
||||
Conceal bool `json:"-" xorm:"secret_conceal"`
|
||||
}
|
||||
} // @name Secret
|
||||
|
||||
// TableName return database table name for xorm
|
||||
func (Secret) TableName() string {
|
||||
|
|
|
@ -29,7 +29,6 @@ type StepStore interface {
|
|||
}
|
||||
|
||||
// Step represents a process in the pipeline.
|
||||
// swagger:model step
|
||||
type Step struct {
|
||||
ID int64 `json:"id" xorm:"pk autoincr 'step_id'"`
|
||||
PipelineID int64 `json:"pipeline_id" xorm:"UNIQUE(s) INDEX 'step_pipeline_id'"`
|
||||
|
@ -46,7 +45,7 @@ type Step struct {
|
|||
Platform string `json:"platform,omitempty" xorm:"step_platform"`
|
||||
Environ map[string]string `json:"environ,omitempty" xorm:"json 'step_environ'"`
|
||||
Children []*Step `json:"children,omitempty" xorm:"-"`
|
||||
}
|
||||
} // @name Step
|
||||
|
||||
type UpdateStepStore interface {
|
||||
StepUpdate(*Step) error
|
||||
|
|
|
@ -35,7 +35,7 @@ type Task struct {
|
|||
RunOn []string `json:"run_on" xorm:"json 'task_run_on'"`
|
||||
DepStatus map[string]StatusValue `json:"dep_status" xorm:"json 'task_dep_status'"`
|
||||
AgentID int64 `json:"agent_id" xorm:"'agent_id'"`
|
||||
}
|
||||
} // @name Task
|
||||
|
||||
// TableName return database table name for xorm
|
||||
func (Task) TableName() string {
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
package model
|
||||
|
||||
// Team represents a team or organization in the forge.
|
||||
//
|
||||
// swagger:model user
|
||||
type Team struct {
|
||||
// Login is the username for this team.
|
||||
Login string `json:"login"`
|
||||
|
|
|
@ -26,8 +26,6 @@ var reUsername = regexp.MustCompile("^[a-zA-Z0-9-_.]+$")
|
|||
var errUserLoginInvalid = errors.New("Invalid User Login")
|
||||
|
||||
// User represents a registered user.
|
||||
//
|
||||
// swagger:model user
|
||||
type User struct {
|
||||
// the id for this user.
|
||||
//
|
||||
|
@ -66,7 +64,7 @@ type User struct {
|
|||
|
||||
// Hash is a unique token used to sign tokens.
|
||||
Hash string `json:"-" xorm:"UNIQUE varchar(500) 'user_hash'"`
|
||||
}
|
||||
} // @name User
|
||||
|
||||
// TableName return database table name for xorm
|
||||
func (User) TableName() string {
|
||||
|
|
|
@ -29,7 +29,7 @@ type InfoT struct {
|
|||
Complete int `json:"completed_count"`
|
||||
} `json:"stats"`
|
||||
Paused bool `json:"paused"`
|
||||
}
|
||||
} // @name InfoT
|
||||
|
||||
func (t *InfoT) String() string {
|
||||
var sb strings.Builder
|
||||
|
|
|
@ -16,9 +16,14 @@ package router
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/rs/zerolog/log"
|
||||
swaggerfiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
"github.com/woodpecker-ci/woodpecker/cmd/server/docs"
|
||||
"github.com/woodpecker-ci/woodpecker/server"
|
||||
|
||||
"github.com/woodpecker-ci/woodpecker/server/api"
|
||||
"github.com/woodpecker-ci/woodpecker/server/api/metrics"
|
||||
|
@ -64,6 +69,18 @@ func Load(noRouteHandler http.HandlerFunc, middleware ...gin.HandlerFunc) http.H
|
|||
e.GET("/healthz", api.Health)
|
||||
|
||||
apiRoutes(e)
|
||||
setupSwaggerConfigAndRoutes(e)
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func setupSwaggerConfigAndRoutes(e *gin.Engine) {
|
||||
docs.SwaggerInfo.Host = getHost(server.Config.Server.Host)
|
||||
docs.SwaggerInfo.BasePath = server.Config.Server.RootURL + "/api"
|
||||
e.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
|
||||
}
|
||||
|
||||
func getHost(s string) string {
|
||||
parse, _ := url.Parse(s)
|
||||
return parse.Host
|
||||
}
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package classification Drone API.
|
||||
//
|
||||
// Schemes: http, https
|
||||
// BasePath: /api
|
||||
// Version: 1.0.0
|
||||
//
|
||||
// Consumes:
|
||||
// - application/json
|
||||
//
|
||||
// Produces:
|
||||
// - application/json
|
||||
//
|
||||
// swagger:meta
|
||||
package swagger
|
||||
|
||||
//go:generate swagger generate spec -o files/swagger.json
|
||||
//go:generate go-bindata -pkg swagger -o swagger_gen.go files/
|
|
@ -1,991 +0,0 @@
|
|||
swagger: "2.0"
|
||||
info:
|
||||
version: 1.0.0
|
||||
title: Woodpecker API
|
||||
license:
|
||||
name: Creative Commons 4.0 International
|
||||
url: "http://creativecommons.org/licenses/by/4.0/"
|
||||
|
||||
host: "localhost:8080"
|
||||
basePath: /api
|
||||
schemes:
|
||||
- http
|
||||
- https
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
|
||||
#
|
||||
# Operation tags
|
||||
#
|
||||
|
||||
tags:
|
||||
- name: Repos
|
||||
- name: Builds
|
||||
- name: User
|
||||
- name: Users
|
||||
|
||||
#
|
||||
# Security Definitions
|
||||
#
|
||||
|
||||
security:
|
||||
- accessToken: []
|
||||
securityDefinitions:
|
||||
accessToken:
|
||||
type: apiKey
|
||||
in: query
|
||||
name: access_token
|
||||
|
||||
#
|
||||
# Endpoint Definitions
|
||||
#
|
||||
|
||||
paths:
|
||||
|
||||
#
|
||||
# Repos Endpoint
|
||||
#
|
||||
|
||||
/repos/{owner}/{name}:
|
||||
get:
|
||||
parameters:
|
||||
- name: owner
|
||||
in: path
|
||||
type: string
|
||||
description: owner of the repository
|
||||
- name: name
|
||||
in: path
|
||||
type: string
|
||||
description: name of the repository
|
||||
tags:
|
||||
- Repos
|
||||
summary: Get a repo
|
||||
description: Retrieves the details of a repository.
|
||||
security:
|
||||
- accessToken: []
|
||||
responses:
|
||||
200:
|
||||
schema:
|
||||
$ref: "#/definitions/Repo"
|
||||
404:
|
||||
description: |
|
||||
Unable to find the repository.
|
||||
|
||||
patch:
|
||||
parameters:
|
||||
- name: owner
|
||||
in: path
|
||||
type: string
|
||||
description: owner of the repository
|
||||
- name: name
|
||||
in: path
|
||||
type: string
|
||||
description: name of the repository
|
||||
- name: repo
|
||||
in: body
|
||||
description: The updated repository JSON
|
||||
schema:
|
||||
$ref: '#/definitions/Repo'
|
||||
example: |
|
||||
{
|
||||
"timeout": 60,
|
||||
"private": false,
|
||||
"trusted": false,
|
||||
"allow_pr": true
|
||||
}
|
||||
required: true
|
||||
tags:
|
||||
- Repos
|
||||
summary: Updates a repo
|
||||
description: Updates the specified repository.
|
||||
security:
|
||||
- accessToken: []
|
||||
responses:
|
||||
200:
|
||||
schema:
|
||||
$ref: "#/definitions/Repo"
|
||||
400:
|
||||
description: |
|
||||
Unable to update the repository in the database.
|
||||
404:
|
||||
description: |
|
||||
Unable to find the repository.
|
||||
|
||||
post:
|
||||
parameters:
|
||||
- name: owner
|
||||
in: path
|
||||
type: string
|
||||
description: owner of the repository
|
||||
- name: name
|
||||
in: path
|
||||
type: string
|
||||
description: name of the repository
|
||||
tags:
|
||||
- Repos
|
||||
summary: Activates a repo
|
||||
description: Activates a repository.
|
||||
security:
|
||||
- accessToken: []
|
||||
responses:
|
||||
200:
|
||||
schema:
|
||||
$ref: "#/definitions/Repo"
|
||||
400:
|
||||
description: |
|
||||
Unable to update the Repository record in the database
|
||||
403:
|
||||
description: |
|
||||
Unable to activate the Repository due to insufficient privileges
|
||||
404:
|
||||
description: |
|
||||
Unable to retrieve the Repository from the remote system (ie GitHub)
|
||||
409:
|
||||
description: |
|
||||
Unable to activate the Repository because it is already activate
|
||||
500:
|
||||
description: |
|
||||
Unable to activate the Repository due to an internal server error. This may indicate a problem adding hooks to the remote system (ie GitHub), generating SSH deployment keys, or persisting to the database.
|
||||
|
||||
delete:
|
||||
parameters:
|
||||
- name: owner
|
||||
in: path
|
||||
type: string
|
||||
description: owner of the repository
|
||||
- name: name
|
||||
in: path
|
||||
type: string
|
||||
description: name of the repository
|
||||
tags:
|
||||
- Repos
|
||||
summary: Delete a repo
|
||||
description: Permanently deletes a repository. It cannot be undone.
|
||||
security:
|
||||
- accessToken: []
|
||||
responses:
|
||||
200:
|
||||
description: |
|
||||
Successfully deleted the Repository
|
||||
400:
|
||||
description: |
|
||||
Unable to remove post-commit hooks from the remote system (ie GitHub)
|
||||
404:
|
||||
description: |
|
||||
Unable to find the Repository in the database
|
||||
500:
|
||||
description: |
|
||||
Unable to update the Repository record in the database
|
||||
|
||||
|
||||
#
|
||||
# Repos Param Encryption Endpoint
|
||||
# TODO: properly add the input output schema
|
||||
|
||||
/repos/{owner}/{name}/encrypt:
|
||||
post:
|
||||
parameters:
|
||||
- name: owner
|
||||
in: path
|
||||
type: string
|
||||
description: owner of the repository
|
||||
- name: name
|
||||
in: path
|
||||
type: string
|
||||
description: name of the repository
|
||||
tags:
|
||||
- Repos
|
||||
summary: Encrypt repo secrets
|
||||
description: Encrypts a Yaml file with secret environment variables for secure public storage.
|
||||
security:
|
||||
- accessToken: []
|
||||
responses:
|
||||
200:
|
||||
description: The encrypted parameters.
|
||||
400:
|
||||
description: |
|
||||
Unable to encrypt the parameters.
|
||||
404:
|
||||
description: |
|
||||
Unable to find the repository.
|
||||
|
||||
|
||||
#
|
||||
# Builds Endpoint
|
||||
#
|
||||
|
||||
/repos/{owner}/{name}/builds:
|
||||
get:
|
||||
parameters:
|
||||
- name: owner
|
||||
in: path
|
||||
type: string
|
||||
description: owner of the repository
|
||||
- name: name
|
||||
in: path
|
||||
type: string
|
||||
description: name of the repository
|
||||
tags:
|
||||
- Builds
|
||||
summary: Get recent builds
|
||||
description: Returns recent builds for the repository based on name.
|
||||
security:
|
||||
- accessToken: []
|
||||
responses:
|
||||
200:
|
||||
description: The recent builds.
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/Build"
|
||||
404:
|
||||
description: |
|
||||
Unable to find the Repository in the database
|
||||
|
||||
|
||||
/repos/{owner}/{name}/builds/{number}:
|
||||
get:
|
||||
parameters:
|
||||
- name: owner
|
||||
in: path
|
||||
type: string
|
||||
description: owner of the repository
|
||||
- name: name
|
||||
in: path
|
||||
type: string
|
||||
description: name of the repository
|
||||
- name: branch
|
||||
in: query
|
||||
type: string
|
||||
description: name of the branch
|
||||
required: false
|
||||
- name: number
|
||||
in: path
|
||||
type: integer
|
||||
description: sequential build number
|
||||
tags:
|
||||
- Builds
|
||||
summary: Get the latest build
|
||||
description: Returns the latest repository build.
|
||||
security:
|
||||
- accessToken: []
|
||||
responses:
|
||||
200:
|
||||
description: The build.
|
||||
schema:
|
||||
$ref: "#/definitions/Build"
|
||||
404:
|
||||
description: |
|
||||
Unable to find the Repository or Build
|
||||
|
||||
post:
|
||||
parameters:
|
||||
- name: owner
|
||||
in: path
|
||||
type: string
|
||||
description: owner of the repository
|
||||
- name: name
|
||||
in: path
|
||||
type: string
|
||||
description: name of the repository
|
||||
- name: number
|
||||
in: path
|
||||
type: integer
|
||||
description: sequential build number
|
||||
tags:
|
||||
- Builds
|
||||
summary: Restart a build
|
||||
description: Restart the a build by number.
|
||||
security:
|
||||
- accessToken: []
|
||||
responses:
|
||||
200:
|
||||
description: Successfully restarted the Pipeline.
|
||||
schema:
|
||||
$ref: "#/definitions/Build"
|
||||
404:
|
||||
description: |
|
||||
Unable to find the Repository or Build.
|
||||
409:
|
||||
description: |
|
||||
Cannot re-start a Build that is running.
|
||||
|
||||
|
||||
#
|
||||
# Jobs Endpoint
|
||||
#
|
||||
|
||||
/repos/{owner}/{name}/logs/{number}/{job}:
|
||||
get:
|
||||
parameters:
|
||||
- name: owner
|
||||
in: path
|
||||
type: string
|
||||
description: owner of the repository
|
||||
- name: name
|
||||
in: path
|
||||
type: string
|
||||
description: name of the repository
|
||||
- name: number
|
||||
in: path
|
||||
type: integer
|
||||
description: sequential build number
|
||||
- name: job
|
||||
in: path
|
||||
type: integer
|
||||
description: sequential job number
|
||||
tags:
|
||||
- Builds
|
||||
summary: Get build logs
|
||||
description: Returns the build logs for a specific job (build step).
|
||||
produces:
|
||||
- text/plain
|
||||
security:
|
||||
- accessToken: []
|
||||
responses:
|
||||
200:
|
||||
description: The logs for the requested job.
|
||||
404:
|
||||
description: |
|
||||
Unable to find the repository, build or job.
|
||||
|
||||
delete:
|
||||
parameters:
|
||||
- name: owner
|
||||
in: path
|
||||
type: string
|
||||
description: owner of the repository
|
||||
- name: name
|
||||
in: path
|
||||
type: string
|
||||
description: name of the repository
|
||||
- name: number
|
||||
in: path
|
||||
type: integer
|
||||
description: sequential build number
|
||||
- name: job
|
||||
in: path
|
||||
type: integer
|
||||
description: sequential job number
|
||||
tags:
|
||||
- Builds
|
||||
summary: Cancel a Job
|
||||
description: Cancel the a build job by number.
|
||||
security:
|
||||
- accessToken: []
|
||||
responses:
|
||||
200:
|
||||
description: Successfully canceled the Job
|
||||
404:
|
||||
description: |
|
||||
Unable to find the Repository or Job
|
||||
409:
|
||||
description: |
|
||||
Cannot cancel a Job that is already stopped
|
||||
|
||||
|
||||
#
|
||||
# User Endpoint
|
||||
#
|
||||
|
||||
/user:
|
||||
get:
|
||||
summary: Gets a user
|
||||
description: Returns the currently authenticated user.
|
||||
security:
|
||||
- accessToken: []
|
||||
tags:
|
||||
- User
|
||||
responses:
|
||||
200:
|
||||
description: The currently authenticated user.
|
||||
schema:
|
||||
$ref: "#/definitions/User"
|
||||
patch:
|
||||
summary: Updates a user
|
||||
description: Updates the currently authenticated user.
|
||||
tags:
|
||||
- User
|
||||
parameters:
|
||||
- name: user
|
||||
in: body
|
||||
description: Updates to the user.
|
||||
required: true
|
||||
schema:
|
||||
$ref: "#/definitions/User"
|
||||
responses:
|
||||
200:
|
||||
description: The updated user.
|
||||
schema:
|
||||
$ref: "#/definitions/User"
|
||||
400:
|
||||
description: |
|
||||
Unable to update the user in the database
|
||||
|
||||
|
||||
#
|
||||
# User Repos
|
||||
#
|
||||
|
||||
/user/repos:
|
||||
get:
|
||||
summary: Get user repos
|
||||
description: |
|
||||
Retrieve the currently authenticated User's Repository list
|
||||
tags:
|
||||
- User
|
||||
responses:
|
||||
200:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/Repo"
|
||||
400:
|
||||
description: |
|
||||
Unable to retrieve Repository list
|
||||
|
||||
|
||||
#
|
||||
# Users Endpoint
|
||||
#
|
||||
|
||||
/users:
|
||||
get:
|
||||
tags:
|
||||
- Users
|
||||
summary: Get all users
|
||||
description: Returns all registered, active users in the system.
|
||||
security:
|
||||
- accessToken: []
|
||||
responses:
|
||||
200:
|
||||
description: All registered users.
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/User"
|
||||
|
||||
/users/{login}:
|
||||
get:
|
||||
parameters:
|
||||
- name: login
|
||||
in: path
|
||||
type: string
|
||||
description: user login
|
||||
tags:
|
||||
- Users
|
||||
summary: Get a user
|
||||
description: Returns a user with the specified login name.
|
||||
security:
|
||||
- accessToken: []
|
||||
responses:
|
||||
200:
|
||||
description: Returns the user.
|
||||
schema:
|
||||
$ref: "#/definitions/User"
|
||||
404:
|
||||
description: Cannot find user with matching login.
|
||||
|
||||
post:
|
||||
parameters:
|
||||
- name: login
|
||||
in: path
|
||||
type: string
|
||||
description: user login to activate
|
||||
tags:
|
||||
- Users
|
||||
summary: Create a user
|
||||
description: Creates a new user account with the specified external login.
|
||||
security:
|
||||
- accessToken: []
|
||||
responses:
|
||||
201:
|
||||
description: Returns the created user.
|
||||
schema:
|
||||
$ref: "#/definitions/User"
|
||||
400:
|
||||
description: |
|
||||
Error inserting User into the database
|
||||
|
||||
patch:
|
||||
parameters:
|
||||
- name: login
|
||||
in: path
|
||||
type: string
|
||||
description: user login
|
||||
- name: user
|
||||
in: body
|
||||
description: changes to the user
|
||||
schema:
|
||||
$ref: '#/definitions/User'
|
||||
example: |
|
||||
{
|
||||
"email": "octocat@github.com",
|
||||
"admin": false,
|
||||
"active": true
|
||||
}
|
||||
required: true
|
||||
|
||||
tags:
|
||||
- Users
|
||||
summary: Update a user
|
||||
description: Updates an existing user account.
|
||||
security:
|
||||
- accessToken: []
|
||||
responses:
|
||||
200:
|
||||
description: Returns the updated user.
|
||||
schema:
|
||||
$ref: "#/definitions/User"
|
||||
400:
|
||||
description: |
|
||||
Error updating the User in the database
|
||||
|
||||
delete:
|
||||
parameters:
|
||||
- name: login
|
||||
in: path
|
||||
type: string
|
||||
description: user login
|
||||
tags:
|
||||
- Users
|
||||
summary: Delete a user
|
||||
description: Deletes the user with the specified login name.
|
||||
security:
|
||||
- accessToken: []
|
||||
responses:
|
||||
204:
|
||||
description: |
|
||||
Successfully deleted the User
|
||||
400:
|
||||
description: |
|
||||
Error deleting the User from the database
|
||||
403:
|
||||
description: |
|
||||
Cannot delete your own User account
|
||||
404:
|
||||
description: |
|
||||
Cannot find the User
|
||||
|
||||
#
|
||||
# Schema Definitions
|
||||
#
|
||||
|
||||
definitions:
|
||||
User:
|
||||
description: The user account.
|
||||
example: |
|
||||
{
|
||||
"id": 1,
|
||||
"login": "octocat",
|
||||
"email": "octocat@github.com",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/7194e8d48fa1d2b689f99443b767316c",
|
||||
"admin": false,
|
||||
"active": true
|
||||
}
|
||||
properties:
|
||||
id:
|
||||
description: The unique identifier for the account.
|
||||
type: integer
|
||||
format: int64
|
||||
login:
|
||||
description: The login name for the account.
|
||||
type: string
|
||||
email:
|
||||
description: The email address for the account.
|
||||
type: string
|
||||
avatar_url:
|
||||
description: The url for the avatar image.
|
||||
type: string
|
||||
admin:
|
||||
description: Whether the account has administrative privileges.
|
||||
type: boolean
|
||||
active:
|
||||
description: Whether the account is currently active.
|
||||
type: boolean
|
||||
|
||||
Repo:
|
||||
description: A version control repository.
|
||||
example: |
|
||||
{
|
||||
"id": 1,
|
||||
"scm": "git",
|
||||
"owner": "octocat",
|
||||
"name": "hello-world",
|
||||
"full_name": "octocat/hello-world",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/2181346?v=3",
|
||||
"link_url": "https://github.com/octocat/hello-world",
|
||||
"clone_url": "https://github.com/octocat/hello-world.git",
|
||||
"default_branch": "master",
|
||||
"timeout": 60,
|
||||
"private": false,
|
||||
"trusted": false,
|
||||
"allow_pr": true
|
||||
}
|
||||
properties:
|
||||
id:
|
||||
description: The unique identifier for the repository.
|
||||
type: integer
|
||||
format: int64
|
||||
scm:
|
||||
description: |
|
||||
The source control management being used.
|
||||
|
||||
Currently this is either 'git' or 'hg' (Mercurial).
|
||||
type: string
|
||||
owner:
|
||||
description: The owner of the repository.
|
||||
type: string
|
||||
name:
|
||||
description: The name of the repository.
|
||||
type: string
|
||||
full_name:
|
||||
description: |
|
||||
The full name of the repository.
|
||||
|
||||
This is created from the owner and name of the repository.
|
||||
type: string
|
||||
avatar_url:
|
||||
description: The url for the avatar image.
|
||||
type: string
|
||||
link_url:
|
||||
description: The link to view the repository.
|
||||
type: string
|
||||
clone_url:
|
||||
description: The url used to clone the repository.
|
||||
type: string
|
||||
default_branch:
|
||||
description: The default branch of the repository.
|
||||
type: string
|
||||
private:
|
||||
description: Whether the repository is publicly visible.
|
||||
type: boolean
|
||||
trusted:
|
||||
description: |
|
||||
Whether the repository has trusted access for builds.
|
||||
|
||||
If the repository is trusted then the host network can be used and
|
||||
volumes can be created.
|
||||
type: boolean
|
||||
timeout:
|
||||
description: The amount of time in minutes before the build is killed.
|
||||
type: integer
|
||||
x-dart-type: Duration
|
||||
allow_pr:
|
||||
description: Whether pull requests should trigger a build.
|
||||
type: boolean
|
||||
|
||||
Build:
|
||||
description: A build for a repository.
|
||||
example: |
|
||||
{
|
||||
"id": 1,
|
||||
"number": 1,
|
||||
"event": "push",
|
||||
"status": "success",
|
||||
"created_at": 1443677151,
|
||||
"enqueued_at": 1443677151,
|
||||
"started_at": 1443677151,
|
||||
"finished_at": 1443677255,
|
||||
"commit": "2deb7e0d0cbac357eeb110c8a2f2f32ce037e0d5",
|
||||
"branch": "master",
|
||||
"ref": "refs/heads/master",
|
||||
"remote": "https://github.com/octocat/hello-world.git",
|
||||
"message": "New line at end of file. --Signed off by Spaceghost",
|
||||
"timestamp": 1443677255,
|
||||
"author": "Spaceghost",
|
||||
"author_avatar": "https://avatars0.githubusercontent.com/u/251370?v=3",
|
||||
"author_email": "octocat@github.com",
|
||||
"link_url": "https://github.com/octocat/hello-world/commit/762941318ee16e59dabbacb1b4049eec22f0d303",
|
||||
"jobs": [
|
||||
{
|
||||
"id": 1,
|
||||
"number": 1,
|
||||
"status": "success",
|
||||
"enqueued_at": 1443677151,
|
||||
"started_at": 1443677151,
|
||||
"finished_at": 1443677255,
|
||||
"exit_code": 0,
|
||||
"environment": { "GO_VERSION": "1.4" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"number": 2,
|
||||
"status": "success",
|
||||
"enqueued_at": 1443677151,
|
||||
"started_at": 1443677151,
|
||||
"finished_at": 1443677255,
|
||||
"exit_code": 0,
|
||||
"environment": { "GO_VERSION": "1.5" }
|
||||
}
|
||||
]
|
||||
}
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
number:
|
||||
description: |
|
||||
The build number.
|
||||
|
||||
This number is specified within the context of the repository the build
|
||||
belongs to and is unique within that.
|
||||
type: integer
|
||||
status:
|
||||
description: The current status of the build.
|
||||
$ref: '#definitions/BuildStatus'
|
||||
created_at:
|
||||
description: When the build request was received.
|
||||
type: integer
|
||||
format: int64
|
||||
x-dart-type: DateTime
|
||||
enqueued_at:
|
||||
description: When the build was enqueued.
|
||||
type: integer
|
||||
format: int64
|
||||
x-dart-type: DateTime
|
||||
started_at:
|
||||
description: When the build began execution.
|
||||
type: integer
|
||||
format: int64
|
||||
x-dart-type: DateTime
|
||||
finished_at:
|
||||
description: When the build was finished.
|
||||
type: integer
|
||||
format: int64
|
||||
x-dart-type: DateTime
|
||||
deploy_to:
|
||||
description: Where the deployment should go.
|
||||
type: string
|
||||
commit:
|
||||
description: The commit for the build.
|
||||
type: string
|
||||
branch:
|
||||
description: The branch the commit was pushed to.
|
||||
type: string
|
||||
message:
|
||||
description: The commit message.
|
||||
type: string
|
||||
timestamp:
|
||||
description: When the commit was created.
|
||||
type: integer
|
||||
format: int64
|
||||
x-dart-format: DateTime
|
||||
ref:
|
||||
description: The alias for the commit.
|
||||
type: string
|
||||
refspec:
|
||||
description: The mapping from the local repository to a branch in the remote.
|
||||
type: string
|
||||
remote:
|
||||
description: The remote repository.
|
||||
type: string
|
||||
author:
|
||||
description: The login for the author of the commit.
|
||||
type: string
|
||||
author_avatar:
|
||||
description: The avatar for the author of the commit.
|
||||
type: string
|
||||
author_email:
|
||||
description: The email for the author of the commit.
|
||||
type: string
|
||||
link_url:
|
||||
description: |
|
||||
The link to view the repository.
|
||||
|
||||
This link will point to the repository state associated with the
|
||||
build's commit.
|
||||
type: string
|
||||
jobs:
|
||||
description: |
|
||||
The jobs associated with this build.
|
||||
|
||||
A build will have multiple jobs if a matrix build was used or if a
|
||||
rebuild was requested.
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/Job"
|
||||
|
||||
BuildStatus:
|
||||
description: The status of a build.
|
||||
type: string
|
||||
enum:
|
||||
- success
|
||||
- failure
|
||||
- pending
|
||||
- started
|
||||
- error
|
||||
- killed
|
||||
x-enum-descriptions:
|
||||
- The build was successful.
|
||||
- The build failed.
|
||||
- The build is pending execution.
|
||||
- The build was started.
|
||||
- There was an error running the build.
|
||||
- The build was killed either manually or through a timeout.
|
||||
|
||||
Job:
|
||||
description: A single job being executed as part of a build.
|
||||
example: |
|
||||
{
|
||||
"id": 1,
|
||||
"number": 1,
|
||||
"status": "success",
|
||||
"enqueued_at": 1443677151,
|
||||
"started_at": 1443677151,
|
||||
"finished_at": 1443677255,
|
||||
"exit_code": 0,
|
||||
"environment": { "GO_VERSION": "1.4" }
|
||||
}
|
||||
properties:
|
||||
id:
|
||||
description: The unique identifier for the build.
|
||||
type: integer
|
||||
format: int64
|
||||
number:
|
||||
description: |
|
||||
The job number.
|
||||
|
||||
This number is specified within the context of the build the job
|
||||
belongs to and is unique within that.
|
||||
type: integer
|
||||
status:
|
||||
description: The current status of the job.
|
||||
$ref: '#definitions/BuildStatus'
|
||||
exit_code:
|
||||
description: The exit code for the build.
|
||||
type: integer
|
||||
enqueued_at:
|
||||
description: When the job was enqueued.
|
||||
type: integer
|
||||
format: int64
|
||||
x-dart-type: DateTime
|
||||
started_at:
|
||||
description: When the job began execution.
|
||||
type: integer
|
||||
format: int64
|
||||
x-dart-type: DateTime
|
||||
finished_at:
|
||||
description: When the job finished execution.
|
||||
type: integer
|
||||
format: int64
|
||||
x-dart-type: DateTime
|
||||
environment:
|
||||
description: |
|
||||
The environment that the job was run with.
|
||||
|
||||
This is a map containing any values for matrix builds.
|
||||
type: object
|
||||
|
||||
Feed:
|
||||
description: |
|
||||
A feed entry for a build.
|
||||
|
||||
Feed entries can be used to display information on the latest builds.
|
||||
example: |
|
||||
{
|
||||
"owner": "octocat",
|
||||
"name": "hello-world",
|
||||
"full_name": "octocat/hello-world",
|
||||
"number": 1,
|
||||
"event": "push",
|
||||
"status": "success",
|
||||
"created_at": 1443677151,
|
||||
"enqueued_at": 1443677151,
|
||||
"started_at": 1443677151,
|
||||
"finished_at": 1443677255,
|
||||
"commit": "2deb7e0d0cbac357eeb110c8a2f2f32ce037e0d5",
|
||||
"branch": "master",
|
||||
"ref": "refs/heads/master",
|
||||
"remote": "https://github.com/octocat/hello-world.git",
|
||||
"message": "New line at end of file. --Signed off by Spaceghost",
|
||||
"timestamp": 1443677255,
|
||||
"author": "Spaceghost",
|
||||
"author_avatar": "https://avatars0.githubusercontent.com/u/251370?v=3",
|
||||
"author_email": "octocat@github.com",
|
||||
"link_url": "https://github.com/octocat/hello-world/commit/762941318ee16e59dabbacb1b4049eec22f0d303",
|
||||
}
|
||||
properties:
|
||||
owner:
|
||||
description: The owner of the repository.
|
||||
type: string
|
||||
name:
|
||||
description: The name of the repository.
|
||||
type: string
|
||||
full_name:
|
||||
description: |
|
||||
The full name of the repository.
|
||||
|
||||
This is created from the owner and name of the repository.
|
||||
type: string
|
||||
number:
|
||||
description: |
|
||||
The build number.
|
||||
|
||||
This number is specified within the context of the repository the build
|
||||
belongs to and is unique within that.
|
||||
type: integer
|
||||
status:
|
||||
description: The current status of the build.
|
||||
$ref: '#definitions/BuildStatus'
|
||||
created_at:
|
||||
description: When the build request was received.
|
||||
type: integer
|
||||
format: int64
|
||||
x-dart-type: DateTime
|
||||
enqueued_at:
|
||||
description: When the build was enqueued.
|
||||
type: integer
|
||||
format: int64
|
||||
x-dart-type: DateTime
|
||||
started_at:
|
||||
description: When the build began execution.
|
||||
type: integer
|
||||
format: int64
|
||||
x-dart-type: DateTime
|
||||
finished_at:
|
||||
description: When the build was finished.
|
||||
type: integer
|
||||
format: int64
|
||||
x-dart-type: DateTime
|
||||
commit:
|
||||
description: The commit for the build.
|
||||
type: string
|
||||
branch:
|
||||
description: The branch the commit was pushed to.
|
||||
type: string
|
||||
message:
|
||||
description: The commit message.
|
||||
type: string
|
||||
timestamp:
|
||||
description: When the commit was created.
|
||||
type: integer
|
||||
format: int64
|
||||
x-dart-format: DateTime
|
||||
ref:
|
||||
description: The alias for the commit.
|
||||
type: string
|
||||
refspec:
|
||||
description: The mapping from the local repository to a branch in the remote.
|
||||
type: string
|
||||
remote:
|
||||
description: The remote repository.
|
||||
type: string
|
||||
author:
|
||||
description: The login for the author of the commit.
|
||||
type: string
|
||||
author_avatar:
|
||||
description: The avatar for the author of the commit.
|
||||
type: string
|
||||
author_email:
|
||||
description: The email for the author of the commit.
|
||||
type: string
|
||||
link_url:
|
||||
description: |
|
||||
The link to view the repository.
|
||||
|
||||
This link will point to the repository state associated with the
|
||||
build's commit.
|
||||
type: string
|
|
@ -19,7 +19,10 @@
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div class="flex items-center">
|
||||
<h2 class="text-lg text-color">{{ $t('user.api_usage') }}</h2>
|
||||
<a :href="`${address}/swagger/index.html`" target="_blank" class="ml-4 text-link">Swagger UI</a>
|
||||
</div>
|
||||
<pre class="cli-box">{{ usageWithCurl }}</pre>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Reference in a new issue