Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into export-conda-yaml
Browse files Browse the repository at this point in the history
# Conflicts:
#	.github/workflows/rust.yml
  • Loading branch information
abkfenris committed Sep 17, 2024
2 parents 5053348 + de470e7 commit 7cb1b59
Show file tree
Hide file tree
Showing 16 changed files with 1,124 additions and 223 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -446,3 +446,9 @@ jobs:
needs: export-filter
if: needs.export-filter.outputs.exports == 'true'
uses: ./.github/workflows/test_exports.yml

test_common_wheels:
name: "Test installation of common wheels"
needs:
- build
uses: ./.github/workflows/test_common_wheels.yml
77 changes: 77 additions & 0 deletions .github/workflows/test_common_wheels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: "Test common wheel files for installation with pixi"

on:
workflow_call:

jobs:
test_common_wheels:
name: ${{ matrix.arch.name }} - Test Installation of Common Wheels
runs-on: ${{ matrix.arch.os }}
env:
TARGET_RELEASE: "${{ github.workspace }}/.pixi/target/release"
LOGS_DIR: "${{ github.workspace }}/tests/wheel_tests/.logs"
SUMMARY_FILE: "${{ github.workspace }}/tests/wheel_tests/.summary.md"
PYTHONIOENCODING: utf-8
strategy:
fail-fast: false
matrix:
arch:
# Linux
- {
target: x86_64-unknown-linux-musl,
os: 8core_ubuntu_latest_runner,
name: "Linux",
}
# MacOS
- { target: x86_64-apple-darwin, os: macos-13, name: "MacOS-x86" }
- { target: aarch64-apple-darwin, os: macos-14, name: "MacOS-Arm" } # macOS-14 is the ARM chipset
# Windows
- {
target: x86_64-pc-windows-msvc,
os: windows-latest,
extension: .exe,
name: "Windows",
}
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Download binary from build
uses: actions/download-artifact@v4
with:
name: pixi-${{ matrix.arch.target }}${{ matrix.arch.extension }}
path: pixi_bin
- name: Debug
run: |
pwd
- name: Create Directory and Move Executable to TARGET_RELEASE
if: matrix.arch.name != 'Windows'
run: |
mkdir -p ${{ env.TARGET_RELEASE }}
mv pixi_bin/pixi-${{ matrix.arch.target }} ${{ env.TARGET_RELEASE }}/pixi
chmod a+x ${{ env.TARGET_RELEASE }}/pixi
- name: Create Directory and Move Executable to TARGET_RELEASE
if: matrix.arch.name == 'Windows' && matrix.arch.target == 'x86_64-pc-windows-msvc'
run: |
New-Item -ItemType Directory -Force -Path "${{ env.TARGET_RELEASE }}"
Move-Item -Path "pixi_bin/pixi-${{ matrix.arch.target }}${{ matrix.arch.extension }}" -Destination "${{ env.TARGET_RELEASE }}/pixi.exe"
shell: pwsh
- name: Test common wheels
run: ${{ env.TARGET_RELEASE }}/pixi${{ matrix.arch.extension }} run test-common-wheels-ci
- name: Write .summary.md to Github Summary
if: ${{ matrix.arch.name != 'Windows' && always() }}
shell: bash
run: |
cat ${{ env.SUMMARY_FILE }} >> $GITHUB_STEP_SUMMARY
- name: Write .summary.md to GitHub Summary (Windows)
if: ${{ matrix.arch.name == 'Windows' && always() }}
shell: pwsh
run: |
$resolvedPath = Resolve-Path $env:SUMMARY_FILE
Get-Content $resolvedPath | Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY
- name: Upload Logs
uses: actions/upload-artifact@v4
if: ${{ always() }}
with:
name: wheel-tests-logs-${{ matrix.arch.name }}
include-hidden-files: true
path: ${{ env.LOGS_DIR }}
222 changes: 127 additions & 95 deletions crates/pypi_modifiers/src/pypi_tags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,129 +16,161 @@ pub fn package_name_is_python(record: &rattler_conda_types::PackageName) -> bool
record.as_normalized() == "python"
}

