Continuous Deployment
Learning objectives
- Knows the term continuous deployment.
- Knows how to use GitHub Actions for continuous deployment.
Note! We are rewriting these parts to match Fly.io in the near future.
Continuous deployment refers to the process of deploying software to production whenever new code that passes the tests is added to the repository. There exists a range of ready github actions for deploying projects. For example, Deploy to Heroku action could be used to add continuous deployment to Heroku.
Let's continue with our continuous integration example and add continuous deployment to it. The github actions configuration file was as follows.
name: Run tests on project
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Setup repo
uses: actions/checkout@v2
- name: Setup Deno
uses: denoland/setup-deno@v1
with:
deno-version: "v1.42.2"
- name: Run tests
run: deno test --allow-all
Adding a new job
Let's first add a new job called deploy
to the existing configuration file, also entering a new name Test and Deploy
for the configuration. For the job deploy
, we use needs
-command to state that the new job requires that the previously configured job test
passes. The deploy
job uses the Deploy to Heroku action.
For the action, we need to configure an API key, our email, and the name of the application. For now, when these are not entered, the configuration looks as follows.
name: Test and Deploy
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Setup repo
uses: actions/checkout@v2
- name: Setup Deno
uses: denoland/setup-deno@v1
with:
deno-version: "v1.42.2"
- name: Run tests
run: deno test --allow-all
deploy:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v2
- uses: akhileshns/heroku-deploy@v3.12.12
with:
heroku_api_key: "my-very-secret-key"
heroku_app_name: "my-app-name"
heroku_email: "my-email-address"
Let's change the deno.yml
file in GitHub to match the above one.
Not surprisingly, when we commit the above file to GitHub, nothing gets deployed.
Creating a project and extracting API key
Let's create a project to Heroku where the application could be deployed to. We set deno-ci-example
as the name of the project and use https://github.com/chibat/heroku-buildpack-deno.git
as the build pack. Furthermore, we use the following as the content for the Procfile
.
web: deno run --allow-all app.js ${PORT}
And, as the application receives the port as a parameter, we adjust the app.js
to start listening for requests if the application receives a port as a parameter.
import { Application, Router } from "https://deno.land/x/oak@v12.6.1/mod.ts";
const app = new Application();
const router = new Router();
const hello = ({ response }) => {
response.body = "Hello world!";
};
router.get("/", hello);
app.use(router.routes());
if (Deno.args.length > 0) {
const lastArgument = Deno.args[Deno.args.length - 1];
app.listen({ port: Number(lastArgument) });
}
export { app };
For the deployment to work, we need an API key from Heroku. The API key is found in Account settings
in Heroku; account settings are found at https://dashboard.heroku.com/account. The API Key can be found at the end of the page just before the Close Account
option.
Click the Reveal
button and copy the API Key for further use.
Adding Secrets
Now, go back to the project page on GitHub, and click Settings
. Choose Secrets
. This shows a page with the title Action secrets
.
Now, click the button "New repository secret", and create a secret with the name HEROKU_API_KEY
. Set the value of the secret to the API Key that you previously copied from Heroku.
Once the secret has been added, the Action secrets page should look something like the following one.

Proceed by adding two further secrets; (1) your email address to Heroku, and (2) the name of the application on Heroku. Label these secrets as HEROKU_EMAIL_ADDRESS
and HEROKU_APPLICATION_NAME
. At this point, there should be three secrets for the project.
Why do we add secrets?
Secrets are added so that we do not have to store sensitive information in the GitHub repository. For example, if the repository would be a public one, or made public at some point, any sensitive information in the configuration files could be extracted from the GitHub version history.
Deploy configuration
Now that we have the secrets added to GitHub, we can add them to the deno.yml
configuration file. Secrets are referred to using ${{secrets.SECRET_NAME}}
, where SECRET_NAME refers to the name of a specific secret. For example, as we added our email address as a secret using the name HEROKU_EMAIL_ADDRESS
, we can refer to it using ${{secrets.HEROKU_EMAIL_ADDRESS}}
in the configuration file.
Below, we have added the three secrets to our configuration file.
name: Test and Deploy
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Setup repo
uses: actions/checkout@v2
- name: Setup Deno
uses: denoland/setup-deno@v1
with:
deno-version: "v1.42.2"
- name: Run tests
run: deno test --allow-all
deploy:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v2
- uses: akhileshns/heroku-deploy@v3.12.12
with:
heroku_api_key: ${{secrets.HEROKU_API_KEY}}
heroku_app_name: ${{secrets.HEROKU_APPLICATION_NAME}}
heroku_email: ${{secrets.HEROKU_EMAIL_ADDRESS}}
Now, whenever we add new content to GitHub, the application is also deployed to Heroku.