Skip to content

Commit 0b754a2

Browse files
committed
add tests, parallel docker build
1 parent 71bfea1 commit 0b754a2

2 files changed

Lines changed: 106 additions & 29 deletions

File tree

.github/workflows/publish.yml

Lines changed: 88 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,68 @@
1-
name: Publish to GHCR
1+
name: Release
22

33
on:
44
push:
55
branches: [main, master]
66
tags: ['v*']
7+
pull_request:
8+
branches: [main, master]
79
workflow_dispatch:
810

911
env:
1012
REGISTRY: ghcr.io
1113
IMAGE_NAME: ${{ github.repository }}
1214

15+
permissions:
16+
contents: read
17+
packages: write
18+
1319
jobs:
14-
build-and-push:
20+
test:
1521
runs-on: ubuntu-latest
16-
permissions:
17-
contents: read
18-
packages: write
22+
services:
23+
neo4j:
24+
image: neo4j:5.15-community
25+
env:
26+
NEO4J_AUTH: neo4j/testpassword
27+
NEO4J_PLUGINS: '["apoc"]'
28+
ports:
29+
- 7687:7687
30+
- 7474:7474
31+
options: >-
32+
--health-cmd "wget -q --spider http://localhost:7474 || exit 1"
33+
--health-interval 10s
34+
--health-timeout 5s
35+
--health-retries 10
36+
steps:
37+
- uses: actions/checkout@v4
38+
39+
- name: Set up Python
40+
uses: actions/setup-python@v5
41+
with:
42+
python-version: '3.12'
43+
44+
- name: Install uv
45+
uses: astral-sh/setup-uv@v4
46+
47+
- name: Install dependencies
48+
working-directory: mcp-server
49+
run: uv pip install --system -e ".[dev]"
1950

51+
- name: Run unit tests
52+
working-directory: mcp-server
53+
run: pytest ../tests/unit -v -m unit
54+
55+
- name: Run integration tests
56+
working-directory: mcp-server
57+
env:
58+
CCMEMORY_NEO4J_URI: bolt://localhost:7687
59+
CCMEMORY_NEO4J_PASSWORD: testpassword
60+
run: pytest ../tests/integration -v -m integration
61+
62+
build-docker:
63+
runs-on: ubuntu-latest
2064
steps:
21-
- name: Checkout
22-
uses: actions/checkout@v4
65+
- uses: actions/checkout@v4
2366

2467
- name: Set up Docker Buildx
2568
uses: docker/setup-buildx-action@v3
@@ -31,24 +74,46 @@ jobs:
3174
username: ${{ github.actor }}
3275
password: ${{ secrets.GITHUB_TOKEN }}
3376

34-
- name: Extract metadata
35-
id: meta
36-
uses: docker/metadata-action@v5
37-
with:
38-
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
39-
tags: |
40-
type=ref,event=branch
41-
type=semver,pattern={{version}}
42-
type=semver,pattern={{major}}.{{minor}}
43-
type=sha,prefix=
44-
type=raw,value=latest,enable={{is_default_branch}}
45-
46-
- name: Build and push MCP server
47-
uses: docker/build-push-action@v5
77+
- name: Build and push for CI
78+
uses: docker/build-push-action@v6
4879
with:
4980
context: ./mcp-server
5081
push: true
51-
tags: ${{ steps.meta.outputs.tags }}
52-
labels: ${{ steps.meta.outputs.labels }}
82+
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:ci-${{ github.sha }}
5383
cache-from: type=gha
5484
cache-to: type=gha,mode=max
85+
build-args: |
86+
BUILDKIT_INLINE_CACHE=1
87+
88+
release-docker:
89+
runs-on: ubuntu-latest
90+
if: github.event_name == 'push'
91+
needs: [test, build-docker]
92+
steps:
93+
- name: Log in to GHCR
94+
uses: docker/login-action@v3
95+
with:
96+
registry: ${{ env.REGISTRY }}
97+
username: ${{ github.actor }}
98+
password: ${{ secrets.GITHUB_TOKEN }}
99+
100+
- name: Pull and tag for release
101+
run: |
102+
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:ci-${{ github.sha }}
103+
docker tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:ci-${{ github.sha }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
104+
docker tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:ci-${{ github.sha }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
105+
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
106+
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
107+
108+
cleanup:
109+
runs-on: ubuntu-latest
110+
if: github.event_name == 'push'
111+
needs: release-docker
112+
steps:
113+
- name: Delete old package versions
114+
uses: actions/delete-package-versions@v5
115+
with:
116+
package-name: ccmemory
117+
package-type: container
118+
min-versions-to-keep: 5
119+
delete-only-untagged-versions: true

mcp-server/Dockerfile

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
# Build stage
2+
FROM python:3.12-slim AS builder
3+
4+
WORKDIR /app
5+
6+
RUN pip install --no-cache-dir uv
7+
8+
COPY pyproject.toml .
9+
COPY src/ src/
10+
11+
RUN uv pip install --system --target=/app/deps .
12+
13+
# Runtime stage
114
FROM python:3.12-slim
215

316
LABEL org.opencontainers.image.source="https://github.com/patrickkidd/ccmemory"
@@ -6,15 +19,14 @@ LABEL org.opencontainers.image.licenses="MIT"
619

720
WORKDIR /app
821

9-
RUN apt-get update && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/*
10-
RUN pip install --no-cache-dir uv
22+
RUN apt-get update && apt-get install -y --no-install-recommends curl && \
23+
rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
1124

12-
COPY pyproject.toml .
25+
COPY --from=builder /app/deps /usr/local/lib/python3.12/site-packages
1326
COPY init.cypher .
1427
COPY src/ src/
1528

16-
RUN uv pip install --system .
17-
29+
ENV PYTHONPATH=/app/src
1830
ENV CCMEMORY_NEO4J_URI=bolt://ccmemory-neo4j:7687
1931
ENV CCMEMORY_NEO4J_PASSWORD=ccmemory
2032

@@ -23,4 +35,4 @@ EXPOSE 8766
2335
HEALTHCHECK --interval=10s --timeout=5s --start-period=10s --retries=3 \
2436
CMD curl -sf http://localhost:8766/health || exit 1
2537

26-
CMD ["python", "-m", "ccmemory.server", "--http", "--port", "8766"]
38+
CMD ["python", "-m", "ccmemory.server", "--http", "--port", "8766"]

0 commit comments

Comments
 (0)