name: PR Docker Build Check # Lightweight build check on PR only, no image push # Strategy: Quick verify amd64 + spot check arm64 (backend only) on: pull_request: branches: - main - dev paths: - 'docker/**' - 'Dockerfile*' - 'go.mod' - 'go.sum' - '**.go' - 'web/**' - '.github/workflows/docker-build.yml' - '.github/workflows/pr-docker-check.yml' jobs: # Quick check: amd64 builds for all images docker-build-amd64: name: Build Check (amd64) runs-on: ubuntu-22.04 permissions: contents: read strategy: fail-fast: false matrix: include: - name: backend dockerfile: ./docker/Dockerfile.backend test_run: true # Needs test run - name: frontend dockerfile: ./docker/Dockerfile.frontend test_run: true steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build ${{ matrix.name }} image (amd64) id: build uses: docker/build-push-action@v5 with: context: . file: ${{ matrix.dockerfile }} platforms: linux/amd64 push: false load: true # Load into local Docker for test run tags: nofx-${{ matrix.name }}:pr-test cache-from: type=gha,scope=${{ matrix.name }}-amd64 cache-to: type=gha,mode=max,scope=${{ matrix.name }}-amd64 build-args: | BUILD_DATE=${{ github.event.pull_request.updated_at }} VCS_REF=${{ github.event.pull_request.head.sha }} VERSION=pr-${{ github.event.pull_request.number }} - name: Test run container (smoke test) if: matrix.test_run timeout-minutes: 2 run: | echo "๐Ÿงช Testing container startup..." # Start container docker run -d --name test-${{ matrix.name }} \ --health-cmd="exit 0" \ nofx-${{ matrix.name }}:pr-test # Wait for container to start (up to 30 seconds) for i in {1..30}; do if docker ps | grep -q test-${{ matrix.name }}; then echo "โœ… Container started successfully" docker logs test-${{ matrix.name }} docker stop test-${{ matrix.name }} || true exit 0 fi sleep 1 done echo "โŒ Container failed to start" docker logs test-${{ matrix.name }} || true exit 1 - name: Check image size run: | SIZE=$(docker image inspect nofx-${{ matrix.name }}:pr-test --format='{{.Size}}') SIZE_MB=$((SIZE / 1024 / 1024)) echo "๐Ÿ“ฆ Image size: ${SIZE_MB} MB" # Warning thresholds if [ "${{ matrix.name }}" = "backend" ] && [ $SIZE_MB -gt 500 ]; then echo "โš ๏ธ Warning: Backend image is larger than 500MB" elif [ "${{ matrix.name }}" = "frontend" ] && [ $SIZE_MB -gt 200 ]; then echo "โš ๏ธ Warning: Frontend image is larger than 200MB" else echo "โœ… Image size is reasonable" fi # ARM64 native build check: Uses GitHub native ARM64 runner (fast!) docker-build-arm64-native: name: Build Check (arm64 native - backend) runs-on: ubuntu-22.04-arm # Native ARM64 runner permissions: contents: read steps: - name: Checkout code uses: actions/checkout@v4 # Native ARM64 does not need QEMU, builds directly - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build backend image (arm64 native) uses: docker/build-push-action@v5 timeout-minutes: 15 # Native builds are faster! with: context: . file: ./docker/Dockerfile.backend platforms: linux/arm64 push: false load: true # Load locally for testing tags: nofx-backend:pr-test-arm64 cache-from: type=gha,scope=backend-arm64 cache-to: type=gha,mode=max,scope=backend-arm64 build-args: | BUILD_DATE=${{ github.event.pull_request.updated_at }} VCS_REF=${{ github.event.pull_request.head.sha }} VERSION=pr-${{ github.event.pull_request.number }} - name: Test run ARM64 container timeout-minutes: 2 run: | echo "๐Ÿงช Testing ARM64 container startup..." # Start container docker run -d --name test-backend-arm64 \ --health-cmd="exit 0" \ nofx-backend:pr-test-arm64 # Wait for startup for i in {1..30}; do if docker ps | grep -q test-backend-arm64; then echo "โœ… ARM64 container started successfully" docker logs test-backend-arm64 docker stop test-backend-arm64 || true exit 0 fi sleep 1 done echo "โŒ ARM64 container failed to start" docker logs test-backend-arm64 || true exit 1 - name: ARM64 build summary run: | echo "โœ… Backend ARM64 native build successful!" echo "Using GitHub native ARM64 runner - no QEMU needed!" echo "Build time is ~3x faster than emulation" # Aggregate check results check-summary: name: Docker Build Summary needs: [docker-build-amd64, docker-build-arm64-native] runs-on: ubuntu-22.04 if: always() permissions: pull-requests: write # For posting comments steps: - name: Check build results id: check run: | echo "## ๐Ÿณ Docker Build Check Results" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY # Check amd64 build if [[ "${{ needs.docker-build-amd64.result }}" == "success" ]]; then echo "โœ… **AMD64 builds**: All passed" >> $GITHUB_STEP_SUMMARY AMD64_OK=true else echo "โŒ **AMD64 builds**: Failed" >> $GITHUB_STEP_SUMMARY AMD64_OK=false fi # Check arm64 build if [[ "${{ needs.docker-build-arm64-native.result }}" == "success" ]]; then echo "โœ… **ARM64 build** (native): Backend passed (frontend will be verified after merge)" >> $GITHUB_STEP_SUMMARY ARM64_OK=true else echo "โŒ **ARM64 build** (native): Backend failed" >> $GITHUB_STEP_SUMMARY ARM64_OK=false fi echo "" >> $GITHUB_STEP_SUMMARY if [ "$AMD64_OK" = true ] && [ "$ARM64_OK" = true ]; then echo "### ๐ŸŽ‰ All checks passed!" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "After merge:" >> $GITHUB_STEP_SUMMARY echo "- Full multi-arch builds (amd64 + arm64) will run in parallel" >> $GITHUB_STEP_SUMMARY echo "- Estimated time: 15-20 minutes" >> $GITHUB_STEP_SUMMARY exit 0 else echo "### โŒ Build checks failed" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "Please check the build logs above and fix the errors." >> $GITHUB_STEP_SUMMARY exit 1 fi - name: Comment on PR if: always() && github.event.pull_request.head.repo.full_name == github.repository uses: actions/github-script@v7 with: script: | const amd64Status = '${{ needs.docker-build-amd64.result }}'; const arm64Status = '${{ needs.docker-build-arm64-native.result }}'; const successIcon = 'โœ…'; const failIcon = 'โŒ'; const comment = [ '## ๐Ÿณ Docker Build Check Results', '', `**AMD64 builds**: ${amd64Status === 'success' ? successIcon : failIcon} ${amd64Status}`, `**ARM64 build** (native runner): ${arm64Status === 'success' ? successIcon : failIcon} ${arm64Status}`, '', amd64Status === 'success' && arm64Status === 'success' ? '### ๐ŸŽ‰ All Docker builds passed!\n\nโœจ Using GitHub native ARM64 runners - 3x faster than emulation!\n\nAfter merge, full multi-arch builds will run in ~10-12 minutes.' : '### โš ๏ธ Some builds failed\n\nPlease check the Actions tab for details.', '', 'Checked: Backend (amd64 + arm64 native), Frontend (amd64) | Powered by GitHub ARM64 Runners' ].join('\n'); await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.pull_request.number, body: comment });