Version Management
This document describes how version strings are managed across the adblock-compiler project to ensure consistency and prevent version drift.
Single Source of Truth
src/version.ts is the canonical source for the package version.
export const VERSION = '0.12.0';
Version Synchronization
All version strings flow from src/version.ts:
1. Package Metadata
src/version.ts is the only writable version file. All other files are synced
from it automatically by the scripts/sync-version.ts script:
# After editing src/version.ts, propagate to all other files:
deno task version:sync
The following files are read-only (do not edit their version strings directly):
deno.json- Synced byversion:sync(required for JSR publishing)package.json- Synced byversion:sync(required for npm compatibility)package-lock.json- not modified byversion:sync; it is updated automatically by npm whennpm installis run afterpackage.jsonhas been syncedwrangler.toml- Synced byversion:sync(COMPILER_VERSION env var)
2. Worker Code (Automatic)
Worker code imports and uses VERSION as a fallback:
worker/worker.ts- Imports VERSION, usesenv.COMPILER_VERSION || VERSIONworker/router.ts- Imports VERSION, usesenv.COMPILER_VERSION || VERSIONworker/websocket.ts- Imports VERSION, usesenv.COMPILER_VERSION || VERSION
This ensures that even if COMPILER_VERSION is not set in the environment, the worker will use the correct version from src/version.ts.
3. Web UI (Dynamic Loading)
HTML files load version dynamically from the API at runtime:
public/index.html- Calls/api/versionendpoint vialoadVersion()public/compiler.html- Calls/api/versionand/apiendpoints viafetchCompilerVersion()
Fallback HTML values are provided for offline/error scenarios but are always overridden by the API response.
4. Tests
Test files import VERSION for consistency:
worker/queue.integration.test.ts- UsesVERSION + '-test'
Version Update Process
Automatic (Recommended)
The project uses automatic version bumping based on Conventional Commits:
- Automatic: Version is bumped automatically when you merge PRs with proper commit messages
- No manual editing: Version files are updated automatically
- Changelog generation: CHANGELOG.md is updated automatically
- Release creation: GitHub releases are created automatically
See AUTO_VERSION_BUMP.md for complete details.
Quick Guide:
# Minor bump (new feature)
git commit -m "feat: add new transformation"
# Patch bump (bug fix)
git commit -m "fix: resolve parsing error"
# Major bump (breaking change)
git commit -m "feat!: change API interface"
Manual (Fallback)
If you need to manually bump the version:
- ✅ Update
src/version.ts- Change the VERSION constant (only writable source) - ✅ Run
deno task version:sync- Propagates todeno.json,package.json,wrangler.toml, and HTML fallback spans inpublic/index.htmlandpublic/compiler.html - ✅ Update
CHANGELOG.md- Document the changes - ✅ Commit with message:
chore: bump version to X.Y.Z [skip ci]
Or use the GitHub Actions workflow: Actions → Version Bump → Run workflow
Architecture Benefits
Before (Version Drift Problem)
- Multiple hardcoded version strings scattered across the codebase
- Easy to forget updating some locations
- Version drift between components (e.g., 0.11.3, 0.11.4, 0.11.5, 0.12.0 all present)
After (Single Source of Truth)
- One canonical writable source:
src/version.ts - All other version files (
deno.json,package.json,wrangler.toml) are read-only – synced viadeno task version:sync - Worker imports and uses it automatically
- Web UI loads it dynamically from API
- CI/CD version-bump workflow updates only
src/version.tsthen runs the sync script
Version Flow Diagram
src/version.ts (VERSION = '0.12.0')
↓
├─→ worker/worker.ts (import VERSION)
│ └─→ API endpoints (/api, /api/version)
│ └─→ public/index.html (loadVersion())
│ └─→ public/compiler.html (fetchCompilerVersion())
│
├─→ worker/router.ts (import VERSION)
├─→ worker/websocket.ts (import VERSION)
└─→ worker/queue.integration.test.ts (import VERSION)
Implementation Details
Worker Fallback Pattern
All worker files use this pattern:
import { VERSION } from '../src/version.ts';
// Later in code:
version: env.COMPILER_VERSION || VERSION;
This ensures:
- Production uses
COMPILER_VERSIONfrom wrangler.toml - Local dev/tests use
VERSIONfrom src/version.ts if env var missing - No "unknown" versions
Dynamic Loading in HTML
Both HTML files fetch version at page load:
async function loadVersion() {
const response = await fetch('/api/version');
const result = await response.json();
const version = result.data?.version || result.version;
document.getElementById('version').textContent = version;
}
This ensures:
- Version always matches deployed worker
- No manual HTML updates needed
- Fallback version only shown on API failure
Troubleshooting
Version shows as "unknown"
- Check that
COMPILER_VERSIONis set in wrangler.toml - Verify worker files import VERSION from src/version.ts
- Ensure fallback pattern
env.COMPILER_VERSION || VERSIONis used
Version shows old value in UI
- Check browser cache - hard refresh (Ctrl+F5)
- Verify API endpoint
/api/versionreturns correct version - Check that JavaScript
loadVersion()function is being called
Versions out of sync
- Check
src/version.tsis the intended version - Run
deno task version:syncto propagate to all other files - Use grep to find any remaining hardcoded version strings:
grep -r "0\.11\." --include="*.ts" --include="*.html" --include="*.toml"
Related Files
src/version.ts- Primary version definitiondeno.json- Package versionpackage.json- Package versionwrangler.toml- Worker environment variablepublic/index.html- HTML fallback version span (auto-synced byversion:sync)public/compiler.html- HTML fallback version spans (auto-synced byversion:sync)CHANGELOG.md- Version history.github/copilot-instructions.md- Contains version sync instructions for AI assistance