# runs-on must match the label the runner was registered with -- `heos` # here, the way Livetrail uses `livetrail`. A job asking for a label # nobody offers sits in the queue rather than failing. # # The runner has to be in host mode on the machine that serves the panel: # it updates DEPLOY_PATH and restarts the service, and it must run as the # user that owns that directory. # # DEPLOY_PATH is a git checkout, cloned there ONCE by hand -- see # "Deploying from Gitea" in the README. This workflow only fast-forwards # it, so the remote and whatever credentials reach it are set up a single # time and stay put. # # Every step is plain shell on purpose: actions/checkout is a JavaScript # action, and a host-mode runner can only run those with node on its PATH, # failing with "Cannot find: node in PATH" without one. name: Deploy HEOS panel on: push: branches: - main workflow_dispatch: jobs: deploy: runs-on: heos env: DEPLOY_PATH: /var/www/html/heos SERVICE: heos-panel PANEL_URL: http://127.0.0.1:5005/ # WEB_PORT in config.py steps: - name: Check runner tools run: | command -v git command -v python3 command -v curl - name: Check the deploy path is ready run: | if [ ! -d "$DEPLOY_PATH" ] || [ ! -w "$DEPLOY_PATH" ]; then echo "$DEPLOY_PATH is missing, or not writable by $(id -un)." exit 1 fi if [ ! -d "$DEPLOY_PATH/.git" ]; then echo "$DEPLOY_PATH is not a checkout yet. Once, on this machine," echo "as $(id -un):" echo echo " git clone $DEPLOY_PATH" echo " cd $DEPLOY_PATH" echo " python3 -m venv .venv" echo " .venv/bin/pip install -r requirements.txt" echo " sudo cp deploy/heos-panel.service /etc/systemd/system/" echo " sudo systemctl enable --now $SERVICE" echo echo "Then edit config.py for this house and push again." exit 1 fi - name: Check the restart is allowed without a password run: sudo -n systemctl is-active "$SERVICE" || true - name: Fast-forward the checkout run: | cd "$DEPLOY_PATH" git fetch --prune origin # --ff-only on purpose: if someone has edited a tracked file on the # box without committing it, this stops rather than throwing their # change away. git merge --ff-only "origin/${GITHUB_REF_NAME:-main}" git --no-pager log -1 --oneline - name: Install dependencies run: | cd "$DEPLOY_PATH" test -d .venv || python3 -m venv .venv .venv/bin/pip install --quiet -r requirements.txt # Runs against the fake HEOS and AVR servers in tests/fakes.py, so it # needs no speakers and touches nothing on the network. The new code # is on disk by this point, but the running process is still the old # one: a failure here stops the job before the restart below. - name: Run tests run: | cd "$DEPLOY_PATH" .venv/bin/python -m unittest discover -s tests -t . --verbose - name: Restart run: sudo systemctl restart "$SERVICE" - name: Wait for the panel to answer run: | # The home page renders from config alone, so this proves the app # came back up without waiting on the speakers to reply. for attempt in $(seq 1 20); do if curl -fsS -o /dev/null "$PANEL_URL"; then echo "panel is up after ${attempt}s" exit 0 fi sleep 1 done echo "panel did not come back -- last of its log:" sudo systemctl status "$SERVICE" --no-pager --lines 30 || true exit 1