CI/CD Workflow Overview¶
Purpose¶
This document explains the complete structure and execution flow of the ci-cd.yml GitHub Actions workflow, which handles versioning, building, and deploying all SyRF services.
Workflow File¶
Location: .github/workflows/ci-cd.yml
Trigger: Push to main branch, or manual workflow dispatch
Complete Workflow Structure¶
┌─────────────────────────────────────────────────────────────────┐
│ 1. detect-changes │
│ Path-based filtering determines which services changed │
│ Outputs: api_changed, pm_changed, quartz_changed, │
│ web_changed, s3_notifier_changed │
└─────────────────────────────────────────────────────────────────┘
│
┌─────────────────────────┼─────────────────────────┐
│ │ │
▼ ▼ ▼
┌────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐
│ 2. version-* │ │ 2.5 test-dotnet │ │ 2e. version-s3-notifier │
│ (parallel) │ │ (parallel) │ │ (if s3_notifier │
│ │ │ │ │ changed) │
│ version-api │ │ - Run xUnit │ │ │
│ version-pm │ │ - Upload │ │ Uses GitVersion │
│ version-quartz │ │ coverage │ │ Outputs: version, sha │
│ version-web │ │ │ └────────────┬────────────┘
│ │ ├─────────────────┤ │
│ Uses GitVersion│ │ 2.5 test-web │ │
│ Outputs: │ │ (parallel) │ │
│ version, sha │ │ │ │
└───────┬────────┘ │ - Run Vitest │ │
│ │ - Upload │ │
│ │ coverage │ │
│ └────────┬────────┘ │
│ │ │
│ ┌───────────────┴───────────────┐ │
│ │ BLOCKS BUILD IF TESTS FAIL │ │
│ └───────────────┬───────────────┘ │
│ │ │
▼ ▼ ▼
┌───────────────────────────────────────┐ ┌─────────────────────────┐
│ 3. build-and-push-images │ │ 4. deploy-lambda │
│ (Docker services) │ │ (S3 Notifier only) │
│ │ │ │
│ - Build .NET images │ │ - Build Lambda package │
│ - Push to GHCR │ │ - Deploy to AWS Lambda │
│ - Tags: version, version-sha │ │ - Upload package │
│ │ │ │
│ REQUIRES: test-dotnet AND test-web │ │ │
│ to pass (or be skipped) │ │ │
└─────────────────┬─────────────────────┘ └───────────┬─────────────┘
│ │
├────────────┬───────────────────────┘
│ │
┌──────────▼────────┐ │
│ 5. promote-to- │ │
│ staging │ │
│ (Docker only) │ │
│ │ │
│ - Clone gitops │ │
│ - Update values │ │
│ - Create PR │ │
└──────────┬────────┘ │
│ │
└─────┬─────┘
│
┌──────────────▼────────────────────┐
│ 6. create-and-push-tags │
│ (Runs AFTER all builds) │
│ │
│ ONLY creates tags if both: │
│ 1. Versioning succeeded │
│ 2. Build/deployment succeeded │
│ │
│ Tags: {service}-v{version} │
│ NO ORPHANED TAGS │
└──────────────┬────────────────────┘
│
┌──────────────▼────────────────────┐
│ 7. create-lambda-release │
│ (S3 Notifier only) │
│ │
│ - Download Lambda package │
│ - Create GitHub Release │
│ - Attach package as artifact │
└───────────────────────────────────┘
Job Details¶
1. detect-changes¶
Purpose: Determine which services need building based on changes since last tag
Implementation: Uses tag-based detection script (.github/scripts/detect-service-changes.sh)
How it works:
- For each service, find the last matching git tag (e.g.,
api-v8.21.0) - Compare source files against that tag using
git diff - Check if Docker image exists in GHCR for that version
- Determine action:
build,retag,skip
Source Paths Checked:
api:src/services/api/**,src/libs/kernel/**,src/libs/mongo/**, etc.pm:src/services/project-management/**, plus shared librariesquartz:src/services/quartz/**, plus dependenciesweb:src/services/web/**user_guide:user-guide/**docs:docs/**,mkdocs.ymls3_notifier:src/services/s3-notifier/**,src/libs/s3-notifier/**
Outputs per service:
{service}_changed: Boolean (trueif source or chart changed){service}_needs_build: Boolean (trueif Docker build required){service}_needs_retag: Boolean (trueif only chart changed, can retag)
Manual Override: Use workflow dispatch with force_rebuild_* options to bypass detection.
See ADR-007: Tag-Based Change Detection for details.
2. version-* Jobs (Parallel Execution)¶
Purpose: Calculate semantic version for each changed service
Jobs: version-api, version-pm, version-quartz, version-web, version-s3-notifier
Trigger: Only runs if corresponding service changed
Process:
- Checkout code with full git history (
fetch-depth: 0) - Install GitVersion 6.x
- Run GitVersion with service-specific config:
src/services/{service}/GitVersion.yml - Output calculated version and SHA
Outputs:
version: Semantic version (e.g.,1.2.3)sha: Short commit SHA
GitVersion Config:
- Mode:
ContinuousDeployment - Tag prefix:
{service}-v(e.g.,api-v,s3-notifier-v) - Conventional commits:
feat:,fix:,chore:
2.5. test-* Jobs (Test Phase)¶
Purpose: Run automated tests before Docker builds to catch issues early
Jobs: test-dotnet, test-web
Trigger: Only runs if corresponding services changed
test-dotnet¶
Trigger: If API, PM, Quartz, or S3 Notifier changed
Process:
- Checkout code
- Setup .NET 10.x
- Restore dependencies (
dotnet restore syrf.sln) - Build solution (
dotnet build --configuration Release) - Run tests with coverage (
dotnet testwith XPlat Code Coverage) - Upload test results and coverage artifacts
Timeout: 10 minutes
Artifacts:
dotnet-test-results-{sha}: TRX test result filesdotnet-coverage-{sha}: Cobertura XML coverage files
test-web¶
Trigger: If web service changed
Process:
- Checkout code
- Setup Node.js 20
- Install dependencies (
pnpm install --frozen-lockfile) - Run Vitest tests with coverage (
pnpm exec ng test --no-watch --coverage) - Upload coverage artifacts
Timeout: 5 minutes
Artifacts:
web-coverage-{sha}: Coverage reports (lcov, cobertura, text)web-test-results-{sha}: JUnit XML test results
Coverage Thresholds (configured in vitest.config.ts):
- Statements: 50%
- Branches: 40%
- Functions: 50%
- Lines: 50%
Tests fail if coverage drops below these thresholds.
Build Gate¶
The build-docker job requires tests to pass:
needs: [detect-changes, version, build-web-artifacts, test-dotnet, test-web]
if: |
(needs.test-dotnet.result == 'success' || needs.test-dotnet.result == 'skipped') &&
(needs.test-web.result == 'success' || needs.test-web.result == 'skipped')
If tests fail, Docker builds are blocked and deployment does not proceed.
See How to: Run Tests for local testing instructions.
3. build-and-push-images¶
Purpose: Build Docker images for all .NET and Angular services
Depends On: version-api, version-pm, version-quartz, version-web
Trigger: If ANY version job succeeded
Process:
- Setup Docker Buildx
- Login to GHCR (GitHub Container Registry)
- For each successfully versioned service:
- Build Docker image from Dockerfile
- Push to
ghcr.io/camaradesuk/syrf-{service} - Tag with:
{version},{version}-sha.{sha},latest - Use GitHub Actions cache for layer caching
Services Built:
- API:
.src/services/api/SyRF.API.Endpoint/Dockerfile - PM:
./src/services/project-management/SyRF.ProjectManagement.Endpoint/Dockerfile - Quartz:
./src/services/quartz/SyRF.Quartz/Dockerfile - Web:
./src/services/web/Dockerfile
Permissions: contents: read, packages: write
4. deploy-lambda¶
Purpose: Build and deploy S3 Notifier to AWS Lambda
Depends On: version-s3-notifier
Trigger: If version-s3-notifier succeeded
Process:
- Setup .NET 10.0
- Install Amazon.Lambda.Tools globally
- Restore dependencies
- Build Lambda package:
dotnet lambda package - Output:
s3-notifier-{version}.zip - Configuration: Release
- Framework: net10.0
- Deploy to AWS Lambda:
dotnet lambda deploy-function - Function name:
syrfAppUploadS3Notifier - Region:
eu-west-1 - Runtime:
dotnet10 - Tags: Version, SHA, Repository
- Upload package as GitHub artifact (90 day retention)
AWS Secrets Required:
AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY
5. promote-to-staging¶
Purpose: Automatically create PR to cluster-gitops repository to deploy services to staging
Depends On: build-and-push-images, all version-* jobs (except s3-notifier)
Trigger: If build-and-push-images succeeded AND at least one Docker service versioned successfully
Process:
- Checkout
cluster-gitopsrepository usingGITOPS_PAT - For each successfully built Docker service:
- Update
environments/staging/{service}.values.yaml - Replace
image.tagwith new version usingsed - Create pull request using
peter-evans/create-pull-requestaction - Branch:
promote/staging-{run-number} - Title: "Promote services to staging"
- Body: List of updated services with versions and source run link
- Labels:
staging,automated,gitops - Auto-delete branch after merge
- Output summary to GitHub Actions step summary
Services Updated (Docker only):
- API:
environments/staging/api.values.yaml - PM:
environments/staging/project-management.values.yaml - Quartz:
environments/staging/quartz.values.yaml - Web:
environments/staging/web.values.yaml
Note: S3 Notifier (Lambda) is NOT promoted via GitOps - it deploys directly to AWS Lambda
GitHub Secret Required:
APP_ID: GitHub App ID for cluster-gitops authenticationAPP_PRIVATE_KEY: GitHub App private key for cluster-gitops authentication- See setup-gitops-github-app.md for configuration instructions
Example PR Body:
## Automated Staging Promotion
This PR updates the staging environment with the latest service versions from the CI/CD pipeline.
**Source Run**: [123](https://github.com/camaradesuk/syrf/actions/runs/123)
**Source Commit**: abc123def456
### Services Updated
- API: `v8.21.0`
- Web: `v5.0.1`
### Deployment
Once merged, ArgoCD will automatically sync the changes to the staging cluster.
6. create-and-push-tags¶
Purpose: Create git tags ONLY for successful builds/deployments
Depends On: build-and-push-images, deploy-lambda, all version-* jobs
Trigger: always() (runs even if some jobs failed)
Process:
- Checkout code with full history
- Configure git user as
github-actions[bot] - For each service:
- Check BOTH conditions: a) Version job succeeded b) Build/deployment job succeeded
- If both true: Create annotated tag
{service}-v{version} - If either false: Skip (no tag created)
- Push all created tags to remote
Tag Logic (Docker Services):
if [ "${{ needs.version-api.result }}" = "success" ] &&
[ "${{ needs.build-and-push-images.result }}" = "success" ]; then
git tag -a "api-v${VERSION}" -m "Release API v${VERSION}"
fi
Tag Logic (Lambda):
if [ "${{ needs.version-s3-notifier.result }}" = "success" ] &&
[ "${{ needs.deploy-lambda.result }}" = "success" ]; then
git tag -a "s3-notifier-v${VERSION}" -m "Release S3 Notifier v${VERSION}"
fi
Summary Output: Shows which tags were created and which builds failed
6. create-lambda-release¶
Purpose: Create GitHub Release for S3 Notifier Lambda with package artifact
Depends On: create-and-push-tags, version-s3-notifier, deploy-lambda
Trigger: If all three dependencies succeeded
Process:
- Download Lambda package from GitHub artifact
- Create GitHub Release using
softprops/action-gh-release - Tag:
s3-notifier-v{version} - Name:
S3 Notifier v{version} - Body: Deployment details (function name, region, runtime, commit)
- Attach Lambda package (.zip file)
- Not a draft or prerelease
Permissions: contents: write
GitOps Promotion Workflow¶
The promotion workflow creates a declarative deployment pipeline:
- CI builds and pushes Docker images to GHCR
- Promotion job creates PR to cluster-gitops repository
- Human reviews and merges the PR (manual approval gate)
- ArgoCD detects change and syncs to Kubernetes cluster
- Services deployed to staging environment
This approach provides:
- Audit trail: All deployments tracked via git history
- Rollback capability: Revert PR to rollback deployment
- Manual approval: Team can review before deployment
- Declarative state: GitOps repository represents desired cluster state
Key Design Principles¶
1. No Orphaned Tags¶
Problem: Don't want git tags pointing to non-existent artifacts
Solution: Tags are created ONLY after successful builds/deployments
Example:
- If API build fails → No
api-vX.Y.Ztag created - If Lambda deployment fails → No
s3-notifier-vX.Y.Ztag created - User sees clear indication in workflow summary
2. Partial Success Handling¶
Scenario: API builds successfully, PM build fails
Behavior:
- API: ✅ Docker image pushed, ✅ tag created
- PM: ❌ No Docker image, ❌ No tag created
- Workflow continues (doesn't fail completely)
- Summary shows which succeeded and which failed
3. Artifact Retention¶
Docker Images: Stored in GHCR indefinitely (until manually deleted)
Lambda Packages:
- GitHub Artifacts: 90 days retention
- GitHub Releases: Indefinite (attached to release)
4. Parallel Execution¶
Version Jobs: Run in parallel (5 jobs simultaneously)
Build Jobs: Sequential within job but parallel between services
Benefit: Faster overall workflow execution
Workflow Execution Examples¶
Example 1: API and PM Changed¶
1. detect-changes
└─ api_changed=true, pm_changed=true
2. version-api (parallel with version-pm)
└─ version=1.2.3, sha=abc123
3. version-pm
└─ version=2.3.4, sha=abc123
4. build-and-push-images
├─ Build API → ghcr.io/camaradesuk/syrf-api:1.2.3
└─ Build PM → ghcr.io/camaradesuk/syrf-pm:2.3.4
5. promote-to-staging
├─ Update api.values.yaml → tag: "1.2.3"
├─ Update project-management.values.yaml → tag: "2.3.4"
└─ Create PR to cluster-gitops: "Promote services to staging"
6. create-and-push-tags
├─ Create tag: api-v1.2.3
└─ Create tag: pm-v2.3.4
Example 2: S3 Notifier Changed¶
1. detect-changes
└─ s3_notifier_changed=true
2. version-s3-notifier
└─ version=1.0.5, sha=def456
3. deploy-lambda
├─ Build package: s3-notifier-1.0.5.zip
├─ Deploy to syrfAppUploadS3Notifier
└─ Upload artifact
4. create-and-push-tags
└─ Create tag: s3-notifier-v1.0.5
5. create-lambda-release
├─ Download s3-notifier-1.0.5.zip
└─ Create GitHub Release with package
Example 3: Build Failure¶
1. detect-changes
└─ api_changed=true
2. version-api
└─ version=1.2.4, sha=ghi789
3. build-and-push-images
└─ Build API → FAILS (Docker error)
4. create-and-push-tags
└─ NO TAG CREATED (build failed)
Summary shows:
- ❌ API: v1.2.4 (Docker build failed - no tag created)
Monitoring and Debugging¶
View Workflow Run¶
- Go to Actions tab in GitHub
- Select Auto Version with GitVersion workflow
- Click on specific run
Check Job Status¶
- Green checkmark: Job succeeded
- Red X: Job failed
- Yellow circle: Job skipped or in progress
Check Tag Creation¶
# Fetch latest tags
git fetch --tags
# List service tags
git tag -l "api-v*"
git tag -l "s3-notifier-v*"
Check Docker Images¶
# List images in GHCR
gh api /user/packages/container/syrf-api/versions
# Or use Docker
docker pull ghcr.io/camaradesuk/syrf-api:latest
Check Lambda Deployment¶
# Get Lambda function info
aws lambda get-function \
--function-name syrfAppUploadS3Notifier \
--region eu-west-1
# Check Lambda tags
aws lambda list-tags \
--resource arn:aws:lambda:eu-west-1:ACCOUNT:function:syrfAppUploadS3Notifier
Check GitHub Releases¶
Visit: https://github.com/camaradesuk/syrf/releases
Look for releases with tag s3-notifier-v*
Troubleshooting¶
Tag Not Created¶
Check:
- Did version job succeed? (Check
version-{service}job) - Did build/deploy job succeed? (Check
build-and-push-imagesordeploy-lambda) - Both must be green for tag to be created
Fix: Fix the failing build/deployment job and rerun workflow
Docker Build Fails¶
Common Causes:
- Syntax error in Dockerfile
- Missing dependencies
- Build context issues
- Network/GHCR connectivity
Fix: Check build logs in build-and-push-images job
Lambda Deployment Fails¶
Common Causes:
- Missing AWS credentials
- Incorrect IAM permissions
- Lambda function doesn't exist
- Network issues
Fix: Check deploy-lambda job logs, verify AWS secrets
Release Not Created¶
Prerequisite: Tag must be created first
Check:
- Does
s3-notifier-v{version}tag exist? - Did
create-lambda-releasejob run? - Check job logs for errors
Promotion PR Not Created¶
Common Causes:
- Missing or invalid
GITOPS_PATsecret build-and-push-imagesjob failed- No Docker services built successfully (e.g., only Lambda changed)
- Token doesn't have
reposcope - Token doesn't have access to cluster-gitops repository
Fix:
- Check
promote-to-stagingjob logs in GitHub Actions - Verify
APP_IDandAPP_PRIVATE_KEYsecrets exist and are accessible - Ensure GitHub App has proper permissions (Contents: Read/Write, PRs: Read/Write)
- Verify at least one Docker service (API/PM/Quartz/Web) built successfully
- See setup-gitops-github-app.md for GitHub App configuration
Promotion PR Created But Values Not Updated¶
Symptom: PR exists but image tags in values files unchanged
Common Causes:
sedcommand pattern mismatch- Values file structure changed
- Branch conflicts in cluster-gitops
Fix:
- Check PR diff in cluster-gitops repository
- Verify values file structure matches expected format:
- Close conflicting PRs or branches in cluster-gitops
Staging Environment¶
Overview¶
Staging is a pre-production environment that receives automated deployments from the CI/CD pipeline after successful builds on main branch.
Staging vs Production¶
| Aspect | Staging | Production |
|---|---|---|
| URL Pattern | *.staging.syrf.org.uk |
*.syrf.org.uk |
| Namespace | staging |
production |
| Promotion | Automatic (PR auto-merges) | Manual (requires review) |
| Database | syrftest ⚠️ |
syrftest |
| RabbitMQ Vhost | staging |
/ (default) |
| Quartz Schema | [staging] |
[production] |
| Replicas | 1 per service | 2+ per service |
| Resources | Reduced | Full allocation |
⚠️ CRITICAL: Database Sharing¶
Staging shares the production database (syrftest). This is a known issue and represents a significant risk.
Implications:
- Changes in staging can affect production data
- Staging tests run against live user data
- Schema migrations must be backwards-compatible
- No isolated testing of data-destructive operations
Planned resolution: See MongoDB Testing Strategy for the plan to create syrf_staging database.
Staging Deployment Flow¶
┌─────────────────────────────────────────────────────────────────────────────┐
│ Staging Deployment Flow │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. Push to main │
│ ↓ │
│ 2. CI/CD builds Docker images │
│ ↓ │
│ 3. Images pushed to GHCR │
│ ghcr.io/camaradesuk/syrf-{service}:{version} │
│ ↓ │
│ 4. promote-to-staging job creates PR to cluster-gitops │
│ Updates: syrf/environments/staging/{service}/config.yaml │
│ ↓ │
│ 5. PR validation passes (YAML lint, etc.) │
│ ↓ │
│ 6. PR auto-merges (no human approval required for staging) │
│ ↓ │
│ 7. ArgoCD ApplicationSet detects config.yaml change │
│ ↓ │
│ 8. ArgoCD regenerates Application with new targetRevision │
│ ↓ │
│ 9. ArgoCD syncs: pulls Helm chart, deploys to staging namespace │
│ ↓ │
│ 10. PostSync hook creates GitHub commit status (argocd/deploy-staging) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Staging Version Files¶
Staging service versions are stored in the cluster-gitops repository:
cluster-gitops/syrf/environments/staging/
├── namespace.yaml # Environment metadata
├── staging.values.yaml # Environment-specific Helm values
├── api/
│ ├── config.yaml # chartTag: "8.21.0" (updated by CI/CD)
│ └── values.yaml # Service-specific overrides
├── project-management/
│ ├── config.yaml
│ └── values.yaml
├── quartz/
│ ├── config.yaml
│ └── values.yaml
└── web/
├── config.yaml
└── values.yaml
Verifying Staging Deployment¶
Check deployment status:
# Via ArgoCD CLI (requires cluster access)
argocd app get syrf-staging-api
# Via kubectl
kubectl get deployments -n staging
kubectl get pods -n staging
# Check running versions
kubectl get deployment syrf-api -n staging -o jsonpath='{.spec.template.spec.containers[0].image}'
Check commit status in GitHub:
- Navigate to the commit on
mainbranch - Look for
argocd/deploy-stagingstatus check
Production Promotion¶
Overview¶
Production deployments require manual approval via PR merge in the cluster-gitops repository.
Promotion Flow¶
┌─────────────────────────────────────────────────────────────────────────────┐
│ Production Promotion Flow │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. After successful staging promotion (PR merged) │
│ ↓ │
│ 2. promote-to-production job automatically triggers │
│ ↓ │
│ 3. Job copies service configs from staging to production │
│ syrf/environments/staging/{service}/config.yaml │
│ ↓ copy values ↓ │
│ syrf/environments/production/{service}/config.yaml │
│ ↓ │
│ 4. Updates envName from "staging" to "production" │
│ ↓ │
│ 5. Creates PR to cluster-gitops │
│ Labels: requires-review, automated │
│ ↓ │
│ 6. Workflow completes (green checkmark) │
│ PR is NOT auto-merged │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────────────────┐│
│ │ 7. MANUAL GATE: Administrator reviews and merges PR ││
│ │ - Review what services are being updated ││
│ │ - Verify staging testing is complete ││
│ │ - Coordinate deployment timing ││
│ └─────────────────────────────────────────────────────────────────────────┘│
│ ↓ │
│ 8. After merge, ArgoCD syncs to production namespace │
│ ↓ │
│ 9. PostSync hook creates GitHub commit status (argocd/deploy-production) │
│ ↓ │
│ 10. PostSync hook creates GitHub Release (production only) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Production Checklist¶
Before merging a production promotion PR:
- Staging deployment verified working
- Critical user flows tested in staging
- No known regressions or blockers
- Database migrations are backwards-compatible
- On-call team aware of deployment
- Deployment timing appropriate (avoid peak hours)
Rollback Procedure¶
Quick rollback (preferred):
- In cluster-gitops, find the previous production promotion PR
- Copy the old
chartTagvalues from git history - Create a new PR reverting the config.yaml changes
- Merge the revert PR
- ArgoCD will sync the previous versions
Alternative - via ArgoCD:
# List application history
argocd app history syrf-production-api
# Rollback to previous revision
argocd app rollback syrf-production-api {revision-number}
Note: ArgoCD rollback is temporary - the next sync will revert to git state. Always fix in git for permanent changes.
Environment Comparison¶
Complete Environment Matrix¶
| Aspect | Preview | Staging | Production |
|---|---|---|---|
| Trigger | PR + preview label |
Push to main |
Manual PR merge |
| Namespace | pr-{number} |
staging |
production |
| URL | pr-{n}.syrf.org.uk |
staging.syrf.org.uk |
syrf.org.uk |
| MongoDB | syrf_pr_{number} |
syrftest ⚠️ |
syrftest |
| Quartz Schema | [preview_{number}] |
[staging] |
[production] |
| RabbitMQ | pr-{number} |
staging |
/ |
| Lambda | *-pr-{number} |
(shared prod) | syrfAppUploadS3Notifier |
| S3 Prefix | preview/pr-{n}/ |
(shared prod) | Projects/ |
| Auto-cleanup | Yes (on PR close) | No | No |
| GitHub Deployment | Yes | No (commit status) | No (commit status + Release) |
| Replicas | 1 | 1 | 2+ |
| Resources | Minimal | Reduced | Full |
| Data | Seed/Snapshot | Production ⚠️ | Production |
Data Isolation Status¶
| Environment | Database | Isolation | Risk Level |
|---|---|---|---|
| Preview | syrf_pr_{number} |
✅ Full | Low |
| Staging | syrftest |
❌ Shares with production | High |
| Production | syrftest |
N/A (is production) | N/A |
Planned improvements: Staging will get its own syrf_staging database - see MongoDB Testing Strategy.
Related Documentation¶
- GitOps GitHub App Setup: setup-gitops-github-app.md - Required for promotion automation
- Sentry Integration: setup-sentry-integration.md - Web service sourcemaps
- S3 Notifier Service: src/services/s3-notifier/README.md
- CI/CD Decisions: docs/decisions/ADR-001-ci-cd-approach.md
- Dependency Map: docs/architecture/dependency-map.yaml
- CLAUDE.md: Main developer reference guide
Maintenance¶
Adding a New Service¶
- Create service in
src/services/{new-service}/ - Add GitVersion.yml to service folder
- Add Dockerfile (or Lambda configuration)
- Update
detect-changesjob with new path filter - Add
version-{new-service}job - Add to either
build-and-push-imagesor create new deployment job - Add to
create-and-push-tagslogic - Test with a commit to the new service
Modifying Tag Logic¶
Tags are created in create-and-push-tags job.
To change tag format or conditions:
- Edit
.github/workflows/ci-cd.yml - Find
create-and-push-tagsjob - Modify bash script in "Create and push tags" step
- Test thoroughly before merging
Changing Lambda Function Name¶
If Lambda function name changes:
- Update
deploy-lambdajob:dotnet lambda deploy-function {NEW_NAME} - Update documentation
- Update AWS IAM policies
- Consider migration strategy for existing function