- .gitea/workflows/deploy.yml: the bot user on the new prod host has fish as its login shell, which rejects bash syntax (set -e, VAR=..., $(...), trap, process substitution). Wrap the entire deploy script in `bash -c '...'` so fish only spawns a bash subprocess and the script itself is parsed by bash. - Forward DEPLOY_PATH alongside VAULT_PASS through appleboy/ssh-action envs: so the bash subprocess inherits both, instead of interpolating the secret directly into the rendered script (where masking would collide with the cd argument). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
33 lines
938 B
YAML
33 lines
938 B
YAML
name: Deploy to production
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
schedule:
|
|
- cron: '0 1,22 * * *'
|
|
|
|
jobs:
|
|
deploy:
|
|
runs_on: ubuntu-latest
|
|
steps:
|
|
- name: Deploy with SSH
|
|
uses: appleboy/ssh-action@v1.0.0
|
|
env:
|
|
VAULT_PASS: ${{ secrets.ANSIBLE_VAULT_PASSWORD }}
|
|
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
|
|
with:
|
|
host: ${{ secrets.SSH_HOST }}
|
|
username: ${{ secrets.SSH_USER }}
|
|
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
|
port: 22
|
|
envs: VAULT_PASS,DEPLOY_PATH
|
|
script: |
|
|
bash -c '
|
|
set -e
|
|
cd "$DEPLOY_PATH"
|
|
VAULT_FILE="$(mktemp)"
|
|
trap "rm -f \"$VAULT_FILE\"" EXIT
|
|
printf "%s" "$VAULT_PASS" > "$VAULT_FILE"
|
|
chmod 600 "$VAULT_FILE"
|
|
ansible-playbook ansible/deploy.yml -i ansible/hosts.ini --vault-password-file "$VAULT_FILE"
|
|
'
|