Upgrading Neuron CMS

Overview

Neuron CMS follows a structured upgrade process that ensures safe transitions between versions while preserving user customizations and data integrity. The upgrade system automatically handles migration file distribution, configuration updates, and version tracking.

Upgrade Philosophy

CRITICAL PRINCIPLE: Never modify existing migration files. The CMS upgrade system is designed around this constraint:

This approach ensures:

Version Tracking

The CMS uses two manifest files to track versions and migrations:

Package Manifest

Located at vendor/neuron-php/cms/resources/.cms-manifest.json

Contains:

Installation Manifest

Located at .cms-manifest.json (project root)

Contains:

Pre-Upgrade Checklist

Before upgrading, complete these essential steps:

1. Backup Database

SQLite:

# Create timestamped backup
cp storage/database.sqlite3 storage/backups/database-$(date +%Y%m%d-%H%M%S).sqlite3

MySQL:

# Dump database with compression
mysqldump -u cms_user -p cms_database | gzip > backups/cms-$(date +%Y%m%d-%H%M%S).sql.gz

PostgreSQL:

# Dump database with compression
pg_dump -U cms_user cms_database | gzip > backups/cms-$(date +%Y%m%d-%H%M%S).sql.gz

2. Review Changelog

Check the version-specific upgrade notes:

# View upgrade notes in package
cat vendor/neuron-php/cms/UPGRADE_NOTES.md

# Or view online
# https://github.com/neuron-php/cms/blob/main/UPGRADE_NOTES.md

3. Review Breaking Changes

Pay special attention to:

4. Test in Staging Environment

NEVER upgrade production directly. Always:

  1. Clone production environment to staging
  2. Restore production database to staging
  3. Perform upgrade on staging
  4. Test all critical functionality
  5. Document any issues or required changes
  6. Only then upgrade production

5. Enable Maintenance Mode

./vendor/bin/neuron cms:maintenance:enable "System upgrade in progress. We'll be back shortly."

Upgrade Workflow

Step 1: Update Package via Composer

# Update to latest version
composer update neuron-php/cms

# Or update to specific version
composer require neuron-php/cms:^0.9.0

Composer will display a post-install reminder:

neuron-php/cms upgraded from 0.8.5 to 0.9.0

IMPORTANT: Run the upgrade command to complete the update:
  php neuron cms:upgrade

This will:
- Copy new migration files to your project
- Update configuration examples
- Display version-specific upgrade notes

Step 2: Run Upgrade Command

The cms:upgrade command orchestrates the upgrade process:

php neuron cms:upgrade

What it does:

  1. Version Detection

    • Compares installed version (from .cms-manifest.json)
    • With package version (from vendor/neuron-php/cms/resources/.cms-manifest.json)
    • Determines if upgrade is needed
  2. Migration Discovery

    • Scans package migrations directory
    • Compares with installation manifest
    • Identifies new migrations to copy
  3. File Distribution

    • Copies new migration files to db/migrate/
    • Updates configuration examples (.example files)
    • Preserves user customizations
  4. Manifest Update

    • Updates .cms-manifest.json with new version
    • Records newly copied migrations
    • Timestamps the upgrade
  5. Upgrade Notes Display

    • Shows version-specific changes
    • Highlights breaking changes
    • Provides manual action items

Example Output:

Neuron CMS Upgrade Utility
===========================

Current version: 0.8.5
Package version: 0.9.0

Upgrade available: 0.8.5 → 0.9.0

Checking for new migrations...
✓ Found 3 new migration files

Copying migrations:
  ✓ 20250205000000_add_timezone_to_users.php
  ✓ 20250206000000_create_pages_table.php
  ✓ 20250207000000_add_shortcode_to_pages.php

Updating configuration examples...
  ✓ config/neuron.yaml.example
  ✓ config/auth.yaml.example

Upgrade completed successfully!

=== UPGRADE NOTES FOR 0.9.0 ===

NEW FEATURES:
  • Static pages support with Editor.js integration
  • WordPress-style shortcode system
  • User timezone support

BREAKING CHANGES:
  • config/neuron.yaml: New 'timezone' configuration required
  • Routes: /page/:slug route added (may conflict with custom routes)

REQUIRED ACTIONS:
  1. Run migrations: php neuron db:migrate
  2. Update config/neuron.yaml with timezone settings
  3. Review routes.yaml for conflicts with /page/:slug

Next steps:
  1. Review changes above
  2. Run: php neuron db:migrate
  3. Test your application
  4. Run: php neuron cms:maintenance:disable

Step 3: Review Changes

Examine what was modified:

# View new migration files
ls -lt db/migrate/ | head -10

# Check configuration examples
diff config/neuron.yaml config/neuron.yaml.example

# Review upgrade notes
cat vendor/neuron-php/cms/UPGRADE_NOTES.md

Step 4: Apply Database Migrations

