diff --git a/.github/workflows/build-image-and-push.yaml b/.github/workflows/build-image-and-push.yaml new file mode 100644 index 000000000..4410e39c3 --- /dev/null +++ b/.github/workflows/build-image-and-push.yaml @@ -0,0 +1,373 @@ +name: Build Docker Images and Push to Image Registry + +on: + push: + branches: + - main + tags: + - "v*.*.*" + workflow_dispatch: + inputs: + push_images: + description: "Push images to registry" + required: false + default: "true" + type: boolean + +# Limit workflow permissions +permissions: + contents: read + +env: + # Default registry (can be overridden by repository variables) + IMAGE_REGISTRY: ${{ vars.IMAGE_REGISTRY || 'opensource-registry.cn-hangzhou.cr.aliyuncs.com' }} + IMAGE_NAMESPACE: ${{ vars.IMAGE_NAMESPACE || 'himarket' }} + +jobs: + # =========================================== + # Backend Image Build + # =========================================== + build-backend: + name: Build Backend Image + runs-on: ubuntu-latest + # Only run in the main repository or specific forks (others don't have registry credentials) + if: github.repository == 'higress-group/himarket' || github.repository == 'lexburner/himarket' + environment: image-registry + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: 'maven' + + - name: Build with Maven + run: mvn clean package -DskipTests -B + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Registry + if: github.event_name == 'push' || inputs.push_images == true + uses: docker/login-action@v3 + with: + registry: ${{ env.IMAGE_REGISTRY }} + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Calculate Docker metadata + id: docker-meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/himarket-backend + tags: | + type=sha + type=ref,event=tag + type=semver,pattern={{version}} + type=raw,value=latest + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: himarket-bootstrap + file: himarket-bootstrap/Dockerfile + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name == 'push' || inputs.push_images == true }} + tags: ${{ steps.docker-meta.outputs.tags }} + labels: ${{ steps.docker-meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Build summary + run: | + echo "## 🐳 Backend Image Build" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Image**: \`${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/himarket-backend\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Tags**:" >> $GITHUB_STEP_SUMMARY + echo "${{ steps.docker-meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY + + # =========================================== + # Frontend - Admin Portal Build + # =========================================== + build-admin: + name: Build Admin Portal Image + runs-on: ubuntu-latest + if: github.repository == 'higress-group/himarket' || github.repository == 'lexburner/himarket' + environment: image-registry + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + working-directory: himarket-web/himarket-admin + run: npm install --legacy-peer-deps + + - name: Build project + working-directory: himarket-web/himarket-admin + run: npm run build + env: + NODE_ENV: production + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Registry + if: github.event_name == 'push' || inputs.push_images == true + uses: docker/login-action@v3 + with: + registry: ${{ env.IMAGE_REGISTRY }} + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Calculate Docker metadata + id: docker-meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/himarket-admin + tags: | + type=sha + type=ref,event=tag + type=semver,pattern={{version}} + type=raw,value=latest + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: himarket-web/himarket-admin + file: himarket-web/himarket-admin/Dockerfile + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name == 'push' || inputs.push_images == true }} + tags: ${{ steps.docker-meta.outputs.tags }} + labels: ${{ steps.docker-meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Build summary + run: | + echo "## 🐳 Admin Portal Image Build" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Image**: \`${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/himarket-admin\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Tags**:" >> $GITHUB_STEP_SUMMARY + echo "${{ steps.docker-meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY + + # =========================================== + # Frontend - Developer Portal Build + # =========================================== + build-frontend: + name: Build Developer Portal Image + runs-on: ubuntu-latest + if: github.repository == 'higress-group/himarket' || github.repository == 'lexburner/himarket' + environment: image-registry + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + working-directory: himarket-web/himarket-frontend + run: npm install --legacy-peer-deps + + - name: Build project + working-directory: himarket-web/himarket-frontend + run: npm run build + env: + NODE_ENV: production + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Registry + if: github.event_name == 'push' || inputs.push_images == true + uses: docker/login-action@v3 + with: + registry: ${{ env.IMAGE_REGISTRY }} + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Calculate Docker metadata + id: docker-meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/himarket-frontend + tags: | + type=sha + type=ref,event=tag + type=semver,pattern={{version}} + type=raw,value=latest + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: himarket-web/himarket-frontend + file: himarket-web/himarket-frontend/Dockerfile + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name == 'push' || inputs.push_images == true }} + tags: ${{ steps.docker-meta.outputs.tags }} + labels: ${{ steps.docker-meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Build summary + run: | + echo "## 🐳 Developer Portal Image Build" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Image**: \`${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/himarket-frontend\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Tags**:" >> $GITHUB_STEP_SUMMARY + echo "${{ steps.docker-meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY + + # =========================================== + # Sandbox Image Build + # =========================================== + build-sandbox: + name: Build Sandbox Image + runs-on: ubuntu-latest + if: github.repository == 'higress-group/himarket' || github.repository == 'lexburner/himarket' + environment: image-registry + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Registry + if: github.event_name == 'push' || inputs.push_images == true + uses: docker/login-action@v3 + with: + registry: ${{ env.IMAGE_REGISTRY }} + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Calculate Docker metadata + id: docker-meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/himarket-sandbox + tags: | + type=sha + type=ref,event=tag + type=semver,pattern={{version}} + type=raw,value=latest + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: sandbox + file: sandbox/Dockerfile + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name == 'push' || inputs.push_images == true }} + tags: ${{ steps.docker-meta.outputs.tags }} + labels: ${{ steps.docker-meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Build summary + run: | + echo "## 🐳 Sandbox Image Build" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Image**: \`${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/himarket-sandbox\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Tags**:" >> $GITHUB_STEP_SUMMARY + echo "${{ steps.docker-meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY + + # =========================================== + # Build Summary + # =========================================== + build-summary: + name: Build Summary + runs-on: ubuntu-latest + needs: [build-backend, build-admin, build-frontend, build-sandbox] + if: always() + + steps: + - name: Generate summary + uses: actions/github-script@v7 + with: + script: | + const jobs = [ + { name: 'Backend Image', status: '${{ needs.build-backend.result }}' }, + { name: 'Admin Portal Image', status: '${{ needs.build-admin.result }}' }, + { name: 'Developer Portal Image', status: '${{ needs.build-frontend.result }}' }, + { name: 'Sandbox Image', status: '${{ needs.build-sandbox.result }}' } + ]; + + let summary = '## 🐳 Docker Image Build Summary\n\n'; + let allPassed = true; + + jobs.forEach(job => { + let icon = '✅'; + let statusText = job.status; + + if (job.status === 'success') { + icon = '✅'; + statusText = 'Built & Pushed'; + } else if (job.status === 'failure') { + icon = '❌'; + statusText = 'Failed'; + allPassed = false; + } else if (job.status === 'cancelled') { + icon = '🚫'; + statusText = 'Cancelled'; + allPassed = false; + } else if (job.status === 'skipped') { + icon = '⏭️'; + statusText = 'Skipped'; + } else { + icon = '⚠️'; + allPassed = false; + } + + summary += `${icon} **${job.name}**: ${statusText}\n`; + }); + + summary += '\n---\n\n'; + + if (allPassed) { + summary += '🎉 **All images built and pushed successfully!**\n\n'; + summary += '### 📦 Images\n\n'; + summary += `- Backend: \`${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/himarket-backend:latest\`\n'; + summary += `- Admin Portal: \`${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/himarket-admin:latest\`\n'; + summary += `- Developer Portal: \`${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/himarket-frontend:latest\`\n'; + summary += `- Sandbox: \`${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/himarket-sandbox:latest\`\n`; + } else { + summary += '⚠️ **Some image builds failed.** Please check the logs above.\n'; + } + + await core.summary + .addRaw(summary) + .write(); + + if (!allPassed) { + core.setFailed('Some Docker image builds failed'); + } \ No newline at end of file diff --git a/himarket-server/src/main/java/com/alibaba/himarket/service/hichat/manager/ChatBotManager.java b/himarket-server/src/main/java/com/alibaba/himarket/service/hichat/manager/ChatBotManager.java index 9e9683531..43a00b88c 100644 --- a/himarket-server/src/main/java/com/alibaba/himarket/service/hichat/manager/ChatBotManager.java +++ b/himarket-server/src/main/java/com/alibaba/himarket/service/hichat/manager/ChatBotManager.java @@ -294,8 +294,12 @@ private Map buildToolMetas(Toolkit toolkit) { */ private void registerTool(Toolkit toolkit, McpClientWrapper client, McpSchema.Tool tool) { try { + java.util.Set required = + tool.inputSchema() != null && tool.inputSchema().required() != null + ? new java.util.HashSet<>(tool.inputSchema().required()) + : java.util.Collections.emptySet(); Map parameters = - McpTool.convertMcpSchemaToParameters(tool.inputSchema()); + McpTool.convertMcpSchemaToParameters(tool.inputSchema(), required); McpTool mcpTool = new McpTool( tool.name(), diff --git a/himarket-server/src/main/java/com/alibaba/himarket/service/hichat/service/dashscope/DashScopeImageChatModel.java b/himarket-server/src/main/java/com/alibaba/himarket/service/hichat/service/dashscope/DashScopeImageChatModel.java index 76e3875a8..35658a955 100644 --- a/himarket-server/src/main/java/com/alibaba/himarket/service/hichat/service/dashscope/DashScopeImageChatModel.java +++ b/himarket-server/src/main/java/com/alibaba/himarket/service/hichat/service/dashscope/DashScopeImageChatModel.java @@ -206,7 +206,7 @@ public Set getSupportedModels() { public static class DashScopeImageHttpClient extends DashScopeHttpClient { public DashScopeImageHttpClient(HttpTransport transport, String apiKey, String baseUrl) { - super(transport, apiKey, baseUrl); + super(transport, apiKey, baseUrl, null, null); } /** diff --git a/pom.xml b/pom.xml index 208a05001..142b3b06d 100644 --- a/pom.xml +++ b/pom.xml @@ -68,7 +68,7 @@ 3.2.3 2.0.0 2.0 - 1.0.6 + 1.0.10 2.17.2 4.6.1 2.22.4