This article goes over how to deploy to Heroku using the GitHub Actions workflow.
Prerequisites
Heroku
Create a Heroku app and save the app’s name and email associated with your account. Then go to Account settings and copy your API Key
.
GitHub
Go to your GitHub repository’s Settings
> Secrets
and set the secrets:
HEROKU_API_KEY
HEROKU_APP_NAME
HEROKU_EMAIL
GitHub Action
Workflow to deploy using Deploy to Heroku action:
# .github/workflows/heroku-deploy.yml
jobs:
heroku-deploy:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3
- name: Deploy to Heroku
uses: akhileshns/heroku-deploy@v3.12.12
with:
heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
heroku_app_name: ${{ secrets.HEROKU_APP_NAME }}
heroku_email: ${{ secrets.HEROKU_EMAIL }}
The action pushes to the main
branch.
Check out the additional options.
Custom Workflow
Workflow to deploy using a custom job:
# .github/workflows/custom-deploy.yml
jobs:
custom-deploy:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Heroku login credentials
run: |
cat > ~/.netrc <<EOF
machine api.heroku.com
login $HEROKU_EMAIL
password $HEROKU_API_KEY
machine git.heroku.com
login $HEROKU_EMAIL
password $HEROKU_API_KEY
EOF
env:
HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }}
HEROKU_EMAIL: ${{ secrets.HEROKU_EMAIL }}
- name: Add Heroku remote
run: heroku git:remote --app $HEROKU_APP_NAME
env:
HEROKU_APP_NAME: ${{ secrets.HEROKU_APP_NAME }}
- name: Push to Heroku
run: git push heroku master
The differences between the 2 workflows are explained below.
Checkout
The Checkout action must fetch the entire Git history or else the build will fail with the error:
Run git push heroku master
git push heroku master
shell: /usr/bin/bash -e {0}
remote:
remote: ! Push rejected, source repository is a shallow clone. Unshallow it with `git fetch --all --unshallow` and try pushing again.
remote:
To https://git.heroku.com/***.git
! [remote rejected] master -> master (shallow update not allowed)
error: failed to push some refs to 'https://git.heroku.com/***.git'
Error: Process completed with exit code 1.
Heroku Login
The ~/.netrc
contains the Heroku login credentials:
- name: Heroku login credentials
run: |
cat > ~/.netrc <<EOF
machine api.heroku.com
login $HEROKU_EMAIL
password $HEROKU_API_KEY
machine git.heroku.com
login $HEROKU_EMAIL
password $HEROKU_API_KEY
EOF
env:
HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }}
HEROKU_EMAIL: ${{ secrets.HEROKU_EMAIL }}
Deploy with Git
Then the Git remote is set and pushed:
- name: Add Heroku remote
run: heroku git:remote --app $HEROKU_APP_NAME
env:
HEROKU_APP_NAME: ${{ secrets.HEROKU_APP_NAME }}
- name: Push to Heroku
run: git push heroku master
We are pushing to the master
branch here, but we can push to main
as well.
Example
The repository contains the code examples.
See how a successful deploy will look like.
Created and wrote to ~/.netrc
Successfully logged into heroku
› Warning: Our terms of service have changed:
Added git remote heroku
› https://dashboard.heroku.com/terms-of-service
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Building on the Heroku-20 stack
remote: -----> Node.js app detected
remote:
remote: -----> Creating runtime environment
remote:
remote: NPM_CONFIG_LOGLEVEL=error
remote: NODE_VERBOSE=false
remote: NODE_ENV=production
remote: NODE_MODULES_CACHE=true
remote:
remote: -----> Installing binaries
remote: engines.node (package.json): unspecified
remote: engines.npm (package.json): unspecified (use default)
remote:
remote: Resolving node version 14.x...
remote: Downloading and installing node 14.16.0...
remote: Using default npm version: 6.14.11
remote:
remote: -----> Restoring cache
remote: - node_modules
remote:
remote: -----> Installing dependencies
remote: Installing node modules (package.json)
remote: audited 50 packages in 0.733s
remote: found 0 vulnerabilities
remote:
remote:
remote: -----> Build
remote:
remote: -----> Caching build
remote: - node_modules
remote:
remote: -----> Pruning devDependencies
remote: audited 50 packages in 0.735s
remote: found 0 vulnerabilities
remote:
remote:
remote: -----> Build succeeded!
remote: -----> Discovering process types
remote: Procfile declares types -> (none)
remote: Default types for buildpack -> web
remote:
remote: -----> Compressing...
remote: Done: 32.6M
remote: -----> Launching...
remote: Released v6
remote: https://***.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/***.git
88f00ab..1a1a302 HEAD -> main