Skip to content

feat: integrate all services #24

feat: integrate all services

feat: integrate all services #24

name: Docker Validate and Security
on:
pull_request:
paths:
- "infra/compose/docker-compose.yml"
- "infra/compose/docker-compose.cli.yml"
- "infra/compose/**"
- "tools/images/**"
- ".devcontainer/**"
- "pyproject.toml"
- "uv.lock"
- ".github/workflows/docker-validate.yml"
push:
branches:
- main
- "release/**"
paths:
- "infra/compose/docker-compose.yml"
- "infra/compose/docker-compose.cli.yml"
- "infra/compose/**"
- "tools/images/**"
- ".devcontainer/**"
- "pyproject.toml"
- "uv.lock"
- ".github/workflows/docker-validate.yml"
permissions:
contents: read
security-events: write
concurrency:
group: docker-validate-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
# Force JS actions onto Node 24 ahead of the June 2026 GHA default flip.
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
jobs:
compose-config-validation:
name: Compose config validation
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
compose_files:
- "-f infra/compose/docker-compose.yml"
- "-f infra/compose/docker-compose.yml -f infra/compose/docker-compose.cli.yml"
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Validate Compose manifests
run: docker compose ${{ matrix.compose_files }} config > /dev/null
docker-build-and-scan:
name: Build and scan (${{ matrix.image.name }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
image:
- name: open-pulse
context: .
dockerfile: tools/images/Dockerfile-open-pulse
vuln_type: os,library
exit_code: "1"
- name: devcontainer
context: .devcontainer
dockerfile: .devcontainer/Dockerfile
vuln_type: os
exit_code: "0"
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build image
uses: docker/build-push-action@v6
with:
context: ${{ matrix.image.context }}
file: ${{ matrix.image.dockerfile }}
load: true
tags: open-pulse/${{ matrix.image.name }}:ci
- name: Scan image (critical threshold)
uses: aquasecurity/trivy-action@0.34.2
with:
scan-type: image
image-ref: open-pulse/${{ matrix.image.name }}:ci
format: table
output: trivy-${{ matrix.image.name }}.txt
severity: CRITICAL
ignore-unfixed: true
vuln-type: ${{ matrix.image.vuln_type }}
scanners: vuln
exit-code: ${{ matrix.image.exit_code }}
token-setup-trivy: ${{ github.token }}
- name: Generate SARIF report
if: always()
uses: aquasecurity/trivy-action@0.34.2
with:
scan-type: image
image-ref: open-pulse/${{ matrix.image.name }}:ci
format: sarif
output: trivy-${{ matrix.image.name }}.sarif
severity: CRITICAL
ignore-unfixed: true
vuln-type: ${{ matrix.image.vuln_type }}
scanners: vuln
exit-code: "0"
token-setup-trivy: ${{ github.token }}
- name: Upload SARIF to GitHub Security
if: always() && github.event_name != 'pull_request'
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-${{ matrix.image.name }}.sarif
category: trivy-${{ matrix.image.name }}
- name: Upload Trivy artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: trivy-${{ matrix.image.name }}
path: |
trivy-${{ matrix.image.name }}.txt
trivy-${{ matrix.image.name }}.sarif
if-no-files-found: error
- name: Write job summary
if: always()
run: |
{
echo "## Docker validation summary (${{ matrix.image.name }})"
echo "- Built image: \`open-pulse/${{ matrix.image.name }}:ci\`"
echo "- Vulnerability scope: \`${{ matrix.image.vuln_type }}\`"
echo "- Blocking gate: \`exit-code=${{ matrix.image.exit_code }}\` (fail on CRITICAL when set to 1)"
echo "- Artifacts: \`trivy-${{ matrix.image.name }}\`"
} >> "$GITHUB_STEP_SUMMARY"