From 4cff820070baf5bc416e298f3bb6198927f928c3 Mon Sep 17 00:00:00 2001 From: Franzz Date: Mon, 14 Sep 2026 23:35:29 +0200 Subject: [PATCH] Check out with git rather than actions/checkout actions/checkout is a JavaScript action, so a host-mode runner needs node on its PATH to run it and fails with "Cannot find: node in PATH" without one. Every step is plain shell now, which needs nothing of the runner beyond git, python3, rsync and curl. The clone is shallow and takes its URL from the live checkout's remote, so there is no URL or token in the workflow. It works because the runner already has to run as the user that owns that checkout. Co-Authored-By: Claude Opus 5 --- .gitea/workflows/deploy.yml | 26 +++++++++++++++++++++++--- README.md | 11 +++++++++-- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index eeedb2a..83742dc 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -7,6 +7,11 @@ # deploy/heos-panel.service for the unit and the one sudoers line the # restart needs. # +# Every step here is plain shell, on purpose. actions/checkout is a +# JavaScript action, and a host-mode runner can only run those if node is +# on its PATH -- swapping the clone below back to `uses: actions/checkout` +# brings back "Cannot find: node in PATH" on a runner without it. +# # DEPLOY_PATH is also where you edit: an rsync --delete lands on top of # whatever is sitting there uncommitted, so commit before you push. @@ -26,13 +31,12 @@ jobs: DEPLOY_PATH: /var/www/html/heos SERVICE: heos-panel PANEL_URL: http://127.0.0.1:5005/ # WEB_PORT in config.py + SRC: src # the clone, inside the workspace steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Check runner tools run: | + command -v git command -v python3 command -v rsync command -v curl @@ -45,10 +49,24 @@ jobs: - name: Check the restart is allowed without a password run: sudo -n systemctl is-active "$SERVICE" || true + # A shallow clone of the pushed branch, taking the remote from the + # live checkout so there is no URL or token written down here. It + # works because the runner runs as the user that owns that checkout, + # which is the same reason it can write to DEPLOY_PATH at all. + - name: Checkout + run: | + rm -rf "$SRC" + git init --quiet "$SRC" + git -C "$SRC" remote add origin "$(git -C "$DEPLOY_PATH" remote get-url origin)" + git -C "$SRC" fetch --quiet --depth 1 origin "${GITHUB_REF_NAME:-main}" + git -C "$SRC" checkout --quiet FETCH_HEAD + git -C "$SRC" --no-pager log -1 --oneline + # A throwaway virtualenv in the workspace: the one under # $DEPLOY_PATH/.venv is what the running panel imports from, and a # test run has no business touching it. - name: Install dependencies + working-directory: src run: | python3 -m venv .venv-ci .venv-ci/bin/pip install --quiet --upgrade pip @@ -57,9 +75,11 @@ jobs: # Runs against the fake HEOS and AVR servers in tests/fakes.py, so it # needs no speakers and touches nothing on the network. - name: Run tests + working-directory: src run: .venv-ci/bin/python -m unittest discover -s tests -t . --verbose - name: Deploy to production + working-directory: src run: | rsync -azc --no-times --delete \ --exclude "/.git/" \ diff --git a/README.md b/README.md index 10c6448..0043c97 100644 --- a/README.md +++ b/README.md @@ -103,8 +103,15 @@ restarts the service and waits for the panel to answer again. It needs a runner **in host mode on the machine that serves the panel**, registered with the label `heos` (`runs-on:` must match, or the job queues -forever), running as the user that owns the directory. Restarting needs -one sudoers line: +forever), running as the user that owns the directory. + +Every step is plain shell. `actions/checkout` is a JavaScript action, and a +host-mode runner can only run those with `node` on its PATH — swapping the +clone back for it brings back `Cannot find: node in PATH`. The clone takes +its URL from the live checkout's own remote, so no URL or token is written +down here. + +Restarting needs one sudoers line: ```bash echo 'franzz ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart heos-panel' \