feat(ci/cd): Implement release-based deployment with two-workflow architecture

- Add prepare-release.yml: Manual release creation workflow
  * Builds code, generates appsettings.Production.json
  * Packages artifact (.tar.gz)
  * Creates git tag and Gitea Release with attached artifact

- Refactor deploy-prod.yml: Release-based deployment workflow
  * Fetch Release stage: Query Gitea Releases, download artifact
  * Pre-Check stage: Verify SSH credentials and release integrity
  * Deploy stage: Upload, extract, symlink, restart service
  * Health Check stage: 5-point verification (HTTP, CSS, login, service, release)
  * Report stage: Final deployment status
  * Now triggered via workflow_dispatch with release version input
  * Removes on:push trigger (manual release selection required)

- Update CLAUDE.md:
  * Document two-workflow architecture
  * Add release creation and deployment procedures
  * Update SSH key configuration with GITEA_TOKEN requirement
  * Clarify CI/CD-Only Deployment Mandate with release traceability
  * Add complete deployment flow documentation

**Motivation**:
- Separate build/release phase from deployment phase
- Enable release tagging for version control and rollback
- Reduce build time on re-deployments (use cached releases)
- Improve deployment auditability via git tags and Gitea Releases
- Match taxbaik-pattern release management strategy

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-07-11 23:21:20 +09:00
parent c10f9f78c0
commit 352b440e8d
3 changed files with 376 additions and 130 deletions
+108 -26
View File
@@ -120,40 +120,60 @@ Projects on server:
- Audit trail (all deployments logged in Gitea Actions)
- Consistent process (no manual errors)
- Rollback safety (deployment history retained)
- Release traceability (version control via git tags)
### Production Deployment Strategy (Gitea Actions CI/CD)
### Production Deployment Strategy (Release-Based)
**Status**: Gitea Actions fully operational (taxbaik-pattern with enhanced health checks)
**Architecture**: Two-Workflow System (Release Creation → Deployment)
**Pre-Deployment Checklist**:
1. ✅ Local build: `dotnet build src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj -c Release`
2. ✅ E2E tests pass: `npx playwright test`
3. ✅ Admin pages verified (200 status, no 500 errors)
4. ✅ All changes committed to main branch
#### Workflow 1: prepare-release.yml (Release Creation)
**Deployment via Gitea Actions (CI/CD)**:
**Purpose**: Create a release with built artifact
**Option A: Automatic (on push to main)**
**Trigger**: Manual (`workflow_dispatch`)
```bash
git push origin main
# → Gitea Actions automatically triggers deploy-prod.yml
# → Build, deploy, health checks run automatically
# Visit Gitea Actions and select prepare-release.yml
# Input version: v0.1.20260711 (or any semantic version)
```
**Option B: Manual (workflow_dispatch)**
1. Visit: https://gitea.taxbaik.com/kjh2064/QuantEngineByItz/actions
2. Click "Deploy to Production" workflow
3. Click "Run workflow" button
4. Monitor execution in Gitea Actions UI
**What it does**:
1. ✓ Build (restore, build, publish)
2. ✓ Generate `appsettings.Production.json`
3. ✓ Package artifact: `.tar.gz`
4. ✓ Create git tag: `v0.1.20260711`
5. ✓ Create Gitea Release with artifact attached
6. ✓ Notify: Release ready for deployment
**Deployment Pipeline (Automatic - 7 Stages)**:
**Output**: Gitea Release with downloadable artifact
#### Workflow 2: deploy-prod.yml (Deployment)
**Purpose**: Deploy a release to production
**Trigger**: Manual (`workflow_dispatch`)
```bash
# Visit Gitea Actions and select deploy-prod.yml
# Input release: v0.1.20260711 (optional — uses latest if empty)
```
**What it does**:
1. ✓ Fetch Release (from Gitea Releases)
2. ✓ Download artifact
3. ✓ Verify SSH credentials
4. ✓ Upload to production server
5. ✓ Extract and symlink
6. ✓ Restart service
7. ✓ 5-point health checks
8. ✓ Report deployment status
**Deployment Pipeline (5 Stages)**:
| Stage | Purpose | Timeout |
|-------|---------|---------|
| 1. Build | Restore, build, publish Release | 15min |
| 2. Pre-Check | Verify SSH keys, secrets, artifact | 5min |
| 3. Deploy | Upload artifact, extract, symlink, restart | 30min |
| 4. Health Check | 5-point verification (HTTP, CSS, login, service, commit) | 10min |
| 1. Fetch Release | Query Gitea Releases, download artifact | 10min |
| 2. Pre-Check | Verify SSH keys, secrets, release | 5min |
| 3. Deploy | Upload, extract, symlink, restart service | 30min |
| 4. Health Check | 5-point verification (HTTP, CSS, login, service, release) | 10min |
| 5. Report | Final deployment status | Auto |
**Health Checks (Automatic)**:
@@ -161,7 +181,62 @@ git push origin main
- ✓ Login page content verification
- ✓ CSS file loads (`/css/admin.css`)
- ✓ Service status (systemctl active)
-Commit hash verification (deployed version matches)
-Release verification (deployed release tag matches)
**Complete Deployment Flow**:
```
1. Code committed to main branch
2. Create release: prepare-release.yml workflow_dispatch (manual)
→ Builds code
→ Creates Gitea Release with artifact
→ Tags repository
3. Deploy release: deploy-prod.yml workflow_dispatch (manual)
→ Selects release version
→ Downloads artifact from Gitea Release
→ Deploys to production server
→ Runs health checks
→ Reports status
```
### Pre-Deployment Checklist
**Before creating a release**, verify:
1. ✅ Local build: `dotnet build src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj -c Release` (0 errors, 0 warnings)
2. ✅ E2E tests pass: `npx playwright test`
3. ✅ Admin pages verified (200 status, no 500 errors)
4. ✅ All changes committed and pushed to main branch
5. ✅ No uncommitted changes: `git status`
### Release & Deployment Workflow
**Step 1: Create Release (prepare-release.yml)**
```bash
# Visit Gitea Actions
# https://gitea.taxbaik.com/kjh2064/QuantEngineByItz/actions
# Run prepare-release.yml workflow
# Input: version = v0.1.20260711
# Workflow will:
# - Build and publish
# - Package artifact
# - Create git tag
# - Create Gitea Release
# - Attach artifact
```
**Step 2: Deploy Release (deploy-prod.yml)**
```bash
# Visit Gitea Actions (same page)
# Run deploy-prod.yml workflow
# Input: release = v0.1.20260711 (leave empty for latest)
# Workflow will:
# - Download artifact from release
# - Deploy to production server
# - Run health checks
# - Report status
```
### SSH Key Configuration (Required)
@@ -178,15 +253,22 @@ git push origin main
3. Get private key in base64 format:
```bash
base64 -w 0 ~/.ssh/quantengine_deploy | wc -c
base64 -w 0 ~/.ssh/quantengine_deploy | pbcopy # macOS
# On Windows: Get-Content ~/.ssh/quantengine_deploy -Raw | [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($_)) | Set-Clipboard
# macOS/Linux
base64 -w 0 ~/.ssh/quantengine_deploy > /tmp/key_b64.txt
cat /tmp/key_b64.txt | pbcopy
# Or Windows PowerShell
$key = Get-Content ~/.ssh/quantengine_deploy -Raw
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($key)) | Set-Clipboard
```
4. Configure in Gitea:
- URL: https://gitea.taxbaik.com/kjh2064/QuantEngineByItz/settings/secrets
- Add secret: `DEPLOY_SSH_KEY_B64` (base64-encoded private key)
- Or: `DEPLOY_SSH_KEY` (raw PEM format)
- Also add: `GITEA_TOKEN` (for release API access)
- Generate at: https://gitea.taxbaik.com/user/settings/applications
- Required permissions: `repo` + `read:actions`
### Deployment Monitoring