Add Woodpecker CI pipeline with semantic versioning
Pipeline stages: - restore: Restore NuGet dependencies - build: Build in Release mode - test: Run test suite - version: Determine version from git tags - package-nuget: Create NuGet package (main branch) - package-docker: Build multi-arch Docker image (tags only) - release: Create GitHub release with artifacts (tags only) Versioning: - Tags (v1.0.0) → version 1.0.0 - Main branch → version X.Y.Z-dev.main.abc1234 - PRs → version X.Y.Z-dev.branch.abc1234 Docker image published to ghcr.io/barryw/paperlessmcp 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+110
@@ -0,0 +1,110 @@
|
|||||||
|
variables:
|
||||||
|
- &dotnet_image "mcr.microsoft.com/dotnet/sdk:10.0-preview"
|
||||||
|
- &docker_image "woodpeckerci/plugin-docker-buildx"
|
||||||
|
|
||||||
|
when:
|
||||||
|
- event: [push, pull_request, tag]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# Restore dependencies
|
||||||
|
restore:
|
||||||
|
image: *dotnet_image
|
||||||
|
commands:
|
||||||
|
- dotnet restore
|
||||||
|
|
||||||
|
# Build the project
|
||||||
|
build:
|
||||||
|
image: *dotnet_image
|
||||||
|
commands:
|
||||||
|
- dotnet build --no-restore -c Release
|
||||||
|
depends_on: [restore]
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
test:
|
||||||
|
image: *dotnet_image
|
||||||
|
commands:
|
||||||
|
- dotnet test --no-build -c Release --logger "console;verbosity=detailed"
|
||||||
|
depends_on: [build]
|
||||||
|
|
||||||
|
# Determine version from git tags
|
||||||
|
version:
|
||||||
|
image: alpine/git
|
||||||
|
commands:
|
||||||
|
- |
|
||||||
|
if [ -n "$CI_COMMIT_TAG" ]; then
|
||||||
|
# Use tag as version (strip 'v' prefix if present)
|
||||||
|
VERSION=$(echo "$CI_COMMIT_TAG" | sed 's/^v//')
|
||||||
|
else
|
||||||
|
# Generate dev version from branch and short SHA
|
||||||
|
BRANCH=$(echo "$CI_COMMIT_BRANCH" | sed 's/[^a-zA-Z0-9]/-/g')
|
||||||
|
SHORT_SHA=$(echo "$CI_COMMIT_SHA" | cut -c1-7)
|
||||||
|
# Get latest tag or default to 0.0.0
|
||||||
|
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
|
||||||
|
BASE_VERSION=$(echo "$LATEST_TAG" | sed 's/^v//')
|
||||||
|
VERSION="${BASE_VERSION}-dev.${BRANCH}.${SHORT_SHA}"
|
||||||
|
fi
|
||||||
|
echo "$VERSION" > .version
|
||||||
|
echo "Building version: $VERSION"
|
||||||
|
depends_on: [test]
|
||||||
|
|
||||||
|
# Package as NuGet (for library distribution)
|
||||||
|
package-nuget:
|
||||||
|
image: *dotnet_image
|
||||||
|
commands:
|
||||||
|
- VERSION=$(cat .version)
|
||||||
|
- echo "Packaging version $VERSION"
|
||||||
|
- dotnet pack PaperlessMCP/PaperlessMCP.csproj --no-build -c Release -o ./artifacts /p:Version=$VERSION /p:PackageVersion=$VERSION
|
||||||
|
- ls -la ./artifacts/
|
||||||
|
depends_on: [version]
|
||||||
|
when:
|
||||||
|
- event: [push, tag]
|
||||||
|
branch: main
|
||||||
|
|
||||||
|
# Build and push Docker image (tags only)
|
||||||
|
package-docker:
|
||||||
|
image: *docker_image
|
||||||
|
settings:
|
||||||
|
repo: ghcr.io/barryw/paperlessmcp
|
||||||
|
dockerfile: PaperlessMCP/Dockerfile
|
||||||
|
context: PaperlessMCP
|
||||||
|
platforms:
|
||||||
|
- linux/amd64
|
||||||
|
- linux/arm64
|
||||||
|
tag: [latest, "${CI_COMMIT_TAG}"]
|
||||||
|
build_args:
|
||||||
|
- VERSION=${CI_COMMIT_TAG}
|
||||||
|
registry: ghcr.io
|
||||||
|
username:
|
||||||
|
from_secret: github_username
|
||||||
|
password:
|
||||||
|
from_secret: github_token
|
||||||
|
depends_on: [version]
|
||||||
|
when:
|
||||||
|
- event: tag
|
||||||
|
|
||||||
|
# Build Docker for PRs (no push, just verify it builds)
|
||||||
|
docker-verify:
|
||||||
|
image: *docker_image
|
||||||
|
settings:
|
||||||
|
repo: ghcr.io/barryw/paperlessmcp
|
||||||
|
dockerfile: PaperlessMCP/Dockerfile
|
||||||
|
context: PaperlessMCP
|
||||||
|
platforms:
|
||||||
|
- linux/amd64
|
||||||
|
dry_run: true
|
||||||
|
depends_on: [version]
|
||||||
|
when:
|
||||||
|
- event: pull_request
|
||||||
|
|
||||||
|
# Create GitHub release (tags only)
|
||||||
|
release:
|
||||||
|
image: woodpeckerci/plugin-github-release
|
||||||
|
settings:
|
||||||
|
api_key:
|
||||||
|
from_secret: github_token
|
||||||
|
files:
|
||||||
|
- artifacts/*.nupkg
|
||||||
|
title: ${CI_COMMIT_TAG}
|
||||||
|
depends_on: [package-nuget, package-docker]
|
||||||
|
when:
|
||||||
|
- event: tag
|
||||||
+10
-5
@@ -1,5 +1,6 @@
|
|||||||
# Build stage
|
# Build stage
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:10.0-preview AS build
|
FROM mcr.microsoft.com/dotnet/sdk:10.0-preview AS build
|
||||||
|
ARG VERSION=0.0.0-dev
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
|
|
||||||
# Copy project file and restore dependencies
|
# Copy project file and restore dependencies
|
||||||
@@ -8,12 +9,20 @@ RUN dotnet restore
|
|||||||
|
|
||||||
# Copy source code and build
|
# Copy source code and build
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet publish -c Release -o /app/publish
|
RUN dotnet publish -c Release -o /app/publish /p:Version=${VERSION}
|
||||||
|
|
||||||
# Runtime stage
|
# Runtime stage
|
||||||
FROM mcr.microsoft.com/dotnet/aspnet:10.0-preview AS runtime
|
FROM mcr.microsoft.com/dotnet/aspnet:10.0-preview AS runtime
|
||||||
|
ARG VERSION=0.0.0-dev
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
# OCI Labels
|
||||||
|
LABEL org.opencontainers.image.title="PaperlessMCP"
|
||||||
|
LABEL org.opencontainers.image.description="Model Context Protocol server for Paperless-ngx"
|
||||||
|
LABEL org.opencontainers.image.version="${VERSION}"
|
||||||
|
LABEL org.opencontainers.image.source="https://github.com/barryw/PaperlessMCP"
|
||||||
|
LABEL org.opencontainers.image.licenses="MIT"
|
||||||
|
|
||||||
# Copy published application
|
# Copy published application
|
||||||
COPY --from=build /app/publish .
|
COPY --from=build /app/publish .
|
||||||
|
|
||||||
@@ -24,9 +33,5 @@ ENV MCP_PORT=5000
|
|||||||
# Expose port for HTTP transport
|
# Expose port for HTTP transport
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
|
|
||||||
# Health check
|
|
||||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
|
||||||
CMD curl -f http://localhost:5000/mcp || exit 1
|
|
||||||
|
|
||||||
# Run the application (HTTP mode by default)
|
# Run the application (HTTP mode by default)
|
||||||
ENTRYPOINT ["dotnet", "PaperlessMCP.dll"]
|
ENTRYPOINT ["dotnet", "PaperlessMCP.dll"]
|
||||||
|
|||||||
@@ -139,6 +139,25 @@ dotnet build # Build
|
|||||||
dotnet test # Run tests
|
dotnet test # Run tests
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### CI/CD
|
||||||
|
|
||||||
|
This project uses [Woodpecker CI](https://woodpecker-ci.org/) for continuous integration:
|
||||||
|
|
||||||
|
| Event | Actions |
|
||||||
|
|-------|---------|
|
||||||
|
| **Push/PR** | Build → Test |
|
||||||
|
| **Push to main** | Build → Test → Package NuGet |
|
||||||
|
| **Tag (vX.Y.Z)** | Build → Test → Package → Docker → GitHub Release |
|
||||||
|
|
||||||
|
**Versioning:** Semantic versioning via git tags. Create a release with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git tag v1.0.0
|
||||||
|
git push origin v1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
**Docker Images:** `ghcr.io/barryw/paperlessmcp:latest`
|
||||||
|
|
||||||
### Project Structure
|
### Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user