diff --git a/.github/actions/build-and-push/action.yml b/.github/actions/build-and-push/action.yml index b149d27d..524981b6 100644 --- a/.github/actions/build-and-push/action.yml +++ b/.github/actions/build-and-push/action.yml @@ -27,6 +27,10 @@ inputs: description: 'Build arguments' required: false default: '' + platforms: + description: 'Target platforms for buildx (comma-separated)' + required: false + default: 'linux/amd64,linux/arm64' runs: using: 'composite' steps: @@ -60,7 +64,7 @@ runs: context: ${{ steps.get_docker_build_context.outputs.dockerfile_dir }} file: ${{ inputs.dockerfile }} multiPlatform: true - platforms: linux/amd64,linux/arm64 + platforms: ${{ inputs.platforms }} build-args: | ${{ inputs.build_args }} ${{ inputs.build_base_image != '' && format('BASE_IMAGE={0}', inputs.build_base_image) || '' }} diff --git a/.github/actions/generate-image-names/action.yml b/.github/actions/generate-image-names/action.yml index aabc2e69..2c372645 100644 --- a/.github/actions/generate-image-names/action.yml +++ b/.github/actions/generate-image-names/action.yml @@ -18,11 +18,7 @@ inputs: expt_image_naming: description: 'Enable experimental base image naming conventions' required: false - type: choice - options: - - 'images' - - 'runtimes' - - 'none' + # Allowed values: images, runtimes, none default: 'none' outputs: ghcr_image_name: diff --git a/.github/workflows/build-all-expt-images-and-runtimes.yaml b/.github/workflows/build-all-expt-images-and-runtimes.yaml new file mode 100644 index 00000000..8ebdeba2 --- /dev/null +++ b/.github/workflows/build-all-expt-images-and-runtimes.yaml @@ -0,0 +1,205 @@ +name: Build All Expt Images And Runtimes + +on: + workflow_dispatch: + inputs: + tag: + description: 'Tag for the Docker image' + required: true + default: 'latest' + tools_version: + description: 'Base tools version (optional, defaults to tag if not specified)' + required: false + type: string + default: '' + os_version: + description: 'OS image version (optional, defaults to tag if not specified)' + required: false + type: string + default: '' + framework_image_version: + description: 'Framework image version (optional, defaults to tag if not specified)' + required: false + type: string + default: '' + l10n: + description: 'Localization setting (choose one or both)' + required: false + type: choice + options: + - en_US + - zh_CN + - both + default: 'en_US' + arch: + description: 'System architecture (choose one or both)' + required: false + type: choice + options: + - amd64 + - arm64 + - both + default: 'amd64' + aliyun_enabled: + description: 'Enable Aliyun ACR builds' + required: false + type: boolean + default: false + +permissions: + contents: read + packages: write + +jobs: + build-tools: + name: Tools Image + uses: ./.github/workflows/build-expt-tools.yml + with: + image_tag: ${{ inputs.tools_version != '' && inputs.tools_version || inputs.tag }} + architectures: ${{ inputs.arch == 'both' && 'amd64,arm64' || inputs.arch }} + push: true + secrets: inherit + + build-os-base: + name: Base Images (OS) + needs: build-tools + uses: ./.github/workflows/build-expt-image-or-runtime.yaml + with: + tag: ${{ inputs.tag }} + kind: operating-systems + name: '' + build_type: images + tools_version: ${{ needs['build-tools'].outputs.image_tag }} + os_version: ${{ inputs.os_version }} + framework_image_version: ${{ inputs.framework_image_version }} + l10n: ${{ inputs.l10n }} + arch: ${{ inputs.arch }} + aliyun_enabled: ${{ inputs.aliyun_enabled }} + secrets: inherit + + build-language-base: + name: Base Images (Languages) + needs: [build-tools, build-os-base] + uses: ./.github/workflows/build-expt-image-or-runtime.yaml + with: + tag: ${{ inputs.tag }} + kind: languages + name: '' + build_type: images + tools_version: ${{ needs['build-tools'].outputs.image_tag }} + os_version: ${{ inputs.os_version }} + framework_image_version: ${{ inputs.framework_image_version }} + l10n: ${{ inputs.l10n }} + arch: ${{ inputs.arch }} + aliyun_enabled: ${{ inputs.aliyun_enabled }} + secrets: inherit + + build-framework-base: + name: Base Images (Frameworks) + needs: [build-tools, build-language-base] + uses: ./.github/workflows/build-expt-image-or-runtime.yaml + with: + tag: ${{ inputs.tag }} + kind: frameworks + name: '' + build_type: images + tools_version: ${{ needs['build-tools'].outputs.image_tag }} + os_version: ${{ inputs.os_version }} + framework_image_version: ${{ inputs.framework_image_version }} + l10n: ${{ inputs.l10n }} + arch: ${{ inputs.arch }} + aliyun_enabled: ${{ inputs.aliyun_enabled }} + secrets: inherit + + build-os-runtime: + name: Runtime Images (OS) + needs: [build-tools, build-framework-base] + uses: ./.github/workflows/build-expt-image-or-runtime.yaml + with: + tag: ${{ inputs.tag }} + kind: operating-systems + name: '' + build_type: runtimes + tools_version: ${{ needs['build-tools'].outputs.image_tag }} + os_version: ${{ inputs.os_version }} + framework_image_version: ${{ inputs.framework_image_version }} + l10n: ${{ inputs.l10n }} + arch: ${{ inputs.arch }} + aliyun_enabled: ${{ inputs.aliyun_enabled }} + secrets: inherit + + build-language-runtime: + name: Runtime Images (Languages) + needs: [build-tools, build-os-runtime] + uses: ./.github/workflows/build-expt-image-or-runtime.yaml + with: + tag: ${{ inputs.tag }} + kind: languages + name: '' + build_type: runtimes + tools_version: ${{ needs['build-tools'].outputs.image_tag }} + os_version: ${{ inputs.os_version }} + framework_image_version: ${{ inputs.framework_image_version }} + l10n: ${{ inputs.l10n }} + arch: ${{ inputs.arch }} + aliyun_enabled: ${{ inputs.aliyun_enabled }} + secrets: inherit + + build-framework-runtime: + name: Runtime Images (Frameworks) + needs: [build-tools, build-language-runtime] + uses: ./.github/workflows/build-expt-image-or-runtime.yaml + with: + tag: ${{ inputs.tag }} + kind: frameworks + name: '' + build_type: runtimes + tools_version: ${{ needs['build-tools'].outputs.image_tag }} + os_version: ${{ inputs.os_version }} + framework_image_version: ${{ inputs.framework_image_version }} + l10n: ${{ inputs.l10n }} + arch: ${{ inputs.arch }} + aliyun_enabled: ${{ inputs.aliyun_enabled }} + secrets: inherit + + build-summary: + runs-on: ubuntu-latest + needs: + [ + build-tools, + build-os-base, + build-language-base, + build-framework-base, + build-os-runtime, + build-language-runtime, + build-framework-runtime + ] + if: always() + steps: + - name: Build Summary + run: | + echo "## 🎉 Build Summary" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "| Component | Status |" >> $GITHUB_STEP_SUMMARY + echo "|-----------|--------|" >> $GITHUB_STEP_SUMMARY + echo "| Tools Image | ${{ needs.build-tools.result }} |" >> $GITHUB_STEP_SUMMARY + echo "| Base Images (OS) | ${{ needs.build-os-base.result }} |" >> $GITHUB_STEP_SUMMARY + echo "| Base Images (Languages) | ${{ needs.build-language-base.result }} |" >> $GITHUB_STEP_SUMMARY + echo "| Base Images (Frameworks) | ${{ needs.build-framework-base.result }} |" >> $GITHUB_STEP_SUMMARY + echo "| Runtime Images (OS) | ${{ needs.build-os-runtime.result }} |" >> $GITHUB_STEP_SUMMARY + echo "| Runtime Images (Languages) | ${{ needs.build-language-runtime.result }} |" >> $GITHUB_STEP_SUMMARY + echo "| Runtime Images (Frameworks) | ${{ needs.build-framework-runtime.result }} |" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + if [[ "${{ needs.build-tools.result }}" == "success" && \ + "${{ needs.build-os-base.result }}" == "success" && \ + "${{ needs.build-language-base.result }}" == "success" && \ + "${{ needs.build-framework-base.result }}" == "success" && \ + "${{ needs.build-os-runtime.result }}" == "success" && \ + "${{ needs.build-language-runtime.result }}" == "success" && \ + "${{ needs.build-framework-runtime.result }}" == "success" ]]; then + echo "✅ All images and runtimes built successfully!" >> $GITHUB_STEP_SUMMARY + else + echo "❌ Some builds failed. Please check the logs above." >> $GITHUB_STEP_SUMMARY + exit 1 + fi diff --git a/.github/workflows/build-expt-image-or-runtime.yaml b/.github/workflows/build-expt-image-or-runtime.yaml index 3fc387a9..e9d083ce 100644 --- a/.github/workflows/build-expt-image-or-runtime.yaml +++ b/.github/workflows/build-expt-image-or-runtime.yaml @@ -66,6 +66,66 @@ on: required: false type: boolean default: false + workflow_call: + inputs: + tag: + description: 'Tag for the Docker image' + required: true + type: string + kind: + description: 'Type of packages to build' + required: false + type: string + default: 'operating-systems' + name: + description: 'Specific package folder; leave empty to build all packages of the selected kind' + required: false + type: string + default: '' + build_type: + description: 'Type of build to perform' + required: false + type: string + default: 'images' + tools_version: + description: 'Base tools version (optional, defaults to tag if not specified)' + required: false + type: string + default: '' + os_version: + description: 'OS image version (optional, defaults to tag if not specified)' + required: false + type: string + default: '' + framework_image_version: + description: 'Framework image version (optional, defaults to tag if not specified)' + required: false + type: string + default: '' + l10n: + description: 'Localization setting (choose one or both)' + required: false + type: string + default: 'en_US' + arch: + description: 'System architecture (choose one or both)' + required: false + type: string + default: 'amd64' + aliyun_enabled: + description: 'Enable Aliyun ACR builds' + required: false + type: boolean + default: false + secrets: + ALIYUN_REGISTRY: + required: false + ALIYUN_USERNAME: + required: false + ALIYUN_PASSWORD: + required: false + ALIYUN_NAMESPACE: + required: false jobs: # Define expt image matrix @@ -218,6 +278,7 @@ jobs: - name: Build and push standard images uses: ./.github/actions/build-and-push with: + platforms: linux/${{ matrix.arch }} build_args: | REPO=${{ github.repository_owner }}/devbox-base-expt L10N=${{ matrix.l10n.display }} @@ -252,7 +313,7 @@ jobs: docker builder prune -af || true - name: Output built image names (standard) run: | - echo "## 🐳 Built OS Base Images (Standard)" >> $GITHUB_STEP_SUMMARY + echo "## 🐳 Built ${{ inputs.kind }} ${{ inputs.build_type }} (Standard)" >> $GITHUB_STEP_SUMMARY echo "Localization: ${{ matrix.l10n.display }} (normalized: ${{ matrix.l10n.normalized }}), Arch: ${{ matrix.arch }}" >> $GITHUB_STEP_SUMMARY echo "| Image Name | Registry |" >> $GITHUB_STEP_SUMMARY echo "|------------|----------|" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/build-expt-tools.yml b/.github/workflows/build-expt-tools.yml index 9aef245d..699b8657 100644 --- a/.github/workflows/build-expt-tools.yml +++ b/.github/workflows/build-expt-tools.yml @@ -9,10 +9,38 @@ on: architectures: description: 'Comma-separated architectures to build (default: amd64,arm64)' required: false + push: + description: 'Push images to registry' + required: false + type: boolean + default: true + workflow_call: + inputs: + image_tag: + description: 'Custom image tag (defaults to commit SHA)' + required: false + type: string + default: '' + architectures: + description: 'Comma-separated architectures to build (default: amd64,arm64)' + required: false + type: string + default: '' + push: + description: 'Push images to registry' + required: false + type: boolean + default: true + outputs: + image_tag: + description: 'Resolved image tag used for base-tools' + value: ${{ jobs.build.outputs.image_tag }} jobs: build: runs-on: ubuntu-latest + outputs: + image_tag: ${{ steps.params.outputs.image_tag }} permissions: contents: read packages: write @@ -21,10 +49,10 @@ jobs: uses: actions/checkout@v4 - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Compute build parameters id: params @@ -54,23 +82,23 @@ jobs: else echo "add_latest=false" >> $GITHUB_OUTPUT fi - - name: Log in to GHCR (only workflow_dispatch pushes) - if: ${{ github.event_name == 'workflow_dispatch' }} - uses: docker/login-action@v2 + - name: Log in to GHCR (push enabled) + if: ${{ inputs.push }} + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build `base-tools` image (dispatch only pushes) + - name: Build `base-tools` image uses: docker/build-push-action@v5 with: context: ./experimental/base-tools file: ./experimental/base-tools/Dockerfile - push: ${{ github.event_name == 'workflow_dispatch' }} + push: ${{ inputs.push }} platforms: ${{ steps.params.outputs.platforms }} cache-from: type=gha cache-to: type=gha,mode=max tags: | ghcr.io/${{ github.repository_owner }}/devbox-base-expt/base-tools:${{ steps.params.outputs.image_tag }} - ${{ steps.params.outputs.add_latest == 'true' && format('ghcr.io/{0}/devbox-base-expt/base-tools:latest', github.repository_owner) || '' }} \ No newline at end of file + ${{ steps.params.outputs.add_latest == 'true' && format('ghcr.io/{0}/devbox-base-expt/base-tools:latest', github.repository_owner) || '' }}