feat(hub): URL-keyed knowledge surface + CHAOSS metrics dashboard + Overview polish #44
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: 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@a9c7b0f06e461e9d4b4d1711f154ee024b8d7ab8 # 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}`); | |
| } |