build: cache docker layers, configurable engine, bump owasp/pnpm
- CI workflow uses BuildKit inline cache + --cache-from previous :latest; NVD_REFRESH build-arg busts the OWASP layer on schedule/dispatch so weekly rebuilds still refresh NVD while push builds reuse cached layers. - build-and-push.ps1 reads CONTAINER_ENGINE from .env (docker default, podman supported); add .env.example. - Bump OWASP Dependency-Check 12.2.1 -> 12.2.2 and pnpm 11.0.6 -> 11.1.1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
# Copy this file to .env and fill in the values.
|
||||
# .env is gitignored — never commit real credentials.
|
||||
|
||||
# ── Container engine (docker | podman) ──
|
||||
CONTAINER_ENGINE=docker
|
||||
|
||||
# ── Docker Registry ──
|
||||
REGISTRY=kcr.kollect.biz
|
||||
REGISTRY_USER='robot$kollect-tools+ci-builder'
|
||||
REGISTRY_PASS=harbor-robot-password
|
||||
IMAGE_TAG=latest
|
||||
|
||||
# ── OWASP Dependency-Check ──
|
||||
# Get an API key at https://nvd.nist.gov/developers/request-an-api-key
|
||||
# Optional but strongly recommended — without it NVD rate-limits to 5 req / 30s.
|
||||
NVD_API_KEY=<nvd-api-key>
|
||||
@@ -74,8 +74,26 @@ jobs:
|
||||
--password-stdin
|
||||
|
||||
- name: Build image
|
||||
env:
|
||||
DOCKER_BUILDKIT: "1"
|
||||
run: |
|
||||
# Pull the previous :latest to use as a layer cache source.
|
||||
# First builds (no prior image) fail this pull — that's fine.
|
||||
docker pull "${{ steps.meta.outputs.tag_latest }}" || true
|
||||
|
||||
# On schedule / manual dispatch, bust the OWASP NVD layer so the
|
||||
# weekly rebuild actually refreshes the NVD database. Push builds
|
||||
# leave it empty so unchanged layers stay cached.
|
||||
NVD_REFRESH=""
|
||||
if [ "${{ github.event_name }}" = "schedule" ] || \
|
||||
[ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
NVD_REFRESH="$(date +%Y%m%d)"
|
||||
fi
|
||||
|
||||
docker build \
|
||||
--build-arg BUILDKIT_INLINE_CACHE=1 \
|
||||
--build-arg NVD_REFRESH="${NVD_REFRESH}" \
|
||||
--cache-from "${{ steps.meta.outputs.tag_latest }}" \
|
||||
--label "org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}" \
|
||||
--label "org.opencontainers.image.revision=${{ github.sha }}" \
|
||||
-t "${{ steps.meta.outputs.tag_sha }}" \
|
||||
|
||||
+22
-9
@@ -1,7 +1,10 @@
|
||||
#Requires -Version 5.1
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Build and push a CI image to the Harbor registry using podman.
|
||||
Build and push a CI image to the Harbor registry.
|
||||
|
||||
The container engine is read from CONTAINER_ENGINE in .env
|
||||
(docker | podman). Defaults to docker when unset.
|
||||
|
||||
.EXAMPLE
|
||||
.\build-and-push.ps1 -Image ci/java-builder
|
||||
@@ -36,6 +39,16 @@ foreach ($v in 'REGISTRY', 'REGISTRY_USER', 'REGISTRY_PASS') {
|
||||
}
|
||||
}
|
||||
|
||||
# --- Resolve container engine ---
|
||||
$engine = if ($env:CONTAINER_ENGINE) { $env:CONTAINER_ENGINE.Trim().ToLower() } else { 'docker' }
|
||||
if ($engine -notin @('docker', 'podman')) {
|
||||
throw "CONTAINER_ENGINE must be 'docker' or 'podman' (got '$engine')"
|
||||
}
|
||||
if (-not (Get-Command $engine -ErrorAction SilentlyContinue)) {
|
||||
throw "Container engine '$engine' not found on PATH"
|
||||
}
|
||||
Write-Host "=> Using container engine: $engine"
|
||||
|
||||
# --- Resolve paths ---
|
||||
# $Image is the path to the image directory relative to the repo root, and
|
||||
# also the image name pushed to the registry (e.g. "ci/java-builder").
|
||||
@@ -72,7 +85,7 @@ $tags = @('latest', $Version, $date)
|
||||
# (PowerShell's native pipe appends CRLF, which breaks --password-stdin).
|
||||
Write-Host "=> Logging in to $regHost"
|
||||
$psi = New-Object System.Diagnostics.ProcessStartInfo
|
||||
$psi.FileName = 'podman'
|
||||
$psi.FileName = $engine
|
||||
$psi.Arguments = "login $regHost --username `"$($env:REGISTRY_USER)`" --password-stdin"
|
||||
$psi.RedirectStandardInput = $true
|
||||
$psi.UseShellExecute = $false
|
||||
@@ -80,7 +93,7 @@ $proc = [System.Diagnostics.Process]::Start($psi)
|
||||
$proc.StandardInput.Write($env:REGISTRY_PASS)
|
||||
$proc.StandardInput.Close()
|
||||
$proc.WaitForExit()
|
||||
if ($proc.ExitCode -ne 0) { throw "podman login failed (exit $($proc.ExitCode))" }
|
||||
if ($proc.ExitCode -ne 0) { throw "$engine login failed (exit $($proc.ExitCode))" }
|
||||
|
||||
# --- Build ---
|
||||
Write-Host "=> Building ${repo}:latest"
|
||||
@@ -90,21 +103,21 @@ if ($env:NVD_API_KEY) {
|
||||
}
|
||||
$buildArgs += $imageDir
|
||||
|
||||
& podman @buildArgs
|
||||
if ($LASTEXITCODE -ne 0) { throw "podman build failed" }
|
||||
& $engine @buildArgs
|
||||
if ($LASTEXITCODE -ne 0) { throw "$engine build failed" }
|
||||
|
||||
# --- Tag ---
|
||||
foreach ($tag in $Version, $date) {
|
||||
Write-Host "=> Tagging ${repo}:$tag"
|
||||
podman tag "${repo}:latest" "${repo}:$tag"
|
||||
if ($LASTEXITCODE -ne 0) { throw "podman tag failed for $tag" }
|
||||
& $engine tag "${repo}:latest" "${repo}:$tag"
|
||||
if ($LASTEXITCODE -ne 0) { throw "$engine tag failed for $tag" }
|
||||
}
|
||||
|
||||
# --- Push ---
|
||||
foreach ($tag in $tags) {
|
||||
Write-Host "=> Pushing ${repo}:$tag"
|
||||
podman push "${repo}:$tag"
|
||||
if ($LASTEXITCODE -ne 0) { throw "podman push failed for $tag" }
|
||||
& $engine push "${repo}:$tag"
|
||||
if ($LASTEXITCODE -ne 0) { throw "$engine push failed for $tag" }
|
||||
}
|
||||
|
||||
Write-Host "Done. Pushed $($tags.Count) tags to $repo"
|
||||
|
||||
@@ -66,11 +66,14 @@ RUN curl -fsSL "https://dlcdn.apache.org/maven/maven-3/${MAVEN_VERSION}/binaries
|
||||
#
|
||||
# Rebuild this image weekly to keep the NVD database fresh.
|
||||
# ─────────────────────────────────────────────────────────────────────
|
||||
ARG OWASP_DC_VERSION=12.2.1
|
||||
ARG OWASP_DC_VERSION=12.2.2
|
||||
ARG NVD_API_KEY=""
|
||||
# Bump to invalidate the cached NVD layer (e.g. weekly date stamp from CI).
|
||||
ARG NVD_REFRESH=""
|
||||
ENV OWASP_DATA_DIR=/opt/owasp/dependency-check-data
|
||||
|
||||
RUN if [ -n "${NVD_API_KEY}" ]; then \
|
||||
RUN echo "NVD_REFRESH=${NVD_REFRESH}" \
|
||||
&& if [ -n "${NVD_API_KEY}" ]; then \
|
||||
echo "NVD API key: set (length=$(printf %s "${NVD_API_KEY}" | wc -c))"; \
|
||||
else \
|
||||
echo "WARNING: NVD_API_KEY is empty — NVD will rate-limit at 5 req / 30s"; \
|
||||
@@ -113,7 +116,7 @@ RUN curl -fsSL "https://github.com/bufbuild/buf/releases/download/v${BUF_VERSION
|
||||
# Last because it's the most volatile pin and corepack prepare is the
|
||||
# cheapest layer; bumping pnpm shouldn't force any other layer to rebuild.
|
||||
# ─────────────────────────────────────────────────────────────────────
|
||||
ARG PNPM_VERSION=11.0.6
|
||||
ARG PNPM_VERSION=11.1.1
|
||||
|
||||
RUN corepack enable \
|
||||
&& corepack prepare "pnpm@${PNPM_VERSION}" --activate
|
||||
|
||||
Reference in New Issue
Block a user