Add Woodpecker CI pipeline and k8s manifests #4

Open
forgejo_admin wants to merge 1 commit from 3-add-woodpecker-ci-pipeline-and-k8s-manif into main
Contributor

Summary

  • Add Woodpecker CI pipeline and k8s manifests following the proven pattern from notion-mcp-remote
  • Add /metrics endpoint for Prometheus ServiceMonitor
  • Add ruff dev dependency and config for CI linting

Changes

  • .woodpecker.yaml: Woodpecker CI — ruff lint/format on PRs + push, kaniko build-and-push to Harbor on main
  • Dockerfile.k8s: Simple requirements.txt-based container build for k8s
  • k8s/deployment.yaml: All 10 env vars from server.py mapped (secrets + values), port 8000, 256Mi memory limit, harbor-creds imagePullSecret, liveness/readiness probes, PVC mount
  • k8s/service.yaml: ClusterIP service on port 8000 with named port
  • k8s/pvc.yaml: 100Mi local-path PVC (linkedin-mcp-data) for token/DB storage
  • k8s/servicemonitor.yaml: Prometheus ServiceMonitor scraping /metrics every 30s
  • k8s/kustomization.yaml: Resource list for ArgoCD
  • server.py: Added /metrics endpoint (Prometheus gauge), added starlette Request/Response imports
  • pyproject.toml: Added [project.optional-dependencies] dev (ruff>=0.8), [tool.ruff] config (py312, line-length 100, E/F/I/N/W)
  • requirements.txt: Added mcp-remote-auth-ldraney (was missing from requirements.txt but in pyproject.toml), reordered
  • client_patch.py: Reformatted by ruff (line length adjustments)

Conventions followed

  • Port 8000 everywhere
  • $CI_COMMIT_SHA (no curly braces)
  • No namespace: in any k8s manifest
  • Memory limit 256Mi
  • .argocd-source-* excluded from CI triggers
  • Container port has name: http
  • Secret name: linkedin-mcp-secrets
  • PVC name: linkedin-mcp-data

Test Plan

  • ruff check . passes
  • ruff format --check . passes
  • Woodpecker CI test step passes on PR
  • k8s manifests valid (deployment, service, pvc, servicemonitor, kustomization all present)
  • Every os.environ / os.environ.get call in server.py has a corresponding env entry in deployment.yaml

Review Checklist

  • Passed automated review-fix loop
  • No secrets committed
  • No unnecessary file changes
  • Commit messages are descriptive
  • issue-linkedin-scheduler-remote-woodpecker-k8s — the issue this PR addresses
  • plan-2026-02-25-mcp-gateway-migration — Phase 3

Closes #3

## Summary - Add Woodpecker CI pipeline and k8s manifests following the proven pattern from notion-mcp-remote - Add /metrics endpoint for Prometheus ServiceMonitor - Add ruff dev dependency and config for CI linting ## Changes - `.woodpecker.yaml`: Woodpecker CI — ruff lint/format on PRs + push, kaniko build-and-push to Harbor on main - `Dockerfile.k8s`: Simple requirements.txt-based container build for k8s - `k8s/deployment.yaml`: All 10 env vars from server.py mapped (secrets + values), port 8000, 256Mi memory limit, harbor-creds imagePullSecret, liveness/readiness probes, PVC mount - `k8s/service.yaml`: ClusterIP service on port 8000 with named port - `k8s/pvc.yaml`: 100Mi local-path PVC (`linkedin-mcp-data`) for token/DB storage - `k8s/servicemonitor.yaml`: Prometheus ServiceMonitor scraping /metrics every 30s - `k8s/kustomization.yaml`: Resource list for ArgoCD - `server.py`: Added `/metrics` endpoint (Prometheus gauge), added starlette Request/Response imports - `pyproject.toml`: Added `[project.optional-dependencies] dev` (ruff>=0.8), `[tool.ruff]` config (py312, line-length 100, E/F/I/N/W) - `requirements.txt`: Added `mcp-remote-auth-ldraney` (was missing from requirements.txt but in pyproject.toml), reordered - `client_patch.py`: Reformatted by ruff (line length adjustments) ### Conventions followed - Port 8000 everywhere - `$CI_COMMIT_SHA` (no curly braces) - No `namespace:` in any k8s manifest - Memory limit 256Mi - `.argocd-source-*` excluded from CI triggers - Container port has `name: http` - Secret name: `linkedin-mcp-secrets` - PVC name: `linkedin-mcp-data` ## Test Plan - [ ] `ruff check .` passes - [ ] `ruff format --check .` passes - [ ] Woodpecker CI test step passes on PR - [ ] k8s manifests valid (deployment, service, pvc, servicemonitor, kustomization all present) - [ ] Every `os.environ` / `os.environ.get` call in server.py has a corresponding env entry in deployment.yaml ## Review Checklist - [ ] Passed automated review-fix loop - [ ] No secrets committed - [ ] No unnecessary file changes - [ ] Commit messages are descriptive ## Related Notes - `issue-linkedin-scheduler-remote-woodpecker-k8s` — the issue this PR addresses - `plan-2026-02-25-mcp-gateway-migration` — Phase 3 Closes #3
Add Woodpecker CI pipeline and k8s manifests
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
64ef52ccb1
Follow the proven pattern from notion-mcp-remote:
- .woodpecker.yaml: ruff lint/format + kaniko build to Harbor
- Dockerfile.k8s: requirements.txt-based build for k8s
- k8s/: deployment, service, pvc, servicemonitor, kustomization
- server.py: add /metrics endpoint for ServiceMonitor
- pyproject.toml: add dev deps (ruff) and ruff config
- requirements.txt: add mcp-remote-auth-ldraney dependency

