diff --git a/.github/workflows/build-images.yml b/.github/workflows/build-images.yml
index 84a29a2..5d1b923 100644
--- a/.github/workflows/build-images.yml
+++ b/.github/workflows/build-images.yml
@@ -1,72 +1,11 @@
-name: Build Dashboard Images
-
-on:
- workflow_call:
- inputs:
- push_images:
- description: "Push service images instead of local builds"
- type: boolean
- default: true
-
- dockerhub_namespace:
- description: "Docker Hub namespace (user/org)"
- type: string
-
- skip_security:
- description: "Skip security scans and signing"
- type: boolean
- default: false
-
- node_builder_image:
- type: string
- default: "node:22-bookworm"
-
- node_runtime_image:
- type: string
- default: "node:22-slim"
-
- workflow_dispatch:
- inputs:
- push_images:
- type: boolean
- default: true
-
- dockerhub_namespace:
- description: "Docker Hub namespace (user/org)"
- type: string
- default: "cloudneutral"
-
- skip_security:
- description: "Skip security scans and signing"
- type: boolean
- default: false
-
- node_builder_image:
- type: string
- default: "node:22-bookworm"
-
- node_runtime_image:
- type: string
- default: "node:22-slim"
-
- push:
- branches: [ main ]
-
-permissions:
- contents: read
- packages: write
- id-token: write
+name: Build Multi-Arch Images
env:
REGISTRY: ghcr.io
- # ✅ 不硬编码:默认推到 ghcr.io/<当前仓库 owner>/...
ORG: ${{ github.repository_owner }}
-
SKIP_SECURITY: ${{ inputs.skip_security || github.event.inputs.skip_security || 'false' }}
-
NODE_BUILDER_IMAGE: ${{ inputs.node_builder_image || github.event.inputs.node_builder_image || 'node:22-bookworm' }}
NODE_RUNTIME_IMAGE: ${{ inputs.node_runtime_image || github.event.inputs.node_runtime_image || 'node:22-slim' }}
-
PUSH_IMAGES: ${{ github.event_name == 'push'
|| (github.event_name == 'workflow_call' && inputs.push_images)
|| (github.event_name == 'workflow_dispatch' && github.event.inputs.push_images == 'true') }}
@@ -86,7 +25,7 @@ jobs:
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
- - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9
+ - uses: ./.github/actions/docker-login
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
@@ -98,15 +37,15 @@ jobs:
with:
image: ${{ env.REGISTRY }}/${{ env.ORG }}/${{ matrix.service.name }}
- - uses: docker/setup-qemu-action@v3
- - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f
+ - uses: ./.github/actions/docker-setup-qemu
+ - uses: ./.github/actions/docker-setup-buildx
- name: Clone knowledge content
run: git clone https://github.com/Cloud-Neutral-Workshop/knowledge.git knowledge
- name: Build Service Image (per-arch)
id: build
- uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8
+ uses: ./.github/actions/docker-build-push
with:
context: ${{ matrix.service.workdir }}
file: ${{ matrix.service.dockerfile }}
@@ -131,144 +70,3 @@ jobs:
with:
name: digest-${{ matrix.service.name }}-${{ matrix.arch.artifact }}
path: digest-${{ matrix.service.name }}-${{ matrix.arch.artifact }}.txt
-
- security:
- runs-on: ubuntu-latest
- needs: build
- if: ${{ (github.event_name == 'push' || inputs.push_images == true || github.event.inputs.push_images == 'true') && !((inputs.skip_security == true) || (github.event.inputs.skip_security == 'true')) }}
-
- strategy:
- matrix:
- arch:
- - { platform: linux/amd64, artifact: linux-amd64 }
- - { platform: linux/arm64, artifact: linux-arm64 }
- service:
- - { name: dashboard }
-
- steps:
- - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
-
- - uses: actions/download-artifact@v4
- with:
- name: digest-${{ matrix.service.name }}-${{ matrix.arch.artifact }}
-
- - name: Load image digest
- env:
- DIGEST_FILE: digest-${{ matrix.service.name }}-${{ matrix.arch.artifact }}.txt
- run: bash .github/scripts/build-images/load-image-digest.sh
-
- - name: Set image ref
- env:
- SERVICE_NAME: ${{ matrix.service.name }}
- IMAGE_SHA: ${{ github.sha }}
- IMAGE_ARTIFACT: ${{ matrix.arch.artifact }}
- run: bash .github/scripts/build-images/set-image-ref.sh
-
- - uses: anchore/sbom-action@v0
- with:
- image: ${{ env.IMG }}
- output-file: sbom.spdx.json
-
- - uses: actions/upload-artifact@v4
- with:
- name: sbom-${{ matrix.service.name }}-${{ matrix.arch.artifact }}
- path: sbom.spdx.json
-
- - uses: aquasecurity/trivy-action@0.28.0
- with:
- image-ref: ${{ env.IMG }}
- severity: HIGH,CRITICAL
- exit-code: '1'
-
- - uses: sigstore/cosign-installer@v3
- with:
- cosign-release: 'v2.4.1'
-
- - name: Cosign Sign Image
- env:
- COSIGN_EXPERIMENTAL: "true"
- run: |
- set -euo pipefail
- cosign sign --yes "${{ env.IMG }}"
-
- push:
- runs-on: ubuntu-latest
- needs:
- - build
- - security
- if: ${{ needs.build.result == 'success' && (github.event_name == 'push' || inputs.push_images == true || github.event.inputs.push_images == 'true') && ((inputs.skip_security == true) || (github.event.inputs.skip_security == 'true') || (needs.security.result == 'success')) }}
-
- strategy:
- fail-fast: false
- matrix:
- registry:
- - ghcr.io
- - docker.io
-
- steps:
- - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
-
- - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f
-
- - uses: actions/download-artifact@v4
- with:
- name: digest-dashboard-linux-amd64
-
- - uses: actions/download-artifact@v4
- with:
- name: digest-dashboard-linux-arm64
-
- - name: Load digests
- env:
- AMD_DIGEST_FILE: digest-dashboard-linux-amd64.txt
- ARM_DIGEST_FILE: digest-dashboard-linux-arm64.txt
- run: bash .github/scripts/build-images/load-manifest-digests.sh
-
- - name: Generate Auto Tags
- id: meta
- uses: ./.github/actions/auto-tag
- with:
- image: ${{ env.REGISTRY }}/${{ env.ORG }}/dashboard
-
- - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9
- if: matrix.registry == 'ghcr.io'
- with:
- registry: ${{ matrix.registry }}
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Create & Push Multi-Arch Manifests (GHCR)
- if: matrix.registry == 'ghcr.io'
- env:
- IMAGE_SHA: ${{ github.sha }}
- TAGS_CSV: ${{ steps.meta.outputs.tags }}
- run: bash .github/scripts/build-images/create-ghcr-manifest.sh
-
- - name: Clone knowledge content
- if: matrix.registry == 'ghcr.io'
- run: git clone https://github.com/Cloud-Neutral-Workshop/knowledge.git knowledge
-
- - name: Validate blog content mount
- if: matrix.registry == 'ghcr.io'
- env:
- IMAGE: ${{ env.REGISTRY }}/${{ env.ORG }}/dashboard@${{ env.MANIFEST_DIGEST }}
- KNOWLEDGE_CONTENT_DIR: ${{ github.workspace }}/knowledge/content
- run: bash .github/scripts/build-images/validate-blog-content-mount.sh
-
- - name: Login to Docker Hub
- if: matrix.registry == 'docker.io'
- uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9
- with:
- registry: docker.io
- username: ${{ secrets.DOCKERHUB_USERNAME }}
- password: ${{ secrets.DOCKERHUB_TOKEN }}
-
- - name: Copy Multi-Arch Image to Docker Hub (skopeo)
- if: matrix.registry == 'docker.io'
- env:
- TARGET_NS: ${{ inputs.dockerhub_namespace || github.event.inputs.dockerhub_namespace || 'cloudneutral' }}
- GHCR_USERNAME: ${{ github.actor }}
- GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
- DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
- run: bash .github/scripts/build-images/copy-image-to-dockerhub.sh
diff --git a/.github/workflows/check-image.yaml b/.github/workflows/check-image.yaml
index 9475579..8c37f19 100644
--- a/.github/workflows/check-image.yaml
+++ b/.github/workflows/check-image.yaml
@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Authenticate to GHCR
- uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9
+ uses: ./.github/actions/docker-login
with:
registry: ghcr.io
username: ${{ github.actor }}
diff --git a/next-env.d.ts b/next-env.d.ts
index 9edff1c..c4b7818 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,6 +1,6 @@
///