mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 03:49:26 +00:00
One base (Temurin 21 JDK, node/npm/tsc, php/composer, maven, sqlite, bwrap) built only when its Dockerfile or dependencies change, plus a browser variant; engine/search/VM images FROM base@sha256 with the code in the last layer; the image workflow runs on dispatch, tags, Dockerfile or pin changes, with a build cache. Executor NPROC bound relative to the current process count. Co-Authored-By: Claude Fable 5.1 <[email protected]>
200 lines
7.4 KiB
YAML
200 lines
7.4 KiB
YAML
name: Engine image
|
|
on:
|
|
workflow_dispatch:
|
|
push:
|
|
branches: [main]
|
|
tags: ['v*']
|
|
paths:
|
|
- 'plane/Dockerfile.*'
|
|
- 'plane/task-base.digest'
|
|
- 'Dockerfile'
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
concurrency:
|
|
group: engine-image-${{ github.ref }}
|
|
cancel-in-progress: false
|
|
jobs:
|
|
pins:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
base_tag: ${{ steps.pins.outputs.base_tag }}
|
|
base_digest: ${{ steps.pins.outputs.base_digest }}
|
|
browser_tag: ${{ steps.pins.outputs.browser_tag }}
|
|
browser_digest: ${{ steps.pins.outputs.browser_digest }}
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
- uses: docker/setup-buildx-action@v3
|
|
# No login: every pinned base must be anonymously pullable.
|
|
- id: pins
|
|
run: |
|
|
python3 - <<'PYTHON'
|
|
import json, os, re, subprocess
|
|
from pathlib import Path
|
|
pins = json.loads(Path("plane/task-base.digest").read_text())
|
|
manifests = {}
|
|
for key, output in (("base", "base"), ("base-browser", "browser")):
|
|
ref = pins.get(key)
|
|
pattern = r"ghcr.io/norandom/ousast-task-base:(base-[a-z0-9-]+)@(sha256:[0-9a-f]{64})"
|
|
match = re.fullmatch(pattern, ref or "")
|
|
if not match:
|
|
raise SystemExit(f"{key}: unpublished/invalid pin; run task-base-image and update plane/task-base.digest")
|
|
raw = subprocess.check_output(["docker", "buildx", "imagetools", "inspect", "--raw", ref])
|
|
manifests[key] = json.loads(raw)["layers"]
|
|
with open(os.environ["GITHUB_OUTPUT"], "a") as out:
|
|
out.write(f"{output}_tag={match[1]}\n{output}_digest={match[2]}\n")
|
|
base = manifests["base"]
|
|
if not base or manifests["base-browser"][:len(base)] != base:
|
|
raise SystemExit("Browser pin does not share the pinned base's layers")
|
|
PYTHON
|
|
image:
|
|
needs: pins
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- package: openultrasast
|
|
dockerfile: Dockerfile
|
|
- package: ousast-search-task
|
|
dockerfile: plane/Dockerfile.search-task
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
- uses: docker/setup-buildx-action@v3
|
|
- uses: docker/login-action@v3
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
- id: names
|
|
env:
|
|
OWNER: ${{ github.repository_owner }}
|
|
PACKAGE: ${{ matrix.package }}
|
|
run: |
|
|
echo "image=ghcr.io/${OWNER,,}/$PACKAGE" >> "$GITHUB_OUTPUT"
|
|
echo "sha=sha-${GITHUB_SHA:0:7}" >> "$GITHUB_OUTPUT"
|
|
- id: build
|
|
uses: docker/build-push-action@v6
|
|
with:
|
|
context: .
|
|
file: ${{ matrix.dockerfile }}
|
|
platforms: linux/amd64
|
|
push: true
|
|
provenance: false
|
|
build-args: |
|
|
TASK_BASE_TAG=${{ needs.pins.outputs.base_tag }}
|
|
TASK_BASE_DIGEST=${{ needs.pins.outputs.base_digest }}
|
|
TASK_BROWSER_TAG=${{ needs.pins.outputs.browser_tag }}
|
|
TASK_BROWSER_DIGEST=${{ needs.pins.outputs.browser_digest }}
|
|
cache-from: |
|
|
type=gha,scope=${{ matrix.package }}
|
|
type=gha,scope=ousast-engine-task
|
|
cache-to: type=gha,mode=max,scope=${{ matrix.package }}
|
|
tags: |
|
|
${{ steps.names.outputs.image }}:${{ steps.names.outputs.sha }}
|
|
${{ steps.names.outputs.image }}:main
|
|
- env:
|
|
IMAGE: ${{ steps.names.outputs.image }}
|
|
DIGEST: ${{ steps.build.outputs.digest }}
|
|
run: |
|
|
echo "$IMAGE@$DIGEST"
|
|
echo "$IMAGE@$DIGEST" >> "$GITHUB_STEP_SUMMARY"
|
|
docker logout ghcr.io
|
|
docker buildx imagetools inspect "$IMAGE@$DIGEST"
|
|
engine:
|
|
needs: pins
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
image: ${{ steps.names.outputs.image }}
|
|
digest: ${{ steps.build.outputs.digest }}
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
- uses: docker/setup-buildx-action@v3
|
|
- uses: docker/login-action@v3
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
- id: names
|
|
env:
|
|
OWNER: ${{ github.repository_owner }}
|
|
PACKAGE: ousast-engine-task
|
|
run: |
|
|
echo "image=ghcr.io/${OWNER,,}/$PACKAGE" >> "$GITHUB_OUTPUT"
|
|
echo "sha=sha-${GITHUB_SHA:0:7}" >> "$GITHUB_OUTPUT"
|
|
- id: build
|
|
uses: docker/build-push-action@v6
|
|
with:
|
|
context: .
|
|
file: plane/Dockerfile.engine-task
|
|
target: engine
|
|
platforms: linux/amd64
|
|
push: true
|
|
provenance: false
|
|
build-args: |
|
|
TASK_BASE_TAG=${{ needs.pins.outputs.base_tag }}
|
|
TASK_BASE_DIGEST=${{ needs.pins.outputs.base_digest }}
|
|
TASK_BROWSER_TAG=${{ needs.pins.outputs.browser_tag }}
|
|
TASK_BROWSER_DIGEST=${{ needs.pins.outputs.browser_digest }}
|
|
cache-from: type=gha,scope=ousast-engine-task
|
|
cache-to: type=gha,mode=max,scope=ousast-engine-task
|
|
tags: |
|
|
${{ steps.names.outputs.image }}:${{ steps.names.outputs.sha }}
|
|
${{ steps.names.outputs.image }}:main
|
|
- env:
|
|
IMAGE: ${{ steps.names.outputs.image }}
|
|
DIGEST: ${{ steps.build.outputs.digest }}
|
|
run: |
|
|
echo "$IMAGE@$DIGEST"
|
|
echo "$IMAGE@$DIGEST" >> "$GITHUB_STEP_SUMMARY"
|
|
docker logout ghcr.io
|
|
docker buildx imagetools inspect "$IMAGE@$DIGEST"
|
|
replay:
|
|
needs: [pins, engine]
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
- uses: docker/setup-buildx-action@v3
|
|
- uses: docker/login-action@v3
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
- id: names
|
|
env:
|
|
OWNER: ${{ github.repository_owner }}
|
|
PACKAGE: ousast-replay-task
|
|
run: |
|
|
echo "image=ghcr.io/${OWNER,,}/$PACKAGE" >> "$GITHUB_OUTPUT"
|
|
echo "sha=sha-${GITHUB_SHA:0:7}" >> "$GITHUB_OUTPUT"
|
|
- id: build
|
|
uses: docker/build-push-action@v6
|
|
with:
|
|
context: .
|
|
file: plane/Dockerfile.engine-task
|
|
target: replay
|
|
platforms: linux/amd64
|
|
push: true
|
|
provenance: false
|
|
build-args: |
|
|
ENGINE_REF=${{ needs.engine.outputs.image }}@${{ needs.engine.outputs.digest }}
|
|
TASK_BASE_TAG=${{ needs.pins.outputs.base_tag }}
|
|
TASK_BASE_DIGEST=${{ needs.pins.outputs.base_digest }}
|
|
TASK_BROWSER_TAG=${{ needs.pins.outputs.browser_tag }}
|
|
TASK_BROWSER_DIGEST=${{ needs.pins.outputs.browser_digest }}
|
|
cache-from: |
|
|
type=gha,scope=ousast-replay-task
|
|
type=gha,scope=ousast-engine-task
|
|
cache-to: type=gha,mode=max,scope=ousast-replay-task
|
|
tags: |
|
|
${{ steps.names.outputs.image }}:${{ steps.names.outputs.sha }}
|
|
${{ steps.names.outputs.image }}:main
|
|
- env:
|
|
IMAGE: ${{ steps.names.outputs.image }}
|
|
DIGEST: ${{ steps.build.outputs.digest }}
|
|
run: |
|
|
echo "$IMAGE@$DIGEST"
|
|
echo "$IMAGE@$DIGEST" >> "$GITHUB_STEP_SUMMARY"
|
|
docker logout ghcr.io
|
|
docker buildx imagetools inspect "$IMAGE@$DIGEST"
|