Skip to content

Commit 1e0334c

Browse files
authored
ci: mirror toolbox changelog into extension changelog (#47)
1 parent 238fc52 commit 1e0334c

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
name: Mirror Toolbox Changelog
16+
17+
on:
18+
pull_request_target:
19+
types: [opened, edited]
20+
21+
jobs:
22+
add-release-notes:
23+
if: github.actor == 'renovate[bot]' && startsWith(github.head_ref, 'renovate/googleapis-genai-toolbox')
24+
runs-on: ubuntu-latest
25+
permissions:
26+
pull-requests: write
27+
28+
steps:
29+
- name: Add Toolbox Release Notes to PR Body
30+
uses: actions/github-script@v6
31+
env:
32+
REQUIRED_KEYWORDS: 'postgres'
33+
with:
34+
script: |
35+
const requiredKeywordsEnv = process.env.REQUIRED_KEYWORDS;
36+
const requiredKeywords = requiredKeywordsEnv.split(',').map(kw => kw.trim()).filter(kw => kw.length > 0);
37+
38+
const prBody = context.payload.pull_request.body || '';
39+
40+
// Extract the relevant changelog section
41+
const startMarker = '<summary>googleapis/genai-toolbox';
42+
const endMarker = '</details>';
43+
const startIndex = prBody.indexOf(startMarker);
44+
const endIndex = prBody.indexOf(endMarker, startIndex);
45+
46+
if (startIndex === -1 || endIndex === -1) {
47+
console.log('Could not find the release notes section in the PR body. Exiting.');
48+
return;
49+
}
50+
const releaseNotesSection = prBody.substring(startIndex, endIndex);
51+
52+
// Parse, Filter, and transform
53+
const prefixesToFilter = ['source/', 'sources/', 'tool/', 'tools/'];
54+
55+
// Use a map for cleaner type switching
56+
const typeMap = {
57+
'##### ⚠ BREAKING CHANGES': 'feat!',
58+
'##### Features': 'feat',
59+
'##### Bug Fixes': 'fix',
60+
'##### Chores': 'ignore',
61+
'##### Miscellaneous Chores': 'ignore',
62+
'##### Documentation': 'ignore',
63+
};
64+
65+
let currentType = 'feat'; // Default
66+
const newChangelog = [];
67+
68+
for (const line of releaseNotesSection.split('\n')) {
69+
const trimmedLine = line.trim();
70+
71+
// Update current type if it's a header
72+
if (typeMap[trimmedLine]) {
73+
currentType = typeMap[trimmedLine];
74+
continue;
75+
}
76+
77+
// Skip ignored sections
78+
if (currentType === 'ignore') {
79+
continue;
80+
}
81+
82+
// Match and extract changelog item
83+
const itemMatch = trimmedLine.match(/^[*-]\s(.*)$/);
84+
if (itemMatch) {
85+
const originalContent = itemMatch[1];
86+
const lineAsLowerCase = originalContent.toLowerCase();
87+
88+
const hasPrefix = prefixesToFilter.some(prefix => lineAsLowerCase.includes(prefix));
89+
90+
// Check if the line includes ANY of the required keywords
91+
let hasAnyRequiredKeyword = false;
92+
if (requiredKeywords.length > 0) {
93+
hasAnyRequiredKeyword = requiredKeywords.some(keyword => lineAsLowerCase.includes(keyword));
94+
}
95+
96+
// Include if it doesn't have a prefix OR it has any of the required keywords
97+
if (!hasPrefix || hasAnyRequiredKeyword) {
98+
newChangelog.push(`- ${currentType}: ${originalContent}`);
99+
} else {
100+
console.log(`Filtering out: ${originalContent}`);
101+
}
102+
}
103+
}
104+
105+
if (newChangelog.length === 0) {
106+
console.log('Found no changelog items to add after filtering. Exiting.');
107+
return;
108+
}
109+
110+
// Construct the override block
111+
const overrideBlock = [
112+
'\n\nBEGIN_COMMIT_OVERRIDE',
113+
...newChangelog,
114+
'END_COMMIT_OVERRIDE'
115+
].join('\n');
116+
117+
// Update PR body
118+
const baseBody = prBody.split('\n\nBEGIN_COMMIT_OVERRIDE')[0].trim();
119+
const finalBody = baseBody + overrideBlock;
120+
121+
if (finalBody === prBody) {
122+
console.log('The generated changelog is identical. No update needed.');
123+
return;
124+
}
125+
126+
// Update the PR
127+
await github.rest.pulls.update({
128+
owner: context.repo.owner,
129+
repo: context.repo.repo,
130+
pull_number: context.issue.number,
131+
body: finalBody,
132+
});
133+
134+
console.log('Successfully updated the PR body with filtered release notes.');

0 commit comments

Comments
 (0)