This guide shows how to version quality checks in Git and automatically promote them across environments (Dev → Test → Prod) using GitHub Actions.
your-repo/
checks/
orders/
notnull__order_id.yaml
between__total_amount.yaml
customers/
matchespattern__email.yaml
isunique__customer_id.yaml
.github/
workflows/
promote-checks.yml
Each file in checks/ is a portable quality check definition:
# checks/orders/notnull__order_id.yaml
rule_type: notNull
description: Order ID must not be null
container: orders
fields:
- order_id
coverage: 1.0
filter: null
properties: {}
tags:
- data-quality
- orders
status: Active
additional_metadata:
_qualytics_check_uid: orders__notnull__order_idChecks are portable — they reference containers by name (not ID), so the same file works across any datastore that has a matching container.
pip install qualytics-cli
qualytics init --url "$QUALYTICS_URL" --token "$QUALYTICS_TOKEN"
# Export all checks from the Dev datastore
qualytics checks export --datastore-id $DEV_DATASTORE_ID --output ./checks/git add checks/
git commit -m "Update quality checks from Dev"
git push origin mainOpen a PR. Reviewers can see exactly which checks changed in the diff — each check is a separate YAML file, so changes are clear and reviewable.
The GitHub Actions workflow below handles the rest.
# .github/workflows/promote-checks.yml
name: Promote Quality Checks
on:
push:
branches: [main]
paths: ['checks/**']
release:
types: [published]
jobs:
promote-to-test:
if: github.event_name == 'push'
runs-on: ubuntu-latest
environment: test
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install Qualytics CLI
run: pip install qualytics-cli
- name: Configure Qualytics
run: qualytics init --url "${{ secrets.QUALYTICS_URL }}" --token "${{ secrets.QUALYTICS_TOKEN }}"
- name: Import checks to Test
run: qualytics checks import --datastore-id ${{ vars.TEST_DATASTORE_ID }} --input ./checks/
promote-to-prod:
if: github.event_name == 'release'
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install Qualytics CLI
run: pip install qualytics-cli
- name: Configure Qualytics
run: qualytics init --url "${{ secrets.QUALYTICS_URL }}" --token "${{ secrets.QUALYTICS_TOKEN }}"
- name: Import checks to Prod
run: qualytics checks import --datastore-id ${{ vars.PROD_DATASTORE_ID }} --input ./checks/| Secret | Description |
|---|---|
QUALYTICS_URL |
Qualytics instance URL (e.g., https://qualytics.example.com/) |
QUALYTICS_TOKEN |
API token for the Qualytics instance |
| Variable | Description |
|---|---|
TEST_DATASTORE_ID |
Datastore ID in the Test environment |
PROD_DATASTORE_ID |
Datastore ID in the Production environment |
- Go to Settings → Environments in your GitHub repository
- Create
testandproductionenvironments - Add the secrets and variables listed above to each environment
- Optionally add required reviewers to
productionfor manual approval before Prod deployments
To import checks to multiple datastores in a single step:
qualytics checks import \
--datastore-id $DATASTORE_1 \
--datastore-id $DATASTORE_2 \
--datastore-id $DATASTORE_3 \
--input ./checks/Preview what would change before actually importing:
qualytics checks import \
--datastore-id $PROD_DATASTORE_ID \
--input ./checks/ \
--dry-runOutput:
Loaded 15 check definitions from ./checks/
[DRY RUN] Importing to datastore 42...
Import Summary
┏━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┓
┃ Datastore ID ┃ Created ┃ Updated ┃ Failed ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━┩
│ 42 │ 10 │ 5 │ 0 │
└──────────────┴─────────┴─────────┴────────┘
Import uses upsert (create-or-update) logic:
- Each check has a stable
_qualytics_check_uidin itsadditional_metadata - On import, the CLI matches UIDs against existing checks in the target datastore
- Match found → update the existing check
- No match → create a new check
- Container names are resolved to IDs within each target datastore
This means you can safely re-import the same checks multiple times — existing checks are updated, new ones are created, and nothing is duplicated.