From e31c924614dd1c12b17ce0f8c02ca5c74c62fb3e Mon Sep 17 00:00:00 2001 From: Xuwznln <18435084+Xuwznln@users.noreply.github.com> Date: Wed, 3 Sep 2025 10:51:34 +0800 Subject: [PATCH 01/14] Update docs --- .github/workflows/docs.yml | 22 +- README.md | 203 +++---------------- docs/development/contributing.rst | 131 +++++------- docs/examples/basic_usage.rst | 327 ++++++++++++------------------ docs/index.rst | 102 +++++----- docs/installation.rst | 97 ++------- docs/quickstart.rst | 138 ------------- setup-dev.ps1 | 69 ------- setup-dev.sh | 52 ----- 9 files changed, 292 insertions(+), 849 deletions(-) delete mode 100644 docs/quickstart.rst delete mode 100644 setup-dev.ps1 delete mode 100644 setup-dev.sh diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index f91f110..d9df9fe 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -5,6 +5,18 @@ on: branches: [main] pull_request: branches: [main] + workflow_dispatch: + inputs: + branch: + description: "要部署文档的分支" + required: false + default: "main" + type: string + deploy_to_pages: + description: "是否部署到 GitHub Pages" + required: false + default: true + type: boolean # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages permissions: @@ -25,6 +37,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.branch || github.ref }} - name: Set up Python uses: actions/setup-python@v5 @@ -42,7 +56,7 @@ jobs: - name: Setup Pages id: pages uses: actions/configure-pages@v4 - if: github.ref == 'refs/heads/main' + if: github.ref == 'refs/heads/main' || (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_to_pages == 'true') - name: Build Sphinx documentation run: | @@ -51,13 +65,13 @@ jobs: - name: Upload artifact uses: actions/upload-pages-artifact@v3 - if: github.ref == 'refs/heads/main' + if: github.ref == 'refs/heads/main' || (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_to_pages == 'true') with: path: docs/_build/html - # Deploy to GitHub Pages (only on main branch) + # Deploy to GitHub Pages deploy: - if: github.ref == 'refs/heads/main' + if: github.ref == 'refs/heads/main' || (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_to_pages == 'true') environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} diff --git a/README.md b/README.md index e1615b1..2155900 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![PyPI version](https://badge.fury.io/py/msgcenterpy.svg)](https://badge.fury.io/py/msgcenterpy) [![Python versions](https://img.shields.io/pypi/pyversions/msgcenterpy.svg)](https://pypi.org/project/msgcenterpy/) -[![Build Status](https://github.com/ZGCA-Forge/MsgCenterPy/workflows/CI/badge.svg)](https://github.com/ZGCA-Forge/MsgCenterPy/actions) +[![Build Status](https://github.com/ZGCA-Forge/MsgCenterPy/actions/workflows/ci.yml/badge.svg)](https://github.com/ZGCA-Forge/MsgCenterPy/actions) [![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-brightgreen)](https://zgca-forge.github.io/MsgCenterPy/) [![GitHub stars](https://img.shields.io/github/stars/ZGCA-Forge/MsgCenterPy.svg?style=social&label=Star)](https://github.com/ZGCA-Forge/MsgCenterPy) @@ -16,47 +16,36 @@ --- -## 🚀 概述 +MsgCenterPy is a multi-format message conversion system based on a unified instance manager architecture, supporting seamless conversion between **ROS2**, **Pydantic**, **Dataclass**, **JSON**, **Dict**, **YAML**, and **JSON Schema**. -MsgCenterPy 是一个基于统一实例管理器架构的多格式消息转换系统,支持 **ROS2**、**Pydantic**、**Dataclass**、**JSON**、**Dict**、**YAML** 和 **JSON Schema** 之间的无缝互转。 +### Supported Formats -### 支持的格式 +| Format | Read | Write | JSON Schema | Type Constraints | +| ----------- | ---- | ----- | ----------- | ---------------- | +| ROS2 | ✅ | ✅ | ✅ | ✅ | +| JSON Schema | ✅ | ✅ | ✅ | ✅ | +| Pydantic | 🚧 | 🚧 | 🚧 | 🚧 | +| Dataclass | 🚧 | 🚧 | 🚧 | 🚧 | +| JSON | 🚧 | 🚧 | 🚧 | 🚧 | +| Dict | 🚧 | 🚧 | 🚧 | 🚧 | +| YAML | 🚧 | 🚧 | 🚧 | 🚧 | -| 格式 | 读取 | 写入 | JSON Schema | 类型约束 | -| ----------- | ------ | ------ | ----------- | -------- | -| ROS2 | ✅ | ✅ | ✅ | ✅ | -| JSON Schema | ✅ | ✅ | ✅ | ✅ | -| Pydantic | 开发中 | 开发中 | 开发中 | 开发中 | -| Dataclass | 开发中 | 开发中 | 开发中 | 开发中 | -| JSON | 开发中 | 开发中 | 开发中 | 开发中 | -| Dict | 开发中 | 开发中 | 开发中 | 开发中 | -| YAML | 开发中 | 开发中 | 开发中 | 开发中 | +## Installation -## 📦 安装 - -### 基础安装 +### Basic Installation ```bash pip install msgcenterpy ``` -### 包含可选依赖 +### With Optional Dependencies ```bash -# 安装 ROS2 支持 -conda install - -# 安装开发工具 -pip install msgcenterpy[dev] - -# 安装文档工具 -pip install msgcenterpy[docs] - -# 安装所有依赖 -pip install msgcenterpy[all] +# Install ROS2 support +conda install ros-humble-ros-core ros-humble-std-msgs ros-humble-geometry-msgs -c robostack-staging ``` -### 从源码安装 +### From Source ```bash git clone https://github.com/ZGCA-Forge/MsgCenterPy.git @@ -64,98 +53,13 @@ cd MsgCenterPy pip install -e .[dev] ``` -## 🔧 快速开始 +## Quick Start -### 基础使用 +Please visit: [https://zgca-forge.github.io/MsgCenterPy/](https://zgca-forge.github.io/MsgCenterPy/) -```python -from msgcenterpy import MessageInstance, MessageType +## Development -# 从字典创建消息实例 -data = { - "name": "sensor_001", - "readings": [1.0, 2.0, 3.0], - "active": True -} -dict_instance = MessageInstance.create(MessageType.DICT, data) - -# 生成 JSON Schema -schema = dict_instance.get_json_schema() -print(schema) -``` - -### ROS2 消息转换 - -```python -from std_msgs.msg import String -from msgcenterpy.instances.ros2_instance import ROS2MessageInstance - -# 创建 ROS2 消息实例 -string_msg = String() -string_msg.data = "Hello ROS2" -ros2_instance = ROS2MessageInstance(string_msg) - -# 转换为 JSON Schema -json_schema_instance = ros2_instance.to_json_schema() - -# 获取生成的 Schema -schema = json_schema_instance.json_schema -print(schema) -``` - -### 字段访问和约束 - -```python -# 动态字段访问 -ros2_instance.data_field = "new_value" -print(ros2_instance.fields.get_field_info("data")) - -# 类型约束验证 -type_info = ros2_instance.fields.get_sub_type_info("data") -print(f"约束条件: {[c.type.value for c in type_info.constraints]}") -``` - -## 📖 文档 - -### 核心概念 - -- **MessageInstance**: 统一消息实例基类 -- **TypeInfo**: 详细的字段类型信息和约束 -- **FieldAccessor**: 统一字段访问接口 -- **MessageCenter**: 消息类型管理和转换中心 - -### API 参考 - -详细的 API 文档请访问:[https://zgca-forge.github.io/MsgCenterPy/](https://zgca-forge.github.io/MsgCenterPy/) - -### 示例代码 - -更多示例请查看 [`examples/`](examples/) 目录: - -- [ROS2 消息转换示例](examples/ros2_example.py) -- [JSON Schema 生成示例](examples/json_schema_example.py) -- [类型约束示例](examples/type_constraints_example.py) - -## 🧪 测试 - -### 运行测试 - -```bash -# 运行所有测试 -python -m pytest - -# 运行特定测试套件 -python run_all_tests.py --type json_schema -``` - -```bash -# 生成覆盖率报告 -pytest --cov=msgcenterpy --cov-report=html -``` - -## 🛠️ 开发 - -### 开发环境设置 +### Development Environment Setup ```bash git clone https://github.com/ZGCA-Forge/MsgCenterPy.git @@ -164,73 +68,16 @@ pip install -e .[dev] pre-commit install ``` -### 代码质量 +For API documentation, please refer to Quick Start -```bash -# 代码格式化 -black msgcenterpy tests -isort msgcenterpy tests +## License -# 类型检查 -mypy msgcenterpy - -# 运行测试 -pytest -``` - -### 贡献指南 - -1. Fork 项目 -2. 创建特性分支 (`git checkout -b feature/AmazingFeature`) -3. 提交变更 (`git commit -m 'Add some AmazingFeature'`) -4. 推送到分支 (`git push origin feature/AmazingFeature`) -5. 创建 Pull Request - -详细贡献指南请查看 [CONTRIBUTING.md](CONTRIBUTING.md) - -## 📊 开发路线图 - -- [x] ✅ ROS2 消息支持 -- [x] ✅ JSON Schema 生成和验证 -- [x] ✅ 统一字段访问器 -- [x] ✅ 类型约束系统 -- [ ] 🔄 Pydantic 集成 -- [ ] 🔄 Dataclass 支持 -- [ ] 🔄 YAML 格式支持 -- [ ] 🔄 性能优化 -- [ ] 🔄 插件系统 - -## 🤝 社区 - -### 支持渠道 - -- 💬 讨论: [GitHub Discussions](https://github.com/ZGCA-Forge/MsgCenterPy/discussions) -- 🐛 问题: [GitHub Issues](https://github.com/ZGCA-Forge/MsgCenterPy/issues) -- 📖 文档: [GitHub Pages](https://zgca-forge.github.io/MsgCenterPy/) - -### 贡献者 - -感谢所有为 MsgCenterPy 做出贡献的开发者! - -[![Contributors](https://contrib.rocks/image?repo=ZGCA-Forge/MsgCenterPy)](https://github.com/ZGCA-Forge/MsgCenterPy/graphs/contributors) - -## 📄 许可证 - -本项目基于 Apache-2.0 许可证开源 - 查看 [LICENSE](LICENSE) 文件了解详情。 - -## 🙏 致谢 - -- [ROS2](https://ros.org/) - 机器人操作系统 -- [Pydantic](https://pydantic-docs.helpmanual.io/) - 数据验证库 -- [pytest](https://pytest.org/) - 测试框架 -- [jsonschema](https://python-jsonschema.readthedocs.io/) - JSON Schema 验证 +This project is licensed under Apache-2.0 License - see the [LICENSE](LICENSE) file for details. ---
-**[⭐ 给个 Star](https://github.com/ZGCA-Forge/MsgCenterPy)** • **[🍴 Fork 项目](https://github.com/ZGCA-Forge/MsgCenterPy/fork)** • **[📖 查看文档](https://zgca-forge.github.io/MsgCenterPy/)** - Made with ❤️ by the MsgCenterPy Team
diff --git a/docs/development/contributing.rst b/docs/development/contributing.rst index a18bf83..c13412d 100644 --- a/docs/development/contributing.rst +++ b/docs/development/contributing.rst @@ -3,98 +3,92 @@ Contributing to MsgCenterPy Thank you for your interest in contributing to MsgCenterPy! This document provides guidelines for contributing to the project. -For detailed contribution guidelines, please see our `Contributing Guide `_ on GitHub. - Quick Links ----------- - `GitHub Repository `_ - `Issue Tracker `_ - `Pull Requests `_ -- `Discussions `_ Development Setup ----------------- 1. Fork the repository on GitHub -2. Clone your fork locally -3. Install in development mode: +2. Clone your fork locally: .. code-block:: bash - git clone https://github.com/YOUR-USERNAME/MsgCenterPy.git + git clone https://github.com/YOUR_USERNAME/MsgCenterPy.git cd MsgCenterPy - pip install -e .[dev] -4. Set up pre-commit hooks: +3. (Optional) If you need ROS2 support, set up ROS environment first: .. code-block:: bash - pre-commit install + # Create and activate conda environment with ROS2 + conda create -n msgcenterpy-dev python=3.11 + conda activate msgcenterpy-dev + conda install ros-humble-ros-core ros-humble-std-msgs ros-humble-geometry-msgs -c robostack-staging + +4. Run the development setup script: + +**Linux/macOS:** + +.. code-block:: bash + + ./scripts/setup-dev.sh + +**Windows:** + +.. code-block:: powershell + + .\scripts\setup-dev.ps1 + +The setup script will automatically: + +- Install the package in development mode with all dependencies +- Set up pre-commit hooks +- Run initial code quality checks +- Display helpful commands for development Code Style and Quality ---------------------- -We use several tools to maintain code quality: +We use automated code quality checks that run via pre-commit hooks: -- **Black**: Code formatting +- **Black**: Code formatting (line length: 120) - **isort**: Import sorting +- **flake8**: Code linting - **mypy**: Type checking -- **pytest**: Testing +- **bandit**: Security scanning +- **prettier**: YAML/JSON formatting -Run quality checks: +These checks run automatically when you commit. You can also run them manually: .. code-block:: bash - # Format code - black msgcenterpy tests - isort msgcenterpy tests - - # Type checking - mypy msgcenterpy - - # Run tests - pytest + # Run all pre-commit hooks + pre-commit run --all-files Testing ------- -Please ensure all tests pass and add tests for new features: +**Important**: Always run tests before committing to ensure your changes work correctly. .. code-block:: bash # Run all tests pytest - # Run with coverage + # Run with verbose output pytest -v - # Run specific test file - pytest tests/test_specific_module.py +**Note**: If ROS2 is not installed, ROS-related tests will be automatically skipped. The test suite is designed to work with or without ROS2 dependencies. Version Management ------------------ -This project uses `bump2version` for semantic version management. The tool is included in development dependencies and automatically manages version numbers across the codebase. - -**Setup** - -bump2version is automatically installed when you install development dependencies: - -.. code-block:: bash - - pip install -e .[dev] - -**Configuration** - -Version configuration is stored in `.bumpversion.cfg`: - -- **Single source of truth**: `msgcenterpy/__init__.py` -- **Auto-commit**: Creates commit with version bump -- **Auto-tag**: Creates git tag for new version -- **Semantic versioning**: Follows MAJOR.MINOR.PATCH format - -**Usage** +This project uses `bump2version` for version management. It's automatically installed with dev dependencies. .. code-block:: bash @@ -107,54 +101,25 @@ Version configuration is stored in `.bumpversion.cfg`: # Breaking changes (0.1.0 → 1.0.0) bump2version major -**Release Workflow** - -1. Make your changes and commit them -2. Choose appropriate version bump type -3. Run bump2version command -4. Push changes and tags: +After bumping version, push changes and tags: .. code-block:: bash git push && git push --tags -**Version Bump Guidelines** - -- **patch**: Bug fixes, documentation updates, internal refactoring -- **minor**: New features, backward-compatible API additions -- **major**: Breaking changes, API removals or modifications - -**Notes** - -- Only developers need bump2version (it's in dev dependencies only) -- Version numbers are automatically synchronized across all files -- Git working directory must be clean before version bump -- Each version bump creates a commit and git tag automatically - Submitting Changes ------------------ 1. Create a new branch for your feature/fix -2. Make your changes -3. Add tests for new functionality -4. Ensure all tests pass -5. Update documentation if needed -6. Submit a pull request - -Pull Request Guidelines ------------------------ - -- Use descriptive titles and descriptions -- Reference related issues -- Include tests for new features -- Update documentation as needed -- Follow the existing code style +2. Make your changes and add tests +3. Run tests to ensure everything works +4. Update documentation if needed +5. Submit a pull request with: + - Descriptive title and description + - Reference to related issues + - Tests for new features Getting Help ------------ -If you need help: - - Check existing `Issues `_ -- Start a `Discussion `_ -- Contact the maintainers diff --git a/docs/examples/basic_usage.rst b/docs/examples/basic_usage.rst index 20f9300..f852cea 100644 --- a/docs/examples/basic_usage.rst +++ b/docs/examples/basic_usage.rst @@ -6,220 +6,161 @@ This page contains basic usage examples to help you get started with MsgCenterPy Creating Message Instances --------------------------- -Dictionary Messages -~~~~~~~~~~~~~~~~~~~ +ROS2 Message Instances +---------------------- -.. code-block:: python - - from msgcenterpy import MessageInstance, MessageType - - # Simple dictionary - simple_data = {"name": "sensor_01", "active": True} - instance = MessageInstance.create(MessageType.DICT, simple_data) - - # Access fields - name = instance.get_field("name") - print(f"Sensor name: {name}") - - # Nested dictionary - nested_data = { - "device": { - "id": "dev_001", - "sensors": [ - {"type": "temperature", "value": 23.5}, - {"type": "humidity", "value": 65.2} - ] - } - } - nested_instance = MessageInstance.create(MessageType.DICT, nested_data) - -JSON Schema Generation -~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: python - - # Generate JSON Schema from dictionary - schema = instance.get_json_schema() - print("Generated Schema:") - print(schema) - - # Schema includes type information - assert schema["type"] == "object" - assert "name" in schema["properties"] - assert schema["properties"]["name"]["type"] == "string" - -Field Access and Manipulation ------------------------------- - -Getting Field Values -~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: python - - # Simple field access - name = instance.get_field("name") - - # Nested field access using dot notation - device_id = nested_instance.get_field("device.id") - temp_value = nested_instance.get_field("device.sensors.0.value") - -Setting Field Values -~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: python - - # Set simple field - instance.set_field("name", "sensor_02") - - # Set nested field - nested_instance.set_field("device.id", "dev_002") - nested_instance.set_field("device.sensors.0.value", 24.1) - -Working with Field Information -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: python - - # Get field type information - field_info = instance.fields.get_field_info("name") - print(f"Field type: {field_info.type}") - print(f"Field constraints: {field_info.constraints}") - - # Check if field exists - if instance.fields.has_field("name"): - print("Field 'name' exists") - -Type Constraints and Validation -------------------------------- - -.. code-block:: python - - from msgcenterpy.core.types import TypeConstraintError - - try: - # This will raise an error if type doesn't match - instance.set_field("active", "not_a_boolean") - except TypeConstraintError as e: - print(f"Type constraint violation: {e}") - - # Type conversion when possible - instance.set_field("name", 123) # Converts to string if allowed - -Message Conversion ------------------- - -Converting Between Formats +Working with ROS2 Messages ~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: python - # Create from dictionary - dict_instance = MessageInstance.create(MessageType.DICT, {"key": "value"}) + from msgcenterpy.instances.ros2_instance import ROS2MessageInstance + from std_msgs.msg import String, Float64MultiArray + from geometry_msgs.msg import Point, Pose - # Convert to JSON Schema instance - schema_instance = dict_instance.to_json_schema() + # Simple String message + string_msg = String() + string_msg.data = "Hello ROS2" + ros2_instance = ROS2MessageInstance(string_msg) - # Get the actual schema - schema = schema_instance.json_schema - print(schema) + # Access and modify field + ros2_instance.data = "Updated message" + print(f"Message data: {ros2_instance.inner_data.data}") -Error Handling --------------- + # Float array message + array_msg = Float64MultiArray() + array_msg.data = [1.1, 2.2, 3.3, 4.4, 5.5] + array_instance = ROS2MessageInstance(array_msg) -Common Error Scenarios -~~~~~~~~~~~~~~~~~~~~~~ + # Complex nested message + pose_msg = Pose() + pose_instance = ROS2MessageInstance(pose_msg) + + # Set nested fields + pose_instance.position.x = 1.5 + pose_instance.position.y = 2.5 + pose_instance.position.z = 3.5 + + # Or set entire object + new_position = Point(x=10.0, y=20.0, z=30.0) + pose_instance.position = new_position + +Converting ROS2 to Python Dictionary +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: python - from msgcenterpy.core.exceptions import FieldAccessError, TypeConstraintError + # Get Python dictionary representation + python_dict = ros2_instance.get_python_dict() + print(f"Dictionary: {python_dict}") - # Field access errors - try: - value = instance.get_field("nonexistent_field") - except FieldAccessError as e: - print(f"Field not found: {e}") + # Set data from dictionary + new_data = {"data": "dictionary_value"} + ros2_instance.set_python_dict(new_data) - # Type constraint errors - try: - instance.set_field("active", "invalid_boolean") - except TypeConstraintError as e: - print(f"Invalid type: {e}") - # Graceful handling - def safe_get_field(instance, field_name, default=None): - try: - return instance.get_field(field_name) - except FieldAccessError: - return default +JSON Schema Message Instances +----------------------------- - # Usage - value = safe_get_field(instance, "optional_field", "default_value") - -Best Practices --------------- - -1. **Always handle exceptions** when accessing fields that might not exist -2. **Use type hints** in your code for better development experience -3. **Validate data** before creating instances when working with external data -4. **Use dot notation** for nested field access instead of manual dictionary traversal -5. **Check field existence** before accessing optional fields - -Complete Example ----------------- - -Here's a complete example that demonstrates multiple features: +Creating JSON Schema Instances +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: python - from msgcenterpy import MessageInstance, MessageType - from msgcenterpy.core.exceptions import FieldAccessError, TypeConstraintError - import json + from msgcenterpy.instances.json_schema_instance import JSONSchemaMessageInstance - def process_sensor_data(sensor_data): - """Process sensor data with proper error handling.""" - try: - # Create instance - instance = MessageInstance.create(MessageType.DICT, sensor_data) - - # Validate required fields - required_fields = ["id", "type", "readings"] - for field in required_fields: - if not instance.fields.has_field(field): - raise ValueError(f"Missing required field: {field}") - - # Process readings - readings = instance.get_field("readings") - if isinstance(readings, list) and len(readings) > 0: - avg_reading = sum(readings) / len(readings) - instance.set_field("average", avg_reading) - - # Generate schema for validation - schema = instance.get_json_schema() - - # Return processed data and schema - return { - "processed_data": instance.to_dict(), - "schema": schema, - "success": True + # Define JSON Schema + schema = { + "type": "object", + "properties": { + "name": {"type": "string", "minLength": 2, "maxLength": 50}, + "age": {"type": "integer", "minimum": 0, "maximum": 150}, + "active": {"type": "boolean"}, + "tags": { + "type": "array", + "items": {"type": "string"}, + "minItems": 1, + "maxItems": 10 } - - except (FieldAccessError, TypeConstraintError, ValueError) as e: - return { - "error": str(e), - "success": False - } - - # Usage - sensor_data = { - "id": "temp_001", - "type": "temperature", - "readings": [23.1, 23.5, 24.0, 23.8], - "unit": "celsius" + }, + "required": ["name"] } - result = process_sensor_data(sensor_data) - if result["success"]: - print("Processing successful!") - print(f"Average reading: {result['processed_data']['average']}") + # Sample data + data = { + "name": "John Doe", + "age": 30, + "active": True, + "tags": ["developer", "python"] + } + + # Create instance + json_schema_instance = JSONSchemaMessageInstance(data, schema) + +Working with JSON Schema Constraints +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + # Get field type information with constraints + name_type_info = json_schema_instance.fields.get_sub_type_info("name") + print(f"Field type: {name_type_info.standard_type}") + print(f"Min length: {name_type_info.get_constraint_value('min_length')}") + + # Check validation errors + if len(json_schema_instance._validation_errors) == 0: + print("Data is valid according to schema") else: - print(f"Processing failed: {result['error']}") + print(f"Validation errors: {json_schema_instance._validation_errors}") + + # Export to envelope format + envelope = json_schema_instance.export_to_envelope() + print(f"Envelope metadata: {envelope['metadata']}") + +Message Type Conversion +----------------------- + +Converting ROS2 to JSON Schema +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + from std_msgs.msg import String + from msgcenterpy.instances.ros2_instance import ROS2MessageInstance + + # Create ROS2 instance + string_msg = String() + string_msg.data = "conversion_test" + ros2_instance = ROS2MessageInstance(string_msg) + + # Convert to JSON Schema instance + json_schema_instance = ros2_instance.to_json_schema() + + # Verify conversion + print(f"Original data: {ros2_instance.get_python_dict()}") + print(f"Converted data: {json_schema_instance.get_python_dict()}") + print(f"Generated schema: {json_schema_instance.json_schema}") + +Generate JSON Schema from ROS2 Message +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + from geometry_msgs.msg import Pose + + # Create complex ROS2 message + pose_msg = Pose() + pose_msg.position.x = 5.0 + pose_msg.position.y = 10.0 + pose_msg.position.z = 15.0 + pose_msg.orientation.w = 1.0 + + ros2_instance = ROS2MessageInstance(pose_msg) + + # Generate JSON Schema + schema = ros2_instance.get_json_schema() + + print("Generated JSON Schema:") + print(f"Type: {schema['type']}") + print(f"Properties: {list(schema['properties'].keys())}") + print(f"Position schema: {schema['properties']['position']}") diff --git a/docs/index.rst b/docs/index.rst index c0a4a12..d1a801c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -13,37 +13,40 @@ Welcome to MsgCenterPy's Documentation! :target: https://pypi.org/project/msgcenterpy/ :alt: Python versions -MsgCenterPy is a unified message conversion system based on unified instance manager architecture, +MsgCenterPy is a multi-format message conversion system based on a unified instance manager architecture, supporting seamless conversion between **ROS2**, **Pydantic**, **Dataclass**, **JSON**, **Dict**, **YAML** and **JSON Schema**. -✨ Key Features +📦 Installation --------------- -🔄 **Unified Conversion**: Supports bidirectional conversion between multiple message formats - -🤖 **ROS2 Integration**: Complete support for ROS2 message types and constraints - -📊 **JSON Schema**: Automatic generation and validation of JSON Schema - -🏗️ **Type Safety**: Strong type constraint system based on TypeInfo - -🔍 **Field Access**: Unified field accessor interface - -⚡ **High Performance**: Optimized conversion algorithms and caching mechanism - -🧪 **Complete Testing**: 47+ test cases with >90% coverage - -📦 Quick Start --------------- - -Installation -~~~~~~~~~~~~ +Basic Installation +~~~~~~~~~~~~~~~~~~~ .. code-block:: bash pip install msgcenterpy +With Optional Dependencies +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: bash + + # Install ROS2 support + conda install ros-humble-ros-core ros-humble-std-msgs ros-humble-geometry-msgs -c robostack-staging + +From Source +~~~~~~~~~~~ + +.. code-block:: bash + + git clone https://github.com/ZGCA-Forge/MsgCenterPy.git + cd MsgCenterPy + pip install -e .[dev] + +🚀 Quick Start +-------------- + Basic Usage ~~~~~~~~~~~ @@ -86,33 +89,41 @@ Basic Usage - ✅ - ✅ * - Pydantic - - 开发中 - - 开发中 - - 开发中 - - 开发中 + - 🚧 + - 🚧 + - 🚧 + - 🚧 * - Dataclass - - 开发中 - - 开发中 - - 开发中 - - 开发中 + - 🚧 + - 🚧 + - 🚧 + - 🚧 * - JSON - - 开发中 - - 开发中 - - ✅ - - ⚡ + - 🚧 + - 🚧 + - 🚧 + - 🚧 * - Dict - - 开发中 - - 开发中 - - ✅ - - ⚡ + - 🚧 + - 🚧 + - 🚧 + - 🚧 * - YAML - - 开发中 - - 开发中 - - ✅ - - ⚡ + - 🚧 + - 🚧 + - 🚧 + - 🚧 .. note:: - ✅ Fully Supported | 开发中 In Development | ⚡ Basic Support + ✅ Fully Supported | 🚧 In Development + +🛠️ Development +-------------- + +Development Environment Setup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For detailed development guidelines, please refer to the Development section. 📚 Documentation Contents ------------------------- @@ -122,7 +133,6 @@ Basic Usage :caption: User Guide installation - quickstart user_guide/index .. toctree:: @@ -168,9 +178,3 @@ Indices and Tables - 📖 **Documentation**: https://zgca-forge.github.io/MsgCenterPy/ - 🐛 **Issues**: https://github.com/ZGCA-Forge/MsgCenterPy/issues -- 💬 **Discussions**: https://github.com/ZGCA-Forge/MsgCenterPy/discussions - -📄 License -========== - -This project is licensed under the Apache-2.0 License - see the `LICENSE `_ file for details. diff --git a/docs/installation.rst b/docs/installation.rst index c3f8fd0..2848c15 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -3,8 +3,8 @@ Installation Guide This guide will help you install MsgCenterPy in different environments. -Quick Installation ------------------- +Basic Installation +------------------- The easiest way to install MsgCenterPy is using pip: @@ -18,96 +18,27 @@ Requirements - Python 3.10 or higher (Python 3.11+ recommended for optimal ROS2 compatibility) - Operating System: Linux, macOS, or Windows -Optional Dependencies ---------------------- +With Optional Dependencies +-------------------------- ROS2 Support ~~~~~~~~~~~~ -To use ROS2 message conversion features: +To use ROS2 message conversion features, install ROS2 packages via conda: .. code-block:: bash - pip install msgcenterpy[ros2] + # Install ROS2 support + conda install ros-humble-ros-core ros-humble-std-msgs ros-humble-geometry-msgs -c robostack-staging -This will install: -- ``rosidl-runtime-py>=0.10.0`` -- ``rclpy>=3.0.0`` +This provides the necessary ROS2 packages for message type conversion and integration. -.. warning:: - **ROS2 Python Version Compatibility Notice** +.. note:: + **ROS2 Installation Notes** - While Python 3.10+ is supported by this package, ROS2 official binary distributions - may have varying support across Python versions. You might need to: - - - Build ROS2 from source for newer Python versions - - Use ROS2 distributions that officially support your Python version - - Consider using conda-forge ROS2 packages if available - - For production environments, verify ROS2 compatibility in your specific setup. - -Development Tools -~~~~~~~~~~~~~~~~~ - -For development and testing: - -.. code-block:: bash - - pip install msgcenterpy[dev] - -This includes: -- ``pytest>=7.0.0`` -- ``black>=22.0.0`` -- ``isort>=5.0.0`` -- ``mypy>=1.0.0`` -- ``pre-commit>=2.20.0`` - -Documentation Tools -~~~~~~~~~~~~~~~~~~~ - -For building documentation: - -.. code-block:: bash - - pip install msgcenterpy[docs] - -All Dependencies -~~~~~~~~~~~~~~~~ - -To install all optional dependencies: - -.. code-block:: bash - - pip install msgcenterpy[all] - -From Source ------------ - -Development Installation -~~~~~~~~~~~~~~~~~~~~~~~~ - -To install from source for development: - -.. code-block:: bash - - git clone https://github.com/ZGCA-Forge/MsgCenterPy.git - cd MsgCenterPy - pip install -e .[dev] - -This will install the package in development mode, allowing you to make changes to the source code. - -Verification ------------- - -To verify your installation: - -.. code-block:: python - - import msgcenterpy - print(msgcenterpy.get_version()) - print(msgcenterpy.check_dependencies()) - -The output should show the version number and available dependencies. + - We recommend using conda with the robostack-staging channel for ROS2 packages + - This approach provides better Python version compatibility + - Alternative ROS2 installation methods are also supported if you have them set up Troubleshooting --------------- @@ -115,7 +46,7 @@ Troubleshooting Common Issues ~~~~~~~~~~~~~ -1. **Python Version**: Ensure you're using Python 3.10 or higher (3.11+ recommended for optimal ROS2 compatibility) +1. **Python Version**: Ensure you're using Python 3.10 or higher (3.11.11 recommended for 0.6.x ROS2 compatibility) 2. **ROS2 Dependencies**: ROS2 support requires a proper ROS2 installation 3. **Virtual Environments**: Consider using virtual environments for isolation diff --git a/docs/quickstart.rst b/docs/quickstart.rst deleted file mode 100644 index 0358981..0000000 --- a/docs/quickstart.rst +++ /dev/null @@ -1,138 +0,0 @@ -Quick Start Guide -================= - -This guide will get you up and running with MsgCenterPy in just a few minutes. - -First Steps ------------ - -After installation, you can start using MsgCenterPy immediately: - -.. code-block:: python - - from msgcenterpy import MessageInstance, MessageType - - # Create a simple message from dictionary - data = {"name": "test", "value": 42} - instance = MessageInstance.create(MessageType.DICT, data) - - # Get JSON Schema - schema = instance.get_json_schema() - print(schema) - -Basic Concepts --------------- - -MessageInstance -~~~~~~~~~~~~~~~ - -The core concept in MsgCenterPy is the ``MessageInstance``, which provides a unified interface for different message formats. - -.. code-block:: python - - from msgcenterpy import MessageInstance, MessageType - - # Different ways to create instances - dict_instance = MessageInstance.create(MessageType.DICT, {"key": "value"}) - - # Access fields - print(dict_instance.get_field("key")) - -MessageType -~~~~~~~~~~~ - -MsgCenterPy supports various message types: - -- ``MessageType.DICT``: Python dictionaries -- ``MessageType.JSON_SCHEMA``: JSON Schema objects -- ``MessageType.ROS2``: ROS2 messages (with optional dependency) - -Working with ROS2 Messages ---------------------------- - -If you have ROS2 installed, you can work with ROS2 messages: - -.. code-block:: python - - from std_msgs.msg import String - from msgcenterpy.instances.ros2_instance import ROS2MessageInstance - - # Create ROS2 message - msg = String() - msg.data = "Hello ROS2" - - # Create instance - ros2_instance = ROS2MessageInstance(msg) - - # Convert to JSON Schema - json_schema_instance = ros2_instance.to_json_schema() - print(json_schema_instance.json_schema) - -JSON Schema Generation ----------------------- - -One of the key features is automatic JSON Schema generation: - -.. code-block:: python - - from msgcenterpy import MessageInstance, MessageType - - # Complex nested structure - data = { - "sensor": { - "name": "temperature_01", - "readings": [23.5, 24.1, 23.8], - "metadata": { - "unit": "celsius", - "precision": 0.1 - } - } - } - - instance = MessageInstance.create(MessageType.DICT, data) - schema = instance.get_json_schema() - - # The schema will include type information for all nested structures - -Field Access and Type Information ----------------------------------- - -MsgCenterPy provides detailed type information and field access: - -.. code-block:: python - - # Access field information - field_info = instance.fields.get_field_info("sensor.name") - print(f"Field type: {field_info.type}") - print(f"Field constraints: {field_info.constraints}") - - # Dynamic field access - instance.set_field("sensor.name", "temperature_02") - value = instance.get_field("sensor.name") - -Error Handling --------------- - -MsgCenterPy includes comprehensive error handling: - -.. code-block:: python - - try: - # Invalid field access - value = instance.get_field("nonexistent.field") - except FieldAccessError as e: - print(f"Field access error: {e}") - - try: - # Type constraint violation - instance.set_field("sensor.readings", "invalid") - except TypeConstraintError as e: - print(f"Type error: {e}") - -Next Steps ----------- - -- Read the :doc:`user_guide/index` for detailed usage -- Check out :doc:`examples/basic_usage` for more examples -- Explore the :doc:`api/core` documentation -- Learn about :doc:`development/contributing` if you want to contribute diff --git a/setup-dev.ps1 b/setup-dev.ps1 deleted file mode 100644 index dac7bdd..0000000 --- a/setup-dev.ps1 +++ /dev/null @@ -1,69 +0,0 @@ -# Development environment setup script for MsgCenterPy (Windows PowerShell) - -Write-Host "🚀 Setting up MsgCenterPy development environment..." -ForegroundColor Green - -# Check if Python is available -try { - $pythonVersion = python --version - Write-Host "✅ Found: $pythonVersion" -ForegroundColor Green -} catch { - Write-Host "❌ Error: Python 3 is required but not found in PATH." -ForegroundColor Red - Write-Host "Please install Python 3.10+ and add it to your PATH." -ForegroundColor Yellow - exit 1 -} - -# Install the package in development mode -Write-Host "📦 Installing package in development mode..." -ForegroundColor Blue -pip install -e .[dev] -if ($LASTEXITCODE -ne 0) { - Write-Host "❌ Failed to install package in development mode" -ForegroundColor Red - exit 1 -} - -# Install pre-commit -Write-Host "🔧 Installing pre-commit..." -ForegroundColor Blue -pip install pre-commit -if ($LASTEXITCODE -ne 0) { - Write-Host "❌ Failed to install pre-commit" -ForegroundColor Red - exit 1 -} - -# Install pre-commit hooks -Write-Host "🪝 Installing pre-commit hooks..." -ForegroundColor Blue -pre-commit install -if ($LASTEXITCODE -ne 0) { - Write-Host "❌ Failed to install pre-commit hooks" -ForegroundColor Red - exit 1 -} - -# Install pre-commit hooks for commit-msg (optional) -Write-Host "📝 Installing commit-msg hooks..." -ForegroundColor Blue -pre-commit install --hook-type commit-msg -if ($LASTEXITCODE -ne 0) { - Write-Host "⚠️ commit-msg hooks installation failed (optional)" -ForegroundColor Yellow -} - -# Run pre-commit on all files to check setup -Write-Host "🔍 Running pre-commit on all files to verify setup..." -ForegroundColor Blue -pre-commit run --all-files -if ($LASTEXITCODE -eq 0) { - Write-Host "✅ Pre-commit setup completed successfully!" -ForegroundColor Green - Write-Host "" - Write-Host "🎉 You're all set! Pre-commit will now run automatically on every commit." -ForegroundColor Green - Write-Host "" - Write-Host "📋 Quick commands:" -ForegroundColor Cyan - Write-Host " • Run all hooks manually: pre-commit run --all-files" -ForegroundColor White - Write-Host " • Update hook versions: pre-commit autoupdate" -ForegroundColor White - Write-Host " • Skip hooks for one commit: git commit --no-verify" -ForegroundColor White - Write-Host " • Run tests: pytest" -ForegroundColor White - Write-Host " • Type checking: mypy msgcenterpy" -ForegroundColor White -} else { - Write-Host "⚠️ Pre-commit found some issues. Please fix them and run 'pre-commit run --all-files' again." -ForegroundColor Yellow - Write-Host "💡 Or use 'pre-commit run --all-files --show-diff-on-failure' to see what needs to be fixed." -ForegroundColor Yellow -} - -Write-Host "" -Write-Host "🔗 Integration with CI:" -ForegroundColor Cyan -Write-Host " • CI will run the same pre-commit hooks" -ForegroundColor White -Write-Host " • If you skip pre-commit locally, CI will catch the issues" -ForegroundColor White -Write-Host " • Best practice: Always let pre-commit fix issues before committing" -ForegroundColor White diff --git a/setup-dev.sh b/setup-dev.sh deleted file mode 100644 index 18717e8..0000000 --- a/setup-dev.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash -# Development environment setup script for MsgCenterPy - -set -e # Exit on any error - -echo "🚀 Setting up MsgCenterPy development environment..." - -# Check if Python is available -if ! command -v python3 &> /dev/null; then - echo "❌ Error: Python 3 is required but not installed." - exit 1 -fi - -# Install the package in development mode -echo "📦 Installing package in development mode..." -pip install -e .[dev] - -# Install pre-commit -echo "🔧 Installing pre-commit..." -pip install pre-commit - -# Install pre-commit hooks -echo "🪝 Installing pre-commit hooks..." -pre-commit install - -# Install pre-commit hooks for commit-msg (optional) -echo "📝 Installing commit-msg hooks..." -pre-commit install --hook-type commit-msg || echo "⚠️ commit-msg hooks installation failed (optional)" - -# Run pre-commit on all files to check setup -echo "🔍 Running pre-commit on all files to verify setup..." -if pre-commit run --all-files; then - echo "✅ Pre-commit setup completed successfully!" - echo "" - echo "🎉 You're all set! Pre-commit will now run automatically on every commit." - echo "" - echo "📋 Quick commands:" - echo " • Run all hooks manually: pre-commit run --all-files" - echo " • Update hook versions: pre-commit autoupdate" - echo " • Skip hooks for one commit: git commit --no-verify" - echo " • Run tests: pytest" - echo " • Type checking: mypy msgcenterpy" -else - echo "⚠️ Pre-commit found some issues. Please fix them and run 'pre-commit run --all-files' again." - echo "💡 Or use 'pre-commit run --all-files --show-diff-on-failure' to see what needs to be fixed." -fi - -echo "" -echo "🔗 Integration with CI:" -echo " • CI will run the same pre-commit hooks" -echo " • If you skip pre-commit locally, CI will catch the issues" -echo " • Best practice: Always let pre-commit fix issues before committing" From 544dbe128fb4275cbba8c55c41d220b45b0bd282 Mon Sep 17 00:00:00 2001 From: Xuwznln <18435084+Xuwznln@users.noreply.github.com> Date: Wed, 3 Sep 2025 11:01:27 +0800 Subject: [PATCH 02/14] Update workflow --- .github/workflows/ci.yml | 10 ++---- .github/workflows/publish.yml | 66 +++++++++++++++++++++++++---------- 2 files changed, 50 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad61cb8..8e9abd6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,12 +58,12 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install flake8 pytest + python -m pip install pytest pip install -e .[dev] - name: Test with pytest run: | - pytest + pytest -v # Step 3: ROS2 integration test test-with-ros2: @@ -122,10 +122,7 @@ jobs: - name: Install security tools run: | python -m pip install --upgrade pip - pip install bandit "safety>=3.0.0" "typer<0.12.0" "marshmallow<4.0.0" - - - name: Run bandit security scan - run: bandit -r msgcenterpy/ -f json -o bandit-report.json + pip install "safety>=3.0.0" "typer<0.12.0" "marshmallow<4.0.0" - name: Run safety security scan run: safety check --output json > safety-report.json @@ -135,7 +132,6 @@ jobs: with: name: security-reports path: | - bandit-report.json safety-report.json if: always() diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index fd6812d..8fa5209 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,7 +6,7 @@ # separate terms of service, privacy policy, and support # documentation. -name: Upload Python Package +name: Upload PyPI package on: release: @@ -23,6 +23,7 @@ permissions: contents: read jobs: + # Step 1: Code formatting and pre-commit validation (fast failure) code-format: name: Code formatting and pre-commit validation runs-on: ubuntu-latest @@ -33,7 +34,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.10" # Use minimum version for consistency - name: Install dependencies run: | @@ -45,15 +46,16 @@ jobs: with: extra_args: --all-files + # Step 2: Basic build and test with minimum Python version (3.10) basic-build: - name: Basic build and test + name: Basic build (Python 3.10, Ubuntu) runs-on: ubuntu-latest - needs: [code-format] + needs: [code-format] # Only run after code formatting passes steps: - uses: actions/checkout@v4 - - name: Set up Python + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: python-version: "3.10" @@ -69,23 +71,18 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install flake8 pytest + python -m pip install pytest pip install -e .[dev] - name: Test with pytest run: | pytest -v - - name: Run linting - run: | - black --check --line-length=120 msgcenterpy tests - isort --check-only msgcenterpy tests - mypy msgcenterpy --disable-error-code=unused-ignore - + # Step 3: ROS2 integration test test-with-ros2: name: ROS2 integration test runs-on: ubuntu-latest - needs: [basic-build] + needs: [basic-build] # Only run after basic build passes steps: - uses: actions/checkout@v4 @@ -105,6 +102,7 @@ jobs: - name: Install ROS2 and dependencies shell: bash -l {0} run: | + # Install ROS2 core packages conda install -y \ ros-humble-ros-core \ ros-humble-std-msgs \ @@ -113,10 +111,43 @@ jobs: - name: Install package and run tests shell: bash -l {0} run: | + # Install our package with basic dependencies (not ros2 extra to avoid conflicts) pip install -e .[dev] + + # Run all tests with verbose output (ROS2 tests will be automatically included) python -c "import rclpy, rosidl_runtime_py; print('All ROS2 dependencies available')" pytest -v + # Step 4: Security scan + security: + name: Security scan + runs-on: ubuntu-latest + needs: [basic-build] # Run in parallel with ROS2 test after basic build + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" # Use minimum version for consistency + + - name: Install security tools + run: | + python -m pip install --upgrade pip + pip install "safety>=3.0.0" "typer<0.12.0" "marshmallow<4.0.0" + + - name: Run safety security scan + run: safety check --output json > safety-report.json + + - name: Upload security reports + uses: actions/upload-artifact@v4 + with: + name: security-reports + path: | + safety-report.json + if: always() + release-build: name: Build release distributions runs-on: ubuntu-latest @@ -125,9 +156,10 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - name: Set up Python + uses: actions/setup-python@v5 with: - python-version: "3.x" + python-version: "3.10" # Use minimum version for consistency - name: Install build dependencies run: | @@ -252,7 +284,3 @@ jobs: echo "| GitHub Release | Assets uploaded |" >> $GITHUB_STEP_SUMMARY echo "| Version | ${{ github.event.release.tag_name || 'test' }} |" >> $GITHUB_STEP_SUMMARY - - - name: Notify team - run: | - echo "Package published successfully!" From 8f3826223f131dd3ebf9dea3581452956d4f4a66 Mon Sep 17 00:00:00 2001 From: Xuwznln <18435084+Xuwznln@users.noreply.github.com> Date: Wed, 3 Sep 2025 11:07:08 +0800 Subject: [PATCH 03/14] Cancel manifest check in publish workflow --- .github/workflows/publish.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8fa5209..6a52e71 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -164,7 +164,7 @@ jobs: - name: Install build dependencies run: | python -m pip install --upgrade pip - python -m pip install build twine check-manifest + python -m pip install build twine - name: Verify version consistency if: github.event_name == 'release' @@ -176,9 +176,6 @@ jobs: exit 1 fi - - name: Check manifest - run: check-manifest - - name: Build release distributions run: | python -m build From dc80e72fbaffa8290c2754e1868b5666fcbe6e64 Mon Sep 17 00:00:00 2001 From: Xuwznln <18435084+Xuwznln@users.noreply.github.com> Date: Wed, 3 Sep 2025 12:42:41 +0800 Subject: [PATCH 04/14] =?UTF-8?q?Bump=20version:=200.0.2=20=E2=86=92=200.0?= =?UTF-8?q?.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- msgcenterpy/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 192a9a0..ca71c0e 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.0.2 +current_version = 0.0.3 commit = True tag = True tag_name = v{new_version} diff --git a/msgcenterpy/__init__.py b/msgcenterpy/__init__.py index a092062..159072b 100644 --- a/msgcenterpy/__init__.py +++ b/msgcenterpy/__init__.py @@ -5,7 +5,7 @@ A multi-format message conversion system supporting seamless conversion between ROS2, Pydantic, Dataclass, JSON, Dict, YAML and JSON Schema. """ -__version__ = "0.0.2" +__version__ = "0.0.3" __license__ = "Apache-2.0" from msgcenterpy.core.envelope import MessageEnvelope, create_envelope From 7d1bc307eecdddc27f8014a4e56bd8c8379e1fc5 Mon Sep 17 00:00:00 2001 From: Xuwznln <18435084+Xuwznln@users.noreply.github.com> Date: Wed, 3 Sep 2025 12:59:22 +0800 Subject: [PATCH 05/14] Update publish.yml --- .github/workflows/publish.yml | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6a52e71..05878cf 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -169,13 +169,31 @@ jobs: - name: Verify version consistency if: github.event_name == 'release' run: | - VERSION=$(python -c "import msgcenterpy; print(msgcenterpy.__version__)" 2>/dev/null || echo "unknown") - TAG_VERSION="${GITHUB_REF#refs/tags/v}" + # Install package first + pip install -e . + + # Get package version (fail fast if not available) + VERSION=$(python -c "import msgcenterpy; print(msgcenterpy.__version__)") + + # Handle both v0.0.3 and 0.0.3 tag formats + RAW_TAG="${GITHUB_REF#refs/tags/}" + if [[ "$RAW_TAG" == v* ]]; then + TAG_VERSION="${RAW_TAG#v}" + else + TAG_VERSION="$RAW_TAG" + fi + + echo "Package version: $VERSION" + echo "Tag version: $TAG_VERSION" + if [ "$VERSION" != "$TAG_VERSION" ]; then - echo "Version mismatch: package=$VERSION, tag=$TAG_VERSION" + echo "❌ Version mismatch: package=$VERSION, tag=$TAG_VERSION" + echo "Please ensure the package version matches the git tag" exit 1 fi + echo "✅ Version verification passed: $VERSION" + - name: Build release distributions run: | python -m build From a871c11df8bf819a36a2f4f3ac22748b09e2c8e6 Mon Sep 17 00:00:00 2001 From: Xuwznln <18435084+Xuwznln@users.noreply.github.com> Date: Wed, 3 Sep 2025 12:59:30 +0800 Subject: [PATCH 06/14] =?UTF-8?q?Bump=20version:=200.0.3=20=E2=86=92=200.0?= =?UTF-8?q?.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- msgcenterpy/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index ca71c0e..858e49c 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.0.3 +current_version = 0.0.4 commit = True tag = True tag_name = v{new_version} diff --git a/msgcenterpy/__init__.py b/msgcenterpy/__init__.py index 159072b..aabd76b 100644 --- a/msgcenterpy/__init__.py +++ b/msgcenterpy/__init__.py @@ -5,7 +5,7 @@ A multi-format message conversion system supporting seamless conversion between ROS2, Pydantic, Dataclass, JSON, Dict, YAML and JSON Schema. """ -__version__ = "0.0.3" +__version__ = "0.0.4" __license__ = "Apache-2.0" from msgcenterpy.core.envelope import MessageEnvelope, create_envelope From 02f321645627cd95190c93b1051cdc7d671e8c64 Mon Sep 17 00:00:00 2001 From: Xuwznln <18435084+Xuwznln@users.noreply.github.com> Date: Wed, 3 Sep 2025 13:04:30 +0800 Subject: [PATCH 07/14] Update publish.yml --- .github/workflows/publish.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 05878cf..ebd9677 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -261,6 +261,8 @@ jobs: runs-on: ubuntu-latest needs: release-build if: github.event_name == 'release' + permissions: + contents: write # Need write access to upload release assets steps: - name: Retrieve release distributions From 502d4c4c0460d8093865403b8a352d431763eac4 Mon Sep 17 00:00:00 2001 From: Xuwznln <18435084+Xuwznln@users.noreply.github.com> Date: Wed, 3 Sep 2025 13:09:03 +0800 Subject: [PATCH 08/14] Update publish.yml --- .github/workflows/publish.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ebd9677..2e8892d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -10,7 +10,7 @@ name: Upload PyPI package on: release: - types: [published] + types: [published, edited] workflow_dispatch: inputs: test_pypi: @@ -167,7 +167,7 @@ jobs: python -m pip install build twine - name: Verify version consistency - if: github.event_name == 'release' + if: github.event_name == 'release' && (github.event.action == 'published' || (github.event.action == 'edited' && !github.event.release.prerelease)) run: | # Install package first pip install -e . @@ -213,7 +213,7 @@ jobs: runs-on: ubuntu-latest needs: - release-build - if: github.event_name == 'release' && !github.event.release.prerelease && github.event.inputs.test_pypi != 'true' + if: github.event_name == 'release' && !github.event.release.prerelease && github.event.inputs.test_pypi != 'true' && (github.event.action == 'published' || github.event.action == 'edited') permissions: # IMPORTANT: this permission is mandatory for trusted publishing id-token: write @@ -236,7 +236,7 @@ jobs: runs-on: ubuntu-latest needs: - release-build - if: github.event.inputs.test_pypi == 'true' || (github.event_name == 'release' && github.event.release.prerelease) + if: github.event.inputs.test_pypi == 'true' || (github.event_name == 'release' && github.event.release.prerelease && (github.event.action == 'published' || github.event.action == 'edited')) permissions: # IMPORTANT: this permission is mandatory for trusted publishing id-token: write @@ -260,7 +260,7 @@ jobs: name: Add assets to GitHub release runs-on: ubuntu-latest needs: release-build - if: github.event_name == 'release' + if: github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'edited') permissions: contents: write # Need write access to upload release assets From 9d6d21de624850bab0bc671ce683402f0671d047 Mon Sep 17 00:00:00 2001 From: Xuwznln <18435084+Xuwznln@users.noreply.github.com> Date: Wed, 3 Sep 2025 13:09:22 +0800 Subject: [PATCH 09/14] =?UTF-8?q?Bump=20version:=200.0.4=20=E2=86=92=200.0?= =?UTF-8?q?.5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- msgcenterpy/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 858e49c..e124335 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.0.4 +current_version = 0.0.5 commit = True tag = True tag_name = v{new_version} diff --git a/msgcenterpy/__init__.py b/msgcenterpy/__init__.py index aabd76b..eef5fec 100644 --- a/msgcenterpy/__init__.py +++ b/msgcenterpy/__init__.py @@ -5,7 +5,7 @@ A multi-format message conversion system supporting seamless conversion between ROS2, Pydantic, Dataclass, JSON, Dict, YAML and JSON Schema. """ -__version__ = "0.0.4" +__version__ = "0.0.5" __license__ = "Apache-2.0" from msgcenterpy.core.envelope import MessageEnvelope, create_envelope From d5704e78c37e81582bc8568f221369c8f2016db5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 05:41:50 +0000 Subject: [PATCH 10/14] ci(deps): bump actions/upload-pages-artifact from 3 to 4 Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 3 to 4. - [Release notes](https://github.com/actions/upload-pages-artifact/releases) - [Commits](https://github.com/actions/upload-pages-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/upload-pages-artifact dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index f91f110..cbe0c3f 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -50,7 +50,7 @@ jobs: make html - name: Upload artifact - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@v4 if: github.ref == 'refs/heads/main' with: path: docs/_build/html From d8070b5e4913b59632b3d79409b4f0cd163bd22c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 05:47:49 +0000 Subject: [PATCH 11/14] ci(deps): bump actions/download-artifact from 4 to 5 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/publish.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index fd6812d..8f25c1f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -176,7 +176,7 @@ jobs: steps: - name: Retrieve release distributions - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: name: release-dists path: dist/ @@ -199,7 +199,7 @@ jobs: steps: - name: Retrieve release distributions - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: name: release-dists path: dist/ @@ -217,7 +217,7 @@ jobs: steps: - name: Retrieve release distributions - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: name: release-dists path: dist/ From 20a904ef8a96711457f55bac2dbab56459a471a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 05:52:50 +0000 Subject: [PATCH 12/14] ci(deps): bump softprops/action-gh-release from 1 to 2 Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 1 to 2. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/v1...v2) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-version: '2' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index fd6812d..c736752 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -223,7 +223,7 @@ jobs: path: dist/ - name: Upload release assets - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: files: dist/* env: From 89169ca7be24a92d9739bf0b5f5441dfc576e465 Mon Sep 17 00:00:00 2001 From: Xuwznln <18435084+Xuwznln@users.noreply.github.com> Date: Fri, 5 Sep 2025 01:22:52 +0800 Subject: [PATCH 13/14] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20PyPI=20=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E9=87=8F=E5=BE=BD=E7=AB=A0=E5=B9=B6=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2155900..eb8b9e4 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![PyPI version](https://badge.fury.io/py/msgcenterpy.svg)](https://badge.fury.io/py/msgcenterpy) [![Python versions](https://img.shields.io/pypi/pyversions/msgcenterpy.svg)](https://pypi.org/project/msgcenterpy/) +[![PyPI downloads](https://img.shields.io/pypi/dm/msgcenterpy.svg)](https://pypi.org/project/msgcenterpy/) [![Build Status](https://github.com/ZGCA-Forge/MsgCenterPy/actions/workflows/ci.yml/badge.svg)](https://github.com/ZGCA-Forge/MsgCenterPy/actions) [![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-brightgreen)](https://zgca-forge.github.io/MsgCenterPy/) @@ -59,7 +60,25 @@ Please visit: [https://zgca-forge.github.io/MsgCenterPy/](https://zgca-forge.git ## Development -### Development Environment Setup +### Quick Development Setup + +For **Linux/macOS**: + +```bash +git clone https://github.com/ZGCA-Forge/MsgCenterPy.git +cd MsgCenterPy +./scripts/setup-dev.sh +``` + +For **Windows**: + +```powershell +git clone https://github.com/ZGCA-Forge/MsgCenterPy.git +cd MsgCenterPy +.\scripts\setup-dev.ps1 +``` + +### Manual Development Setup ```bash git clone https://github.com/ZGCA-Forge/MsgCenterPy.git @@ -70,6 +89,10 @@ pre-commit install For API documentation, please refer to Quick Start +## Star History + +[![Star History Chart](https://api.star-history.com/svg?repos=ZGCA-Forge/MsgCenterPy&type=Date)](https://star-history.com/#ZGCA-Forge/MsgCenterPy&Date) + ## License This project is licensed under Apache-2.0 License - see the [LICENSE](LICENSE) file for details. From 9d52781134cd15568c5b5c4c96af5c19a52a1ddd Mon Sep 17 00:00:00 2001 From: Xuwznln <18435084+Xuwznln@users.noreply.github.com> Date: Fri, 5 Sep 2025 01:23:06 +0800 Subject: [PATCH 14/14] =?UTF-8?q?Bump=20version:=200.0.5=20=E2=86=92=200.0?= =?UTF-8?q?.6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- msgcenterpy/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index e124335..aeb6a67 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.0.5 +current_version = 0.0.6 commit = True tag = True tag_name = v{new_version} diff --git a/msgcenterpy/__init__.py b/msgcenterpy/__init__.py index eef5fec..44457ab 100644 --- a/msgcenterpy/__init__.py +++ b/msgcenterpy/__init__.py @@ -5,7 +5,7 @@ A multi-format message conversion system supporting seamless conversion between ROS2, Pydantic, Dataclass, JSON, Dict, YAML and JSON Schema. """ -__version__ = "0.0.5" +__version__ = "0.0.6" __license__ = "Apache-2.0" from msgcenterpy.core.envelope import MessageEnvelope, create_envelope