142 lines
4.7 KiB
YAML
142 lines
4.7 KiB
YAML
# 供应链 CI:构建两个镜像 → 功能冒烟 → Trivy 高危阻断 → push 到 ACR。
|
||
#
|
||
# 单 job(build-and-scan):镜像在 job 内 build + load,冒烟 + Trivy 过后,
|
||
# master 推送时再 tag + push 到阿里云 ACR(用 ACR_USERNAME / ACR_PASSWORD
|
||
# secret)。仓库:registry.example.com/dsh/
|
||
name: build
|
||
|
||
on:
|
||
push:
|
||
branches: [master]
|
||
pull_request:
|
||
workflow_dispatch:
|
||
|
||
permissions:
|
||
contents: read
|
||
|
||
jobs:
|
||
build-and-scan:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- uses: actions/setup-node@v4
|
||
with:
|
||
node-version: 22
|
||
cache: npm
|
||
|
||
- name: Install + typecheck
|
||
run: |
|
||
npm ci
|
||
npm run typecheck
|
||
|
||
- name: Set up Docker Buildx
|
||
uses: docker/setup-buildx-action@v3
|
||
|
||
- name: Build control-plane image
|
||
uses: docker/build-push-action@v6
|
||
with:
|
||
context: .
|
||
file: Dockerfile
|
||
push: false
|
||
load: true
|
||
tags: dshs:ci
|
||
cache-from: type=gha
|
||
cache-to: type=gha,mode=max
|
||
|
||
- name: Build dsh image
|
||
uses: docker/build-push-action@v6
|
||
with:
|
||
context: .
|
||
file: Dockerfile.dsh
|
||
push: false
|
||
load: true
|
||
tags: dsh:ci
|
||
cache-from: type=gha
|
||
cache-to: type=gha,mode=max
|
||
|
||
- name: Smoke — control plane (bootstrap-admin + serve)
|
||
run: |
|
||
# bootstrap-admin as the non-root image user (uid 65532), default data root.
|
||
docker run --rm dshs:ci bootstrap-admin \
|
||
--username admin --password 'ci-test-pass-123'
|
||
# Boot the server and publish 3080 so the host can reach it, then probe.
|
||
docker run --rm -d --name dsh-cp -p 3080:3080 dshs:ci \
|
||
--host 0.0.0.0 --port 3080
|
||
for i in $(seq 1 30); do
|
||
curl -fsS http://127.0.0.1:3080/ >/dev/null 2>&1 && break
|
||
sleep 1
|
||
done
|
||
# On failure, surface the server logs before the step aborts.
|
||
curl -fsS http://127.0.0.1:3080/ >/dev/null || { docker logs dsh-cp; exit 1; }
|
||
echo "control plane serving OK"
|
||
docker logs dsh-cp
|
||
docker stop dsh-cp
|
||
|
||
- name: Smoke — dsh resolves runtime plugin
|
||
run: |
|
||
# A patch referencing dshs/runtime must resolve and load:
|
||
# the plugin's apply() logs "[dshs-runtime] role=...".
|
||
# printf (not a here-doc) so the YAML stays at column 0 inside a
|
||
# literal block scalar.
|
||
printf '%s\n' \
|
||
'- insert:' \
|
||
' - id: dshs-runtime' \
|
||
' name: dshs/runtime' \
|
||
> /tmp/patch.yml
|
||
# Foreground + bounded timeout so an early exit still leaves logs.
|
||
# DSH_HOME mirrors the production layout (§4.3) so the parent-dir
|
||
# walk reaches /var/lib/dshs/node_modules; run as root so
|
||
# dsh can create that tree (the per-user uid is set by the Pod spec
|
||
# at deploy time, not exercised here).
|
||
timeout 25 docker run --rm --user 0 \
|
||
-v /tmp/patch.yml:/tmp/patch.yml:ro \
|
||
-e DSH_HOME=/var/lib/dshs/users/smoke/home \
|
||
dsh:ci --profile web --patch /tmp/patch.yml --host 127.0.0.1 --port 8080 \
|
||
> /tmp/dsh.log 2>&1 || true
|
||
cat /tmp/dsh.log
|
||
grep -q 'dshs-runtime' /tmp/dsh.log
|
||
echo "runtime plugin resolved OK"
|
||
|
||
- name: Trivy — control plane
|
||
uses: aquasecurity/[email protected]
|
||
with:
|
||
image-ref: dshs:ci
|
||
severity: HIGH,CRITICAL
|
||
exit-code: 1
|
||
# 只阻断「可修复」的高危;收紧为 false 则连不可修复的也拦。
|
||
ignore-unfixed: true
|
||
|
||
- name: Trivy — dsh
|
||
uses: aquasecurity/[email protected]
|
||
with:
|
||
image-ref: dsh:ci
|
||
severity: HIGH,CRITICAL
|
||
exit-code: 1
|
||
ignore-unfixed: true
|
||
|
||
# --- push to ACR (master push / manual dispatch on master only) ---
|
||
- name: Login to ACR
|
||
if: github.ref == 'refs/heads/master'
|
||
uses: docker/login-action@v3
|
||
with:
|
||
registry: registry.example.com
|
||
username: ${{ secrets.ACR_USERNAME }}
|
||
password: ${{ secrets.ACR_PASSWORD }}
|
||
|
||
- name: Push control plane to ACR
|
||
if: github.ref == 'refs/heads/master'
|
||
run: |
|
||
docker tag dshs:ci \
|
||
registry.example.com/dsh/dshs:0.2.0
|
||
docker push \
|
||
registry.example.com/dsh/dshs:0.2.0
|
||
|
||
- name: Push dsh to ACR
|
||
if: github.ref == 'refs/heads/master'
|
||
run: |
|
||
docker tag dsh:ci \
|
||
registry.example.com/dsh/dsh:0.1.1-rc.2
|
||
docker push \
|
||
registry.example.com/dsh/dsh:0.1.1-rc.2
|