This post serves as my single source of truth deploying local changes to a Heroku app.
Local(production) to Github(production)
- Pull the latest changes from master
git pull origin master
- Switch to production branch. Update that shit
git checkout production
- Look over diffs for both master/production branches. It's more or less a sanity check
git diff production..master
. Take notes of features you're merging - Looks good? Merge changes from master to production on your production branch
git merge master
- Push the latest version production to Github
git push origin production
Github(production) to Heroku Staging
- Check Heroku for green status:
heroku status
- Push to production:master branch on staging, update the schema (if needed) and reboot the app
git push staging production:master && heroku run rake db:migrate -r staging && heroku restart -r staging
- Wait for the dyno slug to change
watch -n 5 bin/deploy_slug_information
(details below on this script) - Login to staging. Poke around features you just merged
- Check JS console for any interesting front end errors
- Check Honeybadger for server errors
Github(production) to Heroku Production
- Push to production:master branch on staging, update the schema (if needed) and reboot the app
git push production production:master && heroku run rake db:migrate -r production && heroku restart -r production
- Ensure latest SHA release is the same as production branch
heroku releases -r production | grep <production_SHA>
- Check HoneyBadger for errors from release
How to run watch -n 5 bin/deploy_slug_information
:
Setup an executable in your bin directory to watch ./bin/deploy_slug_information
#!/bin/bash
URL="https://my-app-name.com"
if [ "$1" == "staging" ]; then
URL="https://my-app-name-staging.com"
fi
URL+="/deploy_slug_information.json"
echo $URL
curl -s $URL
echo
Add middleware to your Rails app app/middleware/deploy_slug_information.rb
class DeploySlugInformationMiddleware
HEADER = "X-Slug-Commit".freeze
JSON_ENDPOINT = "/deploy_slug_information.json".freeze
def initialize(app)
@app = app
@partial_sha = (ENV["HEROKU_SLUG_COMMIT"].to_s[0, 4].presence || "unknown").freeze
end
def call(env)
if env["PATH_INFO"] == JSON_ENDPOINT
json_endpoint_reply(env)
else
header_injection_reply(env)
end
end
private
def header_injection_reply(env)
status, headers, response = @app.call(env)
headers[HEADER] = @partial_sha
[status, headers, response]
end
def json_endpoint_reply(env)
body = { slug_commit: @partial_sha }.to_json
headers = {
"Content-Length" => body.length.to_s,
"Content-Type" => "application/json",
}
[200, headers, [body]]
end
end
Tips
- Unix trick - use
fc
to edit and execute your most recently used shell command.
Top comments (0)