Skip to content

Commit 6835c55

Browse files
committed
Deploy action
1 parent d53b258 commit 6835c55

1 file changed

Lines changed: 97 additions & 0 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Build the workspace on GitHub-hosted Linux and sync the tree to a remote server over SSH.
2+
#
3+
# Required repository secrets:
4+
# DEPLOY_HOST — hostname or IP
5+
# DEPLOY_USER — SSH user (e.g. deploy)
6+
# DEPLOY_SSH_KEY — private key (PEM), full multiline content
7+
# DEPLOY_PATH — absolute path on the server (e.g. /var/www/game)
8+
#
9+
# Optional:
10+
# DEPLOY_PORT — SSH port (default 22)
11+
# DEPLOY_COMMAND — command to run after rsync (e.g. sudo systemctl restart myapp). If unset, only files are synced.
12+
13+
name: Build and deploy
14+
15+
on:
16+
push:
17+
branches: [dev]
18+
workflow_dispatch:
19+
20+
concurrency:
21+
group: deploy-${{ github.ref }}
22+
cancel-in-progress: true
23+
24+
jobs:
25+
build-and-deploy:
26+
runs-on: ubuntu-latest
27+
28+
steps:
29+
- name: Checkout
30+
uses: actions/checkout@v4
31+
32+
- name: Install pnpm
33+
uses: pnpm/action-setup@v4
34+
with:
35+
version: 10
36+
37+
- name: Setup Node.js
38+
uses: actions/setup-node@v4
39+
with:
40+
node-version: "22"
41+
cache: pnpm
42+
43+
- name: Install dependencies
44+
run: pnpm install --frozen-lockfile
45+
46+
- name: Build
47+
run: pnpm run build
48+
49+
- name: Load SSH key
50+
uses: webfactory/ssh-agent@v0.9.0
51+
with:
52+
ssh-private-key: ${{ secrets.DEPLOY_SSH_KEY }}
53+
54+
- name: Add server to known_hosts
55+
env:
56+
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
57+
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
58+
run: |
59+
set -e
60+
PORT="${DEPLOY_PORT:-22}"
61+
mkdir -p ~/.ssh
62+
ssh-keyscan -p "$PORT" -H "$DEPLOY_HOST" >> ~/.ssh/known_hosts
63+
64+
- name: Rsync to server
65+
env:
66+
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
67+
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
68+
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
69+
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
70+
run: |
71+
set -euo pipefail
72+
PORT="${DEPLOY_PORT:-22}"
73+
# Sync project without .git; --delete removes files on server that no longer exist in the tree
74+
rsync -az --delete \
75+
--exclude '.git' \
76+
--exclude '.github' \
77+
-e "ssh -p ${PORT} -o StrictHostKeyChecking=yes" \
78+
./ "${DEPLOY_USER}@${DEPLOY_HOST}:${DEPLOY_PATH}/"
79+
80+
- name: Remote post-deploy command
81+
env:
82+
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
83+
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
84+
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
85+
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
86+
DEPLOY_COMMAND: ${{ secrets.DEPLOY_COMMAND }}
87+
run: |
88+
set -euo pipefail
89+
if [ -z "${DEPLOY_COMMAND}" ]; then
90+
echo "DEPLOY_COMMAND is not set; skipping remote command."
91+
exit 0
92+
fi
93+
PORT="${DEPLOY_PORT:-22}"
94+
# shell over SSH: cd then run your restart script or systemctl
95+
ssh -p "$PORT" -o StrictHostKeyChecking=yes \
96+
"${DEPLOY_USER}@${DEPLOY_HOST}" \
97+
bash -lc "cd $(printf %q "$DEPLOY_PATH") && $DEPLOY_COMMAND"

0 commit comments

Comments
 (0)