Skip to content

ref(options): migrate runtime config to sentry-options (Python RPC/query + Rust killswitches) #25311

ref(options): migrate runtime config to sentry-options (Python RPC/query + Rust killswitches)

ref(options): migrate runtime config to sentry-options (Python RPC/query + Rust killswitches) #25311

Workflow file for this run

name: ci
on:
push:
branches:
- master
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
files-changed:
name: detect what files changed
runs-on: ubuntu-latest
timeout-minutes: 3
# Map a step output to a job output
outputs:
api_changes: ${{ steps.changes.outputs.api_changes }}
devservices_changes: ${{ steps.changes.outputs.devservices_changes }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Check for backend file changes
uses: getsentry/paths-filter@66f7f1844185eb7fb6738ea4ea59d74bb99199e5 # v2
id: changes
with:
token: ${{ github.token }}
filters: .github/file-filters.yml
bump-version-test:
name: "Test bump_version.py script"
runs-on: ubuntu-latest
timeout-minutes: 6
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
name: Checkout code
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
enable-cache: false
- name: Test bump_version.py runs without errors
run: |
# Test that the script can be imported and shows help
uv run --no-project python tools/bump_version.py --help
# Test with a dry run (should fail with appropriate message for non-existent package)
uv run --no-project python tools/bump_version.py test-package 1.0.0 || echo "Expected failure for non-existent package"
linting:
name: "pre-commit hooks" # (includes Python formatting + linting)
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
name: Checkout code
- name: Internal github app token
id: token
uses: getsentry/action-github-app-token@5c1e90706fe007857338ac1bfbd7a4177db2f789 # v4.0.0
continue-on-error: true
with:
app_id: ${{ vars.SENTRY_INTERNAL_APP_ID }}
private_key: ${{ secrets.SENTRY_INTERNAL_APP_PRIVATE_KEY }}
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
# we just cache the venv-dir directly in action-setup-venv
enable-cache: false
- uses: getsentry/action-setup-venv@5a80476d175edf56cb205b08bc58986fa99d1725 # v3.2.0
with:
cache-dependency-path: uv.lock
# NOTE: can't pass --only-dev yet since we're missing some mypy stub packages
install-cmd: uv sync --frozen --active
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: ~/.cache/pre-commit
key: cache-epoch-1|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml', 'uv.lock') }}
- name: Setup pre-commit
run: pre-commit install-hooks
- uses: getsentry/paths-filter@66f7f1844185eb7fb6738ea4ea59d74bb99199e5 # v2
id: files
with:
# Enable listing of files matching each filter.
# Paths to files will be available in `${FILTER_NAME}_files` output variable.
# Paths will be escaped and space-delimited.
# Output is usable as command line argument list in linux shell
list-files: shell
# It doesn't make sense to lint deleted files.
# Therefore we specify we are only interested in added or modified files.
filters: |
all:
- added|modified: '**/*'
- name: Run pre-commit checks
# Run pre-commit to lint and format check files that were changed (but not deleted) compared to master.
# XXX: there is a very small chance that it'll expand to exceed Linux's limits
# `getconf ARG_MAX` - max # bytes of args + environ for exec()
# we skip the `no-commit-to-branch` because in CI we are in fact on master already
# and we have merged to it
run: |
SKIP=no-commit-to-branch pre-commit run --files ${{ steps.files.outputs.all_files }}
# If working tree is dirty, commit and update if we have a token
- name: Apply any pre-commit fixed files
if: steps.token.outcome == 'success' && github.ref != 'refs/heads/master' && always()
uses: getsentry/action-github-commit@5972d5f578ad77306063449e718c0c2a6fbc4ae1 # v2.1.0
with:
github-token: ${{ steps.token.outputs.token }}
rust-linting:
name: "Linting - Rust"
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
name: Checkout code
- name: Install protoc
uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b # v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install Rust Toolchain
run: |
rustup toolchain install stable --profile minimal --no-self-update
rustup component add clippy rustfmt --toolchain stable
- name: Run linter
run: |
make lint-rust format-rust-ci
config-validation:
name: "Dataset Config Validation"
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
name: Checkout code
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
# we just cache the venv-dir directly in action-setup-venv
enable-cache: false
- uses: getsentry/action-setup-venv@5a80476d175edf56cb205b08bc58986fa99d1725 # v3.2.0
with:
cache-dependency-path: uv.lock
install-cmd: uv sync --frozen --active
- name: Validate configs
run: |
make validate-configs
snuba-image:
name: Build snuba CI image
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: read
packages: write
outputs:
branch: ${{ steps.branch.outputs.branch }}
steps:
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Get branch name
id: branch
# strip `refs/heads/` from $GITHUB_REF and replace `/` with `-` so that
# it can be used as a docker tag
run: echo "branch=$(echo ${GITHUB_REF#refs/heads/} | tr / -)" >> "$GITHUB_OUTPUT"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Log in to GHCR for build cache
if: ${{ github.event.pull_request.head.repo.fork != true }}
run: docker login --username '${{ github.actor }}' --password-stdin ghcr.io <<< "$GHCR_TOKEN"
env:
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build snuba CI image
env:
IMAGE: ghcr.io/getsentry/snuba-ci:${{ github.event.pull_request.head.sha || github.sha }}
CACHE_REF: ghcr.io/getsentry/snuba-ci:buildcache
# Write the cache on master only; PRs read-only, so a cache miss never costs more than baseline.
PUSH_CACHE: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
run: |
cache_to=""
if [ "$PUSH_CACHE" = "true" ]; then
cache_to="--cache-to type=registry,ref=${CACHE_REF},mode=max,image-manifest=true,oci-mediatypes=true"
fi
docker buildx build \
--platform linux/amd64 \
--file Dockerfile \
--target testing \
--tag "$IMAGE" \
--cache-from "type=registry,ref=${CACHE_REF}" \
$cache_to \
--output "type=docker,dest=/tmp/snuba-ci.tar" \
.
- name: Publish snuba-ci image to artifacts
# we publish to github artifacts separately so that third-party
# contributions also work, as all the test jobs need this image.
# otherwise third-party contributors would have to provide a working,
# authenticated GHCR, which seems impossible to ensure in the general
# case.
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: snuba-ci
path: /tmp/snuba-ci.tar
docker-deps:
name: Warm Docker dependency image cache
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Restore Docker dependency image cache
id: cache-restore
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: /tmp/docker-deps
key: docker-deps-${{ hashFiles('docker-compose.gcb.yml') }}-${{ github.run_id }}
restore-keys: docker-deps-${{ hashFiles('docker-compose.gcb.yml') }}-
- name: Load and pull Docker dependency images
id: load-pull
run: |
if [ -f /tmp/docker-deps/deps.tar ]; then
docker load --input /tmp/docker-deps/deps.tar
fi
images=(
"ghcr.io/getsentry/image-mirror-altinity-clickhouse-server:25.3.8.10041.altinitystable"
"ghcr.io/getsentry/image-mirror-confluentinc-cp-kafka:6.2.0"
"ghcr.io/getsentry/image-mirror-confluentinc-cp-zookeeper:6.2.0"
"ghcr.io/getsentry/docker-redis-cluster:7.0.10"
)
pulled=0
for image in "${images[@]}"; do
if ! docker image inspect "$image" &>/dev/null; then
docker pull "$image"
pulled=1
fi
done
if [ "$pulled" -eq 1 ]; then
mkdir -p /tmp/docker-deps
docker save "${images[@]}" -o /tmp/docker-deps/deps.tar
fi
echo "pulled=$pulled" >> $GITHUB_OUTPUT
- name: Save Docker dependency image cache
if: steps.load-pull.outputs.pulled == '1'
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: /tmp/docker-deps
key: docker-deps-${{ hashFiles('docker-compose.gcb.yml') }}-${{ github.run_id }}
tests:
needs: [linting, snuba-image, docker-deps]
name: Tests and code coverage
runs-on: ubuntu-latest
timeout-minutes: 40
strategy:
matrix:
include:
- snuba_settings: test
- snuba_settings: test_rust
- snuba_settings: test_distributed
shard: 0
shard_total: 2
- snuba_settings: test_distributed
shard: 1
shard_total: 2
- snuba_settings: test_distributed_migrations
- snuba_settings: test_migrations
- snuba_settings: test_migrations_distributed
steps:
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Download snuba-ci image from artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: snuba-ci
path: /tmp
- name: Load snuba-ci image
run: |
docker load --input /tmp/snuba-ci.tar
docker image ls -a
- name: Restore Docker dependency image cache
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: /tmp/docker-deps
key: docker-deps-${{ hashFiles('docker-compose.gcb.yml') }}-${{ github.run_id }}
restore-keys: docker-deps-${{ hashFiles('docker-compose.gcb.yml') }}-
- name: Load Docker dependency images
run: |
if [ -f /tmp/docker-deps/deps.tar ]; then
docker load --input /tmp/docker-deps/deps.tar
fi
images=(
"ghcr.io/getsentry/image-mirror-altinity-clickhouse-server:25.3.8.10041.altinitystable"
"ghcr.io/getsentry/image-mirror-confluentinc-cp-kafka:6.2.0"
"ghcr.io/getsentry/image-mirror-confluentinc-cp-zookeeper:6.2.0"
"ghcr.io/getsentry/docker-redis-cluster:7.0.10"
)
for image in "${images[@]}"; do
if ! docker image inspect "$image" &>/dev/null; then
docker pull "$image"
fi
done
- name: Docker set up
run: |
docker network create --attachable cloudbuild
- name: Docker Snuba Rust tests
run: |
SNUBA_IMAGE=ghcr.io/getsentry/snuba-ci:${{ github.event.pull_request.head.sha || github.sha }} SNUBA_SETTINGS=test docker compose -f docker-compose.gcb.yml run --rm snuba-test-rust
if: ${{ matrix.snuba_settings == 'test_rust' }}
- name: Docker Snuba tests
env:
SNUBA_TEST_SHARD: ${{ matrix.shard || 0 }}
SNUBA_TEST_SHARD_TOTAL: ${{ matrix.shard_total || 1 }}
run: |
SNUBA_IMAGE=ghcr.io/getsentry/snuba-ci:${{ github.event.pull_request.head.sha || github.sha }} SNUBA_SETTINGS=${{ matrix.snuba_settings }} docker compose -f docker-compose.gcb.yml run --rm -e SNUBA_TEST_SHARD -e SNUBA_TEST_SHARD_TOTAL snuba-test
if: ${{ matrix.snuba_settings == 'test' || matrix.snuba_settings == 'test_distributed' }}
- name: Docker Snuba Migrations tests
run: |
SNUBA_IMAGE=ghcr.io/getsentry/snuba-ci:${{ github.event.pull_request.head.sha || github.sha }} SNUBA_SETTINGS=test docker compose -f docker-compose.gcb.yml run --rm snuba-test-migrations
if: ${{ matrix.snuba_settings == 'test_migrations' }}
- name: Docker Snuba Migrations Distributed tests
run: |
SNUBA_IMAGE=ghcr.io/getsentry/snuba-ci:${{ github.event.pull_request.head.sha || github.sha }} SNUBA_SETTINGS=test_distributed docker compose -f docker-compose.gcb.yml run --rm snuba-test-migrations
if: ${{ matrix.snuba_settings == 'test_migrations_distributed' }}
- name: Docker Snuba Multi-Node Tests
run: |
SNUBA_IMAGE=ghcr.io/getsentry/snuba-ci:${{ github.event.pull_request.head.sha || github.sha }} SNUBA_SETTINGS=test_distributed_migrations docker compose --profile multi_node -f docker-compose.gcb.yml up -d
SNUBA_IMAGE=ghcr.io/getsentry/snuba-ci:${{ github.event.pull_request.head.sha || github.sha }} SNUBA_SETTINGS=test_distributed_migrations TEST_LOCATION=test_distributed_migrations docker compose --profile multi_node -f docker-compose.gcb.yml run --rm snuba-test
if: ${{ matrix.snuba_settings == 'test_distributed_migrations' }}
- name: Docker Snuba Init Tests
run: |
SNUBA_IMAGE=ghcr.io/getsentry/snuba-ci:${{ github.event.pull_request.head.sha || github.sha }} SNUBA_SETTINGS=test_initialization TEST_LOCATION=test_initialization docker compose -f docker-compose.gcb.yml run --rm snuba-test
if: ${{ matrix.snuba_settings == 'test' }}
- name: Upload test results to Codecov
if: ${{ !cancelled() }}
uses: codecov/test-results-action@0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3 # v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
- name: Upload to codecov
run: |
curl -Os https://uploader.codecov.io/latest/linux/codecov && chmod +x codecov && ./codecov -t ${CODECOV_TOKEN}
admin-tests:
needs: [linting]
name: Front end tests for snuba admin
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
name: Checkout code
- uses: volta-cli/action@615a78f6c83e116339c53b94f3f82b4d6c0b7d18 # v5.0.0
- name: Set up and run tests through yarn
run: cd snuba/admin && yarn install && yarn run test --coverage
- name: Upload to codecov
run: |
curl -Os https://uploader.codecov.io/latest/linux/codecov && chmod +x codecov && ./codecov -t ${CODECOV_TOKEN}
sentry:
needs: [snuba-image, files-changed]
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
matrix:
instance: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
env:
MIGRATIONS_TEST_MIGRATE: 1
# XXX: `MATRIX_INSTANCE_TOTAL` must be hardcoded to the length of `strategy.matrix.instance`.
MATRIX_INSTANCE_TOTAL: 16
TEST_GROUP_STRATEGY: ROUND_ROBIN
XDIST_WORKERS: 2
XDIST_PER_WORKER_SNUBA: '1'
steps:
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Download snuba-ci image from artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: snuba-ci
path: /tmp
- name: Load snuba-ci image
run: |
docker load --input /tmp/snuba-ci.tar
docker image ls -a
- name: Checkout sentry
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
repository: getsentry/sentry
path: sentry
- name: Setup steps
id: setup
run: |
# We cannot execute actions that are not placed under .github of the main repo
mkdir -p .github/actions
cp -r sentry/.github/actions/* .github/actions
- name: Setup Sentry
id: setup-sentry
uses: ./.github/actions/setup-sentry
with:
workdir: sentry
mode: minimal
- name: Start snuba
run: |
# TODO(hubertdeng123): New devservices doesn't support running sentry without snuba yet, remove this when it does
docker stop snuba-snuba-1
docker rm snuba-snuba-1
docker run -d --rm \
-p 127.0.0.1:1218:1218 \
-e PYTHONUNBUFFERED=1 \
-e SNUBA_SETTINGS=docker \
-e DEBUG=1 \
-e DEFAULT_BROKERS=kafka:9093 \
-e CLICKHOUSE_HOST=clickhouse \
-e CLICKHOUSE_PORT=9000 \
-e CLICKHOUSE_HTTP_PORT=8123 \
-e REDIS_HOST=redis \
-e REDIS_PORT=6379 \
-e REDIS_DB=1 \
--name snuba-snuba-1 \
--network devservices \
ghcr.io/getsentry/snuba-ci:${{ github.event.pull_request.head.sha || github.sha }}
docker exec snuba-snuba-1 snuba migrations migrate --force
- name: Bootstrap per-worker Snuba instances
run: python3 sentry/.github/workflows/scripts/bootstrap-snuba.py
- name: Run snuba tests
if: needs.files-changed.outputs.api_changes == 'false'
working-directory: sentry
run: |
# Only these dirs carry the `snuba_ci` marker; collecting all of tests/ just to find them is wasteful.
pytest -k 'not __In' \
tests/sentry/snuba \
tests/sentry/workflow_engine/endpoints \
tests/snuba/rules/conditions \
-m snuba_ci \
-n "$XDIST_WORKERS" --dist=loadfile --reuse-db \
-vv
- name: Run full tests
if: needs.files-changed.outputs.api_changes == 'true'
working-directory: sentry
run: |
pytest -k 'not __In' \
tests/snuba \
tests/sentry/snuba \
tests/sentry/eventstream/kafka \
tests/sentry/post_process_forwarder \
tests/sentry/services/eventstore/snuba \
tests/sentry/search/events \
tests/sentry/event_manager \
tests/sentry/api/endpoints/test_organization_profiling_functions.py \
tests/sentry/integrations/slack/test_unfurl.py \
tests/sentry/uptime/endpoints/test_project_uptime_alert_check_index.py \
tests/sentry/uptime/endpoints/test_organization_uptime_stats.py \
tests/sentry/api/endpoints/test_organization_traces.py \
tests/sentry/api/endpoints/test_organization_spans_fields.py \
tests/sentry/sentry_metrics/querying \
-n "$XDIST_WORKERS" --dist=loadfile --reuse-db \
-vv
- name: Run CI module tests
if: needs.files-changed.outputs.api_changes == 'true'
working-directory: sentry
run: |
pytest -k 'not __In' \
tests/sentry/snuba \
tests/sentry/workflow_engine/endpoints \
tests/snuba/rules/conditions \
-m snuba_ci \
-n "$XDIST_WORKERS" --dist=loadfile --reuse-db \
-vv
clickhouse-versions:
needs: [linting, snuba-image, docker-deps]
name: Tests on multiple clickhouse versions
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
version:
[
"25.3.8.10041.altinitystable",
"25.8.16.10001.altinitystable",
]
test_type: [snuba-test, snuba-test-migrations]
steps:
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Download snuba-ci image from artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: snuba-ci
path: /tmp
- name: Load snuba-ci image
run: |
docker load --input /tmp/snuba-ci.tar
docker image ls -a
- name: Restore Docker dependency image cache
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: /tmp/docker-deps
key: docker-deps-${{ hashFiles('docker-compose.gcb.yml') }}-${{ github.run_id }}
restore-keys: docker-deps-${{ hashFiles('docker-compose.gcb.yml') }}-
- name: Load Docker dependency images
run: |
if [ -f /tmp/docker-deps/deps.tar ]; then
docker load --input /tmp/docker-deps/deps.tar
fi
images=(
"ghcr.io/getsentry/image-mirror-altinity-clickhouse-server:${{ matrix.version }}"
"ghcr.io/getsentry/image-mirror-confluentinc-cp-kafka:6.2.0"
"ghcr.io/getsentry/image-mirror-confluentinc-cp-zookeeper:6.2.0"
"ghcr.io/getsentry/docker-redis-cluster:7.0.10"
)
for image in "${images[@]}"; do
if ! docker image inspect "$image" &>/dev/null; then
docker pull "$image"
fi
done
- name: Docker set up
run: |
docker network create --attachable cloudbuild
- name: Docker Snuba Test other ClickHouse versions
run: |
export CLICKHOUSE_IMAGE=ghcr.io/getsentry/image-mirror-altinity-clickhouse-server:${{matrix.version}}
SNUBA_IMAGE=ghcr.io/getsentry/snuba-ci:${{ github.event.pull_request.head.sha || github.sha }} SNUBA_SETTINGS=test docker compose -f docker-compose.gcb.yml run --rm ${{ matrix.test_type }}
- name: Upload to codecov
run: |
curl -Os https://uploader.codecov.io/latest/linux/codecov && chmod +x codecov && ./codecov -t ${CODECOV_TOKEN}
distroless-smoke-test:
name: Distroless image smoke test
needs: [snuba-image]
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Build distroless image
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
target: application-distroless
load: true
tags: snuba-distroless:test
cache-from: type=registry,ref=ghcr.io/getsentry/snuba-ci:buildcache
- name: Verify --help works
run: docker run --rm snuba-distroless:test --help
- name: Verify subcommand resolution (api)
# Exercises the docker_entrypoint.py path where args[0] does NOT
# start with "-". This is the default self-hosted snuba-api
# invocation and the path that previously fell through to a
# FileNotFoundError when the snuba --help probe timed out.
run: docker run --rm snuba-distroless:test api --help
- name: Verify subcommand resolution (rust-consumer)
# rust-consumer is what every self-hosted consumer service runs.
run: docker run --rm snuba-distroless:test rust-consumer --help
- name: Verify Python imports
run: |
docker run --rm --entrypoint python3 snuba-distroless:test \
-c "import snuba, rust_snuba, confluent_kafka; print('OK')"
- name: Verify jemalloc LD_PRELOAD is active
run: |
docker run --rm --entrypoint python3 snuba-distroless:test \
-c "import ctypes; ctypes.CDLL('libjemalloc.so.2'); print('jemalloc OK')"
- name: Verify no shell available
run: |
# This should fail — distroless has no /bin/sh
if docker run --rm --entrypoint /bin/sh snuba-distroless:test -c "echo hi" 2>/dev/null; then
echo "ERROR: /bin/sh should not be available in distroless image"
exit 1
else
echo "OK: /bin/sh is not available"
fi
validate-devservices-config:
runs-on: ubuntu-24.04
needs: files-changed
if: ${{ needs.files-changed.outputs.devservices_changes == 'true' }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
name: Checkout repository
- name: Get devservices version
id: get-devservices-version
run: |
awk -F'"' '
/name/ { pkg = $2 }
/version/ { if (pkg == "devservices") print "version="$2 }
' uv.lock >> $GITHUB_OUTPUT
- uses: getsentry/action-validate-devservices-config@711ae7221998ddf81211f25f5e3873ecffd22387
name: Validate devservices config
with:
devservices-version: ${{ steps.get-devservices-version.outputs.version }}