Skip to content

Commit 01a67ae

Browse files
authored
Merge pull request #103 from BuildCanada/db-dump
Add weekly database dump workflow
2 parents 662e729 + 8d4eda6 commit 01a67ae

1 file changed

Lines changed: 137 additions & 0 deletions

File tree

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
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

Comments
 (0)