Building and Releasing Using the Platform API
Last updated April 03, 2023
Table of Contents
This article describes how to use the build
resource of the Platform API to build source code into slugs that can be run by apps on the Heroku platform.
The build resource complements the interactive git-based deployment flow but is optimized for non-interactive continuous integration setups. The outputs of using the Build resource are slugs and releases that can be downloaded, manipulated, reused, and moved around with the slug and release endpoints of the Platform API.
By combining the Build resource and the slug and release resources, developers can build flows where source code is pushed to a repository (not on Heroku), built into a slug by the Build resource and then deployed to one or more apps on the platform.
The Build resource is available on api.heroku.com
along with the rest of the Platform API.
Creating builds
Need a place to upload source tarballs for use with the Build API? See the sources endpoint section below.
Creating a build from a source tarball is simple:
$ curl -n -X POST https://api.heroku.com/apps/example-app/builds \
-d '{"source_blob":{"url":"https://github.com/heroku/node-js-sample/archive/master.tar.gz", "version": "cb6999d361a0244753cf89813207ad53ad906a14"}}' \
-H 'Accept: application/vnd.heroku+json; version=3' \
-H "Content-Type: application/json"
{
"created_at": "2014-04-23T02:47:04+00:00",
"id": "01234567-89ab-cdef-0123-456789abcdef",
"source_blob": {
"url": "https://github.com/heroku/node-js-sample/archive/cb6999d361a0244753cf89813207ad53ad906a14.tar.gz",
"version": "cb6999d361a0244753cf89813207ad53ad906a14"
},
"slug": {
"id": null
},
"status": "pending",
"updated_at": "2014-04-23T02:47:11+00:00",
"user": {
"email": "username@example.com",
"id": "01234567-89ab-cdef-0123-456789abcdef"
}
}
This will cause Heroku to fetch the source tarball, unpack it and start a build, just as if the source code had been pushed to Heroku using git. If the build completes successfully, the resulting slug will be deployed automatically to the app in a new release.
If for some reason you just want to create slugs that are not immediately released to a particular app, we currently recommend creating a separate app to handle builds and then use the generated slugs to create releases on the apps where you want slugs to run.
In the example above, we pass in an optional version
parameter. This is a piece of metadata that you use to track what version of your source originated this build. If you are creating builds from git-versioned source code, for example, the commit hash would be a good value to use for the version
parameter. The version parameter is not required and is not used when downloading and building the source code. It’s merely a piece of metadata used that you can optionally use to track what source code version went into building what slug.
Listing builds
You can list builds for a particular app:
$ curl -n https://api.heroku.com/apps/example-app/builds \
-H 'Accept: application/vnd.heroku+json; version=3'
[
{
"created_at": "2014-04-23T02:47:04+00:00",
"id": "01234567-89ab-cdef-0123-456789abcdef",
"source_blob": {
"url": "https://github.com/heroku/node-js-sample/archive/cb6999d361a0244753cf89813207ad53ad906a14.tar.gz",
"version": "cb6999d361a0244753cf89813207ad53ad906a14"
},
"slug": {
"id": "01234567-89ab-cdef-0123-456789abcdef"
},
"status": "succeeded",
"updated_at": "2014-04-23T02:47:11+00:00",
"user": {
"email": "username@example.com",
"id": "01234567-89ab-cdef-0123-456789abcdef"
}
},
...
]
The sample output above show one completed build. Note that the slug id is included in the output. You can use the slug id to create new releases on the same apps or on other apps on Heroku. You can also use the slug resource to download slugs to debug builds, for example.
All builds are available in the build list, including ones created by git-pushing to the Heroku repository for the app. Builds that fail for any reason are also tracked. To get the status of a build, check the status
property. Possible values are pending
, successful
and failed
.
Build output
You can also get the output of a particular build:
$ curl -n -X POST https://api.heroku.com/apps/example-app/builds \
-d '{"source_blob":{"url":"https://github.com/heroku/node-js-sample/archive/master.tar.gz", "version": "cb6999d361a0244753cf89813207ad53ad906a14"}}' \
-H 'Accept: application/vnd.heroku+json; version=3' \
-H "Content-Type: application/json"
{
"created_at": "2014-07-25T21:46:02+00:00",
"id": "4dff04cd-08ae-4a73-b4c1-12b84170a30f",
"output_stream_url": "https://build-output.heroku.com/streams/1b/1be0f203-4d00-4948-9c7f-769067c99843/logs/cc/cce90488-d545-4cc8-a5f2-de10f0802d5d.log",
"slug": {
"id": null
},
"source_blob": {
"url": "https://github.com/heroku/node-js-sample/archive/cb6999d361a0244753cf89813207ad53ad906a14.tar.gz",
"version": "cb6999d361a0244753cf89813207ad53ad906a14",
"version_description": null
},
"status": "pending",
"updated_at": "2014-07-25T21:46:02+00:00",
"user": {
"email": "username@example.com",
"id": "01234567-89ab-cdef-0123-456789abcdef"
}
}
Make a GET
request to the URL in output_stream_url
.
$ curl "https://build-output.heroku.com/streams/1b/1be0f203-4d00-4948-9c7f-769067c99843"
-----> Node.js app detected
-----> Requested node range: 0.10.x
...
The output_stream_url
url is also available if you GET
an existing build.
The build output is sent via chunked encoding and the connection is closed when the build completes. If a client connects after data is sent for a given build, the data is buffered from the start of the build. Output can be streamed while the build is on progress, and at any time after the build has completed (in the latter case, all output will be sent immediately).
A null character chunk may be sent as a heartbeat while receiving data. This is not build output. It is a signal the build is still running but has not output any data recently.
Sources endpoint
The Build API requires that input source tarball are available for download. As a convenience, we provide a sources endpoint that accepts tarball uploads and provides an expiring url to the uploaded tarball. Use the sources endpoint if you want to use the build API with source code that is not otherwise available for public download.
Create a Source
The first API call creates a PUT
and a GET
URL. Use the PUT
url to upload your source tar.gz
file and then pass the GET
URL to build API when creating the build. The URLs are only available for 1 hour, after which they both expire.
$ curl -n -X POST https://api.heroku.com/apps/example-app/sources \
-H 'Accept: application/vnd.heroku+json; version=3' \
{
"source_blob": {
"get_url":"https://s3-external-1.amazonaws.com/herokusources/...",
"put_url":"https://s3-external-1.amazonaws.com/herokusources/..."
}
}
Use the source_blob:put_url
to Upload Data
Next, upload the source tarball to the source_blob:put_url
you received
in the previous step with a HTTP PUT
:
$ curl "https://s3-external-1.amazonaws.com/herokusources/..." \
-X PUT -H 'Content-Type:' --data-binary @source.tgz
...
Note: when using curl
, it’s important to set -H 'Content-type:'
to avoid sending a Content-Type header.
Create a Build Using source_blob:get_url
Finally, use the source_blob:get_url
from the first API call to create a new build:
curl -n -X POST https://api.heroku.com/apps/example-app/builds \
-d '{"source_blob":{"url":"https://s3-external-1.amazonaws.com/herokusources/...", "version": "cb6999d361a0244753cf89813207ad53ad906a14"}}' \
-H 'Accept: application/vnd.heroku+json; version=3' \
-H "Content-Type: application/json"
{
"created_at": "2014-04-23T02:47:04+00:00",
"id": "01234567-89ab-cdef-0123-456789abcdef",
"source_blob": {
"url": "https://s3-external-1.amazonaws.com/herokusources/...",
"version": "cb6999d361a0244753cf89813207ad53ad906a14"
},
"slug": {
"id": null
},
"status": "pending",
"updated_at": "2014-04-23T02:47:11+00:00",
"user": {
"email": "username@example.com",
"id": "01234567-89ab-cdef-0123-456789abcdef"
}
}