All env vars from server.py mapped in deployment.yaml.
Port 8000, 256Mi memory limit, no namespace fields.

Closes #3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Contributor

Review Pass: CLEAN

Reviewed all 11 changed files against the proven pattern from notion-mcp-remote (main branch).

Checklist

  • .woodpecker.yaml matches pattern — correct triggers, $CI_COMMIT_SHA (no braces), .argocd-source-* excluded
  • Dockerfile.k8s matches pattern — requirements.txt-based, EXPOSE 8000
  • k8s/deployment.yaml — all 10 env vars from server.py mapped, port 8000 with name: http, 256Mi limit, no namespace, harbor-creds, probes on /health
  • k8s/service.yaml — port 8000, named http, no namespace
  • k8s/pvc.yamllinkedin-mcp-data, local-path, 100Mi, no namespace
  • k8s/servicemonitor.yaml — /metrics, 30s interval, matches app label
  • k8s/kustomization.yaml — all 4 resources listed
  • server.py — /metrics endpoint follows notion-mcp-remote pattern exactly
  • pyproject.toml — dev deps + ruff config match pattern
  • requirements.txt — added missing mcp-remote-auth-ldraney dep (bug fix)
  • client_patch.py — ruff formatting only (cosmetic)
  • No secrets committed
  • No unnecessary changes
  • Commit message is descriptive

Zero issues found. Ready for user review.

## Review Pass: CLEAN Reviewed all 11 changed files against the proven pattern from notion-mcp-remote (main branch). ### Checklist - [x] `.woodpecker.yaml` matches pattern — correct triggers, `$CI_COMMIT_SHA` (no braces), `.argocd-source-*` excluded - [x] `Dockerfile.k8s` matches pattern — requirements.txt-based, EXPOSE 8000 - [x] `k8s/deployment.yaml` — all 10 env vars from server.py mapped, port 8000 with `name: http`, 256Mi limit, no namespace, harbor-creds, probes on /health - [x] `k8s/service.yaml` — port 8000, named `http`, no namespace - [x] `k8s/pvc.yaml` — `linkedin-mcp-data`, local-path, 100Mi, no namespace - [x] `k8s/servicemonitor.yaml` — /metrics, 30s interval, matches app label - [x] `k8s/kustomization.yaml` — all 4 resources listed - [x] `server.py` — /metrics endpoint follows notion-mcp-remote pattern exactly - [x] `pyproject.toml` — dev deps + ruff config match pattern - [x] `requirements.txt` — added missing `mcp-remote-auth-ldraney` dep (bug fix) - [x] `client_patch.py` — ruff formatting only (cosmetic) - [x] No secrets committed - [x] No unnecessary changes - [x] Commit message is descriptive **Zero issues found. Ready for user review.**
Author
Contributor

Merge conflicts with main (k8s/deployment.yaml, k8s/kustomization.yaml). Main already has CI + k8s from a prior merge. Feature branch has improved patterns (Dockerfile.k8s, service.yaml, pvc.yaml, servicemonitor.yaml) but needs manual conflict resolution. Deferring — not blocking the first LinkedIn post (only linkedin-sdk is needed for posting).

Merge conflicts with main (k8s/deployment.yaml, k8s/kustomization.yaml). Main already has CI + k8s from a prior merge. Feature branch has improved patterns (Dockerfile.k8s, service.yaml, pvc.yaml, servicemonitor.yaml) but needs manual conflict resolution. Deferring — not blocking the first LinkedIn post (only linkedin-sdk is needed for posting).
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
This pull request has changes conflicting with the target branch.
  • k8s/deployment.yaml
  • k8s/kustomization.yaml
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin 3-add-woodpecker-ci-pipeline-and-k8s-manif:3-add-woodpecker-ci-pipeline-and-k8s-manif
git switch 3-add-woodpecker-ci-pipeline-and-k8s-manif

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff 3-add-woodpecker-ci-pipeline-and-k8s-manif
git switch 3-add-woodpecker-ci-pipeline-and-k8s-manif
git rebase main
git switch main
git merge --ff-only 3-add-woodpecker-ci-pipeline-and-k8s-manif
git switch 3-add-woodpecker-ci-pipeline-and-k8s-manif
git rebase main
git switch main
git merge --no-ff 3-add-woodpecker-ci-pipeline-and-k8s-manif
git switch main
git merge --squash 3-add-woodpecker-ci-pipeline-and-k8s-manif
git switch main
git merge --ff-only 3-add-woodpecker-ci-pipeline-and-k8s-manif
git switch main
git merge 3-add-woodpecker-ci-pipeline-and-k8s-manif
git push origin main
Sign in to join this conversation.
No description provided.