fix(plugin): bind adapter to real Hermes gateway API; add contract-test gate
- Resolve the Hermes gateway API lazily via get_adapter_class() so the adapter
always inherits the real gateway.platforms.base.BasePlatformAdapter instead
of the ImportError fallback stub (root cause of the AttributeError:
'set_message_handler' crash at gateway startup).
- Pass Platform('meshtastic') enum to super().__init__ and align
connect(*, is_reconnect=False) -> bool with the gateway contract.
- Split pure formatting utils into formatting.py; remove the stub fallback.
- Add tests/contract (L0-L3): real-base binding, ABC instantiation, gateway
run.py wiring replay, signature and event-shape conformance, run against
hermes-agent pinned to the deployed image source (v2026.8.31).
- Add scripts/contract-test.sh and a contract-test CI job; release publish
now requires contract tests to pass.
- Untrack stray __pycache__ artifacts.
This commit is contained in:
@@ -8,8 +8,49 @@ on:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
# Gateway contract gate: the plugin must bind and wire against the REAL
|
||||
# Hermes gateway API (pinned to the deployed image source) before any
|
||||
# release can be built or published. Without this, adapter/API drift used
|
||||
# to surface only as a gateway crash after deploy (the set_message_handler
|
||||
# AttributeError). HERMES_CONTRACT_REQUIRED=1 turns a missing hermes-agent
|
||||
# into a hard failure so this gate can never silently skip.
|
||||
contract-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python 3.13 (matches Hermes image)
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.13'
|
||||
|
||||
- name: Install uv
|
||||
run: pip install uv
|
||||
|
||||
- name: Clone pinned Hermes gateway source (deployed image tag)
|
||||
run: |
|
||||
git clone --depth 1 --branch v2026.8.31 \
|
||||
https://github.com/NousResearch/hermes-agent.git plugin/.hermes-src
|
||||
test "$(git -C plugin/.hermes-src rev-parse HEAD)" = \
|
||||
"29112bef099274229cadff79cdff7bf7b99c4b77"
|
||||
|
||||
- name: Editable install hermes-agent + pytest
|
||||
run: |
|
||||
uv venv --python 3.13 plugin/.venv-contract
|
||||
uv pip install --python plugin/.venv-contract/bin/python -e plugin/.hermes-src
|
||||
uv pip install --python plugin/.venv-contract/bin/python pytest
|
||||
|
||||
- name: Run gateway contract tests
|
||||
env:
|
||||
HERMES_CONTRACT_REQUIRED: '1'
|
||||
run: |
|
||||
cd plugin
|
||||
.venv-contract/bin/python -m pytest tests/contract -q
|
||||
|
||||
test-and-release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: contract-test
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
@@ -40,13 +81,13 @@ jobs:
|
||||
echo "Publishing release for $tag_name"
|
||||
wheel_file=$(ls plugin/dist/*.whl | head -n 1)
|
||||
tar_file=$(ls plugin/dist/*.tar.gz | head -n 1)
|
||||
|
||||
|
||||
# Create release
|
||||
response=$(curl -s -k -X POST "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases" \
|
||||
-H "Authorization: token $GITEA_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"tag_name\": \"$tag_name\", \"name\": \"$tag_name\", \"body\": \"Release $tag_name for hermes-meshtastic plugin\"}")
|
||||
|
||||
|
||||
release_id=$(echo "$response" | grep -o '"id":[0-9]*' | head -n 1 | cut -d: -f2)
|
||||
if [ -n "$release_id" ]; then
|
||||
curl -s -k -X POST "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases/$release_id/assets?name=$(basename $wheel_file)" \
|
||||
|
||||
Reference in New Issue
Block a user