> ## Documentation Index
> Fetch the complete documentation index at: https://commander-docs.cyshel.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Releasing a new version

> How to ship a new Commander version through the automated release pipeline

This guide covers the full release process for Commander — from version bump to public download.

## How it works

The release pipeline is fully automated via AWS CodePipeline. There is no manual tag creation, no manual approval gate, and no GitHub release step:

```
Merge dev → production (push)
  → CodePipeline Source (triggers on every push to production)
  → Build: orchestrator CodeBuild
      reads the version from apps/commander/package.json,
      creates the commander@X.Y.Z git tag,
      dispatches the "Build Commander (macOS)" GitHub Actions workflow,
      polls every 30 s (up to ~40 min) until it completes
  → Promote: promote CodeBuild
      validates the staged artifacts, copies staging → production,
      invalidates the CDN, updates the Homebrew tap
```

Your job is to bump the version on `dev` and merge to `production`. The pipeline handles everything else, including the git tag.

## Prerequisites

* Push access to the `production` branch of `cyshel-platform`
* The `cyshel-prod` AWS profile (for monitoring and rollback)
* GitHub CLI (`gh`) authenticated, if you want to watch the macOS build

## Step 1: bump the version on dev

Edit `apps/commander/package.json` and increment the version:

```json theme={null}
{
  "version": "0.27.0"
}
```

