name: Build and Push Docker Images on: push: tags: [ 'v*' ] workflow_dispatch: inputs: version: description: 'Version to publish (e.g., 1.0.0)' required: true default: '1.0.0' publish_all_variants: description: 'Publish all Docker image variants (latest tag)' type: boolean default: false env: REGISTRY: ghcr.io IMAGE_PREFIX: l5yth/potato-mesh jobs: build-and-push: runs-on: ubuntu-latest if: (startsWith(github.ref, 'refs/tags/v') && github.event_name == 'push') || github.event_name == 'workflow_dispatch' environment: production permissions: contents: read packages: write strategy: matrix: service: [web, ingestor] architecture: - { name: linux-amd64, platform: linux/amd64, label: "Linux x86_64" } - { name: linux-arm64, platform: linux/arm64, label: "Linux ARM64" } - { name: linux-armv7, platform: linux/arm/v7, label: "Linux ARMv7" } steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up QEMU emulation uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract version from tag or input id: version run: | if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then VERSION="${{ github.event.inputs.version }}" else VERSION=${GITHUB_REF#refs/tags/v} fi echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Published version: $VERSION" - name: Build and push ${{ matrix.service }} for ${{ matrix.architecture.name }} uses: docker/build-push-action@v5 with: context: . file: ./${{ matrix.service == 'web' && 'web/Dockerfile' || 'data/Dockerfile' }} target: production platforms: ${{ matrix.architecture.platform }} push: true tags: | ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-${{ matrix.service }}-${{ matrix.architecture.name }}:latest ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-${{ matrix.service }}-${{ matrix.architecture.name }}:${{ steps.version.outputs.version }} labels: | org.opencontainers.image.source=https://github.com/${{ github.repository }} org.opencontainers.image.description=PotatoMesh ${{ matrix.service == 'web' && 'Web Application' || 'Python Ingestor' }} for ${{ matrix.architecture.label }} org.opencontainers.image.licenses=Apache-2.0 org.opencontainers.image.version=${{ steps.version.outputs.version }} org.opencontainers.image.created=${{ github.event.head_commit.timestamp }} org.opencontainers.image.revision=${{ github.sha }} org.opencontainers.image.title=PotatoMesh ${{ matrix.service == 'web' && 'Web' || 'Ingestor' }} (${{ matrix.architecture.label }}) org.opencontainers.image.vendor=PotatoMesh org.opencontainers.image.architecture=${{ matrix.architecture.name }} org.opencontainers.image.os=linux org.opencontainers.image.arch=${{ matrix.architecture.name }} cache-from: type=gha,scope=${{ matrix.service }}-${{ matrix.architecture.name }} cache-to: type=gha,mode=max,scope=${{ matrix.service }}-${{ matrix.architecture.name }} test-images: runs-on: ubuntu-latest needs: build-and-push if: startsWith(github.ref, 'refs/tags/v') && github.event_name == 'push' steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract version from tag id: version run: | VERSION=${GITHUB_REF#refs/tags/v} echo "version=$VERSION" >> $GITHUB_OUTPUT - name: Test web application (Linux AMD64) run: | docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-web-linux-amd64:${{ steps.version.outputs.version }} docker run --rm -d --name web-test -p 41447:41447 \ -e API_TOKEN=test-token \ -e DEBUG=1 \ ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-web-linux-amd64:${{ steps.version.outputs.version }} sleep 10 curl -f http://localhost:41447/ || exit 1 docker stop web-test - name: Test ingestor (Linux AMD64) run: | docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-ingestor-linux-amd64:${{ steps.version.outputs.version }} docker run --rm --name ingestor-test \ -e POTATOMESH_INSTANCE=http://localhost:41447 \ -e API_TOKEN=test-token \ -e CONNECTION=mock \ -e DEBUG=1 \ ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-ingestor-linux-amd64:${{ steps.version.outputs.version }} & sleep 5 docker stop ingestor-test || true publish-summary: runs-on: ubuntu-latest needs: [build-and-push, test-images] if: always() && startsWith(github.ref, 'refs/tags/v') && github.event_name == 'push' steps: - name: Extract version from tag id: version run: | VERSION=${GITHUB_REF#refs/tags/v} echo "version=$VERSION" >> $GITHUB_OUTPUT - name: Publish release summary run: | echo "## 🚀 PotatoMesh Images Published to GHCR" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "**Version:** ${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "**Published Images:**" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY # Web images echo "### 🌐 Web Application" >> $GITHUB_STEP_SUMMARY echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-web-linux-amd64:latest\` - Linux x86_64" >> $GITHUB_STEP_SUMMARY echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-web-linux-arm64:latest\` - Linux ARM64" >> $GITHUB_STEP_SUMMARY echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-web-linux-armv7:latest\` - Linux ARMv7" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY # Ingestor images echo "### 📡 Ingestor Service" >> $GITHUB_STEP_SUMMARY echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-ingestor-linux-amd64:latest\` - Linux x86_64" >> $GITHUB_STEP_SUMMARY echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-ingestor-linux-arm64:latest\` - Linux ARM64" >> $GITHUB_STEP_SUMMARY echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-ingestor-linux-armv7:latest\` - Linux ARMv7" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY