Versioning & Upgrades
FORGE tracks the version used to generate your project. When a new FORGE release adds features, fixes bugs, or improves generated code, the upgrade system applies those changes to your existing project without overwriting your custom work.
Two Separate Versions
There are two distinct version numbers to be aware of:
┌─────────────────────────────────────────────────────┐
│ 1. FORGE CLI Version │
│ The tool installed on your machine │
│ Example: forge v2.1.0 │
│ │
│ 2. Project FORGE Version │
│ The version that generated/last upgraded │
│ your project. Stored in forge.yaml │
│ and forge.lock │
└─────────────────────────────────────────────────────┘These versions can differ. You might have FORGE CLI v2.1.0 installed, but your project might have been created with v2.0.0. The upgrade system bridges this gap.
Version Tracking
forge.yaml
The project configuration stores the FORGE version:
# forge.yaml
name: myapp
forge_version: 2.0.0
backend: rust
frontend: nextjs
# ...forge.lock
The lock file contains detailed version and integrity information:
# forge.lock
forge_version: 2.0.0
created_at: 2026-01-20T10:00:00Z
last_upgraded: 2026-01-20T10:00:00Z
templates:
base: 2.0.0
crm: 1.0.0 # if CRM module installed
checksums:
migrations: sha256:abc123...
seeders: sha256:def456...
files:
"apps/api/src/routes/mod.rs":
type: managed
checksum: sha256:def456
"apps/web/src/app/layout.tsx":
type: template
original_checksum: sha256:ghi789
current_checksum: sha256:ghi789TIP
Always commit forge.lock to version control. This ensures every team member works with the same FORGE version context, and upgrades can be applied consistently.
Semantic Versioning
FORGE follows Semantic Versioning:
MAJOR.MINOR.PATCH
│ │ │
│ │ └── Bug fixes, no breaking changes
│ └──────── New features, backwards compatible
└────────────── Breaking changes, requires migrationWhat Constitutes a Breaking Change
| Change Type | Breaking? | Example |
|---|---|---|
| New CLI command | No | Adding forge deploy:k8s |
| New API endpoint | No | Adding GET /api/v1/stats |
| Change API response format | Yes | Changing { user: {...} } to { data: {...} } |
| Change database column name | Yes | Renaming users.name to users.full_name |
| Remove CLI command | Yes | Removing a deprecated command |
| Change default behavior | Yes | Changing default auth from email to mobile |
Checking for Upgrades
Before upgrading, check what has changed:
forge upgrade:checkOutput:
Current project version: 2.0.0
Latest FORGE version: 2.1.0
Upgrade type: minor
Changes in 2.1.0:
+ Added RTL language support
+ Added API key rate limiting
+ Improved audit logging
+ 1 new migration
No breaking changes.
Run `forge upgrade:apply` to apply.WARNING
Always read the changelog before upgrading. For major version upgrades, review the BREAKING_CHANGES.md document carefully and plan the upgrade during a development window.
The Upgrade Process
Running forge upgrade:apply follows a structured six-step process:
┌─────────────────────────────────────────────────┐
│ 1. VERSION CHECK │
│ Read forge.lock → compare with latest │
│ Determine upgrade type (major/minor/patch) │
├─────────────────────────────────────────────────┤
│ 2. COMPATIBILITY CHECK │
│ Verify custom code doesn't conflict │
│ Check template and module compatibility │
├─────────────────────────────────────────────────┤
│ 3. BACKUP │
│ Backup forge.yaml, forge.lock │
│ Database backup (pg_dump) │
│ Create git commit or stash │
├─────────────────────────────────────────────────┤
│ 4. APPLY MIGRATIONS │
│ Run new database migrations │
│ Update forge.lock checksums │
├─────────────────────────────────────────────────┤
│ 5. UPDATE CODE │
│ Auto-update managed files │
│ Prompt for customized template files │
│ Add new files from the upgrade │
├─────────────────────────────────────────────────┤
│ 6. VERIFY │
│ Run tests (forge test) │
│ Run linting (forge lint) │
│ Health check (forge doctor) │
│ Update forge.lock with new version │
└─────────────────────────────────────────────────┘File Classification
FORGE classifies every generated file into one of three categories, which determines how it behaves during upgrades:
Core Files
Files that you own. FORGE never touches these after initial generation.
apps/api/src/services/*.rs # Your business logic
apps/web/src/components/custom/ # Your custom componentsFORGE tracks the original checksum but does not compare or update these files. You are free to modify them however you wish.
Managed Files
Files that FORGE owns. These are auto-updated during upgrades.
apps/api/src/routes/mod.rs # Route registration
apps/api/migrations/*.sql # Database migrations (immutable)Managed files include a header comment:
// FORGE MANAGED - DO NOT EDIT
// This file is auto-generated and will be overwritten during upgrades.WARNING
Do not manually edit managed files. Your changes will be overwritten on the next upgrade. If you need to customize routing or other managed concerns, use the extension points FORGE provides (e.g., custom route files that are imported by the managed router).
Template Files
Files that may need merging. FORGE generated them, but you might have customized them.
apps/web/src/app/layout.tsx # You might have added custom headers
apps/admin/src/components/Sidebar.tsx # You might have added menu items
docker-compose.yml # You might have added servicesFORGE tracks both the original checksum (when generated) and the current checksum. During an upgrade:
- If checksums match (you did not modify it): auto-update safely
- If checksums differ (you customized it): prompt for action
Handling Customized Files
When a template file was modified by you and the upgrade also needs to change it, FORGE presents an interactive prompt:
┌─────────────────────────────────────────────────────────────────┐
│ apps/web/src/app/layout.tsx │
├─────────────────────────────────────────────────────────────────┤
│ │
│ - import { Inter } from 'next/font/google' │
│ + import { Inter, Cairo } from 'next/font/google' // RTL font │
│ │
│ export default function RootLayout({ children }) { │
│ - return <html lang="en"> │
│ + return <html lang={locale} dir={direction}> │
│ │
│ Your changes: │
│ + Added custom header component on line 15 │
│ + Added analytics script on line 42 │
│ │
└─────────────────────────────────────────────────────────────────┘
What would you like to do?
[A] Accept new version (your changes will be lost)
[K] Keep your version (skip this upgrade change)
[M] Merge (open in editor for manual merge)
[D] Show full diff
[S] Skip for nowThis ensures you never lose custom work without explicit consent.
Upgrade Commands
forge upgrade:apply
The primary upgrade command:
# Upgrade to latest compatible version
forge upgrade:apply
# Upgrade to a specific version
forge upgrade:apply --version=2.1.0
# Preview changes without applying
forge upgrade:apply --dry-run
# Skip creating a backup
forge upgrade:apply --no-backupforge upgrade:check
Check for available upgrades without making changes:
forge upgrade:checkforge upgrade:rollback
Undo the last upgrade:
# Rollback to the previous version
forge upgrade:rollback
# Rollback to a specific version
forge upgrade:rollback --version=2.0.0The rollback process:
- Restores
forge.yamlandforge.lockfrom backup - Rolls back database migrations added by the upgrade
- Reverts code changes using the git history
- Verifies the application still passes tests
forge upgrade:history
View the upgrade history for the project:
forge upgrade:historyOutput:
Upgrade History for myapp
─────────────────────────
Version Date Type Status
─────── ────────────────── ────── ──────
2.0.0 2026-01-15 10:00 initial success
2.0.1 2026-01-18 14:30 patch success
2.1.0 2026-01-22 09:15 minor successforge doctor
Verify project health after an upgrade:
forge doctorOutput:
FORGE Doctor - Project Health Check
✓ forge.yaml valid
✓ forge.lock integrity verified
✓ All migrations applied
✓ Backend compiles (cargo check)
✓ Frontend builds (npm run build)
✓ API contract satisfied
✓ Required pages present
✓ Permissions seeded correctly
All checks passed. Project is healthy.Minor Upgrade Example
A typical minor version upgrade (no breaking changes):
$ forge upgrade:apply
Checking for updates...
Current: 2.0.0
Latest: 2.1.0 (minor)
Changes in 2.1.0:
+ Added RTL language support
+ Added API key rate limiting
+ Improved audit logging
+ 1 new migration
No breaking changes.
Proceed with upgrade? [Y/n] Y
Creating backup... ✓
Running migrations... ✓
Updating managed files... ✓
Updating forge.lock... ✓
Successfully upgraded to 2.1.0
Run `forge test` to verify everything works.Major Upgrade Example
A major version upgrade with breaking changes requires more care:
$ forge upgrade:apply --version=3.0.0
MAJOR VERSION UPGRADE
This upgrade includes BREAKING CHANGES:
- API response format changed
- Permission format changed (users.view → user:read)
- Removed deprecated forge:ssl command
Required manual actions after upgrade:
1. Update frontend API calls to new response format
2. Run permission migration script
3. Update any scripts using forge:ssl
Read full changelog: https://forge.dev/changelog/3.0.0
Proceed? [y/N] y
Creating backup... ✓
Running pre-upgrade checks... ✓
Step 1/5: Migrate database schema
Running 5 migrations... ✓
Step 2/5: Update API handlers
12 files updated ✓
Step 3/5: Migrate permissions
Converting 24 permissions... ✓
Step 4/5: Update frontend
3 files need manual merge
Step 5/5: Verify
Running tests... ✓
Running lints... ✓
Upgrade to 3.0.0 complete!
Manual steps remaining:
- Review and merge 3 conflicted files
- Update custom API integrations (see migration guide)Best Practices
| Practice | Reason |
|---|---|
| Always back up first | Use forge upgrade:apply (creates backup by default) or commit to git before upgrading |
| Upgrade staging first | Test the upgrade on a staging environment before production |
| Read the changelog | forge upgrade:check shows what changed -- read it |
| Upgrade incrementally | Go 2.0 to 2.1 to 2.2 to 3.0, not 2.0 to 3.0 directly |
| Commit forge.lock | Keep it in version control so the whole team stays in sync |
| Run tests after upgrade | forge test && forge lint catches regressions |
| Avoid editing managed files | Files marked FORGE MANAGED will be overwritten |
Run forge doctor | Post-upgrade health check catches issues early |
TIP
The safest upgrade workflow: commit all changes to git, run forge upgrade:apply, run forge test, and if anything fails, use git reset to return to the pre-upgrade state. This gives you a clean rollback path independent of FORGE's built-in rollback mechanism.