Run a DriftGuard schema check on every pull request.
If the incoming schema is breaking against your contract, the CI job fails and the PR is blocked.
Prerequisites
A DriftGuard API key (dg_live_... or dg_test_...)
A contract already created — see Create Contract
Your repo on GitHub
Step 1: Add Your API Key as a Secret
Go to your GitHub repo → Settings → Secrets and variables → Actions
Click New repository secret
Name: DRIFTGUARD_KEY
Value: your full API key (e.g. dg_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
Click Add secret
Use a dg_test_ key in CI to keep your development checks separate from
production. Create one from your dashboard .
Step 2: Create the Workflow File
Create .github/workflows/schema-check.yml in your repo:
name : DriftGuard Schema Check
on :
pull_request :
branches : [ main , staging ]
jobs :
schema-check :
name : Check schema drift
runs-on : ubuntu-latest
steps :
- name : Checkout code
uses : actions/checkout@v4
- name : Run DriftGuard check
env :
DRIFTGUARD_KEY : ${{ secrets.DRIFTGUARD_KEY }}
run : |
RESULT=$(curl -s -X POST https://api.driftguard.dev/api/v1/check \
-H "X-API-Key: $DRIFTGUARD_KEY" \
-H "Content-Type: application/json" \
-d '{
"contract_id": "your_contract_id_here",
"incoming_schema": {
"columns": [
{ "name": "user_id", "type": "integer", "required": true },
{ "name": "email", "type": "string", "required": true },
{ "name": "created_at", "type": "timestamp", "required": true }
]
}
}')
echo "$RESULT" | jq .
RESULT_STATUS=$(echo "$RESULT" | jq -r '.result')
SEVERITY=$(echo "$RESULT" | jq -r '.severity')
echo "DriftGuard result: $RESULT_STATUS (severity: $SEVERITY)"
if [ "$RESULT_STATUS" = "breaking" ]; then
echo "❌ Breaking schema change detected. Failing CI."
echo "Removed columns: $(echo "$RESULT" | jq '.diff.removed')"
echo "Type changes: $(echo "$RESULT" | jq '.diff.type_changes')"
exit 1
elif [ "$RESULT_STATUS" = "warning" ]; then
echo "⚠️ Warning: schema drift detected. Review before merging."
echo "Added columns: $(echo "$RESULT" | jq '.diff.added')"
else
echo "✅ Schema check passed."
fi
Step 3: Generate Your Incoming Schema Dynamically
In a real pipeline, generate incoming_schema.columns from your actual data
instead of hardcoding it. Here’s an example using Python with pandas:
import pandas as pd
import json
df = pd.read_parquet( "users.parquet" )
TYPE_MAP = {
"int64" : "integer" ,
"float64" : "number" ,
"object" : "string" ,
"bool" : "boolean" ,
"datetime64[ns]" : "timestamp"
}
columns = [
{
"name" : col,
"type" : TYPE_MAP .get( str (df[col].dtype), "string" ),
"required" : not df[col].isnull().any()
}
for col in df.columns
]
payload = json.dumps({ "columns" : columns })
print (payload)
Then pipe this into your curl command in CI:
SCHEMA = $( python generate_schema.py )
RESULT = $( curl -s -X POST https://api.driftguard.dev/api/v1/check \
-H "X-API-Key: $DRIFTGUARD_KEY " \
-H "Content-Type: application/json" \
-d "{ \" contract_id \" : \" your_contract_id_here \" , \" incoming_schema \" : $SCHEMA }" )
Map your DataFrame dtypes to DriftGuard’s supported types: string, integer,
number, boolean, date, timestamp, json. Any unrecognised type should
default to string.
What Failure Looks Like
When a breaking change is detected, your PR will show:
DriftGuard result: breaking (severity: 70)
❌ Breaking schema change detected. Failing CI.
Removed columns: ["email"]
Type changes: [{"column":"created_at","from":"timestamp","to":"string"}]
Error: Process completed with exit code 1.
What a Passing Check Looks Like
DriftGuard result: pass (severity: 0)
✅ Schema check passed.
Set up Slack Alerts Get notified in Slack when a breaking check is detected.
Webhooks Register a webhook to receive check results automatically.