/// Get the python version and implementation name for the specified platform.
pub fn get_pypi_tags(
platform: Platform,
system_requirements: &SystemRequirements,
python_record: &PackageRecord,
) -> miette::Result<Tags> {
let platform = if platform.is_linux() {
let arch = match platform.arch() {
None => unreachable!("every platform we support has an arch"),
Some(Arch::X86) => platform_tags::Arch::X86,
Some(Arch::X86_64) => platform_tags::Arch::X86_64,
Some(Arch::Aarch64 | Arch::Arm64) => platform_tags::Arch::Aarch64,
Some(Arch::ArmV7l) => platform_tags::Arch::Armv7L,
Some(Arch::Ppc64le) => platform_tags::Arch::Powerpc64Le,
Some(Arch::Ppc64) => platform_tags::Arch::Powerpc64,
Some(Arch::S390X) => platform_tags::Arch::S390X,
Some(unsupported_arch) => {
miette::bail!("unsupported arch for pypi packages '{unsupported_arch}'")
}
};
let platform = get_platform_tags(platform, system_requirements)?;
let python_version = get_python_version(python_record)?;
let implementation_name = get_implementation_name(python_record)?;
create_tags(platform, python_version, implementation_name)
}

// Find the glibc version
match system_requirements
.libc
.as_ref()
.map(LibCSystemRequirement::family_and_version)
{
None => {
let (major, minor) = default_glibc_version()
.as_major_minor()
.expect("expected default glibc version to be a major.minor version");
platform_tags::Platform::new(
Os::Manylinux {
major: major as _,
minor: minor as _,
},
arch,
)
}
Some(("glibc", version)) => {
let Some((major, minor)) = version.as_major_minor() else {
miette::bail!(
"expected glibc version to be a major.minor version, but got '{version}'"
)
};
platform_tags::Platform::new(
Os::Manylinux {
major: major as _,
minor: minor as _,
},
arch,
)
}
Some((family, _)) => {
miette::bail!("unsupported libc family for pypi packages '{family}'");
}
}
/// Create a uv platform tag for the specified platform
fn get_platform_tags(
platform: Platform,
system_requirements: &SystemRequirements,
) -> miette::Result<platform_tags::Platform> {
if platform.is_linux() {
get_linux_platform_tags(platform, system_requirements)
} else if platform.is_windows() {
let arch = match platform.arch() {
None => unreachable!("every platform we support has an arch"),
Some(Arch::X86) => platform_tags::Arch::X86,
Some(Arch::X86_64) => platform_tags::Arch::X86_64,
Some(Arch::Aarch64 | Arch::Arm64) => platform_tags::Arch::Aarch64,
Some(unsupported_arch) => {
miette::bail!("unsupported arch for pypi packages '{unsupported_arch}'")
}
};

platform_tags::Platform::new(Os::Windows, arch)
get_windows_platform_tags(platform)
} else if platform.is_osx() {
let osx_version = system_requirements
.macos
.clone()
.unwrap_or_else(|| default_mac_os_version(platform));
let Some((major, minor)) = osx_version.as_major_minor() else {
miette::bail!(
"expected macos version to be a major.minor version, but got '{osx_version}'"
)
};

let arch = match platform.arch() {
None => unreachable!("every platform we support has an arch"),
Some(Arch::X86) => platform_tags::Arch::X86,
Some(Arch::X86_64) => platform_tags::Arch::X86_64,
Some(Arch::Aarch64 | Arch::Arm64) => platform_tags::Arch::Aarch64,
Some(unsupported_arch) => {
miette::bail!("unsupported arch for pypi packages '{unsupported_arch}'")
}
};

platform_tags::Platform::new(
Os::Macos {
major: major as _,
minor: minor as _,
},
arch,
)
get_macos_platform_tags(platform, system_requirements)
} else {
miette::bail!("unsupported platform for pypi packages {platform}")
}
}

/// Get linux specific platform tags
fn get_linux_platform_tags(
platform: Platform,
system_requirements: &SystemRequirements,
) -> miette::Result<platform_tags::Platform> {
let arch = get_arch_tags(platform)?;

// Find the glibc version
match system_requirements
.libc
.as_ref()
.map(LibCSystemRequirement::family_and_version)
{
None => {
let (major, minor) = default_glibc_version()
.as_major_minor()
.expect("expected default glibc version to be a major.minor version");
Ok(platform_tags::Platform::new(
Os::Manylinux {
major: major as _,
minor: minor as _,
},
arch,
))
}
Some(("glibc", version)) => {
let Some((major, minor)) = version.as_major_minor() else {
miette::bail!(
"expected glibc version to be a major.minor version, but got '{version}'"
)
};
Ok(platform_tags::Platform::new(
Os::Manylinux {
major: major as _,
minor: minor as _,
},
arch,
))
}
Some((family, _)) => {
miette::bail!("unsupported libc family for pypi packages '{family}'");
}
}
}

/// Get windows specific platform tags
fn get_windows_platform_tags(platform: Platform) -> miette::Result<platform_tags::Platform> {
let arch = get_arch_tags(platform)?;
Ok(platform_tags::Platform::new(Os::Windows, arch))
}

/// Get macos specific platform tags
fn get_macos_platform_tags(
platform: Platform,
system_requirements: &SystemRequirements,
) -> miette::Result<platform_tags::Platform> {
let osx_version = system_requirements
.macos
.clone()
.unwrap_or_else(|| default_mac_os_version(platform));
let Some((major, minor)) = osx_version.as_major_minor() else {
miette::bail!("expected macos version to be a major.minor version, but got '{osx_version}'")
};

// Build the wheel tags based on the interpreter, the target platform, and the python version.
let arch = get_arch_tags(platform)?;

Ok(platform_tags::Platform::new(
Os::Macos {
major: major as _,
minor: minor as _,
},
arch,
))
}

/// Get the arch tag for the specified platform
fn get_arch_tags(platform: Platform) -> miette::Result<platform_tags::Arch> {
match platform.arch() {
None => unreachable!("every platform we support has an arch"),
Some(Arch::X86) => Ok(platform_tags::Arch::X86),
Some(Arch::X86_64) => Ok(platform_tags::Arch::X86_64),
Some(Arch::Aarch64 | Arch::Arm64) => Ok(platform_tags::Arch::Aarch64),
Some(Arch::ArmV7l) => Ok(platform_tags::Arch::Armv7L),
Some(Arch::Ppc64le) => Ok(platform_tags::Arch::Powerpc64Le),
Some(Arch::Ppc64) => Ok(platform_tags::Arch::Powerpc64),
Some(Arch::S390X) => Ok(platform_tags::Arch::S390X),
Some(unsupported_arch) => {
miette::bail!("unsupported arch for pypi packages '{unsupported_arch}'")
}
}
}

fn get_python_version(python_record: &PackageRecord) -> miette::Result<(u8, u8)> {
let Some(python_version) = python_record.version.as_major_minor() else {
miette::bail!(
"expected python version to be a major.minor version, but got '{}'",
&python_record.version
);
};
let implementation_name = match python_record.name.as_normalized() {
"python" => "cpython",
"pypy" => "pypy",
Ok((python_version.0 as u8, python_version.1 as u8))
}

fn get_implementation_name(python_record: &PackageRecord) -> miette::Result<&'static str> {
match python_record.name.as_normalized() {
"python" => Ok("cpython"),
"pypy" => Ok("pypy"),
_ => {
miette::bail!(
"unsupported python implementation '{}'",
python_record.name.as_source()
);
}
};
}
}

fn create_tags(
platform: platform_tags::Platform,
python_version: (u8, u8),
implementation_name: &str,
) -> miette::Result<Tags> {
// Build the wheel tags based on the interpreter, the target platform, and the python version.
let tags = Tags::from_env(
&platform,
(python_version.0 as u8, python_version.1 as u8),
python_version,
implementation_name,
// TODO: This might not be entirely correct..
(python_version.0 as u8, python_version.1 as u8),
python_version,
true,
// Should revisit this when this lands: https://github.com/conda-forge/python-feedstock/pull/679
false,
Expand Down
Loading

0 comments on commit 7cb1b59

Please sign in to comment.