Skip to content

Deploy

Deploy #33

Workflow file for this run

name: Deploy
on:
workflow_dispatch:
inputs:
skip_tests:
description: "Skip tests before deploying"
required: false
default: false
type: boolean
env:
CARGO_TERM_COLOR: always
DRAMMA_HOST: dramma.lan
DRAMMA_USER: dramma
REMOTE_DIR: /home/dramma/dramma-app
# Required GitHub Secrets:
# DRAMMA_SSH_KEY - Private SSH key whose public key is in root@dramma.lan's authorized_keys
# DRAMMA_HOST_KEY - Output of: ssh-keyscan dramma.lan (prevents MITM)
# TS_AUTHKEY - TailScale auth key
#
# If you run a self-hosted runner on your local network instead of using Tailscale,
# remove the "Connect to Tailscale" step and change runs-on to: [self-hosted, linux]
jobs:
test:
name: Test
runs-on: ubuntu-latest
if: ${{ !inputs.skip_tests }}
steps:
- uses: actions/checkout@v4
- name: Install system dependencies
run: |
sudo apt-get update -q
sudo apt-get install -y -q \
libfontconfig1-dev \
libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \
libxkbcommon-dev \
libudev-dev \
libcurl4-openssl-dev \
libasound2-dev
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo test --all-features
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install system dependencies
run: |
sudo apt-get update -q
sudo apt-get install -y -q \
libfontconfig1-dev \
libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \
libxkbcommon-dev \
libudev-dev \
libcurl4-openssl-dev \
libasound2-dev
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Build release binary
run: cargo build --release
- name: Upload binary artifact
uses: actions/upload-artifact@v4
with:
name: dramma-binary
path: target/release/dramma
retention-days: 7
deploy:
name: Deploy to dramma.lan
runs-on: ubuntu-latest
needs: [test, build]
if: always() && needs.build.result == 'success' && (needs.test.result == 'success' || needs.test.result == 'skipped')
environment: production
steps:
- uses: actions/checkout@v4
- name: Download binary artifact
uses: actions/download-artifact@v4
with:
name: dramma-binary
path: target/release/
- name: Connect to Tailscale
run: |
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscaled --state=/tmp/tailscaled.state &
sleep 3
sudo tailscale up \
--login-server=https://tail.hackem.cc \
--authkey=${{ secrets.TS_AUTHKEY }} \
--hostname=github-actions \
--timeout=30s \
--accept-routes
echo "Tailscale status:"
sudo tailscale status
echo "Ping dramma.lan:"
sudo tailscale ping dramma.lan || ping -c3 dramma.lan
- name: Set up SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DRAMMA_SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
echo "${{ secrets.DRAMMA_HOST_KEY }}" > ~/.ssh/known_hosts
- name: Stop service
run: |
ssh root@${{ env.DRAMMA_HOST }} \
"su - ${{ env.DRAMMA_USER }} -c \
'XDG_RUNTIME_DIR=/run/user/\$(id -u ${{ env.DRAMMA_USER }}) \
systemctl --user stop dramma.service' || true"
- name: Create remote directory structure
run: |
ssh root@${{ env.DRAMMA_HOST }} \
"mkdir -p ${{ env.REMOTE_DIR }}/{data,logs,.config} && \
chown -R ${{ env.DRAMMA_USER }}:${{ env.DRAMMA_USER }} ${{ env.REMOTE_DIR }}"
- name: Ensure runtime dependencies on target
run: |
ssh root@${{ env.DRAMMA_HOST }} "apt-get update -q && apt-get install -y -q \
libfontconfig1 \
libxcb-render0 libxcb-shape0 libxcb-xfixes0 \
libxkbcommon0 \
libudev1 \
libcurl4 \
libstdc++6 \
libasound2"
- name: Deploy binary
run: |
chmod +x target/release/dramma
scp target/release/dramma root@${{ env.DRAMMA_HOST }}:${{ env.REMOTE_DIR }}/dramma
ssh root@${{ env.DRAMMA_HOST }} \
"chmod +x ${{ env.REMOTE_DIR }}/dramma && \
chown ${{ env.DRAMMA_USER }}:${{ env.DRAMMA_USER }} ${{ env.REMOTE_DIR }}/dramma"
- name: Deploy configuration
run: |
ssh root@${{ env.DRAMMA_HOST }} "cat > ${{ env.REMOTE_DIR }}/.config/dramma.toml" << 'EOF'
token = "${{ secrets.DRAMMA_TOKEN }}"
cashcode_serial_port = "/dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0"
cctalk_serial_port = "/dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0"
retroarch_command = "sudo retroarch"
[[games]]
name = "Tetris"
core = "/etc/retroarch/cores/nestopia_libretro.so"
rom = "/home/dramma/roms/tetris.nes"
[[games]]
name = "DOOM"
core = "/etc/retroarch/cores/dosbox_pure_libretro.so"
rom = "/home/dramma/roms/doom.wad"
EOF
ssh root@${{ env.DRAMMA_HOST }} \
"chown ${{ env.DRAMMA_USER }}:${{ env.DRAMMA_USER }} ${{ env.REMOTE_DIR }}/.config/dramma.toml"
- name: Set up systemd service
run: |
ssh root@${{ env.DRAMMA_HOST }} \
"su - ${{ env.DRAMMA_USER }} -c 'mkdir -p ~/.config/systemd/user'"
ssh root@${{ env.DRAMMA_HOST }} \
"su - ${{ env.DRAMMA_USER }} -c 'cat > ~/.config/systemd/user/dramma.service'" << 'SERVICEEOF'
[Unit]
Description=Dramma Donation Kiosk
After=graphical-session.target
[Service]
Type=simple
Environment=DISPLAY=:0
Environment=RUST_LOG=info
WorkingDirectory=/home/dramma/dramma-app
ExecStart=/home/dramma/dramma-app/dramma
Restart=always
RestartSec=5
[Install]
WantedBy=graphical-session.target
SERVICEEOF
- name: Set up LXQt autostart
run: |
ssh root@${{ env.DRAMMA_HOST }} \
"su - ${{ env.DRAMMA_USER }} -c 'mkdir -p ~/.config/autostart'"
ssh root@${{ env.DRAMMA_HOST }} \
"su - ${{ env.DRAMMA_USER }} -c 'cat > ~/.config/autostart/dramma.desktop'" << 'DESKTOPEOF'
[Desktop Entry]
Type=Application
Name=Dramma Kiosk
Exec=systemctl --user start dramma.service
X-LXQt-Need-Tray=false
DESKTOPEOF
- name: Enable and start service
run: |
ssh root@${{ env.DRAMMA_HOST }} "usermod -a -G dialout ${{ env.DRAMMA_USER }}"
ssh root@${{ env.DRAMMA_HOST }} "loginctl enable-linger ${{ env.DRAMMA_USER }}"
ssh root@${{ env.DRAMMA_HOST }} \
"su - ${{ env.DRAMMA_USER }} -c \
'XDG_RUNTIME_DIR=/run/user/\$(id -u ${{ env.DRAMMA_USER }}) \
systemctl --user daemon-reload && \
XDG_RUNTIME_DIR=/run/user/\$(id -u ${{ env.DRAMMA_USER }}) \
systemctl --user enable dramma.service && \
XDG_RUNTIME_DIR=/run/user/\$(id -u ${{ env.DRAMMA_USER }}) \
systemctl --user start dramma.service'"
- name: Verify service is running
run: |
sleep 3
ssh root@${{ env.DRAMMA_HOST }} \
"su - ${{ env.DRAMMA_USER }} -c \
'XDG_RUNTIME_DIR=/run/user/\$(id -u ${{ env.DRAMMA_USER }}) \
systemctl --user is-active dramma.service'"