From e89e83243afa79e741615063fa9d3e940d4aa2fd Mon Sep 17 00:00:00 2001 From: -LAN- Date: Sat, 28 Mar 2026 06:50:19 +0800 Subject: [PATCH] narrow docker builds --- .github/workflows/build-push.yml | 186 +++++++++++++++++++++++------ .github/workflows/docker-build.yml | 72 +++++++---- 2 files changed, 201 insertions(+), 57 deletions(-) diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index 1ae8d44482..62caf8b398 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -23,27 +23,41 @@ env: DIFY_API_IMAGE_NAME: ${{ vars.DIFY_API_IMAGE_NAME || 'langgenius/dify-api' }} jobs: - build: + check-changes: + runs-on: ubuntu-latest + outputs: + api: ${{ steps.changes.outputs.api }} + web: ${{ steps.changes.outputs.web }} + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 2 + persist-credentials: false + + - name: Check changed files + id: changes + uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 + with: + filters: | + api: + - 'api/**' + - 'docker/**' + web: + - 'web/**' + - 'docker/**' + + build-api: + name: Build API Images + needs: check-changes + if: github.repository == 'langgenius/dify' && (startsWith(github.ref, 'refs/tags/') || needs.check-changes.outputs.api == 'true') runs-on: ${{ matrix.platform == 'linux/arm64' && 'arm64_runner' || 'ubuntu-latest' }} - if: github.repository == 'langgenius/dify' strategy: matrix: include: - service_name: "build-api-amd64" - image_name_env: "DIFY_API_IMAGE_NAME" - context: "api" platform: linux/amd64 - service_name: "build-api-arm64" - image_name_env: "DIFY_API_IMAGE_NAME" - context: "api" - platform: linux/arm64 - - service_name: "build-web-amd64" - image_name_env: "DIFY_WEB_IMAGE_NAME" - context: "web" - platform: linux/amd64 - - service_name: "build-web-arm64" - image_name_env: "DIFY_WEB_IMAGE_NAME" - context: "web" platform: linux/arm64 steps: @@ -68,17 +82,17 @@ jobs: id: meta uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 with: - images: ${{ env[matrix.image_name_env] }} + images: ${{ env.DIFY_API_IMAGE_NAME }} - name: Build Docker image id: build uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 with: - context: "{{defaultContext}}:${{ matrix.context }}" + context: "{{defaultContext}}:api" platforms: ${{ matrix.platform }} build-args: COMMIT_SHA=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} labels: ${{ steps.meta.outputs.labels }} - outputs: type=image,name=${{ env[matrix.image_name_env] }},push-by-digest=true,name-canonical=true,push=true + outputs: type=image,name=${{ env.DIFY_API_IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true cache-from: type=gha,scope=${{ matrix.service_name }} cache-to: type=gha,mode=max,scope=${{ matrix.service_name }} @@ -93,30 +107,23 @@ jobs: - name: Upload digest uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: - name: digests-${{ matrix.context }}-${{ env.PLATFORM_PAIR }} + name: digests-api-${{ env.PLATFORM_PAIR }} path: /tmp/digests/* if-no-files-found: error retention-days: 1 - create-manifest: - needs: build + merge-api-images: + needs: + - check-changes + - build-api runs-on: ubuntu-latest - if: github.repository == 'langgenius/dify' - strategy: - matrix: - include: - - service_name: "merge-api-images" - image_name_env: "DIFY_API_IMAGE_NAME" - context: "api" - - service_name: "merge-web-images" - image_name_env: "DIFY_WEB_IMAGE_NAME" - context: "web" + if: github.repository == 'langgenius/dify' && (startsWith(github.ref, 'refs/tags/') || needs.check-changes.outputs.api == 'true') steps: - name: Download digests uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: /tmp/digests - pattern: digests-${{ matrix.context }}-* + pattern: digests-api-* merge-multiple: true - name: Login to Docker Hub @@ -129,7 +136,7 @@ jobs: id: meta uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 with: - images: ${{ env[matrix.image_name_env] }} + images: ${{ env.DIFY_API_IMAGE_NAME }} tags: | type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/') && !contains(github.ref, '-') }} type=ref,event=branch @@ -139,14 +146,125 @@ jobs: - name: Create manifest list and push working-directory: /tmp/digests env: - IMAGE_NAME: ${{ env[matrix.image_name_env] }} + IMAGE_NAME: ${{ env.DIFY_API_IMAGE_NAME }} run: | docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ $(printf "$IMAGE_NAME@sha256:%s " *) - name: Inspect image env: - IMAGE_NAME: ${{ env[matrix.image_name_env] }} + IMAGE_NAME: ${{ env.DIFY_API_IMAGE_NAME }} + IMAGE_VERSION: ${{ steps.meta.outputs.version }} + run: | + docker buildx imagetools inspect "$IMAGE_NAME:$IMAGE_VERSION" + + build-web: + name: Build Web Images + needs: check-changes + if: github.repository == 'langgenius/dify' && (startsWith(github.ref, 'refs/tags/') || needs.check-changes.outputs.web == 'true') + runs-on: ${{ matrix.platform == 'linux/arm64' && 'arm64_runner' || 'ubuntu-latest' }} + strategy: + matrix: + include: + - service_name: "build-web-amd64" + platform: linux/amd64 + - service_name: "build-web-arm64" + platform: linux/arm64 + + steps: + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + + - name: Login to Docker Hub + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 + with: + username: ${{ env.DOCKERHUB_USER }} + password: ${{ env.DOCKERHUB_TOKEN }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 + + - name: Extract metadata for Docker + id: meta + uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 + with: + images: ${{ env.DIFY_WEB_IMAGE_NAME }} + + - name: Build Docker image + id: build + uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 + with: + context: "{{defaultContext}}:web" + platforms: ${{ matrix.platform }} + build-args: COMMIT_SHA=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=${{ env.DIFY_WEB_IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true + cache-from: type=gha,scope=${{ matrix.service_name }} + cache-to: type=gha,mode=max,scope=${{ matrix.service_name }} + + - name: Export digest + env: + DIGEST: ${{ steps.build.outputs.digest }} + run: | + mkdir -p /tmp/digests + sanitized_digest=${DIGEST#sha256:} + touch "/tmp/digests/${sanitized_digest}" + + - name: Upload digest + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: digests-web-${{ env.PLATFORM_PAIR }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge-web-images: + needs: + - check-changes + - build-web + runs-on: ubuntu-latest + if: github.repository == 'langgenius/dify' && (startsWith(github.ref, 'refs/tags/') || needs.check-changes.outputs.web == 'true') + steps: + - name: Download digests + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + path: /tmp/digests + pattern: digests-web-* + merge-multiple: true + + - name: Login to Docker Hub + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 + with: + username: ${{ env.DOCKERHUB_USER }} + password: ${{ env.DOCKERHUB_TOKEN }} + + - name: Extract metadata for Docker + id: meta + uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 + with: + images: ${{ env.DIFY_WEB_IMAGE_NAME }} + tags: | + type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/') && !contains(github.ref, '-') }} + type=ref,event=branch + type=sha,enable=true,priority=100,prefix=,suffix=,format=long + type=raw,value=${{ github.ref_name }},enable=${{ startsWith(github.ref, 'refs/tags/') }} + + - name: Create manifest list and push + working-directory: /tmp/digests + env: + IMAGE_NAME: ${{ env.DIFY_WEB_IMAGE_NAME }} + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf "$IMAGE_NAME@sha256:%s " *) + + - name: Inspect image + env: + IMAGE_NAME: ${{ env.DIFY_WEB_IMAGE_NAME }} IMAGE_VERSION: ${{ steps.meta.outputs.version }} run: | docker buildx imagetools inspect "$IMAGE_NAME:$IMAGE_VERSION" diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 340b380dc9..56f048c0fc 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -13,27 +13,34 @@ concurrency: cancel-in-progress: true jobs: - build-docker: + check-changes: runs-on: ubuntu-latest - strategy: - matrix: - include: - - service_name: "api-amd64" - platform: linux/amd64 - context: "api" - - service_name: "api-arm64" - platform: linux/arm64 - context: "api" - - service_name: "web-amd64" - platform: linux/amd64 - context: "web" - - service_name: "web-arm64" - platform: linux/arm64 - context: "web" + outputs: + api: ${{ steps.changes.outputs.api }} + web: ${{ steps.changes.outputs.web }} steps: - - name: Set up QEMU - uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 2 + persist-credentials: false + - name: Check changed files + id: changes + uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 + with: + filters: | + api: + - 'api/Dockerfile' + web: + - 'web/Dockerfile' + + build-api: + name: Build API Docker Image + needs: check-changes + if: needs.check-changes.outputs.api == 'true' + runs-on: ubuntu-latest + steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 @@ -41,8 +48,27 @@ jobs: uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 with: push: false - context: "{{defaultContext}}:${{ matrix.context }}" - file: "${{ matrix.file }}" - platforms: ${{ matrix.platform }} - cache-from: type=gha - cache-to: type=gha,mode=max + context: "{{defaultContext}}:api" + file: Dockerfile + platforms: linux/amd64 + cache-from: type=gha,scope=api-pr + cache-to: type=gha,mode=max,scope=api-pr + + build-web: + name: Build Web Docker Image + needs: check-changes + if: needs.check-changes.outputs.web == 'true' + runs-on: ubuntu-latest + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 + + - name: Build Docker Image + uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 + with: + push: false + context: "{{defaultContext}}:web" + file: Dockerfile + platforms: linux/amd64 + cache-from: type=gha,scope=web-pr + cache-to: type=gha,mode=max,scope=web-pr