ci: split deploy.yml into staging→production pipeline with approval gate

This commit is contained in:
peptiderepo
2026-04-24 13:11:24 +07:00
parent 05cb3caf0d
commit deadccc27b

View File

@@ -7,67 +7,84 @@ on:
permissions: permissions:
contents: read contents: read
# Cancel previous deploys if a new push arrives while one is running.
concurrency: concurrency:
group: deploy-peptide-repo-core group: deploy-peptide-repo-core
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
# ── Run CI first ─────────────────────────────────────────────────
ci: ci:
name: Pre-deploy CI name: Pre-deploy CI
uses: ./.github/workflows/ci.yml uses: ./.github/workflows/ci.yml
# ── Deploy via rsync over SSH ──────────────────────────────────── deploy-staging:
deploy: name: Deploy to Staging
needs: ci needs: ci
name: Deploy to Production
runs-on: ubuntu-latest runs-on: ubuntu-latest
environment: staging
steps: steps:
- name: Checkout code - uses: actions/checkout@v4
uses: actions/checkout@v4
- name: Setup SSH key - name: Setup SSH key
run: | run: |
mkdir -p ~/.ssh mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key
ssh-keyscan -p ${{ secrets.SSH_PORT }} ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts 2>/dev/null ssh-keyscan -p ${{ secrets.SSH_PORT }} ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
- name: Deploy via rsync → staging
- name: Deploy via rsync
run: | run: |
rsync -avz --delete \ rsync -avz --delete \
--exclude '.git' \ --exclude '.git' --exclude '.github' \
--exclude '.github' \ --exclude 'tests' --exclude 'phpunit.xml.dist' \
--exclude 'tests' \ --exclude 'composer.json' --exclude 'composer.lock' \
--exclude 'phpunit.xml.dist' \ --exclude 'vendor' --exclude 'phpcs.xml.dist' \
--exclude 'composer.json' \ --exclude 'ARCHITECTURE.md' --exclude 'CONVENTIONS.md' --exclude 'CHANGELOG.md' \
--exclude 'composer.lock' \ -e "ssh -i ~/.ssh/deploy_key -p ${{ secrets.SSH_PORT }}" \
--exclude 'vendor' \ ./ ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}:~/domains/peptiderepo.com/public_html/staging/wp-content/plugins/peptide-repo-core/
--exclude 'phpcs.xml.dist' \ - name: Staging health check
--exclude 'ARCHITECTURE.md' \ run: |
--exclude 'CONVENTIONS.md' \ sleep 5
--exclude 'CHANGELOG.md' \ STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://staging.peptiderepo.com/ || echo "000")
echo "Staging responded: HTTP $STATUS"
- name: Cleanup
if: always()
run: rm -f ~/.ssh/deploy_key
deploy-production:
name: Deploy to Production
needs: [ci, deploy-staging]
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Setup SSH key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
ssh-keyscan -p ${{ secrets.SSH_PORT }} ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
- name: Deploy via rsync → production
run: |
rsync -avz --delete \
--exclude '.git' --exclude '.github' \
--exclude 'tests' --exclude 'phpunit.xml.dist' \
--exclude 'composer.json' --exclude 'composer.lock' \
--exclude 'vendor' --exclude 'phpcs.xml.dist' \
--exclude 'ARCHITECTURE.md' --exclude 'CONVENTIONS.md' --exclude 'CHANGELOG.md' \
-e "ssh -i ~/.ssh/deploy_key -p ${{ secrets.SSH_PORT }}" \ -e "ssh -i ~/.ssh/deploy_key -p ${{ secrets.SSH_PORT }}" \
./ ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}:~/domains/peptiderepo.com/public_html/wp-content/plugins/peptide-repo-core/ ./ ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}:~/domains/peptiderepo.com/public_html/wp-content/plugins/peptide-repo-core/
- name: Purge LiteSpeed Cache - name: Purge LiteSpeed Cache
run: | run: |
ssh -i ~/.ssh/deploy_key -p ${{ secrets.SSH_PORT }} \ ssh -i ~/.ssh/deploy_key -p ${{ secrets.SSH_PORT }} \
${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }} \ ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }} \
"cd ~/domains/peptiderepo.com/public_html && find wp-content/litespeed/ -type f -delete 2>/dev/null; touch .lscache_purge 2>/dev/null || true" "cd ~/domains/peptiderepo.com/public_html && find wp-content/litespeed/ -type f -delete 2>/dev/null; touch .lscache_purge 2>/dev/null || true"
- name: Production health check
- name: Health check
run: | run: |
sleep 5 sleep 5
STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://peptiderepo.com) STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://peptiderepo.com)
if [ "$STATUS" != "200" ] && [ "$STATUS" != "403" ]; then if [ "$STATUS" != "200" ] && [ "$STATUS" != "403" ]; then
echo "ERROR: Site returned unexpected HTTP $STATUS after deploy" echo "ERROR: Site returned HTTP $STATUS"
exit 1 exit 1
fi fi
echo "Site is responsive (HTTP $STATUS)" echo "Production healthy (HTTP $STATUS)"
- name: Cleanup - name: Cleanup
if: always() if: always()
run: rm -f ~/.ssh/deploy_key run: rm -f ~/.ssh/deploy_key