+44
-54
@@ -3,17 +3,17 @@
|
||||
# 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 writes into DEPLOY_PATH and restarts the service. See
|
||||
# deploy/heos-panel.service for the unit and the one sudoers line the
|
||||
# restart needs.
|
||||
# it updates DEPLOY_PATH and restarts the service, and it must run as the
|
||||
# user that owns that directory.
|
||||
#
|
||||
# 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 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.
|
||||
#
|
||||
# DEPLOY_PATH is also where you edit: an rsync --delete lands on top of
|
||||
# whatever is sitting there uncommitted, so commit before you push.
|
||||
# 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
|
||||
|
||||
@@ -31,72 +31,62 @@ 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: Check runner tools
|
||||
run: |
|
||||
command -v git
|
||||
command -v python3
|
||||
command -v rsync
|
||||
command -v curl
|
||||
|
||||
- name: Check deploy path
|
||||
- name: Check the deploy path is ready
|
||||
run: |
|
||||
test -d "$DEPLOY_PATH"
|
||||
test -w "$DEPLOY_PATH"
|
||||
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 <this repo> $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
|
||||
|
||||
# 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
|
||||
- name: Fast-forward the 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
|
||||
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
|
||||
|
||||
# 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
|
||||
.venv-ci/bin/pip install --quiet -r requirements.txt
|
||||
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.
|
||||
# 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
|
||||
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/" \
|
||||
--exclude "/.gitea/" \
|
||||
--exclude "/.venv/" \
|
||||
--exclude "/.venv-ci/" \
|
||||
--exclude "/members.json" \
|
||||
--exclude "__pycache__/" \
|
||||
./ "$DEPLOY_PATH/"
|
||||
|
||||
# members.json is the stereo pair's learned membership and .venv is
|
||||
# the runtime -- both are excluded above, so --delete leaves them be.
|
||||
|
||||
- name: Install runtime dependencies
|
||||
run: |
|
||||
test -d "$DEPLOY_PATH/.venv" || python3 -m venv "$DEPLOY_PATH/.venv"
|
||||
"$DEPLOY_PATH/.venv/bin/pip" install --quiet -r "$DEPLOY_PATH/requirements.txt"
|
||||
cd "$DEPLOY_PATH"
|
||||
.venv/bin/python -m unittest discover -s tests -t . --verbose
|
||||
|
||||
- name: Restart
|
||||
run: sudo systemctl restart "$SERVICE"
|
||||
|
||||
Reference in New Issue
Block a user