Skip to content

Conversation

@hassoncs
Copy link
Contributor

@hassoncs hassoncs commented Nov 5, 2025

This is a proposal after today's scramble to publish a working version of the extension:
https://kilo-code.slack.com/archives/C090U1NLQUC/p1762375603554519

When we publish a broken extension, we have no fast recovery path. Our changeset-based release process requires reverting PRs, code reviews, and manual version coordination—all while users are experiencing issues in production.

The pain: Emergency rollbacks require:

  1. Reverting multiple PRs
  2. Creating changeset PRs
  3. Manual version number calculations
  4. Code reviews during an emergency

Added one-click automatic rollback to the marketplace publish workflow. Just provide the git tag of a working version, and the system handles everything else.

Normal publish (unchanged):

Actions → Publish Extension → Run workflow
→ Leave rollback field empty

Emergency rollback:

Actions → Publish Extension → Run workflow
→ rollback_source_version: v4.115.0

That's it! The system automatically:

  1. Calculates next version (e.g., 4.116.2-fix)
  2. Updates package.json
  3. Checks out old code from tag
  4. Builds and publishes
$ node scripts/set-rollback-version.js v4.115.0

Current version on main: 4.116.1
Rolling back from source: v4.115.0
Calculated rollback version: 4.116.2-fix

SemVer ordering:
  4.116.1 < 4.116.2-fix < 4.116.2

✅ Updated src/package.json to version 4.116.2-fix

Modified: .github/workflows/marketplace-publish.yml (+13 lines)

  • Added single optional input: rollback_source_version
  • Modified GIT_REF to use rollback source when provided
  • Added simple one-line step: node scripts/set-rollback-version.js
  • Applied to both extension and JetBrains jobs
  • Zero code duplication, fully backward compatible

Added: scripts/set-rollback-version.js (~105 lines)

  • Calculates appropriate rollback version automatically
  • Updates src/package.json with new version
  • Handles edge cases (existing -fix versions, etc.)
  • All logic consolidated in one place

Added: scripts/__tests__/set-rollback-version.test.js

  • Unit tests for version calculation logic

  • Instant: One input, everything else automatic

  • 🧠 Smart: Calculates correct SemVer version

  • 🎯 Simple: No mental math, no version errors

  • 🔒 Safe: Uses proven code from git history

  • ♻️ Maintainable: Minimal YAML, logic in JS

  • 📦 SemVer compatible: Proper ordering guaranteed

User Input: v4.115.0
           ↓
Script calculates: 4.116.2-fix
           ↓
Updates package.json
           ↓
Workflow builds & publishes

Version calculation:

  • Checks current version on main: 4.116.1
  • Increments patch: 4.116.2
  • Adds -fix suffix: 4.116.2-fix
  • Handles multiple rollbacks: fix, fix2, fix3...

Key insight: During emergencies, minimize decisions. The system should figure out versions automatically.

When we publish a broken extension, we have no fast recovery path. Our changeset-based release process requires reverting PRs, code reviews, and manual version coordination—all while users are experiencing issues in production.

**The pain:** Emergency rollbacks require:
1. Reverting multiple PRs
2. Creating changeset PRs
3. Manual version number calculations
4. Code reviews during an emergency

Added **one-click automatic rollback** to the marketplace publish workflow. Just provide the git tag of a working version, and the system handles everything else.

**Normal publish (unchanged):**
```
Actions → Publish Extension → Run workflow
→ Leave rollback field empty
```

**Emergency rollback:**
```
Actions → Publish Extension → Run workflow
→ rollback_source_version: v4.115.0
```

**That's it!** The system automatically:
1. Calculates next version (e.g., `4.116.2-fix`)
2. Updates `package.json`
3. Checks out old code from tag
4. Builds and publishes

```bash
$ node scripts/set-rollback-version.js v4.115.0

Current version on main: 4.116.1
Rolling back from source: v4.115.0
Calculated rollback version: 4.116.2-fix

SemVer ordering:
  4.116.1 < 4.116.2-fix < 4.116.2

✅ Updated src/package.json to version 4.116.2-fix
```

**Modified:** `.github/workflows/marketplace-publish.yml` (+13 lines)
- Added single optional input: `rollback_source_version`
- Modified `GIT_REF` to use rollback source when provided
- Added simple one-line step: `node scripts/set-rollback-version.js`
- Applied to both extension and JetBrains jobs
- Zero code duplication, fully backward compatible

**Added:** `scripts/set-rollback-version.js` (~105 lines)
- Calculates appropriate rollback version automatically
- Updates `src/package.json` with new version
- Handles edge cases (existing `-fix` versions, etc.)
- All logic consolidated in one place

**Added:** `scripts/__tests__/set-rollback-version.test.js`
- Unit tests for version calculation logic

- ⚡ **Instant**: One input, everything else automatic
- 🧠 **Smart**: Calculates correct SemVer version
- 🎯 **Simple**: No mental math, no version errors
- 🔒 **Safe**: Uses proven code from git history
- ♻️ **Maintainable**: Minimal YAML, logic in JS
- 📦 **SemVer compatible**: Proper ordering guaranteed

