chore(deps)(deps): bump bullmq from 5.79.3 to 5.80.2 in /apps/api in the bullmq group #440
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
| name: validate-compose | |
| # Validates every docker-compose YAML and every meaningful overlay | |
| # combination — without actually building images or booting services. | |
| # Catches syntax errors, missing env vars, malformed Traefik labels, and | |
| # overlay-merge regressions before they hit a developer's `up`. | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - "infra/compose/**" | |
| # Root gate scripts are validated here (shellcheck job) — keep the | |
| # trigger in lockstep so direct pushes touching them still run it. | |
| - "scripts/**" | |
| - "setup.sh" | |
| # The yamllint job lints every workflow file, so any workflow edit | |
| # must trigger this run — not just edits to this file. | |
| - ".github/workflows/**" | |
| # Prod Dockerfiles COPY the whole app context, so any app source | |
| # change can break the prod image build — not just Dockerfile or | |
| # lockfile edits. | |
| - "apps/api/**" | |
| - "apps/ui/**" | |
| pull_request: | |
| branches: [main] | |
| concurrency: | |
| group: infra-compose-validate-compose-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| compose-config: | |
| name: docker compose config (all overlay combinations) | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 5 | |
| # Build contexts point at monorepo apps (`../../../apps/api` and | |
| # `../../../apps/ui` from infra/compose/compose). | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Detect relevant changes | |
| uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 | |
| id: filter | |
| with: | |
| filters: | | |
| code: | |
| - 'infra/compose/**' | |
| - 'scripts/**' | |
| - '.github/workflows/**' | |
| - name: Seed .env | |
| if: steps.filter.outputs.code == 'true' | |
| working-directory: infra/compose/compose | |
| run: | | |
| cp .env.example .env | |
| # Required for STACK=prod + WITH_GLITCHTIP combinations: | |
| echo "GLITCHTIP_SECRET_KEY=$(openssl rand -base64 50 | tr -d '\n')" >> .env | |
| echo "GLITCHTIP_PUBLIC_HOST=glitchtip.example.com" >> .env | |
| echo "GLITCHTIP_BASIC_AUTH_USERS=user:placeholder" >> .env | |
| echo "GLITCHTIP_SUPERUSER_PASSWORD=$(openssl rand -base64 24 | tr -d '/+=')" >> .env | |
| echo "GRAFANA_ADMIN_PASSWORD=$(openssl rand -base64 24 | tr -d '/+=')" >> .env | |
| - name: Validate — dev (base) | |
| if: steps.filter.outputs.code == 'true' | |
| working-directory: infra/compose/compose | |
| run: | | |
| docker compose \ | |
| -f docker-compose.yml \ | |
| -f docker-compose.development-labels.yml \ | |
| --profile dev config --quiet | |
| - name: Validate — prod (base) | |
| if: steps.filter.outputs.code == 'true' | |
| working-directory: infra/compose/compose | |
| run: | | |
| docker compose \ | |
| -f docker-compose.yml \ | |
| -f docker-compose.production-labels.yml \ | |
| --profile prod config --quiet | |
| # Guardrail: every long-running prod-profile service in the base | |
| # compose file must define a healthcheck so `up --wait` and | |
| # service_healthy dependents have a readiness signal. One-shot jobs | |
| # (restart: "no", e.g. api-migrate-prod) exit by design and are | |
| # exempt; overlays ship sidecars and are not scanned. | |
| - name: Guardrail — prod services define healthchecks | |
| if: steps.filter.outputs.code == 'true' | |
| # Single-source: the same script runs in the local pre-push gate, | |
| # so CI and local guardrails cannot drift. | |
| run: ../scripts/validate-guardrails.sh healthchecks | |
| working-directory: infra/compose/compose | |
| - name: Guardrail — compose images digest-pinned, no floating latest | |
| if: steps.filter.outputs.code == 'true' | |
| # Single-source: the same script runs in the local pre-push gate, | |
| # so CI and local guardrails cannot drift. | |
| run: ../scripts/validate-guardrails.sh digest-pins | |
| working-directory: infra/compose/compose | |
| - name: Guardrail — no hardcoded credential fallbacks in compose | |
| if: steps.filter.outputs.code == 'true' | |
| # Single-source: the same script runs in the local pre-push gate, | |
| # so CI and local guardrails cannot drift. | |
| run: ../scripts/validate-guardrails.sh credential-fallbacks | |
| working-directory: infra/compose/compose | |
| - name: Guardrail — valkey enforces auth and prod requires the password | |
| if: steps.filter.outputs.code == 'true' | |
| # Single-source: the same script runs in the local pre-push gate, | |
| # so CI and local guardrails cannot drift. | |
| run: ../scripts/validate-guardrails.sh valkey-auth | |
| working-directory: infra/compose/compose | |
| - name: Guardrail — rooted prod services must drop capabilities | |
| if: steps.filter.outputs.code == 'true' | |
| # Single-source: the same script runs in the local pre-push gate, | |
| # so CI and local guardrails cannot drift. | |
| run: ../scripts/validate-guardrails.sh rooted-caps | |
| working-directory: infra/compose/compose | |
| - name: Guardrail — every service blocks privilege escalation | |
| if: steps.filter.outputs.code == 'true' | |
| # Single-source: the same script runs in the local pre-push gate, | |
| # so CI and local guardrails cannot drift. | |
| run: ../scripts/validate-guardrails.sh no-new-privileges | |
| working-directory: infra/compose/compose | |
| - name: Guardrail — long-running services reserve resources (no starvation) | |
| if: steps.filter.outputs.code == 'true' | |
| # Single-source: the same script runs in the local pre-push gate, | |
| # so CI and local guardrails cannot drift. | |
| run: ../scripts/validate-guardrails.sh resource-reservations | |
| working-directory: infra/compose/compose | |
| - name: Guardrail — prod rejects unpinned image tags (dev.sh fail-closed) | |
| if: steps.filter.outputs.code == 'true' | |
| # Single-source: the same script runs in the local pre-push gate, | |
| # so CI and local guardrails cannot drift. | |
| run: ../scripts/validate-guardrails.sh prod-image-tags | |
| working-directory: infra/compose/compose | |
| - name: Validate — dev + observability | |
| if: steps.filter.outputs.code == 'true' | |
| working-directory: infra/compose/compose | |
| run: | | |
| docker compose \ | |
| -f docker-compose.yml \ | |
| -f docker-compose.development-labels.yml \ | |
| -f docker-compose.observability.yml \ | |
| --profile dev --profile observability config --quiet | |
| - name: Validate — dev + glitchtip | |
| if: steps.filter.outputs.code == 'true' | |
| working-directory: infra/compose/compose | |
| run: | | |
| docker compose \ | |
| -f docker-compose.yml \ | |
| -f docker-compose.development-labels.yml \ | |
| -f docker-compose.glitchtip.yml \ | |
| --profile dev --profile glitchtip-dev config --quiet | |
| - name: Validate — prod + glitchtip (+ prod labels) | |
| if: steps.filter.outputs.code == 'true' | |
| working-directory: infra/compose/compose | |
| run: | | |
| docker compose \ | |
| -f docker-compose.yml \ | |
| -f docker-compose.production-labels.yml \ | |
| -f docker-compose.glitchtip.yml \ | |
| -f docker-compose.glitchtip-prod-labels.yml \ | |
| --profile prod --profile glitchtip-prod config --quiet | |
| - name: Validate — dev + bullmq | |
| if: steps.filter.outputs.code == 'true' | |
| working-directory: infra/compose/compose | |
| run: | | |
| docker compose \ | |
| -f docker-compose.yml \ | |
| -f docker-compose.development-labels.yml \ | |
| -f docker-compose.bullmq.yml \ | |
| --profile dev --profile bullmq config --quiet | |
| - name: Validate — dev + wud | |
| if: steps.filter.outputs.code == 'true' | |
| working-directory: infra/compose/compose | |
| run: | | |
| docker compose \ | |
| -f docker-compose.yml \ | |
| -f docker-compose.development-labels.yml \ | |
| -f docker-compose.wud.yml \ | |
| --profile dev --profile wud config --quiet | |
| - name: Validate — kitchen-sink (dev + all overlays) | |
| if: steps.filter.outputs.code == 'true' | |
| working-directory: infra/compose/compose | |
| run: | | |
| docker compose \ | |
| -f docker-compose.yml \ | |
| -f docker-compose.development-labels.yml \ | |
| -f docker-compose.observability.yml \ | |
| -f docker-compose.glitchtip.yml \ | |
| -f docker-compose.bullmq.yml \ | |
| -f docker-compose.wud.yml \ | |
| --profile dev \ | |
| --profile observability \ | |
| --profile glitchtip-dev \ | |
| --profile bullmq \ | |
| --profile wud \ | |
| config --quiet | |
| shellcheck: | |
| name: shellcheck (scripts/) | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 2 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Detect relevant changes | |
| uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 | |
| id: filter | |
| with: | |
| filters: | | |
| code: | |
| - 'infra/compose/**' | |
| - 'scripts/**' | |
| - 'setup.sh' | |
| - '.github/workflows/**' | |
| - name: ShellCheck | |
| if: steps.filter.outputs.code == 'true' | |
| run: | | |
| # Strict: error on warnings, follow `source` directives. | |
| # Root gate scripts (scripts/ci/*, stack-*.sh, setup.sh) are the | |
| # repo's primary local defense — they get the same bar as infra. | |
| shellcheck -x -S warning \ | |
| infra/compose/compose/dev.sh \ | |
| infra/compose/scripts/*.sh \ | |
| scripts/*.sh \ | |
| scripts/ci/*.sh \ | |
| setup.sh | |
| prod-image-build: | |
| name: build prod images (sanity) | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 15 | |
| # Cheaper than booting the prod profile end-to-end, but still | |
| # exercises the actual prod Dockerfiles. Catches broken | |
| # multi-stage builds, missing build deps, or registry-auth | |
| # changes before main, instead of leaving the first breakage to | |
| # the post-merge release workflow. | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Detect relevant changes | |
| uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 | |
| id: filter | |
| with: | |
| filters: | | |
| code: | |
| # Dockerfile.prod runs COPY . . — the whole app tree is | |
| # image input, so app-only source changes must rebuild too. | |
| - 'apps/api/**' | |
| - 'apps/ui/**' | |
| - 'infra/compose/**' | |
| - '.github/workflows/infra-compose-validate-compose.yml' | |
| - name: Set up Docker Buildx | |
| if: steps.filter.outputs.code == 'true' | |
| uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 | |
| - name: Build apps/api prod image | |
| if: steps.filter.outputs.code == 'true' | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 | |
| with: | |
| context: apps/api | |
| file: apps/api/Dockerfile.prod | |
| push: false | |
| load: true | |
| tags: boringstack-api:pr-build | |
| cache-from: type=gha,scope=apps-api-prod | |
| cache-to: type=gha,scope=apps-api-prod,mode=max | |
| - name: Build apps/ui prod image | |
| if: steps.filter.outputs.code == 'true' | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 | |
| with: | |
| context: apps/ui | |
| file: apps/ui/Dockerfile.prod | |
| push: false | |
| load: true | |
| tags: boringstack-ui:pr-build | |
| cache-from: type=gha,scope=apps-ui-prod | |
| cache-to: type=gha,scope=apps-ui-prod,mode=max | |
| build-args: | | |
| VITE_API_URL=https://api.example.test | |
| yamllint: | |
| name: yamllint (compose + workflows) | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 2 | |
| env: | |
| # Single source for the yamllint pin — the local pre-push gate | |
| # (infra/compose/scripts/pre-push.sh) reads this value at runtime to | |
| # warn when the brew-installed yamllint diverges from CI. | |
| YAMLLINT_VERSION: "1.38.0" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Detect relevant changes | |
| uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 | |
| id: filter | |
| with: | |
| filters: | | |
| code: | |
| - 'infra/compose/**' | |
| - 'scripts/**' | |
| - '.github/workflows/**' | |
| - name: yamllint | |
| if: steps.filter.outputs.code == 'true' | |
| run: | | |
| pip install --user "yamllint==${YAMLLINT_VERSION}" | |
| # Document syntax (line length, indentation, truthy values) but | |
| # don't fail on style nits — only on real syntax errors. | |
| ~/.local/bin/yamllint -d "{extends: relaxed, rules: {line-length: disable}}" \ | |
| infra/compose/compose/ .github/workflows/ |