ec27228a8e
Em dashes (—) and en dashes (–) had spread across comments, docs, tests, and a few UI strings, reading as AI-generated boilerplate rather than house style. Replaced each with punctuation matching its context: colon for explanatory clauses, comma for asides, plain hyphen for numeric/legal ranges (e.g. "21-23§"), "to"/"till" for date ranges, parentheses for paired-dash asides. messages/en.json and messages/sv.json were fixed by hand together to keep sv/en in sync. Left untouched where the dash is the functional subject rather than decorative punctuation: date-range-parser.ts's separator regex, charset-repair.ts's CP1252 byte-mapping table (and its test), the SIE encoding mojibake docs, generic-csv.ts's minus-sign normalizer, the agent system-prompt files that already instruct against em dashes, and a golden iXBRL test fixture compared byte-for-byte. Also fixes two bugs surfaced along the way: an off-by-one in ApiKeysPanel's scope-label split (a leftover from an earlier partial pass), and a charset-repair test that had lost the literal en-dash it exists to verify. Regenerated the agent atom seed migration (skills:generate) since 27 SKILL.md files changed. Added a CLAUDE.md rule against em/en dashes, with an explicit carve-out for the functional-dash cases above. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
81 lines
3.2 KiB
YAML
81 lines
3.2 KiB
YAML
name: Scheduled Image Vulnerability Scan
|
|
|
|
# The build pipeline (docker-publish.yml) builds and publishes the image but
|
|
# does NOT fail on CVEs: it stays green so deploys are deterministic. This
|
|
# workflow is the actual vulnerability gate: it re-scans the published `latest`
|
|
# image and fails (notifying repo admins) plus raises a Security-tab alert on a
|
|
# fixable CRITICAL/HIGH CVE, prompting a dependency or base-image bump.
|
|
#
|
|
# It fires on three triggers:
|
|
# 1. workflow_run: the moment "Build and Push Docker Image" completes, so a
|
|
# freshly published image is gated within the scan's own duration (minutes)
|
|
# rather than waiting up to 24h for the cron. This is what shrinks the
|
|
# vulnerable-image exposure window after every publish.
|
|
# 2. schedule (daily): catches CVEs newly disclosed against an already-
|
|
# published image even when nothing was republished.
|
|
# 3. workflow_dispatch: run on demand from the Actions tab after a patch to
|
|
# confirm clean.
|
|
#
|
|
# NOTE: GitHub only runs `schedule` and `workflow_run` triggers from the default
|
|
# branch, so both start firing once this is merged to main.
|
|
on:
|
|
workflow_run:
|
|
workflows: ['Build and Push Docker Image']
|
|
types: [completed]
|
|
schedule:
|
|
# 06:17 UTC daily: off the hour to dodge cron congestion on GitHub.
|
|
- cron: '17 6 * * *'
|
|
workflow_dispatch: {}
|
|
|
|
env:
|
|
REGISTRY: ghcr.io
|
|
IMAGE_NAME: erp-mafia/gnubok
|
|
|
|
jobs:
|
|
scan:
|
|
runs-on: ubuntu-latest
|
|
# workflow_run fires even when the publish FAILED: there's no new image to
|
|
# gate in that case, so skip. schedule/workflow_dispatch carry no
|
|
# workflow_run payload, so the `!= 'workflow_run'` arm lets them through.
|
|
if: >-
|
|
github.event_name != 'workflow_run' ||
|
|
github.event.workflow_run.conclusion == 'success'
|
|
permissions:
|
|
contents: read
|
|
# Pull the published image from GHCR.
|
|
packages: read
|
|
# SARIF upload to the repo's "Security" tab.
|
|
security-events: write
|
|
|
|
steps:
|
|
- name: Log in to GHCR
|
|
uses: docker/login-action@v4
|
|
with:
|
|
registry: ${{ env.REGISTRY }}
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Scan published image with Trivy
|
|
uses: aquasecurity/trivy-action@v0.36.0
|
|
with:
|
|
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
|
# Block on fixable CRITICAL/HIGH: the same policy the build pipeline
|
|
# used to enforce inline. It is safe to block here: a red scheduled
|
|
# run is a "go patch" notification, not a blocked deploy. ignore-unfixed
|
|
# keeps it actionable (only CVEs we can resolve by rebuilding fail).
|
|
severity: CRITICAL,HIGH
|
|
exit-code: '1'
|
|
ignore-unfixed: true
|
|
format: sarif
|
|
output: trivy-results.sarif
|
|
|
|
- name: Upload Trivy results to GitHub Security tab
|
|
# if: always() so findings still reach the Security tab even though the
|
|
# scan step above failed the run. Same category as docker-publish.yml so
|
|
# the two analyses share one alert set instead of duplicating.
|
|
if: always()
|
|
uses: github/codeql-action/upload-sarif@v3
|
|
with:
|
|
sarif_file: trivy-results.sarif
|
|
category: trivy
|