gowalk-cicd 1.0.41 → 1.0.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -3
- package/action/.daemux-version +1 -1
- package/android-action/.daemux-version +1 -1
- package/backend-action/.daemux-version +1 -1
- package/backend-action/action.yml +44 -6
- package/package.json +1 -1
- package/src/install.mjs +21 -9
- package/templates/deploy-backend.yml +21 -6
- package/templates/deploy.yml +17 -3
package/README.md
CHANGED
|
@@ -58,11 +58,16 @@ account or domain.
|
|
|
58
58
|
|
|
59
59
|
## Backend deploy (Python + Postgres, Docker)
|
|
60
60
|
|
|
61
|
-
When a repo carries a Dockerized backend
|
|
62
|
-
with a `docker-compose.yml` — the installer also vendors a backend deploy path:
|
|
61
|
+
When a repo carries a Dockerized backend, the installer also vendors a backend deploy path:
|
|
63
62
|
`.github/actions/backend-app/` and `.github/workflows/deploy-backend.yml`. A
|
|
64
63
|
mobile-only repo is unaffected (the backend path is not installed).
|
|
65
64
|
|
|
65
|
+
Both supported layouts keep application source under `backend/` or `server/`:
|
|
66
|
+
|
|
67
|
+
- the compose file can live beside that source as `backend/docker-compose.yml`; or
|
|
68
|
+
- it can live at the repository root as `docker-compose.yml` and build `./backend`
|
|
69
|
+
(equivalently for `server/`).
|
|
70
|
+
|
|
66
71
|
The backend workflow runs on a GitHub-hosted runner and, on a push touching
|
|
67
72
|
`backend/**`, deploys to the gowalk host (`138.197.36.107`, publicly reachable):
|
|
68
73
|
it rsyncs the backend dir to `/opt/gowalk-backends/<app>/`, runs
|
|
@@ -71,7 +76,7 @@ wires an nginx vhost + Let's Encrypt cert for the API domain, and health-checks.
|
|
|
71
76
|
|
|
72
77
|
Requirements on the consumer repo:
|
|
73
78
|
|
|
74
|
-
- **`
|
|
79
|
+
- A supported **`docker-compose.yml`** that publishes the API on a **loopback host
|
|
75
80
|
port** (`127.0.0.1:<port>:<container-port>`) so nginx can proxy it. Include a
|
|
76
81
|
Postgres service (or use a per-app database) and a `/health` endpoint.
|
|
77
82
|
- A **`Dockerfile`** the compose file builds; pin the base image, run non-root,
|
package/action/.daemux-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.43
|
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.43
|
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.43
|
|
@@ -28,9 +28,15 @@ inputs:
|
|
|
28
28
|
required: false
|
|
29
29
|
default: ""
|
|
30
30
|
backend-dir:
|
|
31
|
-
description: Path to the backend
|
|
31
|
+
description: Path to the backend source directory.
|
|
32
32
|
required: false
|
|
33
33
|
default: "backend"
|
|
34
|
+
compose-file:
|
|
35
|
+
description: >
|
|
36
|
+
Compose file path. Empty defaults to <backend-dir>/docker-compose.yml;
|
|
37
|
+
docker-compose.yml supports a root compose file that builds ./backend or ./server.
|
|
38
|
+
required: false
|
|
39
|
+
default: ""
|
|
34
40
|
health-path:
|
|
35
41
|
description: HTTP path the service answers 2xx on once healthy.
|
|
36
42
|
required: false
|
|
@@ -51,14 +57,33 @@ runs:
|
|
|
51
57
|
using: composite
|
|
52
58
|
steps:
|
|
53
59
|
- name: Validate inputs
|
|
60
|
+
id: layout
|
|
54
61
|
shell: bash
|
|
62
|
+
env:
|
|
63
|
+
BACKEND_DIR: ${{ inputs.backend-dir }}
|
|
64
|
+
COMPOSE_FILE_INPUT: ${{ inputs.compose-file }}
|
|
55
65
|
run: |
|
|
56
66
|
set -euo pipefail
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
COMPOSE_FILE="${COMPOSE_FILE_INPUT:-$BACKEND_DIR/docker-compose.yml}"
|
|
68
|
+
test -d "$BACKEND_DIR" \
|
|
69
|
+
|| { echo "::error::no backend directory $BACKEND_DIR"; exit 1; }
|
|
70
|
+
test -f "$COMPOSE_FILE" \
|
|
71
|
+
|| { echo "::error::no compose file $COMPOSE_FILE"; exit 1; }
|
|
72
|
+
case "$BACKEND_DIR" in
|
|
73
|
+
/*|../*|*/../*|*/..|.) echo "::error::backend-dir must be a safe relative path"; exit 1;;
|
|
74
|
+
esac
|
|
75
|
+
case "$COMPOSE_FILE" in
|
|
76
|
+
/*|../*|*/../*|*/..) echo "::error::compose-file must be a safe relative path"; exit 1;;
|
|
77
|
+
esac
|
|
78
|
+
if [ "$COMPOSE_FILE" != "$BACKEND_DIR/docker-compose.yml" ] \
|
|
79
|
+
&& [ "$COMPOSE_FILE" != "docker-compose.yml" ]; then
|
|
80
|
+
echo "::error::compose-file must be docker-compose.yml or $BACKEND_DIR/docker-compose.yml"
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
59
83
|
case "${{ inputs.app-name }}" in
|
|
60
84
|
*[!a-z0-9-]*|"") echo "::error::app-name must be [a-z0-9-]"; exit 1;;
|
|
61
85
|
esac
|
|
86
|
+
echo "compose-file=$COMPOSE_FILE" >> "$GITHUB_OUTPUT"
|
|
62
87
|
|
|
63
88
|
- name: Configure SSH
|
|
64
89
|
shell: bash
|
|
@@ -74,6 +99,9 @@ runs:
|
|
|
74
99
|
|
|
75
100
|
- name: Sync backend to the host
|
|
76
101
|
shell: bash
|
|
102
|
+
env:
|
|
103
|
+
BACKEND_DIR: ${{ inputs.backend-dir }}
|
|
104
|
+
COMPOSE_FILE: ${{ steps.layout.outputs.compose-file }}
|
|
77
105
|
run: |
|
|
78
106
|
set -euo pipefail
|
|
79
107
|
SSH="ssh -i ~/.ssh/backend_deploy -o IdentitiesOnly=yes"
|
|
@@ -81,9 +109,19 @@ runs:
|
|
|
81
109
|
$SSH "${{ inputs.ssh-user }}@${{ inputs.host }}" "mkdir -p '$DEST'"
|
|
82
110
|
# --delete keeps the mirror true; exclude .env so server-side secrets
|
|
83
111
|
# (generated DB password, etc.) survive across deploys.
|
|
84
|
-
|
|
85
|
-
-
|
|
86
|
-
|
|
112
|
+
if [ "$COMPOSE_FILE" = "$BACKEND_DIR/docker-compose.yml" ]; then
|
|
113
|
+
rsync -az --delete --exclude '.env' --exclude '.git' \
|
|
114
|
+
-e "$SSH" "$BACKEND_DIR/" \
|
|
115
|
+
"${{ inputs.ssh-user }}@${{ inputs.host }}:$DEST/"
|
|
116
|
+
else
|
|
117
|
+
$SSH "${{ inputs.ssh-user }}@${{ inputs.host }}" \
|
|
118
|
+
"mkdir -p '$DEST/$BACKEND_DIR'"
|
|
119
|
+
rsync -az --delete --exclude '.env' --exclude '.git' \
|
|
120
|
+
-e "$SSH" "$BACKEND_DIR/" \
|
|
121
|
+
"${{ inputs.ssh-user }}@${{ inputs.host }}:$DEST/$BACKEND_DIR/"
|
|
122
|
+
rsync -az -e "$SSH" "$COMPOSE_FILE" \
|
|
123
|
+
"${{ inputs.ssh-user }}@${{ inputs.host }}:$DEST/docker-compose.yml"
|
|
124
|
+
fi
|
|
87
125
|
# ship the remote deploy script (kept out of the app checkout)
|
|
88
126
|
rsync -az -e "$SSH" "${{ github.action_path }}/remote_deploy.sh" \
|
|
89
127
|
"${{ inputs.ssh-user }}@${{ inputs.host }}:$DEST/.remote_deploy.sh"
|
package/package.json
CHANGED
package/src/install.mjs
CHANGED
|
@@ -44,10 +44,22 @@ const VERSION_MARKER_REL = join('.github', 'actions', 'swift-app', '.daemux-vers
|
|
|
44
44
|
const ANDROID_VERSION_MARKER_REL = join('.github', 'actions', 'android-app', '.daemux-version');
|
|
45
45
|
const BACKEND_VERSION_MARKER_REL = join('.github', 'actions', 'backend-app', '.daemux-version');
|
|
46
46
|
|
|
47
|
-
// A repo has a backend when
|
|
48
|
-
|
|
47
|
+
// A repo has a backend when backend/ or server/ either carries the compose file
|
|
48
|
+
// or is referenced by a root compose file. The latter is Flutter's common
|
|
49
|
+
// full-stack layout: docker-compose.yml stays at the repo root so it can build
|
|
50
|
+
// ./backend while the deploy action still syncs only backend-owned files.
|
|
51
|
+
function backendLayout(repoRoot) {
|
|
49
52
|
for (const d of ['backend', 'server']) {
|
|
50
|
-
if (existsSync(join(repoRoot, d, 'docker-compose.yml')))
|
|
53
|
+
if (existsSync(join(repoRoot, d, 'docker-compose.yml'))) {
|
|
54
|
+
return { backendDir: d, composeFile: join(d, 'docker-compose.yml') };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (existsSync(join(repoRoot, 'docker-compose.yml'))) {
|
|
58
|
+
for (const d of ['backend', 'server']) {
|
|
59
|
+
if (existsSync(join(repoRoot, d, 'Dockerfile'))) {
|
|
60
|
+
return { backendDir: d, composeFile: 'docker-compose.yml' };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
51
63
|
}
|
|
52
64
|
return null;
|
|
53
65
|
}
|
|
@@ -235,12 +247,12 @@ export async function runInstall({ dryRun = false } = {}) {
|
|
|
235
247
|
}
|
|
236
248
|
}
|
|
237
249
|
|
|
238
|
-
// Backend deploy path — installed only
|
|
239
|
-
//
|
|
240
|
-
//
|
|
241
|
-
const
|
|
242
|
-
if (
|
|
243
|
-
console.log(` Backend detected (${
|
|
250
|
+
// Backend deploy path — installed only for a supported nested or root
|
|
251
|
+
// compose layout. Mobile-only repos are unaffected, so this is backward
|
|
252
|
+
// compatible.
|
|
253
|
+
const layout = backendLayout(repoRoot);
|
|
254
|
+
if (layout) {
|
|
255
|
+
console.log(` Backend detected (${layout.composeFile}) — installing backend deploy`);
|
|
244
256
|
copyAction(BACKEND_ACTION_SRC, BACKEND_ACTION_DEST_REL, repoRoot, dryRun);
|
|
245
257
|
if (!dryRun) writeFileSync(
|
|
246
258
|
join(repoRoot, BACKEND_VERSION_MARKER_REL),
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
name: Backend Deploy
|
|
2
2
|
|
|
3
3
|
# Deploys the Dockerized Python+Postgres backend to the gowalk host. Installed
|
|
4
|
-
# by gowalk-cicd
|
|
5
|
-
#
|
|
4
|
+
# by gowalk-cicd when backend/ or server/ has a compose file, or when a root
|
|
5
|
+
# compose file builds one of those directories. Mobile deploy stays in deploy.yml.
|
|
6
6
|
on:
|
|
7
7
|
push:
|
|
8
8
|
branches: [main]
|
|
9
9
|
paths:
|
|
10
10
|
- "backend/**"
|
|
11
11
|
- "server/**"
|
|
12
|
+
- "docker-compose.yml"
|
|
12
13
|
- ".github/workflows/deploy-backend.yml"
|
|
13
14
|
workflow_dispatch:
|
|
14
15
|
|
|
@@ -23,12 +24,25 @@ jobs:
|
|
|
23
24
|
steps:
|
|
24
25
|
- uses: actions/checkout@v4
|
|
25
26
|
|
|
26
|
-
# Pick
|
|
27
|
+
# Pick the source dir and either its nested compose file or a root one.
|
|
27
28
|
- id: dir
|
|
28
29
|
run: |
|
|
29
|
-
if [ -f backend/docker-compose.yml ]; then
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
if [ -f backend/docker-compose.yml ]; then
|
|
31
|
+
echo "path=backend" >> "$GITHUB_OUTPUT"
|
|
32
|
+
echo "compose=backend/docker-compose.yml" >> "$GITHUB_OUTPUT"
|
|
33
|
+
elif [ -f server/docker-compose.yml ]; then
|
|
34
|
+
echo "path=server" >> "$GITHUB_OUTPUT"
|
|
35
|
+
echo "compose=server/docker-compose.yml" >> "$GITHUB_OUTPUT"
|
|
36
|
+
elif [ -f docker-compose.yml ] && [ -f backend/Dockerfile ]; then
|
|
37
|
+
echo "path=backend" >> "$GITHUB_OUTPUT"
|
|
38
|
+
echo "compose=docker-compose.yml" >> "$GITHUB_OUTPUT"
|
|
39
|
+
elif [ -f docker-compose.yml ] && [ -f server/Dockerfile ]; then
|
|
40
|
+
echo "path=server" >> "$GITHUB_OUTPUT"
|
|
41
|
+
echo "compose=docker-compose.yml" >> "$GITHUB_OUTPUT"
|
|
42
|
+
else
|
|
43
|
+
echo "::error::no supported backend compose layout"
|
|
44
|
+
exit 1
|
|
45
|
+
fi
|
|
32
46
|
|
|
33
47
|
- name: Deploy backend
|
|
34
48
|
uses: ./.github/actions/backend-app
|
|
@@ -38,5 +52,6 @@ jobs:
|
|
|
38
52
|
app-name: ${{ vars.BACKEND_APP_NAME || github.event.repository.name }}
|
|
39
53
|
api-domain: ${{ vars.BACKEND_API_DOMAIN }}
|
|
40
54
|
backend-dir: ${{ steps.dir.outputs.path }}
|
|
55
|
+
compose-file: ${{ steps.dir.outputs.compose }}
|
|
41
56
|
health-path: ${{ vars.BACKEND_HEALTH_PATH || '/health' }}
|
|
42
57
|
runtime-env: ${{ secrets.BACKEND_RUNTIME_ENV }}
|
package/templates/deploy.yml
CHANGED
|
@@ -415,9 +415,22 @@ jobs:
|
|
|
415
415
|
- id: dir
|
|
416
416
|
shell: bash
|
|
417
417
|
run: |
|
|
418
|
-
if [ -f backend/docker-compose.yml ]; then
|
|
419
|
-
|
|
420
|
-
|
|
418
|
+
if [ -f backend/docker-compose.yml ]; then
|
|
419
|
+
echo "path=backend" >> "$GITHUB_OUTPUT"
|
|
420
|
+
echo "compose=backend/docker-compose.yml" >> "$GITHUB_OUTPUT"
|
|
421
|
+
elif [ -f server/docker-compose.yml ]; then
|
|
422
|
+
echo "path=server" >> "$GITHUB_OUTPUT"
|
|
423
|
+
echo "compose=server/docker-compose.yml" >> "$GITHUB_OUTPUT"
|
|
424
|
+
elif [ -f docker-compose.yml ] && [ -f backend/Dockerfile ]; then
|
|
425
|
+
echo "path=backend" >> "$GITHUB_OUTPUT"
|
|
426
|
+
echo "compose=docker-compose.yml" >> "$GITHUB_OUTPUT"
|
|
427
|
+
elif [ -f docker-compose.yml ] && [ -f server/Dockerfile ]; then
|
|
428
|
+
echo "path=server" >> "$GITHUB_OUTPUT"
|
|
429
|
+
echo "compose=docker-compose.yml" >> "$GITHUB_OUTPUT"
|
|
430
|
+
else
|
|
431
|
+
echo "path=" >> "$GITHUB_OUTPUT"
|
|
432
|
+
echo "compose=" >> "$GITHUB_OUTPUT"
|
|
433
|
+
fi
|
|
421
434
|
- name: Deploy backend from feature branch
|
|
422
435
|
if: ${{ steps.dir.outputs.path != '' }}
|
|
423
436
|
uses: ./.github/actions/backend-app
|
|
@@ -427,5 +440,6 @@ jobs:
|
|
|
427
440
|
app-name: ${{ vars.BACKEND_APP_NAME || github.event.repository.name }}
|
|
428
441
|
api-domain: ${{ vars.BACKEND_API_DOMAIN }}
|
|
429
442
|
backend-dir: ${{ steps.dir.outputs.path }}
|
|
443
|
+
compose-file: ${{ steps.dir.outputs.compose }}
|
|
430
444
|
health-path: ${{ vars.BACKEND_HEALTH_PATH || '/health' }}
|
|
431
445
|
runtime-env: ${{ secrets.BACKEND_RUNTIME_ENV }}
|