Skip to content

fix(release): pick the right artifact line for a local iOS build - #59

Merged
greymag merged 1 commit into
masterfrom
worktree-release-fix
Aug 24, 2026
Merged

fix(release): pick the right artifact line for a local iOS build#59
greymag merged 1 commit into
masterfrom
worktree-release-fix

Conversation

@greymag

@greymag greymag commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Problem

alex release start -s -b fails for iOS even when the IPA was built successfully:

Run local build for ios
Local build succeed.
✓ Built build/ios/archive/Runner.xcarchive (202.3MB)
Build for ios has placed the artifact in <…/build/ios/archive/Runner.xcarchive>, but
<…/build/ios/ipa> was expected. …

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>.ipa was created correctly by that very run.

Reason

Current Flutter prints two ✓ Built lines for flutter build ipa — the Xcode archive first,
the IPA second:

✓ Built build/ios/archive/Runner.xcarchive (202.3MB)   ← alex picked this one
Building App Store IPA...
✓ Built IPA to build/ios/ipa (24.4MB)                  ← the actual artifact

Alex took the first line with firstWhereOrNull, assuming a build reports exactly one
artifact 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 ✓ 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 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
StartReleaseCommand to BuildOutput (lib/src/release/build_output.dart), so the line
selection 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 for BuildOutput (the reported
    archive-then-IPA output, reversed order, a fallback when no line points into the output
    directory, and an output without ✓ Built lines at all).

🤖 Generated with Claude Code

`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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 BuildOutput with getArtifactLine, parseArtifactPath, and isInDir, centralizing line selection and path verification.
  • Refactored StartReleaseCommand to delegate to BuildOutput for 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.

@greymag
greymag merged commit 7ccef81 into master Aug 24, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants