chore(deps): bump activestorage from 8.0.2.1 to 8.0.4.1 in /docker/pghero/app #277
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # SPDX-FileCopyrightText: 2025 Blackcat Informatics® Inc. | |
| # SPDX-License-Identifier: MIT | |
| name: CI | |
| permissions: | |
| contents: read | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| jobs: | |
| docker-build: | |
| name: Validate Docker Build | |
| runs-on: ubuntu-latest | |
| outputs: | |
| stack_tag: ${{ steps.stack-build.outputs.stack_tag }} | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v4 | |
| - name: Reset secrets directory | |
| run: rm -rf ./secrets && mkdir -p ./secrets | |
| - name: Generate .env and secrets | |
| run: ./scripts/manage.sh create-env --non-interactive --force | |
| - name: Export build env | |
| run: | | |
| set -a | |
| source .env | |
| set +a | |
| { | |
| echo "POSTGRES_UID=${POSTGRES_UID:-$(id -u)}" | |
| echo "POSTGRES_GID=${POSTGRES_GID:-$(id -g)}" | |
| echo "POSTGRES_RUNTIME_USER=${POSTGRES_RUNTIME_USER:-postgres}" | |
| echo "POSTGRES_RUNTIME_GECOS=${POSTGRES_RUNTIME_GECOS:-Core Data PostgreSQL Administrator}" | |
| echo "POSTGRES_RUNTIME_HOME=${POSTGRES_RUNTIME_HOME:-/home/postgres}" | |
| echo "PG_VERSION=${PG_VERSION:-17}" | |
| echo "AGE_VERSION=${AGE_VERSION:-master}" | |
| } >> "$GITHUB_ENV" | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Build stack images | |
| id: stack-build | |
| env: | |
| STACK_REGISTRY: ghcr.io/${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| STACK_TAG="${GITHUB_SHA}" | |
| echo "stack_tag=${STACK_TAG}" >>"$GITHUB_OUTPUT" | |
| SERVICES=("postgres" "valkey" "pgbouncer" "rabbitmq" "memcached" "pghero" "network-probe" "network-guard") | |
| mkdir -p stack-images | |
| for service in "${SERVICES[@]}"; do | |
| case "${service}" in | |
| postgres) | |
| docker buildx build --load \ | |
| --platform linux/amd64 \ | |
| --file postgres/Dockerfile \ | |
| --build-arg CORE_UID="${POSTGRES_UID:-$(id -u)}" \ | |
| --build-arg CORE_GID="${POSTGRES_GID:-$(id -g)}" \ | |
| --build-arg CORE_USERNAME="${POSTGRES_RUNTIME_USER:-postgres}" \ | |
| --build-arg CORE_GECOS="${POSTGRES_RUNTIME_GECOS:-Core Data PostgreSQL Administrator}" \ | |
| --build-arg CORE_HOME="${POSTGRES_RUNTIME_HOME:-/home/postgres}" \ | |
| --build-arg PG_VERSION="${PG_VERSION:-17}" \ | |
| --build-arg AGE_VERSION="${AGE_VERSION:-master}" \ | |
| --tag "${STACK_REGISTRY}/${service}:${STACK_TAG}" \ | |
| . | |
| ;; | |
| valkey) | |
| docker buildx build --load \ | |
| --platform linux/amd64 \ | |
| --file docker/valkey/Dockerfile \ | |
| --tag "${STACK_REGISTRY}/${service}:${STACK_TAG}" \ | |
| . | |
| ;; | |
| pgbouncer) | |
| docker buildx build --load \ | |
| --platform linux/amd64 \ | |
| --file docker/pgbouncer/Dockerfile \ | |
| --tag "${STACK_REGISTRY}/${service}:${STACK_TAG}" \ | |
| . | |
| ;; | |
| rabbitmq) | |
| docker buildx build --load \ | |
| --platform linux/amd64 \ | |
| --file docker/rabbitmq/Dockerfile \ | |
| --tag "${STACK_REGISTRY}/${service}:${STACK_TAG}" \ | |
| . | |
| ;; | |
| memcached) | |
| docker buildx build --load \ | |
| --platform linux/amd64 \ | |
| --file docker/memcached/Dockerfile \ | |
| --tag "${STACK_REGISTRY}/${service}:${STACK_TAG}" \ | |
| . | |
| ;; | |
| pghero) | |
| docker buildx build --load \ | |
| --platform linux/amd64 \ | |
| --file docker/pghero/Dockerfile \ | |
| --tag "${STACK_REGISTRY}/${service}:${STACK_TAG}" \ | |
| . | |
| ;; | |
| network-probe) | |
| docker buildx build --load \ | |
| --platform linux/amd64 \ | |
| --file docker/network-probe/Dockerfile \ | |
| --tag "${STACK_REGISTRY}/${service}:${STACK_TAG}" \ | |
| . | |
| ;; | |
| network-guard) | |
| docker buildx build --load \ | |
| --platform linux/amd64 \ | |
| --file docker/network-guard/Dockerfile \ | |
| --tag "${STACK_REGISTRY}/${service}:${STACK_TAG}" \ | |
| . | |
| ;; | |
| esac | |
| docker save "${STACK_REGISTRY}/${service}:${STACK_TAG}" -o "stack-images/${service}.tar" | |
| done | |
| { | |
| echo "CORE_DATA_STACK_TAG=${STACK_TAG}" | |
| echo "CORE_DATA_STACK_REGISTRY=${STACK_REGISTRY}" | |
| echo "POSTGRES_IMAGE_NAME=${STACK_REGISTRY}/postgres" | |
| echo "POSTGRES_IMAGE_TAG=${STACK_TAG}" | |
| echo "CORE_DATA_IMAGE=${STACK_REGISTRY}/postgres" | |
| echo "CORE_DATA_TAG=${STACK_TAG}" | |
| echo "VALKEY_IMAGE=${STACK_REGISTRY}/valkey:${STACK_TAG}" | |
| echo "PGBOUNCER_IMAGE=${STACK_REGISTRY}/pgbouncer:${STACK_TAG}" | |
| echo "RABBITMQ_IMAGE=${STACK_REGISTRY}/rabbitmq:${STACK_TAG}" | |
| echo "MEMCACHED_IMAGE=${STACK_REGISTRY}/memcached:${STACK_TAG}" | |
| echo "PGHERO_IMAGE=${STACK_REGISTRY}/pghero:${STACK_TAG}" | |
| echo "NETWORK_PROBE_IMAGE=${STACK_REGISTRY}/network-probe:${STACK_TAG}" | |
| echo "NETWORK_GUARD_IMAGE=${STACK_REGISTRY}/network-guard:${STACK_TAG}" | |
| } >>"$GITHUB_ENV" | |
| - name: Smoke-test Docker image | |
| env: | |
| PGPASSWORD: thinice-test | |
| run: | | |
| set -euo pipefail | |
| set -a | |
| source .env | |
| set +a | |
| cleanup() { docker rm -f postgres-smoke >/dev/null 2>&1 || true; } | |
| trap cleanup EXIT | |
| image="${POSTGRES_IMAGE_NAME}:${POSTGRES_IMAGE_TAG}" | |
| docker run -d --name postgres-smoke \ | |
| -e POSTGRES_USER=thinice-test \ | |
| -e POSTGRES_PASSWORD=thinice-test \ | |
| -e POSTGRES_DB=thinice-test \ | |
| -e CORE_DATA_SKIP_CONFIG_RENDER=1 \ | |
| "${image}" | |
| tries=0 | |
| max_tries=150 | |
| until docker exec postgres-smoke pg_isready -h localhost -U thinice-test >/dev/null 2>&1; do | |
| tries=$((tries + 1)) | |
| if ((tries >= max_tries)); then | |
| echo "[smoke] postgres-smoke never became ready; printing logs." | |
| docker logs postgres-smoke || true | |
| exit 1 | |
| fi | |
| sleep 2 | |
| done | |
| docker exec postgres-smoke psql -U thinice-test -d thinice-test -c "SELECT 1" >/dev/null | |
| - name: Stop Docker smoke container | |
| if: always() | |
| run: docker rm -f postgres-smoke >/dev/null 2>&1 || true | |
| - name: Upload stack image artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: stack-images | |
| path: stack-images | |
| - name: Collect diagnostics bundle | |
| if: failure() | |
| run: ./scripts/collect_diagnostics.sh --output diagnostics-docker-build | |
| - name: Upload diagnostics bundle | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: diagnostics-docker-build | |
| path: diagnostics-docker-build | |
| - name: Validate Dockerfile with hadolint | |
| uses: hadolint/hadolint-action@v3.1.0 | |
| with: | |
| dockerfile: postgres/Dockerfile | |
| config: .hadolint.yaml | |
| smoke: | |
| name: Smoke (${{ matrix.profile_name }}) | |
| runs-on: ubuntu-latest | |
| needs: | |
| - docker-build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - profile_name: full | |
| compose_profiles: "valkey,pgbouncer,memcached" | |
| - profile_name: minimal | |
| compose_profiles: "" | |
| env: | |
| TEST_COMPOSE_PROFILES: ${{ matrix.compose_profiles }} | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v4 | |
| - name: Reset secrets directory | |
| run: rm -rf ./secrets && mkdir -p ./secrets | |
| - name: Generate .env and secrets | |
| run: ./scripts/manage.sh create-env --non-interactive --force | |
| - name: Download stack images | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: stack-images | |
| path: stack-images | |
| - name: Load stack images | |
| run: for image_tar in stack-images/*.tar; do docker load --input "$image_tar"; done | |
| - name: Pin stack images | |
| run: | | |
| cat <<'EOF' >> .env | |
| CORE_DATA_STACK_REGISTRY=ghcr.io/${{ github.repository }} | |
| CORE_DATA_STACK_TAG=${{ needs.docker-build.outputs.stack_tag }} | |
| POSTGRES_IMAGE_NAME=ghcr.io/${{ github.repository }}/postgres | |
| POSTGRES_IMAGE_TAG=${{ needs.docker-build.outputs.stack_tag }} | |
| CORE_DATA_IMAGE=ghcr.io/${{ github.repository }}/postgres | |
| CORE_DATA_TAG=${{ needs.docker-build.outputs.stack_tag }} | |
| VALKEY_IMAGE=ghcr.io/${{ github.repository }}/valkey:${{ needs.docker-build.outputs.stack_tag }} | |
| PGBOUNCER_IMAGE=ghcr.io/${{ github.repository }}/pgbouncer:${{ needs.docker-build.outputs.stack_tag }} | |
| RABBITMQ_IMAGE=ghcr.io/${{ github.repository }}/rabbitmq:${{ needs.docker-build.outputs.stack_tag }} | |
| MEMCACHED_IMAGE=ghcr.io/${{ github.repository }}/memcached:${{ needs.docker-build.outputs.stack_tag }} | |
| PGHERO_IMAGE=ghcr.io/${{ github.repository }}/pghero:${{ needs.docker-build.outputs.stack_tag }} | |
| NETWORK_PROBE_IMAGE=ghcr.io/${{ github.repository }}/network-probe:${{ needs.docker-build.outputs.stack_tag }} | |
| NETWORK_GUARD_IMAGE=ghcr.io/${{ github.repository }}/network-guard:${{ needs.docker-build.outputs.stack_tag }} | |
| EOF | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Cache uv | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/uv | |
| key: ${{ runner.os }}-uv-3.12-${{ hashFiles('pyproject.toml', 'uv.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-uv-3.12- | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v2 | |
| - name: Sync dependencies | |
| run: uv sync --dev | |
| - name: Preflight stack bring-up | |
| id: bringup-smoke | |
| run: | | |
| set -euo pipefail | |
| cleanup() { ./scripts/manage.sh down >/dev/null 2>&1 || true; } | |
| trap cleanup EXIT | |
| if ! ./scripts/manage.sh up; then | |
| mkdir -p bringup-logs | |
| docker compose logs postgres | tee bringup-logs/postgres.log || true | |
| docker compose logs pgbouncer | tee bringup-logs/pgbouncer.log || true | |
| docker compose logs valkey | tee bringup-logs/valkey.log || true | |
| docker compose logs rabbitmq | tee bringup-logs/rabbitmq.log || true | |
| exit 1 | |
| fi | |
| - name: Run core_data smoke workflow | |
| run: uv run python -m pytest -k full_workflow --junitxml=report-smoke-${{ matrix.profile_name }}.xml | |
| - name: Collect docker diagnostics | |
| if: always() | |
| run: | | |
| mkdir -p diagnostics-smoke-${{ matrix.profile_name }} | |
| docker ps -a > diagnostics-smoke-${{ matrix.profile_name }}/docker-ps.txt | |
| docker compose logs > diagnostics-smoke-${{ matrix.profile_name }}/docker-compose.log || true | |
| ./scripts/collect_diagnostics.sh --output diagnostics-smoke-${{ matrix.profile_name }}/bundle || true | |
| - name: Upload diagnostics bundle | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: diagnostics-smoke-${{ matrix.profile_name }} | |
| path: diagnostics-smoke-${{ matrix.profile_name }} | |
| - name: Upload generated backups | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: backups-${{ matrix.profile_name }} | |
| path: backups | |
| if-no-files-found: ignore | |
| - name: Upload smoke JUnit report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: report-smoke-${{ matrix.profile_name }} | |
| path: report-smoke-${{ matrix.profile_name }}.xml | |
| - name: Publish smoke summary | |
| if: always() | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const profile = process.env.MATRIX_PROFILE; | |
| const reportPath = `report-smoke-${profile}.xml`; | |
| if (!fs.existsSync(reportPath)) { | |
| core.warning(`JUnit report not found at ${reportPath}`); | |
| } else { | |
| const report = fs.readFileSync(reportPath, 'utf8'); | |
| core.summary | |
| .addHeading(`Smoke (${profile})`) | |
| .addCodeBlock(report, 'xml') | |
| .write(); | |
| } | |
| env: | |
| MATRIX_PROFILE: ${{ matrix.profile_name }} | |
| - name: Upload bring-up logs | |
| if: failure() && steps.bringup-smoke.outcome == 'failure' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: bringup-logs-${{ matrix.profile_name }} | |
| path: bringup-logs | |
| markers: | |
| name: Marker (${{ matrix.marker }}) | |
| runs-on: ubuntu-latest | |
| needs: | |
| - docker-build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| marker: [security, backup, extensions, pool, pool_heavy, lint, config, ci] | |
| env: | |
| TEST_COMPOSE_PROFILES: "valkey,pgbouncer,memcached" | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v4 | |
| - name: Reset secrets directory | |
| run: rm -rf ./secrets && mkdir -p ./secrets | |
| - name: Generate .env and secrets | |
| run: ./scripts/manage.sh create-env --non-interactive --force | |
| - name: Download stack images | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: stack-images | |
| path: stack-images | |
| - name: Load stack images | |
| run: for image_tar in stack-images/*.tar; do docker load --input "$image_tar"; done | |
| - name: Pin stack images | |
| run: | | |
| cat <<'EOF' >> .env | |
| CORE_DATA_STACK_REGISTRY=ghcr.io/${{ github.repository }} | |
| CORE_DATA_STACK_TAG=${{ needs.docker-build.outputs.stack_tag }} | |
| POSTGRES_IMAGE_NAME=ghcr.io/${{ github.repository }}/postgres | |
| POSTGRES_IMAGE_TAG=${{ needs.docker-build.outputs.stack_tag }} | |
| CORE_DATA_IMAGE=ghcr.io/${{ github.repository }}/postgres | |
| CORE_DATA_TAG=${{ needs.docker-build.outputs.stack_tag }} | |
| VALKEY_IMAGE=ghcr.io/${{ github.repository }}/valkey:${{ needs.docker-build.outputs.stack_tag }} | |
| PGBOUNCER_IMAGE=ghcr.io/${{ github.repository }}/pgbouncer:${{ needs.docker-build.outputs.stack_tag }} | |
| RABBITMQ_IMAGE=ghcr.io/${{ github.repository }}/rabbitmq:${{ needs.docker-build.outputs.stack_tag }} | |
| MEMCACHED_IMAGE=ghcr.io/${{ github.repository }}/memcached:${{ needs.docker-build.outputs.stack_tag }} | |
| PGHERO_IMAGE=ghcr.io/${{ github.repository }}/pghero:${{ needs.docker-build.outputs.stack_tag }} | |
| NETWORK_PROBE_IMAGE=ghcr.io/${{ github.repository }}/network-probe:${{ needs.docker-build.outputs.stack_tag }} | |
| NETWORK_GUARD_IMAGE=ghcr.io/${{ github.repository }}/network-guard:${{ needs.docker-build.outputs.stack_tag }} | |
| EOF | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Cache uv | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/uv | |
| key: ${{ runner.os }}-uv-3.12-${{ hashFiles('pyproject.toml', 'uv.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-uv-3.12- | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v2 | |
| - name: Install shellcheck | |
| if: matrix.marker == 'lint' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y shellcheck | |
| - name: Sync dependencies | |
| run: uv sync --dev | |
| - name: Preflight stack bring-up | |
| if: matrix.marker != 'ci' | |
| id: bringup-marker | |
| run: | | |
| set -euo pipefail | |
| cleanup() { ./scripts/manage.sh down >/dev/null 2>&1 || true; } | |
| trap cleanup EXIT | |
| if ! ./scripts/manage.sh up; then | |
| mkdir -p bringup-logs | |
| docker compose logs postgres | tee bringup-logs/postgres.log || true | |
| docker compose logs pgbouncer | tee bringup-logs/pgbouncer.log || true | |
| docker compose logs valkey | tee bringup-logs/valkey.log || true | |
| docker compose logs rabbitmq | tee bringup-logs/rabbitmq.log || true | |
| exit 1 | |
| fi | |
| - name: Run marker tests | |
| run: uv run python -m pytest -m ${{ matrix.marker }} --junitxml=report-marker-${{ matrix.marker }}.xml | |
| - name: Collect docker diagnostics | |
| if: matrix.marker != 'ci' | |
| run: | | |
| mkdir -p diagnostics-marker-${{ matrix.marker }} | |
| docker ps -a > diagnostics-marker-${{ matrix.marker }}/docker-ps.txt | |
| docker compose logs > diagnostics-marker-${{ matrix.marker }}/docker-compose.log || true | |
| ./scripts/collect_diagnostics.sh --output diagnostics-marker-${{ matrix.marker }}/bundle || true | |
| - name: Upload diagnostics bundle | |
| if: matrix.marker != 'ci' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: diagnostics-marker-${{ matrix.marker }} | |
| path: diagnostics-marker-${{ matrix.marker }} | |
| - name: Upload bring-up logs | |
| if: matrix.marker != 'ci' && failure() && steps.bringup-marker.outcome == 'failure' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: bringup-logs-${{ matrix.marker }} | |
| path: bringup-logs | |
| - name: Upload marker JUnit report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: report-marker-${{ matrix.marker }} | |
| path: report-marker-${{ matrix.marker }}.xml | |
| - name: Publish marker summary | |
| if: always() | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const reportPath = `report-marker-${process.env.MATRIX_MARKER}.xml`; | |
| if (!fs.existsSync(reportPath)) { | |
| core.warning(`JUnit report not found at ${reportPath}`); | |
| } else { | |
| const report = fs.readFileSync(reportPath, 'utf8'); | |
| core.summary | |
| .addHeading(`Marker (${process.env.MATRIX_MARKER})`) | |
| .addCodeBlock(report, 'xml') | |
| .write(); | |
| } | |
| env: | |
| MATRIX_MARKER: ${{ matrix.marker }} |