docs: update masking #3
This file contains 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 Masking Policy Update | |
on: | |
pull_request: | |
types: [opened, synchronize, reopened] | |
branches: | |
- main | |
- develop | |
workflow_dispatch: | |
jobs: | |
bytebase-masking: | |
runs-on: ubuntu-latest | |
permissions: | |
pull-requests: write | |
issues: write | |
contents: read | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- 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: | | |
masking/databases/**/**/column-masking.json | |
masking/projects/**/masking-exception.json | |
- name: Debug changed files in detail | |
run: | | |
echo "All changed files:" | |
echo "${{ steps.changed-files.outputs.all_changed_files }}" | |
echo "Contains column-masking.json: ${{ contains(steps.changed-files.outputs.all_changed_files, 'column-masking.json') }}" | |
echo "Contains masking-exception.json: ${{ contains(steps.changed-files.outputs.all_changed_files, 'masking-exception.json') }}" | |
echo "Raw output:" | |
echo "${{ toJSON(steps.changed-files.outputs) }}" | |
- name: Apply column masking policy | |
id: apply-column-masking | |
if: ${{ steps.changed-files.outputs.any_changed == 'true' && contains(steps.changed-files.outputs.all_changed_files, '/column-masking.json') }} | |
run: | | |
# Process all column-masking.json files | |
echo "${{ steps.changed-files.outputs.all_changed_files }}" | tr ' ' '\n' | grep "column-masking.json" | while read -r CHANGED_FILE; do | |
echo "Processing: $CHANGED_FILE" | |
INSTANCE_NAME=$(echo "$CHANGED_FILE" | sed -n 's/masking\/databases\/\([^/]*\)\/\([^/]*\).*/\1/p') | |
DATABASE_NAME=$(echo "$CHANGED_FILE" | sed -n 's/masking\/databases\/\([^/]*\)\/\([^/]*\).*/\2/p') | |
echo "INSTANCE_NAME=$INSTANCE_NAME" | |
echo "DATABASE_NAME=$DATABASE_NAME" | |
response=$(curl -s -w "\n%{http_code}" --request PATCH "${{ steps.bytebase-login.outputs.api_url }}/instances/${INSTANCE_NAME}/databases/${DATABASE_NAME}/policies/masking?allow_missing=true&update_mask=payload" \ | |
--header "Authorization: Bearer ${{ steps.bytebase-login.outputs.token }}" \ | |
--header "Content-Type: application/json" \ | |
--data @"$CHANGED_FILE") | |
# Extract status code and response body | |
status_code=$(echo "$response" | tail -n1) | |
body=$(echo "$response" | sed '$d') | |
echo "Status code: $status_code" | |
echo "Response body: $body" | |
# Append to outputs (with unique identifiers) | |
echo "status_code_${DATABASE_NAME}=${status_code}" >> $GITHUB_OUTPUT | |
echo "response_${DATABASE_NAME}<<EOF" >> $GITHUB_OUTPUT | |
echo "${body}" >> $GITHUB_OUTPUT | |
echo "EOF" >> $GITHUB_OUTPUT | |
if [[ $status_code -lt 200 || $status_code -ge 300 ]]; then | |
echo "Failed with status code: $status_code for database: $DATABASE_NAME" | |
exit 1 | |
fi | |
done | |
- name: Apply masking exception policy | |
id: apply-masking-exception | |
if: ${{ steps.changed-files.outputs.any_changed == 'true' && contains(steps.changed-files.outputs.all_changed_files, '/masking-exception.json') }} | |
run: | | |
# Process all masking-exception.json files | |
echo "${{ steps.changed-files.outputs.all_changed_files }}" | tr ' ' '\n' | grep "masking-exception.json" | while read -r CHANGED_FILE; do | |
echo "Processing: $CHANGED_FILE" | |
PROJECT_NAME=$(echo "$CHANGED_FILE" | sed -n 's/masking\/projects\/\([^/]*\).*/\1/p') | |
echo "PROJECT_NAME=$PROJECT_NAME" | |
response=$(curl -s -w "\n%{http_code}" --request PATCH "${{ steps.bytebase-login.outputs.api_url }}/projects/${PROJECT_NAME}/policies/masking_exception?allow_missing=true&update_mask=payload" \ | |
--header "Authorization: Bearer ${{ steps.bytebase-login.outputs.token }}" \ | |
--header "Content-Type: application/json" \ | |
--data @"$CHANGED_FILE") | |
# Extract status code and response body | |
status_code=$(echo "$response" | tail -n1) | |
body=$(echo "$response" | sed '$d') | |
echo "Status code: $status_code" | |
echo "Response body: $body" | |
# Append to outputs (with unique identifiers) | |
echo "status_code_${PROJECT_NAME}=${status_code}" >> $GITHUB_OUTPUT | |
echo "response_${PROJECT_NAME}<<EOF" >> $GITHUB_OUTPUT | |
echo "${body}" >> $GITHUB_OUTPUT | |
echo "EOF" >> $GITHUB_OUTPUT | |
if [[ $status_code -lt 200 || $status_code -ge 300 ]]; then | |
echo "Failed with status code: $status_code for project: $PROJECT_NAME" | |
exit 1 | |
fi | |
done | |
- name: Comment on PR | |
if: github.event_name == 'pull_request' | |
uses: actions/github-script@v7 | |
env: | |
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} | |
with: | |
script: | | |
const changedFiles = process.env.CHANGED_FILES || ''; | |
let commentBody = `### Masking Policy Update Summary\n\n`; | |
// Add changed files section | |
commentBody += `📝 **Changed Files:**\n\n`; | |
if (changedFiles.trim()) { | |
commentBody += changedFiles.split(' ').map(f => `- ${f}`).join('\n'); | |
} else { | |
commentBody += `None`; | |
} | |
commentBody += '\n\n'; | |
// Add API calls summary | |
commentBody += `🔄 **API Calls:**\n\n`; | |
let apiCallsFound = false; | |
if (changedFiles.includes('column-masking.json')) { | |
const maskingStatuses = Object.keys(${{ toJSON(steps.apply-column-masking.outputs) }} || {}) | |
.filter(key => key.startsWith('status_code_')) | |
.map(key => ({ | |
name: key.replace('status_code_', ''), | |
status: ${{ toJSON(steps.apply-column-masking.outputs) }}[key] | |
})); | |
maskingStatuses.forEach(({name, status}) => { | |
apiCallsFound = true; | |
const success = status >= 200 && status < 300; | |
commentBody += `- Column Masking (${name}): ${success ? '✅' : '❌'} ${status}\n`; | |
}); | |
} | |
if (changedFiles.includes('masking-exception.json')) { | |
const exceptionStatuses = Object.keys(${{ toJSON(steps.apply-masking-exception.outputs) }} || {}) | |
.filter(key => key.startsWith('status_code_')) | |
.map(key => ({ | |
name: key.replace('status_code_', ''), | |
status: ${{ toJSON(steps.apply-masking-exception.outputs) }}[key] | |
})); | |
exceptionStatuses.forEach(({name, status}) => { | |
apiCallsFound = true; | |
const success = status >= 200 && status < 300; | |
commentBody += `- Masking Exception (${name}): ${success ? '✅' : '❌'} ${status}\n`; | |
}); | |
} | |
if (!apiCallsFound) { | |
commentBody += `None`; | |
} | |
await github.rest.issues.createComment({ | |
...context.repo, | |
issue_number: context.issue.number, | |
body: commentBody | |
}); |