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 |