Getting started with Qovery is easy. Just plug your Git repository, and you can deploy your application directly. But in some cases you will want a more advanced CI workflow where some steps need to happen before deployment.
One of the CI tools you can use for that matter is GitHub Actions.
Before you begin, this guide assumes the following:
- You have a Qovery cluster running.
- You are using GitHub Actions as a CI server.
- You have a Qovery application deployed.
- You have the Qovery CLI installed and configured.
If you don't have an application running on Qovery yet, check the documentation to create one.
Goal
In this tutorial, we will deploy an application with the official Qovery GitHub action.
You can find it on the marketplace.
Get your application ready
The first thing we need to do, is to disable automatic deployments. By default, Qovery applications get re-deployed whenever you push some code to the configured branch. Since we want to trigger the deployment through GitHub Actions, we need to disable this behavior.
Go to your environment page, then click Settings
:
Then go to Deployment
and on the Auto-deploy
dropdown, select Off
:
Click save and close the modal.
Add your GitHub action Workflow
We will now add a GitHub Actions workflow to your application. Workflow are defined with YAML configuration files that are placed in the code directory of your application. As an example we will define a workflow for a NodeJS application. We will first run our unit tests, then launch the Qovery deployment if the tests pass.
You can adapt those steps for your own stack and needs. Read the GitHub Actions documentation to learn more.
Create the Workflows directory
All your workflows files must be stored in a specific
.github/workflows
directory. Create this directory at the root of your project.Add a Test and Deploy workflow
In your Workflows folder, create a
test-and-deploy.yaml
file with the following content:name: Test And Deploy to Qoveryon:workflow_call:inputs:organization-name:required: truetype: stringproject-name:required: truetype: stringenvironment-name:required: truetype: stringapplication-names:required: truetype: stringsecrets:api-token:required: truejobs:test:runs-on: ubuntu-lateststeps:- name: Install modulesrun: yarn- name: Run testsrun: yarn testdeploy:needs: testruns-on: ubuntu-latestname: Deploy on Qoverysteps:- name: Checkout- name: Deploy on Qoveryid: qoverywith:qovery-organization-name: ${{ inputs.organization-name }}qovery-project-name: ${{ inputs.project-name }}qovery-environment-name: ${{ inputs.environment-name }}qovery-application-names: ${{ inputs.application-names }}qovery-api-token: ${{ secrets.api-token }}- We give it a name
Test And Deploy to Qovery
. It could be anything. - The
on
section contains aworkflow_call
directive. It means that this workflow will be triggered when called from another workflow. We're doing this because we won't use this workflow directly. Since we might have several environments to deploy to Qovery depending on the branch, we could have one workflow per environment, and we want to avoid repeating all the steps. - The
inputs
andsecrets
sections are defining the values that we will need to pass to our workflow - The
jobs
section lists thejobs
and thesteps
that in needs to accomplish. Here we have two jobs and five steps:test
where we check out the code, we install Yarn modules, and we run tests through Jestdeploy
where we check out the code and deploy to Qovery.
Several things worth noting:
- Our
deploy
job has aneeds
instructions, telling GitHub Actions that this job can only run when thetest
job succeeds. - The
with
section of our lastdeploy
step contains interpolated strings: ${{ inputs.xxxx }}. Those are values passed to our workflow, that our Qovery action needs. They will be passed from the calling workflow.
- We give it a name
Add an actual workflow
Now we will add a deployment workflow that will be called every time we push our code to the
main
branch to deploy ourproduction
environment.name: Deploy to productionon:push:branches:- mainjobs:test-and-deploy:uses: ./.github/workflows/test-and-deploy.yamlwith:organization-name: XXXproject-name: XXXenvironment-name: XXXapplication-names: XXXsecrets:api-token: ${{ secrets.QOVERY_API_TOKEN }}- We are setting the
on
section with apush
directive pointing to themain
branch. It means that this workflow will be executed when we push code to themain
branch. - Our
test-and-deploy
job calls our previously created workflow with theuse
instruction. - In the
with
section, we are passing IDs corresponding to the application we want to deploy. - In the
secret
section, we are reading our API key from a GitHub secret we will create later.
- We are setting the
Get the Organization, Project, Environment and Application names
First we need to get the names that we will to add to our YAML file.
Get a Qovery API token
To get an API token, use the Qovery CLI:
qovery token- Select your organization. (tokens are valid for only one organization).
- Enter a name for your token.
- Enter a description for your token.
You will get an output like this one:
qovery token Qovery: ---- Never share this authentication token and keep it secure ----Qovery: qov_xxx....Qovery: ---- Never share this authentication token and keep it secure ----Add your token to your GitHub repository secrets
Go to your GitHub repository then to the
Settings
:Got to the
Secrets/Actions
section and click onNew repository secret
:Add your secret with the name
QOVERY_API_TOKEN
and save:
Push your code
We're done with the setup. You can now push your code to the main
branch. If you did it properly, under the Actions
tab on your GitHub repository, you should see your job being run.
You can click on it to see the details of the jobs. Once the testing phase is green, it will start the deployment job.
As soon as the job is set up, and it starts actually deploying, go to the Qovery console and check that your application is actually being deployed.
Deploy several applications in the same environment
Most of the time, you will have several applications in your environment (e.g. a backend
and a frontend
). To deploy all of them through the action, you can add all the ids separated by commas:
...jobs:test-and-deploy:uses: ./.github/workflows/test-and-deploy.yamlwith:organization-name: XXXproject-name: XXXenvironment-name: XXXapplication-ids: app 1,app 2, app 3...secrets:api-token: ${{ secrets.QOVERY_API_TOKEN }}
Advanced use-cases
For any use case that's not covered by the official Qovery GitHub Action, you can use the Qovery API directly in your workflows. As an example, let's say we want to append the GitHub Actions Workflow execution ID to our environment name after each deployment:
Add a shell script
First we will add a shell script that will make the necessary calls to the Qovery API. Create a
.github/scripts
directory, and add a file calledadd-run-id-to-env-name.sh
with the following content:#!/usr/bin/env bashset -eo pipefailecho "Getting the current environment name"envName=$(curl -fs -X GET -H "Authorization: Token $QOVERY_API_TOKEN" \"https://api.qovery.com/environment/$ENVIRONMENT_ID" | jq -r .name)if [[ $envName == *"- #"* ]];thennewEnvName=$(echo $envName | sed "s/#.*/#$GITHUB_RUN_ID/")elsenewEnvName="$envName - #$GITHUB_RUN_ID"fiecho "New environment name: $newEnvName"echo "Renaming the base environment ..."curl -fs -o /dev/null -X PUT -d "{\"name\": \"$newEnvName\"}" -H 'Content-type: application/json' -H "Authorization: Token $QOVERY_API_TOKEN" \"https://api.qovery.com/environment/$ENVIRONMENT_ID"echo "Done!"## keep goingexit 0Make this file executable:
chmod +x .github/scripts/add-run-id-to-env-name.shAdd a job to our Test and Deploy Workflow
Edit the
test-and-deploy.yaml
workflow configuration file so it now looks like this:name: Test And Deploy to Qoveryon:workflow_call:inputs:organization-name:required: truetype: stringproject-name:required: truetype: stringenvironment-name:required: truetype: stringapplication-names:required: truetype: stringsecrets:api-token:required: truejobs:test:runs-on: ubuntu-lateststeps:- name: Checkout- name: Install modulesrun: yarn- name: Run testsrun: yarn testdeploy:needs: testruns-on: ubuntu-latestname: Deploy on Qoverysteps:- name: Checkout- name: Deploy on Qoveryid: qoverywith:qovery-organization-name: ${{ inputs.organization-name }}qovery-project-name: ${{ inputs.project-name }}qovery-environment-name: ${{ inputs.environment-name }}qovery-application-names: ${{ inputs.application-names }}qovery-api-token: ${{ secrets.api-token }}add-run-id-to-env-name:needs: deployruns-on: ubuntu-latestname: Add Workflow execution ID to env nameenv:ENVIRONMENT_ID: ${{ inputs.environment-id }}QOVERY_API_TOKEN: ${{ secrets.api-token }}steps:- name: Checkout- name: Add Workflow execution ID to env namerun: ./.github/scripts/add-run-id-to-env-name.shshell: bashCommit and push your changes
Push your changes and wait to the workflow execution to finish. Your Qovery environment name should now contain the execution ID of the workflow.
It might not be the most useful example, but you can be creative and do all kind of things using the Qovery API with GitHub Actions.
For some other use-cases, like preview environments
, you can use the scripts we provide here.
Conclusion
Integrating Qovery with GitHub Actions enables more complex workflows than just deploying on code push. You can make sure your test suite succeeds before deploying or anything else you need, without sacrificing the simplicity of deployment Qovery brings you.