Merge pull request #735 from cloud-neutral-toolkit/codex/update-build-service-images.yml-inputs
This commit is contained in:
commit
4971fd45fd
99
.github/workflows/build-base-images.yml
vendored
99
.github/workflows/build-base-images.yml
vendored
@ -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"
|
||||
|
||||
31
.github/workflows/build-service-images.yml
vendored
31
.github/workflows/build-service-images.yml
vendored
@ -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:
|
||||
|
||||
@ -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 \
|
||||
|
||||
Loading…
Reference in New Issue
Block a user