diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2011314..4234966 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,6 +10,7 @@ jobs: build: runs-on: ${{ matrix.runner }} strategy: + fail-fast: false matrix: include: - runner: ubuntu-24.04 @@ -17,24 +18,64 @@ jobs: - runner: ubuntu-24.04-arm arch: arm64 + outputs: + image-tag: ${{ steps.tag.outputs.tag }} + steps: - name: "Checkout code" uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: "Generate image tag" + id: tag + run: | + GIT_COMMIT=$(git rev-parse --short=7 HEAD) + echo "tag=${GIT_COMMIT}" >> $GITHUB_OUTPUT + echo "platform-tag=${GIT_COMMIT}-${{ matrix.arch }}" >> $GITHUB_OUTPUT - name: "Login to Docker Hub" uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} - - - name: "Build and Test Docker Image" + + - name: "Build Docker image" + run: make docker_image env: PLATFORM: ${{ matrix.arch }} - run: | - make docker_image DOCKER_TAG=${{ github.sha }} - make docker_test - - - name: "Push Docker image" + DOCKER_TAG: ${{ steps.tag.outputs.platform-tag }} + + - name: "Test Docker image" + run: make docker_test env: PLATFORM: ${{ matrix.arch }} + DOCKER_TAG: ${{ steps.tag.outputs.platform-tag }} + + - name: "Push Docker image" run: make docker_push + env: + PLATFORM: ${{ matrix.arch }} + DOCKER_TAG: ${{ steps.tag.outputs.platform-tag }} + + manifest: + runs-on: ubuntu-latest + needs: build + if: success() + + steps: + - name: "Checkout code" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: "Login to Docker Hub" + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: "Create and push manifest" + run: make docker_manifest + env: + DOCKER_TAG: ${{ needs.build.outputs.image-tag }} diff --git a/Makefile b/Makefile index e946703..5da6ba1 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ DOCKER_BUILDKIT ?= 1 BUILD_DATE := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ") VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev") -.PHONY: help docker_image docker_push docker_clean info security_scan +.PHONY: help docker_image docker_push docker_clean info security_scan docker_manifest help: ## Show this help message @echo "BeamSim Docker Build" @@ -134,6 +134,17 @@ docker_size: ## Show image size information @echo "Layer breakdown:" docker history $(FULL_IMAGE_NAME) +# Create and push multi-architecture manifest +docker_manifest: ## Create and push multi-architecture manifest + @echo "Creating multi-architecture manifest for $(DOCKER_TAG)..." + docker manifest create --amend \ + $(DOCKER_REGISTRY)/$(IMAGE_NAME):$(DOCKER_TAG) \ + $(DOCKER_REGISTRY)/$(IMAGE_NAME):$(DOCKER_TAG)-amd64 \ + $(DOCKER_REGISTRY)/$(IMAGE_NAME):$(DOCKER_TAG)-arm64 + @echo "Pushing manifest..." + docker manifest push $(DOCKER_REGISTRY)/$(IMAGE_NAME):$(DOCKER_TAG) + @echo "Multi-architecture manifest created and pushed successfully!" + # Clean all clean: docker_clean ## Clean all build artifacts @echo "Cleaning build artifacts..." diff --git a/docs/BUILD.md b/docs/BUILD.md index ee2ced6..7ed0bd4 100644 --- a/docs/BUILD.md +++ b/docs/BUILD.md @@ -211,6 +211,22 @@ make docker_buildx make docker_buildx DOCKER_REGISTRY=your-registry.com/beamsim ``` +### Manual Multi-Architecture Workflow + +For more control over the build process, you can build each architecture separately and create a manifest: + +```bash +# Build for each architecture +make docker_image PLATFORM=amd64 DOCKER_TAG=v1.0.0-amd64 +make docker_push DOCKER_TAG=v1.0.0-amd64 + +make docker_image PLATFORM=arm64 DOCKER_TAG=v1.0.0-arm64 +make docker_push DOCKER_TAG=v1.0.0-arm64 + +# Create multi-architecture manifest +make docker_manifest DOCKER_TAG=v1.0.0 DOCKER_REGISTRY=your-registry.com +``` + **Note**: Multi-platform builds automatically push to the registry (default: `qdrvm`). Make sure you're logged in: ```bash docker login # For Docker Hub (default) diff --git a/docs/MAKEFILE.md b/docs/MAKEFILE.md index 55ddf8d..7e7a360 100644 --- a/docs/MAKEFILE.md +++ b/docs/MAKEFILE.md @@ -74,6 +74,25 @@ make docker_push DOCKER_REGISTRY=ghcr.io/myorg - Docker login credentials configured - Image must be built first +### `docker_manifest` +Creates and pushes multi-architecture manifest from existing platform-specific images. + +```bash +make docker_manifest DOCKER_TAG=v1.0.0 DOCKER_REGISTRY=your-registry.com +``` + +**Requirements:** +- Both `amd64` and `arm64` images must already be pushed to registry +- `DOCKER_REGISTRY` must be set +- Docker login credentials configured + +**Process:** +1. Creates manifest referencing remote platform-specific images (`-amd64` and `-arm64` tagged) +2. Pushes manifest to registry under the specified tag +3. Enables `docker pull` to automatically select correct architecture + +**Note:** This command works directly with remote registry images without pulling them locally. The `--amend` flag allows overwriting existing manifests if needed. + ## Development Targets ### `docker_shell` @@ -239,8 +258,15 @@ make docker_push make docker_image PLATFORM=amd64 make docker_image PLATFORM=arm64 -# Multi-platform release +# Multi-platform release (automated) make docker_buildx + +# Multi-platform release (manual) +make docker_image PLATFORM=amd64 DOCKER_TAG=v1.0.0-amd64 +make docker_push DOCKER_TAG=v1.0.0-amd64 +make docker_image PLATFORM=arm64 DOCKER_TAG=v1.0.0-arm64 +make docker_push DOCKER_TAG=v1.0.0-arm64 +make docker_manifest DOCKER_TAG=v1.0.0 ``` ### Experimentation