diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 4673742..69ee818 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -5,6 +5,41 @@ on: workflow_call: {} jobs: + CheckGeneratedProtobuf: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.10" + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + version: "0.9.15" + python-version: "3.10" + - name: Install protoc 33.2 + run: | + curl --fail --location \ + --output "$RUNNER_TEMP/protoc.zip" \ + https://github.com/protocolbuffers/protobuf/releases/download/v33.2/protoc-33.2-linux-x86_64.zip + unzip "$RUNNER_TEMP/protoc.zip" -d "$RUNNER_TEMP/protoc" + echo "$RUNNER_TEMP/protoc/bin" >> "$GITHUB_PATH" + - name: Install dependencies + run: uv sync --locked --dev + - name: Generate protobuf bindings + run: | + uv run protoc \ + --proto_path=src/wlsonar/range_image_protocol/_proto/ \ + --python_out=src/wlsonar/range_image_protocol/_proto/ \ + --mypy_out=src/wlsonar/range_image_protocol/_proto/ \ + src/wlsonar/range_image_protocol/_proto/WaterLinkedSonarIntegrationProtocol.proto + - name: Check generated protobuf bindings are up to date + run: | + echo "Checking that protobuf generation did not cause a diff." + echo "If this fails, regenerate the bindings before committing." + git diff --exit-code -- src/wlsonar/range_image_protocol/_proto/ + Check: runs-on: ${{ matrix.os }} strategy: diff --git a/README_dev.md b/README_dev.md index cbda7c3..14c1705 100644 --- a/README_dev.md +++ b/README_dev.md @@ -40,7 +40,19 @@ Versioning is handled with `uv`. Setting a new version with `uv version =6.33.2,<7`, meaning the protoc compiler should be 33.2. + +Install 33.2 here: https://github.com/protocolbuffers/protobuf/releases/tag/v33.2 + +There is a pipeline check to assert that the generated code matches the expected protoc version. + +> [!IMPORTANT] +> If the Python library in pyproject.toml is updated, this section should be updated also. + +When changing the .proto file, run the following to generate new Python code: ```bash uv run protoc \ diff --git a/examples/convert_recording.py b/examples/convert_recording.py index e0c27af..802fb97 100644 --- a/examples/convert_recording.py +++ b/examples/convert_recording.py @@ -2,7 +2,7 @@ # requires-python = ">=3.10" # dependencies = [ # "pillow>=12.1.0,<13", -# "wlsonar>=0.5.4,<0.6", +# "wlsonar>=0.5.5,<0.6", # ] # /// """Example use of wlsonar module to convert .sonar recordings to .xyz and .png files.""" diff --git a/examples/imu.py b/examples/imu.py index 4b129c8..1941bc4 100644 --- a/examples/imu.py +++ b/examples/imu.py @@ -1,7 +1,7 @@ # /// script # requires-python = ">=3.10" # dependencies = [ -# "wlsonar>=0.5.4,<0.6", +# "wlsonar>=0.5.5,<0.6", # ] # /// """Example use of wlsonar module: Receive IMU data and print it.""" diff --git a/examples/record_udp_to_file.py b/examples/record_udp_to_file.py index b392902..08ff59d 100644 --- a/examples/record_udp_to_file.py +++ b/examples/record_udp_to_file.py @@ -1,7 +1,7 @@ # /// script # requires-python = ">=3.10" # dependencies = [ -# "wlsonar>=0.5.4,<0.6", +# "wlsonar>=0.5.5,<0.6", # ] # /// """Example use of wlsonar module: Record UDP packets from Sonar 3D-15 to a .sonar file.""" diff --git a/examples/trim_recording.py b/examples/trim_recording.py index ba7f7e7..f9f906f 100644 --- a/examples/trim_recording.py +++ b/examples/trim_recording.py @@ -1,7 +1,7 @@ # /// script # requires-python = ">=3.10" # dependencies = [ -# "wlsonar>=0.5.4,<0.6", +# "wlsonar>=0.5.5,<0.6", # ] # /// """Example use of wlsonar module to trim a .sonar recording by timestamps.""" diff --git a/pyproject.toml b/pyproject.toml index 4f56e48..1f90b4c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "wlsonar" -version = "0.5.4" +version = "0.5.5" description = "Python client and Range Image Protocol utilities for Water Linked Sonar 3D-15." readme = "README.md" authors = [ diff --git a/src/wlsonar/range_image_protocol/_proto/WaterLinkedSonarIntegrationProtocol_pb2.py b/src/wlsonar/range_image_protocol/_proto/WaterLinkedSonarIntegrationProtocol_pb2.py index f08aaa5..baa7bda 100644 --- a/src/wlsonar/range_image_protocol/_proto/WaterLinkedSonarIntegrationProtocol_pb2.py +++ b/src/wlsonar/range_image_protocol/_proto/WaterLinkedSonarIntegrationProtocol_pb2.py @@ -1,11 +1,22 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE # source: WaterLinkedSonarIntegrationProtocol.proto +# Protobuf Python Version: 6.33.2 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 2, + '', + 'WaterLinkedSonarIntegrationProtocol.proto' +) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -20,8 +31,8 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'WaterLinkedSonarIntegrationProtocol_pb2', _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None _globals['_BITMAPIMAGETYPE']._serialized_start=959 _globals['_BITMAPIMAGETYPE']._serialized_end=1021 _globals['_PACKET']._serialized_start=133 diff --git a/tests/test_e2e_real_sonar.py b/tests/test_e2e_real_sonar.py index 87a88d4..a87e91a 100644 --- a/tests/test_e2e_real_sonar.py +++ b/tests/test_e2e_real_sonar.py @@ -1,4 +1,5 @@ from datetime import datetime +from importlib.metadata import version from typing import Literal, cast import pytest @@ -32,6 +33,8 @@ def test_e2e_Sonar3D_client_against_real_sonar(request: pytest.FixtureRequest) - Example use: uv run pytest -s -m e2e --sonar-ip 10.1.2.156 """ + print(f"wlsonar version: {version('wlsonar')}") + sonar_ip = request.config.getoption("--sonar-ip") assert sonar_ip is not None and isinstance(sonar_ip, str), ( "This test requires --sonar-ip to be set." diff --git a/uv.lock b/uv.lock index 04f54e3..60e1a7c 100644 --- a/uv.lock +++ b/uv.lock @@ -224,7 +224,7 @@ name = "exceptiongroup" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [ @@ -634,7 +634,7 @@ wheels = [ [[package]] name = "wlsonar" -version = "0.5.4" +version = "0.5.5" source = { editable = "." } dependencies = [ { name = "protobuf" },