mirror of
https://github.com/harness/drone.git
synced 2025-05-19 10:29:55 +08:00
code to generate API documentation
This commit is contained in:
parent
25d6a8c4bc
commit
2b00d12bb6
14
Makefile
14
Makefile
@ -13,9 +13,19 @@ deps:
|
|||||||
go get -u github.com/elazarl/go-bindata-assetfs/...
|
go get -u github.com/elazarl/go-bindata-assetfs/...
|
||||||
go get -u github.com/dchest/jsmin
|
go get -u github.com/dchest/jsmin
|
||||||
go get -u github.com/franela/goblin
|
go get -u github.com/franela/goblin
|
||||||
|
go get -u github.com/go-swagger/go-swagger
|
||||||
|
|
||||||
gen:
|
gen: gen_static gen_template gen_migrations
|
||||||
go generate $(PACKAGES)
|
|
||||||
|
gen_static:
|
||||||
|
mkdir -p static/docs_gen/api
|
||||||
|
go generate github.com/drone/drone/static
|
||||||
|
|
||||||
|
gen_template:
|
||||||
|
go generate github.com/drone/drone/template
|
||||||
|
|
||||||
|
gen_migrations:
|
||||||
|
go generate github.com/drone/drone/shared/database
|
||||||
|
|
||||||
build:
|
build:
|
||||||
go build
|
go build
|
||||||
|
219
contrib/generate-api-docs.go
Normal file
219
contrib/generate-api-docs.go
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
// +build ignore
|
||||||
|
|
||||||
|
// This program generates api documentation from a
|
||||||
|
// swaggerfile using an amber template.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/eknkc/amber"
|
||||||
|
"github.com/go-swagger/go-swagger/spec"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
templ = flag.String("template", "index.amber", "")
|
||||||
|
input = flag.String("input", "swagger.json", "")
|
||||||
|
output = flag.String("output", "", "")
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
// parses the swagger spec file
|
||||||
|
spec, err := spec.YAMLSpec(*input)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
swag := spec.Spec()
|
||||||
|
|
||||||
|
// create output source for file. defaults to
|
||||||
|
// stdout but may be file.
|
||||||
|
var w io.WriteCloser = os.Stdout
|
||||||
|
if *output != "" {
|
||||||
|
w, err = os.Create(*output)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer w.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// we wrap the swagger file in a map, otherwise it
|
||||||
|
// won't work with our existing templates, which expect
|
||||||
|
// a map as the root parameter.
|
||||||
|
var data = map[string]interface{}{
|
||||||
|
"Swagger": normalize(swag),
|
||||||
|
}
|
||||||
|
|
||||||
|
t := amber.MustCompileFile(*templ, amber.DefaultOptions)
|
||||||
|
err = t.Execute(w, data)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swagger is a simplified representation of the swagger
|
||||||
|
// document with a subset of the fields used to generate
|
||||||
|
// our API documentation.
|
||||||
|
type Swagger struct {
|
||||||
|
Tags []Tag
|
||||||
|
}
|
||||||
|
|
||||||
|
type Tag struct {
|
||||||
|
Name string
|
||||||
|
Ops []Operation
|
||||||
|
}
|
||||||
|
|
||||||
|
type Operation struct {
|
||||||
|
ID string
|
||||||
|
Method string
|
||||||
|
Path string
|
||||||
|
Desc string
|
||||||
|
Summary string
|
||||||
|
|
||||||
|
Params []Param
|
||||||
|
Results []Result
|
||||||
|
}
|
||||||
|
|
||||||
|
type Param struct {
|
||||||
|
Name string
|
||||||
|
Desc string
|
||||||
|
Type string
|
||||||
|
Example interface{}
|
||||||
|
InputTo string
|
||||||
|
IsObject bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type Result struct {
|
||||||
|
Status int
|
||||||
|
Desc string
|
||||||
|
Example interface{}
|
||||||
|
IsObject bool
|
||||||
|
IsArray bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize is a helper function that normalizes the swagger
|
||||||
|
// file to a simpler format that makes it easier to work with
|
||||||
|
// inside the template.
|
||||||
|
func normalize(swag *spec.Swagger) Swagger {
|
||||||
|
swag_ := Swagger{}
|
||||||
|
|
||||||
|
for _, tag := range swag.Tags {
|
||||||
|
tag_ := Tag{Name: tag.Name}
|
||||||
|
|
||||||
|
// group the paths based on their tag value.
|
||||||
|
for route, path := range swag.Paths.Paths {
|
||||||
|
|
||||||
|
var ops = []*spec.Operation{
|
||||||
|
path.Get,
|
||||||
|
path.Put,
|
||||||
|
path.Post,
|
||||||
|
path.Patch,
|
||||||
|
path.Delete,
|
||||||
|
}
|
||||||
|
|
||||||
|
// flatten the operations into an array and convert
|
||||||
|
// the underlying data so that it is a bit easier to
|
||||||
|
// work with.
|
||||||
|
for _, op := range ops {
|
||||||
|
|
||||||
|
// the operation must have a tag to
|
||||||
|
// be rendered in our custom template.
|
||||||
|
if op == nil || !hasTag(tag.Name, op.Tags) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
item := Operation{}
|
||||||
|
item.Path = route
|
||||||
|
item.Method = getMethod(op, path)
|
||||||
|
item.Desc = op.Description
|
||||||
|
item.Summary = op.Summary
|
||||||
|
item.ID = fmt.Sprintf("%x", md5.Sum([]byte(item.Path+item.Method)))
|
||||||
|
|
||||||
|
// convert the operation input parameters into
|
||||||
|
// our internal format so that it is easier to
|
||||||
|
// work with in the template.
|
||||||
|
for _, param := range op.Parameters {
|
||||||
|
param_ := Param{}
|
||||||
|
param_.Name = param.Name
|
||||||
|
param_.Desc = param.Description
|
||||||
|
param_.Type = param.Type
|
||||||
|
param_.IsObject = param.Schema != nil
|
||||||
|
param_.InputTo = param.In
|
||||||
|
|
||||||
|
if param_.IsObject {
|
||||||
|
param_.Type = param.Schema.Ref.GetPointer().String()[13:]
|
||||||
|
param_.Example = param.Schema.Example
|
||||||
|
}
|
||||||
|
item.Params = append(item.Params, param_)
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert the operation response types into
|
||||||
|
// our internal format so that it is easier to
|
||||||
|
// work with in the template.
|
||||||
|
for code, resp := range op.Responses.StatusCodeResponses {
|
||||||
|
result := Result{}
|
||||||
|
result.Desc = resp.Description
|
||||||
|
result.Status = code
|
||||||
|
result.IsObject = resp.Schema != nil
|
||||||
|
if result.IsObject {
|
||||||
|
result.IsArray = resp.Schema.Items != nil
|
||||||
|
|
||||||
|
name := resp.Schema.Ref.GetPointer().String()
|
||||||
|
if len(name) != 0 {
|
||||||
|
def, _ := swag.Definitions[name[13:]]
|
||||||
|
result.Example = def.Example
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if result.IsArray {
|
||||||
|
name := resp.Schema.Items.Schema.Ref.GetPointer().String()
|
||||||
|
def, _ := swag.Definitions[name[13:]]
|
||||||
|
result.Example = def.Example
|
||||||
|
}
|
||||||
|
item.Results = append(item.Results, result)
|
||||||
|
}
|
||||||
|
tag_.Ops = append(tag_.Ops, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
swag_.Tags = append(swag_.Tags, tag_)
|
||||||
|
}
|
||||||
|
|
||||||
|
return swag_
|
||||||
|
}
|
||||||
|
|
||||||
|
// hasTag is a helper function that returns true if
|
||||||
|
// an operation has the specified tag label.
|
||||||
|
func hasTag(want string, in []string) bool {
|
||||||
|
for _, got := range in {
|
||||||
|
if got == want {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// getMethod is a helper function that returns the http
|
||||||
|
// method for the specified operation in a path.
|
||||||
|
func getMethod(op *spec.Operation, path spec.PathItem) string {
|
||||||
|
switch {
|
||||||
|
case op == path.Get:
|
||||||
|
return "GET"
|
||||||
|
case op == path.Put:
|
||||||
|
return "PUT"
|
||||||
|
case op == path.Patch:
|
||||||
|
return "PATCH"
|
||||||
|
case op == path.Post:
|
||||||
|
return "POST"
|
||||||
|
case op == path.Delete:
|
||||||
|
return "DELETE"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
499
docs/api.raml
499
docs/api.raml
@ -1,499 +0,0 @@
|
|||||||
#%RAML 0.8
|
|
||||||
|
|
||||||
title: Drone API
|
|
||||||
baseUri: http://localhost:8080/api
|
|
||||||
traits:
|
|
||||||
- authenticate:
|
|
||||||
description: Some requests require authentication.
|
|
||||||
queryParameters:
|
|
||||||
access_token:
|
|
||||||
description: Access Token
|
|
||||||
type: string
|
|
||||||
example: ACCESS_TOKEN
|
|
||||||
- authorize:
|
|
||||||
responses:
|
|
||||||
401:
|
|
||||||
description: |
|
|
||||||
Access Denied. User must be authenticated.
|
|
||||||
403:
|
|
||||||
description: |
|
|
||||||
Access Forbidden. User must be a system administrator.
|
|
||||||
|
|
||||||
/repos/{owner}/{name}:
|
|
||||||
is: [ authorize, authenticate ]
|
|
||||||
uriParameters:
|
|
||||||
owner:
|
|
||||||
displayName: Owner
|
|
||||||
description: Owner of the repository
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
name:
|
|
||||||
displayName: Name
|
|
||||||
description: Name of the repository
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
|
|
||||||
get:
|
|
||||||
displayName: Find Repository
|
|
||||||
description: |
|
|
||||||
Retrieve a Repository by Name
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
body:
|
|
||||||
application/json:
|
|
||||||
example: !include samples/repo.json
|
|
||||||
404:
|
|
||||||
description: |
|
|
||||||
Unable to find the Repository in the database
|
|
||||||
|
|
||||||
patch:
|
|
||||||
displayName: Update Repository
|
|
||||||
description: |
|
|
||||||
Update a Repository
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
body:
|
|
||||||
application/json:
|
|
||||||
example: !include samples/repo.json
|
|
||||||
400:
|
|
||||||
description: |
|
|
||||||
Unable to update the Repository record in the database
|
|
||||||
404:
|
|
||||||
description: |
|
|
||||||
Unable to find the Repository in the database
|
|
||||||
|
|
||||||
post:
|
|
||||||
displayName: Activate Repository
|
|
||||||
description: |
|
|
||||||
Activate a Repository
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
body:
|
|
||||||
application/json:
|
|
||||||
example: !include samples/repo.json
|
|
||||||
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:
|
|
||||||
displayName: Delete Repository
|
|
||||||
description: |
|
|
||||||
Deletes a Repository
|
|
||||||
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
|
|
||||||
|
|
||||||
/watch:
|
|
||||||
is: [ authorize, authenticate ]
|
|
||||||
description: |
|
|
||||||
Watch the Repository
|
|
||||||
post:
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: |
|
|
||||||
Successfully Watching this Repository
|
|
||||||
400:
|
|
||||||
description: |
|
|
||||||
Unable to insert the Starred record in the database
|
|
||||||
404:
|
|
||||||
description: |
|
|
||||||
Unable to find the Repository in the database
|
|
||||||
|
|
||||||
/unwatch:
|
|
||||||
is: [ authorize, authenticate ]
|
|
||||||
description: |
|
|
||||||
Unwatch the Repository
|
|
||||||
delete:
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: |
|
|
||||||
Successfully Unwatched this Repository
|
|
||||||
400:
|
|
||||||
description: |
|
|
||||||
Unable to delete the Starred record in the database
|
|
||||||
404:
|
|
||||||
description: |
|
|
||||||
Unable to find the Repository in the database
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Builds
|
|
||||||
#
|
|
||||||
|
|
||||||
/repos/{owner}/{name}/builds:
|
|
||||||
displayName: Builds
|
|
||||||
is: [ authorize, authenticate ]
|
|
||||||
uriParameters:
|
|
||||||
owner:
|
|
||||||
displayName: Owner
|
|
||||||
description: Owner of the repository
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
name:
|
|
||||||
displayName: Name
|
|
||||||
description: Name of the repository
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
|
|
||||||
get:
|
|
||||||
displayName: List Builds
|
|
||||||
description: |
|
|
||||||
Retrieve the list of recent Builds for the Repository
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
body:
|
|
||||||
application/json:
|
|
||||||
example: !include samples/builds.json
|
|
||||||
404:
|
|
||||||
description: |
|
|
||||||
Unable to find the Repository in the database
|
|
||||||
|
|
||||||
/{number}:
|
|
||||||
is: [ authorize, authenticate ]
|
|
||||||
uriParameters:
|
|
||||||
number:
|
|
||||||
displayName: Number
|
|
||||||
type: integer
|
|
||||||
|
|
||||||
get:
|
|
||||||
displayName: Find Build
|
|
||||||
description: |
|
|
||||||
Retrieve a specific Build by Number
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
body:
|
|
||||||
application/json:
|
|
||||||
example: !include samples/build.json
|
|
||||||
404:
|
|
||||||
description: |
|
|
||||||
Unable to find the Build in the database
|
|
||||||
|
|
||||||
delete:
|
|
||||||
displayName: Cancel Build
|
|
||||||
description: |
|
|
||||||
Cancel an running Build by Number
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: |
|
|
||||||
Successfully cancelled the Build
|
|
||||||
404:
|
|
||||||
description: |
|
|
||||||
Cannot find Build by Number
|
|
||||||
409:
|
|
||||||
description: |
|
|
||||||
Cannot cancel a Build that is already stopped
|
|
||||||
|
|
||||||
post:
|
|
||||||
displayName: Restart Build
|
|
||||||
description: |
|
|
||||||
Restart a completed Build
|
|
||||||
responses:
|
|
||||||
202:
|
|
||||||
description: |
|
|
||||||
Successfully restarted the Build
|
|
||||||
404:
|
|
||||||
description: |
|
|
||||||
Cannot find Build by Number
|
|
||||||
409:
|
|
||||||
description: |
|
|
||||||
Cannot re-start a Build that is running
|
|
||||||
|
|
||||||
#
|
|
||||||
# Build Logs
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
/repos/{owner}/{name}/logs/{number}/{job}:
|
|
||||||
displayName: Builds
|
|
||||||
is: [ authorize, authenticate ]
|
|
||||||
uriParameters:
|
|
||||||
owner:
|
|
||||||
displayName: Owner
|
|
||||||
description: Owner of the repository
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
name:
|
|
||||||
displayName: Name
|
|
||||||
description: Name of the repository
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
number:
|
|
||||||
displayName: Build Number
|
|
||||||
description: Incremental Build Number
|
|
||||||
type: integer
|
|
||||||
required: true
|
|
||||||
job:
|
|
||||||
displayName: Job Number
|
|
||||||
description: Sequential Job Number
|
|
||||||
type: integer
|
|
||||||
required: true
|
|
||||||
|
|
||||||
get:
|
|
||||||
displayName: Find Build Logs
|
|
||||||
description: |
|
|
||||||
Retrieve the Logs for a specific Build Job
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
body:
|
|
||||||
text/plain:
|
|
||||||
404:
|
|
||||||
description: |
|
|
||||||
Cannot find Build Logs
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# User Endpoint
|
|
||||||
#
|
|
||||||
|
|
||||||
/user:
|
|
||||||
is: [ authorize, authenticate ]
|
|
||||||
displayName: User
|
|
||||||
|
|
||||||
get:
|
|
||||||
description: |
|
|
||||||
Retrieve the currently authenticated User
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
body:
|
|
||||||
application/json:
|
|
||||||
example: !include samples/user.json
|
|
||||||
|
|
||||||
patch:
|
|
||||||
description: |
|
|
||||||
Update the currently authenticated User
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: |
|
|
||||||
Updated User
|
|
||||||
body:
|
|
||||||
application/json:
|
|
||||||
example: !include samples/user.json
|
|
||||||
400:
|
|
||||||
description: |
|
|
||||||
Bad Request. Error updating User
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# User Repos
|
|
||||||
#
|
|
||||||
|
|
||||||
/user/repos:
|
|
||||||
is: [ authorize, authenticate ]
|
|
||||||
displayName: User Repos
|
|
||||||
|
|
||||||
get:
|
|
||||||
description: |
|
|
||||||
Retrieve the currently authenticated User's Repository list
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
body:
|
|
||||||
application/json:
|
|
||||||
example: !include samples/repos.json
|
|
||||||
400:
|
|
||||||
description: |
|
|
||||||
Bad Request. Error retrieving Repository list
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# User Tokens
|
|
||||||
#
|
|
||||||
|
|
||||||
/user/tokens:
|
|
||||||
is: [ authorize, authenticate ]
|
|
||||||
displayName: User Tokens
|
|
||||||
|
|
||||||
get:
|
|
||||||
description: |
|
|
||||||
Retrieve the currently authenticated User's active Token list
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
body:
|
|
||||||
application/json:
|
|
||||||
example: !include samples/tokens.json
|
|
||||||
400:
|
|
||||||
description: |
|
|
||||||
Error retrieving the Token list
|
|
||||||
|
|
||||||
post:
|
|
||||||
description: |
|
|
||||||
Generate a new User Token
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
body:
|
|
||||||
application/json:
|
|
||||||
example: !include samples/token.json
|
|
||||||
400:
|
|
||||||
description: |
|
|
||||||
Error when attempting to generate the JWT token
|
|
||||||
500:
|
|
||||||
description: |
|
|
||||||
Error when attempting to save the Token
|
|
||||||
|
|
||||||
/{label}:
|
|
||||||
is: [ authorize, authenticate ]
|
|
||||||
delete:
|
|
||||||
description: |
|
|
||||||
Delete a specific User Token by Label
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: |
|
|
||||||
Successfully deleted the Token
|
|
||||||
400:
|
|
||||||
description: |
|
|
||||||
Error attempting to delete Token from database
|
|
||||||
404:
|
|
||||||
description: |
|
|
||||||
Unable to find Token in database
|
|
||||||
|
|
||||||
#
|
|
||||||
# Users Endpoint
|
|
||||||
#
|
|
||||||
|
|
||||||
/users:
|
|
||||||
is: [ authorize, authenticate ]
|
|
||||||
displayName: Users
|
|
||||||
|
|
||||||
get:
|
|
||||||
description: Retrieve a list of all registered Users.
|
|
||||||
displayName: List Users
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
body:
|
|
||||||
application/json:
|
|
||||||
example: !include samples/users.json
|
|
||||||
|
|
||||||
/{login}:
|
|
||||||
is: [ authorize, authenticate ]
|
|
||||||
uriParameters:
|
|
||||||
login:
|
|
||||||
displayName: Login
|
|
||||||
description: Username in remote system
|
|
||||||
example: Octocat
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
|
|
||||||
get:
|
|
||||||
displayName: Find User
|
|
||||||
description: |
|
|
||||||
Retrieve a specific User by Login name
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
body:
|
|
||||||
application/json:
|
|
||||||
schema: !include schemas/user.json
|
|
||||||
404:
|
|
||||||
description: |
|
|
||||||
Cannot find the User
|
|
||||||
|
|
||||||
post:
|
|
||||||
displayName: Enable User
|
|
||||||
description: |
|
|
||||||
Enable a new User by Login name
|
|
||||||
responses:
|
|
||||||
201:
|
|
||||||
body:
|
|
||||||
application/json:
|
|
||||||
schema: !include schemas/user.json
|
|
||||||
400:
|
|
||||||
description: |
|
|
||||||
Error inserting User into the database
|
|
||||||
|
|
||||||
patch:
|
|
||||||
displayName: Update User
|
|
||||||
description: |
|
|
||||||
Update a specific User
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
body:
|
|
||||||
application/json:
|
|
||||||
schema: !include schemas/user.json
|
|
||||||
400:
|
|
||||||
description: |
|
|
||||||
Error updating User record in the database
|
|
||||||
|
|
||||||
delete:
|
|
||||||
displayName: Delete User
|
|
||||||
description: |
|
|
||||||
Delete a specific User
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Badge Endpoint
|
|
||||||
#
|
|
||||||
|
|
||||||
/badges/{owner}/{name}:
|
|
||||||
displayName: Badges
|
|
||||||
uriParameters:
|
|
||||||
owner:
|
|
||||||
displayName: Owner
|
|
||||||
description: Owner of the repository
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
name:
|
|
||||||
displayName: Name
|
|
||||||
description: Name of the repository
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
|
|
||||||
/status.svg:
|
|
||||||
description: Returns an SVG status badge for the latest Build
|
|
||||||
displayName: Status Badge
|
|
||||||
get:
|
|
||||||
queryParameters:
|
|
||||||
branch:
|
|
||||||
default: master
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
example: master
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
body:
|
|
||||||
image/svg+xml:
|
|
||||||
|
|
||||||
/cc.xml:
|
|
||||||
description: Returns a CCMenu feed for the Repository
|
|
||||||
displayName: CCMenu
|
|
||||||
get:
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
body:
|
|
||||||
application/xml:
|
|
||||||
example: !include samples/ccmenu.xml
|
|
202
static/styles/pages/docs.sass
Normal file
202
static/styles/pages/docs.sass
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
.toc
|
||||||
|
list-style-type: none;
|
||||||
|
padding:0px;
|
||||||
|
margin:0px;
|
||||||
|
padding-bottom:40px;
|
||||||
|
|
||||||
|
h2
|
||||||
|
font-size:21px;
|
||||||
|
font-weight:normal;
|
||||||
|
margin-bottom:20px;
|
||||||
|
color:#2b303b;
|
||||||
|
|
||||||
|
ul
|
||||||
|
list-style-type: none;
|
||||||
|
padding:0px;
|
||||||
|
margin:0px;
|
||||||
|
margin-bottom:40px;
|
||||||
|
border-bottom: 1px solid #EEE;
|
||||||
|
padding-bottom:40px;
|
||||||
|
li
|
||||||
|
line-height:25px;
|
||||||
|
a
|
||||||
|
color: #2b303b;
|
||||||
|
text-decoration:none;
|
||||||
|
a:hover
|
||||||
|
text-decoration:underline;
|
||||||
|
|
||||||
|
[data-method]:before
|
||||||
|
content: attr(data-method);
|
||||||
|
padding:0px 10px;
|
||||||
|
line-height:18px;
|
||||||
|
min-width:70px;
|
||||||
|
font-size:11px;
|
||||||
|
text-transform:uppercase;
|
||||||
|
display: inline-block;
|
||||||
|
text-align:center;
|
||||||
|
color:#FFF;
|
||||||
|
border-radius:2px;
|
||||||
|
margin-right:20px;
|
||||||
|
|
||||||
|
[data-method="GET"]:before
|
||||||
|
background-color:#1ABC9C;
|
||||||
|
[data-method="PUT"]:before
|
||||||
|
background-color:#9B59B6;
|
||||||
|
[data-method="POST"]:before
|
||||||
|
background-color:#3498DB;
|
||||||
|
[data-method="PATCH"]:before
|
||||||
|
background-color:#E67E22;
|
||||||
|
[data-method="DELETE"]:before
|
||||||
|
background-color:#E74C3C;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[data-method]:before
|
||||||
|
background:#FFF;
|
||||||
|
border:1px solid #FFF;
|
||||||
|
[data-method="GET"]:before
|
||||||
|
color:#1ABC9C;
|
||||||
|
border-color:#1ABC9C;
|
||||||
|
[data-method="PUT"]:before
|
||||||
|
color:#9B59B6;
|
||||||
|
border-color:#9B59B6;
|
||||||
|
[data-method="POST"]:before
|
||||||
|
color:#3498DB;
|
||||||
|
border-color:#3498DB;
|
||||||
|
[data-method="PATCH"]:before
|
||||||
|
color:#E67E22;
|
||||||
|
border-color:#E67E22;
|
||||||
|
[data-method="DELETE"]:before
|
||||||
|
color:#E74C3C;
|
||||||
|
border-color:#E74C3C;
|
||||||
|
|
||||||
|
.operation
|
||||||
|
|
||||||
|
[data-method]:before
|
||||||
|
content: attr(data-method);
|
||||||
|
padding:0px 10px;
|
||||||
|
line-height:18px;
|
||||||
|
min-width:70px;
|
||||||
|
font-size:11px;
|
||||||
|
text-transform:uppercase;
|
||||||
|
display: inline-block;
|
||||||
|
text-align:center;
|
||||||
|
color:#FFF;
|
||||||
|
border-radius:2px;
|
||||||
|
margin-right:20px;
|
||||||
|
background:#FFF;
|
||||||
|
border:1px solid #FFF;
|
||||||
|
line-height: 20px;
|
||||||
|
vertical-align: top;
|
||||||
|
|
||||||
|
|
||||||
|
[data-method]:before
|
||||||
|
background:#FFF;
|
||||||
|
border:1px solid #FFF;
|
||||||
|
[data-method="GET"]:before
|
||||||
|
color:#1ABC9C;
|
||||||
|
border-color:#1ABC9C;
|
||||||
|
[data-method="PUT"]:before
|
||||||
|
color:#9B59B6;
|
||||||
|
border-color:#9B59B6;
|
||||||
|
[data-method="POST"]:before
|
||||||
|
color:#3498DB;
|
||||||
|
border-color:#3498DB;
|
||||||
|
[data-method="PATCH"]:before
|
||||||
|
color:#E67E22;
|
||||||
|
border-color:#E67E22;
|
||||||
|
[data-method="DELETE"]:before
|
||||||
|
color:#E74C3C;
|
||||||
|
border-color:#E74C3C;
|
||||||
|
|
||||||
|
.docs
|
||||||
|
margin-top:40px;
|
||||||
|
padding: 0px 50px;
|
||||||
|
padding-right:40px;
|
||||||
|
pre
|
||||||
|
margin-right: 15px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #eff1f5;
|
||||||
|
color: #2b303b;
|
||||||
|
border-radius: 2px;
|
||||||
|
background: #2b303b;
|
||||||
|
background: #ECF0F1;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 25px 30px;
|
||||||
|
font-family: "Roboto Mono";
|
||||||
|
|
||||||
|
|
||||||
|
.operation
|
||||||
|
min-height:100vh;
|
||||||
|
padding:20px 0px;
|
||||||
|
display: flex
|
||||||
|
&> aside,
|
||||||
|
&> div
|
||||||
|
min-width:50%;
|
||||||
|
max-width:50%;
|
||||||
|
width:50%;
|
||||||
|
padding-right:40px;
|
||||||
|
h2
|
||||||
|
color:#2b303b;
|
||||||
|
font-size:21px;
|
||||||
|
h3
|
||||||
|
font-size:16px;
|
||||||
|
margin-bottom:20px;
|
||||||
|
margin-top:40px;
|
||||||
|
aside
|
||||||
|
background: rgba(43, 48, 59, 0.95);
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20px 0px 10px 0px;
|
||||||
|
border-radius:2px;
|
||||||
|
h4
|
||||||
|
color: #d0d4d7;
|
||||||
|
font-size:15px;
|
||||||
|
padding:20px;
|
||||||
|
padding-left:40px;
|
||||||
|
pre
|
||||||
|
background: #2b303b;
|
||||||
|
color: #d0d4d7;
|
||||||
|
margin-right:0px;
|
||||||
|
padding-left:40px;
|
||||||
|
|
||||||
|
.params
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
list-style-type: none;
|
||||||
|
border-top: 1px solid #f0f4f7
|
||||||
|
li
|
||||||
|
padding:15px 10px;
|
||||||
|
border-bottom:1px solid #f0f4f7;
|
||||||
|
font-size:15px
|
||||||
|
p
|
||||||
|
line-height:20px;
|
||||||
|
margin: 0 0 0 170px;
|
||||||
|
|
||||||
|
li:after
|
||||||
|
visibility: hidden;
|
||||||
|
display: block;
|
||||||
|
font-size: 0;
|
||||||
|
content: " ";
|
||||||
|
clear: both;
|
||||||
|
height: 0;
|
||||||
|
|
||||||
|
h4
|
||||||
|
float:left;
|
||||||
|
line-height:20px;
|
||||||
|
text-align:right;
|
||||||
|
padding-right:20px;
|
||||||
|
width:150px;
|
||||||
|
font-weight:bold;
|
||||||
|
font-size:15px;
|
||||||
|
|
||||||
|
small
|
||||||
|
display:block;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color:#E67E22;
|
||||||
|
font-size:11px;
|
||||||
|
font-weight:normal;
|
||||||
|
margin-top:5px;
|
||||||
|
|
@ -15,6 +15,7 @@
|
|||||||
@import pages/repo.sass
|
@import pages/repo.sass
|
||||||
@import pages/login.sass
|
@import pages/login.sass
|
||||||
@import pages/feed.sass
|
@import pages/feed.sass
|
||||||
|
@import pages/docs.sass
|
||||||
|
|
||||||
@import header
|
@import header
|
||||||
@import search
|
@import search
|
||||||
|
@ -289,6 +289,86 @@ body.login div.alert { position: fixed; top: 0px; left: 0px; right: 0px; line-he
|
|||||||
|
|
||||||
.repo-row .card-header { background: #FFF; border-bottom: none; padding-right: 0px; padding-left: 0px; width: 45px; }
|
.repo-row .card-header { background: #FFF; border-bottom: none; padding-right: 0px; padding-left: 0px; width: 45px; }
|
||||||
|
|
||||||
|
.toc { list-style-type: none; padding: 0px; margin: 0px; padding-bottom: 40px; }
|
||||||
|
|
||||||
|
.toc h2 { font-size: 21px; font-weight: normal; margin-bottom: 20px; color: #2b303b; }
|
||||||
|
|
||||||
|
.toc ul { list-style-type: none; padding: 0px; margin: 0px; margin-bottom: 40px; border-bottom: 1px solid #EEE; padding-bottom: 40px; }
|
||||||
|
|
||||||
|
.toc ul li { line-height: 25px; }
|
||||||
|
|
||||||
|
.toc ul li a { color: #2b303b; text-decoration: none; }
|
||||||
|
|
||||||
|
.toc ul li a:hover { text-decoration: underline; }
|
||||||
|
|
||||||
|
.toc [data-method]:before { content: attr(data-method); padding: 0px 10px; line-height: 18px; min-width: 70px; font-size: 11px; text-transform: uppercase; display: inline-block; text-align: center; color: #FFF; border-radius: 2px; margin-right: 20px; }
|
||||||
|
|
||||||
|
.toc [data-method="GET"]:before { background-color: #1ABC9C; }
|
||||||
|
|
||||||
|
.toc [data-method="PUT"]:before { background-color: #9B59B6; }
|
||||||
|
|
||||||
|
.toc [data-method="POST"]:before { background-color: #3498DB; }
|
||||||
|
|
||||||
|
.toc [data-method="PATCH"]:before { background-color: #E67E22; }
|
||||||
|
|
||||||
|
.toc [data-method="DELETE"]:before { background-color: #E74C3C; }
|
||||||
|
|
||||||
|
.toc [data-method]:before { background: #FFF; border: 1px solid #FFF; }
|
||||||
|
|
||||||
|
.toc [data-method="GET"]:before { color: #1ABC9C; border-color: #1ABC9C; }
|
||||||
|
|
||||||
|
.toc [data-method="PUT"]:before { color: #9B59B6; border-color: #9B59B6; }
|
||||||
|
|
||||||
|
.toc [data-method="POST"]:before { color: #3498DB; border-color: #3498DB; }
|
||||||
|
|
||||||
|
.toc [data-method="PATCH"]:before { color: #E67E22; border-color: #E67E22; }
|
||||||
|
|
||||||
|
.toc [data-method="DELETE"]:before { color: #E74C3C; border-color: #E74C3C; }
|
||||||
|
|
||||||
|
.operation [data-method]:before { content: attr(data-method); padding: 0px 10px; line-height: 18px; min-width: 70px; font-size: 11px; text-transform: uppercase; display: inline-block; text-align: center; color: #FFF; border-radius: 2px; margin-right: 20px; background: #FFF; border: 1px solid #FFF; line-height: 20px; vertical-align: top; }
|
||||||
|
|
||||||
|
.operation [data-method]:before { background: #FFF; border: 1px solid #FFF; }
|
||||||
|
|
||||||
|
.operation [data-method="GET"]:before { color: #1ABC9C; border-color: #1ABC9C; }
|
||||||
|
|
||||||
|
.operation [data-method="PUT"]:before { color: #9B59B6; border-color: #9B59B6; }
|
||||||
|
|
||||||
|
.operation [data-method="POST"]:before { color: #3498DB; border-color: #3498DB; }
|
||||||
|
|
||||||
|
.operation [data-method="PATCH"]:before { color: #E67E22; border-color: #E67E22; }
|
||||||
|
|
||||||
|
.operation [data-method="DELETE"]:before { color: #E74C3C; border-color: #E74C3C; }
|
||||||
|
|
||||||
|
.docs { margin-top: 40px; padding: 0px 50px; padding-right: 40px; }
|
||||||
|
|
||||||
|
.docs pre { margin-right: 15px; font-size: 14px; color: #eff1f5; color: #2b303b; border-radius: 2px; background: #2b303b; background: #ECF0F1; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; padding: 25px 30px; font-family: "Roboto Mono"; }
|
||||||
|
|
||||||
|
.operation { min-height: 100vh; padding: 20px 0px; display: flex; }
|
||||||
|
|
||||||
|
.operation > aside, .operation > div { min-width: 50%; max-width: 50%; width: 50%; padding-right: 40px; }
|
||||||
|
|
||||||
|
.operation h2 { color: #2b303b; font-size: 21px; }
|
||||||
|
|
||||||
|
.operation h3 { font-size: 16px; margin-bottom: 20px; margin-top: 40px; }
|
||||||
|
|
||||||
|
.operation aside { background: rgba(43, 48, 59, 0.95); box-sizing: border-box; padding: 20px 0px 10px 0px; border-radius: 2px; }
|
||||||
|
|
||||||
|
.operation aside h4 { color: #d0d4d7; font-size: 15px; padding: 20px; padding-left: 40px; }
|
||||||
|
|
||||||
|
.operation aside pre { background: #2b303b; color: #d0d4d7; margin-right: 0px; padding-left: 40px; }
|
||||||
|
|
||||||
|
.operation .params { padding: 0px; margin: 0px; list-style-type: none; border-top: 1px solid #f0f4f7; }
|
||||||
|
|
||||||
|
.operation .params li { padding: 15px 10px; border-bottom: 1px solid #f0f4f7; font-size: 15px; }
|
||||||
|
|
||||||
|
.operation .params li p { line-height: 20px; margin: 0 0 0 170px; }
|
||||||
|
|
||||||
|
.operation .params li:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; }
|
||||||
|
|
||||||
|
.operation .params h4 { float: left; line-height: 20px; text-align: right; padding-right: 20px; width: 150px; font-weight: bold; font-size: 15px; }
|
||||||
|
|
||||||
|
.operation .params small { display: block; text-transform: uppercase; color: #E67E22; font-size: 11px; font-weight: normal; margin-top: 5px; }
|
||||||
|
|
||||||
.tt-open { position: absolute; top: 34px; left: 0px; z-index: 100; display: none; background: #FFF; min-width: 100%; border: 1px solid #eee; border-radius: 0px; }
|
.tt-open { position: absolute; top: 34px; left: 0px; z-index: 100; display: none; background: #FFF; min-width: 100%; border: 1px solid #eee; border-radius: 0px; }
|
||||||
|
|
||||||
.tt-selectable:hover, .tt-cursor { background: #f4f4f4; }
|
.tt-selectable:hover, .tt-cursor { background: #f4f4f4; }
|
||||||
|
65
template/amber/swagger.amber
Normal file
65
template/amber/swagger.amber
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
extends base
|
||||||
|
|
||||||
|
block append head
|
||||||
|
title API · Drone
|
||||||
|
|
||||||
|
block header
|
||||||
|
ol
|
||||||
|
li Documentation
|
||||||
|
ul.nav.nav-tabs
|
||||||
|
li.nav-item
|
||||||
|
a.nav-link[href="#"] Install
|
||||||
|
li.nav-item
|
||||||
|
a.nav-link[href="#"] Builds
|
||||||
|
li.nav-item
|
||||||
|
a.nav-link[href="#"] Plugins
|
||||||
|
li.nav-item
|
||||||
|
a.nav-link.active[href="#"] API Reference
|
||||||
|
|
||||||
|
block content
|
||||||
|
div.container-fluid.docs.docs-api
|
||||||
|
a[name="top"]
|
||||||
|
div.row
|
||||||
|
ul.toc
|
||||||
|
each $tag in Swagger.Tags
|
||||||
|
li
|
||||||
|
h2 #{$tag.Name}
|
||||||
|
ul
|
||||||
|
each $op in $tag.Ops
|
||||||
|
li
|
||||||
|
a[href="#"+$op.ID][data-method=$op.Method] #{$op.Path}
|
||||||
|
div.row
|
||||||
|
each $tag in Swagger.Tags
|
||||||
|
each $op in $tag.Ops
|
||||||
|
a[name=$op.ID]
|
||||||
|
div.operation
|
||||||
|
div
|
||||||
|
h2[data-method=$op.Method] #{$op.Summary}
|
||||||
|
p #{$op.Desc}
|
||||||
|
|
||||||
|
h3 Request Parameters
|
||||||
|
ul.params
|
||||||
|
each $param in $op.Params
|
||||||
|
li
|
||||||
|
h4
|
||||||
|
| #{$param.Name}
|
||||||
|
small Required
|
||||||
|
p #{$param.Desc}
|
||||||
|
|
||||||
|
h3 Response Messages
|
||||||
|
ul.params
|
||||||
|
each $result in $op.Results
|
||||||
|
li
|
||||||
|
h4
|
||||||
|
| #{$result.Status}
|
||||||
|
p #{$result.Desc}
|
||||||
|
aside
|
||||||
|
h4 Endpoint
|
||||||
|
pre #{$op.Method} #{$op.Path}
|
||||||
|
each $res in $op.Results
|
||||||
|
if $res.Example
|
||||||
|
h4 Example Response
|
||||||
|
if $res.IsArray
|
||||||
|
pre [#{$res.Example}]
|
||||||
|
else if $res.IsObject
|
||||||
|
pre #{$res.Example}
|
Loading…
Reference in New Issue
Block a user