91 lines
3.4 KiB
YAML
91 lines
3.4 KiB
YAML
name: CI/CD
|
|
# Runner capacity: 1 (sequential) to prevent OOM on shared host
|
|
|
|
on:
|
|
push:
|
|
branches: [dev, main]
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
env:
|
|
REGISTRY: gitea.jeffemmett.com
|
|
IMAGE: gitea.jeffemmett.com/jeffemmett/canvas-website
|
|
|
|
jobs:
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
run: |
|
|
apt-get update -qq && apt-get install -y -qq git > /dev/null 2>&1
|
|
git clone --depth 1 --branch ${{ github.ref_name }} http://token:${{ github.token }}@server:3000/${{ github.repository }}.git .
|
|
|
|
- name: Install dependencies
|
|
run: npm ci --legacy-peer-deps --ignore-scripts
|
|
|
|
- name: Type check
|
|
run: npx tsc --noEmit
|
|
|
|
- name: Unit tests
|
|
run: npx vitest run
|
|
|
|
- name: Worker tests
|
|
run: npx vitest run --config vitest.worker.config.ts || echo "::warning::Worker tests had failures"
|
|
|
|
deploy:
|
|
if: ${{ github.ref == 'refs/heads/main' && github.event_name == 'push' }}
|
|
needs: [test]
|
|
runs-on: ubuntu-latest
|
|
container:
|
|
image: docker:24-cli
|
|
steps:
|
|
- name: Setup tools
|
|
run: apk add --no-cache git openssh-client curl
|
|
|
|
- name: Checkout
|
|
run: git clone --depth 1 --branch ${{ github.ref_name }} http://token:${{ github.token }}@server:3000/${{ github.repository }}.git .
|
|
|
|
- name: Set image tag
|
|
run: |
|
|
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-8)
|
|
echo "IMAGE_TAG=${SHORT_SHA}" >> $GITHUB_ENV
|
|
echo "Building image tag: ${SHORT_SHA}"
|
|
|
|
- name: Build image
|
|
run: docker build -t ${{ env.IMAGE }}:${{ env.IMAGE_TAG }} -t ${{ env.IMAGE }}:latest .
|
|
|
|
- name: Push to registry
|
|
run: |
|
|
echo "${{ secrets.REGISTRY_TOKEN }}" | docker login ${{ env.REGISTRY }} -u ${{ secrets.REGISTRY_USER }} --password-stdin
|
|
docker push ${{ env.IMAGE }}:${{ env.IMAGE_TAG }}
|
|
docker push ${{ env.IMAGE }}:latest
|
|
|
|
- name: Deploy to server
|
|
run: |
|
|
mkdir -p ~/.ssh
|
|
echo "${{ secrets.DEPLOY_SSH_KEY }}" | base64 -d > ~/.ssh/deploy_key
|
|
chmod 600 ~/.ssh/deploy_key
|
|
ssh -o StrictHostKeyChecking=no -i ~/.ssh/deploy_key root@${{ secrets.DEPLOY_HOST }} "
|
|
cd /opt/websites/canvas-website-staging
|
|
cat .last-deployed-tag 2>/dev/null > .rollback-tag || true
|
|
echo '${{ env.IMAGE_TAG }}' > .last-deployed-tag
|
|
docker pull ${{ env.IMAGE }}:${{ env.IMAGE_TAG }}
|
|
IMAGE_TAG=${{ env.IMAGE_TAG }} docker compose up -d --no-build
|
|
"
|
|
|
|
- name: Smoke test
|
|
run: |
|
|
sleep 10
|
|
HTTP_CODE=$(curl -sS -o /dev/null -w "%{http_code}" --max-time 15 https://jeffemmett.com/ 2>/dev/null || echo "000")
|
|
if [ "$HTTP_CODE" != "200" ]; then
|
|
echo "Smoke test failed (HTTP $HTTP_CODE) — rolling back"
|
|
ROLLBACK_TAG=$(ssh -o StrictHostKeyChecking=no -i ~/.ssh/deploy_key root@${{ secrets.DEPLOY_HOST }} "cat /opt/websites/canvas-website-staging/.rollback-tag 2>/dev/null")
|
|
if [ -n "$ROLLBACK_TAG" ]; then
|
|
ssh -o StrictHostKeyChecking=no -i ~/.ssh/deploy_key root@${{ secrets.DEPLOY_HOST }} \
|
|
"cd /opt/websites/canvas-website-staging && IMAGE_TAG=$ROLLBACK_TAG docker compose up -d --no-build"
|
|
echo "Rolled back to $ROLLBACK_TAG"
|
|
fi
|
|
exit 1
|
|
fi
|
|
echo "Smoke test passed (HTTP $HTTP_CODE)"
|