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 |