Skip to content

Hermes Compat Check #181

Hermes Compat Check

Hermes Compat Check #181

Workflow file for this run

name: Hermes Compat Check
on:
schedule:
- cron: '0 0 * * *' # daily at 08:00 CST
push:
paths:
- 'hermes_lark_streaming/patcher.py'
workflow_dispatch:
permissions:
contents: read
issues: write
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Fetch Hermes sources
run: |
curl -fsSL "https://raw.githubusercontent.com/NousResearch/hermes-agent/main/gateway/run.py" -o hermes_run.py
if [ ! -s hermes_run.py ]; then
echo "::error::Failed to fetch run.py"
exit 1
fi
curl -fsSL "https://raw.githubusercontent.com/NousResearch/hermes-agent/main/cron/scheduler.py" -o hermes_scheduler.py
if [ ! -s hermes_scheduler.py ]; then
echo "::error::Failed to fetch scheduler.py"
exit 1
fi
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Install plugin
run: pip install -e .
- name: Run verify
id: verify
continue-on-error: true
run: |
set +e
python -c "
import pathlib
from hermes_lark_streaming.patcher import Patcher, CronPatcher
p = Patcher(pathlib.Path('hermes_run.py'))
p.verify_target()
cp = CronPatcher(pathlib.Path('hermes_scheduler.py'))
cp.verify_target()
print('Both targets compatible.')
" > /tmp/verify.log 2>&1
code=$?
{
echo "exit=${code}"
if [ -s /tmp/verify.log ]; then
echo "log<<VERIFY_EOF"
cat /tmp/verify.log
echo "VERIFY_EOF"
fi
} >> "$GITHUB_OUTPUT"
- name: Open issue on failure
if: always() && steps.verify.outcome != 'success'
uses: actions/github-script@v7
env:
VERIFY_LOG: ${{ steps.verify.outputs.log }}
with:
script: |
const label = 'hermes-compat';
const title = 'Hermes compatibility check failed';
const log = process.env.VERIFY_LOG || '(no output captured — verify step may have been skipped, e.g. upstream fetch / install failure)';
const run = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`;
const body = `The Hermes compatibility check failed.\n\nPlease check if Hermes has updated function names or injection anchors in \`gateway/run.py\` or \`cron/scheduler.py\`.\n\n<details><summary>verify output</summary>\n\n\`\`\`\n${log}\n\`\`\`\n\n</details>\n\nWorkflow run: ${run}`;
// Ensure label exists
try {
await github.rest.issues.createLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: label,
color: 'e99695',
});
} catch (e) {
// Label already exists, ignore
}
// Only create if no open issue with this label
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: label,
});
if (issues.data.length === 0) {
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title,
body,
labels: [label],
});
}
- name: Fail job on compatibility break
if: always() && steps.verify.outcome != 'success'
run: exit 1