Follow [semver](https://semver.org/):

* **Patch** (0.26.1): bug fixes only
* **Minor** (0.27.0): new features, backward compatible
* **Major** (1.0.0): breaking changes

Commit and push to `dev` as usual. The version in `package.json` is the single source of truth — the pipeline reads it to name the tag and the artifacts.

## Step 2: merge dev into production

```bash theme={null}
git checkout production
git pull origin production
git merge dev
git push origin production
```

The push to `production` is the only trigger. The pipeline creates and pushes the `commander@X.Y.Z` tag itself — do **not** create tags manually.

## Step 3: monitor the pipeline

```bash theme={null}
# Pipeline stage status (Source → Build → Promote)
AWS_PROFILE=cyshel-prod aws codepipeline get-pipeline-state \
  --name commander-release-production \
  --region us-east-1 \
  --query 'stageStates[*].{stage:stageName,status:latestExecution.status}' \
  --output table

# Watch the GHA macOS build the orchestrator dispatched
gh run list --workflow "Build Commander (macOS)" --limit 3
gh run view <run-id>
```

The Build stage dominates the runtime: the GitHub Actions job builds with electron-vite, signs and notarizes with electron-builder, verifies the signature and Gatekeeper assessment, then uploads to S3 staging. The orchestrator polls every 30 seconds for up to \~40 minutes; the GHA job itself has a 45-minute timeout. The Promote stage has a 10-minute timeout.

## Step 4: verify the release

```bash theme={null}
# The CDN should serve the new version
curl -s https://releases.cyshel.com/commander/latest-mac.yml | head -1
# Expected: version: 0.27.0
```

Also confirm:

* The `commander@0.27.0` tag exists on GitHub (created by the pipeline).
* The Homebrew tap (`Cyshel/homebrew-tap`, `Casks/commander.rb`) shows the new version and SHA-256. The tap update retries three times and is non-fatal — check it explicitly if it matters for this release.

Running Commander installations check `latest-mac.yml` 10 seconds after launch and every 5 minutes thereafter, download the update in the background, and prompt the user to install (with snooze and install-when-idle options).

## Rollback

If a bad version ships, restore the previous update manifest:

```bash theme={null}
AWS_PROFILE=cyshel-prod aws codebuild start-build \
  --project-name commander-rollback-production \
  --region us-east-1
```

This restores the previous `latest-mac.yml` from `commander/rollback/` and invalidates the CDN. Clients already on the bad version are not downgraded, but no new clients are offered it.

## Troubleshooting

### Build fails at "Install dependencies"

The GHA workflow runs `pnpm install --frozen-lockfile`, so an out-of-sync `pnpm-lock.yaml` fails the build. Run `pnpm install` locally, commit the updated lockfile to `dev`, and merge to `production` again.

### Retrying a failed stage

You don't need a new commit — retry the failed stage in place:

```bash theme={null}
# Get the execution ID
AWS_PROFILE=cyshel-prod aws codepipeline get-pipeline-state \
  --name commander-release-production \
  --region us-east-1 \
  --query 'stageStates[?stageName==`Build`].latestExecution.pipelineExecutionId' \
  --output text

# Retry
AWS_PROFILE=cyshel-prod aws codepipeline retry-stage-execution \
  --pipeline-name commander-release-production \
  --stage-name Build \
  --pipeline-execution-id <EXECUTION_ID> \
  --retry-mode FAILED_ACTIONS \
  --region us-east-1
```

Retrying Build is safe: the orchestrator is idempotent. If the tag already exists and the staged artifacts are present, it skips the build; if the tag exists but artifacts are missing, it re-dispatches the GHA workflow.

### Promote fails with "Missing artifact" or "Version mismatch"

Promote validates that `latest-mac.yml`, `Commander-X.Y.Z-universal.dmg`, and `Commander-X.Y.Z-universal-mac.zip` exist in `commander/staging/X.Y.Z/` and that the manifest version matches `package.json`. A failure here usually means the GHA upload was incomplete — retry the Build stage first, then Promote.

### Code signing or notarization fails

Signing uses a certificate imported from the `MAC_CERTIFICATE_P12` / `MAC_CERTIFICATE_PASSWORD` GitHub secrets; notarization uses `APPLE_ID`, `APPLE_APP_SPECIFIC_PASSWORD`, and `APPLE_TEAM_ID`. Check the "Import signing certificate" and "Package & Notarize" steps in the GHA run log.

### Pipeline failure notifications

Failures (any stage) publish to the SNS topic `commander-release-failures-production` with the execution ID. Subscribe an email or Slack webhook to that topic to be alerted. There are no success notifications.

## Quick reference

| What                    | Command                                                                                      |
| ----------------------- | -------------------------------------------------------------------------------------------- |
| Pipeline status         | `aws codepipeline get-pipeline-state --name commander-release-production --region us-east-1` |
| Watch GHA build         | `gh run list --workflow "Build Commander (macOS)" --limit 3`                                 |
| Verify CDN version      | `curl -s https://releases.cyshel.com/commander/latest-mac.yml \| head -1`                    |
| Retry a failed stage    | `aws codepipeline retry-stage-execution --pipeline-name commander-release-production …`      |
| Rollback                | `aws codebuild start-build --project-name commander-rollback-production --region us-east-1`  |
| Re-trigger from scratch | Push to `production` (e.g. `git commit --allow-empty`)                                       |

All AWS commands need `AWS_PROFILE=cyshel-prod`.

## Architecture

| Component              | Location       | Purpose                                                                 |
| ---------------------- | -------------- | ----------------------------------------------------------------------- |
| CodePipeline           | AWS (CDK)      | `commander-release-production` — Source → Build → Promote, no approvals |
| Orchestrator CodeBuild | AWS (CDK)      | Creates the `commander@X.Y.Z` tag, dispatches GHA, polls for completion |
| Promote CodeBuild      | AWS (CDK)      | Validates + promotes artifacts, CDN invalidation, Homebrew tap          |
| Rollback CodeBuild     | AWS (CDK)      | Restores the previous manifest on demand                                |
| GHA `build-mac.yml`    | GitHub Actions | macOS build, code signing, notarization, S3 staging upload              |
| S3 + CloudFront        | AWS (CDK)      | Hosts release artifacts at `releases.cyshel.com`                        |
| SNS + EventBridge      | AWS (CDK)      | Pipeline failure notifications                                          |

The CDK stack is `infrastructure/lib/stacks/commander-releases-stack.ts`; the full reference lives at `docs/infrastructure/commander-releases.md`.
