From 1c7b1fd843c8a428901ade1ac034e36f5ed3552d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=BCseyin=20Karakaya?= Date: Sun, 7 Jun 2026 19:08:57 +0300 Subject: [PATCH] feat(release): add CD release pipeline for C++ binaries, PyPI and npm --- .github/workflows/release.yml | 138 ++++++++++++++++++++++++++++++++++ clients/node/README.md | 35 +++++++++ clients/node/index.js | 6 ++ clients/node/package.json | 25 ++++++ clients/python/README.md | 33 ++++++++ clients/python/pyproject.toml | 23 ++++++ 6 files changed, 260 insertions(+) create mode 100644 .github/workflows/release.yml create mode 100644 clients/node/README.md create mode 100644 clients/node/index.js create mode 100644 clients/node/package.json create mode 100644 clients/python/README.md create mode 100644 clients/python/pyproject.toml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..4c1699e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,138 @@ +name: CD / Release + +on: + push: + tags: + - 'v*' + +jobs: + release-cpp: + name: Build & Release C++ Binary + runs-on: ubuntu-24.04 + permissions: + contents: write + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install System Dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + build-essential \ + cmake \ + git \ + python3 \ + python3-pip \ + python3-venv \ + libgrpc++-dev \ + libprotobuf-dev \ + protobuf-compiler \ + protobuf-compiler-grpc + + - name: Set up Python Virtual Environment + run: | + python3 -m venv venv + ./venv/bin/pip install -r generator/requirements.txt + echo "$GITHUB_WORKSPACE/venv/bin" >> $GITHUB_PATH + + - name: Configure and Build (Release Mode) + run: | + cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DMAVLINK_DIALECT=common + cmake --build build -j$(nproc) + + - name: Create Release Tarball + run: | + mkdir -p release_bin + cp build/bridge/mavlink2grpc release_bin/ + tar -czf mavlink2grpc-linux-amd64.tar.gz -C release_bin mavlink2grpc + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + files: mavlink2grpc-linux-amd64.tar.gz + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + publish-python: + name: Publish Python Package to PyPI + runs-on: ubuntu-24.04 + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Python Dependencies + run: | + python3 -m pip install --upgrade pip + python3 -m pip install grpcio-tools build twine + + - name: Generate Protobuf Python Stubs + run: | + # Generate the main common proto files + python3 generator/main.py --dialect common --proto-out proto --cpp-out bridge/src/mavlink + + # Compile the proto files into python package + mkdir -p clients/python/src + python3 -m grpc_tools.protoc \ + --proto_path=proto \ + --python_out=clients/python/src \ + --grpc_python_out=clients/python/src \ + proto/mavlink_bridge.proto proto/mavlink/common.proto + + # Add __init__.py files to make it a package + touch clients/python/src/__init__.py + mkdir -p clients/python/src/mavlink + touch clients/python/src/mavlink/__init__.py + + - name: Build Python Package + run: | + cd clients/python + python3 -m build + + - name: Publish to PyPI + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} + run: | + cd clients/python + python3 -m twine upload dist/* + + publish-node: + name: Publish Node.js Package to npm + runs-on: ubuntu-24.04 + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Generate Protobuf Definition Files + run: | + # Generate proto files + python3 -m pip install -r generator/requirements.txt + python3 generator/main.py --dialect common --proto-out proto --cpp-out bridge/src/mavlink + + # Copy proto files to npm package folder + mkdir -p clients/node/proto/mavlink + cp proto/mavlink_bridge.proto clients/node/proto/ + cp proto/mavlink/*.proto clients/node/proto/mavlink/ + + - name: Publish to npm + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: | + cd clients/node + npm config set //registry.npmjs.org/:_authToken "${NODE_AUTH_TOKEN}" + npm publish --access public diff --git a/clients/node/README.md b/clients/node/README.md new file mode 100644 index 0000000..580a31a --- /dev/null +++ b/clients/node/README.md @@ -0,0 +1,35 @@ +# MAVLink2gRPC Node.js Client Definitions + +This package contains the gRPC Protocol Buffer definition files for communicating with a `MAVLink2gRPC` bridge server. + +## Installation + +```bash +npm install mavlink2grpc-proto +``` + +## Usage + +```javascript +const grpc = require('@grpc/grpc-js'); +const protoLoader = require('@grpc/proto-loader'); +const { protoPath, protoDir } = require('mavlink2grpc-proto'); + +// Load proto definitions +const packageDefinition = protoLoader.loadSync(protoPath, { + keepCase: true, + longs: String, + enums: String, + defaults: true, + oneofs: true, + includeDirs: [protoDir] +}); + +const proto = grpc.loadPackageDefinition(packageDefinition); + +// Connect to the gRPC bridge +const client = new proto.mavlink.MavlinkBridge( + 'localhost:50051', + grpc.credentials.createInsecure() +); +``` diff --git a/clients/node/index.js b/clients/node/index.js new file mode 100644 index 0000000..506df59 --- /dev/null +++ b/clients/node/index.js @@ -0,0 +1,6 @@ +const path = require('path'); + +module.exports = { + protoDir: path.join(__dirname, 'proto'), + protoPath: path.join(__dirname, 'proto', 'mavlink_bridge.proto') +}; diff --git a/clients/node/package.json b/clients/node/package.json new file mode 100644 index 0000000..2b23172 --- /dev/null +++ b/clients/node/package.json @@ -0,0 +1,25 @@ +{ + "name": "mavlink2grpc-proto", + "version": "0.0.1", + "description": "Node.js gRPC Protocol Buffer definitions for MAVLink2gRPC", + "main": "index.js", + "files": [ + "proto", + "index.js", + "README.md" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/Setuav/mavlink2grpc.git" + }, + "keywords": [ + "mavlink", + "grpc", + "protobuf", + "uorb", + "drone", + "px4" + ], + "author": "Hüseyin Karakaya", + "license": "MIT" +} diff --git a/clients/python/README.md b/clients/python/README.md new file mode 100644 index 0000000..705dba7 --- /dev/null +++ b/clients/python/README.md @@ -0,0 +1,33 @@ +# MAVLink2gRPC Python Client Stubs + +This package contains the auto-generated gRPC and Protocol Buffer client stubs for communicating with a `MAVLink2gRPC` bridge server. + +## Installation + +```bash +pip install mavlink2grpc-proto +``` + +## Usage + +```python +import grpc +import mavlink_bridge_pb2 +import mavlink_bridge_pb2_grpc +from mavlink import common_pb2 + +# Connect to the gRPC bridge +channel = grpc.insecure_channel('localhost:50051') +stub = mavlink_bridge_pb2_grpc.MavlinkBridgeStub(channel) + +# Subscribe to HEARTBEAT messages +stream_filter = mavlink_bridge_pb2.StreamFilter( + system_id=0, + component_id=0, + message_ids=[0] # HEARTBEAT message ID is 0 +) + +for message in stub.StreamMessages(stream_filter): + if message.has_heartbeat: + print(f"Received HEARTBEAT: Type {message.heartbeat.type}") +``` diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml new file mode 100644 index 0000000..ba7c9cf --- /dev/null +++ b/clients/python/pyproject.toml @@ -0,0 +1,23 @@ +[build-system] +requires = ["setuptools>=61.0.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "mavlink2grpc-proto" +version = "0.0.1" +description = "Python gRPC stubs for MAVLink2gRPC" +readme = "README.md" +requires-python = ">=3.7" +license = { text = "MIT" } +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", +] +dependencies = [ + "grpcio>=1.30.0", + "protobuf>=4.21.0", +] + +[tool.setuptools.packages.find] +where = ["src"]