# Copyright © 2025-26 l5yth & contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. 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", os: linux, architecture: amd64 } - { name: linux-arm64, platform: linux/arm64, label: "Linux ARM64", os: linux, architecture: arm64 } - { name: linux-armv7, platform: linux/arm/v7, label: "Linux ARMv7", os: linux, architecture: arm } 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 RAW_VERSION="${{ github.event.inputs.version }}" else RAW_VERSION=${GITHUB_REF#refs/tags/} fi STRIPPED_VERSION=${RAW_VERSION#v} echo "version=$STRIPPED_VERSION" >> $GITHUB_OUTPUT echo "version_with_v=v$STRIPPED_VERSION" >> $GITHUB_OUTPUT echo "raw_version=$RAW_VERSION" >> $GITHUB_OUTPUT echo "Published version: $STRIPPED_VERSION" - name: Determine tagging strategy id: tagging env: EVENT_NAME: ${{ github.event_name }} PUBLISH_ALL_VARIANTS: ${{ github.event.inputs.publish_all_variants || 'false' }} run: | VERSION="${{ steps.version.outputs.version }}" if echo "$VERSION" | grep -E -- '-(rc|beta|alpha|dev)'; then IS_PRERELEASE=true else IS_PRERELEASE=false fi if [ "$IS_PRERELEASE" = "false" ] && { [ "$EVENT_NAME" = "push" ] || [ "$PUBLISH_ALL_VARIANTS" = "true" ]; }; then INCLUDE_LATEST=true else INCLUDE_LATEST=false fi echo "is_prerelease=$IS_PRERELEASE" >> $GITHUB_OUTPUT echo "include_latest=$INCLUDE_LATEST" >> $GITHUB_OUTPUT - 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 }}:${{ steps.version.outputs.version }} ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-${{ matrix.service }}-${{ matrix.architecture.name }}:${{ steps.version.outputs.version_with_v }} ${{ steps.tagging.outputs.include_latest == 'true' && format('{0}/{1}-{2}-{3}:latest', env.REGISTRY, env.IMAGE_PREFIX, matrix.service, matrix.architecture.name) || '' }} 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.architecture }} org.opencontainers.image.os=${{ matrix.architecture.os }} 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: | RAW_VERSION=${GITHUB_REF#refs/tags/} STRIPPED_VERSION=${RAW_VERSION#v} echo "version=$STRIPPED_VERSION" >> $GITHUB_OUTPUT echo "version_with_v=v$STRIPPED_VERSION" >> $GITHUB_OUTPUT - name: Detect pre-release tag id: tagging run: | VERSION="${{ steps.version.outputs.version }}" if echo "$VERSION" | grep -E -- '-(rc|beta|alpha|dev)'; then INCLUDE_LATEST=false else INCLUDE_LATEST=true fi echo "include_latest=$INCLUDE_LATEST" >> $GITHUB_OUTPUT - name: Test web application (Linux AMD64) run: | docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-web-linux-amd64:${{ steps.version.outputs.version }} docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-web-linux-amd64:${{ steps.version.outputs.version_with_v }} 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 pull ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-ingestor-linux-amd64:${{ steps.version.outputs.version_with_v }} 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 if [ "${{ steps.tagging.outputs.include_latest }}" = "true" ]; then 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 fi # Ingestor images echo "### 📡 Ingestor Service" >> $GITHUB_STEP_SUMMARY if [ "${{ steps.tagging.outputs.include_latest }}" = "true" ]; then 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 fi