Files
solar-relay/.gitea/workflows/deploy.yml
T
franzz 7cae29f799
Deploy Solar Relay / deploy (push) Failing after 3s
Fix config file folder
2026-11-01 23:18:55 +01:00

104 lines
4.5 KiB
YAML

# Register the Pi runner with the label solar-relay:host.
# Install the systemd unit and the restricted sudoers rule described in README.md once.
name: Deploy Solar Relay
on:
push:
branches:
- main
workflow_dispatch:
jobs:
deploy:
runs-on: solar-relay
env:
DEPLOY_PATH: /var/www/html/solar-relay
SERVICE: solar-relay.service
HEALTH_URL: https://rpioffice.nest.lutran.ch/solar-relay/healthz
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Check runner and deployment setup
shell: bash
run: |
set -euo pipefail
fail() {
printf '::error::%s\n' "$*" >&2
exit 1
}
printf 'Runner account: %s\nDeployment directory: %s\n' "$(id -un)" "$DEPLOY_PATH"
command -v python3
command -v rsync
command -v sudo
command -v systemctl
command -v flock
command -v curl
python3 -c 'import sys, tomllib; assert sys.version_info >= (3, 11)'
test -d "$DEPLOY_PATH" || fail "Deployment directory does not exist: $DEPLOY_PATH"
test -w "$DEPLOY_PATH" || fail "Deployment directory is not writable by $(id -un): $DEPLOY_PATH"
test -r "$DEPLOY_PATH/config.toml" || fail "Config is missing or unreadable by $(id -un): $DEPLOY_PATH/config.toml. Deployment preserves this file; configure it on the Pi."
python3 - <<'PY'
import os
from pathlib import Path
checkout = Path.cwd().resolve()
deployment = Path(os.environ['DEPLOY_PATH']).resolve()
if checkout == deployment or checkout in deployment.parents or deployment in checkout.parents:
raise SystemExit('The runner checkout and deployment directory must not overlap')
PY
test -r /etc/systemd/system/solar-relay.service || fail "Collector service unit is missing. Install deploy/solar-relay.service as /etc/systemd/system/solar-relay.service and run systemctl daemon-reload once."
cmp deploy/solar-relay.service /etc/systemd/system/solar-relay.service || fail "Installed collector unit differs from deploy/solar-relay.service. Install the updated unit and run systemctl daemon-reload."
sudo -n -l "$(command -v systemctl)" restart "$SERVICE" >/dev/null || fail "$(id -un) needs passwordless sudo for $(command -v systemctl) restart $SERVICE."
- name: Create isolated test environment
run: |
python3 -m venv .venv-ci
.venv-ci/bin/python -m pip install --only-binary=pyarrow -r requirements.txt
- name: Run tests
run: .venv-ci/bin/python -m unittest discover -s tests -v
- name: Deploy and restart
shell: bash
run: |
set -euo pipefail
# Also serializes deployments on Gitea versions that lack workflow concurrency.
exec 9>"$DEPLOY_PATH/.deploy.lock"
flock -w 120 9
rsync -azc --no-times --delete \
--exclude '/.git/' \
--exclude '/.gitea/' \
--exclude '/.venv/' \
--exclude '/.venv-ci/' \
--exclude '/.deploy.lock' \
--exclude '/config.toml' \
--exclude '/.env' \
--exclude '/data/' \
--exclude '__pycache__/' \
--exclude '*.parquet' \
./ "$DEPLOY_PATH/"
if [ ! -x "$DEPLOY_PATH/.venv/bin/python" ]; then
python3 -m venv "$DEPLOY_PATH/.venv"
fi
"$DEPLOY_PATH/.venv/bin/python" -c 'import sys; assert sys.version_info >= (3, 11)'
"$DEPLOY_PATH/.venv/bin/python" -m pip install --only-binary=pyarrow -r "$DEPLOY_PATH/requirements.txt"
sudo -n "$(command -v systemctl)" restart "$SERVICE"
# Catch an invalid config or missing token that triggers an immediate restart loop.
sleep 10
if ! systemctl is-active --quiet "$SERVICE"; then
systemctl status "$SERVICE" --no-pager --lines 30 || true
exit 1
fi
if [ "$(systemctl show --property=NRestarts --value "$SERVICE")" != "0" ]; then
echo 'The collector restarted unexpectedly after deployment.'
systemctl status "$SERVICE" --no-pager --lines 30 || true
exit 1
fi
systemctl status "$SERVICE" --no-pager --lines 10
curl --fail --silent --show-error --connect-timeout 3 --max-time 5 \
--retry 4 --retry-delay 2 "$HEALTH_URL"