Thanks @Melvin_Zottola for your answer. This is my working solution so @rophilogene or @Pierre_Mavro if you want to write a guide feel free to use this if you want ;). My inspiration coming from this guide Build E2E Testing Ephemeral Environments with GitHub Actions and Qovery | Qovery that cover some of my usecase.
First one I created a blueprint environment like explain on the article.
be careful with your environment variable, by default when you have a variable that use only one other environment variable from Qovery, Qovery can change it with the value of the new service.
Let me give you an example : you have a variable from Qovery like QOVERY_CONTAINER_ABC_HOST_INTERNAL
if you have a variable API_HOST={{QOVERY_CONTAINER_ABC_HOST_INTERNAL}}
when you clone the environment for preview it will change QOVERY_CONTAINER_ABC_HOST_INTERNAL
by the new one QOVERY_CONTAINER_XYZ_HOST_INTERNAL
. The best is to use alias for that. But sometimes you will have to build more complexe variable like API_URL=https://{{QOVERY_CONTAINER_ABC_HOST_INTERNAL}}/foo
the value of API_URL
is not updated with the new QOVERY_CONTAINER_XYZ_HOST_INTERNAL
environment variable
To avoid this problem you can create an alias for QOVERY_CONTAINER_ABC_HOST_INTERNAL
with name API_HOST
and build the API_URL
like API_URL=https://{{API_HOST}}/foo
. When environment is clone for preview, all variable are copied and works perfectly.
Let’s see now the github action configuration to start and deploy the preview environment. The preview environment is started when the PR is flagged with the label preview
. In my use case I use arm instances so I have to build docker container compatible with arm. The default github runner are amd instance so building an arm docker image is very slow for that I used depot that speed up the build by sooooo much. With cache (around 10 seconds to build instead of 5-6 minutes)
name: PR Run preview environment
on:
pull_request:
types: [ labeled ]
jobs:
build-preview:
if: ${{ github.event.label.name == 'preview' }}
runs-on: ubuntu-latest
timeout-minutes: 14
permissions:
contents: read
id-token: write
steps:
- name: Check out the repo
uses: actions/checkout@v3
- name: Set up depot.dev multi-arch runner
uses: depot/setup-action@v1
- name: Log in to Docker Hub
uses: docker/login-action@v2.1.0
with:
registry: <registry_url>
username: <username>
password: <password>
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4.1.1
with:
images: <registry_url>/<image_name>
tags: |
type=semver,pattern={{version}}
type=sha,prefix=preview-,format=long #here you can use the prefix you want, I use preview but feel free to use the one you want
- name: Build and push Docker image
uses: depot/build-push-action@v1 # here is depot but you can use docker/build-push-action@v4 image instead for amd instances
with:
project: <project_id>
context: .
platforms: linux/arm64
target: <your_target> # if you have one on your Dockerfile
file: Dockerfile
push: true
build-args: |
<VAR_ENV1>=${{ secrets.VAR_ENV1 }}
<VAR_ENV2>=${{ secrets.VAR_ENV2 }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
create-preview-environment:
if: ${{ github.event.label.name == 'preview' }}
runs-on: ubuntu-latest
needs: [build-preview] # to not start the github workflow without a previous image build
permissions:
pull-requests: write
steps:
- id: create-environment
name: Create and deploy Qovery preview environment
env:
QOVERY_CLI_ACCESS_TOKEN: <QOVERY_CLI_ACCESS_TOKEN>
run: |
# Download and install Qovery CLI
curl -s https://get.qovery.com | bash
echo "Organization name: ${{ vars.QOVERY_ORGANIZATION_NAME }}"
echo "Project name: ${{ vars.QOVERY_PROJECT_NAME }}"
echo "Blueprint name: ${{ vars.QOVERY_BLUEPRINT_ENVIRONMENT_NAME }}"
new_environment_name="${GITHUB_HEAD_REF}"
echo "Let's clone '${{ vars.QOVERY_BLUEPRINT_ENVIRONMENT_NAME }}' environment into '$new_environment_name' environment"
qovery environment clone \
--organization "${{ vars.QOVERY_ORGANIZATION_NAME }}" \
--project "${{ vars.QOVERY_PROJECT_NAME }}" \
--environment "${{ vars.QOVERY_BLUEPRINT_ENVIRONMENT_NAME }}" \
--cluster "${{ vars.QOVERY_CLUSTER_NAME }}" \ # don't forget to specify the cluster name if you have more than one to prevent bad cluster environment location
--new-environment-name "$new_environment_name"
qovery container update \
--organization "${{ vars.QOVERY_ORGANIZATION_NAME }}" \
--project "${{ vars.QOVERY_PROJECT_NAME }}" \
--environment "$new_environment_name" \
--container "<container_name>" \
--tag preview-${{ github.sha }}
# repeat this step if you have many container to update
qovery lifecycle update \
--organization "${{ vars.QOVERY_ORGANIZATION_NAME }}" \
--project "${{ vars.QOVERY_PROJECT_NAME }}" \
--environment "$new_environment_name" \
--lifecycle "<lifecycle_name>" \
--tag preview-${{ github.sha }}
qovery environment deploy \
--organization "${{ vars.QOVERY_ORGANIZATION_NAME }}" \
--project "${{ vars.QOVERY_PROJECT_NAME }}" \
--environment "$new_environment_name" \
-w
qovery_status_markdown_output=`qovery service list \
--organization "${{ vars.QOVERY_ORGANIZATION_NAME }}" \
--project "${{ vars.QOVERY_PROJECT_NAME }}" \
--environment "$new_environment_name" \
--markdown`
echo "QOVERY_STATUS_MARKDOWN_OUTPUT<<EOF" >> "$GITHUB_OUTPUT"
echo "$qovery_status_markdown_output" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
- name: PR Comment with URL
uses: mshick/add-pr-comment@v2
with:
message-id: qovery-preview-environment-status
message: |
${{ steps.create-environment.outputs.QOVERY_STATUS_MARKDOWN_OUTPUT }}
And the final step, destroy the preview environment on PR close / merge
name: Destroy and clean up preview Environment
on:
pull_request:
types: [ closed ]
jobs:
delete-preview-environment:
runs-on: ubuntu-latest
steps:
- id: delete-environment
name: Delete Qovery preview environment
env:
QOVERY_CLI_ACCESS_TOKEN: ${{ secrets.QOVERY_CLI_ACCESS_TOKEN }}
run: |
# Download and install Qovery CLI
curl -s https://get.qovery.com | bash
echo "Organization name: ${{ vars.QOVERY_ORGANIZATION_NAME }}"
echo "Project name: ${{ vars.QOVERY_PROJECT_NAME }}"
echo "Blueprint name: ${{ vars.QOVERY_BLUEPRINT_ENVIRONMENT_NAME }}"
new_environment_name="${GITHUB_HEAD_REF}"
echo "Let's delete '$new_environment_name' environment and release its resources"
qovery environment delete \
--organization "${{ vars.QOVERY_ORGANIZATION_NAME }}" \
--project "${{ vars.QOVERY_PROJECT_NAME }}" \
--environment "$new_environment_name" \
Feel free if you have some advice to improve these github action