Skip to content

Commit 5c3a28d

Browse files
update
1 parent b511163 commit 5c3a28d

File tree

3 files changed

+175
-4
lines changed

3 files changed

+175
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
name: Bytebase Masking Policy Update Semantic Type and Global Masking Rule
2+
on:
3+
pull_request:
4+
types: [closed]
5+
branches:
6+
- main
7+
workflow_dispatch:
8+
9+
jobs:
10+
bytebase-masking-semantic-type-global:
11+
if: github.event.pull_request.merged == true
12+
runs-on: ubuntu-latest
13+
permissions:
14+
pull-requests: write
15+
issues: write
16+
contents: read
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
with:
21+
ref: ${{ github.event.pull_request.head.sha }}
22+
fetch-depth: 0
23+
24+
- name: Login Bytebase
25+
id: bytebase-login
26+
uses: bytebase/[email protected]
27+
with:
28+
bytebase-url: ${{ secrets.BYTEBASE_URL }}
29+
service-key: ${{ secrets.BYTEBASE_SERVICE_KEY }}
30+
service-secret: ${{ secrets.BYTEBASE_SERVICE_SECRET }}
31+
32+
- name: Get changed files
33+
id: changed-files
34+
uses: tj-actions/changed-files@v42
35+
with:
36+
files: |
37+
masking/masking-algorithm.json
38+
masking/semantic-type.json
39+
since_last_remote_commit: true
40+
fetch_depth: 0
41+
include_all_old_new_renamed_files: true
42+
43+
- name: Debug changed files
44+
run: |
45+
echo "All changed and added files:"
46+
echo "Modified files: ${{ steps.changed-files.outputs.modified_files }}"
47+
echo "Added files: ${{ steps.changed-files.outputs.added_files }}"
48+
echo "All changes: ${{ steps.changed-files.outputs.all_changed_files }}"
49+
50+
- name: Debug changed files in detail
51+
run: |
52+
echo "All changed files:"
53+
echo "${{ steps.changed-files.outputs.all_changed_files }}"
54+
echo "Contains semantic-type.json: ${{ contains(steps.changed-files.outputs.all_changed_files, 'semantic-type.json') }}"
55+
echo "Contains global-masking-rule.json: ${{ contains(steps.changed-files.outputs.all_changed_files, 'global-masking-rule.json') }}"
56+
echo "Raw output:"
57+
echo "${{ toJSON(steps.changed-files.outputs) }}"
58+
59+
- name: Apply semantic type
60+
id: apply-semantic-type
61+
if: ${{ steps.changed-files.outputs.any_changed == 'true' && contains(steps.changed-files.outputs.all_changed_files, 'semantic-type.json') }}
62+
run: |
63+
CHANGED_FILE="masking/semantic-type.json"
64+
echo "Processing: $CHANGED_FILE"
65+
66+
response=$(curl -s -w "\n%{http_code}" --request PATCH "${{ steps.bytebase-login.outputs.api_url }}/settings/bb.workspace.semantic-types?allow_missing=true" \
67+
--header "Authorization: Bearer ${{ steps.bytebase-login.outputs.token }}" \
68+
--header "Content-Type: application/json" \
69+
--data @"$CHANGED_FILE")
70+
71+
# Extract status code and response body
72+
status_code=$(echo "$response" | tail -n1)
73+
body=$(echo "$response" | sed '$d')
74+
75+
echo "status_code=${status_code}" >> $GITHUB_OUTPUT
76+
echo "response_body<<EOF" >> $GITHUB_OUTPUT
77+
echo "${body}" >> $GITHUB_OUTPUT
78+
echo "EOF" >> $GITHUB_OUTPUT
79+
80+
if [[ $status_code -lt 200 || $status_code -ge 300 ]]; then
81+
echo "Failed with status code: $status_code"
82+
exit 1
83+
fi
84+
85+
- name: Apply global masking rule
86+
id: apply-global-masking-rule
87+
if: ${{ steps.changed-files.outputs.any_changed == 'true' && contains(steps.changed-files.outputs.all_changed_files, '/global-masking-rule.json') }}
88+
run: |
89+
# Process all global-masking-rule.json files
90+
echo "${{ steps.changed-files.outputs.all_changed_files }}" | tr ' ' '\n' | grep "global-masking-rule.json" | while read -r CHANGED_FILE; do
91+
echo "Processing: $CHANGED_FILE"
92+
93+
response=$(curl -s -w "\n%{http_code}" --request PATCH "${{ steps.bytebase-login.outputs.api_url }}/policies/masking_rule?allow_missing=true&update_mask=payload" \
94+
--header "Authorization: Bearer ${{ steps.bytebase-login.outputs.token }}" \
95+
--header "Content-Type: application/json" \
96+
--data @"$CHANGED_FILE")
97+
98+
# Extract status code and response body
99+
status_code=$(echo "$response" | tail -n1)
100+
body=$(echo "$response" | sed '$d')
101+
102+
echo "Status code: $status_code"
103+
echo "Response body: $body"
104+
105+
# Append to outputs (with unique identifiers)
106+
echo "${body}" >> $GITHUB_OUTPUT
107+
echo "EOF" >> $GITHUB_OUTPUT
108+
109+
if [[ $status_code -lt 200 || $status_code -ge 300 ]]; then
110+
echo "Failed with status code: $status_code"
111+
exit 1
112+
fi
113+
done
114+
115+
- name: Comment on PR
116+
uses: actions/github-script@v7
117+
env:
118+
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
119+
with:
120+
script: |
121+
const changedFiles = process.env.CHANGED_FILES || '';
122+
let commentBody = `### Update Semantic Type and Global Masking Rule Summary\n\n`;
123+
124+
// Add status of merge
125+
commentBody += `✅ **PR Status:** Merged\n\n`;
126+
127+
// Add changed files section
128+
commentBody += `📝 **Changed Files:**\n\n`;
129+
if (changedFiles.trim()) {
130+
commentBody += changedFiles.split(' ').map(f => `- ${f}`).join('\n');
131+
} else {
132+
commentBody += `None`;
133+
}
134+
commentBody += '\n\n';
135+
136+
// Add API calls summary
137+
commentBody += `🔄 **API Calls:**\n\n`;
138+
let apiCallsFound = false;
139+
140+
if (changedFiles.includes('semantic-type.json')) {
141+
const exceptionStatuses = Object.keys(${{ toJSON(steps.apply-semantic-type.outputs) }} || {})
142+
.filter(key => key.startsWith('status_code_'))
143+
.map(key => ({
144+
name: key.replace('status_code_', ''),
145+
status: ${{ toJSON(steps.apply-semantic-type.outputs) }}[key]
146+
}));
147+
148+
exceptionStatuses.forEach(({name, status}) => {
149+
apiCallsFound = true;
150+
const success = status >= 200 && status < 300;
151+
commentBody += `- Semantic Type (${name}): ${success ? '✅' : '❌'} ${status}\n`;
152+
});
153+
}
154+
155+
if (changedFiles.includes('global-masking-rule.json')) {
156+
const status = ${{ toJSON(steps.apply-global-masking-rule.outputs) }}.status_code;
157+
if (status) {
158+
apiCallsFound = true;
159+
const success = status >= 200 && status < 300;
160+
commentBody += `- Global Masking Rule: ${success ? '✅' : '❌'} ${status}\n`;
161+
}
162+
}
163+
if (!apiCallsFound) {
164+
commentBody += `None`;
165+
}
166+
167+
await github.rest.issues.createComment({
168+
...context.repo,
169+
issue_number: context.issue.number,
170+
body: commentBody
171+
});

