diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 01beefa..7e3a4f6 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,9 +6,8 @@ updates: schedule: interval: "weekly" - # Keep the pinned base image tag in mcp-servers/Containerfile current + # Keep the pinned base image tag in mcp-servers/socrata-mcp/Containerfile current - package-ecosystem: "docker" - directory: "/mcp-servers" + directory: "/mcp-servers/socrata-mcp" schedule: interval: "weekly" - diff --git a/.github/workflows/publish-flint-mcp.yaml b/.github/workflows/publish-flint-mcp.yaml new file mode 100644 index 0000000..3964ff9 --- /dev/null +++ b/.github/workflows/publish-flint-mcp.yaml @@ -0,0 +1,60 @@ +name: Publish Flint MCP image + +on: + push: + branches: [main] + paths: + - "mcp-servers/flint-mcp/Containerfile" + - ".github/workflows/publish-flint-mcp.yaml" + pull_request: + paths: + - "mcp-servers/flint-mcp/Containerfile" + - ".github/workflows/publish-flint-mcp.yaml" + workflow_dispatch: + +concurrency: + group: publish-flint-mcp-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + packages: write + +jobs: + flint-mcp: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + + - uses: docker/setup-qemu-action@v4 + + - uses: docker/setup-buildx-action@v4 + + - name: Log in to GHCR + if: github.event_name != 'pull_request' + uses: docker/login-action@v4 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v6 + with: + images: ghcr.io/${{ github.repository_owner }}/flint-mcp + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=sha,format=long + + - name: Build and push + uses: docker/build-push-action@v7 + with: + context: ./mcp-servers/flint-mcp + file: ./mcp-servers/flint-mcp/Containerfile + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/publish-mcp-servers.yaml b/.github/workflows/publish-mcp-servers.yaml index a7ea4ee..cd3542f 100644 --- a/.github/workflows/publish-mcp-servers.yaml +++ b/.github/workflows/publish-mcp-servers.yaml @@ -4,11 +4,11 @@ on: push: branches: [main] paths: - - "mcp-servers/Containerfile" + - "mcp-servers/socrata-mcp/Containerfile" - ".github/workflows/publish-mcp-servers.yaml" pull_request: paths: - - "mcp-servers/Containerfile" + - "mcp-servers/socrata-mcp/Containerfile" - ".github/workflows/publish-mcp-servers.yaml" workflow_dispatch: @@ -50,8 +50,8 @@ jobs: - name: Build and push uses: docker/build-push-action@v7 with: - context: ./mcp-servers - file: ./mcp-servers/Containerfile + context: ./mcp-servers/socrata-mcp + file: ./mcp-servers/socrata-mcp/Containerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} diff --git a/mcp-servers/flint-mcp/Containerfile b/mcp-servers/flint-mcp/Containerfile new file mode 100644 index 0000000..e3a438e --- /dev/null +++ b/mcp-servers/flint-mcp/Containerfile @@ -0,0 +1,52 @@ +# Upstream release to build. Bump deliberately (after checking the changelog), +# don't track a moving branch/tag. +ARG FLINT_MCP_VERSION=0.5.1 + +# Hummingbird hardened Node.js 24 builder image. +FROM registry.access.redhat.com/hi/nodejs:24-builder AS builder +ARG FLINT_MCP_VERSION + +USER root +RUN dnf install -y ca-certificates git \ + && dnf clean all +USER ${CONTAINER_DEFAULT_USER} + +WORKDIR /src +RUN git clone --branch "${FLINT_MCP_VERSION}" --depth 1 \ + https://github.com/microsoft/flint-chart.git . \ + && rm -rf .git + +# flint-mcp imports the flint-chart workspace, so build the library first. +RUN npm ci +RUN npm run build:js +RUN npm run build:mcp + +# Hummingbird hardened Node.js 24 runtime image. +FROM registry.access.redhat.com/hi/nodejs:24 +ARG FLINT_MCP_VERSION + +LABEL org.opencontainers.image.source="https://github.com/microsoft/flint-chart" \ + org.opencontainers.image.version="${FLINT_MCP_VERSION}" \ + org.opencontainers.image.licenses="MIT" \ + org.opencontainers.image.description="Flint Chart MCP server" + +WORKDIR /app + +# Install only the MCP package's production dependencies. This also installs +# the platform-specific native rendering packages in the runtime image. +COPY --from=builder /src/packages/flint-mcp/package.json ./package.json +RUN npm install --omit=dev --no-audit --no-fund \ + && npm cache clean --force + +COPY --from=builder /src/packages/flint-mcp/dist ./dist +COPY --from=builder /src/packages/flint-mcp/assets ./assets + +ENV NODE_ENV=production \ + FLINT_MCP_TRANSPORT=http \ + FLINT_MCP_HOST=0.0.0.0 \ + FLINT_MCP_DISABLE_FILE_REFERENCE=1 \ + PORT=8080 + +EXPOSE 8080 + +CMD ["node", "dist/cli.js", "--transport", "http"] diff --git a/mcp-servers/Containerfile b/mcp-servers/socrata-mcp/Containerfile similarity index 95% rename from mcp-servers/Containerfile rename to mcp-servers/socrata-mcp/Containerfile index 44a573d..5950592 100644 --- a/mcp-servers/Containerfile +++ b/mcp-servers/socrata-mcp/Containerfile @@ -2,6 +2,7 @@ # don't track a moving branch/tag. ARG SOCRATA_MCP_VERSION=v0.9.0 +# Hummingbird hardened Node.js 24 builder image. FROM registry.access.redhat.com/hi/nodejs:24-builder AS builder ARG SOCRATA_MCP_VERSION