Build server REST API¶
This is a proposed standard for a REST API for build clients to use to communicate with a build server. It’s inspired by pony-build, and generally rather Python-oriented, but the goal is language-agnostic.
Contents
API Usage¶
Registering a new project¶
-> PUT /{project}
{Project}
<- 201 Created
Location: /{project}/builds/{build-id}
If a project already exists, a 403 Forbidden will be returned.
Users may register with authentication via HTTP Basic:
-> PUT /{project}
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
{Project_}
<- 201 Created
Location: /{project}/builds/{build-id}
If this is done, then that authorization may be repeated in the future to update/delete the project or to delete builds. No explicit user registration step is needed; users will be created on the fly.
Warning
Since the authorization uses HTTP Basic, build servers should probably support SSL for the security-conscious.
Reporting a build¶
-> POST /{project}/builds
{Build}
<- 201 Created
Location: /{project}/builds/{build-id}
Incremental build reporting¶
-> POST /{project}/builds
{Incremental build}
<- 201 Created
Location: /{project}/builds/{build-id}/progress
-> POST /{project}/builds/{build-id}/progress
{Build step}
<- 204 No Content
Location: /{project}/builds/{build-id}
-> POST /{project}/builds/{build-id}/progress
{Build step}
<- 204 No Content
Location: /{project}/builds/{build-id}
...
-> DELETE /{project}/builds/{build-id}/progress
<- 204 No Content
Location: /{project}/builds/{build-id}
API Reference¶
Representation formats¶
- JSON.
- UTF-8.
- All datetimes in RFC 2822.
URIs¶
| URI | Resource | Methods | Notes |
|---|---|---|---|
/ |
Project list | GET | |
/{project} |
Project | GET, PUT,
DELETE |
Only the user that created a project may
update (PUT) or delete it. |
/{project}/builds |
Build list | GET, POST |
|
/{project}/builds/latest |
– | GET |
302 redirect to latest build. |
/{project}/builds/{build-id} |
Build | GET, PUT,
DELETE |
Builds may not be updated; PUT only
exists if clients wish for some reason
to use a predetermined build id. Only
the user that created a build or the
project owner may delete a build. |
/{project}/builds/{build-id}/progress |
Build progress | GET, POST,
DELETE |
|
/{project}/tags |
Tag list | GET |
|
/{project}/tags/{-listjoin|-|tags} |
Build list | GET |
|
/{project}/tags/{-listjoin|-|tags}/latest |
– | GET |
302 redirect to latest build given tags |
/users |
User list | GET |
|
/users/{username} |
User | GET, PUT,
DELETE |
Authentication required to PUT or
DELETE. |
/users/{username}/builds |
Build list | GET |
|
/users/{username}/builds/latest |
– | GET |
302 redirect to latest build by user |
All resources support OPTIONS which will return a list of allowed methods
in the Allow header. This is particularly useful to check authentication
for methods that require it.
Resources¶
Build¶
Representation:
{
'success': true, # did the build succeed?
'started': 'Tue, 20 Oct 2009 10:20:00 -0500',
'finished': 'Tue, 20 Oct 2009 10:22:00 -0500,
'tags': ['list', 'of', 'tags'],
'client': {
'host': 'example.com', # host that ran the build
'user': 'http://example.com/' # user to credit for build.
'arch': 'macosx-10.5-i386' # architecture the build was done on.
... [1]
},
'results': [{Build step}, ...],
'links': [{Link}, ...]
}
Notes:
| [1] | Clients may include arbitrary extra client info in the client record. |
Links:
| Rel | Links to |
|---|---|
self |
This build |
project |
The project this is a builds of. |
tag |
A tag this build is tagged with. There’ll probably be
many tag links. |
Build list¶
Representation:
{
'builds': [{Build}, ...],
'count': 100, # total number of builds available
'num_pages': 4, # total number of pages
'page': 1 # current page number
'paginated': true # is this list paginated?
'per_page': 25, # number of builds per page
'links': [{Link, ...}]
}
Links:
| Rel | Links to |
|---|---|
self |
This build list |
project |
The project this is a list of builds for (if applicable). |
user |
The user this is a list of builds for (if applicable). |
tag |
The tag this is a list of builds for (if applicable). |
latest-build |
URI for the redirect to this project’s latest build. |
next |
The next page of builds (if applicable). |
previous |
The previous page of builds (if applicable). |
first |
The first page of builds. |
last |
The last page of builds. |
Build progress¶
Used as an entry point for incremental build reporting
Empty representation – the existence of the resource indicates an in-progress build. When the build is done, the resource will return 410 Gone.
Build step¶
Representation:
{
'success': true, # did this step succeed?
'started': 'Tue, 20 Oct 2009 10:20:00 -0500',
'finished': 'Tue, 20 Oct 2009 10:22:00 -0500,
'name': 'checkout', # human-readable name for the step
'output': '...' # stdout for this step
'errout': '...' # stderr for this step
... [2]
}
Notes:
| [2] | Build steps may include arbitrary extra build info in the record. |
Incremental build¶
POST this resource to a build list to signal the start of an incremental build.
Representation
{
'incremental': true, # never false
'started': 'Tue, 20 Oct 2009 10:20:00 -0500', # when the build started on
# the client (not when the
# packet was posted!)
'client': {
'host': 'example.com', # host that ran the build
'user': 'username' # user to credit for build.
'arch': 'macosx-10.5-i386' # architecture the build was done on.
... [3]
},
'tags': ['list', 'of', 'tags'],
}
Notes:
| [3] | Clients may include arbitrary extra client info in the client record. |
Link¶
Used all over the damn place to knit resources together.
Representation:
{
'rel': 'self', # identifier for the type of link this is
'href': 'http://example.com/', # full URL href
'allowed_methods': ['GET'], # list of methods this client can perform on said resource
}
Project¶
Representation:
{
'name': 'Project Name',
'owner': 'username', # the user who created the project, if applicable.
'links': [{Link}, ...]
}
Links:
| Rel | Links to |
|---|---|
self |
This project. |
build-list |
This project’s build list. |
latest-build |
URI for the redirect to this project’s latest build. |
tag-list |
This project’s tag list. |
Project list¶
{
'projects': [{Project}, ...],
'links': [{Link}, ...]
}
Links:
| Rel | Links to |
|---|---|
self |
This server. |
Tag¶
Tag detail.
{
'tags': ['list', 'of', 'tags'], # Or just a single ['tag'] if this
# is one tag.
'builds': [{Build}, ...],
'count': 100, # total number of builds w/this tag
'num_pages': 4, # total number of pages
'page': 1 # current page number
'paginated': true # is this list paginated?
'per_page': 25, # number of builds per page
'links': [{Link, ...}]
}
Links:
Tag list¶
Representation:
{
'tags': ['tag1', 'tag2', 'tag3'],
'links': [{Link, ...}]
}
Links:
| Rel | Links to |
|---|---|
self |
This tag list |
project |
The project in question. |
tag |
Each tag used by the project gets a link. |
User¶
Representation:
{
'username': 'username',
'links': [{Link}, ...]
}
Links:
| Rel | Links to |
|---|---|
self |
This user |
builds |
Build list for this user. |
User list¶
Representation:
{
'users': [{User}, ...],
'count': 100, # total number of users available
'num_pages': 4, # total number of pages
'page': 1 # current page number
'paginated': true # is this list paginated?
'per_page': 25, # number of users per page
'links': [{Link, ...}]
}
Links:
| Rel | Links to |
|---|---|
self |
This user |