Skip to content

Commit 8cbac0b

Browse files
chore(scripts): add release notes (#1543 by @joshuayoes)
This PR modifies the `release.artifacts.mjs` release scripts to parse the local `CHANGELOG.md` files changes, if they are relevant to a release --------- Co-authored-by: Jamon Holmgren <[email protected]>
1 parent 6838133 commit 8cbac0b

File tree

5 files changed

+303
-63
lines changed

5 files changed

+303
-63
lines changed

apps/reactotron-app/scripts/release.artifacts.js

+93-4
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,102 @@ console.log(`Found ${files.length} files to upload`)
6363
console.log(`Files: ${files.join(", ")}`)
6464

6565
// get mimie types
66-
const mime = require("mime")
67-
mime.define({ "application/x-apple-diskimage": ["dmg"] }, true)
66+
const mime = require("mime-types")
6867
files.forEach((file) => {
69-
const mimeType = mime.getType(file)
68+
const mimeType = mime.lookup(file)
7069
console.log(`File '${file}' has mime type '${mimeType}'`)
7170
})
7271
// #endregion
7372

73+
// #region extract changelog entry for this version
74+
/**
75+
* Gets the changelog entry for a specific version
76+
* @param {string} version The version to extract (without '@' prefix)
77+
* @returns {string} The formatted changelog entry or a default message
78+
*/
79+
function getChangelogEntry(version) {
80+
try {
81+
// Try to find and parse the appropriate CHANGELOG.md file
82+
const changelogPath = path.join(__dirname, "..", "CHANGELOG.md")
83+
84+
// If changelog doesn't exist, return a default message
85+
if (!fs.existsSync(changelogPath)) {
86+
console.warn(`No CHANGELOG.md found at ${changelogPath}`)
87+
return `Release version ${version}. See repository for changes.`
88+
}
89+
90+
const changelog = fs.readFileSync(changelogPath, "utf8")
91+
92+
// Extract the section for this version
93+
// Match both ## and ### header styles
94+
const versionHeaderRegex = new RegExp(
95+
`(?:##|###)\\s*\\[${version}\\][^]*?(?=(?:##|###)\\s*\\[|$)`,
96+
"s"
97+
)
98+
const match = changelog.match(versionHeaderRegex)
99+
100+
if (!match) {
101+
console.warn(`No changelog entry found for version ${version}`)
102+
return `Release version ${version}. See repository for changes.`
103+
}
104+
105+
// Return the matching section, excluding the header
106+
const lines = match[0].split("\n")
107+
const contentWithoutHeader = lines.slice(1).join("\n").trim()
108+
109+
// If the changelog entry is empty, try to find accumulated changes
110+
if (!contentWithoutHeader) {
111+
console.warn(
112+
`Empty changelog entry for version ${version}, looking for accumulated changes...`
113+
)
114+
115+
// Find previous significant version to compare against
116+
const allVersionsRegex = /(?:##|###)\s*\[([^\]]+)\]/g
117+
const versions = []
118+
let versionMatch
119+
120+
while ((versionMatch = allVersionsRegex.exec(changelog)) !== null) {
121+
versions.push(versionMatch[1])
122+
}
123+
124+
// Get index of current version
125+
const currentIndex = versions.indexOf(version)
126+
127+
if (currentIndex !== -1 && currentIndex < versions.length - 1) {
128+
// Find previous significant version (with different major or minor)
129+
const [currentMajor, currentMinor] = version.split(".").map(Number)
130+
let previousVersion = null
131+
132+
for (let i = currentIndex + 1; i < versions.length; i++) {
133+
const ver = versions[i]
134+
const [major, minor] = ver.split(".").map(Number)
135+
136+
if (major !== currentMajor || minor !== currentMinor) {
137+
previousVersion = ver
138+
break
139+
}
140+
}
141+
142+
if (previousVersion) {
143+
return `This release includes all changes accumulated since version ${previousVersion}.\n\nSee the [CHANGELOG](https://github.com/infinitered/reactotron/blob/master/apps/reactotron-app/CHANGELOG.md) for more details.`
144+
}
145+
}
146+
147+
return `Release version ${version}. See repository for changes.`
148+
}
149+
150+
return contentWithoutHeader
151+
} catch (error) {
152+
console.error(`Error extracting changelog entry: ${error.message}`)
153+
return `Release version ${version}. See repository for changes.`
154+
}
155+
}
156+
157+
// Get the release notes for this version
158+
const releaseNotes = getChangelogEntry(version)
159+
console.log(`Got release notes (${releaseNotes.length} characters)`)
160+
// #endregion
161+
74162
// #region release on github
75163
const { Octokit } = require("@octokit/rest")
76164
const octokit = new Octokit({ auth: githubToken })
@@ -86,6 +174,7 @@ const repo = "reactotron"
86174
repo,
87175
tag_name: gitTag,
88176
name: gitTag,
177+
body: releaseNotes,
89178
prerelease: gitTag.includes("beta") || gitTag.includes("alpha"),
90179
draft: !isCi,
91180
target_commitish: gitTag.includes("beta")
@@ -104,7 +193,7 @@ const repo = "reactotron"
104193
release_id: release.id,
105194
name: file,
106195
headers: {
107-
"Content-Type": mime.getType(file) || "application/octet-stream",
196+
"Content-Type": mime.lookup(file) || "application/octet-stream",
108197
},
109198
// @ts-ignore data is expecting json by default, but we want to send a buffer
110199
data: fs.readFileSync(path.join(folder, file)),

lib/eslint-plugin-reactotron/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { noTronInProduction } from "./rules/no-tron-in-production"
1616
}
1717
```
1818
*/
19-
const eslintPluginReactotron = {
19+
const eslintPluginReactotron: Linter.Plugin = {
2020
rules: {
2121
"no-tron-in-production": noTronInProduction,
2222
},

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"@types/eslint": "^8.44.4",
3333
"@typescript-eslint/eslint-plugin": "^6.7.5",
3434
"@typescript-eslint/parser": "^6.7.5",
35-
"eslint": "^8.53.0",
35+
"eslint": "^8.54.0",
3636
"eslint-config-prettier": "^9.0.0",
3737
"eslint-config-standard": "^17.1.0",
3838
"eslint-plugin-import": "^2.29.0",

0 commit comments

Comments
 (0)