CI/CD-Pipeline
Automatisiere Content-Updates und Veröffentlichungen mit GitHub Actions und dem OptimoCMS SDK. Von Staging zu Produktion in einem Push.
CI/CD-Pipeline mit GitHub Actions
Automatisiere deinen OptimoCMS-Workflow mit GitHub Actions. Pushe Content-Änderungen in ein Repository und lass die Pipeline automatisch deine Site aktualisieren und veröffentlichen.
In diesem Tutorial:
- GitHub Actions Workflow einrichten
- Content über das SDK in CI aktualisieren
- Staging (Sandbox) → Produktion Flow
- Automatische Veröffentlichung bei Merge nach
main
Voraussetzungen
- GitHub-Repository mit deiner Content-/Konfiguration
- OptimoCMS API-Schlüssel (als GitHub Secret gespeichert)
- Optional: eine Sandbox-Site für Staging
Schritt 1 — GitHub Secrets einrichten
Gehe zu deinem Repository → Settings → Secrets and variables → Actions und füge hinzu:
| Secret | Wert |
|---|---|
OPTIMOCMS_API_KEY | Dein Live-API-Schlüssel |
OPTIMOCMS_SITE_ID | Deine Produktions-Site-ID |
OPTIMOCMS_SANDBOX_KEY | (optional) Sandbox-API-Schlüssel für Staging |
OPTIMOCMS_SANDBOX_SITE_ID | (optional) Sandbox-Site-ID |
Schritt 2 — Content als Code
Strukturiere deinen Content im Repository:
content/
├── pages/
│ ├── home.json
│ ├── about.json
│ └── menu.json
├── design-tokens.json
└── navigation.jsonBeispiel content/pages/home.json:
{
"title": "Home",
"slug": "home",
"blocks": [
{
"type": "Hero",
"props": {
"title": "Willkommen in unserem Restaurant",
"subtitle": "Die beste italienische Küche seit 1985",
"ctaText": "Jetzt reservieren",
"ctaLink": "/reservieren"
}
},
{
"type": "FeaturedMenu",
"props": {
"title": "Empfehlung des Chefs",
"items": ["bruschetta", "risotto", "tiramisu"]
}
}
]
}Schritt 3 — Deploy-Skript
Erstelle ein scripts/deploy.ts, das Content an OptimoCMS überträgt:
import { OptimoCMS } from '@optimocms/sdk';
import { readFileSync, readdirSync } from 'node:fs';
import { join } from 'node:path';
const client = new OptimoCMS({
apiKey: process.env.OPTIMOCMS_API_KEY!,
});
const siteId = process.env.OPTIMOCMS_SITE_ID!;
interface PageContent {
title: string;
slug: string;
blocks: Array<{ type: string; props: Record<string, unknown> }>;
seo?: { title?: string; description?: string };
}
async function deployPages(): Promise<void> {
const pagesDir = join(process.cwd(), 'content', 'pages');
const files = readdirSync(pagesDir).filter(f => f.endsWith('.json'));
console.log(`Deploye ${files.length} Seiten...`);
for (const file of files) {
const content: PageContent = JSON.parse(
readFileSync(join(pagesDir, file), 'utf-8')
);
const existing = await client.pages.list(siteId, { status: 'published' });
const existingPage = existing.data.find(p => p.slug === content.slug);
if (existingPage) {
await client.pages.update(siteId, existingPage.id, {
title: content.title,
blocks: content.blocks,
seo: content.seo,
});
console.log(` ✓ Aktualisiert: ${content.title} (${content.slug})`);
} else {
await client.pages.create(siteId, {
title: content.title,
slug: content.slug,
status: 'published',
blocks: content.blocks,
seo: content.seo,
});
console.log(` ✓ Erstellt: ${content.title} (${content.slug})`);
}
}
}
async function main(): Promise<void> {
console.log('🚀 OptimoCMS Deploy gestartet\n');
await deployPages();
const result = await client.sites.publish(siteId);
console.log(`\n✓ Site veröffentlicht (${result.status})`);
}
main().catch(error => {
console.error('Deploy fehlgeschlagen:', error.message);
process.exit(1);
});Schritt 4 — GitHub Actions Workflow
Erstelle .github/workflows/deploy-content.yml:
name: Deploy Content to OptimoCMS
on:
push:
branches: [main]
paths:
- 'content/**'
workflow_dispatch:
jobs:
deploy-production:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- name: Deploy to Production
env:
OPTIMOCMS_API_KEY: ${{ secrets.OPTIMOCMS_API_KEY }}
OPTIMOCMS_SITE_ID: ${{ secrets.OPTIMOCMS_SITE_ID }}
run: npx tsx scripts/deploy.tsSchritt 5 — Staging → Produktion Flow
Verwende einen PR-basierten Workflow mit Sandbox-Preview:
name: Preview on PR
on:
pull_request:
paths:
- 'content/**'
jobs:
preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- name: Deploy to Sandbox
env:
OPTIMOCMS_API_KEY: ${{ secrets.OPTIMOCMS_SANDBOX_KEY }}
OPTIMOCMS_SITE_ID: ${{ secrets.OPTIMOCMS_SANDBOX_SITE_ID }}
run: npx tsx scripts/deploy.tsWorkflow-Übersicht
Feature Branch PR Main Branch
│ │ │
│ push content/ │ │
├─────────────────►│ deploy to sandbox │
│ ├───────────────────► │
│ │ Preview-Link in PR │
│ │ │
│ │ merge PR │
│ ├───────────────────────►│
│ │ │ deploy to production
│ │ ├───────────────────►Nächste Schritte
- Multi-Site-Automatisierung — Dieselbe Pipeline für mehrere Sites
- Webhook Sync — Benachrichtigungen bei Veröffentlichung erhalten
- SDK Error Handling — Robuste Fehlerbehandlung in CI
Webhook-Sync mit CRM
Halte dein CRM automatisch mit OptimoCMS über Webhooks synchron. Lerne, wie du Webhooks einrichtest, Payloads verarbeitest und Signaturen verifizierst.
Import aus Lovable
Migriere dein Lovable-Projekt zu OptimoCMS. Importiere Inhalte, Bilder und Design Tokens unter Beibehaltung deines Designs.