# Preview migrations (dry run)
./vendor/bin/neuron db:migrate --dry-run

# Apply migrations
./vendor/bin/neuron db:migrate

IMPORTANT: Always run migrations after upgrade. New features often require schema changes.

Step 5: Update Configuration

Apply any required configuration changes noted in upgrade output:

# Edit main configuration
nano config/neuron.yaml

# Edit authentication configuration
nano config/auth.yaml

Refer to .example files for new configuration options.

Step 6: Clear Cache

# Clear application cache
./vendor/bin/neuron cache:clear

# Clear OPcache if enabled
sudo systemctl reload php-fpm

Step 7: Test Application

Verify critical functionality:

  1. Authentication: Login/logout works
  2. Admin Panel: Dashboard accessible
  3. Content: Create/edit posts
  4. Database: Migrations applied correctly
  5. Email: Test email functionality
  6. Custom Code: Test any customizations

Step 8: Disable Maintenance Mode

./vendor/bin/neuron cms:maintenance:disable

Upgrade Command Options

Check for Updates

Preview available updates without applying:

php neuron cms:upgrade --check

Output:

Current version: 0.8.5
Latest version: 0.9.0

Update available: 0.8.5 → 0.9.0

New migrations available: 3
Configuration updates: 2

Run 'php neuron cms:upgrade' to apply updates.

Migrations Only

Copy only new migration files, skip everything else:

php neuron cms:upgrade --migrations-only

Use when:

Skip View Updates

Don't update view templates:

php neuron cms:upgrade --skip-views

Use when:

Run Migrations Automatically

Apply database migrations immediately after copying files:

php neuron cms:upgrade --run-migrations

WARNING: Use with caution. Always backup first and test in staging.

Combined Options

# Check for updates verbosely
php neuron cms:upgrade --check --verbose

# Copy migrations and run them
php neuron cms:upgrade --migrations-only --run-migrations

# Upgrade without touching views
php neuron cms:upgrade --skip-views

Rollback Procedure

If upgrade fails or causes issues:

1. Restore Database

SQLite:

# Disable maintenance mode if needed
./vendor/bin/neuron cms:maintenance:disable

# Restore backup
cp storage/backups/database-20250112-143000.sqlite3 storage/database.sqlite3

MySQL:

# Drop and recreate database
mysql -u cms_user -p -e "DROP DATABASE cms_database; CREATE DATABASE cms_database;"

# Restore from backup
gunzip < backups/cms-20250112-143000.sql.gz | mysql -u cms_user -p cms_database

PostgreSQL:

# Drop and recreate database
psql -U postgres -c "DROP DATABASE cms_database;"
psql -U postgres -c "CREATE DATABASE cms_database OWNER cms_user;"

# Restore from backup
gunzip < backups/cms-20250112-143000.sql.gz | psql -U cms_user cms_database

2. Rollback Composer Package

# Downgrade to previous version
composer require neuron-php/cms:0.8.5

# Restore autoloader
composer dump-autoload

3. Remove New Migrations

# Remove migrations added during upgrade
# (Check .cms-manifest.json for list)
rm db/migrate/20250205000000_add_timezone_to_users.php
rm db/migrate/20250206000000_create_pages_table.php
rm db/migrate/20250207000000_add_shortcode_to_pages.php

4. Restore Previous Manifest

# If you backed up .cms-manifest.json
cp .cms-manifest.json.backup .cms-manifest.json

5. Clear Cache and Test

./vendor/bin/neuron cache:clear

Access site and verify it's working.

Troubleshooting

"No upgrade needed"

Symptom:

php neuron cms:upgrade
No upgrade needed. Already at version 0.9.0

Cause: .cms-manifest.json already shows latest version

Solution:

# Check actual versions
cat .cms-manifest.json | grep version
composer show neuron-php/cms | grep versions

# If versions differ, manifest may be corrupt
# Backup and regenerate manifest
cp .cms-manifest.json .cms-manifest.json.backup
php neuron cms:upgrade --force  # (if available)

"Migration file already exists"

Symptom:

Error: Migration file 20250205000000_add_timezone_to_users.php already exists

Cause: Migration file exists but isn't tracked in manifest

Solution:

# Check if migration was run
./vendor/bin/neuron db:migrate:status | grep 20250205000000

# If not run, run it
./vendor/bin/neuron db:migrate

# If run, add to manifest manually
nano .cms-manifest.json
# Add to "migrations" array

"Configuration file conflicts"

Symptom: Upgrade wants to overwrite customized config files

Solution:

  1. Upgrade creates .example files, not actual config
  2. Manually merge changes from .example to actual config
  3. Use --skip-views if needed

"Composer update fails"

Symptom:

Your requirements could not be resolved to an installable set of packages.

Causes & Solutions:

Dependency conflict:

# Check what's conflicting
composer why-not neuron-php/cms 0.9.0

# Update dependencies
composer update

