Merge pull request #735 from cloud-neutral-toolkit/codex/update-build-service-images.yml-inputs

This commit is contained in:
cloudneutral 2025-12-03 20:53:19 +08:00 committed by GitHub
commit 4971fd45fd
3 changed files with 135 additions and 2 deletions

View File

@ -2,6 +2,31 @@ name: Build Base Images
on:
workflow_call:
outputs:
node_builder_image:
description: "Node builder image with the preferred tag for downstream workflows"
value: ${{ jobs.collect-base-images.outputs.node_builder_image }}
node_runtime_image:
description: "Node runtime image with the preferred tag for downstream workflows"
value: ${{ jobs.collect-base-images.outputs.node_runtime_image }}
openresty_geoip_image:
description: "OpenResty GeoIP image with the preferred tag for downstream workflows"
value: ${{ jobs.collect-base-images.outputs.openresty_geoip_image }}
postgres_runtime_image:
description: "Postgres runtime image with the preferred tag for downstream workflows"
value: ${{ jobs.collect-base-images.outputs.postgres_runtime_image }}
node_builder_digest:
description: "Node builder image digest for downstream workflows"
value: ${{ jobs.collect-base-images.outputs.node_builder_digest }}
node_runtime_digest:
description: "Node runtime image digest for downstream workflows"
value: ${{ jobs.collect-base-images.outputs.node_runtime_digest }}
openresty_geoip_digest:
description: "OpenResty GeoIP image digest for downstream workflows"
value: ${{ jobs.collect-base-images.outputs.openresty_geoip_digest }}
postgres_runtime_digest:
description: "Postgres runtime image digest for downstream workflows"
value: ${{ jobs.collect-base-images.outputs.postgres_runtime_digest }}
inputs:
push_images:
description: "Push images instead of building locally"
@ -81,6 +106,37 @@ jobs:
image: ${{ env.REGISTRY }}/${{ env.ORG }}/${{ matrix.image.name }}@${{ steps.build.outputs.digest }}
output-file: sbom.spdx.json
- name: Capture image metadata
env:
IMAGE_NAME: ${{ matrix.image.name }}
DIGEST: ${{ steps.build.outputs.digest }}
META_TAGS: ${{ steps.meta.outputs.tags }}
run: |
python - <<'PY'
import json
import os
tags = os.environ.get("META_TAGS", "").splitlines()
preferred = next((tag for tag in tags if tag.endswith(":latest")), tags[0] if tags else "")
metadata = {
"name": os.environ.get("IMAGE_NAME", ""),
"image": f"{os.environ.get('REGISTRY')}/{os.environ.get('ORG')}/{os.environ.get('IMAGE_NAME')}",
"digest": os.environ.get("DIGEST", ""),
"tags": tags,
"preferred_tag": preferred,
"image_with_digest": f"{os.environ.get('REGISTRY')}/{os.environ.get('ORG')}/{os.environ.get('IMAGE_NAME')}@{os.environ.get('DIGEST', '')}",
}
with open("image-metadata.json", "w", encoding="utf-8") as f:
json.dump(metadata, f)
PY
- uses: actions/upload-artifact@v4
with:
name: base-image-metadata-${{ matrix.image.name }}
path: image-metadata.json
- uses: actions/upload-artifact@v4
with:
name: sbom-${{ matrix.image.name }}
@ -96,3 +152,46 @@ jobs:
run: |
COSIGN_IMAGE=${{ env.REGISTRY }}/${{ env.ORG }}/${{ matrix.image.name }}@${{ steps.build.outputs.digest }}
cosign sign --yes "$COSIGN_IMAGE"
collect-base-images:
runs-on: ubuntu-latest
needs: build-base
outputs:
node_builder_image: ${{ steps.expose.outputs.node_builder_image }}
node_runtime_image: ${{ steps.expose.outputs.node_runtime_image }}
openresty_geoip_image: ${{ steps.expose.outputs.openresty_geoip_image }}
postgres_runtime_image: ${{ steps.expose.outputs.postgres_runtime_image }}
node_builder_digest: ${{ steps.expose.outputs.node_builder_digest }}
node_runtime_digest: ${{ steps.expose.outputs.node_runtime_digest }}
openresty_geoip_digest: ${{ steps.expose.outputs.openresty_geoip_digest }}
postgres_runtime_digest: ${{ steps.expose.outputs.postgres_runtime_digest }}
steps:
- uses: actions/download-artifact@v4
with:
pattern: base-image-metadata-*
merge-multiple: true
path: metadata
- name: Extract preferred base image tags
id: expose
run: |
declare -A refs
declare -A digests
for file in metadata/*.json; do
name=$(jq -r '.name' "$file")
preferred=$(jq -r '.preferred_tag' "$file")
digest=$(jq -r '.digest' "$file")
refs[$name]=$preferred
digests[$name]=$digest
done
{
echo "node_builder_image=${refs[node-builder]}"
echo "node_runtime_image=${refs[node-runtime]}"
echo "openresty_geoip_image=${refs[openresty-geoip]}"
echo "postgres_runtime_image=${refs[postgres-runtime]}"
echo "node_builder_digest=${digests[node-builder]}"
echo "node_runtime_digest=${digests[node-runtime]}"
echo "openresty_geoip_digest=${digests[openresty-geoip]}"
echo "postgres_runtime_digest=${digests[postgres-runtime]}"
} >> "$GITHUB_OUTPUT"

View File

@ -7,6 +7,26 @@ on:
description: "Push images instead of local builds"
type: boolean
default: true
postgres_runtime_digest:
description: "Digest for the Postgres runtime base image"
type: string
required: false
default: ''
node_runtime_digest:
description: "Digest for the Node runtime base image"
type: string
required: false
default: ''
node_builder_digest:
description: "Digest for the Node builder base image"
type: string
required: false
default: ''
openresty_geoip_digest:
description: "Digest for the OpenResty GeoIP base image"
type: string
required: false
default: ''
push:
branches: [ main ]
paths:
@ -23,9 +43,17 @@ permissions:
env:
REGISTRY: ghcr.io
ORG: cloudneutral-lab
BASE_ORG: cloud-neutral-toolkit
jobs:
base-images:
uses: ./.github/workflows/build-base-images.yml
secrets: inherit
with:
push_images: ${{ inputs.push_images }}
build-service:
needs: base-images
strategy:
matrix:
service:
@ -80,6 +108,9 @@ jobs:
push: ${{ inputs.push_images }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
NODE_BUILDER_IMAGE=${{ env.REGISTRY }}/${{ env.BASE_ORG }}/node-builder@${{ inputs.node_builder_digest || needs.base-images.outputs.node_builder_digest }}
NODE_RUNTIME_IMAGE=${{ env.REGISTRY }}/${{ env.BASE_ORG }}/node-runtime@${{ inputs.node_runtime_digest || needs.base-images.outputs.node_runtime_digest }}
- uses: anchore/sbom-action@v0
with:

View File

@ -1,5 +1,8 @@
# Multi-stage production build for the Next.js dashboard
FROM node:22.20.0 AS base
ARG NODE_BUILDER_IMAGE
ARG NODE_RUNTIME_IMAGE
FROM ${NODE_BUILDER_IMAGE} AS base
WORKDIR /app
ENV NEXT_TELEMETRY_DISABLED=1
@ -15,7 +18,7 @@ FROM base AS prod-deps
COPY dashboard/package*.json ./
RUN npm ci --omit=dev
FROM node:22.20.0-slim AS runner
FROM ${NODE_RUNTIME_IMAGE} AS runner
WORKDIR /var/www/XControl/dashboard/
ENV NODE_ENV=production \
RUNTIME_ENV=prod \