Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/hermes-plugin-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ jobs:
os: [ubuntu-24.04, ubuntu-24.04-arm, macos-14, windows-2025]
host: [main]
include:
- os: windows-2025
host: main
hermes_ref: bb706e92c775b6a16765b3249a6fdd0427e7430c
- os: ubuntu-24.04
host: release
python: '3.13'
Expand Down Expand Up @@ -155,6 +158,13 @@ jobs:
HERMES_PYTHON=$(uv run --no-sync python -c 'import sys; print(sys.executable)') \
scripts/run_tests.sh "$GITHUB_WORKSPACE/examples/hermes-plugin/tests" \
--confcutdir="$GITHUB_WORKSPACE/examples/hermes-plugin/tests" -p no:cacheprovider -q
- name: Check real plugin installation on Windows
if: runner.os == 'Windows'
run: |
uv run --no-sync python "$GITHUB_WORKSPACE/scripts/check-hermes-plugin-install.py" \
--hermes-root "$PWD" \
--output-dir "$RUNNER_TEMP/hermes-plugin-install" \
--install-only
- name: Install and run real Quick Local services
run: |
ARGS=()
Expand All @@ -168,4 +178,6 @@ jobs:
path: |
${{ runner.temp }}/quick-local/evidence.json
${{ runner.temp }}/quick-local/*/logs/openviking-server.log
${{ runner.temp }}/hermes-plugin-install/*.log
${{ runner.temp }}/hermes-plugin-install/evidence.json
if-no-files-found: ignore
30 changes: 23 additions & 7 deletions scripts/check-hermes-plugin-install.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#!/usr/bin/env python3
"""Check real Hermes subdirectory installation and dependency admission on POSIX."""
"""Check real Hermes subdirectory installation and optional activation."""

import argparse
import errno
import json
import os
import pty
import select
import signal
import subprocess
Expand All @@ -17,6 +16,8 @@

def enable(command, *, host, env, log, timeout):
"""Give the CLI a terminal and accept consent for this repository's plugin."""
import pty

pid, fd = pty.fork()
if pid == 0:
os.chdir(host)
Expand Down Expand Up @@ -56,7 +57,7 @@ def enable(command, *, host, env, log, timeout):
log.write_bytes(output)


def check(host, repository, root, timeout):
def check(host, repository, root, timeout, *, install_only=False):
home = root / "user" / ".hermes"
home.mkdir(parents=True)
env = {
Expand Down Expand Up @@ -102,10 +103,20 @@ def check(host, repository, root, timeout):
"plugin.yaml",
"pyproject.toml",
):
if (installed / name).read_bytes() != (
if (installed / name).read_text(encoding="utf-8") != (
repository / "examples/hermes-plugin" / name
).read_bytes():
).read_text(encoding="utf-8"):
raise RuntimeError("Installed plugin differs from the checked-out source: " + name)
if install_only:
evidence = {
"installed": True,
"enabled": False,
"home": str(home),
"source_ref": ref,
}
(root / "evidence.json").write_text(json.dumps(evidence, indent=2) + "\n")
print(json.dumps(evidence))
return
enable(command, host=host, env=env, log=root / "enable.log", timeout=timeout)
# PM can retire the original .venv after publishing. Read its selected
# interpreter through the stdlib-only path module before the next command.
Expand Down Expand Up @@ -176,17 +187,22 @@ def main():
parser.add_argument("--repository", type=Path, default=Path(__file__).resolve().parents[1])
parser.add_argument("--output-dir", type=Path, help="Keep the isolated profile and logs here")
parser.add_argument("--timeout", type=int, default=300)
parser.add_argument(
"--install-only",
action="store_true",
help="Stop after validating the installed files; this mode is portable to Windows",
)
args = parser.parse_args()
host, repository = args.hermes_root.resolve(), args.repository.resolve()
if args.output_dir:
root = args.output_dir.resolve()
root.mkdir(parents=True, exist_ok=True)
check(host, repository, root, args.timeout)
check(host, repository, root, args.timeout, install_only=args.install_only)
else:
with tempfile.TemporaryDirectory(prefix="hermes-plugin-install-") as directory:
root = Path(directory)
try:
check(host, repository, root, args.timeout)
check(host, repository, root, args.timeout, install_only=args.install_only)
except Exception:
for name in ("install.log", "enable.log", "validate.log"):
if (root / name).exists():
Expand Down
Loading