Use separate CI build directory to avoid clobbering dev working tree

CI was doing git reset --hard on /root/rose-ash (the dev directory),
flipping the checked-out branch and causing empty diffs when merging.
Now builds in /root/rose-ash-ci and uses push event SHAs for diffing.
Also adds --resolve-image always to stack deploys.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-13 15:42:00 +00:00
parent c4a999d0d0
commit 04d3b2ecaf

View File

@@ -7,6 +7,7 @@ on:
env: env:
REGISTRY: registry.rose-ash.com:5000 REGISTRY: registry.rose-ash.com:5000
APP_DIR: /root/rose-ash APP_DIR: /root/rose-ash
BUILD_DIR: /root/rose-ash-ci
jobs: jobs:
build-and-deploy: build-and-deploy:
@@ -33,23 +34,26 @@ jobs:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }} DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
run: | run: |
ssh "root@$DEPLOY_HOST" " ssh "root@$DEPLOY_HOST" "
cd ${{ env.APP_DIR }} # --- Build in isolated CI directory (never touch dev working tree) ---
BUILD=${{ env.BUILD_DIR }}
# Save current HEAD before updating ORIGIN=\$(git -C ${{ env.APP_DIR }} remote get-url origin)
OLD_HEAD=\$(git rev-parse HEAD 2>/dev/null || echo none) if [ ! -d \"\$BUILD/.git\" ]; then
git clone \"\$ORIGIN\" \"\$BUILD\"
git fetch origin ${{ github.ref_name }} fi
cd \"\$BUILD\"
git fetch origin
git reset --hard origin/${{ github.ref_name }} git reset --hard origin/${{ github.ref_name }}
NEW_HEAD=\$(git rev-parse HEAD) # Detect changes using push event SHAs (not local checkout state)
BEFORE='${{ github.event.before }}'
AFTER='${{ github.sha }}'
# Detect what changed
REBUILD_ALL=false REBUILD_ALL=false
if [ \"\$OLD_HEAD\" = \"none\" ] || [ \"\$OLD_HEAD\" = \"\$NEW_HEAD\" ]; then if [ -z \"\$BEFORE\" ] || [ \"\$BEFORE\" = '0000000000000000000000000000000000000000' ] || ! git cat-file -e \"\$BEFORE\" 2>/dev/null; then
# First deploy or CI re-run on same commit — rebuild all # New branch, force push, or unreachable parent — rebuild all
REBUILD_ALL=true REBUILD_ALL=true
else else
CHANGED=\$(git diff --name-only \$OLD_HEAD \$NEW_HEAD) CHANGED=\$(git diff --name-only \$BEFORE \$AFTER)
if echo \"\$CHANGED\" | grep -q '^shared/'; then if echo \"\$CHANGED\" | grep -q '^shared/'; then
REBUILD_ALL=true REBUILD_ALL=true
fi fi
@@ -86,8 +90,8 @@ jobs:
# Deploy swarm stacks only on main branch # Deploy swarm stacks only on main branch
if [ '${{ github.ref_name }}' = 'main' ]; then if [ '${{ github.ref_name }}' = 'main' ]; then
source .env source ${{ env.APP_DIR }}/.env
docker stack deploy -c docker-compose.yml rose-ash docker stack deploy --resolve-image always -c docker-compose.yml rose-ash
echo 'Waiting for swarm services to update...' echo 'Waiting for swarm services to update...'
sleep 10 sleep 10
docker stack services rose-ash docker stack services rose-ash
@@ -99,17 +103,17 @@ jobs:
fi fi
if [ \"\$SX_REBUILT\" = true ]; then if [ \"\$SX_REBUILT\" = true ]; then
echo 'Deploying sx-web stack (sx-web.org)...' echo 'Deploying sx-web stack (sx-web.org)...'
docker stack deploy -c /root/sx-web/docker-compose.yml sx-web docker stack deploy --resolve-image always -c /root/sx-web/docker-compose.yml sx-web
sleep 5 sleep 5
docker stack services sx-web docker stack services sx-web
# Reload Caddy to pick up any Caddyfile changes
docker service update --force caddy_caddy 2>/dev/null || true docker service update --force caddy_caddy 2>/dev/null || true
fi fi
else else
echo 'Skipping swarm deploy (branch: ${{ github.ref_name }})' echo 'Skipping swarm deploy (branch: ${{ github.ref_name }})'
fi fi
# Dev stack always deployed (bind-mounted source + auto-reload) # Dev stack uses working tree (bind-mounted source + auto-reload)
cd ${{ env.APP_DIR }}
echo 'Deploying dev stack...' echo 'Deploying dev stack...'
docker compose -p rose-ash-dev -f docker-compose.yml -f docker-compose.dev.yml up -d docker compose -p rose-ash-dev -f docker-compose.yml -f docker-compose.dev.yml up -d
echo 'Dev stack deployed' echo 'Dev stack deployed'