AgentSkillsCN

Release Preflight Skill

事前检查、版本一致性与严谨的部署流程。

SKILL.md
--- frontmatter
name: "Release Preflight Skill"
description: "Pre-checks, version consistency, and deployment discipline."
applyTo: "**/*release*,**/*publish*,**/*deploy*,**/*version*,**/package.json,**/CHANGELOG*"

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)

LocationFieldExample
package.jsonversion"3.7.0"
CHANGELOG.mdLatest heading## [3.7.0] - 2026-01-30
README badge (if any)Version badgev3.7.0
Git tagTag namev3.7.0

Preflight Checklist

Run BEFORE every release:

powershell
# 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

powershell
# 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)

powershell
# 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

MistakePrevention
Published without version bumpRun preflight checklist
CHANGELOG not updatedInclude in version bump workflow
Forgot to push tagsgit push --tags in workflow
Published broken buildnpm run compile in preflight
Version mismatch between filesSingle source of truth (package.json), derive others

Platform-Specific Versioning

VS Code Marketplace Requirements

RequirementRule
FormatSemVer (major.minor.patch)
Pre-releaseAdd --pre-release flag, NOT version suffix
Version collisionMUST increment; can't overwrite
Engine compatibilityengines.vscode must match target
powershell
# Pre-release (same version number, flag-based)
vsce publish --pre-release

# Stable release
vsce publish

M365 Developer Portal Requirements

RequirementRule
FormatSemVer in manifest.json
App IDGUID, immutable after creation
ValidationMust pass teamsapp validate
SubmissionManual upload to Developer Portal
UpdatesNew package upload, same App ID
json
// appPackage/manifest.json
{
  "version": "4.0.0",
  "id": "{{APP_ID}}"
}

Version Independence

Heirs can version independently from Master Alex:

ComponentCurrentNotes
Master Alex3.x.xArchitecture version
VS Code Extension3.x.xAligned with Master
M365 Agent4.x.xCan diverge (different maturity)

M365 Agent Deployment

powershell
# 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:

powershell
# 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)

powershell
# 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

powershell
# 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:

text
┌─────────┐   ┌─────────┐   ┌─────────┐   ┌─────────┐   ┌─────────┐
│ 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

powershell
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

powershell
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

powershell
function Test-Tests {
    npm test 2>&1 | Out-Null
    if ($LASTEXITCODE -ne 0) { throw "Tests failed" }
    Write-Host "✅ Tests passed"
}

Gate 4: Package Creation

powershell
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

text
package.json  ←─── THE SOURCE
     │
     ├──→ CHANGELOG.md (derived)
     ├──→ Git tag (derived)
     └──→ README badge (derived)

Automated Sync Script

powershell
# 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.