Skip to content

ci: run the release test step against a real redis:7 #78

ci: run the release test step against a real redis:7

ci: run the release test step against a real redis:7 #78

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
permissions:
contents: read
jobs:
test:
name: Python ${{ matrix.python }}
# setup-python ships no 3.9 build for ubuntu-26.04 (ubuntu-latest); keep 3.9 on 24.04 while it stays supported.
runs-on: ${{ matrix.python == '3.9' && 'ubuntu-24.04' || 'ubuntu-latest' }}
strategy:
fail-fast: false
matrix:
python: ['3.9', '3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v7
- name: Setup Python
uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python }}
- name: Install (with Celery + Django adapters)
run: |
python -m pip install --upgrade pip
pip install -e ".[dev,celery,django,otel]" opentelemetry-sdk
- name: Run tests
run: pytest
lint:
name: Static analysis (ruff + mypy)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Setup Python
uses: actions/setup-python@v7
with:
python-version: '3.12'
- name: Install (dev + all adapters for type context)
run: |
python -m pip install --upgrade pip
pip install -e ".[dev,celery,django,redis,amqp,sqs,azureservicebus,artemis,otel]" opentelemetry-sdk
- name: Ruff
run: ruff check src tests
- name: Mypy
run: mypy
integration:
name: Broker integration (Redis · RabbitMQ · SQS)
runs-on: ubuntu-latest
services:
redis:
image: redis:7
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 5s
--health-timeout 3s
--health-retries 10
rabbitmq:
image: rabbitmq:3
ports:
- 5672:5672
options: >-
--health-cmd "rabbitmq-diagnostics -q ping"
--health-interval 10s
--health-timeout 5s
--health-retries 15
# Free, SQS-compatible broker for the SqsTransport round-trip. The native
# image is shell-less, so readiness is polled by a TCP-probe step below.
elasticmq:
image: softwaremill/elasticmq-native:1.6.11
ports:
- 9324:9324
steps:
- uses: actions/checkout@v7
- name: Setup Python
uses: actions/setup-python@v7
with:
python-version: '3.12'
- name: Install (all adapters — full coverage with brokers)
run: |
python -m pip install --upgrade pip
pip install -e ".[redis,amqp,sqs,azureservicebus,artemis,celery,django,dev,otel]" opentelemetry-sdk
- name: Wait for ElasticMQ
run: |
for i in $(seq 1 30); do
if (echo > /dev/tcp/localhost/9324) >/dev/null 2>&1; then
echo "ElasticMQ port 9324 open"; exit 0
fi
sleep 2
done
echo "ElasticMQ did not open port 9324"; exit 1
- name: Run full suite with coverage gate (>=90%)
env:
# A real redis:7 is mandatory here: no silent skip or fakeredis fallback (shared runner contract).
BQ_REQUIRE_REDIS: "1"
BABELQUEUE_TEST_REDIS: redis://localhost:6379/0
BABELQUEUE_TEST_AMQP: amqp://guest:guest@localhost:5672/
SQS_ENDPOINT: http://localhost:9324
AWS_REGION: us-east-1
AWS_ACCESS_KEY_ID: test
AWS_SECRET_ACCESS_KEY: test
run: pytest --cov=babelqueue --cov-report=term-missing --cov-fail-under=90
integration-live:
name: Integration (live Kafka)
# Opt-in, not a required check: runs on push to main and on demand, never on pull requests,
# and is deliberately NOT in ci-green's needs. (The `integration` job above is the required,
# coverage-gated one for Redis / RabbitMQ / SQS.)
if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }}
runs-on: ubuntu-latest
timeout-minutes: 20
services:
kafka:
image: apache/kafka:3.9.0
ports:
- 9092:9092
env:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@localhost:9093
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
options: >-
--health-cmd "/opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092"
--health-interval 10s --health-timeout 10s --health-retries 12 --health-start-period 20s
steps:
- uses: actions/checkout@v7
- name: Setup Python
uses: actions/setup-python@v7
with:
python-version: '3.12'
- name: Install (kafka extra + dev)
run: |
python -m pip install --upgrade pip
pip install -e ".[kafka,dev]"
- name: Live Kafka tests
env:
BQ_INTEGRATION: "1"
BQ_KAFKA_BROKERS: localhost:9092
run: pytest tests/test_kafka_integration.py -v
conformance:
name: Conformance suite in sync + results.json
runs-on: ubuntu-latest
services:
redis:
image: redis:7
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 5s
--health-timeout 3s
--health-retries 10
env:
# The pinned conformance release (ADR-0032). Bump together with tests/conformance/.
BQ_CONFORMANCE_VERSION: 1.6.0
# sha256 of that release's fetch.sh: the script runs on the runner, so it is pinned rather
# than trusted from a mutable tag. Bump together with BQ_CONFORMANCE_VERSION.
BQ_FETCH_SH_SHA256: 8bb6ba567b288fb0ac71a70fd17041b2503df119e01998d76fdad372570bf849
steps:
- uses: actions/checkout@v7
- name: Setup Python
uses: actions/setup-python@v7
with:
python-version: '3.12'
- name: Verify the vendored suite against the release asset
run: |
# fetch.sh comes from the pinned tag; it downloads babelqueue-conformance-<v>.tar.gz,
# verifies it against the release SHA256SUMS before unpacking, then diffs the vendor dir.
curl -fsSL -o "$RUNNER_TEMP/fetch.sh" \
"https://raw.githubusercontent.com/BabelQueue/conformance/v${BQ_CONFORMANCE_VERSION}/fetch.sh"
echo "${BQ_FETCH_SH_SHA256} $RUNNER_TEMP/fetch.sh" | sha256sum -c -
bash "$RUNNER_TEMP/fetch.sh" --check "$BQ_CONFORMANCE_VERSION" tests/conformance
test "$(tr -d '[:space:]' < tests/conformance/CONFORMANCE_VERSION)" = "$BQ_CONFORMANCE_VERSION"
echo "Vendored conformance is in sync with the v${BQ_CONFORMANCE_VERSION} release asset."
- name: Install
run: |
python -m pip install --upgrade pip
pip install -e ".[dev,celery,django,otel,redis]" opentelemetry-sdk jsonschema
- name: Run the conformance suite and write results.json
env:
BQ_CONFORMANCE_RESULTS: ${{ runner.temp }}/results.json
BQ_REQUIRE_REDIS: "1"
BABELQUEUE_TEST_REDIS: redis://localhost:6379/0
run: pytest -q tests/test_conformance.py
- name: Validate results.json (schema, bindings, sections)
run: python scripts/check_conformance_results.py "$RUNNER_TEMP/results.json" tests/conformance
ci-green:
name: CI green
runs-on: ubuntu-latest
needs: [test, lint, integration, conformance]
if: ${{ always() }}
steps:
- name: Fail if any required job did not pass
run: |
if ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}; then
echo "A required job failed or was cancelled."
exit 1
fi