Fix GitHub release notes workflow
This commit is contained in:
@@ -6,6 +6,10 @@ This project follows a simple changelog format inspired by [Keep a Changelog](ht
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed the GitHub Release workflow so release pages use generated changelog-style `RELEASE_NOTES.md` instead of the artifact installation README.
|
||||||
|
|
||||||
## [0.3.3] - 2026-05-20
|
## [0.3.3] - 2026-05-20
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ Use this checklist before publishing a new release of Funplay MCP for Cocos.
|
|||||||
- [ ] `npm run registry:validate` passes when `mcp-publisher` is available
|
- [ ] `npm run registry:validate` passes when `mcp-publisher` is available
|
||||||
- [ ] `npm run release:package` creates `releases/<version>/`
|
- [ ] `npm run release:package` creates `releases/<version>/`
|
||||||
- [ ] `shasum -a 256 -c releases/<version>/SHA256SUMS.txt` passes
|
- [ ] `shasum -a 256 -c releases/<version>/SHA256SUMS.txt` passes
|
||||||
|
- [ ] `releases/<version>/RELEASE_NOTES.md` is organized by change type, such as Added/Optimized/Changed/Fixed
|
||||||
|
|
||||||
## 3. Package Contents
|
## 3. Package Contents
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ Use this checklist before publishing a new release of Funplay MCP for Cocos.
|
|||||||
- [ ] The zip includes docs: `README.md`, `README_CN.md`, `CHANGELOG.md`, `CONTRIBUTING.md`, and `LICENSE`
|
- [ ] The zip includes docs: `README.md`, `README_CN.md`, `CHANGELOG.md`, `CONTRIBUTING.md`, and `LICENSE`
|
||||||
- [ ] The zip does not contain `.git/`, `.github/`, `.DS_Store`, `node_modules/`, `Library/`, `Temp/`, `dist/`, `build/`, `test/`, or `scripts/`
|
- [ ] The zip does not contain `.git/`, `.github/`, `.DS_Store`, `node_modules/`, `Library/`, `Temp/`, `dist/`, `build/`, `test/`, or `scripts/`
|
||||||
- [ ] `release-manifest.json` references the correct GitHub download URL
|
- [ ] `release-manifest.json` references the correct GitHub download URL
|
||||||
- [ ] `SHA256SUMS.txt` includes the zip, manifest, and release README
|
- [ ] `SHA256SUMS.txt` includes the zip, manifest, generated release notes, and release README
|
||||||
|
|
||||||
## 4. Cocos Smoke Test
|
## 4. Cocos Smoke Test
|
||||||
|
|
||||||
@@ -72,7 +73,7 @@ Use this checklist before publishing a new release of Funplay MCP for Cocos.
|
|||||||
- [ ] Tag is `v<version>`
|
- [ ] Tag is `v<version>`
|
||||||
- [ ] GitHub Release title is `v<version>`
|
- [ ] GitHub Release title is `v<version>`
|
||||||
- [ ] GitHub Release includes the zip, manifest, checksum file, and release README
|
- [ ] GitHub Release includes the zip, manifest, checksum file, and release README
|
||||||
- [ ] Public GitHub Release page renders the release notes and assets correctly
|
- [ ] Public GitHub Release page uses `RELEASE_NOTES.md` and renders the release notes/assets correctly
|
||||||
|
|
||||||
## 8. Publish
|
## 8. Publish
|
||||||
|
|
||||||
|
|||||||
+10
-2
@@ -175,7 +175,7 @@ If creating a new release:
|
|||||||
gh release create v<version> \
|
gh release create v<version> \
|
||||||
-R FunplayAI/funplay-cocos-mcp \
|
-R FunplayAI/funplay-cocos-mcp \
|
||||||
--title "v<version>" \
|
--title "v<version>" \
|
||||||
--notes-file /path/to/release-notes.md \
|
--notes-file releases/<version>/RELEASE_NOTES.md \
|
||||||
releases/<version>/Funplay.CocosMcp.v<version>.zip \
|
releases/<version>/Funplay.CocosMcp.v<version>.zip \
|
||||||
releases/<version>/release-manifest.json \
|
releases/<version>/release-manifest.json \
|
||||||
releases/<version>/SHA256SUMS.txt \
|
releases/<version>/SHA256SUMS.txt \
|
||||||
@@ -194,6 +194,14 @@ gh release upload v<version> \
|
|||||||
releases/<version>/README.md
|
releases/<version>/README.md
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If the release body needs to be refreshed without replacing assets:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gh release edit v<version> \
|
||||||
|
-R FunplayAI/funplay-cocos-mcp \
|
||||||
|
--notes-file releases/<version>/RELEASE_NOTES.md
|
||||||
|
```
|
||||||
|
|
||||||
### 7. Verify GitHub Release
|
### 7. Verify GitHub Release
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -202,7 +210,7 @@ gh release view v<version> \
|
|||||||
--json url,assets,isDraft,isPrerelease,publishedAt
|
--json url,assets,isDraft,isPrerelease,publishedAt
|
||||||
```
|
```
|
||||||
|
|
||||||
Confirm the release has all four assets.
|
Confirm the release has all four assets and the public release body is organized by change type.
|
||||||
|
|
||||||
### 8. Publish To npm
|
### 8. Publish To npm
|
||||||
|
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ function main() {
|
|||||||
console.log(`- ${artifacts.zipName}`);
|
console.log(`- ${artifacts.zipName}`);
|
||||||
console.log('- release-manifest.json');
|
console.log('- release-manifest.json');
|
||||||
console.log('- SHA256SUMS.txt');
|
console.log('- SHA256SUMS.txt');
|
||||||
|
console.log('- RELEASE_NOTES.md');
|
||||||
console.log('- README.md');
|
console.log('- README.md');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -270,9 +271,13 @@ function packageRelease(context) {
|
|||||||
const readmePath = path.join(releaseDir, 'README.md');
|
const readmePath = path.join(releaseDir, 'README.md');
|
||||||
fs.writeFileSync(readmePath, buildReleaseReadme(context, manifest));
|
fs.writeFileSync(readmePath, buildReleaseReadme(context, manifest));
|
||||||
|
|
||||||
|
const releaseNotesPath = path.join(releaseDir, 'RELEASE_NOTES.md');
|
||||||
|
fs.writeFileSync(releaseNotesPath, buildGitHubReleaseNotes(context, manifest));
|
||||||
|
|
||||||
const checksums = [
|
const checksums = [
|
||||||
checksumLine(zipPath, zipName),
|
checksumLine(zipPath, zipName),
|
||||||
checksumLine(manifestPath, 'release-manifest.json'),
|
checksumLine(manifestPath, 'release-manifest.json'),
|
||||||
|
checksumLine(releaseNotesPath, 'RELEASE_NOTES.md'),
|
||||||
checksumLine(readmePath, 'README.md')
|
checksumLine(readmePath, 'README.md')
|
||||||
].join('');
|
].join('');
|
||||||
fs.writeFileSync(path.join(releaseDir, 'SHA256SUMS.txt'), checksums);
|
fs.writeFileSync(path.join(releaseDir, 'SHA256SUMS.txt'), checksums);
|
||||||
@@ -362,6 +367,95 @@ shasum -a 256 -c SHA256SUMS.txt
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildGitHubReleaseNotes(context, manifest) {
|
||||||
|
const sections = parseChangelogSections(context.changelogNotes);
|
||||||
|
const rendered = [];
|
||||||
|
const used = new Set();
|
||||||
|
const order = [
|
||||||
|
['Added', '新增'],
|
||||||
|
['Optimized', '优化'],
|
||||||
|
['Changed', '修改'],
|
||||||
|
['Fixed', '修复'],
|
||||||
|
['Security', '安全'],
|
||||||
|
['Deprecated', '弃用'],
|
||||||
|
['Removed', '移除']
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const [sourceHeading, displayHeading] of order) {
|
||||||
|
const section = sections.find((item) => item.heading.toLowerCase() === sourceHeading.toLowerCase());
|
||||||
|
if (!section) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
used.add(section.heading);
|
||||||
|
rendered.push(`## ${displayHeading}`, '', ...section.lines, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const section of sections) {
|
||||||
|
if (used.has(section.heading)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rendered.push(`## ${section.heading}`, '', ...section.lines, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
const zip = manifest.artifacts.extensionZip;
|
||||||
|
return [
|
||||||
|
`# Funplay MCP for Cocos ${context.tag}`,
|
||||||
|
'',
|
||||||
|
...rendered,
|
||||||
|
'## 发布资产',
|
||||||
|
'',
|
||||||
|
`- \`${zip.file}\` - Cocos Creator extension package.`,
|
||||||
|
'- `release-manifest.json` - Machine-readable release metadata.',
|
||||||
|
'- `SHA256SUMS.txt` - SHA-256 checksums for release artifacts.',
|
||||||
|
'',
|
||||||
|
'## 校验',
|
||||||
|
'',
|
||||||
|
'```bash',
|
||||||
|
'shasum -a 256 -c SHA256SUMS.txt',
|
||||||
|
'```',
|
||||||
|
''
|
||||||
|
].join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseChangelogSections(notes) {
|
||||||
|
const sections = [];
|
||||||
|
let current = null;
|
||||||
|
|
||||||
|
for (const line of String(notes || '').split(/\r?\n/)) {
|
||||||
|
const heading = /^###\s+(.+?)\s*$/.exec(line);
|
||||||
|
if (heading) {
|
||||||
|
current = {
|
||||||
|
heading: heading[1].trim(),
|
||||||
|
lines: []
|
||||||
|
};
|
||||||
|
sections.push(current);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current) {
|
||||||
|
current.lines.push(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sections
|
||||||
|
.map((section) => ({
|
||||||
|
heading: section.heading,
|
||||||
|
lines: trimBlankLines(section.lines)
|
||||||
|
}))
|
||||||
|
.filter((section) => section.lines.length > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function trimBlankLines(lines) {
|
||||||
|
const trimmed = lines.slice();
|
||||||
|
while (trimmed.length && !trimmed[0].trim()) {
|
||||||
|
trimmed.shift();
|
||||||
|
}
|
||||||
|
while (trimmed.length && !trimmed[trimmed.length - 1].trim()) {
|
||||||
|
trimmed.pop();
|
||||||
|
}
|
||||||
|
return trimmed;
|
||||||
|
}
|
||||||
|
|
||||||
function validateArchivePaths(paths) {
|
function validateArchivePaths(paths) {
|
||||||
const bad = [];
|
const bad = [];
|
||||||
const prefix = `${PACKAGE_DIR_NAME}/`;
|
const prefix = `${PACKAGE_DIR_NAME}/`;
|
||||||
|
|||||||
Reference in New Issue
Block a user