Skip to content

ci(deps): bump aquasecurity/trivy-action from a9c7b0f06e461e9d4b4d1711f154ee024b8d7ab8 to ed142fd0673e97e23eac54620cfb913e5ce36c25 #26

ci(deps): bump aquasecurity/trivy-action from a9c7b0f06e461e9d4b4d1711f154ee024b8d7ab8 to ed142fd0673e97e23eac54620cfb913e5ce36c25

ci(deps): bump aquasecurity/trivy-action from a9c7b0f06e461e9d4b4d1711f154ee024b8d7ab8 to ed142fd0673e97e23eac54620cfb913e5ce36c25 #26

name: Docker Publish
on:
push:
branches:
- main
- develop
paths:
- "src/**"
- "pyproject.toml"
- "uv.lock"
- "tools/images/Dockerfile-open-pulse"
- ".github/workflows/docker-publish.yml"
pull_request:
types: [opened, synchronize, reopened, closed]
paths:
- "src/**"
- "pyproject.toml"
- "uv.lock"
- "tools/images/Dockerfile-open-pulse"
- ".github/workflows/docker-publish.yml"
workflow_dispatch:
permissions:
contents: read
packages: write
attestations: write
id-token: write
env:
REGISTRY: ghcr.io
# Path matches the OPEN_PULSE_IMAGE default in infra/open-pulse-stack/docker-compose.yml.
# Org is sdsc-ordes; package_name within the org is "open-pulse".
IMAGE_NAME: sdsc-ordes/open-pulse
PACKAGE_NAME: open-pulse
ORG: sdsc-ordes
# Force JS actions onto Node 24 ahead of the June 2026 GHA default flip.
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
concurrency:
group: docker-publish-${{ github.ref }}
cancel-in-progress: true
jobs:
build-and-push:
name: Build, scan and push
if: github.event_name != 'pull_request' || github.event.action != 'closed'
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up QEMU (multi-arch emulation)
uses: docker/setup-qemu-action@v3
with:
platforms: arm64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Compute tags
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push
id: build
uses: docker/build-push-action@v6
with:
context: .
file: tools/images/Dockerfile-open-pulse
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: mode=max
sbom: true
- name: Scan published image (CRITICAL — blocking)
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
scan-type: image
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}
format: table
severity: CRITICAL
ignore-unfixed: true
vuln-type: os,library
scanners: vuln
exit-code: "1"
token-setup-trivy: ${{ github.token }}
- name: Generate SBOM (SPDX)
uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0
with:
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}
format: spdx-json
output-file: sbom.spdx.json
upload-artifact: true
upload-artifact-retention: 30
- name: Attest build provenance
if: github.event_name != 'pull_request'
uses: actions/attest-build-provenance@v2
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
subject-digest: ${{ steps.build.outputs.digest }}
push-to-registry: true
cleanup-pr-image:
name: Cleanup PR image
if: github.event_name == 'pull_request' && github.event.action == 'closed'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Delete pr-<number> tag from GHCR
uses: actions/github-script@v8
with:
script: |
const owner = process.env.ORG;
const packageName = process.env.PACKAGE_NAME;
const prTag = `pr-${context.payload.pull_request.number}`;
try {
const { data: versions } = await github.rest.packages.getAllPackageVersionsForPackageOwnedByOrg({
package_type: 'container',
package_name: packageName,
org: owner,
per_page: 100
});
const prVersion = versions.find(version =>
version.metadata.container.tags.includes(prTag)
);
if (prVersion) {
console.log(`Deleting PR image: ${prTag} (version ID: ${prVersion.id})`);
await github.rest.packages.deletePackageVersionForOrg({
package_type: 'container',
package_name: packageName,
org: owner,
package_version_id: prVersion.id
});
console.log(`Successfully deleted PR image: ${prTag}`);
} else {
console.log(`No image found for PR: ${prTag}`);
}
} catch (error) {
console.log(`Error cleaning up PR image (this is normal if no image was built): ${error.message}`);
}