1+ name : Weekly Database Dump
2+
3+ on :
4+ schedule :
5+ # Run every Monday at 2 AM UTC
6+ - cron : ' 0 2 * * 1'
7+ workflow_dispatch : # Allow manual trigger
8+
9+ jobs :
10+ dump-database :
11+ runs-on : ubuntu-latest
12+ permissions :
13+ contents : read
14+ actions : write
15+
16+ steps :
17+ - name : Set up PostgreSQL client
18+ run : |
19+ sudo apt-get update
20+ sudo apt-get install -y postgresql-client
21+
22+ - name : Create dump directory
23+ run : mkdir -p database_dumps
24+
25+ - name : Dump database (excluding users table)
26+ env :
27+ DATABASE_URL : ${{ secrets.DATABASE_URL }}
28+ run : |
29+ # Parse DATABASE_URL to extract connection details
30+ export PGHOST=$(echo $DATABASE_URL | sed -E 's/.*@([^:\/]+).*/\1/')
31+ export PGPORT=$(echo $DATABASE_URL | sed -E 's/.*:([0-9]+)\/.*/\1/')
32+ export PGDATABASE=$(echo $DATABASE_URL | sed -E 's/.*\/([^?]*).*/\1/')
33+ export PGUSER=$(echo $DATABASE_URL | sed -E 's/postgres:\/\/([^:]+):.*/\1/')
34+ export PGPASSWORD=$(echo $DATABASE_URL | sed -E 's/postgres:\/\/[^:]+:([^@]+)@.*/\1/')
35+
36+ # Create dump excluding users table
37+ DUMP_FILE="database_dumps/db_dump_$(date +%Y%m%d_%H%M%S).sql"
38+
39+ # Dump schema and data, excluding the users table
40+ pg_dump --no-owner --no-privileges \
41+ --exclude-table=users \
42+ --exclude-table=schema_migrations \
43+ --exclude-table=ar_internal_metadata \
44+ -f "$DUMP_FILE"
45+
46+ # Compress the dump
47+ gzip "$DUMP_FILE"
48+ echo "DUMP_FILE=${DUMP_FILE}.gz" >> $GITHUB_ENV
49+ echo "Dump created: ${DUMP_FILE}.gz"
50+
51+ - name : Upload dump as artifact using GitHub API
52+ env :
53+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
54+ run : |
55+ # Get the dump file name
56+ DUMP_FILE_NAME=$(basename "$DUMP_FILE")
57+
58+ # Create a unique artifact name with timestamp
59+ ARTIFACT_NAME="database-dump-$(date +%Y%m%d-%H%M%S)"
60+
61+ # Get workflow run ID
62+ RUN_ID="${{ github.run_id }}"
63+
64+ # Create artifact upload
65+ echo "Creating artifact upload..."
66+ UPLOAD_RESPONSE=$(curl -L \
67+ -X POST \
68+ -H "Accept: application/vnd.github+json" \
69+ -H "Authorization: Bearer $GITHUB_TOKEN" \
70+ -H "X-GitHub-Api-Version: 2022-11-28" \
71+ "https://api.github.com/repos/${{ github.repository }}/actions/runs/${RUN_ID}/artifacts" \
72+ -d "{\"name\":\"${ARTIFACT_NAME}\", \"retention_days\": 30}")
73+
74+ # Extract upload URL and other details
75+ UPLOAD_URL=$(echo "$UPLOAD_RESPONSE" | jq -r '.upload_url')
76+ ARTIFACT_ID=$(echo "$UPLOAD_RESPONSE" | jq -r '.id')
77+
78+ if [ "$UPLOAD_URL" = "null" ] || [ -z "$UPLOAD_URL" ]; then
79+ echo "Failed to create artifact upload"
80+ echo "Response: $UPLOAD_RESPONSE"
81+ exit 1
82+ fi
83+
84+ # Upload the file
85+ echo "Uploading dump file..."
86+ curl -L \
87+ -X PUT \
88+ -H "Accept: application/vnd.github+json" \
89+ -H "Authorization: Bearer $GITHUB_TOKEN" \
90+ -H "X-GitHub-Api-Version: 2022-11-28" \
91+ -H "Content-Type: application/gzip" \
92+ --data-binary "@$DUMP_FILE" \
93+ "$UPLOAD_URL"
94+
95+ # Finalize the artifact
96+ echo "Finalizing artifact..."
97+ curl -L \
98+ -X POST \
99+ -H "Accept: application/vnd.github+json" \
100+ -H "Authorization: Bearer $GITHUB_TOKEN" \
101+ -H "X-GitHub-Api-Version: 2022-11-28" \
102+ "https://api.github.com/repos/${{ github.repository }}/actions/artifacts/${ARTIFACT_ID}/finalize"
103+
104+ echo "Database dump uploaded as artifact: ${ARTIFACT_NAME}"
105+
106+ - name : Clean up old artifacts
107+ env :
108+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
109+ run : |
110+ # Keep only the last 4 weeks of dumps (delete artifacts older than 28 days)
111+ echo "Cleaning up old database dump artifacts..."
112+
113+ # Get all artifacts with name starting with "database-dump-"
114+ ARTIFACTS=$(curl -L \
115+ -H "Accept: application/vnd.github+json" \
116+ -H "Authorization: Bearer $GITHUB_TOKEN" \
117+ -H "X-GitHub-Api-Version: 2022-11-28" \
118+ "https://api.github.com/repos/${{ github.repository }}/actions/artifacts?per_page=100" | \
119+ jq -r '.artifacts[] | select(.name | startswith("database-dump-")) | "\(.id)|\(.created_at)"')
120+
121+ # Delete artifacts older than 28 days
122+ CUTOFF_DATE=$(date -d '28 days ago' +%s)
123+
124+ echo "$ARTIFACTS" | while IFS='|' read -r artifact_id created_at; do
125+ if [ -n "$artifact_id" ]; then
126+ ARTIFACT_DATE=$(date -d "$created_at" +%s)
127+ if [ "$ARTIFACT_DATE" -lt "$CUTOFF_DATE" ]; then
128+ echo "Deleting old artifact ID: $artifact_id (created: $created_at)"
129+ curl -L \
130+ -X DELETE \
131+ -H "Accept: application/vnd.github+json" \
132+ -H "Authorization: Bearer $GITHUB_TOKEN" \
133+ -H "X-GitHub-Api-Version: 2022-11-28" \
134+ "https://api.github.com/repos/${{ github.repository }}/actions/artifacts/$artifact_id"
135+ fi
136+ fi
137+ done
0 commit comments