| name | ios-testflight-release |
| description | Use when the user asks to update TestFlight, publish/release the iOS app, cut a TestFlight build, create an iOS release tag, or says "发版", "更新 TestFlight", "打包提测", or similar. This project releases through GitHub Actions: new marketing versions use ios/vX.Y.Z tags, and same-version rebuilds use workflow_dispatch. |
iOS TestFlight Release
Use this skill for this repository's iOS release flow.
Release Policy
- New marketing-version releases are driven by Git tags matching
ios/v*, for example ios/v1.0.1.
- Same marketing-version TestFlight rebuilds are driven by
workflow_dispatch on the TestFlight workflow.
- The GitHub Actions workflow builds and uploads the build to TestFlight.
- Public Beta submission is manual. Do not automatically submit Beta App Review unless the user explicitly asks for full external distribution automation.
- Do not assume every TestFlight release increments
MARKETING_VERSION. Before releasing, make the user choose one of these version strategies:
- keep the current marketing version and upload a new build;
- increment the patch version and upload a new build;
- use a user-specified marketing version.
- Build numbers are generated by GitHub Actions as Asia/Shanghai
yyyyMMddHHmm, for example 202605081350. Do not manually provide a build number unless fixing a failed or incorrect release.
Safety Checks
- Run
git status --short --branch.
- Work from the latest
origin/main.
- If the local
main is diverged, do not force-reset it. Use a clean worktree or detached origin/main, commit there, and push HEAD:main.
- For a new marketing-version release, check whether the intended tag already exists locally or remotely before creating it:
git tag --list ios/vX.Y.Z
git ls-remote --tags origin ios/vX.Y.Z
If either command shows the tag, do not create or move that tag. Use same-version workflow_dispatch instead if the goal is only to upload another build for an existing version.
Version Selection
First read the current Release build setting for the app target:
xcodebuild -project nodeseek.xcodeproj -scheme nodeseek -configuration Release -showBuildSettings
Extract MARKETING_VERSION and normalize two-part versions to three-part versions:
1.0 -> 1.0.0
1.2.3 -> 1.2.3
If the user provides a version, normalize it:
1.0.1 -> 1.0.1
v1.0.1 -> 1.0.1
ios/v1.0.1 -> 1.0.1
If the user asks to increment patch, increment the patch component by 1:
1.0 -> 1.0.1
1.2.3 -> 1.2.4
If the user only says "发新 TestFlight", "重新发", or otherwise does not specify whether to increment the marketing version, stop and ask whether to keep the current version or increment it. This prevents unnecessary Beta App Review churn for external TestFlight.
For a new marketing-version release, the release tag is ios/v<version>. For a same-version rebuild, do not create a tag.
Update Project Version
Set the project marketing version only when the selected marketing version differs from the current project version. Prefer the project's existing fastlane tooling when available:
bundle exec fastlane run increment_version_number version_number:X.Y.Z xcodeproj:nodeseek.xcodeproj
If local Ruby/bundler is unavailable, update all app/test target MARKETING_VERSION entries in nodeseek.xcodeproj/project.pbxproj consistently and verify the diff only changes version values.
Do not manually edit build number for this workflow. GitHub Actions generates the build number as Asia/Shanghai yyyyMMddHHmm.
Commit, Push, Release
If the marketing version changes, commit and push that version file change, then create and push the matching tag:
git diff --check
git status --short
git add nodeseek.xcodeproj/project.pbxproj
git commit -m "Release iOS X.Y.Z"
git push origin HEAD:main
git tag ios/vX.Y.Z
git push origin ios/vX.Y.Z
The tag push starts the TestFlight GitHub Actions workflow.
If the marketing version stays the same, do not create a duplicate tag. Make sure the desired code is already on main, then trigger the workflow manually:
gh workflow run TestFlight --ref main -f version=X.Y.Z
Only pass -f build_number=... for a deliberate override, and only with a numeric value greater than the latest App Store Connect build for that marketing version.
After Push
Tell the user:
- the commit SHA
- the tag name for new marketing-version releases, or that workflow_dispatch was used for same-version rebuilds
- that GitHub Actions should upload the build to TestFlight
- that the workflow generated the build number automatically from Asia/Shanghai
yyyyMMddHHmm
- that final Public Beta submission is still manual in App Store Connect
If asked for the next manual step, direct them to App Store Connect > the app > TestFlight, select the uploaded build, add it to Public Beta, confirm the test information from the workflow summary, and submit Beta App Review.