This guide explains how to configure GitHub Actions for running Athena integration tests automatically.
Before the CI/CD can run, you need to add secrets and variables to your GitHub repository:
- Go to your repository on GitHub
- Click Settings β Secrets and variables β Actions
Click New repository secret for each of the following:
| Secret Name | Description | Example |
|---|---|---|
AWS_ACCESS_KEY_ID |
AWS Access Key ID for Athena access | AKIAEXAMPLE123 |
AWS_SECRET_ACCESS_KEY |
AWS Secret Access Key | wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY |
AWS_ATHENA_OUTPUT_LOCATION |
S3 location for Athena query results | s3://your-bucket/athena-results/ |
Click on the Variables tab, then New repository variable for each:
| Variable Name | Description | Example |
|---|---|---|
AWS_ATHENA_DATABASE |
Athena database name for tests | test_db |
AWS_REGION |
AWS region (optional, defaults to us-west-2) | us-west-2 |
Create a dedicated IAM user for GitHub Actions with minimal permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"athena:StartQueryExecution",
"athena:GetQueryExecution",
"athena:GetQueryResults",
"athena:StopQueryExecution",
"athena:ListQueryExecutions",
"athena:ListWorkGroups"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:DeleteObject",
"s3:List*",
"s3:Get*"
],
"Resource": [
"arn:aws:s3:::your-athena-results-bucket",
"arn:aws:s3:::your-athena-results-bucket/*"
]
},
{
"Effect": "Allow",
"Action": [
"glue:GetDatabase",
"glue:GetTable",
"glue:GetTables",
"glue:GetPartitions",
"glue:CreateTable",
"glue:DeleteTable",
"glue:UpdateTable"
],
"Resource": "*"
}
]
}- Create user:
github-actions-athena - Attach the policy created above
- Generate access keys
- Add keys to GitHub secrets
Tests are organized using pytest markers for precise execution control:
- Unit tests: No markers (default)
- Integration tests:
@pytest.mark.integration - Athena-specific:
@pytest.mark.athena - Combined:
@pytest.mark.integration+@pytest.mark.athena
tests.yaml: Runspytest -m "not integration"(unit tests intests/only)athena-integration.yml: Runspytest tests/integration/ -m "integration and athena"(Athena integration only)
This ensures: β Unit tests run on every commit (free) β Integration tests run only for specific adapters β No cross-contamination between test types β Clear cost attribution per adapter
The CI/CD workflow runs automatically on:
- Triggers: Any PR to
masterormainbranch - File changes: Only when Athena-related files are modified:
src/sql_testing_library/_adapters/athena.pysrc/sql_testing_library/_core.pysrc/sql_testing_library/_mock_table.pytests/test_athena*.pytests/integration/test_athena_integration.py- Workflow file itself
- Triggers: Direct pushes to
masterormainbranch - Runs: Full test suite including real Athena tests
- Access: Repository β Actions β "Athena Integration Tests" β "Run workflow"
- Use case: Testing without making commits
- Runs mocked Athena adapter tests
- No AWS resources used
- Fast execution (~2-3 minutes)
- Tests adapter logic with mocked AWS responses
- Validates SQL generation and parsing
- No AWS costs
- Connects to real AWS Athena
- Executes actual queries
- Cost: ~$0.01-0.05 per test run
- Includes automatic cleanup
- Every PR: Real Athena tests run (~$0.05 per PR)
- Every merge: Real Athena tests run (~$0.05 per merge)
- Estimated monthly cost: $5-20 (depending on PR frequency)
When ready to optimize costs, update the workflow condition:
# Change this condition in .github/workflows/athena-integration.yml
if: |
(github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main')) ||
(github.event_name == 'workflow_dispatch')
# Remove: (github.event_name == 'pull_request')This will:
- β Run real tests on main branch pushes
- β Allow manual triggers
- β Skip real tests on PRs (only unit/mock tests)
- π° Reduce costs by ~80%
- View detailed logs in: Repository β Actions β Workflow run
- Each step shows detailed output
- Failed tests include full error messages
- Automatic summary appears in PR comments
- Shows which test stages passed/failed
- Includes cost estimation
β AWS credentials not configured in GitHub secrets
Solution: Add all required secrets to repository settings
β Failed to connect to AWS Athena: timeout
Solution: Check AWS region and network connectivity
β User: arn:aws:iam::xxx:user/github-actions is not authorized
Solution: Review IAM policy and ensure all required permissions
- AWS credentials stored as GitHub secrets (encrypted)
- Minimal IAM permissions
- Automatic cleanup of test resources
- No credentials in logs or code
- Use AWS IAM roles with OIDC instead of access keys
- Restrict S3 bucket access by IP/time
- Enable AWS CloudTrail for audit logging
When adding other adapters (BigQuery, Redshift, Trino), the workflow can be extended:
strategy:
matrix:
adapter: [athena, bigquery, redshift, trino]
include:
- adapter: athena
secrets_suffix: ATHENA
- adapter: bigquery
secrets_suffix: BIGQUERYThis allows running all adapter tests in parallel while maintaining cost control.
The SQL Testing Library supports two execution modes for Athena:
- Mock data injected as Common Table Expressions
- No additional AWS permissions required
- Works with the basic IAM policy above
- Suitable for most test scenarios
- Creates temporary external tables in AWS Glue Data Catalog
- Requires additional Glue permissions (included in IAM policy above):
glue:CreateTable- Create temporary test tablesglue:DeleteTable- Clean up test tables after testsglue:UpdateTable- Modify table metadata if needed
Physical tables are automatically used when:
- CTE queries exceed Athena's 256KB query size limit
- Explicitly requested via
use_physical_tables=Trueparameter - Testing complex scenarios that require persistent table structures
If you see errors like:
User: arn:aws:iam::xxx:user/github-actions is not authorized to perform: glue:CreateTable
Solution: Ensure your IAM user has all Glue permissions listed in the IAM policy above. The glue:CreateTable, glue:DeleteTable, and glue:UpdateTable permissions are essential for physical table creation and cleanup.