```
User Input: v4.115.0
           ↓
Script calculates: 4.116.2-fix
           ↓
Updates package.json
           ↓
Workflow builds & publishes
```

**Version calculation:**
- Checks current version on main: `4.116.1`
- Increments patch: `4.116.2`
- Adds `-fix` suffix: `4.116.2-fix`
- Handles multiple rollbacks: `fix`, `fix2`, `fix3`...

**SemVer ordering ensures users auto-update:**
```
4.116.1 < 4.116.2-fix < 4.116.2
```

**Local test:**
```bash
$ node scripts/set-rollback-version.js v4.115.0
✅ Updated src/package.json to version 4.116.2-fix
```

Script successfully:
- ✅ Reads current version from main branch
- ✅ Calculates next rollback version
- ✅ Updates package.json
- ✅ Provides clear output

**Key insight:** During emergencies, minimize decisions. The system should figure out versions automatically.

**Design principles:**
1. **Single input**: Only ask for what we need (old tag)
2. **Automatic calculation**: System determines version
3. **Minimal YAML**: All logic in JavaScript
4. **Clear output**: Script provides full context

---

**Quick summary:**
> Emergency rollback in one input! Just provide an old git tag (e.g., `v4.115.0`), and the system automatically calculates the version, updates files, and publishes. Recovery in ~15 minutes.

**Copy-paste for Discord/Slack:**
> 🚨 One-click rollback is ready! If we ship a broken version, just provide the old git tag and click run. The system auto-calculates the version, checks out old code, and republishes. Emergency recovery in ~15 minutes with zero manual version calculations. 🎯
## Problem
When we publish a broken extension version, we have no fast way to recover:
- Reverting PRs is time-consuming and requires multiple reviews
- Manual version calculations are error-prone during emergencies
- Main branch can get out of sync with published versions

## Solution
Added one-click rollback to marketplace publish workflow:
1. Specify old working version (e.g., v4.115.0)
2. System automatically calculates new rollback version (e.g., 4.116.2-fix)
3. Publishes rollback immediately (~15 minutes)
4. Creates PR to sync main branch with published version

## How It Works

**For Users:**
Actions → Publish Extension → rollback_source_version: v4.115.0

**Behind the Scenes:**
1. Workflow checks out code from old tag
2. `set-rollback-version.js` calculates next version with -fix suffix
3. Updates package.json and publishes
4. `create-rollback-pr.js` creates PR with version + changelog updates

**Version Strategy:**
- Increments patch version with -fix suffix for proper SemVer ordering
- Example: 4.116.1 → rollback as 4.116.2-fix
- Users auto-update, and 4.116.2-fix < 4.116.2 < 4.117.0

## Changes

**Modified:**
- .github/workflows/marketplace-publish.yml
  - Added rollback_source_version input
  - Added version calculation step
  - Added PR creation step (calls Node script instead of inline code)

**Added:**
- scripts/set-rollback-version.js (~105 lines)
  - Calculates rollback version automatically
  - Updates package.json with new version
  - Handles multiple rollbacks (fix, fix2, fix3...)

- scripts/create-rollback-pr.js (~150 lines)
  - Creates branch with updated version
  - Updates package.json and CHANGELOG.md
  - Creates PR to keep main in sync
  - Uses GitHub API (@octokit/rest)

## Why This Design

**Follows existing patterns:**
- Like changesets: publishes first, then creates PR for main
- Keeps main in sync with marketplace
- Clear audit trail via PR

**Avoids inline code:**
- Node scripts are easier to test and maintain
- No 80+ lines of JavaScript in YAML
- Reusable if we need similar functionality elsewhere

## Testing
Successfully tested version calculation locally:
```bash
$ node scripts/set-rollback-version.js v4.115.0
Current version on main: 4.116.1
Calculated rollback version: 4.116.2-fix
✅ Updated src/package.json
```

Workflow itself uses proven publish logic - just with old checkout + version update.
@changeset-bot
Copy link

changeset-bot bot commented Nov 5, 2025

⚠️ No Changeset found

Latest commit: 87d3c33

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Removed duplication where both set-rollback-version.js and the workflow
were calculating the rollback version separately.

Now create-rollback-pr.js imports calculateRollbackVersion() from
set-rollback-version.js - single source of truth for version logic.

Workflow simplified:
- Removed unnecessary get_rollback_version step
- Removed ROLLBACK_VERSION env var passing
- create-rollback-pr.js calculates version itself by reading from main

This keeps version calculation logic in one place and makes the
workflow cleaner.
@hassoncs hassoncs requested a review from RSO November 5, 2025 22:13
Prevents failures from invalid tag references:

1. Auto-fixes missing 'v' prefix (accepts v4.115.0 or 4.115.0)
2. Validates tag exists before checkout
3. Shows recent tags if validation fails
4. Uses VALIDATED_TAG for consistent checkout

This makes the rollback workflow more robust and user-friendly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants