Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/deploy-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ permissions:

jobs:
check:
if: github.head_ref != 'develop'
if: github.head_ref != 'develop' && !startsWith(github.head_ref, 'hotfix/')
runs-on: ubuntu-latest
steps:
- run: |
echo "Pull requests to main branch are only allowed from develop branch."
echo "Pull requests to main branch are only allowed from develop or hotfix/* branches."
exit 1
56 changes: 56 additions & 0 deletions .github/workflows/sync-main-to-develop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Sync main to develop

# Keeps stable hotfix commits reachable from the integration branch after the
# production source of truth publishes successfully.
on:
workflow_run:
workflows:
- Release
types:
- completed
branches:
- main
workflow_dispatch:

permissions:
contents: read

concurrency:
group: sync-main-to-develop
cancel-in-progress: false

jobs:
sync:
name: Merge main into develop
if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
steps:
- id: app-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ vars.GH_APP_CLIENT_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
permission-contents: write

- uses: useblacksmith/checkout@41cdeedae8edb2e684ba22896a5fd2a3cb85db6b # v1
with:
ref: develop
fetch-depth: 0
persist-credentials: true
token: ${{ steps.app-token.outputs.token }}

- name: Merge main into develop
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git fetch origin main develop
if git merge-base --is-ancestor origin/main HEAD; then
echo "develop already contains main."
else
git merge origin/main --no-edit
git push origin develop
fi
30 changes: 29 additions & 1 deletion apps/cli/docs/release-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ flowchart TD

### Trigger

Most releases are automatic — merge a PR into `develop` (beta) or approve the weekly Prod-Deploy PR into `main` (stable). For an `alpha` cut or a one-off override, dispatch manually:
Most releases are automatic — merge a PR into `develop` (beta) or approve the weekly Prod-Deploy PR into `main` (stable). Hotfixes use the same production gate: a reviewed `hotfix/*` PR targets `main`, and the resulting `main` push triggers the stable release path. For an `alpha` cut or a one-off override, dispatch manually:

```sh
# Manual alpha cut (v3 / next shell):
Expand All @@ -265,6 +265,34 @@ gh workflow run release.yml \

Auto-trigger paths leave `version` empty: semantic-release computes it from commits since the last tag.

### Hotfix release flow

Use a hotfix when an urgent stable fix must ship before the next scheduled `develop` -> `main` promotion. The hotfix path deliberately reuses the production PR gate instead of adding a second approval mechanism:

1. Branch from the current `main` tip:

```sh
git fetch origin main
git switch -c hotfix/<short-description> origin/main
```

2. Make the smallest safe fix and open a PR from `hotfix/<short-description>` into `main`.
3. Before merging, run a release dry run against the hotfix branch and the next unique stable version:

```sh
gh workflow run release.yml \
--ref hotfix/<short-description> \
--field channel=stable \
--field version=<next-patch-version> \
--field dry_run=true
```

4. After review and green checks, merge the hotfix PR into `main`. The `push: main` trigger runs the normal stable release pipeline and publishes the next semantic-release version.
5. Watch the stable release workflow through publish, Homebrew/Scoop updates, and verification.
6. Confirm that `Sync main to develop` succeeds. That workflow merges `main` back into `develop` after a successful `Release` run on `main`, keeping the hotfix reachable from the next beta and the next scheduled production deploy. If the sync conflicts, resolve it with a follow-up PR into `develop` before the next production promotion.

Do not use `workflow_dispatch dry_run=false` as the normal hotfix path. Manual stable dispatch is reserved for re-cutting a unique version after an interrupted or stale-bytes release. Hotfixes should land through a PR to `main` so the production source of truth and release tag history stay aligned.

### What each job does

`**build` (ubuntu-latest):\*\*
Expand Down
Loading