Browse Source

Changelog. Find PRs for not-squashed commits (#5223)

Fixes
https://youtrack.jetbrains.com/issue/CMP-7458/Changelog-script.-Change-PR-find-algorithm

It seems we can use `merge_commit_sha` field for it - it contains the
top commit that was merged/rebased/squashed to jb-main

Example:
https://github.com/JetBrains/compose-multiplatform-core/pull/1808 was
rebased on jb-main, and has `merge_commit_sha` of the top commit:


https://api.github.com/repos/JetBrains/compose-multiplatform-core/pulls?state=closed
```
    ...
    "html_url": "https://github.com/JetBrains/compose-multiplatform-core/pull/1808",
    "merge_commit_sha": "9fba10809a6816f778c526ea274c1f031b7d9cab",
```

![image](https://github.com/user-attachments/assets/81f80991-cf16-4bec-96d5-07cf5752737a)

# Testing
```
kotlin changelog.main.kts v1.8.0-alpha02..v1.8.0+dev2047
```
- Changelog for 1.8.0-alpha03 contains only more entries, not less
- it start to contain
https://github.com/JetBrains/compose-multiplatform-core/pull/1771

# Release Notes
N/A
pull/5225/head
Igor Demin 10 months ago committed by GitHub
parent
commit
dff7da6ce6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 58
      tools/changelog.main.kts

58
tools/changelog.main.kts

@ -40,6 +40,7 @@ @@ -40,6 +40,7 @@
@file:DependsOn("com.google.code.gson:gson:2.10.1")
import com.google.gson.Gson
import com.google.gson.annotations.SerializedName
import java.io.IOException
import java.lang.ProcessBuilder.Redirect
import java.net.URL
@ -49,7 +50,6 @@ import java.time.LocalDate @@ -49,7 +50,6 @@ import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.*
import kotlin.system.exitProcess
import kotlin.text.substringAfterLast
//region ========================================== CONSTANTS =========================================
@ -87,8 +87,10 @@ val argsKeyToValue = args @@ -87,8 +87,10 @@ val argsKeyToValue = args
.filter { it.contains("=") }
.associate { it.substringBefore("=") to it.substringAfter("=") }
val token = argsKeyToValue["token"] ?:
val token = argsKeyToValue["token"]
if (token != null) {
println("To increase the rate limit, specify token (https://github.com/settings/tokens), adding token=yourtoken in the end")
}
println()
@ -413,7 +415,7 @@ fun GitHubPullEntry.extractReleaseNotes(): ReleaseNotes? { @@ -413,7 +415,7 @@ fun GitHubPullEntry.extractReleaseNotes(): ReleaseNotes? {
lineFixed,
section,
subsection,
html_url.takeIf { isTopLevel }
htmlUrl.takeIf { isTopLevel }
)
)
isFirstLine = false
@ -433,20 +435,14 @@ fun entriesForRepo(repo: String, firstCommit: String, lastCommit: String): List< @@ -433,20 +435,14 @@ fun entriesForRepo(repo: String, firstCommit: String, lastCommit: String): List<
requestJson<Array<GitHubPullEntry>>("https://api.github.com/repos/$repo/pulls?state=closed&per_page=100&page=$it").toList()
}
val pullNumberToPull = pulls.associateBy { it.number }
val pullTitleToPull = pulls.associateBy { it.title }
fun prForCommit(commit: GitHubCompareResponse.CommitEntry): GitHubPullEntry? {
val (repoTitle, repoNumber) = repoTitleAndNumberForCommit(commit)
return repoNumber?.let(pullNumberToPull::get) ?: pullTitleToPull[repoTitle]
}
val shaToPull = pulls.associateBy { it.mergeCommitSha }
fun changelogEntriesFor(
pullRequest: GitHubPullEntry?
): List<ChangelogEntry> {
return if (pullRequest != null) {
pullRequest.extractReleaseNotes()?.entries ?:
listOf(ChangelogEntry("- ${pullRequest.title}", null, null, pullRequest.html_url))
listOf(ChangelogEntry("- ${pullRequest.title}", null, null, pullRequest.htmlUrl))
} else {
listOf()
}
@ -458,7 +454,7 @@ fun entriesForRepo(repo: String, firstCommit: String, lastCommit: String): List< @@ -458,7 +454,7 @@ fun entriesForRepo(repo: String, firstCommit: String, lastCommit: String): List<
lateinit var mergeBaseCommit: String
val commits = fetchPagedUntilEmpty { page ->
val result = requestJson<GitHubCompareResponse>("https://api.github.com/repos/$repo/compare/$firsCommitSha...$lastCommitSha?per_page=1000&page=$page")
mergeBaseCommit = result.merge_base_commit.sha
mergeBaseCommit = result.mergeBaseCommit.sha
result.commits
}
return CommitsResult(commits, mergeBaseCommit)
@ -466,8 +462,8 @@ fun entriesForRepo(repo: String, firstCommit: String, lastCommit: String): List< @@ -466,8 +462,8 @@ fun entriesForRepo(repo: String, firstCommit: String, lastCommit: String): List<
val main = fetchCommits(firstCommit, lastCommit)
val previous = fetchCommits(main.mergeBaseSha, firstCommit)
val pullRequests = main.commits.mapNotNull { prForCommit(it) }.toSet()
val previousVersionPullRequests = previous.commits.mapNotNull { prForCommit(it) }.toSet()
val pullRequests = main.commits.mapNotNull { shaToPull[it.sha] }.toSet()
val previousVersionPullRequests = previous.commits.mapNotNull { shaToPull[it.sha] }.toSet()
return (pullRequests - previousVersionPullRequests).flatMap { changelogEntriesFor(it) }
}
@ -479,17 +475,6 @@ fun pullRequest(repo: String, prNumber: String): GitHubPullEntry { @@ -479,17 +475,6 @@ fun pullRequest(repo: String, prNumber: String): GitHubPullEntry {
return requestJson<GitHubPullEntry>("https://api.github.com/repos/$repo/pulls/$prNumber")
}
/**
* Extract the PR number from the commit.
*/
fun repoTitleAndNumberForCommit(commit: GitHubCompareResponse.CommitEntry): Pair<String, Int?> {
val commitTitle = commit.commit.message.substringBefore("\n")
// check title similar to `Fix import android flavors with compose resources (#4319)`
val title = commitTitle.substringBeforeLast(" (#")
val number = commitTitle.substringAfterLast(" (#").substringBefore(")").toIntOrNull()
return title to number
}
/**
* Extract redirecting versions from core repo, file gradle.properties
*
@ -547,14 +532,6 @@ sealed interface ReleaseNotes { @@ -547,14 +532,6 @@ sealed interface ReleaseNotes {
}
class Specified(override val entries: List<ChangelogEntry>): ReleaseNotes
fun ifEmpty(action: () -> ReleaseNotes): ReleaseNotes {
return if (entries.isEmpty()) {
action()
} else {
this
}
}
}
data class ChangelogEntry(
@ -572,15 +549,22 @@ fun String.normalizeSectionName() = standardSections.find { it.lowercase() == th @@ -572,15 +549,22 @@ fun String.normalizeSectionName() = standardSections.find { it.lowercase() == th
fun String.normalizeSubsectionName() = standardSubsections.find { it.lowercase() == this.lowercase() } ?: this
// example https://api.github.com/repos/JetBrains/compose-multiplatform-core/compare/v1.6.0-rc02...release/1.6.0
data class GitHubCompareResponse(val commits: List<CommitEntry>, val merge_base_commit: CommitEntry) {
data class GitHubCompareResponse(
val commits: List<CommitEntry>,
@SerializedName("merge_base_commit") val mergeBaseCommit: CommitEntry
) {
data class CommitEntry(val sha: String, val commit: Commit)
data class Commit(val message: String)
}
// example https://api.github.com/repos/JetBrains/compose-multiplatform-core/pulls?state=closed
data class GitHubPullEntry(val html_url: String, val number: Int, val title: String, val body: String?, val labels: List<Label>) {
class Label(val name: String)
}
data class GitHubPullEntry(
@SerializedName("html_url") val htmlUrl: String,
val number: Int,
val title: String,
val body: String?,
@SerializedName("merge_commit_sha") val mergeCommitSha: String?,
)
//region ========================================== UTILS =========================================
fun pipeProcess(command: String) = ProcessBuilder(command.split(" "))

Loading…
Cancel
Save