FEAT: add standalone conda build pipeline + build-validation tooling - #744
FEAT: add standalone conda build pipeline + build-validation tooling#744Jahnvi Thakkar (jahnvi480) wants to merge 28 commits into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The Conda publish/release step templates contain a required-subdirs default mismatch and misleading guard error messages that can enable incorrect publishing behavior or slow diagnosis.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds standalone Conda build + release pipeline infrastructure for mssql-python, plus the validation/audit tooling (and unit tests) used to gate Conda artifacts independently of the wheel/PyPI release flow.
Changes:
- Introduces OneBranch standalone Conda build and Conda release/publish pipelines with shared step/job templates for per-platform build, consolidation, release gating, and publishing.
- Adds build-time and release-time validation tooling: Linux RUNPATH self-containment audit, Windows PE machine-type audit, release metadata gate, and release-time dependency re-solve gate.
- Adds a suite of pure unit tests (no DB / no native extension required) covering the new probes and validation scripts.
File summaries
| File | Description |
|---|---|
OneBranchPipelines/conda-build-pipeline.yml |
Standalone Conda build pipeline consuming wheel artifacts and producing consolidated Conda artifacts. |
OneBranchPipelines/conda-release-pipeline.yml |
Standalone Conda release pipeline that gates completeness/consistency and optionally publishes to Anaconda.org. |
OneBranchPipelines/jobs/consolidate-conda-artifacts-job.yml |
Consolidates per-leg staged Conda packages into a single conda/ artifact tree. |
OneBranchPipelines/steps/conda-build-validate-step.yml |
Windows template to build/validate Conda packages from wheels and stage artifacts. |
OneBranchPipelines/steps/conda-build-validate-step-posix.yml |
POSIX template to build/validate Conda packages from wheels and stage artifacts. |
OneBranchPipelines/steps/conda-release-step.yml |
Release-readiness gate: re-audit + metadata validate consolidated Conda artifacts. |
OneBranchPipelines/steps/conda-publish-step.yml |
Publishes consolidated Conda packages to Anaconda.org using staged-then-promoted flow. |
OneBranchPipelines/scripts/build-conda-packages.ps1 |
Windows implementation of Conda build+validate from wheel inputs (incl. audits and probes). |
OneBranchPipelines/scripts/build-conda-packages.sh |
POSIX implementation of Conda build+validate from wheel inputs (incl. audits and probes). |
OneBranchPipelines/scripts/.gitattributes |
Enforces LF for .sh scripts. |
conda/driver_load_probe.py |
DB-less driver load probe used as a Conda validation gate. |
conda/tls_connect_probe.py |
Live Encrypt=yes TLS probe to prove OpenSSL backend reachability (fail-closed classification). |
conda/validate_conda_release.py |
Metadata-based release readiness gate for Conda artifact completeness and consistency. |
eng/scripts/assert_pe_machine.py |
Audits PE machine type of vendored Windows binaries inside Conda packages. |
eng/scripts/audit_bundled_binaries.py |
Static, masking-immune audit of Linux vendored binaries’ RUNPATH/NEEDED/deps/vendoring rules. |
eng/scripts/conda_resolve_check.py |
Release-time dependency re-solve (dry-run) to catch channel drift before publish. |
tests/test_026_driver_load_probe.py |
Unit tests for conda/driver_load_probe.py classification and main() behavior via stubs. |
tests/test_027_conda_release_metadata.py |
Unit tests for conda/validate_conda_release.py matrix/subdir/version enforcement. |
tests/test_028_tls_connect_probe.py |
Unit tests for TLS probe classification, tokenization, redaction, and skip/guard behavior. |
tests/test_029_bundled_binary_audit.py |
Unit tests for Linux RUNPATH audit logic using synthetic ELF + conda package fixtures. |
tests/test_030_pe_machine_assert.py |
Unit tests for PE machine-type parser + .conda round-trip audit. |
tests/test_031_tls_probe_required.py |
Unit tests for TLS probe required-mode semantics (fail closed on misconfig). |
tests/test_032_conda_resolve_check.py |
Unit tests for conda re-solve helper (channel selection, cmd shape, target enumeration). |
Review details
- Files reviewed: 23/23 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
📊 Code Coverage Report
Diff CoverageDiff: main...HEAD, staged and unstaged changesNo lines with coverage information in this diff. 📋 Files Needing Attention📉 Files with overall lowest coverage (click to expand)mssql_python.pybind.logger_bridge.cpp: 57.9%
mssql_python.pybind.ddbc_bindings.h: 61.5%
mssql_python.pybind.logger_bridge.hpp: 70.8%
mssql_python.pybind.ddbc_bindings.cpp: 77.5%
mssql_python.row.py: 77.6%
mssql_python.pybind.connection.connection_pool.cpp: 82.8%
mssql_python.pybind.connection.connection.cpp: 84.4%
mssql_python.logging.py: 85.5%
mssql_python.helpers.py: 89.3%
mssql_python.pooling.py: 90.1%🔗 Quick Links
|
There was a problem hiding this comment.
🔵 Needs a closer look
There are a few correctness/robustness issues in the new conda validation tooling (notably ODBC braced-string splitting edge cases and script rerunnability) plus misleading failure messages that should be fixed before relying on these gates.
Review details
Suppressed comments (5)
Previously missed (4) — in code that hasn't changed since the last review.
OneBranchPipelines/scripts/build-conda-packages.sh:142
conda create -n conda_builder ...will fail on reruns because the env name is constant and the script never removes/reuses an existing env. This makes the script non-idempotent for local dev or agent/workdir reuse (andset -ewill abort immediately).
conda/tls_connect_probe.py:135_split_top_leveltreats every}as ending a braced value, but MS-ODBCSTR allows escaping a literal closing brace inside{...}as}}. With the current logic, a value containing}}can drop brace depth early and cause semicolons inside the braced value to be split at top level, corrupting the connection string rewrite.
conda/driver_load_probe.py:135- The probe is used for the self-contained conda package (ODBC payload vendored into mssql-python), so "missing companion" is misleading in the failure message and makes triage harder.
conda/tls_connect_probe.py:110 describe()prefixes anySSL Provider/ certificate verification failure as "OpenSSL backend unreachable", but those errors can happen with OpenSSL present (they indicate a TLS handshake failure, not a missing libssl/libcrypto). This wording makes failures misleading to triage.
This issue also appears on line 279 of the same file.
conda/tls_connect_probe.py:282
- The failure exit text always says "TLS/OPENSSL BACKEND UNREACHABLE", but failures can also be due to TLS handshake errors (cert, protocol, etc.) where OpenSSL is reachable. Consider a neutral prefix so the exit reason matches what actually failed.
if tls_completed(outcome):
print("TLS_OK (OpenSSL backend reachable; " + describe(outcome) + ")")
return
sys.exit("TLS/OPENSSL BACKEND UNREACHABLE: " + describe(outcome))
- Files reviewed: 16/16 changed files
- Comments generated: 0 new
- Review effort level: Lite
…unt, harden TLS probe - Rename test_026_driver_load_probe.py -> test_033 (main already has test_026_windows_dll_search.py from #735; restores the unique-NNN convention; 027/032 stay reserved for the release slice). - consolidate-conda-artifacts-job.yml: fix stale accounting — the pipeline now cross-builds win-arm64 (py3.12-3.14), so TOTAL is 28, not 25 (only musllinux is excluded now); a release gate keyed to "25 / no win-arm64" would be wrong. - build-conda-packages.sh: make the conda_builder create idempotent (env remove first) so a reused agent/workdir doesn't fail under set -e. - tls_connect_probe.py: neutral "TLS handshake did not complete" wording (an ssl-routines / cert error is not necessarily an unreachable backend); handle MS-ODBCSTR }} escaped braces in _split_top_level.
… idempotent conda_builder, neutral TLS wording + }} brace escaping
…y audit (twin of assert_pe_machine.py); +3 tests
…it (lipo/otool)' claims; osx-arm64 arch is trusted from the universal2 wheel tag (no Mach-O check), real guards are the PE + ELF audits
…ad targetArch param/condition (win-arm64 is distinguished by condaTargetSubdir); 74 probe tests pass
…r + two odbc no-op branches from build-conda-packages.ps1 (dead in the self-contained model; the .sh twin never had them); -27 lines, PS AST clean
Sumit Sarabhai (sumitmsft)
left a comment
There was a problem hiding this comment.
Summary of review (automated pre-review, pending maintainer judgment)
Reviewed the added conda build pipeline and validation tooling for correctness, secret handling, validation-gate coverage, and repository conventions. The tooling is well-structured and high-coverage (ran the 5 new test files: 97 passed, 4 skipped for the optional zstd .conda path). All specifics are left as inline comments.
Requesting changes on two Medium items (inline): the brace-splitter divergence from the shipped connection-string parser in tls_connect_probe.py (connect-string corruption + password fragment in logs), and the non-secret condaTlsProbeConn pipeline parameter. The remaining inline comments are Low-severity suggestions and two questions.
Recommendation: Request Changes
…bloat cleanup Correctness / arch: - audit_bundled_binaries.py: add an ELF e_machine arch gate (linux-64==x86_64, linux-aarch64==aarch64) -- the Linux twin of assert_pe_machine.py; +3 tests. - consolidate-conda-artifacts-job.yml: reconcile the win-arm64 accounting (25->28). - build-conda-packages.sh + conda-build-pipeline.yml: correct the false osx-arm64 "static arm64-slice audit (lipo/otool)" claims (no such check exists) to admit the arm64 slice is trusted from the universal2 wheel tag; real guards are PE + ELF. Hygiene: - rename test_026_driver_load_probe.py -> test_033 (dup with main's test_026). - build-conda-packages.sh: idempotent conda_builder env create (set -e safe). - tls_connect_probe.py: MS-ODBCSTR }} brace escaping in _split_top_level. Bloat removal (ponytail): - drop the YAGNI _DRIVER_LOAD_FAILURE_MARKERS / _OPENSSL_UNREACHABLE_MARKERS tables (describe() decoration only; classifiers use separate positive-marker lists). - remove the dead targetArch param + always-true ne(...,'arm64') condition + args. - remove the vestigial -Package/-DriverCondaDir params + odbc no-op branches from build-conda-packages.ps1. Probe/audit unit tests pass; black clean. Validated on a NonOfficial ADO build run.
…on", }} test, distro-scope doc - assert_pe_machine.py: assert the native binding (mssql_python/ddbc_bindings*.pyd) AND the vendored ODBC driver DLLs are BOTH present, independently (was: >=1 native file) -- win-arm64 skips the runtime import, so this is its presence gate. +2 tests. - driver_load_probe.py: drop "missing companion" from the failure label -- the package is self-contained (vendors the ODBC payload), there is no separate companion. - tests/test_028: add a }} escaped-brace case for _split_top_level (Medium: '}}' is a literal '}' in MS-ODBCSTR, so a value with '}}' + internal ';' must not be mis-split). - audit_bundled_binaries.py: document that the Linux audit validates every DISCOVERED distro/arch dir but does not assert a required distro SET (the wheel is the source of truth), so a wholesale-missing distro is a wheel-build concern, not caught here. 96 probe/audit unit tests pass; black clean.
…CRET variable, not a plaintext queue-time parameter (ADO leaves params unmasked); define condaTlsProbeConn in a variable group/Key Vault, unset = probe skips (Sumit, Medium)
…onn, small fixes - assert_pe_machine.py: assert the native binding (ddbc_bindings*.pyd) AND the vendored ODBC driver DLLs are BOTH present, independently (win-arm64 skips the runtime import, so this is its presence gate); +2 tests. - conda-build-pipeline.yml: source the TLS probe connection string from a SECRET variable (variable group / Key Vault), not a plaintext queue-time parameter that ADO leaves unmasked in the run UI/logs. - driver_load_probe.py: drop "missing companion" from the failure label (self-contained package -- vendors the ODBC payload; there is no separate companion). - tests/test_028: add a }} escaped-brace case for _split_top_level (MS-ODBCSTR: '}}' is a literal '}', so a value with '}}' + internal ';' must not be mis-split). - audit_bundled_binaries.py: document that the Linux audit does not assert a required distro SET (the repackaged wheel is the source of truth). 96 probe/audit unit tests pass; black clean.
213f68b to
6ecbecf
Compare
…rse, shared conda reader, ldd/TLS hardening
Should-fix (before the release pipeline publishes):
- assert_pe_machine.py: the Windows presence gate now requires the CORE driver
(msodbcsql18*.dll) specifically, not just any vendored .dll -- a support-DLL-only
package (e.g. only mssql-auth) with the core driver missing would otherwise pass, and
on win-arm64 (runtime import skipped) this is the sole check. +1 test.
- tls_connect_probe.py: drop the false-positive-prone 18456+'login' arm (a pre-TLS
'Login timeout ... 18456' carries both '18456' and 'login' and would false-pass this
fail-closed gate); keep only the locale-independent SQLSTATE 28000. +2 tests.
- conda-build-pipeline.yml: wire CONDA_TLS_PROBE_REQUIRED via a new enableMandatoryTlsGate
parameter (default off) so the mandatory-TLS mode is turnable-on at release together
with the secret conn -- it was previously set nowhere (the fail-closed mode shipped inert).
- eng/scripts/_conda_pkg.py: extract the shared .conda/zstd/tar + info/index.json reader
used by BOTH audit scripts (was duplicated; pylint R0801) into one sibling module.
Real gaps:
- audit_bundled_binaries.py: parse the openssl range pin properly (operator+version per
clause) so '>=3,<40' no longer false-passes ('<40' merely CONTAINS '<4'), while conda's
canonical '<4.0a0' still passes and a bare '>=3' (no upper) correctly fails. +2 tests.
- build-conda-packages.sh: the ldd reachability gate now clears LD_LIBRARY_PATH (so the
RUNPATH $ORIGIN climb ALONE must reach the prefix -- an ambient LD_LIBRARY_PATH could
otherwise mask a broken RUNPATH) and requires resolution under $PREFIX/lib, not anywhere
under $PREFIX.
Ponytail:
- audit_bundled_binaries.py: drop the RUNPATH canonical-ORDER check (the loader searches
all entries regardless of order; the set-membership check already pins {$ORIGIN, climb}).
- consolidate-conda-artifacts-job.yml: correct the total-count log (25 -> 28).
black + flake8 + bash -n clean; mypy clean on the scripts; 112 probe/audit unit tests pass.
Second slice of the conda onboarding split (#720), after the recipe (#734, merged). Adds the OneBranch conda-build pipeline that runs conda-build against the recipe already on main and produces a consolidated conda/ artifact tree, plus the pure, no-DB validation tooling the pipeline gates on. Pipeline (OneBranchPipelines/): - conda-build-pipeline.yml + the per-platform build/validate step templates (conda-build-validate-step{,-posix}.yml) and the consolidate-artifacts job (win-arm64 py3.12-3.14 included in the accounting). - build-conda-packages.{ps1,sh}: drive conda-build per leg; idempotent builder env (set -e safe). The TLS-probe connection string is sourced from a SECRET variable (variable group / Key Vault) mapped into the step env, never a plaintext queue-time parameter that ADO would leave unmasked in logs. Validation tooling (conda/, eng/scripts/) + pure no-DB tests (tests/test_028-033): - tls_connect_probe.py / driver_load_probe.py: import-time TLS-handshake and driver-load probes. The connection-string splitter honors MS-ODBCSTR }} brace escaping so a braced password is never mis-split at an internal ';'; neutral failure labels for triage. - assert_pe_machine.py: Windows PE machine assert -- verifies the native binding (ddbc_bindings*.pyd) AND the vendored ODBC driver DLLs are both present and match the package arch (win-arm64 skips the runtime import, so this is its presence gate). - audit_bundled_binaries.py: Linux RUNPATH self-containment audit + ELF e_machine arch gate (linux-64==x86_64, linux-aarch64==aarch64). Scope: BUILD pipeline only. The release/publish steps, release-metadata validator, and re-solve drift gate move to a follow-up PR. The osx-arm64 slice is trusted from the universal2 wheel tag (no Mach-O audit is claimed); the enforced arch guards are the PE and ELF checks. The GitHub conda-audit workflow and the product-code changes are separate slices. All probe/audit unit tests pass; black clean. Validated on a NonOfficial ADO build run.
6ecbecf to
ae9e4a6
Compare
Gaurav Sharma (bewithgaurav)
left a comment
There was a problem hiding this comment.
one thought on the two build scripts (build-conda-packages.ps1 + .sh).
they're the same pipeline written twice:
- same 7 steps, same 7 args
- one in powershell, one in bash
- ~440 lines of parallel logic, plus the same comments duplicated on both sides
the reason i'd push on it: they've already drifted.
- step 2 installs conda-build<26 into a dedicated env in the .sh, but into base in the .ps1
- the .sh comment literally explains that base is the thing that goes unsolvable on a 3.14-pinned runner
- so the ps1 is doing what the sh warns against. that's the gap
- two files means every change is a two-file change, and this one already diverged
also a big chunk of the ps1 complexity only exists because the yaml dot-sources it with &:
- the ErrorActionPreference flip, the
2>$null, thecmd /c "exit 0"reset at the end - if the step just ran
python build_conda_packages.py ...as a normal process, it reads the exit code and all of that goes away
suggestion: one build_conda_packages.py orchestrator.
- conda is python and every agent already has a bootstrap interpreter, so it runs everywhere
- the platform-specific bits (installer invocation, qemu vs ToS env, the linux-only reachability + tls gates) are a handful of if branches, not a second 360-line script
- both step templates collapse to one
python ...call too
on effort: this is small.
- the scripts are short and well scoped, and the logic already exists
- it's collapsing two files into one, not writing new pipeline
- only real work is one ADO run to confirm the legs stay green
Sumit Sarabhai (sumitmsft)
left a comment
There was a problem hiding this comment.
Review Summary
- PR intent: Add a standalone conda build pipeline plus build-validation tooling (PE/ELF architecture asserts, bundled-binary audit, and TLS / driver-load reachability probes) for the mssql-python conda packages.
- Scope reviewed: The full PR diff at head SHA
ae9e4a64— the OneBranch conda pipeline YAML + step/job templates, the build scripts (build-conda-packages.ps1/.sh), and the Python validation tooling underconda/andeng/scripts/. - Overall assessment: The build/validation design is careful and largely fail-closed. One Medium pipeline-wiring defect prevents the TLS gate from ever receiving its secret connection string, plus four Low-severity robustness gaps in the audit/probe tooling.
- Overall risk: Medium
- Proposed decision: Request Changes
- Design compliance: Not Applicable (no formal design/ADR governs this tooling)
Findings: 1 Medium, 4 Low — all posted inline.
Recommendation: Request Changes. The Medium (job-level secret never reaches the posix bash: step) should be fixed so the TLS gate actually runs against the intended connection; the four Low items are robustness hardening of the audit/probe tooling.
- tls_connect_probe.py: _split_top_level now models a SINGLE-LEVEL braced value matching the
production parser (connection_string_parser.py::_parse_braced_value) -- an inner `{` is a
literal (not a nested open) and a `{` is only a brace-open at a value's START, so
`Pwd={a{b};Encrypt=no` splits correctly and force_tls no longer emits a duplicate
`encrypt` that mssql_python.connect would reject. (The production parser cannot be imported
here: it pulls in mssql_python -> the native ddbc_bindings extension, which this standalone
probe must stay importable / unit-testable without.)
- audit_bundled_binaries.py::_openssl_range_ok: the upper bound is valid only as an EXCLUSIVE
`<` at numeric release 4.0(.0...) -- `<4`, `<4.0`, `<4.0.0`, `<4.0a0` pass; `<=4`, `<4.1`,
`<4.0.1` (each admitting some openssl 4.x) now correctly FAIL.
- audit_bundled_binaries.py: an unknown `linux-*` subdir with no _SUBDIR_MACHINE mapping now
FAILS CLOSED instead of proceeding with expected_machine=None and silently skipping the ELF
architecture gate.
- _conda_pkg.py::iter_payload_members: a `.conda` missing its pkg-*.tar.zst now RAISES (was a
bare `return` -> silent empty iteration); both audit scripts convert that to a violation.
The Medium (the job-level TLS secret never reaching the posix `bash:` step) is already
resolved: the live Encrypt=yes gate was removed from the build pipeline entirely in the
previous commit (it moves to the release pipeline, where the secret is always present so the
gate is unconditional).
+7 unit tests (119 pass). black + flake8 clean; mypy clean on the scripts.
…d-pipeline live TLS gate, Sumit round-2 hardening
Applies the accumulated review fixes on top of the main merge:
Pipeline:
- build-conda-packages.ps1: build in a dedicated `conda_builder` env (conda-build<26 +
zstandard) instead of `-n base`, matching the .sh -- a base pinned to a python no
conda-build<26 supports (e.g. 3.14) would otherwise be unsolvable.
- conda-build-pipeline.yml: drop the live Encrypt=yes TLS gate (and its enableMandatoryTlsGate
toggle / CONDA_TLS_PROBE_* wiring) from the BUILD pipeline -- it needs a reachable server + a
secret conn, so it moves to the release pipeline (unconditional there). Fixes the linux-64
TLS_PROBE_MISCONFIGURED failure (undefined secret passed through as a literal) and Sumit's
Medium (a job-level secret never reaches the posix bash step without a step-level env:).
Probe/audit hardening (Sumit round 2):
- tls_connect_probe.py: _split_top_level now matches the production _parse_braced_value grammar
(single-level braces; `{` only opens at a value's start), so a braced password with an inner
`{` can no longer yield a duplicate Encrypt.
- audit_bundled_binaries.py: the openssl upper bound is accepted only as an exclusive `<` at
4.0(.0...); an unknown `linux-*` subdir now fails closed instead of skipping the arch gate.
- _conda_pkg.py: iter_payload_members raises on a `.conda` missing its pkg-*.tar.zst payload.
+ unit tests. black + flake8 + pytest (119) + mypy clean.
There was a problem hiding this comment.
🔵 Needs a closer look
It introduces a large, cross-platform build pipeline and new packaging/audit orchestration where correctness depends on environment-specific behavior that requires final human validation.
Review details
Suppressed comments (1)
OneBranchPipelines/scripts/build_conda_packages.py:407
- _is_emulated_cross() currently treats any -arm64/-aarch64 cross on a non-arm host as "emulated" and logs that runtime probes are best-effort under QEMU. That message (and the boolean) is incorrect for win-arm64 and osx-arm64, which are cross-built without QEMU; it can mislead debugging and conflates two different concepts ("target python not executable" vs "qemu emulation"). Restrict this helper to the actual QEMU case (linux-aarch64 on non-arm) so logs/behavior stay accurate.
if target_subdir.endswith(("aarch64", "arm64")) and host not in ("aarch64", "arm64"):
_log(
f"NOTE: emulated CROSS leg (CONDA_SUBDIR={target_subdir} on {host}); runtime driver "
f"probes are best-effort under QEMU binfmt, build/audit/import remain blocking."
)
- Files reviewed: 16/16 changed files
- Comments generated: 3
- Review effort level: Lite
Restrict emulated best-effort probe behavior to linux-aarch64 on non-Arm hosts, declare and diagnose the zstandard test dependency, and correct per-leg Miniforge/cross-build documentation. Add regressions proving Windows and macOS cross probes remain blocking when executable, QEMU classification is Linux-only, and .conda audit tests cannot silently skip for a missing backend.
There was a problem hiding this comment.
🔵 Needs a closer look
It introduces substantial new pipeline infrastructure plus new cross-platform packaging/audit logic that warrants final human validation in the target CI/CD environment before approval.
Review details
- Files reviewed: 16/17 changed files
- Comments generated: 1
- Review effort level: Lite
Wrap any fallback zstandard ImportError with actionable guidance while preserving the original cause. Add regressions for absent, unloadable, and corrupt zstd backends so decompression errors remain distinct.
There was a problem hiding this comment.
🔵 Needs a closer look
It introduces substantial new cross-platform pipeline/build-validation logic where correctness depends on Azure DevOps runtime behavior and multi-OS edge cases that warrant final human verification.
Review details
Suppressed comments (2)
Previously missed (2) — in code that hasn't changed since the last review.
OneBranchPipelines/conda-build-pipeline.yml:346
- The consolidation stage is described as best-effort, but without an explicit stage condition it won’t run if any of the upstream Conda stages fail (default stage condition is
succeeded()). That prevents collecting partial outputs for diagnosis and contradicts the template’s “never hard-fails” consolidation intent.
Set the stage condition to succeededOrFailed() (or always()) so consolidation still runs and publishes whatever conda artifacts exist.
OneBranchPipelines/jobs/consolidate-conda-artifacts-job.yml:48
- This job is intended to be best-effort (“never hard-fails on a short set”), but
condition: succeeded()will skip it when any dependency fails, so you lose consolidation output/logs exactly when they’re most needed.
Use succeededOrFailed() (or always()) so the job still consolidates and publishes whatever artifacts are available.
- Files reviewed: 16/17 changed files
- Comments generated: 0 new
- Review effort level: Lite
Run consolidation after failed producer stages while honoring cancellation, and make Windows, macOS, and Linux producer stages independent so one platform failure cannot skip the others. Add a regression for the full producer fan-out and consolidation fan-in graph, including stage and reusable job conditions.
There was a problem hiding this comment.
🔵 Needs a closer look
It introduces a large amount of new CI/pipeline and packaging/audit logic across multiple platforms/architectures that warrants final human review of end-to-end behavior in the target build environment.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
OneBranchPipelines/scripts/build_conda_packages.py:71
run_captureis typed as returning a baretuple, which loses the (rc, output) contract and makes type checking less effective (mypy is part of the repo tooling). Consider annotating the return astuple[int, str]to match how callers unpack it.
- Files reviewed: 16/17 changed files
- Comments generated: 0 new
- Review effort level: Lite
Gaurav Sharma (bewithgaurav)
left a comment
There was a problem hiding this comment.
went through the conda build pipeline and validation tooling. the overall approach looks good and the earlier review feedback is addressed. one test issue remains inline, so requesting changes on that.
Gaurav Sharma (bewithgaurav)
left a comment
There was a problem hiding this comment.
on a 2nd review, found 2 more suggestions. both are inline.
the earlier feedback is addressed: the build scripts are consolidated, the linux reachability check remains intact, and osx-arm64 now has a static Mach-O check.
the zstd fallback test remains the merge-blocking issue. these two are smaller fail-closed and partial-diagnostics gaps.
Force the zstandard fallback regression on Python 3.14, reject missing or malformed Linux subdir metadata, preserve staged macOS artifacts after a later failure, and parameterize the new tooling's collection types. Add regressions for the metadata and publication contracts. Validated with the full tooling suite and a real Linux Conda build, clean-prefix install, Driver 18 load, and prefix reachability check.
There was a problem hiding this comment.
🟡 Changes recommended
OneBranchPipelines/conda-build-pipeline.yml has an invalid YAML indentation for demands, which can break the pipeline configuration.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 16/17 changed files
- Comments generated: 3
- Review effort level: Lite
Normalize the Windows OneBranch demand indentation and fail immediately with captured output when prefix discovery, driver location, or dependency listing commands fail. Add regressions for every helper failure, empty prefix output, macOS partial publication, and the exact Windows pool demand structure.
There was a problem hiding this comment.
🟢 Approval recommended
The pipeline/orchestrator flow and the associated audit+test coverage appear consistent and fail-closed where intended, with no confirmed correctness or safety issues found in the reviewed diffs.
Review details
- Files reviewed: 16/17 changed files
- Comments generated: 0 new
- Review effort level: Lite
Gaurav Sharma (bewithgaurav)
left a comment
There was a problem hiding this comment.
re-reviewed the latest changes. the zstd fallback test, fail-closed subdir validation, and partial artifact publishing gaps are fixed.
the additional helper error handling is also in place, and all checks are green. approving.
|
non-blocking I guess - one last thing I noticed before this merges. this pipeline can pick wheels from any successful branch build, not just we already have successful non-main runs in pipeline 2199, so this can happen. can we make
|
Work Item / Issue Reference
Summary
This pull request introduces a new standalone OneBranch pipeline for building, validating, and consolidating self-contained
mssql-pythonconda packages across all supported platforms and Python versions. The pipeline is carefully structured to ensure per-platform correctness, best-effort artifact gathering, and robust isolation between build legs. It also includes a template job for consolidating conda artifacts and a.gitattributesupdate for shell scripts.New Standalone Conda Build Pipeline
Major features and structure:
Adds
conda-build-pipeline.yml: Implements a full multi-stage pipeline that builds and validates self-containedmssql-pythonconda packages for Windows, macOS, and Linux, including cross-platform builds (e.g., win-arm64, osx-arm64, linux-aarch64) using platform-appropriate agents and emulation where needed. Each leg is carefully isolated to prevent failures in one subdir from impacting others, and best-effort logic is used for cross-arch builds.Artifact Consolidation:
consolidate-conda-artifacts-job.yml: Provides a job template that collects all per-platform conda packages into a single artifact, preserving the subdir structure. The consolidation is best-effort in the build pipeline, with hard gating deferred to the release pipeline to avoid blocking primary wheel deliverables.Build and Release Process Improvements
Cross-Platform and Cross-Arch Handling
Repository Hygiene
OneBranchPipelines/scripts/.gitattributesenforcing LF line endings for.shfiles under that folder (the conda recipe scripts are covered separately byconda/.gitattributes).Build-Validation Tooling + Tests
The "build-validation tooling" named in the title -- the exact set of files in this slice:
OneBranchPipelines/scripts/build_conda_packages.py: the single cross-platform orchestrator (gather wheels -> Miniforge/conda-build -> build the self-contained package -> masking-immune audit -> solve a fresh env + import + driver-load + optional reachability gate -> stage). Replaces the former per-OS PowerShell/bash build scripts.OneBranchPipelines/steps/conda-build-validate-step.yml+-posix.yml: the Windows / POSIX step templates that invoke the orchestrator.eng/scripts/audit_bundled_binaries.py,assert_pe_machine.py,assert_macho_arch.py,_conda_pkg.py: masking-immune RUNPATH, ELF/PE/Mach-O architecture, required Linux driver-inventory, and package-reader validation.requirements.txt: declareszstandardso.condapayload tests execute on Python versions without the stdlibcompression.zstdbackend.conda/driver_load_probe.py: the DB-less driver-load proof.tests/test_029_bundled_binary_audit.py,test_030_pe_machine_assert.py,test_033_driver_load_probe.py,test_034_conda_verify_cwd.py,test_035_conda_macho_assert.py: unit coverage for Linux payload completeness/RUNPATH, PE and Mach-O architecture checks, the driver-load probe, neutral-cwd verification, and blocking win-arm64 environment installation.Not in this slice (deliberately): the live
Encrypt=yesTLS gate (conda/tls_connect_probe.pyand itstest_028/test_031) is a release-pipeline concern -- the build pipeline never enables it (no leg setsCONDA_TLS_PROBE_CONN), so it ships with the release slice, not here. The masking-immune static RUNPATH audit already guards the OpenSSL layout at build time.