name: "CD: Docs MCP Server" on: push: branches: - main paths: - "docs/scripts/docs-mcp-server/**" pull_request: branches: - main paths: - "docs/scripts/docs-mcp-server/**" workflow_dispatch: inputs: force_push: description: "Push image even on non-main branch" required: false default: false type: boolean env: AWS_REGION: us-west-2 ECR_REGISTRY: 296062593712.dkr.ecr.us-west-2.amazonaws.com ECR_REPOSITORY: docs-mcp-server SERVICE_DIR: docs/scripts/docs-mcp-server permissions: id-token: write contents: read jobs: build: runs-on: ${{ matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} strategy: fail-fast: false matrix: platform: - linux/amd64 - linux/arm64 outputs: image_tag: ${{ steps.meta.outputs.version }} timestamp: ${{ steps.timestamp.outputs.ts }} steps: - name: Checkout uses: actions/checkout@v4 - name: Prepare platform tag id: platform run: | TAG=$(echo "${{ matrix.platform }}" | sed 's/\//-/g') echo "tag=${TAG}" >> $GITHUB_OUTPUT - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::296062593712:role/github-actions-ecr-push-cua aws-region: ${{ env.AWS_REGION }} - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Generate timestamp id: timestamp run: echo "ts=$(date -u +'%Y%m%d%H%M%S')" >> $GITHUB_OUTPUT - name: Extract metadata id: meta uses: docker/metadata-action@v5 with: images: ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }} tags: | type=sha,prefix=,format=short type=ref,event=branch type=ref,event=pr type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} type=raw,value=main-${{ steps.timestamp.outputs.ts }},enable=${{ github.ref == 'refs/heads/main' }} - name: Determine if push is enabled id: push-check run: | if [[ "${{ github.event_name }}" == "pull_request" ]]; then echo "push=false" >> $GITHUB_OUTPUT elif [[ "${{ github.ref }}" == "refs/heads/main" ]]; then echo "push=true" >> $GITHUB_OUTPUT elif [[ "${{ inputs.force_push }}" == "true" ]]; then echo "push=true" >> $GITHUB_OUTPUT else echo "push=false" >> $GITHUB_OUTPUT fi - name: Build only (PR) if: steps.push-check.outputs.push == 'false' uses: docker/build-push-action@v5 with: context: ./${{ env.SERVICE_DIR }} file: ./${{ env.SERVICE_DIR }}/Dockerfile push: false platforms: ${{ matrix.platform }} cache-from: type=gha,scope=${{ env.ECR_REPOSITORY }}-${{ steps.platform.outputs.tag }} cache-to: type=gha,mode=max,scope=${{ env.ECR_REPOSITORY }}-${{ steps.platform.outputs.tag }} - name: Build and push by digest if: steps.push-check.outputs.push == 'true' id: build uses: docker/build-push-action@v5 with: context: ./${{ env.SERVICE_DIR }} file: ./${{ env.SERVICE_DIR }}/Dockerfile push: true platforms: ${{ matrix.platform }} outputs: type=image,name=${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }},push-by-digest=true,name-canonical=true labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha,scope=${{ env.ECR_REPOSITORY }}-${{ steps.platform.outputs.tag }} cache-to: type=gha,mode=max,scope=${{ env.ECR_REPOSITORY }}-${{ steps.platform.outputs.tag }} - name: Export digest if: steps.push-check.outputs.push == 'true' run: | mkdir -p /tmp/digests digest="${{ steps.build.outputs.digest }}" if [ -n "$digest" ]; then echo "$digest" > "/tmp/digests/${{ steps.platform.outputs.tag }}.txt" echo "Digest exported for platform ${{ matrix.platform }}: $digest" else echo "No digest to export for platform ${{ matrix.platform }}" exit 1 fi - name: Upload digest artifact if: steps.push-check.outputs.push == 'true' uses: actions/upload-artifact@v4 with: name: digests-${{ steps.platform.outputs.tag }} path: /tmp/digests/*.txt retention-days: 1 merge: runs-on: ubuntu-latest needs: build if: | github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || inputs.force_push == true) steps: - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::296062593712:role/github-actions-ecr-push-cua aws-region: ${{ env.AWS_REGION }} - name: Login to Amazon ECR uses: aws-actions/amazon-ecr-login@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Extract metadata id: meta uses: docker/metadata-action@v5 with: images: ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }} tags: | type=sha,prefix=,format=short type=ref,event=branch type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} type=raw,value=main-${{ needs.build.outputs.timestamp }},enable=${{ github.ref == 'refs/heads/main' }} - name: Download all digest artifacts uses: actions/download-artifact@v4 with: pattern: digests-* path: /tmp/digests merge-multiple: true - name: Check available digests id: check-digests run: | DIGEST_COUNT=$(find /tmp/digests -type f -name "*.txt" | wc -l) echo "digest_count=$DIGEST_COUNT" >> $GITHUB_OUTPUT if [ "$DIGEST_COUNT" -eq 0 ]; then echo "Error: No platform builds succeeded!" exit 1 fi echo "Found $DIGEST_COUNT platform digest(s)" for f in $(find /tmp/digests -type f -name "*.txt"); do platform=$(basename "$f" .txt) echo " - $platform: $(cat $f)" done - name: Create and push multi-arch manifest run: | IMAGE="${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}" # Collect all digests DIGEST_ARGS="" for f in $(find /tmp/digests -type f -name "*.txt"); do d=$(cat "$f") DIGEST_ARGS="$DIGEST_ARGS ${IMAGE}@${d}" done echo "Using digests:" echo "$DIGEST_ARGS" # Create manifest for each tag produced by metadata-action echo "${{ steps.meta.outputs.tags }}" | while read FULL_TAG; do if [ -n "$FULL_TAG" ]; then echo "Creating manifest: $FULL_TAG" docker buildx imagetools create --tag "$FULL_TAG" $DIGEST_ARGS fi done - name: Inspect pushed manifests run: | echo "Inspecting manifests:" echo "${{ steps.meta.outputs.tags }}" | while read FULL_TAG; do if [ -n "$FULL_TAG" ]; then echo "" echo "Inspecting: $FULL_TAG" docker buildx imagetools inspect "$FULL_TAG" fi done