fix(ci): fix YAML parse error in deploy workflow caused by inner heredoc
Some checks failed
Deploy — Staging / Lint, Typecheck & Test (push) Successful in 1m29s
Deploy — Staging / Build & push — admin (push) Successful in 54s
Deploy — Staging / Build & push — storefront (push) Successful in 53s
Deploy — Staging / Deploy to staging VPS (push) Failing after 24s
Some checks failed
Deploy — Staging / Lint, Typecheck & Test (push) Successful in 1m29s
Deploy — Staging / Build & push — admin (push) Successful in 54s
Deploy — Staging / Build & push — storefront (push) Successful in 53s
Deploy — Staging / Deploy to staging VPS (push) Failing after 24s
The compose file was written via a bash << 'COMPOSE' heredoc nested inside
the YAML run: | block scalar. Lines like "name: petloft-staging" at column 0
cause the YAML parser to break out of the block scalar early, making the
entire workflow file invalid YAML — Gitea silently drops invalid workflows,
so no jobs triggered at all.
Fix: move compose.yml to deploy/staging/compose.yml in the repo, substitute
${REGISTRY} on the runner, base64-encode the result, and decode it on the VPS
inside the SSH session. No inner heredoc needed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -159,6 +159,8 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Write SSH key
|
- name: Write SSH key
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ~/.ssh
|
mkdir -p ~/.ssh
|
||||||
@@ -174,9 +176,14 @@ jobs:
|
|||||||
SSH_USER: ${{ secrets.STAGING_SSH_USER }}
|
SSH_USER: ${{ secrets.STAGING_SSH_USER }}
|
||||||
SSH_PORT: ${{ secrets.STAGING_SSH_PORT }}
|
SSH_PORT: ${{ secrets.STAGING_SSH_PORT }}
|
||||||
run: |
|
run: |
|
||||||
# Auth key is the hostname only — strip the /owner path
|
|
||||||
REGISTRY_HOST=$(echo "$REGISTRY" | cut -d'/' -f1)
|
REGISTRY_HOST=$(echo "$REGISTRY" | cut -d'/' -f1)
|
||||||
|
|
||||||
|
# Substitute the actual registry value and base64-encode the compose file.
|
||||||
|
# Passing it as a base64 string through the SSH heredoc avoids the need for
|
||||||
|
# an inner heredoc, which breaks YAML parsing when compose content has lines
|
||||||
|
# at column 0 (YAML sees them as new top-level nodes, invalidating the file).
|
||||||
|
COMPOSE_B64=$(sed "s|\${REGISTRY}|${REGISTRY}|g" deploy/staging/compose.yml | base64 -w 0)
|
||||||
|
|
||||||
# StrictHostKeyChecking=accept-new trusts on first connect but rejects
|
# StrictHostKeyChecking=accept-new trusts on first connect but rejects
|
||||||
# changed keys on subsequent runs — safer than no-verify
|
# changed keys on subsequent runs — safer than no-verify
|
||||||
ssh -i ~/.ssh/staging \
|
ssh -i ~/.ssh/staging \
|
||||||
@@ -196,37 +203,10 @@ jobs:
|
|||||||
|
|
||||||
mkdir -p /opt/staging
|
mkdir -p /opt/staging
|
||||||
|
|
||||||
# Write the compose file on every deploy so it stays in sync with CI.
|
# Decode the compose file that was base64-encoded on the runner.
|
||||||
# REGISTRY is interpolated by bash here (not by podman compose), so the
|
|
||||||
# actual registry host:port/owner value is embedded in the file.
|
|
||||||
cat > /opt/staging/compose.yml << 'COMPOSE'
|
|
||||||
name: petloft-staging
|
|
||||||
|
|
||||||
services:
|
|
||||||
storefront:
|
|
||||||
image: ${REGISTRY}/storefront:staging
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "3000:3000"
|
|
||||||
env_file:
|
|
||||||
- path: .env
|
|
||||||
required: false
|
|
||||||
|
|
||||||
admin:
|
|
||||||
image: ${REGISTRY}/admin:staging
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "3001:3001"
|
|
||||||
env_file:
|
|
||||||
- path: .env
|
|
||||||
required: false
|
|
||||||
COMPOSE
|
|
||||||
# Substitute the actual registry value into the compose file
|
|
||||||
sed -i "s|\${REGISTRY}|${REGISTRY}|g" /opt/staging/compose.yml
|
|
||||||
|
|
||||||
# Create a minimal .env if one doesn't exist.
|
|
||||||
# Runtime secrets (CLERK_SECRET_KEY, etc.) should be added manually
|
# Runtime secrets (CLERK_SECRET_KEY, etc.) should be added manually
|
||||||
# to /opt/staging/.env on the VPS after first deploy.
|
# to /opt/staging/.env on the VPS after first deploy.
|
||||||
|
echo "${COMPOSE_B64}" | base64 -d > /opt/staging/compose.yml
|
||||||
touch /opt/staging/.env
|
touch /opt/staging/.env
|
||||||
|
|
||||||
cd /opt/staging
|
cd /opt/staging
|
||||||
|
|||||||
20
deploy/staging/compose.yml
Normal file
20
deploy/staging/compose.yml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
name: petloft-staging
|
||||||
|
|
||||||
|
services:
|
||||||
|
storefront:
|
||||||
|
image: ${REGISTRY}/storefront:staging
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
env_file:
|
||||||
|
- path: .env
|
||||||
|
required: false
|
||||||
|
|
||||||
|
admin:
|
||||||
|
image: ${REGISTRY}/admin:staging
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "3001:3001"
|
||||||
|
env_file:
|
||||||
|
- path: .env
|
||||||
|
required: false
|
||||||
Reference in New Issue
Block a user