gowalk-cicd 1.0.41 → 1.0.42
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/CLAUDE.md +5 -0
- package/README.md +5 -1
- 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 +8 -1
- package/backend-action/remote_deploy.sh +37 -7
- package/package.json +1 -1
- package/templates/deploy-backend.yml +1 -0
- package/templates/deploy.yml +1 -0
package/CLAUDE.md
CHANGED
|
@@ -64,6 +64,11 @@ workflow (`.github/workflows/publish.yml`):
|
|
|
64
64
|
attach the `publish.yml` trusted-publisher relationship; the workflow
|
|
65
65
|
supplies that token as a fallback and uses OIDC after trust is configured.
|
|
66
66
|
|
|
67
|
+
An explicitly dispatched run may publish a tested feature ref by setting its
|
|
68
|
+
`release` boolean input. The input defaults to false, so ordinary manual runs
|
|
69
|
+
remain test-only. Use this path when a deploy repair must ship without pushing
|
|
70
|
+
the feature branch directly to `main`.
|
|
71
|
+
|
|
67
72
|
Manual publish (from repo root):
|
|
68
73
|
|
|
69
74
|
```bash
|
package/README.md
CHANGED
|
@@ -68,6 +68,8 @@ The backend workflow runs on a GitHub-hosted runner and, on a push touching
|
|
|
68
68
|
it rsyncs the backend dir to `/opt/gowalk-backends/<app>/`, runs
|
|
69
69
|
`docker compose up -d --build`, auto-detects the published `127.0.0.1:<port>`,
|
|
70
70
|
wires an nginx vhost + Let's Encrypt cert for the API domain, and health-checks.
|
|
71
|
+
Certificate issuance and the public health check are strict: a deploy fails if
|
|
72
|
+
the hostname cannot present a trusted matching certificate and reach the API.
|
|
71
73
|
|
|
72
74
|
Requirements on the consumer repo:
|
|
73
75
|
|
|
@@ -84,7 +86,9 @@ Requirements on the consumer repo:
|
|
|
84
86
|
- Repo **variables** (optional): `BACKEND_API_DOMAIN` (its DNS A record must point
|
|
85
87
|
at the host for the cert; empty = deploy the container only, skip nginx/cert),
|
|
86
88
|
`BACKEND_APP_NAME` (defaults to the repo name), `BACKEND_HEALTH_PATH`
|
|
87
|
-
(default `/health`), `BACKEND_DEPLOY_HOST` (default `138.197.36.107`)
|
|
89
|
+
(default `/health`), `BACKEND_DEPLOY_HOST` (default `138.197.36.107`), and
|
|
90
|
+
`BACKEND_CERTBOT_ACCOUNT` (optional account ID for hosts with multiple ACME
|
|
91
|
+
accounts; otherwise the sole or host-created account is selected).
|
|
88
92
|
|
|
89
93
|
The action directory is canonical here (like the iOS/Android actions): edit it in
|
|
90
94
|
`backend-action/`, never in a consumer's vendored copy.
|
package/action/.daemux-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.42
|
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.42
|
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.42
|
|
@@ -39,6 +39,12 @@ inputs:
|
|
|
39
39
|
description: Email for the Let's Encrypt registration.
|
|
40
40
|
required: false
|
|
41
41
|
default: "admin@gowalk.com"
|
|
42
|
+
certbot-account:
|
|
43
|
+
description: >
|
|
44
|
+
Optional Certbot account ID. When omitted, the deploy selects the sole
|
|
45
|
+
account or the account created on the current host.
|
|
46
|
+
required: false
|
|
47
|
+
default: ""
|
|
42
48
|
runtime-env:
|
|
43
49
|
description: >
|
|
44
50
|
Optional newline-delimited KEY=value secrets written to a mode-0600
|
|
@@ -104,7 +110,8 @@ runs:
|
|
|
104
110
|
$SSH "${{ inputs.ssh-user }}@${{ inputs.host }}" \
|
|
105
111
|
"bash '$DEST/.remote_deploy.sh' \
|
|
106
112
|
'${{ inputs.app-name }}' '${{ inputs.api-domain }}' \
|
|
107
|
-
'${{ inputs.health-path }}' '${{ inputs.cert-email }}'
|
|
113
|
+
'${{ inputs.health-path }}' '${{ inputs.cert-email }}' \
|
|
114
|
+
'${{ inputs.certbot-account }}'"
|
|
108
115
|
|
|
109
116
|
- name: Cleanup key
|
|
110
117
|
if: always()
|
|
@@ -8,11 +8,37 @@ APP="$1" # slug — compose project + dir name
|
|
|
8
8
|
DOMAIN="${2:-}" # api.<app>.gowalk.com, or empty to skip nginx/cert
|
|
9
9
|
HEALTH="${3:-/health}"
|
|
10
10
|
CERT_EMAIL="${4:-admin@gowalk.com}"
|
|
11
|
+
CERT_ACCOUNT="${5:-}"
|
|
11
12
|
DIR="/opt/gowalk-backends/$APP"
|
|
12
13
|
cd "$DIR"
|
|
13
14
|
|
|
14
15
|
log() { echo "[deploy $APP] $*"; }
|
|
15
16
|
|
|
17
|
+
select_certbot_account() {
|
|
18
|
+
[ -n "$CERT_ACCOUNT" ] && return
|
|
19
|
+
local accounts_root host account_dir creation_host
|
|
20
|
+
local -a accounts=()
|
|
21
|
+
accounts_root="/etc/letsencrypt/accounts/acme-v02.api.letsencrypt.org/directory"
|
|
22
|
+
[ -d "$accounts_root" ] || return
|
|
23
|
+
host="$(hostname)"
|
|
24
|
+
while IFS= read -r account_dir; do
|
|
25
|
+
accounts+=("$(basename "$account_dir")")
|
|
26
|
+
creation_host="$(sed -nE \
|
|
27
|
+
's/.*"creation_host"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/p' \
|
|
28
|
+
"$account_dir/meta.json" 2>/dev/null | head -1)"
|
|
29
|
+
if [ "$creation_host" = "$host" ]; then
|
|
30
|
+
CERT_ACCOUNT="$(basename "$account_dir")"
|
|
31
|
+
fi
|
|
32
|
+
done < <(find "$accounts_root" -mindepth 1 -maxdepth 1 -type d | sort)
|
|
33
|
+
if [ -z "$CERT_ACCOUNT" ] && [ "${#accounts[@]}" -eq 1 ]; then
|
|
34
|
+
CERT_ACCOUNT="${accounts[0]}"
|
|
35
|
+
fi
|
|
36
|
+
if [ -z "$CERT_ACCOUNT" ] && [ "${#accounts[@]}" -gt 1 ]; then
|
|
37
|
+
log "ERROR: multiple Certbot accounts; set BACKEND_CERTBOT_ACCOUNT"
|
|
38
|
+
return 1
|
|
39
|
+
fi
|
|
40
|
+
}
|
|
41
|
+
|
|
16
42
|
# ── secrets: generate a per-app .env once, then preserve it (rsync excludes it)
|
|
17
43
|
if [ ! -f .env ]; then
|
|
18
44
|
log "first deploy — generating .env (POSTGRES_PASSWORD)"
|
|
@@ -95,16 +121,20 @@ fi
|
|
|
95
121
|
# ── Let's Encrypt cert (idempotent; certbot skips if current)
|
|
96
122
|
if ! certbot certificates 2>/dev/null | grep -q "Domains: $DOMAIN\b"; then
|
|
97
123
|
log "requesting LE cert for $DOMAIN"
|
|
124
|
+
select_certbot_account
|
|
125
|
+
CERTBOT_ARGS=()
|
|
126
|
+
if [ -n "$CERT_ACCOUNT" ]; then
|
|
127
|
+
log "using Certbot account ${CERT_ACCOUNT:0:4}…"
|
|
128
|
+
CERTBOT_ARGS+=(--account "$CERT_ACCOUNT")
|
|
129
|
+
fi
|
|
98
130
|
certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos \
|
|
99
|
-
--email "$CERT_EMAIL" --redirect
|
|
131
|
+
--email "$CERT_EMAIL" --redirect "${CERTBOT_ARGS[@]}"
|
|
100
132
|
else
|
|
101
133
|
log "cert for $DOMAIN already present"
|
|
102
134
|
fi
|
|
103
135
|
|
|
104
|
-
# ── public health-check
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
log "warn: public URL not answering yet (DNS/cert propagation) — container is up on :$PORT"
|
|
109
|
-
fi
|
|
136
|
+
# ── public health-check: validates DNS, certificate/SNI, routing and service.
|
|
137
|
+
curl -fsS --retry 6 --retry-all-errors --retry-delay 2 \
|
|
138
|
+
"https://$DOMAIN$HEALTH" >/dev/null
|
|
139
|
+
log "public https://$DOMAIN$HEALTH healthy with verified TLS"
|
|
110
140
|
log "done"
|
package/package.json
CHANGED
package/templates/deploy.yml
CHANGED
|
@@ -428,4 +428,5 @@ jobs:
|
|
|
428
428
|
api-domain: ${{ vars.BACKEND_API_DOMAIN }}
|
|
429
429
|
backend-dir: ${{ steps.dir.outputs.path }}
|
|
430
430
|
health-path: ${{ vars.BACKEND_HEALTH_PATH || '/health' }}
|
|
431
|
+
certbot-account: ${{ vars.BACKEND_CERTBOT_ACCOUNT }}
|
|
431
432
|
runtime-env: ${{ secrets.BACKEND_RUNTIME_ENV }}
|