Skip to content

Conversation

@thelvis4
Copy link

@thelvis4 thelvis4 commented Aug 5, 2025

We noticed that xcrun appintentsmetadataprocessor produces non-deterministic Metadata.appintents/extract.actionsdata and Metadata.appintents/version.json JSON outputs (unstable json key order) resulting in different hashes for them when building the same target on different machines.

Tree Digest: root:  {
  files:  {
    name:  "extract.actionsdata"
    digest:  {
      hash:  "1a5948b0129723785ddccd42ec3e6f0315d43dbb77db291c890cf314b0f42b1b"
      size_bytes:  2981
    }
    is_executable:  true
  }
Tree Digest: root:  {
  files:  {
    name:  "extract.actionsdata"
    digest:  {
      hash:  "278dbe486ed21bebe61a5fef6dab2be05ba5fae588d7b330eb0200b8300e23e9"
      size_bytes:  2981
    }
    is_executable:  true
  }

Changes
Sort the keys of Metadata.appintents/extract.actionsdataand Metadata.appintents/extract.actionsdata directory tree output using /usr/bin/python3 -m json.tool to make it deterministic.

Filed Apple Feedback: FB19585633
Fixes #2760

@thelvis4 thelvis4 changed the title Make app intents metadata processor output deterministic Make AppIntentsMetadataProcessor outputs deterministic Aug 5, 2025
# Set write permission to allow rewrite extract.actionsdata
chmod -R +w {output_dir}
# Write extract.actionsdata with sorted keys
"$DEVELOPER_DIR/usr/bin/python3" -m json.tool --compact --sort-keys "$original_actionsdata_file" > "$temporary_actionsdata_file"
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not crazy about relying on the toolchain's Python here – normally I would prefer this live in a tool declared in a py_binary. That being said, I acknowledge that you're mainly working within the existing code here, and that json.tool hasn't meaningfully changed in several years now, so it's not the worst idea.

Copy link
Author

Choose a reason for hiding this comment

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

Right, given the action depends on DEVELOPER_DIR and is invalidated when Xcode version changes, I figured I can call python3 shipped with Xcode. It reduces the amount of code needed to pass the python binary and makes it easier to remove the mitigation after Apple fixes the root issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

I would take this change as is. @aaronsky do you feel strongly about py_binary here?

@adincebic adincebic force-pushed the make-AppIntentsMetadataProcessor-output-deterministic branch from ee839a7 to ce3aa36 Compare November 16, 2025 09:02
@adincebic adincebic self-requested a review as a code owner November 16, 2025 09:02
Copy link
Contributor

@adincebic adincebic left a comment

Choose a reason for hiding this comment

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

Thanks for fixing this.

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.

AppIntentsMetadataProcessor produces a JSON output that can be non-deterministic

4 participants