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
39 changes: 33 additions & 6 deletions .github/workflows/release-ios.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
name: Release iOS

on:
push:
tags:
- "v*.*.*"
workflow_dispatch:
inputs:
version:
description: "Release version (for example 1.2.3 or v1.2.3)"
required: true
type: string
ref:
description: "Git ref to build (defaults to refs/tags/v<version>; may also be a branch or SHA)"
required: false
type: string

permissions:
contents: read
Expand All @@ -23,7 +24,8 @@ jobs:
tag: ${{ steps.release_meta.outputs.tag }}
release_channel: ${{ steps.release_meta.outputs.release_channel }}
build_timestamp: ${{ steps.release_meta.outputs.build_timestamp }}
ref: ${{ github.sha }}
ref: ${{ steps.release_meta.outputs.ref }}
commit_sha: ${{ steps.resolved_commit.outputs.sha }}
steps:
- id: release_meta
name: Resolve release version
Expand All @@ -33,8 +35,10 @@ jobs:

if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
raw="${{ github.event.inputs.version }}"
requested_ref="${{ github.event.inputs.ref }}"
else
raw="${GITHUB_REF_NAME}"
requested_ref="${GITHUB_REF}"
fi

version="${raw#v}"
Expand All @@ -43,18 +47,41 @@ jobs:
exit 1
fi

tag="v$version"
if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
if [[ -n "$requested_ref" ]]; then
resolved_ref="$requested_ref"
else
resolved_ref="refs/tags/$tag"
fi
else
resolved_ref="$requested_ref"
fi

build_timestamp="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"

echo "version=$version" >> "$GITHUB_OUTPUT"
echo "tag=v$version" >> "$GITHUB_OUTPUT"
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "build_timestamp=$build_timestamp" >> "$GITHUB_OUTPUT"
echo "ref=$resolved_ref" >> "$GITHUB_OUTPUT"

