Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.ci
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
BUILD_BACKENDS_PR_NUMBER="395"
15 changes: 0 additions & 15 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,8 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Setup binary permissions
run: chmod a+x artifacts/pixi*

- name: Run integration tests
run: pixi run --locked test-slow
env:
PIXI_BIN_DIR: ${{ github.workspace }}/artifacts
BUILD_BACKENDS_BIN_DIR: ${{ github.workspace }}/artifacts

test-windows-x86_64:
timeout-minutes: 10
Expand Down Expand Up @@ -78,9 +72,6 @@ jobs:
- name: Run integration tests
run: pixi run --locked test-slow
working-directory: ${{ env.PIXI_WORKSPACE }}
env:
PIXI_BIN_DIR: ${{ env.PIXI_WORKSPACE }}/artifacts
BUILD_BACKENDS_BIN_DIR: ${{ env.PIXI_WORKSPACE }}/artifacts

test-macos-aarch64:
timeout-minutes: 10
Expand All @@ -100,11 +91,5 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Setup binary permissions
run: chmod a+x artifacts/pixi*

- name: Run integration tests
run: pixi run --locked test-slow
env:
PIXI_BIN_DIR: ${{ github.workspace }}/artifacts
BUILD_BACKENDS_BIN_DIR: ${{ github.workspace }}/artifacts
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ If you prefer to use local checkouts, create a `.env` file with the paths to you

```shell
PIXI_REPO="/path/to/pixi-repository"
BUILD_BACKENDS_REPO="/path/to/pixi-build-backends-repository"

PIXI_BIN_DIR="${PIXI_REPO}/target/pixi/release"
BUILD_BACKENDS_BIN_DIR="${BUILD_BACKENDS_REPO}/target/pixi/release"

BUILD_BACKENDS_REPO="/path/to/pixi-build-backends-repository"
```

