How to integrate Qovery with GitHub Actions

Learn how to integrate Qovery with GitHub Actions

Getting starting 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.

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.

  1. 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.

  2. 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 Qovery
    on:
    workflow_call:
    inputs:
    organization-name:
    required: true
    type: string
    project-name:
    required: true
    type: string
    environment-name:
    required: true
    type: string
    application-names:
    required: true
    type: string
    secrets:
    api-token:
    required: true
    jobs:
    test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/[email protected]
    - name: Install modules
    run: yarn
    - name: Run tests
    run: yarn test
    deploy:
    needs: test
    runs-on: ubuntu-latest
    name: Deploy on Qovery
    steps:
    - name: Checkout
    uses: actions/[email protected]
    - name: Deploy on Qovery
    uses: Qovery/qovery-[email protected]
    id: qovery
    with:
    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 a workflow_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 and secrets sections are defining the values that we will need to pass to our workflow
    • The jobs section lists the jobs and the steps 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 Jest
      • deploy where we check out the code and deploy to Qovery.

    Several things worth noting:

    • Our deploy job has a needs instructions, telling GitHub Actions that this job can only run when the test job succeeds.
    • The with section of our last deploy 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.
  3. 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 our production environment.

    name: Deploy to production
    on:
    push:
    branches:
    - main
    jobs:
    test-and-deploy:
    uses: ./.github/workflows/test-and-deploy.yaml
    with:
    organization-name: XXX
    project-name: XXX
    environment-name: XXX
    application-names: XXX
    secrets:
    api-token: ${{ secrets.QOVERY_API_TOKEN }}
    • We are setting the on section with a push directive pointing to the main branch. It means that this workflow will be executed when we push code to the main branch.
    • Our test-and-deploy job calls our previously created workflow with the use 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.
  4. Get the Organization, Project, Environment and Application names

    First we need to get the names that we will to add to our YAML file.

  5. 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 ----
  6. 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 on New 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.yaml
with:
organization-name: XXX
project-name: XXX
environment-name: XXX
application-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:

  1. 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 called add-run-id-to-env-name.sh with the following content:

    #!/usr/bin/env bash
    set -eo pipefail
    echo "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 == *"- #"* ]];
    then
    newEnvName=$(echo $envName | sed "s/#.*/#$GITHUB_RUN_ID/")
    else
    newEnvName="$envName - #$GITHUB_RUN_ID"
    fi
    echo "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 going
    exit 0

    Make this file executable:

    chmod +x .github/scripts/add-run-id-to-env-name.sh
  2. Add 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 Qovery
    on:
    workflow_call:
    inputs:
    organization-name:
    required: true
    type: string
    project-name:
    required: true
    type: string
    environment-name:
    required: true
    type: string
    application-names:
    required: true
    type: string
    secrets:
    api-token:
    required: true
    jobs:
    test:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
    uses: actions/[email protected]
    - name: Install modules
    run: yarn
    - name: Run tests
    run: yarn test
    deploy:
    needs: test
    runs-on: ubuntu-latest
    name: Deploy on Qovery
    steps:
    - name: Checkout
    uses: actions/[email protected]
    - name: Deploy on Qovery
    uses: Qovery/qovery-[email protected]
    id: qovery
    with:
    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: deploy
    runs-on: ubuntu-latest
    name: Add Workflow execution ID to env name
    env:
    ENVIRONMENT_ID: ${{ inputs.environment-id }}
    QOVERY_API_TOKEN: ${{ secrets.api-token }}
    steps:
    - name: Checkout
    uses: actions/[email protected]
    - name: Add Workflow execution ID to env name
    run: ./.github/scripts/add-run-id-to-env-name.sh
    shell: bash
  3. Commit 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.