At Helpling we deploy the same code to several different Heroku applications. When using the traditional deploy system in Heroku, they take the code, download dependencies, generate assets and pack it all in what Heroku calls a Slug.
When you deploy the same code to several applications, this process is repeated for all of them resulting in an identical Slug in all cases. That always bothered us, because it seemed a bit inefficient.
Some months ago, David found this article Copying Slugs with the Platform API and we kept the link to it in out tech backlog.
Some weeks ago I managed to spend some time with it and we managed to reduce our deploy to production time from ~13minutes to <2 minutes.
I’m so happy about it that I have decided to inaugurate our Tech Blog with a small example.
Goal
- Deploy our code to a Staging with the traditional method
- Deploy the same code to production reusing the staging’s slug
Prerequisites
- Have the system configured to deploy on Heroku
- Have a HEROKU_API_KEY env var for a user with access to both Staging and Production
- Have jq accessible in your console
Step 1: Deploy to Staging
Run the standard commands to push your branch to the git remote from Heroku:
git remote add heroku-staging https://git.heroku.com/heroku-staging.git git push --force heroku-staging master
Step 2: Obtain the slug id
This command will call the Platform API to obtain the latest released slug_id on the heroku_staging
app:
SLUG_ID="$(curl -H "Authorization: Bearer $HEROKU_API_KEY" -H "Accept: application/vnd.heroku+json; version=3" -n https://api.heroku.com/apps/heroku-staging/releases | jq ".[-1].slug.id" -r)"
Extra: If you want to check the revision you can run this:
SLUG_DESCRIPTION="$(curl -H "Authorization: Bearer $HEROKU_API_KEY" -H "Accept: application/vnd.heroku+json; version=3" -n https://api.heroku.com/apps/heroku-staging/releases | jq ".[-1].description" -r
Step 3: Deploy to Production
Now it’s as easy as calling the Platform API to tell the heroku-production
app to use the slug in SLUG_ID
:
curl -H "Authorization: Bearer $HEROKU_API_KEY" -H "Accept: application/vnd.heroku+json; version=3" -H "Content-Type: application/json" -X POST -n -d "{\"slug\": \"${SLUG_ID}\"}" https://api.heroku.com/apps/heroku-production/releases