gowalk-cicd 1.0.179 → 1.0.180

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 CHANGED
@@ -284,11 +284,11 @@ Requirements on the consumer repo:
284
284
  never bake secrets in. A generated `.env` (with `POSTGRES_PASSWORD`) is created
285
285
  on the host on first deploy and preserved across deploys (rsync excludes it).
286
286
  - Repo **secret** `BACKEND_DEPLOY_SSH_KEY` (a private key with access to the host).
287
- - Repo **variable** `BACKEND_DEPLOY_KNOWN_HOSTS` (recommended): `known_hosts` lines for the exact
287
+ - Repo **variable** `BACKEND_DEPLOY_KNOWN_HOSTS` (required): trusted `known_hosts` lines for the exact
288
288
  host string the workflow connects to (`BACKEND_DEPLOY_HOST`, for example
289
- `138.197.36.107 ssh-ed25519 AAAA...`). Deploys then require that key
290
- (`StrictHostKeyChecking=yes`). While it is empty the job trusts `ssh-keyscan` and prints one
291
- `backend_host_key_unpinned` warning.
289
+ `backend.example.com ssh-ed25519 AAAA...`). Deploys require that key
290
+ (`StrictHostKeyChecking=yes`). Missing pins refuse with `backend_host_key_required` before SSH
291
+ or writing the private key; the action never discovers and trusts an unverified host key.
292
292
  - Repo **secret** `BACKEND_RUNTIME_ENV` (optional): newline-delimited `KEY=value`
293
293
  runtime secrets. The action writes it as mode 0600 on the host and passes it
294
294
  to Compose without copying values into the repository or action log.
@@ -36,8 +36,8 @@ inputs:
36
36
  known-hosts:
37
37
  description: >
38
38
  known_hosts lines pinning the deploy host's key (vars.BACKEND_DEPLOY_KNOWN_HOSTS).
39
- Empty trusts whatever ssh-keyscan returns and prints a warning.
40
- required: false
39
+ Required before SSH; missing pins refuse without network discovery.
40
+ required: true
41
41
  default: ""
42
42
  app-name:
43
43
  description: Stable slug — the compose project and /opt/gowalk-backends/<app-name> dir.
@@ -160,15 +160,14 @@ runs:
160
160
  set -euo pipefail
161
161
  source "${{ github.action_path }}/deploy_evidence.sh"
162
162
  BACKEND_DEPLOY_PHASE=configure_ssh
163
+ if [[ ! "${KNOWN_HOSTS:-}" =~ [^[:space:]] ]]; then
164
+ echo "::error title=backend_host_key_required::Configure the backend binding's trusted SSH host key"
165
+ exit 1
166
+ fi
163
167
  mkdir -p ~/.ssh && chmod 700 ~/.ssh
164
168
  printf '%s\n' "$DEPLOY_SSH_KEY" > ~/.ssh/backend_deploy
165
169
  chmod 600 ~/.ssh/backend_deploy
166
- if [ -n "${KNOWN_HOSTS:-}" ]; then
167
- printf '%s\n' "$KNOWN_HOSTS" > ~/.ssh/known_hosts
168
- else
169
- echo "::warning title=backend_host_key_unpinned::BACKEND_DEPLOY_KNOWN_HOSTS is empty; trusting the key ssh-keyscan returns"
170
- ssh-keyscan -t ed25519,rsa,ecdsa "${{ inputs.host }}" >> ~/.ssh/known_hosts 2>/dev/null
171
- fi
170
+ printf '%s\n' "$KNOWN_HOSTS" > ~/.ssh/known_hosts
172
171
  chmod 644 ~/.ssh/known_hosts
173
172
 
174
173
  - name: Sync backend to the host
@@ -16,6 +16,7 @@ OWNERS = Path('/var/lib/gowalk-backend-ownership')
16
16
  APPS = Path('/opt/gowalk-backends')
17
17
  INGRESS = Path('/opt/gowalk-backend-ingress')
18
18
  ROOT_UID = 0
19
+ PLATFORM = ['docker', 'info', '--format', '{{.OSType}}/{{.Architecture}}']
19
20
  READY = ('command -v docker >/dev/null && docker info >/dev/null 2>&1 '
20
21
  '&& docker compose version >/dev/null 2>&1')
21
22
 
@@ -143,6 +144,15 @@ def readiness():
143
144
  return 0
144
145
 
145
146
 
147
+ def platform():
148
+ result = subprocess.run(PLATFORM, capture_output=True, text=True, timeout=15, check=True)
149
+ value = result.stdout.strip()
150
+ if not re.fullmatch('[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+', value):
151
+ raise ValueError('ssh_platform_invalid')
152
+ print(value)
153
+ return 0
154
+
155
+
146
156
  def main():
147
157
  try:
148
158
  os.umask(0o077)
@@ -151,6 +161,8 @@ def main():
151
161
  command = os.environ.get('SSH_ORIGINAL_COMMAND', '')
152
162
  if ' '.join(command.split()) in (READY, 'gowalk-backend readiness'):
153
163
  return readiness()
164
+ if shlex.split(command) == PLATFORM:
165
+ return platform()
154
166
  if policy.get('disabled', True):
155
167
  raise ValueError('ssh_backend_disabled')
156
168
  project, may_claim, arguments = plan(command)
@@ -9,7 +9,7 @@ needed for the transport protocol below.
9
9
  Each panel gets its own dedicated SSH key. Its `authorized_keys` entry uses `restrict` and a fixed owner:
10
10
 
11
11
  ```text
12
- restrict,command="/usr/bin/python3 /opt/gowalk-cicd-runtime/1.0.179/backend-action/ssh_gate.py robot" ssh-ed25519 <key>
12
+ restrict,command="/usr/bin/python3 /opt/gowalk-cicd-runtime/1.0.180/backend-action/ssh_gate.py robot" ssh-ed25519 <key>
13
13
  ```
14
14
 
15
15
  Keep operator and release credentials separate. Never install an unrestricted backend key as a fallback.
@@ -24,7 +24,7 @@ Create root-owned mode-0600 `/etc/gowalk-backend-ssh.json`:
24
24
  }
25
25
  ```
26
26
 
27
- `disabled: true` refuses every mutation while permitting the read-only readiness probe. Keep it set
27
+ `disabled: true` refuses every mutation while permitting the read-only readiness and platform probes. Keep it set
28
28
  through migration and validation. Existing per-app runtime `disabled` profiles remain an independent
29
29
  start fence when the global transport gate opens.
30
30
 
@@ -38,6 +38,7 @@ provisioning without a manual allowlist update; existing ownership and private d
38
38
  The entry permits only:
39
39
 
40
40
  - the panel's exact existing Docker/Compose readiness probe, or `gowalk-backend readiness`;
41
+ - exactly `docker info --format '{{.OSType}}/{{.Architecture}}'` for real deployment-platform discovery;
41
42
  - scoped app-directory creation and the action's rsync **receiver** protocol inside that app;
42
43
  - the standard private runtime environment and edge-input receive envelopes;
43
44
  - the standard backend deploy invocation, redirected to the host-owned released helper;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gowalk-cicd",
3
- "version": "1.0.179",
3
+ "version": "1.0.180",
4
4
  "description": "Zero-config GitHub Actions delivery for iOS TestFlight and Android Google Play.",
5
5
  "type": "module",
6
6
  "bin": {