fix(release): pick the right artifact line for a local iOS build - #59
Conversation
`flutter build ipa` prints two `✓ Built` lines — for the Xcode archive
and for the IPA itself:
✓ Built build/ios/archive/Runner.xcarchive (202.3MB)
✓ Built IPA to build/ios/ipa (24.4MB)
Alex took the first one, so the archive path was compared with the
expected `build/ios/ipa` and the release failed, even though the `.ipa`
was built correctly.
Now all `✓ Built` lines are collected and the one with a path inside the
build output directory is preferred (the last line is used as a fallback,
so a failure still reports a concrete path). Parsing and the output
directory check are extracted to `BuildOutput` and covered with tests.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes a bug in alex release start --local (-b) for iOS where the release aborted even though the IPA built correctly. flutter build ipa prints two ✓ Built lines (the Xcode archive first, then the IPA), and alex previously picked the first one via firstWhereOrNull, then wrongly concluded the artifact landed outside the expected build/ios/ipa directory. The fix extracts build-output parsing into a new BuildOutput helper that selects the line whose path is inside the output directory (falling back to the last ✓ Built line), preserving the existing safety guarantee that an artifact outside the cleaned output directory still aborts the release.
Changes:
- Added
BuildOutputwithgetArtifactLine,parseArtifactPath, andisInDir, centralizing line selection and path verification. - Refactored
StartReleaseCommandto delegate toBuildOutputfor both artifact-line selection and the output-directory check. - Added 11 unit tests and a changelog entry.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
lib/src/release/build_output.dart |
New helper that collects ✓ Built lines, prefers the one inside the output directory, and parses/validates artifact paths. |
lib/commands/release/start_release_command.dart |
Replaces inline first-match parsing/regex with BuildOutput calls for line selection and path verification. |
test/src/release/build_output_test.dart |
New unit tests covering getArtifactLine, parseArtifactPath, and isInDir across Android/iOS and edge cases. |
CHANGELOG.md |
Documents the iOS local-build artifact-line fix under ## Next. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Problem
alex release start -s -bfails for iOS even when the IPA was built successfully:The release aborts with exit code 2 before any commit, merge, tag or push, so it has to be
finished by hand — even though
build/ios/ipa/<app>.ipawas created correctly by that very run.Reason
Current Flutter prints two
✓ Builtlines forflutter build ipa— the Xcode archive first,the IPA second:
Alex took the first line with
firstWhereOrNull, assuming a build reports exactly oneartifact path, and then compared the archive path with the expected output directory.
The path regex already handled both line shapes — only the line selection was wrong.
Solution
All
✓ Builtlines are collected, and the one with a path inside the build output directoryis preferred; the last line is used as a fallback, so if nothing landed in the output directory
the failure still reports a concrete path instead of an arbitrary one.
The safety guarantee is unchanged: the output directory is still cleaned before the build,
so anything found there is a result of this build, and a reported path outside of it still
aborts the release.
Parsing of a build line and the "is it inside the output directory" check are extracted from
StartReleaseCommandtoBuildOutput(lib/src/release/build_output.dart), so the lineselection and the verification use the same logic, and both are covered with unit tests.
Verification
dart analyze— No issues found!dart test— 79 tests passed, including 11 new ones forBuildOutput(the reportedarchive-then-IPA output, reversed order, a fallback when no line points into the output
directory, and an output without
✓ Builtlines at all).🤖 Generated with Claude Code