Add version in __init__.py

Update conda-pack-build.yml
Add create_zip_archive.py
This commit is contained in:
Xuwznln
2025-10-12 20:28:04 +08:00
parent 3d95c9896a
commit 040073f430
4 changed files with 174 additions and 23 deletions

View File

@@ -65,7 +65,7 @@ jobs:
if: steps.should_build.outputs.should_build == 'true'
uses: conda-incubator/setup-miniconda@v3
with:
miniforge-version: latest
miniconda-version: latest
python-version: '3.11.11'
channels: conda-forge,robostack-staging,uni-lab,defaults
channel-priority: strict
@@ -74,16 +74,11 @@ jobs:
auto-update-conda: false
show-channel-urls: true
- name: Install conda-pack
if: steps.should_build.outputs.should_build == 'true'
run: |
conda install -c conda-forge conda-pack -y
- name: Install unilabos and dependencies
- name: Install conda-pack, unilabos and dependencies
if: steps.should_build.outputs.should_build == 'true'
run: |
echo "Installing unilabos and dependencies to unilab environment..."
conda install uni-lab::unilabos -c uni-lab -c robostack-staging -c conda-forge -y
conda install uni-lab::unilabos conda-pack -c uni-lab -c robostack-staging -c conda-forge -y
- name: Get latest ros-humble-unilabos-msgs version
if: steps.should_build.outputs.should_build == 'true'
@@ -231,12 +226,14 @@ jobs:
run: |
echo "=========================================="
if [ "${{ matrix.platform }}" == "win-64" ]; then
echo "Creating Windows ZIP archive..."
echo "Creating Windows ZIP archive (ZIP64 support for large files)..."
echo "Archive: unilab-pack-win-64.zip"
echo "Contents: install_unilab.bat + unilab-env-win-64.tar.gz + extras"
cd dist-package
powershell -Command "Compress-Archive -Path * -DestinationPath ../unilab-pack-${{ matrix.platform }}.zip -Force"
cd ..
echo ""
# Use Python script with ZIP64 support instead of PowerShell Compress-Archive
# PowerShell Compress-Archive has a 2GB limitation
python scripts/create_zip_archive.py dist-package unilab-pack-${{ matrix.platform }}.zip
else
echo "Creating Unix/Linux TAR.GZ archive..."
echo "Archive: unilab-pack-${{ matrix.platform }}.tar.gz"

View File

