docs: add frontend conventions, CI/CD templates, and deployment scripts

- Frontend conventions document (setup, patterns, workflow)
- CI workflow template for GitHub Actions
- Staging deploy workflow template
- Plesk post-deploy script template

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martin Porwoll 2026-02-14 17:53:09 +00:00
parent 774d7bc402
commit 715783dbf3
4 changed files with 196 additions and 0 deletions

View file

@ -0,0 +1,108 @@
# Frontend Conventions
This document defines conventions for all frontend repos consuming Payload CMS via `@c2s/payload-contracts`.
## Setup
### Install Contracts Package (Git dependency)
```json
{
"dependencies": {
"@c2s/payload-contracts": "github:complexcaresolutions/payload-contracts"
}
}
```
```bash
pnpm install
```
### Environment Variables
Every frontend needs these in `.env.local`:
```env
NEXT_PUBLIC_PAYLOAD_URL=https://cms.c2sgmbh.de
NEXT_PUBLIC_TENANT_ID=<tenant-id>
NEXT_PUBLIC_TENANT_SLUG=<tenant-slug>
NEXT_PUBLIC_SITE_URL=https://<domain>
NODE_ENV=production
```
### API Client Initialization
```typescript
// src/lib/cms.ts
import { createPayloadClient } from '@c2s/payload-contracts/api-client'
export const cms = createPayloadClient({
baseUrl: process.env.NEXT_PUBLIC_PAYLOAD_URL!,
tenantId: process.env.NEXT_PUBLIC_TENANT_ID!,
})
```
### Block Renderer Setup
```typescript
// src/components/blocks/index.tsx
import { createBlockRenderer } from '@c2s/payload-contracts/blocks'
import { HeroBlock } from './HeroBlock'
import { TextBlock } from './TextBlock'
// ... import site-specific block components
export const BlockRenderer = createBlockRenderer({
'hero-block': HeroBlock,
'text-block': TextBlock,
// Register only blocks this site uses
})
```
## Git Workflow
| Branch | Purpose | Deployment |
|--------|---------|------------|
| `develop` | Active development | Staging (sv-frontend) |
| `main` | Production-ready | Plesk auto-deploy |
### Commit Conventions
```
feat: add hero block component
fix: correct image aspect ratio in card grid
refactor: extract shared section header component
```
## TypeScript Standards
- Strict mode enabled
- Import types from `@c2s/payload-contracts`, never define CMS types locally
- Use `BlockByType<'hero-block'>` for block component props
- All API calls through the shared client, never raw `fetch` to CMS
## Block Component Pattern
```typescript
// src/components/blocks/HeroBlock.tsx
import type { BlockByType } from '@c2s/payload-contracts/types'
import { getImageUrl } from '@c2s/payload-contracts/types'
type Props = Omit<BlockByType<'hero-block'>, 'blockType'>
export function HeroBlock({ title, subtitle, image, ctaButtons }: Props) {
const imageUrl = getImageUrl(image, 'xlarge')
// ... render
}
```
## Updating Contracts
When a work order arrives:
1. `pnpm update @c2s/payload-contracts` (or `pnpm install` for Git deps)
2. Check `node_modules/@c2s/payload-contracts/work-orders/` for instructions
3. Implement changes
4. `pnpm build` to verify types
5. Commit and push to `develop`
6. Test on staging
7. Merge to `main` for production deploy

View file

@ -0,0 +1,35 @@
# CI Workflow Template for Frontend Repos
# Copy to: .github/workflows/ci.yml
name: CI
on:
push:
branches: [develop, main]
pull_request:
branches: [develop]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 10
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm build
env:
NEXT_PUBLIC_PAYLOAD_URL: https://cms.c2sgmbh.de
NEXT_PUBLIC_TENANT_ID: ${{ vars.TENANT_ID }}
NEXT_PUBLIC_TENANT_SLUG: ${{ vars.TENANT_SLUG }}
NEXT_PUBLIC_SITE_URL: ${{ vars.SITE_URL }}

View file

@ -0,0 +1,32 @@
# Staging Deploy Template for Frontend Repos
# Copy to: .github/workflows/deploy-staging.yml
# Requires secret: FRONTEND_SSH_KEY (SSH key for sv-frontend)
name: Deploy Staging
on:
push:
branches: [develop]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to sv-frontend
uses: appleboy/ssh-action@v1
with:
host: 10.10.181.104
username: frontend
key: ${{ secrets.FRONTEND_SSH_KEY }}
script: |
REPO_NAME="${{ github.event.repository.name }}"
cd ~/frontend.${REPO_NAME#frontend.}
git fetch origin develop
git reset --hard origin/develop
export PATH="/home/frontend/.local/share/pnpm:$PATH"
pnpm install --frozen-lockfile
pnpm build
# Restart if using PM2
pm2 restart "frontend-${REPO_NAME#frontend.}" --silent 2>/dev/null || true

View file

@ -0,0 +1,21 @@
#!/bin/bash
# Plesk Post-Deploy Script
# Configure in: Plesk → Domain → Git → Post-deploy actions
#
# This runs after Plesk pulls the latest code from the main branch.
set -e
export NODE_ENV=production
export PATH=/opt/plesk/node/22/bin:$PATH
echo "[deploy] Installing dependencies..."
pnpm install --frozen-lockfile 2>/dev/null || npm ci
echo "[deploy] Building..."
pnpm build 2>/dev/null || npm run build
echo "[deploy] Restarting application..."
touch tmp/restart.txt
echo "[deploy] Done!"