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.

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.

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