Then build the binaries with:
Expand Down
2 changes: 1 addition & 1 deletion mypy.ini
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[mypy]
strict = True
exclude = tests/data/pypi-indexes
exclude = tests/data/pypi-indexes|.*setup\.py
files = tests,scripts
55 changes: 49 additions & 6 deletions scripts/build-repos.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"""

import os
import shutil
import subprocess
import sys
from pathlib import Path
Expand All @@ -35,14 +36,28 @@ class PixiBuildError(Exception):
pass


class PixiChannelError(Exception):
"""Raised when creating the testsuite channel fails."""

pass


def run_command(
cmd: list[str], cwd: Path | None = None, capture_output: bool = True
cmd: list[str],
cwd: Path | None = None,
capture_output: bool = True,
env: dict[str, str] | None = None,
) -> tuple[int, str, str]:
"""Run a command and return exit code, stdout, and stderr."""
result = subprocess.run(cmd, cwd=cwd, capture_output=capture_output, text=True)
result = subprocess.run(cmd, cwd=cwd, capture_output=capture_output, text=True, env=env)
return result.returncode, result.stdout, result.stderr


def executable_name(base: str) -> str:
"""Return the platform specific executable name."""
return f"{base}.exe" if sys.platform.startswith("win") else base


def is_git_worktree(path: Path) -> bool:
"""Check if the given path is inside a git work tree (repo or worktree)."""
if not path.exists() or not path.is_dir():
Expand Down Expand Up @@ -89,6 +104,34 @@ def build_executables(repo_path: Path) -> None:
raise PixiBuildError(error_msg)


def create_channel(repo_path: Path, project_root: Path) -> None:
"""Create the local testsuite channel and move it into this repository."""
channel_source = repo_path / "artifacts-channel"

if channel_source.exists():
print("🧹 Removing existing channel directory before rebuilding")
shutil.rmtree(channel_source)

print("📦 Creating channel")
returncode, stdout, stderr = run_command(["pixi", "run", "create-channel"], cwd=repo_path)

if returncode != 0:
error_msg = "Failed to create testsuite channel"
if stderr:
error_msg += f": {stderr}"
if stdout:
error_msg += f" (Output: {stdout})"
raise PixiChannelError(error_msg)

if not channel_source.exists():
raise PixiChannelError(
f"Expected channel directory '{channel_source}' was not created. "
"Verify that 'pixi run create-channel' completed successfully."
)

print("✅ Testsuite channel ready at source repo")


def process_repository(repo_path: Path, repo_name: str) -> None:
"""Process a single repository: verify, pull if on main, and build."""
print(f"\n{'=' * 60}")
Expand All @@ -112,14 +155,12 @@ def process_repository(repo_path: Path, repo_name: str) -> None:
else:
print("⚠️ Could not determine current branch")

# Run pixi build
build_executables(repo_path)


def main() -> None:
"""Main function to process repositories."""
# Load environment variables from .env file
env_file = Path(__file__).parent.parent / ".env"
project_root = Path(__file__).parent.parent
env_file = project_root / ".env"
if env_file.exists():
load_dotenv(env_file, override=True)
print(f"✅ Loaded environment variables from {env_file}")
Expand Down Expand Up @@ -150,12 +191,14 @@ def main() -> None:

try:
process_repository(pixi_repo_path, "PIXI_REPO")
build_executables(pixi_repo_path)
except Exception as e:
print(f"❌ Error processing PIXI_REPO: {e}")
success = False

try:
process_repository(build_backends_repo_path, "BUILD_BACKENDS_REPO")
create_channel(build_backends_repo_path, project_root)
except Exception as e:
print(f"❌ Error processing BUILD_BACKENDS_REPO: {e}")
success = False
Expand Down
53 changes: 16 additions & 37 deletions scripts/download-artifacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,48 +139,27 @@ def download_and_extract_artifact(
console.print(f"[green]Successfully downloaded pixi binary to: {final_path}")

elif repo == "prefix-dev/pixi-build-backends":
# Extract all pixi-build-* executables
backend_executables = []
is_windows = sys.platform.startswith("win")

# Find the pixi binary
some_repodata_file = None
for file_name in file_list:
base_name = Path(file_name).name
if base_name.startswith("pixi-build-"):
# On Windows, expect .exe extension; on others, no extension
if is_windows and base_name.endswith(".exe"):
backend_executables.append(file_name)
elif not is_windows and not base_name.endswith(".exe") and "." not in base_name:
backend_executables.append(file_name)

if not backend_executables:
console.print("[red]Could not find any pixi-build-* executables in archive")
raise FileNotFoundError(
f"Could not find any pixi-build-* executables in archive. Archive contents: {file_list}"
)

console.print(f"[blue]Found {len(backend_executables)} backend executable(s)")

# Extract all executables
for executable in backend_executables:
final_path = output_dir / Path(executable).name
if final_path.exists():
if final_path.is_dir():
shutil.rmtree(final_path)
else:
final_path.unlink()

zip_ref.extract(executable, output_dir)
extracted_path = output_dir / executable
if file_name.endswith("repodata.json"):
some_repodata_file = True
break

if extracted_path != final_path:
extracted_path.rename(final_path)
if not some_repodata_file:
console.print("[red]Could not locate a channel directory inside the artifact.")
raise FileNotFoundError("Could not locate a channel directory inside the artifact.")

# Make executable on Unix systems
if not sys.platform.startswith("win"):
final_path.chmod(0o755)
console.print("[blue]Detected backend channel artifact")
final_channel_path = output_dir / "pixi-build-backends"
if final_channel_path.exists():
console.print(f"[yellow]Removing existing channel at {final_channel_path}")
shutil.rmtree(final_channel_path)

console.print(f"[green]Extracted executable: {final_path}")
final_channel_path.parent.mkdir(parents=True, exist_ok=True)
zip_ref.extractall(final_channel_path)

console.print(f"[green]Channel is ready at: {final_channel_path}")
else:
raise ValueError(f"Unsupported repository: {repo}")

Expand Down
Loading
Loading