if [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "release_channel=stable" >> "$GITHUB_OUTPUT"
else
echo "release_channel=prerelease" >> "$GITHUB_OUTPUT"
fi

- name: Checkout release ref
uses: actions/checkout@v6
with:
ref: ${{ steps.release_meta.outputs.ref }}
fetch-depth: 0

- id: resolved_commit
name: Resolve release commit
shell: bash
run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"

ios_signing_preflight:
name: iOS signing preflight
needs: [preflight]
Expand Down Expand Up @@ -102,7 +129,7 @@ jobs:
runs-on: macos-14
env:
RELEASE_VERSION: ${{ needs.preflight.outputs.version }}
OKCODE_COMMIT_HASH: ${{ github.sha }}
OKCODE_COMMIT_HASH: ${{ needs.preflight.outputs.commit_sha }}
OKCODE_BUILD_TIMESTAMP: ${{ needs.preflight.outputs.build_timestamp }}
OKCODE_RELEASE_CHANNEL: ${{ needs.preflight.outputs.release_channel }}
steps:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ Notes:
Release is driven by `.github/workflows/release.yml` and the canonical runbook in
[`docs/release.md`](/Users/buns/.okcode/worktrees/okcode/okcode-1c7a5554/docs/release.md).

- Release tags publish desktop artifacts and `okcodes` from `release.yml`, while `release-ios.yml` uploads the matching iOS TestFlight build separately.
- Release tags publish desktop artifacts and `okcodes` from `release.yml`, while `release-ios.yml` is dispatched separately for the matching iOS TestFlight build.
- Preflight runs format, lint, typecheck, tests, browser tests, desktop smoke, and release smoke.
- The separate Intel mac workflow is compatibility-only and non-blocking.
- Publishing still requires release notes and an asset manifest for the tagged version.
Expand Down Expand Up @@ -236,7 +236,7 @@ Release is driven by `.github/workflows/release.yml` and the canonical runbook i
2. Confirm macOS, Windows, Linux, iOS TestFlight, and CLI release inputs are ready.
3. Confirm signing secrets availability for macOS/Windows targets.
4. Confirm `docs/releases/v<version>.md` and `docs/releases/v<version>/assets.md` exist.
5. Trigger the desktop/CLI release and monitor both the desktop/CLI and iOS workflows.
5. Trigger the desktop/CLI release, then dispatch and monitor the separate iOS workflow for the same version when needed.

## 12) Contributing expectations

Expand Down
13 changes: 7 additions & 6 deletions docs/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The next stable train ships one semver across desktop, CLI, and iOS surfaces:
- macOS arm64 desktop DMG plus updater metadata
- Windows x64 signed NSIS installer
- Linux x64 AppImage
- iOS TestFlight build from the same tag
- iOS TestFlight build from the same release tag, dispatched separately
- `okcodes` npm package from the same tag

`docs/release.md` is the source of truth for release policy, release gates, and the platform matrix. Treat `docs/releases/README.md` and README release references as pointers only.
Expand All @@ -32,10 +32,10 @@ The next stable train ships one semver across desktop, CLI, and iOS surfaces:

## Release workflows

Official release tags now fan out into two workflows:
Official release tags and follow-up mobile promotion now use two workflows:

- [`release.yml`](../.github/workflows/release.yml) for desktop artifacts, npm publish, GitHub Release publication, and finalize.
- [`release-ios.yml`](../.github/workflows/release-ios.yml) for the matching TestFlight upload from the same tag.
- [`release.yml`](../.github/workflows/release.yml) runs automatically on release tags for desktop artifacts, npm publish, GitHub Release publication, and finalize.
- [`release-ios.yml`](../.github/workflows/release-ios.yml) is dispatched manually for the matching version/ref when we want the TestFlight upload.

`release.yml` job order:

Expand Down Expand Up @@ -114,6 +114,7 @@ Non-blocking compatibility lane:
- Build the mobile web bundle and sync Capacitor before archiving.
- Run a simulator build in CI before archive/upload.
- Upload the archive to TestFlight from the dedicated `release-ios.yml` workflow.
- Dispatch `release-ios.yml` with the release version and matching tag/ref (defaults to `refs/tags/vX.Y.Z`).
- During RC soak, manually verify on:
- one current supported iPhone/iOS
- one older supported iPhone/iOS
Expand Down Expand Up @@ -175,12 +176,12 @@ If any blocker fails, cut a new RC and repeat the soak.
## Post-release expectations

- The GitHub release includes desktop artifacts plus release notes and asset manifest.
- iOS is distributed through TestFlight by `release-ios.yml`, not attached to the GitHub release.
- iOS is distributed through TestFlight by a separate `release-ios.yml` dispatch against the release tag, not attached to the GitHub release.
- `finalize` updates version strings and pushes the post-release bump to `main`.

## Troubleshooting

- If `preflight` fails, reproduce locally with the exact failing command before retriggering the workflow.
- If `desktop_build` fails, inspect the target-specific signing secrets first.
- If `ios_testflight` fails, re-check provisioning, App Store Connect API key setup, and archive/export logs in `release-ios.yml`.
- If `ios_testflight` fails, re-check provisioning, App Store Connect API key setup, the dispatched ref, and archive/export logs in `release-ios.yml`.
- If `publish_cli` fails, do not continue the train. Fix the publish issue so the app and CLI do not drift.
6 changes: 3 additions & 3 deletions docs/releases/v0.26.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ File-content search, desktop terminal docking, transport snapshot fixes, updated

## Upgrade and install

- **CLI:** `npm install -g okcodes@0.26.0` once the coordinated release workflow finishes.
- **CLI:** `npm install -g okcodes@0.26.0` once the desktop/CLI release workflow finishes.
- **Desktop:** Download from [GitHub Releases](https://github.com/OpenKnots/okcode/releases/tag/v0.26.0). Filenames are listed in [assets.md](v0.26.0/assets.md).
- **iOS:** Available via TestFlight (uploaded automatically by the Release iOS workflow).
- **iOS:** Available via TestFlight after the separate Release iOS workflow is dispatched for this tag.

## Known limitations

Expand All @@ -32,5 +32,5 @@ OK Code remains early work in progress. Expect rough edges around session recove
## Release operations

- Review the [asset manifest](v0.26.0/assets.md) to confirm every expected GitHub Release attachment is present.
- Use the [rollout checklist](v0.26.0/rollout-checklist.md) to walk the coordinated release from preflight through post-release verification.
- Use the [rollout checklist](v0.26.0/rollout-checklist.md) to walk the desktop/CLI release plus the separate iOS TestFlight dispatch through post-release verification.
- Use the [soak test plan](v0.26.0/soak-test-plan.md) to validate the highest-risk surfaces after the tag is live.
2 changes: 1 addition & 1 deletion docs/releases/v0.26.0/assets.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ All macOS DMG and ZIP payloads are **code-signed** with an Apple Developer ID ce

## iOS (TestFlight)

The iOS build is uploaded directly to App Store Connect / TestFlight by the [Release iOS workflow](../../.github/workflows/release-ios.yml). No IPA artifact is attached to the GitHub Release.
The iOS build is uploaded directly to App Store Connect / TestFlight by the separately dispatched [Release iOS workflow](../../.github/workflows/release-ios.yml). No IPA artifact is attached to the GitHub Release.

| Detail | Value |
| ----------------- | ------------------------------------------ |
Expand Down
2 changes: 1 addition & 1 deletion docs/releases/v0.26.0/rollout-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Step-by-step playbook for the v0.26.0 release. Each phase must complete before a
- [ ] Push the release-prep commit to `main`.
- [ ] Create and push tag `v0.26.0`.
- [ ] Verify the coordinated `release.yml` workflow starts.
- [ ] Verify the separate `release-ios.yml` workflow starts for `v0.26.0`, or trigger it manually with the same version if needed.
- [ ] Trigger `release-ios.yml` manually for `v0.26.0` (or the matching release ref if the tag is unavailable).
- [ ] Monitor `release.yml` through Preflight, Desktop builds, Publish CLI, Publish GitHub Release, and Finalize release.
- [ ] Monitor `release-ios.yml` through Preflight, iOS signing preflight, and iOS TestFlight.

Expand Down
10 changes: 5 additions & 5 deletions scripts/prepare-release.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ ${highlights || "- See changelog for detailed changes."}

- **CLI:** \`npm install -g okcodes@${version}\` once the desktop/CLI release workflow finishes.
- **Desktop:** Download from [GitHub Releases](${REPO_URL}/releases/tag/v${version}). Filenames are listed in [assets.md](v${version}/assets.md).
- **iOS:** Available via TestFlight (uploaded automatically by the Release iOS workflow).
- **iOS:** Available via TestFlight after the separate Release iOS workflow is dispatched for this tag.

## Known limitations

Expand All @@ -274,7 +274,7 @@ OK Code remains early work in progress. Expect rough edges around session recove
## Release operations

- Review the [asset manifest](v${version}/assets.md) to confirm every expected GitHub Release attachment is present.
- Use the [rollout checklist](v${version}/rollout-checklist.md) to walk the desktop/CLI release plus the matching iOS TestFlight workflow through post-release verification.
- Use the [rollout checklist](v${version}/rollout-checklist.md) to walk the desktop/CLI release plus the separate iOS TestFlight dispatch through post-release verification.
- Use the [soak test plan](v${version}/soak-test-plan.md) to validate the highest-risk surfaces after the tag is live.
`;
}
Expand Down Expand Up @@ -319,7 +319,7 @@ All macOS DMG and ZIP payloads are **code-signed** with an Apple Developer ID ce

## iOS (TestFlight)

The iOS build is uploaded directly to App Store Connect / TestFlight by the [Release iOS workflow](../../.github/workflows/release-ios.yml). No IPA artifact is attached to the GitHub Release.
The iOS build is uploaded directly to App Store Connect / TestFlight by the separately dispatched [Release iOS workflow](../../.github/workflows/release-ios.yml). No IPA artifact is attached to the GitHub Release.

| Detail | Value |
| ----------------- | ------------------------------------------ |
Expand Down Expand Up @@ -378,7 +378,7 @@ Step-by-step playbook for the v${version} release. Each phase must complete befo
- [ ] Push the release-prep commit to \`main\`.
- [ ] Create and push tag \`v${version}\`.
- [ ] Verify the coordinated \`release.yml\` workflow starts.
- [ ] Verify the separate \`release-ios.yml\` workflow starts for the same tag or trigger it manually with the same version if needed.
- [ ] Trigger \`release-ios.yml\` manually for \`v${version}\` (or the matching release ref if the tag is unavailable).
- [ ] Monitor \`release.yml\` through Preflight, Desktop builds, Publish CLI, Publish GitHub Release, and Finalize release.
- [ ] Monitor \`release-ios.yml\` through Preflight, iOS signing preflight, and iOS TestFlight.

Expand Down Expand Up @@ -948,7 +948,7 @@ async function main(): Promise<void> {
` 1. Monitor the desktop release workflow: ${REPO_URL}/actions/workflows/release.yml`,
);
console.log(
` 2. Monitor the iOS TestFlight workflow: ${REPO_URL}/actions/workflows/release-ios.yml`,
` 2. Trigger and monitor the iOS TestFlight workflow: ${REPO_URL}/actions/workflows/release-ios.yml`,
);
console.log(` 3. Verify the GitHub Release: ${REPO_URL}/releases/tag/${tag}`);
console.log(" 4. Test downloaded installers on each platform.");
Expand Down