Skip to content

PlistBuddy command fallbacks for builds - #580

Open
sushidub wants to merge 3 commits into
schuyler:mainfrom
sushidub:main
Open

PlistBuddy command fallbacks for builds#580
sushidub wants to merge 3 commits into
schuyler:mainfrom
sushidub:main

Conversation

@sushidub

@sushidub sushidub commented Sep 3, 2026

Copy link
Copy Markdown

What

Replaces assertive external cli commands (existing within custom build file) with conditionals and failure (nonzero exit codes) fallbacks.

Where

Last two lines of the Update Build Number shell script Tools/update_build_number.sh

Why

To avoid potential build failures due to breaking changes in and/or rando updates to users version of PlistBuddy.

Issue Context

From what I'm able to grok from source, build execution (via Xcode IDE) contains a Run script build phase in which the custom bash script (e.g., Update Build Number) is invoked. The last three lines of that file contain command calls to users local version of PlistBuddy (located /usr/libexec/PlistBuddy).

For reasons that I'm blissfully ignorant/unaware of, my Xcode (v26.6) builds fail at the last two (of the three) lines being executed against PlistBuddy.

Run custom shell script 'Update Build Number' 0.1 seconds
Set: Entry, ":CFBundleShortVersionString", Does Not Exist
Command PhaseScriptExecution failed with a nonzero exit code

Debugging & Tests

Manual PlistBuddy tests in separate shell using same two line assertions as in file

Confirm Info.plist and file content

$ cd <xcode's tmp build dir>

$ cat < Info.plist 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleBuildVersion</key>
	<string>e9a9c47+</string>
</dict>
</plist>

plist content exists only for the commands leading up to build failure

To test for issues associated with local version of PlistBuddy, we'll copy the last two commands within the Tools/update_build_number.sh into separate shell and run them separately from command line.

Note that the Xcode build process is not containerized (at least it isn't on my machine), so both commands are invoking my local version of PlistBuddy just as its invoked during Xcode Run script build phase.

  1. Add to Info.plist a preexisting key/value item.
$ /usr/libexec/PlistBuddy -c "Add :CFBundleBuildVersion string sushidub-test-01" "Info.plist"
Add: ":CFBundleBuildVersion" Entry Already Exists

since return value is a non zero exitcode (e.g. Add: ":CFBundleBuildVersion" Entry Already Exists) this would result in Xcode build fail

  1. Set the value for key in Info.plist where key does not exist.
$ /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString sushidub-test-01" "Info.plist"
Set: Entry, ":CFBundleShortVersionString", Does Not Exist

this would also result in build fail since the return value is non zero exitcode (e.g. Set: Entry, ":CFBundleShortVersionString", Does Not Exist)

  1. If key exists in Info.plist give it a value of ..., otherwise add the key to the plist file with a type assignment of string and a value of ...
$ /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString sushidub-test-01" "Info.plist" 2>/dev/null ||  /usr/libexec/PlistBuddy -c "Add :CFBundleShortVersionString string sushidub-test-01" "Info.plist"
$ cat < Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>CFBundleBuildVersion</key>
  <string>e9a9c47+</string>
  <key>CFBundleShortVersionString</key>
  <string>sushidub-test-01</string>
</dict>
</plist>

Build passes since the return value is 0

NOTE: Its not obvious in the above tests, but if the Set subcommand contains a type declaration (e.g. 'string') as is the requirement for the Add subcommand, the resulting string value will include that type declaration as a prepended string to the overall value output. Avoid this.


For obvious reasons its not realistic to expect external tooling to execute with the same test and results precision throughout update cycles - let alone variations that might make it into future OS release.

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.

1 participant