Skip to content

feat: emit remaining_ttl_ms on reserve and extend responses (v0.1.25.59) #226

feat: emit remaining_ttl_ms on reserve and extend responses (v0.1.25.59)

feat: emit remaining_ttl_ms on reserve and extend responses (v0.1.25.59) #226

name: Container Scan
# Runs Trivy against a locally-built image on PRs that change the Dockerfile
# or Maven dependencies, AND on every push to main with the same paths filter.
# Paths filter is deliberate: most PRs don't touch the image, and running this
# on every PR would add ~5-10 min of build time for no benefit.
#
# The push:main trigger ensures stale Trivy alerts auto-close after a fix
# lands — without it, the SARIF only ever uploads against PR refs and the
# main-branch alert track goes stale after every fix merge.
#
# Never pushes images — this is feedback only. release.yml continues to run
# the authoritative scan at release publish time (with the real version tag).
on:
pull_request:
paths:
- 'Dockerfile'
- '**/Dockerfile'
- 'pom.xml'
- '**/pom.xml'
- '.github/workflows/pr-container-scan.yml'
push:
branches: [main]
paths:
- 'Dockerfile'
- '**/Dockerfile'
- 'pom.xml'
- '**/pom.xml'
- '.github/workflows/pr-container-scan.yml'
permissions: read-all
jobs:
scan:
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: read
security-events: write # required for Trivy SARIF upload to Security tab
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
- name: Build image (load for scan, no push)
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7
with:
context: .
push: false
load: true
tags: ghcr.io/runcycles/cycles-server:scan-${{ github.event.pull_request.number || github.sha }}
build-args: |
APP_VERSION=scan-${{ github.event.pull_request.number || github.sha }}
# no-cache + pull are critical for security scans: cached layers
# (especially `apk upgrade`) keep reporting old packages even
# after a base-image bump. Witnessed in cycles-dashboard PR #157
# / #158 — FROM bump didn't take effect because cached layer
# served months-old apk state. Always build fresh for scans.
no-cache: true
pull: true
- name: Trivy vulnerability scan
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
image-ref: ghcr.io/runcycles/cycles-server:scan-${{ github.event.pull_request.number || github.sha }}
severity: 'HIGH,CRITICAL'
ignore-unfixed: true
format: 'sarif'
output: 'trivy-results.sarif'
exit-code: '1'
# In `format: sarif` mode the action builds an all-severities report
# by default, so `exit-code: 1` trips on ANY fixable finding and the
# `severity` filter above is ignored for gating. Limit the SARIF to
# the declared severities so the gate (and the Security-tab report)
# honor HIGH,CRITICAL only — a fixable MEDIUM should not block a PR.
# See AUDIT.md (jackson-databind CVE-2026-54515).
limit-severities-for-sarif: true
- name: Upload Trivy SARIF to Security tab
if: always()
uses: github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4
with:
sarif_file: 'trivy-results.sarif'
category: trivy-container-pr # category kept stable so push-to-main scans clear PR-track alerts