@@ -0,0 +1,148 @@
#!/usr/bin/env python3
"""
Create ZIP Archive with ZIP64 Support
======================================
This script creates a ZIP archive with ZIP64 support for large files (>2GB).
It's used in the conda-pack build workflow to package the distribution.
PowerShell's Compress-Archive has a 2GB limitation, so we use Python's zipfile
module with allowZip64=True to handle large conda-packed environments.
Usage:
python create_zip_archive.py <source_dir> <output_zip> [--compression-level LEVEL]
Arguments:
source_dir: Directory to compress
output_zip: Output ZIP file path
--compression-level: Compression level (0-9, default: 6)
Example:
python create_zip_archive.py dist-package unilab-pack-win-64.zip
"""
import argparse
import os
import sys
import zipfile
from pathlib import Path
def create_zip_archive(source_dir: str, output_zip: str, compression_level: int = 6) -> bool:
"""
Create a ZIP archive with ZIP64 support.
Args:
source_dir: Directory to compress
output_zip: Output ZIP file path
compression_level: Compression level (0-9)
Returns:
bool: True if successful
"""
try:
source_path = Path(source_dir)
output_path = Path(output_zip)
# Validate source directory
if not source_path.exists():
print(f"Error: Source directory does not exist: {source_dir}", file=sys.stderr)
return False
if not source_path.is_dir():
print(f"Error: Source path is not a directory: {source_dir}", file=sys.stderr)
return False
# Remove existing output file if present
if output_path.exists():
print(f"Removing existing archive: {output_path}")
output_path.unlink()
# Create ZIP archive
print("=" * 70)
print(f"Creating ZIP archive with ZIP64 support")
print(f" Source: {source_path.absolute()}")
print(f" Output: {output_path.absolute()}")
print(f" Compression: Level {compression_level}")
print("=" * 70)
total_size = 0
file_count = 0
with zipfile.ZipFile(
output_path, "w", zipfile.ZIP_DEFLATED, allowZip64=True, compresslevel=compression_level
) as zipf:
# Walk through source directory
for root, dirs, files in os.walk(source_dir):
for file in files:
file_path = os.path.join(root, file)
arcname = os.path.relpath(file_path, source_dir)
file_size = os.path.getsize(file_path)
# Add file to archive
zipf.write(file_path, arcname)
# Display progress
total_size += file_size
file_count += 1
print(f" [{file_count:3d}] Adding: {arcname:50s} {file_size:>15,} bytes")
# Get final archive size
archive_size = output_path.stat().st_size
compression_ratio = (1 - archive_size / total_size) * 100 if total_size > 0 else 0
# Display summary
print("=" * 70)
print("Archive created successfully!")
print(f" Files added: {file_count}")
print(f" Total size (uncompressed): {total_size:>15,} bytes ({total_size / (1024**3):.2f} GB)")
print(f" Archive size (compressed): {archive_size:>15,} bytes ({archive_size / (1024**3):.2f} GB)")
print(f" Compression ratio: {compression_ratio:.1f}%")
print("=" * 70)
return True
except Exception as e:
print(f"Error creating ZIP archive: {e}", file=sys.stderr)
import traceback
traceback.print_exc()
return False
def main():
"""Main entry point."""
parser = argparse.ArgumentParser(
description="Create ZIP archive with ZIP64 support for large files",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
python create_zip_archive.py dist-package unilab-pack-win-64.zip
python create_zip_archive.py dist-package unilab-pack-win-64.zip --compression-level 9
""",
)
parser.add_argument("source_dir", help="Directory to compress")
parser.add_argument("output_zip", help="Output ZIP file path")
parser.add_argument(
"--compression-level",
type=int,
default=6,
choices=range(0, 10),
metavar="LEVEL",
help="Compression level (0=no compression, 9=maximum compression, default=6)",
)
args = parser.parse_args()
# Create archive
success = create_zip_archive(args.source_dir, args.output_zip, args.compression_level)
# Exit with appropriate code
sys.exit(0 if success else 1)
if __name__ == "__main__":
main()

View File

@@ -1,4 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
UniLabOS Installation Verification Script
=========================================
@@ -17,6 +18,10 @@ Usage:
import sys
import importlib
# Use ASCII-safe symbols that work across all platforms
CHECK_MARK = "[OK]"
CROSS_MARK = "[FAIL]"
def check_package(package_name: str, display_name: str = None) -> bool:
"""
@@ -34,10 +39,10 @@ def check_package(package_name: str, display_name: str = None) -> bool:
try:
importlib.import_module(package_name)
print(f" {display_name}")
print(f" {CHECK_MARK} {display_name}")
return True
except ImportError:
print(f" {display_name}")
print(f" {CROSS_MARK} {display_name}")
return False
@@ -47,10 +52,10 @@ def check_python_version() -> bool:
version_str = f"{version.major}.{version.minor}.{version.micro}"
if version.major == 3 and version.minor >= 11:
print(f" Python {version_str}")
print(f" {CHECK_MARK} Python {version_str}")
return True
else:
print(f" Python {version_str} (requires Python 3.8+)")
print(f" {CROSS_MARK} Python {version_str} (requires Python 3.8+)")
return False
@@ -80,23 +85,23 @@ def main():
try:
from unilabos.utils.environment_check import EnvironmentChecker
print(" UniLabOS installed")
print(f" {CHECK_MARK} UniLabOS installed")
checker = EnvironmentChecker()
env_check_passed = checker.check_all_packages()
if env_check_passed:
print(" All required packages available")
print(f" {CHECK_MARK} All required packages available")
else:
print(f" Missing {len(checker.missing_packages)} package(s):")
print(f" {CROSS_MARK} Missing {len(checker.missing_packages)} package(s):")
for import_name, _ in checker.missing_packages:
print(f" - {import_name}")
all_passed = False
except ImportError:
print(" UniLabOS not installed")
print(f" {CROSS_MARK} UniLabOS not installed")
all_passed = False
except Exception as e:
print(f" Environment check failed: {str(e)}")
print(f" {CROSS_MARK} Environment check failed: {str(e)}")
all_passed = False
print()
@@ -106,14 +111,14 @@ def main():
print("=" * 60)
if all_passed:
print("\n All checks passed! Your UniLabOS installation is ready.")
print(f"\n{CHECK_MARK} All checks passed! Your UniLabOS installation is ready.")
print("\nNext steps:")
print(" 1. Review the documentation: docs/user_guide/launch.md")
print(" 2. Try the examples: docs/boot_examples/")
print(" 3. Configure your devices: unilabos_data/startup_config.json")
return 0
else:
print("\n Some checks failed. Please review the errors above.")
print(f"\n{CROSS_MARK} Some checks failed. Please review the errors above.")
print("\nTroubleshooting:")
print(" 1. Ensure you're in the correct conda environment: conda activate unilab")
print(" 2. Check the installation documentation: docs/user_guide/installation.md")

View File

@@ -0,0 +1 @@
__version__ = "0.10.6"