Merge origin/main into align-wilm-main (align wilm with Cameron's latest)
Bring main's endpoint hardening, operator-report validation, launch-path policy, and theme-variable CSS into wilm. Channel model reconciled to this repo's shipping (stable=release tag, edge=main trunk) while keeping wilm's remote-BuildKit publish step and GHCR pull-based launcher.
This commit is contained in:
60
.github/workflows/publish-images.yml
vendored
60
.github/workflows/publish-images.yml
vendored
@@ -8,22 +8,31 @@
|
||||
# A single image pull is one resumable HTTPS stream, far more robust through
|
||||
# the proxy than hundreds of npm requests.
|
||||
#
|
||||
# Channels map to branches:
|
||||
# main -> ghcr.io/<owner>/shopdb-flask:stable (badge off)
|
||||
# dev-be -> ghcr.io/<owner>/shopdb-flask:edge (SHOPDB_ENV_LABEL=DEV badge)
|
||||
# Channels are mapped to how THIS repo actually ships, which is not how the
|
||||
# branch this came from ships. Upstream, main is a release branch and dev-be is
|
||||
# the trunk. Here main IS the trunk - it runs hundreds of commits past the last
|
||||
# release - and releases are tags (ADR-007). Publishing main as :stable would
|
||||
# put unreleased work behind a word that promises the opposite, to sites that
|
||||
# have no way to know:
|
||||
#
|
||||
# Each push to those branches rebuilds and republishes its channel tag, so
|
||||
# `edge` stays genuinely bleeding edge. The image is also tagged with the short
|
||||
# commit SHA for traceability and rollback.
|
||||
# tag v* -> ghcr.io/<owner>/shopdb-flask:stable (badge off) the release
|
||||
# main -> ghcr.io/<owner>/shopdb-flask:edge (DEV badge) the trunk
|
||||
#
|
||||
# The image also carries a short-SHA tag for traceability and rollback.
|
||||
#
|
||||
# Automatic publishing is OFF until someone confirms the GHCR package exists
|
||||
# under this owner and decides who may pull it. Re-enable by uncommenting the
|
||||
# push: block below; workflow_dispatch works meanwhile.
|
||||
|
||||
name: publish-images
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- dev-be
|
||||
# Allow a manual rebuild/publish of the current branch's channel image.
|
||||
# push:
|
||||
# tags:
|
||||
# - 'v*'
|
||||
# branches:
|
||||
# - main
|
||||
# Manual rebuild/publish of the current ref's channel image.
|
||||
workflow_dispatch:
|
||||
|
||||
# One in-flight publish per branch; a newer push supersedes an older one.
|
||||
@@ -48,7 +57,10 @@ jobs:
|
||||
run: |
|
||||
owner="$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')"
|
||||
image="ghcr.io/${owner}/shopdb-flask"
|
||||
if [ "${{ github.ref_name }}" = "main" ]; then
|
||||
# A tag is a release, anything else is the trunk. Deliberately not
|
||||
# keyed on the branch name: a release here is a tag, so keying on
|
||||
# "main" would label the trunk stable.
|
||||
if [ "${{ github.ref_type }}" = "tag" ]; then
|
||||
channel="stable"
|
||||
else
|
||||
channel="edge"
|
||||
@@ -64,18 +76,18 @@ jobs:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Connect to a persistent, out-of-cluster BuildKit deployment instead of
|
||||
# spinning up a builder against a local Docker daemon. The arc-runner-set
|
||||
# pods have no Docker daemon (no /var/run/docker.sock) and cannot run a
|
||||
# privileged DinD sidecar under cluster policy, so we point Buildx at a
|
||||
# remote buildkitd Service. The endpoint is provided as a repo/org secret
|
||||
# (e.g. tcp://buildkit.buildkit.svc.cluster.local:1234), so it is not
|
||||
# hardcoded here. See deploy/ci/buildkit-remote.yaml for the deployment.
|
||||
- name: Set up Buildx (remote BuildKit)
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
driver: remote
|
||||
endpoint: ${{ secrets.BUILDKIT_ENDPOINT }}
|
||||
# Connect to a persistent, out-of-cluster BuildKit deployment instead of
|
||||
# spinning up a builder against a local Docker daemon. The arc-runner-set
|
||||
# pods have no Docker daemon (no /var/run/docker.sock) and cannot run a
|
||||
# privileged DinD sidecar under cluster policy, so we point Buildx at a
|
||||
# remote buildkitd Service. The endpoint is provided as a repo/org secret
|
||||
# (e.g. tcp://buildkit.buildkit.svc.cluster.local:1234), so it is not
|
||||
# hardcoded here. See deploy/ci/buildkit-remote.yaml for the deployment.
|
||||
- name: Set up Buildx (remote BuildKit)
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
driver: remote
|
||||
endpoint: ${{ secrets.BUILDKIT_ENDPOINT }}
|
||||
|
||||
- name: Build and push channel image
|
||||
uses: docker/build-push-action@v6
|
||||
|
||||
32
.github/workflows/scan-darkwing-portable.yml
vendored
Normal file
32
.github/workflows/scan-darkwing-portable.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# Darkwing vulnerability scan, manual dispatch.
|
||||
#
|
||||
# Copied verbatim from the ge-aero/darkwing README so it stays byte-identical
|
||||
# to the sanctioned integration. Do not edit this file to add triggers or
|
||||
# gating - see scan-darkwing-pr.yml for that, which is ours to change.
|
||||
#
|
||||
# The file must sit on the default branch before a scan can run on ANY branch.
|
||||
name: Scan (darkwing, portable)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
target_ref:
|
||||
description: Ref, branch, or sha of this repo to scan
|
||||
required: false
|
||||
type: string
|
||||
default: main
|
||||
|
||||
permissions:
|
||||
contents: read # checkout this repo via the ambient GITHUB_TOKEN
|
||||
security-events: write # SARIF upload to the Security tab
|
||||
actions: read # required by upload-sarif on private/internal repos
|
||||
|
||||
jobs:
|
||||
scan:
|
||||
runs-on: darkwing-scan
|
||||
steps:
|
||||
# @v1 is a moving tag pointing to the latest release that is compatible
|
||||
# with this workflow file.
|
||||
- uses: ge-aero/darkwing@v1
|
||||
with:
|
||||
target_ref: ${{ inputs.target_ref || 'main' }}
|
||||
62
.github/workflows/scan-darkwing-pr.yml
vendored
Normal file
62
.github/workflows/scan-darkwing-pr.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
# Darkwing scan on pull requests, so the "check against darkwing" is a check
|
||||
# and not a thing somebody remembers to click.
|
||||
#
|
||||
# WHY THIS IS SEPARATE from scan-darkwing-portable.yml: that file is copied
|
||||
# byte-for-byte from the ge-aero/darkwing README and is left alone so it keeps
|
||||
# matching the sanctioned integration. Everything below is ours.
|
||||
#
|
||||
# THE TRAP THIS AVOIDS. The README workflow resolves its scan target as
|
||||
# `inputs.target_ref || 'main'`. On a pull_request event there are no inputs,
|
||||
# so that expression falls through to 'main' and the job scans the default
|
||||
# branch instead of the code under review - a green Darkwing check that never
|
||||
# looked at the change. Resolve the head SHA explicitly.
|
||||
#
|
||||
# Darkwing exits 0 whatever it finds (its own FAQ: "Does a finding fail my
|
||||
# build? No."), so a passing job means the scan RAN, not that the code is
|
||||
# clean. Findings land in Security -> Code scanning. Turning a finding into a
|
||||
# hard failure means reading findings.sarif ourselves; the commented step at
|
||||
# the bottom is the shape of that, deliberately left off until we have seen the
|
||||
# false-positive rate on this repo.
|
||||
name: Scan (darkwing, PR)
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
actions: read
|
||||
|
||||
# One scan per PR. A new push supersedes the old one rather than queueing a
|
||||
# second Bedrock spend against a diff nobody is reviewing any more.
|
||||
concurrency:
|
||||
group: darkwing-pr-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
scan:
|
||||
runs-on: darkwing-scan
|
||||
steps:
|
||||
- uses: ge-aero/darkwing@v1
|
||||
with:
|
||||
# The PR's head, NOT the default branch. See the note above.
|
||||
target_ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
# Gating, once the signal is trusted. Darkwing writes findings.sarif into
|
||||
# its work dir and attaches it as the `findings` artifact; this reads the
|
||||
# severities out and fails on error-level results only.
|
||||
#
|
||||
# - name: Fail on error-level findings
|
||||
# run: |
|
||||
# python - <<'PY'
|
||||
# import json, pathlib, sys
|
||||
# sarif = pathlib.Path('darkwing/findings.sarif')
|
||||
# if not sarif.is_file():
|
||||
# sys.exit('no findings.sarif: the scan did not produce results')
|
||||
# doc = json.loads(sarif.read_text())
|
||||
# bad = [r for run in doc.get('runs', [])
|
||||
# for r in run.get('results', [])
|
||||
# if r.get('level') == 'error']
|
||||
# if bad:
|
||||
# sys.exit(f'{len(bad)} error-level finding(s); see the Security tab')
|
||||
# PY
|
||||
Reference in New Issue
Block a user