The test-runners job was failing because network_mode: host puts the
armature container on DinD's network namespace, unreachable from the
workflow container which is on a separate bridge network.
Fix: Remove host networking entirely. Add a test-runner service to the
CI compose override that runs Playwright tests on the same bridge
network as armature, using Docker DNS (http://armature:80).
Changes:
- docker-compose.ci.yml: Replace network_mode: host with healthcheck
on armature + Playwright test-runner service (depends_on: healthy)
- ci.yaml: Collapse 7 test-runners steps into 3 (checkout, compose
up --exit-code-from test-runner, teardown)
The previous fix (container IP resolution) still failed because the
CI runner and compose containers are on separate Docker networks.
- Add docker-compose.ci.yml override with network_mode: host so the
container shares the runner's network stack directly
- Add --connect-timeout 2 to curl in wait-for-healthy.sh so it fails
fast instead of hanging indefinitely on unreachable hosts
- Cap health check at 30s (server boots in 5-10s)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
In Gitea runner pods, docker compose port mapping (3000:80) doesn't
expose to the runner container's localhost. Resolve the armature
container IP via `docker inspect` and pass it directly to the health
check and Playwright test runner.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Five package-level test runners validating extension API contracts:
- notes-runner: CRUD, folders, tags, search, backlinks (12 tests)
- chat-runner: conversations, messaging, search (9 tests)
- schedules-runner: CRUD + run (5 tests)
- workflow-runner: definitions, instances, stage progression (5 tests)
- renderer-runner: registry contract, block matching (4 tests)
Runner Result API (in-memory, 3 admin endpoints) stores results
from browser runs for CI consumption. Test-runners surface v0.2.0
posts results after each run and fixes suite prefix matching.
CI integration via Playwright: wait-for-healthy.sh, run-surface-tests.sh,
surface-test-driver.js. New test-runners stage in Gitea CI pipeline.
Verified: 169 passed, 0 failed, 9 warned, 8 skipped on fresh install.
Go handler tests: 4/4 passing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- k8s/backend.yaml → k8s/switchboard.yaml (already renamed)
- Deployment/Service name: switchboard-be → switchboard
- Removed component:backend labels (single image, no component split)
- Ingress: all paths route to switchboard service on :8080
- CI: updated manifest render, apply, and rollout references
- Removed stale extractor sidecar and extraction env vars
- Updated CHANGELOG and ROADMAP with CI fixes and design decisions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
k8s/backend.yaml referenced ${BE_IMAGE} but the workflow env
defines ${IMAGE}, causing envsubst to produce an empty image
name (InvalidImageName). Also consolidated the summary table
to single image line since FE/BE are merged.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The rollout step referenced deployment/switchboard${SUFFIX} but the
k8s manifest names the deployment switchboard-be${SUFFIX}, causing
a NotFound error during rollout verification.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CI pipeline: replace separate FE + BE image builds with single unified
Dockerfile. Remove FE_IMAGE, FE_REPLICAS, FE_* resource vars. Simplify
build/push/deploy to single IMAGE. Remove frontend.yaml k8s manifest.
Remove provider integration test env vars (PROVIDER, PROVIDER_KEY,
VENICE_API_KEY). Remove EXTRACTION_CONCURRENCY.
Delete server/Dockerfile (backend-only image, superseded by root
Dockerfile). Delete k8s/frontend.yaml (no separate FE deployment).
Update ROADMAP: steps 5-7 and 9 marked complete. Step 8 (ICD) partial.
Step 10 (smoke test + tag) is all that remains for v0.1.0.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## Summary
This PR sets up the complete CI/CD infrastructure for the Chat Switchboard project, implementing automated testing, linting, building, and Docker containerization.
## Changes
### CI/CD Workflows
1. **`.gitea/workflows/backend.yml`** - Backend CI pipeline
- Automated Go module initialization
- Test execution with coverage reporting
- Code linting with golangci-lint
- Binary compilation with version tags
- Artifact upload for debugging
2. **`.gitea/workflows/frontend.yml`** - Frontend CI pipeline
- JavaScript linting with ESLint
- CSS validation with Prettier
- Standalone HTML build via build.sh
- HTML structure validation
- Build artifact management
3. **`.gitea/workflows/docker.yml`** - Docker CI pipeline
- Backend container building and testing
- Frontend container building
- Automatic image tagging on tags/branches
- Registry push on main branch
- Multi-arch manifest creation
### Docker Configuration
- `server/Dockerfile` - Multi-stage Go backend container with health checks
- `Dockerfile.frontend` - Nginx frontend container with gzip compression
- `nginx.conf` - Optimized nginx config with security headers
### Dependencies
- `server/go.mod` - Initialized Go module with Gin and godotenv
### Documentation
- `docs/CICD_SETUP.md` - Comprehensive CI/CD documentation
## Features
- ✅ Auto-trigger on push/PR to main/develop
- ✅ Test coverage reporting
- ✅ Code quality checks (golangci-lint, ESLint)
- ✅ Build artifact management (7-day retention)
- ✅ Semantic versioning support (v* tags)
- ✅ Multi-stage Docker builds
- ✅ Container health checks
- ✅ Security headers in nginx
- ✅ Gzip compression
- ✅ Non-root container execution
## Testing
The workflows will automatically run on this PR. Once merged, all future PRs and pushes to main/develop will trigger the appropriate CI checks.
## Acceptance Criteria
- ✅ All PRs run CI checks
- ✅ Docker images auto-build on tags
- ✅ Standalone build generates on each commit
## Next Steps (Manual)
1. Merge this PR to `main`
2. Create `develop` branch: `git checkout main && git checkout -b develop && git push origin develop`
3. Configure branch protection in Gitea (Settings → Branches → Add protection rule for main/develop)
4. Test with a sample PR to verify CI runs
## Breaking Changes
None. This is purely infrastructure setup with no impact on existing functionality.
Reviewed-on: xcaliber/chat-switchboard#22