diff --git a/.github/workflows/staging-pipeline.yml b/.github/workflows/staging-pipeline.yml index 59ae8c2..a517045 100644 --- a/.github/workflows/staging-pipeline.yml +++ b/.github/workflows/staging-pipeline.yml @@ -7,9 +7,16 @@ on: pull_request: branches: - staging + +# Least-privilege GITHUB_TOKEN: deny everything at the workflow level, then grant +# only what each job actually needs (see per-job `permissions` below). +permissions: {} + jobs: test: runs-on: ubuntu-latest + permissions: + contents: read services: # Label used to access the service container redis: @@ -56,6 +63,9 @@ jobs: publish: needs: test runs-on: ubuntu-latest + permissions: + contents: read + packages: write if: github.event_name == 'push' steps: - name: Check out the repo @@ -83,6 +93,8 @@ jobs: deploy: needs: publish runs-on: ubuntu-latest + # No GITHUB_TOKEN needed: the SSH action authenticates with a deploy key. + permissions: {} steps: - name: SSH and Redeploy uses: appleboy/ssh-action@v1.0.0 @@ -92,8 +104,18 @@ jobs: key: ${{ secrets.STAGING_PRIVATE_KEY_ALL }} port: ${{ secrets.SSH_PORT }} script: | + set -e cd giveth-all - docker-compose stop notification-center - docker-compose pull notification-center - docker-compose up -d notification-center - docker image prune -a --force + # Use docker compose v2 (host has v2.40.0). The old `docker-compose` + # v1.29.2 crashes with `KeyError: 'ContainerConfig'` when recreating a + # BuildKit-format image (it choked on the redis-all dep), which left NC + # stopped-and-not-restarted while the run still went green — the failure + # was masked by the trailing `prune` (last command, exit 0). `set -e` + # makes a failed deploy fail RED; `-f docker-compose.staging.yml` pins the + # staging image tag deterministically; `--no-deps` avoids churning + # redis-all. Mirrors the prod (main) pipeline, which already uses v2. + docker compose -f docker-compose.staging.yml pull notification-center + docker compose -f docker-compose.staging.yml up -d --no-deps notification-center + # Best-effort cleanup — never fail an already-successful deploy if prune + # errors (e.g. an image still in use); `set -e` would otherwise turn it red. + docker image prune -a --force || echo "Image cleanup failed (non-fatal)" >&2