Skip to content

{CI} Fix macOS build: Use libexec/bin/python instead of libexec/bin/python3#33538

Merged
YangAn-microsoft merged 1 commit into
Azure:devfrom
YangAn-microsoft:fix/macos-homebrew-python-libexec-path
Jun 12, 2026
Merged

{CI} Fix macOS build: Use libexec/bin/python instead of libexec/bin/python3#33538
YangAn-microsoft merged 1 commit into
Azure:devfrom
YangAn-microsoft:fix/macos-homebrew-python-libexec-path

Conversation

@YangAn-microsoft

@YangAn-microsoft YangAn-microsoft commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Problem

After bumping the embedded Python to 3.14, the macOS build pipeline fails at the Install Homebrew Python step:

Python path: /opt/homebrew/opt/python@3.14/libexec/bin/python3
.../python@3.14/libexec/bin/python3: No such file or directory

Root cause

The Homebrew python@X.Y formula creates the unversioned python symlink in libexec/bin unconditionally, but creates the major-versioned python3 symlink in libexec/bin only for altinstalls (i.e. when the formula is not Homebrew's current default python3):

def altinstall? = name != Formula["python3"].name
...
{ "python" => "python#{version.major_minor}", ... }                        # unversioned, ALWAYS
  .merge(altinstall? ? { "python3" => "python#{version.major_minor}", ... } : {})   # python3, ONLY if altinstall?

python@3.14 is currently Homebrew's default python3 (altinstall? == false; it is installed as /opt/homebrew/bin/python3). For the default formula the real python3 lives in HOMEBREW_PREFIX/bin, so no python3 symlink is added under libexec/bin -- only the unversioned python. Hence .../python@3.14/libexec/bin/python3 does not exist.

This is confirmed by the formulae caveats: 3.14 says Python is installed as .../bin/python3 and lists only unversioned libexec symlinks (python, pip); 3.13 (the altinstall) says .../bin/python3.13 and lists both python and python3 in libexec. This is why the pipeline worked on 3.13 and broke after the bump to 3.14.

Fix

Use the always-present unversioned libexec/bin/python symlink instead of libexec/bin/python3. This is robust regardless of which minor version is Homebrew's default python3.

Files changed

  • .azure-pipelines/templates/macos/macos-build-jobs.yml (2 occurrences)
  • .azure-pipelines/templates/macos/macos-cask-generation-and-tests.yml
  • .azure-pipelines/templates/macos/macos-sign-notarize-jobs.yml
  • scripts/release/macos/build_binary_tar_gz.py (candidate list + brew --prefix fallback)

Copilot AI review requested due to automatic review settings June 12, 2026 00:47
@azure-client-tools-bot-prd

azure-client-tools-bot-prd Bot commented Jun 12, 2026

Copy link
Copy Markdown
️✔️AzureCLI-FullTest
️✔️acr
️✔️latest
️✔️3.12
️✔️3.14
️✔️acs
️✔️latest
️✔️3.12
️✔️3.14
️✔️advisor
️✔️latest
️✔️3.12
️✔️3.14
️✔️ams
️✔️latest
️✔️3.12
️✔️3.14
️✔️apim
️✔️latest
️✔️3.12
️✔️3.14
️✔️appconfig
️✔️latest
️✔️3.12
️✔️3.14
️✔️appservice
️✔️latest
️✔️3.12
️✔️3.14
️✔️aro
️✔️latest
️✔️3.12
️✔️3.14
️✔️backup
️✔️latest
️✔️3.12
️✔️3.14
️✔️batch
️✔️latest
️✔️3.12
️✔️3.14
️✔️batchai
️✔️latest
️✔️3.12
️✔️3.14
️✔️billing
️✔️latest
️✔️3.12
️✔️3.14
️✔️botservice
️✔️latest
️✔️3.12
️✔️3.14
️✔️cdn
️✔️latest
️✔️3.12
️✔️3.14
️✔️cloud
️✔️latest
️✔️3.12
️✔️3.14
️✔️cognitiveservices
️✔️latest
️✔️3.12
️✔️3.14
️✔️compute_recommender
️✔️latest
️✔️3.12
️✔️3.14
️✔️computefleet
️✔️latest
️✔️3.12
️✔️3.14
️✔️config
️✔️latest
️✔️3.12
️✔️3.14
️✔️configure
️✔️latest
️✔️3.12
️✔️3.14
️✔️consumption
️✔️latest
️✔️3.12
️✔️3.14
️✔️container
️✔️latest
️✔️3.12
️✔️3.14
️✔️containerapp
️✔️latest
️✔️3.12
️✔️3.14
️✔️core
️✔️latest
️✔️3.12
️✔️3.14
️✔️cosmosdb
️✔️latest
️✔️3.12
️✔️3.14
️✔️databoxedge
️✔️latest
️✔️3.12
️✔️3.14
️✔️dls
️✔️latest
️✔️3.12
️✔️3.14
️✔️dms
️✔️latest
️✔️3.12
️✔️3.14
️✔️eventgrid
️✔️latest
️✔️3.12
️✔️3.14
️✔️eventhubs
️✔️latest
️✔️3.12
️✔️3.14
️✔️feedback
️✔️latest
️✔️3.12
️✔️3.14
️✔️find
️✔️latest
️✔️3.12
️✔️3.14
️✔️hdinsight
️✔️latest
️✔️3.12
️✔️3.14
️✔️identity
️✔️latest
️✔️3.12
️✔️3.14
️✔️iot
️✔️latest
️✔️3.12
️✔️3.14
️✔️keyvault
️✔️latest
️✔️3.12
️✔️3.14
️✔️lab
️✔️latest
️✔️3.12
️✔️3.14
️✔️managedservices
️✔️latest
️✔️3.12
️✔️3.14
️✔️maps
️✔️latest
️✔️3.12
️✔️3.14
️✔️marketplaceordering
️✔️latest
️✔️3.12
️✔️3.14
️✔️monitor
️✔️latest
️✔️3.12
️✔️3.14
️✔️mysql
️✔️latest
️✔️3.12
️✔️3.14
️✔️netappfiles
️✔️latest
️✔️3.12
️✔️3.14
️✔️network
️✔️latest
️✔️3.12
️✔️3.14
️✔️policyinsights
️✔️latest
️✔️3.12
️✔️3.14
️✔️postgresql
️✔️latest
️✔️3.12
️✔️3.14
️✔️privatedns
️✔️latest
️✔️3.12
️✔️3.14
️✔️profile
️✔️latest
️✔️3.12
️✔️3.14
️✔️rdbms
️✔️latest
️✔️3.12
️✔️3.14
️✔️redis
️✔️latest
️✔️3.12
️✔️3.14
️✔️relay
️✔️latest
️✔️3.12
️✔️3.14
️✔️resource
️✔️latest
️✔️3.12
️✔️3.14
️✔️role
️✔️latest
️✔️3.12
️✔️3.14
️✔️search
️✔️latest
️✔️3.12
️✔️3.14
️✔️security
️✔️latest
️✔️3.12
️✔️3.14
️✔️servicebus
️✔️latest
️✔️3.12
️✔️3.14
️✔️serviceconnector
️✔️latest
️✔️3.12
️✔️3.14
️✔️servicefabric
️✔️latest
️✔️3.12
️✔️3.14
️✔️signalr
️✔️latest
️✔️3.12
️✔️3.14
️✔️sql
️✔️latest
️✔️3.12
️✔️3.14
️✔️sqlvm
️✔️latest
️✔️3.12
️✔️3.14
️✔️storage
️✔️latest
️✔️3.12
️✔️3.14
️✔️synapse
️✔️latest
️✔️3.12
️✔️3.14
️✔️telemetry
️✔️latest
️✔️3.12
️✔️3.14
️✔️util
️✔️latest
️✔️3.12
️✔️3.14
️✔️vm
️✔️latest
️✔️3.12
️✔️3.14

@azure-client-tools-bot-prd

azure-client-tools-bot-prd Bot commented Jun 12, 2026

Copy link
Copy Markdown
️✔️AzureCLI-BreakingChangeTest
️✔️Non Breaking Changes

The Homebrew python@X.Y formula only creates the unversioned 'python'
symlink in libexec/bin unconditionally. The 'python3' symlink is created
only for altinstalls (when the formula is NOT Homebrew's default python3
alias). After bumping to 3.14, python@3.14 is an altinstall (3.13 remains
the python3 alias), so .../python@3.14/libexec/bin/python3 does not exist,
breaking the macOS build/sign/cask pipelines. Use the always-present
'python' symlink instead.
@YangAn-microsoft YangAn-microsoft force-pushed the fix/macos-homebrew-python-libexec-path branch from 188b08e to 126239f Compare June 12, 2026 00:50

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 addresses a macOS packaging pipeline break caused by Homebrew python@X.Y formulae not always providing libexec/bin/python3 (notably for 3.14), by switching to the always-present libexec/bin/python. It also introduces a new automated “Python Upgrade Agent” (scripts, tests, and a scheduled GitHub Actions workflow) plus associated documentation.

Changes:

  • Fix macOS pipeline and packaging scripts to use .../libexec/bin/python instead of .../libexec/bin/python3 for Homebrew-managed Python.
  • Add a Python minor-version upgrade automation agent (scripts/python_upgrade_agent/) with validation, post-checking, and unit tests.
  • Add a scheduled GitHub Actions workflow to run the agent, plus playbook/docs and log-file gitignore entry.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

Show a summary per file
File Description
.azure-pipelines/templates/macos/macos-build-jobs.yml Switches Homebrew Python path usage to libexec/bin/python in macOS build/test steps.
.azure-pipelines/templates/macos/macos-cask-generation-and-tests.yml Switches AZ_PYTHON to libexec/bin/python for cask generation/tests.
.azure-pipelines/templates/macos/macos-sign-notarize-jobs.yml Switches AZ_PYTHON to libexec/bin/python for functional tests in sign/notarize jobs.
scripts/release/macos/build_binary_tar_gz.py Updates Homebrew Python discovery to prefer libexec/bin/python (candidates + brew --prefix fallback).
.github/workflows/PythonUpgradeAgent.yml Adds scheduled + manual workflow to run the new Python upgrade agent using an app token and models token.
scripts/python_upgrade_agent/agent.py Orchestrates detect → discover → LLM → validate → post-check → apply → draft PR creation.
scripts/python_upgrade_agent/ai.py Implements GitHub Models call, prompt construction, and reference-PR few-shot retrieval.
scripts/python_upgrade_agent/detect.py Detects current embedded Python from build.cmd and selects next-minor target from python.org feed.
scripts/python_upgrade_agent/discover.py Uses git grep with exclusions to discover candidate version references with context.
scripts/python_upgrade_agent/validate.py Validates LLM-proposed edits against candidate set, uniqueness, and size caps.
scripts/python_upgrade_agent/post_check.py Simulates edits in-memory and flags leftover current-minor hits not listed as skipped.
scripts/python_upgrade_agent/github_ops.py Thin wrappers around git/gh for branching, applying edits, pushing, and PR creation.
scripts/python_upgrade_agent/README.md Documents the agent’s flow, configuration, and local testing.
scripts/python_upgrade_agent/pr_template.md PR body template emitted by the agent.
scripts/python_upgrade_agent/next_steps_template.md “Next steps” content embedded into the agent-opened PR body.
scripts/python_upgrade_agent/__init__.py Marks the agent as a package.
scripts/python_upgrade_agent/tests/__init__.py Test package marker.
scripts/python_upgrade_agent/tests/test_validate.py Unit tests for validation logic (paths, uniqueness, caps, additive classifier rule).
scripts/python_upgrade_agent/tests/test_post_check.py Unit tests for deterministic post-check behavior.
scripts/python_upgrade_agent/tests/test_discover.py Unit tests for discovery regex/path exclusion behavior using a mini git repo.
scripts/python_upgrade_agent/tests/test_detect.py Unit tests for version detection/decision logic.
doc/presentations/python-upgrade-campaign-playbook.md Adds a playbook describing the operational workflow for Python minor bumps.
.gitignore Ignores the agent’s verbose log file (python_upgrade_agent.log).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@YangAn-microsoft YangAn-microsoft changed the title Fix macOS build: use libexec/bin/python instead of libexec/bin/python3 [CI] Fix macOS build: use libexec/bin/python instead of libexec/bin/python3 Jun 12, 2026
@YangAn-microsoft YangAn-microsoft changed the title [CI] Fix macOS build: use libexec/bin/python instead of libexec/bin/python3 [CI] Fix macOS build: Use libexec/bin/python instead of libexec/bin/python3 Jun 12, 2026
@yonzhan

yonzhan commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

CI

@YangAn-microsoft YangAn-microsoft changed the title [CI] Fix macOS build: Use libexec/bin/python instead of libexec/bin/python3 {CI} Fix macOS build: Use libexec/bin/python instead of libexec/bin/python3 Jun 12, 2026
@YangAn-microsoft YangAn-microsoft merged commit c3df1ab into Azure:dev Jun 12, 2026
50 checks passed
@YangAn-microsoft YangAn-microsoft deleted the fix/macos-homebrew-python-libexec-path branch June 12, 2026 02:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants