Release Preflight Skill
Release Preflight Skill
Pre-checks, version consistency, and deployment discipline.
The Golden Rule
NEVER publish without running the preflight checklist.
Version Locations (Must Stay Synchronized)
| Location | Field | Example |
|---|---|---|
package.json |
version |
"3.7.0" |
CHANGELOG.md |
Latest heading | ## [3.7.0] - 2026-01-30 |
| README badge (if any) | Version badge | v3.7.0 |
| Git tag | Tag name | v3.7.0 |
Preflight Checklist
Run BEFORE every release:
# 1. Version check - are all locations synchronized?
$pkg = Get-Content package.json | ConvertFrom-Json
Write-Host "package.json version: $($pkg.version)"
$changelog = Get-Content CHANGELOG.md | Select-Object -First 20
Write-Host "CHANGELOG latest:`n$($changelog -join "`n")"
# 2. Build check - does it compile?
npm run compile
if ($LASTEXITCODE -ne 0) { throw "Build failed!" }
# 3. Lint check - any errors?
npm run lint
if ($LASTEXITCODE -ne 0) { throw "Lint failed!" }
# 4. Test check - do tests pass?
npm test
if ($LASTEXITCODE -ne 0) { throw "Tests failed!" }
# 5. Package check - does it package?
npx vsce package --no-dependencies
if ($LASTEXITCODE -ne 0) { throw "Package failed!" }
Write-Host "✅ Preflight complete - ready to publish"
Version Bump Workflow
# 1. Decide version type
$bumpType = "patch" # patch | minor | major
# 2. Bump package.json
npm version $bumpType --no-git-tag-version
# 3. Get new version
$newVersion = (Get-Content package.json | ConvertFrom-Json).version
# 4. Update CHANGELOG (add new section at top)
# ## [$newVersion] - $(Get-Date -Format 'yyyy-MM-dd')
# 5. Commit
git add -A
git commit -m "chore: bump version to $newVersion"
# 6. Tag
git tag "v$newVersion"
# 7. Push
git push && git push --tags
Publishing Workflow (VS Code Extension)
# Ensure PAT is set
if (-not $env:VSCE_PAT) {
$env:VSCE_PAT = (Get-Content .env | Select-String "VSCE_PAT").Line.Split("=",2)[1]
}
# Publish
vsce publish
# If version collision error:
# 1. npm version patch --no-git-tag-version
# 2. Update CHANGELOG
# 3. git commit + tag + push
# 4. Retry vsce publish
Common Mistakes We've Made
| Mistake | Prevention |
|---|---|
| Published without version bump | Run preflight checklist |
| CHANGELOG not updated | Include in version bump workflow |
| Forgot to push tags | git push --tags in workflow |
| Published broken build | npm run compile in preflight |
| Version mismatch between files | Single source of truth (package.json), derive others |
Platform-Specific Versioning
VS Code Marketplace Requirements
| Requirement | Rule |
|---|---|
| Format | SemVer (major.minor.patch) |
| Pre-release | Add --pre-release flag, NOT version suffix |
| Version collision | MUST increment; can't overwrite |
| Engine compatibility | engines.vscode must match target |
# Pre-release (same version number, flag-based)
vsce publish --pre-release
# Stable release
vsce publish
M365 Developer Portal Requirements
| Requirement | Rule |
|---|---|
| Format | SemVer in manifest.json |
| App ID | GUID, immutable after creation |
| Validation | Must pass teamsapp validate |
| Submission | Manual upload to Developer Portal |
| Updates | New package upload, same App ID |
// appPackage/manifest.json
{
"version": "4.0.0",
"id": "{{APP_ID}}"
}
Version Independence
Heirs can version independently from Master Alex:
| Component | Current | Notes |
|---|---|---|
| Master Alex | 3.x.x | Architecture version |
| VS Code Extension | 3.x.x | Aligned with Master |
| M365 Agent | 4.x.x | Can diverge (different maturity) |
M365 Agent Deployment
# Package
npx teamsapp package --env local
# Validate
npx teamsapp validate --package-file appPackage/build/*.zip
# Upload to Developer Portal manually
Rollback Plan
If a release is broken:
# 1. Unpublish (VS Code Marketplace)
vsce unpublish fabioc-aloha.alex-cognitive-architecture
# 2. Or publish previous version quickly
git checkout v3.6.0
vsce publish
# 3. Investigate and fix
git checkout main
# Fix the issue
# Go through full release workflow again
Automation Script Location
Create and maintain: scripts/release-preflight.ps1
Run with: .\scripts\release-preflight.ps1 -Package
Complete Release Scripts
Full Release Script (VS Code Extension)
# scripts/release-vscode.ps1
param(
[Parameter(Mandatory)][ValidateSet("patch","minor","major")][string]$BumpType,
[switch]$PreRelease,
[switch]$DryRun
)
$ErrorActionPreference = "Stop"
Push-Location (Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path))
Write-Host "`n🚀 Starting VS Code Extension Release" -ForegroundColor Cyan
# 1. Run preflight
Write-Host "`n📋 Running preflight checks..." -ForegroundColor Yellow
.\scripts\release-preflight.ps1 -Package
if ($LASTEXITCODE -ne 0) { throw "Preflight failed!" }
# 2. Bump version
Write-Host "`n📈 Bumping version ($BumpType)..." -ForegroundColor Yellow
npm version $BumpType --no-git-tag-version
$newVersion = (Get-Content package.json | ConvertFrom-Json).version
Write-Host " New version: $newVersion" -ForegroundColor Green
# 3. Update CHANGELOG
Write-Host "`n📝 Updating CHANGELOG..." -ForegroundColor Yellow
$date = Get-Date -Format "yyyy-MM-dd"
$changelog = Get-Content CHANGELOG.md -Raw
$newEntry = "## [$newVersion] - $date`n`n### Added`n`n### Changed`n`n### Fixed`n`n"
$changelog = $changelog -replace '(# Changelog\s*\n)', "`$1`n$newEntry"
Set-Content CHANGELOG.md $changelog
Write-Host " Added entry for $newVersion" -ForegroundColor Green
if ($DryRun) {
Write-Host "`n⚠️ DRY RUN - Stopping before commit" -ForegroundColor Yellow
Pop-Location
exit 0
}
# 4. Commit and tag
Write-Host "`n📦 Committing and tagging..." -ForegroundColor Yellow
git add -A
git commit -m "chore: release v$newVersion"
git tag "v$newVersion"
Write-Host " Tagged: v$newVersion" -ForegroundColor Green
# 5. Push
Write-Host "`n⬆️ Pushing to remote..." -ForegroundColor Yellow
git push
git push --tags
# 6. Publish
Write-Host "`n🎯 Publishing to marketplace..." -ForegroundColor Yellow
if (-not $env:VSCE_PAT) {
$envFile = ".env"
if (Test-Path $envFile) {
$env:VSCE_PAT = (Get-Content $envFile | Select-String "VSCE_PAT").Line.Split("=",2)[1]
} else {
throw "VSCE_PAT not set and .env not found"
}
}
if ($PreRelease) {
vsce publish --pre-release
} else {
vsce publish
}
Write-Host "`n✅ Release v$newVersion complete!" -ForegroundColor Green
Pop-Location
M365 Agent Release Script
# scripts/release-m365.ps1
param([switch]$Validate)
$ErrorActionPreference = "Stop"
Push-Location "platforms/m365-copilot"
Write-Host "`n🚀 M365 Copilot Agent Release" -ForegroundColor Cyan
# 1. Package
Write-Host "`n📦 Packaging agent..." -ForegroundColor Yellow
npx teamsapp package --env local
# 2. Validate
Write-Host "`n✅ Validating package..." -ForegroundColor Yellow
$pkg = Get-ChildItem "appPackage/build/*.zip" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
npx teamsapp validate --package-file $pkg.FullName
if ($Validate) {
Write-Host "`n⚠️ Validation only - stopping here" -ForegroundColor Yellow
Pop-Location
exit 0
}
Write-Host "`n📋 Next steps:" -ForegroundColor Cyan
Write-Host " 1. Go to https://dev.teams.microsoft.com/apps" -ForegroundColor Gray
Write-Host " 2. Upload package: $($pkg.Name)" -ForegroundColor Gray
Write-Host " 3. Test in Teams/M365 Copilot" -ForegroundColor Gray
Write-Host " 4. Submit for approval if ready" -ForegroundColor Gray
Pop-Location
Pre-Check Methodology
The 5-Gate Model
Every release must pass through 5 gates:
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ GATE 1 │ → │ GATE 2 │ → │ GATE 3 │ → │ GATE 4 │ → │ GATE 5 │
│ Version │ │ Build │ │ Test │ │ Package │ │ Human │
│ Sync │ │ Check │ │ Check │ │ Check │ │ Review │
└─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
↓ ↓ ↓ ↓ ↓
Automatic Automatic Automatic Automatic Manual
Gate 1: Version Synchronization
function Test-VersionSync {
$pkg = (Get-Content package.json | ConvertFrom-Json).version
$changelog = (Select-String -Path CHANGELOG.md -Pattern '\[(\d+\.\d+\.\d+)\]' |
Select-Object -First 1).Matches.Groups[1].Value
if ($pkg -ne $changelog) {
throw "Version mismatch: package.json ($pkg) != CHANGELOG ($changelog)"
}
Write-Host "✅ Versions synchronized: $pkg"
}
Gate 2: Build Verification
function Test-Build {
npm run compile 2>&1 | Out-Null
if ($LASTEXITCODE -ne 0) { throw "Build failed" }
Write-Host "✅ Build successful"
}
Gate 3: Test Execution
function Test-Tests {
npm test 2>&1 | Out-Null
if ($LASTEXITCODE -ne 0) { throw "Tests failed" }
Write-Host "✅ Tests passed"
}
Gate 4: Package Creation
function Test-Package {
npx vsce package --no-dependencies 2>&1 | Out-Null
if ($LASTEXITCODE -ne 0) { throw "Package failed" }
Write-Host "✅ Package created"
}
Gate 5: Human Review
- CHANGELOG has meaningful entries
- README is current
- No debug code left in
- No secrets in codebase
- Breaking changes documented
Version Rationalization
Single Source of Truth
package.json ←─── THE SOURCE
│
├──→ CHANGELOG.md (derived)
├──→ Git tag (derived)
└──→ README badge (derived)
Automated Sync Script
# scripts/sync-versions.ps1
$version = (Get-Content package.json | ConvertFrom-Json).version
# Check CHANGELOG has this version
if (-not (Select-String -Path CHANGELOG.md -Pattern "\[$version\]" -Quiet)) {
Write-Host "⚠️ CHANGELOG missing entry for $version" -ForegroundColor Yellow
}
# Check git tag exists
$tag = git tag -l "v$version"
if (-not $tag) {
Write-Host "⚠️ Git tag v$version not found" -ForegroundColor Yellow
}
Write-Host "Version: $version"
Synapses
See synapses.json for connections.
More from fabioc-aloha/windowswidget
prompt engineering skill
Craft effective prompts that get the best results from language models.
3text-to-speech
Alex's voice synthesis capability for reading documents aloud
1socratic questioning skill
Help users discover answers, don't just deliver them.
1academic research skill
Patterns for thesis writing, dissertations, research papers, literature reviews, and scholarly work.
1work-life balance skill
Detect burnout signals and proactively support sustainable productivity.
1grant writing skill
Translate research vision into funded reality.
1