Deploy the Python MCP host checkout after tests pass.
This commit is contained in:
parent
394c46ebfc
commit
39eb0401d8
3 changed files with 128 additions and 0 deletions
24
.forgejo/workflows/test-and-deploy.yml
Normal file
24
.forgejo/workflows/test-and-deploy.yml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
name: test-and-deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: 138
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Unit tests
|
||||
run: bash scripts/test-138.sh
|
||||
|
||||
deploy-138:
|
||||
needs: test
|
||||
if: success() && github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
|
||||
runs-on: 138
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Deploy the host checkout
|
||||
run: bash scripts/deploy-138.sh
|
||||
99
scripts/deploy-138.sh
Executable file
99
scripts/deploy-138.sh
Executable file
|
|
@ -0,0 +1,99 @@
|
|||
#!/usr/bin/env bash
|
||||
# Test, then replace the Python MCP host checkout on ns1.
|
||||
# Does not restart verae-mcp-timestamping (the live listener is the Go binary),
|
||||
# verae-timestamping-svc, or forgejo-runner, and does not read secret files.
|
||||
set -euo pipefail
|
||||
|
||||
LOCK="${LOCK:-/tmp/verae-mcp-py-deploy.lock}"
|
||||
DEST="${DEST:-/opt/verae/verae-mcp-timestamping-server}"
|
||||
BACKUP_ROOT="${BACKUP_ROOT:-/SSD2/verae-deploy-backups}"
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
SCHEMA_FILE="src/verae_mcp_timestamping_server/metadata_history.py"
|
||||
|
||||
mkdir -p "$(dirname "$LOCK")"
|
||||
exec 9>"$LOCK"
|
||||
if ! flock -w 900 9; then
|
||||
echo "another python mcp deploy holds the lock" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
prepare_cache() {
|
||||
sudo mkdir -p "$BACKUP_ROOT"
|
||||
sudo chmod 1777 "$BACKUP_ROOT"
|
||||
sudo mkdir -p "$BACKUP_ROOT/uv-cache-$USER"
|
||||
sudo chown "$USER:$USER" "$BACKUP_ROOT/uv-cache-$USER"
|
||||
export UV_CACHE_DIR="$BACKUP_ROOT/uv-cache-$USER"
|
||||
export UV_LINK_MODE=copy
|
||||
}
|
||||
|
||||
run_tests() {
|
||||
prepare_cache
|
||||
cd "$ROOT"
|
||||
uv sync --frozen --group dev
|
||||
uv run pytest -q
|
||||
if ! grep -q 'verae-meta-git/1' "$SCHEMA_FILE"; then
|
||||
echo "checkout is missing verae-meta-git/1" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
probe_tree() {
|
||||
local tree="$1"
|
||||
grep -q 'verae-meta-git/1' "$tree/$SCHEMA_FILE"
|
||||
sudo -u verae-mcp env HOME=/var/lib/verae-mcp \
|
||||
"$tree/.venv/bin/python" -c 'import verae_mcp_timestamping_server.metadata_history as m; assert m.SCHEMA == "verae-meta-git/1"'
|
||||
}
|
||||
|
||||
install_tree() {
|
||||
local stage previous ts sha
|
||||
ts="$(date -u +%Y%m%dT%H%M%SZ)"
|
||||
sha="$(git -C "$ROOT" rev-parse HEAD)"
|
||||
stage="$(mktemp -d "$BACKUP_ROOT/py-mcp-stage.XXXXXX")"
|
||||
sudo rsync -a \
|
||||
--exclude '.git/' \
|
||||
--exclude '.venv/' \
|
||||
--exclude '__pycache__/' \
|
||||
--exclude '.pytest_cache/' \
|
||||
--exclude 'debug-trace/' \
|
||||
"$ROOT/" "$stage/"
|
||||
printf '%s\n' "$sha" | sudo tee "$stage/DEPLOYED_SHA" >/dev/null
|
||||
if [[ -d "$DEST/.venv" ]]; then
|
||||
sudo mv "$DEST/.venv" "$stage/.venv"
|
||||
fi
|
||||
sudo chown -R verae-mcp:verae-mcp "$stage"
|
||||
sudo mkdir -p "$BACKUP_ROOT/uv-cache-verae-mcp"
|
||||
sudo chown verae-mcp:verae-mcp "$BACKUP_ROOT/uv-cache-verae-mcp"
|
||||
if ! sudo -u verae-mcp env HOME=/var/lib/verae-mcp UV_CACHE_DIR="$BACKUP_ROOT/uv-cache-verae-mcp" UV_LINK_MODE=copy \
|
||||
uv sync --frozen --group dev --directory "$stage"; then
|
||||
sudo rm -rf "$stage"
|
||||
echo "uv sync failed" >&2
|
||||
return 1
|
||||
fi
|
||||
if ! probe_tree "$stage"; then
|
||||
sudo rm -rf "$stage"
|
||||
echo "staged python checkout failed probe" >&2
|
||||
return 1
|
||||
fi
|
||||
previous=""
|
||||
if [[ -d "$DEST" ]]; then
|
||||
previous="$BACKUP_ROOT/py-mcp-src-${ts}"
|
||||
sudo mv "$DEST" "$previous"
|
||||
fi
|
||||
if ! sudo mv "$stage" "$DEST"; then
|
||||
if [[ -n "$previous" ]]; then
|
||||
sudo mv "$previous" "$DEST"
|
||||
fi
|
||||
echo "could not move the python checkout into place" >&2
|
||||
return 1
|
||||
fi
|
||||
sudo chown -R verae-mcp:verae-mcp "$DEST"
|
||||
echo "deployed ${ts} ${sha} checkout probe ok"
|
||||
}
|
||||
|
||||
run_tests
|
||||
if [[ "${1:-}" == "--test-only" ]]; then
|
||||
echo "tests ok"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
install_tree
|
||||
5
scripts/test-138.sh
Executable file
5
scripts/test-138.sh
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
# Unit-test the Python MCP server. Does not restart a service.
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
exec bash "$ROOT/scripts/deploy-138.sh" --test-only
|
||||
Loading…
Reference in a new issue