Skip to content

Commit bd508a8

Browse files
Merge pull request #82 from bytebase/a-branch-23
update
2 parents 4f89bf7 + 089c3cc commit bd508a8

File tree

2 files changed

+205
-0
lines changed

2 files changed

+205
-0
lines changed

.github/workflows/4-bb-export.yml

+205
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
name: Bytebase Export SQL
2+
on:
3+
pull_request:
4+
types: [closed]
5+
branches:
6+
- main
7+
paths:
8+
- 'export/**'
9+
workflow_dispatch:
10+
11+
jobs:
12+
bytebase-export:
13+
if: github.event.pull_request.merged == true
14+
runs-on: ubuntu-latest
15+
permissions:
16+
pull-requests: write
17+
issues: write
18+
contents: read
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
with:
23+
ref: ${{ github.event.pull_request.head.sha }}
24+
fetch-depth: 0
25+
26+
- name: Login Bytebase
27+
id: bytebase-login
28+
uses: bytebase/[email protected]
29+
with:
30+
bytebase-url: ${{ secrets.BYTEBASE_URL }}
31+
service-key: ${{ secrets.BYTEBASE_SERVICE_KEY }}
32+
service-secret: ${{ secrets.BYTEBASE_SERVICE_SECRET }}
33+
34+
- name: Get changed files
35+
id: changed-files
36+
uses: tj-actions/changed-files@v42
37+
with:
38+
files: |
39+
export/**/*.sql
40+
since_last_remote_commit: true
41+
42+
- name: Process SQL files
43+
id: process-sql
44+
if: steps.changed-files.outputs.any_changed == 'true'
45+
run: |
46+
call_api() {
47+
local url="$1"
48+
local method="$2"
49+
local data="$3"
50+
local description="$4"
51+
52+
echo "=== DEBUG: API Call Details ==="
53+
echo "Description: $description"
54+
echo "URL: $url"
55+
echo "Method: $method"
56+
echo "Data: $data"
57+
58+
temp_file=$(mktemp)
59+
http_code=$(curl -v -s -w "%{http_code}" \
60+
--request "$method" "$url" \
61+
--header "Authorization: Bearer ${{ steps.bytebase-login.outputs.token }}" \
62+
--header "Content-Type: application/json" \
63+
--data "$data" \
64+
-o "$temp_file" 2>&1)
65+
66+
echo "=== DEBUG: Response Details ==="
67+
echo "HTTP Status: $http_code"
68+
echo "Response body:"
69+
cat "$temp_file"
70+
echo "==========================="
71+
72+
if [[ $http_code -lt 200 || $http_code -ge 300 ]]; then
73+
echo "Error: Failed $description. Status: $http_code"
74+
cat "$temp_file"
75+
rm "$temp_file"
76+
return 1
77+
fi
78+
79+
if [[ ! -s "$temp_file" ]]; then
80+
echo "Error: Empty response from server"
81+
rm "$temp_file"
82+
return 1
83+
fi
84+
85+
# Simple one-line JSON validation
86+
if ! python3 -c "import json,sys; json.load(open('$temp_file'))" 2>/dev/null; then
87+
echo "Error: Invalid JSON response"
88+
echo "Response content:"
89+
cat "$temp_file"
90+
rm "$temp_file"
91+
return 1
92+
fi
93+
94+
cat "$temp_file"
95+
rm "$temp_file"
96+
return 0
97+
}
98+
99+
MANIFEST_PATH=""
100+
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
101+
DIR_PATH=$(dirname "$file")
102+
while [[ "$DIR_PATH" == export* ]]; do
103+
if [[ -f "$DIR_PATH/manifest.toml" ]]; then
104+
MANIFEST_PATH="$DIR_PATH/manifest.toml"
105+
break 2
106+
fi
107+
DIR_PATH=$(dirname "$DIR_PATH")
108+
done
109+
done
110+
111+
if [[ -z "$MANIFEST_PATH" ]]; then
112+
echo "Error: No manifest.toml found in the export directory"
113+
exit 1
114+
fi
115+
116+
echo "Found manifest file at: $MANIFEST_PATH"
117+
echo "Manifest contents:"
118+
cat "$MANIFEST_PATH"
119+
120+
read_toml() {
121+
local key="$1"
122+
python3 -c "import tomllib; print(tomllib.load(open('$MANIFEST_PATH', 'rb')).get('$key', ''))"
123+
}
124+
125+
PROJECT=$(read_toml "project") || exit 1
126+
INSTANCE=$(read_toml "instance") || exit 1
127+
DATABASE=$(read_toml "database") || exit 1
128+
FORMAT=$(read_toml "format") || FORMAT="JSON"
129+
130+
echo "=== Parsed Configuration ==="
131+
echo "Project: $PROJECT"
132+
echo "Instance: $INSTANCE"
133+
echo "Database: $DATABASE"
134+
echo "Format: $FORMAT"
135+
echo "==========================="
136+
137+
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
138+
echo "Processing $file"
139+
SQL_CONTENT=$(base64 < "$file")
140+
echo "SQL_CONTENT=$SQL_CONTENT" >> $GITHUB_ENV
141+
STEP_ID=$(python3 -c "import uuid; print(str(uuid.uuid4()))")
142+
echo "STEP_ID=$STEP_ID" >> $GITHUB_ENV
143+
BASE_URL="${{ steps.bytebase-login.outputs.api_url }}"
144+
echo "BASE_URL1111=$BASE_URL"
145+
echo "BASE_URL=$BASE_URL" >> $GITHUB_ENV
146+
147+
sheet_data=$(call_api \
148+
"$BASE_URL/projects/$PROJECT/sheets" \
149+
"POST" \
150+
"{\"title\":\"\",\"content\":\"$SQL_CONTENT\",\"type\":\"TYPE_SQL\",\"source\":\"SOURCE_BYTEBASE_ARTIFACT\",\"visibility\":\"VISIBILITY_PUBLIC\"}" \
151+
"Create Sheet")
152+
153+
SHEET_NAME=$(echo "$sheet_data" | python3 -c "import sys, json; print(json.load(sys.stdin)['name'])")
154+
155+
plan_data=$(call_api \
156+
"$BASE_URL/projects/$PROJECT/plans" \
157+
"POST" \
158+
"{\"steps\":[{\"specs\":[{\"id\":\"$STEP_ID\",\"export_data_config\":{\"target\":\"/instances/$INSTANCE/databases/$DATABASE\",\"format\":\"$FORMAT\",\"sheet\":\"$SHEET_NAME\"}}]}],\"title\":\"Export data from $DATABASE\",\"description\":\"EXPORT\"}" \
159+
"Create Plan")
160+
161+
PLAN_NAME=$(echo "$plan_data" | python3 -c "import sys, json; print(json.load(sys.stdin)['name'])")
162+
163+
issue_data=$(call_api \
164+
"$BASE_URL/projects/$PROJECT/issues" \
165+
"POST" \
166+
"{\"approvers\":[],\"approvalTemplates\":[],\"subscribers\":[],\"title\":\"Issue: Export data from instances/$INSTANCE/databases/$DATABASE\",\"description\":\"SQL request from GitHub\",\"type\":\"DATABASE_DATA_EXPORT\",\"assignee\":\"\",\"plan\":\"$PLAN_NAME\"}" \
167+
"Create Issue")
168+
169+
rollout_data=$(call_api \
170+
"$BASE_URL/projects/$PROJECT/rollouts" \
171+
"POST" \
172+
"{\"plan\":\"$PLAN_NAME\"}" \
173+
"Create Rollout")
174+
175+
ISSUE_NUMBER=$(echo "$issue_data" | python3 -c "import sys, json; print(json.load(sys.stdin)['name'].split('/')[-1])")
176+
ISSUE_LINK="${{ secrets.BYTEBASE_URL }}/projects/$PROJECT/issues/$ISSUE_NUMBER"
177+
echo "ISSUE_LINK=$ISSUE_LINK" >> $GITHUB_ENV
178+
done
179+
180+
- name: Comment on PR
181+
uses: actions/github-script@v7
182+
if: always()
183+
env:
184+
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
185+
with:
186+
script: |
187+
const changedFiles = process.env.CHANGED_FILES || '';
188+
let commentBody = `### SQL Export Summary\n\n`;
189+
190+
commentBody += `✅ **PR Status:** Merged\n\n`;
191+
192+
commentBody += `📝 **Processed SQL Files:**\n\n`;
193+
if (changedFiles.trim()) {
194+
commentBody += changedFiles.split(' ').map(f => `- ${f}`).join('\n');
195+
} else {
196+
commentBody += `None`;
197+
}
198+
199+
commentBody += `\n\n**Status:** ${process.env.STATUS || 'Completed'}`;
200+
201+
await github.rest.issues.createComment({
202+
...context.repo,
203+
issue_number: context.issue.number,
204+
body: commentBody
205+
});

0 commit comments

Comments
 (0)