feat: matrix support (part 1) #482
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Docker | |
| on: | |
| push: | |
| branches: [main, "v*.*"] | |
| tags: ["v*"] | |
| paths-ignore: | |
| - "docs/**" | |
| - "**.md" | |
| - "devenv/**" | |
| release: | |
| types: [published] | |
| pull_request: | |
| branches: [main, "v*.*"] | |
| paths-ignore: | |
| - "docs/**" | |
| - "**.md" | |
| - "devenv/**" | |
| workflow_dispatch: | |
| concurrency: | |
| group: docker-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| PUSH: ${{ github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/v') || startsWith(github.ref, 'refs/tags/') || github.event_name == 'release') }} | |
| REGISTRY: ghcr.io | |
| permissions: | |
| contents: read | |
| packages: write | |
| id-token: write | |
| jobs: | |
| build: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| image: [server, agent, web, mcp, browser, sparse] | |
| platform: [linux/amd64, linux/arm64] | |
| include: | |
| - image: server | |
| dockerfile: docker/Dockerfile.server | |
| - image: agent | |
| dockerfile: docker/Dockerfile.agent | |
| - image: web | |
| dockerfile: docker/Dockerfile.web | |
| - image: mcp | |
| dockerfile: docker/Dockerfile.mcp | |
| - image: browser | |
| dockerfile: docker/Dockerfile.browser | |
| - image: sparse | |
| dockerfile: docker/Dockerfile.sparse | |
| - platform: linux/amd64 | |
| runner: ubuntu-latest | |
| - platform: linux/arm64 | |
| runner: ubuntu-24.04-arm | |
| runs-on: ${{ matrix.runner }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Set up Go | |
| if: matrix.image == 'server' || matrix.image == 'mcp' | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.25' | |
| cache: true | |
| - name: Pre-warm Go mod cache | |
| if: matrix.image == 'server' || matrix.image == 'mcp' | |
| run: | | |
| mkdir -p .go-cache | |
| GOMODCACHE=$(pwd)/.go-cache go mod download | |
| - name: Login to Docker Hub | |
| if: env.PUSH == 'true' | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Login to GitHub Container Registry | |
| if: env.PUSH == 'true' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and push by digest | |
| id: build | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: ${{ matrix.dockerfile }} | |
| platforms: ${{ matrix.platform }} | |
| outputs: ${{ env.PUSH == 'true' && format('type=image,"name={0}/{1}/{2}",push-by-digest=true,name-canonical=true,push=true,compression=zstd', env.REGISTRY, github.repository_owner, matrix.image) || '' }} | |
| build-contexts: ${{ (matrix.image == 'server' || matrix.image == 'mcp') && format('gomodcache={0}/.go-cache', github.workspace) || '' }} | |
| build-args: | | |
| VERSION=${{ github.ref_name }} | |
| COMMIT_HASH=${{ github.sha }} | |
| VITE_API_URL=/api | |
| VITE_AGENT_URL=/agent | |
| cache-from: | | |
| type=gha,scope=${{ matrix.image }}-${{ matrix.platform }} | |
| type=registry,ref=${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ matrix.image }}:buildcache-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }} | |
| cache-to: | | |
| type=gha,scope=${{ matrix.image }}-${{ matrix.platform }},mode=max | |
| ${{ env.PUSH == 'true' && format('type=registry,ref={0}/{1}/{2}:buildcache-{3},mode=max,compression=zstd', env.REGISTRY, github.repository_owner, matrix.image, matrix.platform == 'linux/amd64' && 'amd64' || 'arm64') || '' }} | |
| - name: Export digest | |
| if: env.PUSH == 'true' | |
| run: | | |
| mkdir -p /tmp/digests | |
| digest="${{ steps.build.outputs.digest }}" | |
| touch "/tmp/digests/${digest#sha256:}" | |
| - name: Upload digest | |
| if: env.PUSH == 'true' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: digests-${{ matrix.image }}-${{ strategy.job-index }} | |
| path: /tmp/digests/* | |
| if-no-files-found: error | |
| retention-days: 1 | |
| merge: | |
| runs-on: ubuntu-latest | |
| if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/v') || startsWith(github.ref, 'refs/tags/') || github.event_name == 'release') | |
| needs: build | |
| strategy: | |
| matrix: | |
| image: [server, agent, web, mcp, browser, sparse] | |
| steps: | |
| - name: Download digests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: /tmp/digests | |
| pattern: digests-${{ matrix.image }}-* | |
| merge-multiple: true | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Login to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Docker meta | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: | | |
| memohai/${{ matrix.image }} | |
| ghcr.io/${{ github.repository_owner }}/${{ matrix.image }} | |
| tags: | | |
| type=raw,value=dev,enable=${{ github.ref == 'refs/heads/main' }} | |
| type=raw,value=${{ github.ref_name }}-dev,enable=${{ startsWith(github.ref, 'refs/heads/v') }} | |
| type=raw,value=latest,enable=${{ github.event_name == 'release' || (startsWith(github.ref, 'refs/tags/') && !contains(github.ref_name, '-')) }} | |
| type=ref,event=pr | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| - name: Create manifest list and push | |
| working-directory: /tmp/digests | |
| run: | | |
| docker buildx imagetools create \ | |
| $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ | |
| $(printf 'ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}@sha256:%s ' *) | |
| env: | |
| DOCKER_METADATA_OUTPUT_JSON: ${{ steps.meta.outputs.json }} |