masking/global-masking-rule.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"id": "76356d81-6231-4128-9be7-2c549fc505f5",
99
"condition": {
1010
"expression": "classification_level in [\"2\", \"3\"]",
11-
"title": "",
11+
"title": "x",
1212
"description": ""
1313
},
1414
"semanticType": "bb.default-partial"
@@ -17,7 +17,7 @@
1717
"id": "1ddc47c9-6ab6-4760-accd-947bc1a5f155",
1818
"condition": {
1919
"expression": "classification_level in [\"4\"]",
20-
"title": "",
20+
"title": "x",
2121
"description": ""
2222
},
2323
"semanticType": "bb.default"

masking/semantic-type.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
},
1616
{
1717
"id": "e8d3fd41-eba0-4afd-ae0f-32c91a4ee710",
18-
"title": "Personal sensitive data",
18+
"title": "Personal sensitive data x",
1919
"description": "Custom semantic type with full masking for personal sensitive data",
2020
"algorithm": {
2121
"fullMask": {
@@ -26,7 +26,7 @@
2626
{
2727
"id": "38b31ac4-b90d-44ac-b42a-19d9c76c83ea",
2828
"title": "Location",
29-
"description": "Custom semantic type with range masking for location",
29+
"description": "Custom semantic type with range masking for location x",
3030
"algorithm": {
3131
"rangeMask": {
3232
"slices": [

0 commit comments

Comments
 (0)