PHP version mismatch:

# Check PHP version
php -v

# Ensure it meets requirements (8.4+)
# Update PHP if needed

Memory limit:

# Increase memory temporarily
COMPOSER_MEMORY_LIMIT=-1 composer update neuron-php/cms

"Migrations fail to execute"

Symptom:

Migration failed: SQLSTATE[42S01]: Base table or view already exists

Solution:

# Check migration status
./vendor/bin/neuron db:migrate:status

# If table exists, mark migration as run without executing
./vendor/bin/neuron db:migrate --fake

"Installation manifest missing"

Symptom: .cms-manifest.json doesn't exist

Solution:

# Create basic manifest
cat > .cms-manifest.json << 'EOF'
{
  "version": "0.8.5",
  "installed_at": "2025-01-12T14:30:00Z",
  "migrations": []
}
EOF

# Run upgrade
php neuron cms:upgrade

"Views not updating"

Issue: View templates aren't being updated

Explanation: By design, upgrade doesn't overwrite views to preserve customizations

Solution:

# Manually copy updated views
cp -r vendor/neuron-php/cms/resources/views/* resources/views/

# Or use symbolic links for easier updates
rm -rf resources/views/admin
ln -s ../vendor/neuron-php/cms/resources/views/admin resources/views/admin

Version-Specific Upgrade Notes

Upgrading to 0.9.x from 0.8.x

Breaking Changes:

Required Actions:

  1. Add timezone configuration to config/neuron.yaml
  2. Review routes.yaml for /page/:slug conflicts
  3. Update any custom shortcode implementations

New Migrations:

Upgrading to 1.0.x from 0.9.x

Breaking Changes:

Best Practices

1. Always Use Staging

Never upgrade production without testing:

# On staging server
composer update neuron-php/cms
php neuron cms:upgrade
php neuron db:migrate
# Test thoroughly

2. Automate Backups

Create pre-upgrade backup script:

#!/bin/bash
# scripts/backup-before-upgrade.sh

DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_DIR="backups/$DATE"

mkdir -p "$BACKUP_DIR"

# Backup database
mysqldump -u cms_user -p cms_database | gzip > "$BACKUP_DIR/database.sql.gz"

# Backup files
cp .cms-manifest.json "$BACKUP_DIR/"
tar -czf "$BACKUP_DIR/config.tar.gz" config/

echo "Backup completed: $BACKUP_DIR"

Run before upgrade:

./scripts/backup-before-upgrade.sh
composer update neuron-php/cms
php neuron cms:upgrade

3. Track Customizations

Document all customizations in a CUSTOMIZATIONS.md file:

# CMS Customizations

## Views
- `resources/views/layouts/main.php`: Added custom header
- `resources/views/admin/dashboard.php`: Custom widgets

## Configuration
- `config/neuron.yaml`: Custom cache settings
- `config/routes.yaml`: Added /api/* routes

## Controllers
- `app/Controllers/CustomDashboard.php`: Custom admin dashboard

Review this file before upgrade to know what to preserve.

4. Use Version Control

# Commit before upgrade
git add .
git commit -m "Pre-upgrade checkpoint: CMS 0.8.5"

# Perform upgrade
composer update neuron-php/cms
php neuron cms:upgrade
php neuron db:migrate

# Review changes
git diff

# Commit upgrade
git add .
git commit -m "Upgrade CMS to 0.9.0"

5. Monitor After Upgrade

Check logs for issues:

# Watch application log
tail -f storage/logs/app.log

# Check for errors
grep "ERROR" storage/logs/app.log

# Monitor web server logs
tail -f /var/log/nginx/error.log

Automated Upgrade Script

For production deployments, create an automated upgrade script:

#!/bin/bash
# scripts/upgrade-cms.sh

set -e  # Exit on error

echo "=== Neuron CMS Upgrade Script ==="

# 1. Backup
echo "Creating backup..."
DATE=$(date +%Y%m%d-%H%M%S)
./scripts/backup-before-upgrade.sh

# 2. Enable maintenance mode
echo "Enabling maintenance mode..."
./vendor/bin/neuron cms:maintenance:enable "Upgrade in progress"

# 3. Update package
echo "Updating CMS package..."
composer update neuron-php/cms --no-dev

# 4. Run upgrade
echo "Running upgrade command..."
php neuron cms:upgrade

# 5. Apply migrations
echo "Applying database migrations..."
./vendor/bin/neuron db:migrate

# 6. Clear cache
echo "Clearing cache..."
./vendor/bin/neuron cache:clear

# 7. Disable maintenance mode
echo "Disabling maintenance mode..."
./vendor/bin/neuron cms:maintenance:disable

echo "=== Upgrade completed successfully! ==="
echo "Backup location: backups/$DATE"

Usage:

chmod +x scripts/upgrade-cms.sh
./scripts/upgrade-cms.sh

Related Documentation