s:CMS Update & Deployment System

Overview

s:CMS uses a core/usr separation architecture that allows you to:

  • βœ… Receive framework updates without losing customizations
  • πŸ›‘οΈ Keep your content and configurations protected
  • πŸš€ Deploy to any platform (GitHub Pages, Netlify, Vercel, etc.)

Quick Commands

Terminal window
# One-time setup (after creating from template)
npm run setup-upstream
# Update to latest s:CMS version
npm run update-core
# Deploy
git push # Auto-deploys via GitHub Actions

File Structure

s:CMS/
β”œβ”€β”€ core/ # ❌ Framework code (receives updates)
β”‚ β”œβ”€β”€ components/ # React & Astro components
β”‚ β”œβ”€β”€ layouts/ # Base layouts
β”‚ └── utils/ # Framework utilities
β”‚
β”œβ”€β”€ usr/ # βœ… Your code (always protected)
β”‚ β”œβ”€β”€ content/ # Your content (MDX, blog posts)
β”‚ β”œβ”€β”€ pages/ # Your pages
β”‚ β”œβ”€β”€ components/ # Your custom components
β”‚ β”œβ”€β”€ layouts/ # Your custom layouts
β”‚ β”œβ”€β”€ public/ # Your static assets
β”‚ └── user.config.mjs # Your site configuration
β”‚
β”œβ”€β”€ scripts/ # Update automation scripts
β”‚ β”œβ”€β”€ setup-upstream.sh
β”‚ └── update-core.sh
β”‚
β”œβ”€β”€ docs/
β”‚ β”œβ”€β”€ UPDATING.md # Detailed update guide
β”‚ └── DEPLOYMENT.md # Deployment instructions
β”‚
└── .gitattributes # Protects usr/ during merges

How It Works

1. Protected Folders

.gitattributes tells git to preserve usr/** during merges:

usr/** merge=ours

2. Update Script

npm run update-core automates:

  1. Creates backup branch
  2. Fetches latest s:CMS release
  3. Merges with usr/ protection
  4. Installs new dependencies
  5. Shows what changed

3. Merged Configs

astro.config.mjs combines core + user settings:

import coreConfig from './core/core.config.mjs'
import userConfig from './usr/user.config.mjs'
export default merge(coreConfig, userConfig)

Update Workflow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 1. Run: npm run update-core β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 2. Script creates backup branch β”‚
β”‚ backup-before-update-TIMESTAMP β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 3. Fetches latest from upstream β”‚
β”‚ github.com/lad-sapienza/sCMS β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 4. Shows preview of changes β”‚
β”‚ You confirm to proceed β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 5. Merges updates β”‚
β”‚ β€’ core/ updated β”‚
β”‚ β€’ usr/ protected β”‚
β”‚ β€’ configs merged β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 6. Installs new dependencies β”‚
β”‚ npm install (if package.json changed)β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 7. Test: npm run dev β”‚
β”‚ If OK: delete backup branch β”‚
β”‚ If issues: git reset --hard backup β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Deployment Options

GitHub Pages (Included)

  • βœ… Workflow already configured: .github/workflows/deploy.yml
  • βœ… Push to main β†’ automatic deployment
  • Set repo to public or GitHub Pro for private repos

Other Platforms

  • Netlify: Build command npm run build, Publish dir dist
  • Vercel: Auto-detects Astro, just connect repo
  • Cloudflare Pages: Same as Netlify
  • Traditional hosting: Upload dist/ folder after npm run build

Configuration

Site URL

Edit usr/user.config.mjs:

export const siteMetadata = {
siteUrl: 'https://yourdomain.com',
title: 'Your Site Title',
// ... other settings
}

Astro Settings

Edit usr/user.config.mjs:

export const userConfig = {
integrations: [
// Your custom integrations
],
// Other Astro config overrides
}

Handling Merge Conflicts

If package.json conflicts occur:

  1. Keep your dependencies
  2. Add new framework dependencies
  3. Update shared dependencies to newer versions

Example merge:

// Your version + upstream version = merged result
{
"dependencies": {
"astro": "^5.1.0", // Updated version
"my-package": "^1.0.0", // Your addition
"photoswipe": "^5.4.4" // New framework dep
}
}

Best Practices

  1. βœ… Never edit core/ - Framework receives updates
  2. βœ… Customize in usr/ - Always protected
  3. βœ… Update regularly - Easier than large jumps
  4. βœ… Test after updating - Run npm run dev
  5. βœ… Read changelogs - Know what’s changing

For More Details

Support