update #12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Bytebase Export SQL | |
on: | |
pull_request: | |
types: [closed] | |
branches: | |
- main | |
paths: | |
- 'export/**' | |
workflow_dispatch: | |
jobs: | |
bytebase-export: | |
if: github.event.pull_request.merged == true | |
runs-on: ubuntu-latest | |
permissions: | |
pull-requests: write | |
issues: write | |
contents: read | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ github.event.pull_request.head.sha }} | |
fetch-depth: 0 | |
- name: Login Bytebase | |
id: bytebase-login | |
uses: bytebase/[email protected] | |
with: | |
bytebase-url: ${{ secrets.BYTEBASE_URL }} | |
service-key: ${{ secrets.BYTEBASE_SERVICE_KEY }} | |
service-secret: ${{ secrets.BYTEBASE_SERVICE_SECRET }} | |
- name: Get changed files | |
id: changed-files | |
uses: tj-actions/changed-files@v42 | |
with: | |
files: | | |
export/**/*.sql | |
since_last_remote_commit: true | |
- name: Install jq | |
run: sudo apt-get install -y jq | |
- name: Process SQL files | |
id: process-sql | |
if: steps.changed-files.outputs.any_changed == 'true' | |
run: | | |
# Find and read manifest.toml | |
MANIFEST_PATH="" | |
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do | |
DIR_PATH=$(dirname "$file") | |
while [[ "$DIR_PATH" == export* ]]; do | |
if [[ -f "$DIR_PATH/manifest.toml" ]]; then | |
MANIFEST_PATH="$DIR_PATH/manifest.toml" | |
break 2 | |
fi | |
DIR_PATH=$(dirname "$DIR_PATH") | |
done | |
done | |
if [[ -z "$MANIFEST_PATH" ]]; then | |
echo "Error: No manifest.toml found in the export directory" | |
exit 1 | |
fi | |
echo "Found manifest file at: $MANIFEST_PATH" | |
echo "Manifest contents:" | |
cat "$MANIFEST_PATH" | |
# Parse TOML file | |
read_toml() { | |
local key="$1" | |
python3 -c "import tomllib; print(tomllib.load(open('$MANIFEST_PATH', 'rb')).get('$key', ''))" | |
} | |
PROJECT=$(read_toml "project") || exit 1 | |
INSTANCE=$(read_toml "instance") || exit 1 | |
DATABASE=$(read_toml "database") || exit 1 | |
FORMAT=$(read_toml "format") || FORMAT="JSON" | |
echo "=== Parsed Configuration ===" | |
echo "Project: $PROJECT" | |
echo "Instance: $INSTANCE" | |
echo "Database: $DATABASE" | |
echo "Format: $FORMAT" | |
echo "===========================" | |
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do | |
echo "Processing $file" | |
SQL_CONTENT=$(base64 < "$file") | |
STEP_ID=$(python3 -c "import uuid; print(str(uuid.uuid4()))") | |
BASE_URL="${{ steps.bytebase-login.outputs.api_url }}" | |
# Create Sheet | |
echo "Creating sheet..." | |
sheet_response=$(curl -s -X POST "$BASE_URL/projects/$PROJECT/sheets" \ | |
-H "Authorization: Bearer ${{ steps.bytebase-login.outputs.token }}" \ | |
-H "Content-Type: application/json" \ | |
-d "{\"title\":\"\",\"content\":\"$SQL_CONTENT\",\"type\":\"TYPE_SQL\",\"source\":\"SOURCE_BYTEBASE_ARTIFACT\",\"visibility\":\"VISIBILITY_PUBLIC\"}") | |
SHEET_NAME=$(echo "$sheet_response" | jq -r '.name') | |
echo "Sheet created: $SHEET_NAME" | |
# Create Plan | |
echo "Creating plan..." | |
plan_response=$(curl -s -X POST "$BASE_URL/projects/$PROJECT/plans" \ | |
-H "Authorization: Bearer ${{ steps.bytebase-login.outputs.token }}" \ | |
-H "Content-Type: application/json" \ | |
-d "{\"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\"}") | |
PLAN_NAME=$(echo "$plan_response" | jq -r '.name') | |
echo "Plan created: $PLAN_NAME" | |
# Create Issue | |
echo "Creating issue..." | |
issue_response=$(curl -s -X POST "$BASE_URL/projects/$PROJECT/issues" \ | |
-H "Authorization: Bearer ${{ steps.bytebase-login.outputs.token }}" \ | |
-H "Content-Type: application/json" \ | |
-d "{\"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\"}") | |
ISSUE_NUMBER=$(echo "$issue_response" | jq -r '.name | split("/")[-1]') | |
ISSUE_LINK="${{ secrets.BYTEBASE_URL }}/projects/$PROJECT/issues/$ISSUE_NUMBER" | |
echo "Issue created: $ISSUE_LINK" | |
# Create Rollout | |
echo "Creating rollout..." | |
rollout_response=$(curl -s -X POST "$BASE_URL/projects/$PROJECT/rollouts" \ | |
-H "Authorization: Bearer ${{ steps.bytebase-login.outputs.token }}" \ | |
-H "Content-Type: application/json" \ | |
-d "{\"plan\":\"$PLAN_NAME\"}") | |
echo "Rollout created: $(echo "$rollout_response" | jq -r '.name')" | |
done | |
- name: Comment on PR | |
uses: actions/github-script@v7 | |
if: always() | |
env: | |
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} | |
with: | |
script: | | |
const changedFiles = process.env.CHANGED_FILES || ''; | |
let commentBody = `### SQL Export Summary\n\n`; | |
commentBody += `✅ **PR Status:** Merged\n\n`; | |
commentBody += `📝 **Processed SQL Files:**\n\n`; | |
if (changedFiles.trim()) { | |
commentBody += changedFiles.split(' ').map(f => `- ${f}`).join('\n'); | |
} else { | |
commentBody += `None`; | |
} | |
commentBody += `\n\n**Status:** ${process.env.STATUS || 'Completed'}`; | |
await github.rest.issues.createComment({ | |
...context.repo, | |
issue_number: context.issue.number, | |
body: commentBody | |
}); |