This repository has been archived by the owner on Feb 20, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
No issue: add script for compiling closed issues from commit history
- Loading branch information
1 parent
769c1e4
commit ebc4b28
Showing
2 changed files
with
105 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
|
||
import java.io.File | ||
import java.io.IOException | ||
import java.util.concurrent.TimeUnit | ||
import java.util.stream.Stream | ||
|
||
/** | ||
* Script for use when compiling a changelog. It will find all GH mentions in commit | ||
* messages newer than the HEAD of the passed git tag. If no tag is passed, it will | ||
* default to the highest versioned tag, as defined by gits `--sort=version:refname`. | ||
* | ||
* @param (optional) git tag of the earliest commit through which to search. If null, | ||
* this will default to the tag on origin with the highest version name. | ||
* | ||
* To run this script: | ||
* - Update local master | ||
* - From project root, run `kotlinc -script automation/releasetools/PrintMentionedIssuesAndPrs.kts` | ||
* | ||
* TODO | ||
* - Use origin/master, instead of local master | ||
* - Interface with the GitHub API to filter out references to PRs | ||
* - Pull down issue names for each, to make constructing the changelog easier | ||
*/ | ||
|
||
val origin = "https://github.com/mozilla-mobile/fenix.git" | ||
val DEBUG = false | ||
|
||
println("Starting PrintMentionedIssuesAndPrs.kts") | ||
|
||
val tag = try { args[0] } catch(e: IndexOutOfBoundsException) { getHighestVersionedTag() } | ||
debug { "Last tag: $tag" } | ||
|
||
val commonCommit = getMostRecentCommonAncestorWithMaster(tag) | ||
debug { "common commit: $commonCommit" } | ||
|
||
val log = gitLogSince(commonCommit) | ||
debug { "Log: $log" } | ||
|
||
val numbers = getNumbersFromLog(log) | ||
debug { "Numbers: ${numbers.joinToString()}" } | ||
|
||
println(numbers) | ||
|
||
fun getHighestVersionedTag(): String { | ||
val originTags = runCommand("git ls-remote --tags --sort=version:refname $origin") | ||
|
||
// Tags are sorted in ascending order, so this returns the name of the newest tag | ||
return originTags.substringAfterLast("refs/tags/") | ||
// Trim the trailing line break | ||
.trim() | ||
} | ||
|
||
fun getMostRecentCommonAncestorWithMaster(tag: String): String { | ||
runCommand("git fetch --tags") | ||
// TODO use origin master | ||
return runCommand("git merge-base master $tag").trim() | ||
} | ||
|
||
fun gitLogSince(sha: String): String { | ||
val returnAsString = "--no-pager" | ||
val maxCount = "-500" | ||
// There is no plumbing version of 'git log', but pretty formatting provides a | ||
// mostly consistent return value | ||
// See: https://stackoverflow.com/a/53584289/9307461 | ||
val formatSubjectOnly = "--pretty=format:%s" | ||
|
||
return runCommand("git $returnAsString log $sha..HEAD $maxCount $formatSubjectOnly") | ||
} | ||
|
||
fun getNumbersFromLog(log: String): List<String> { | ||
val pattern = "#\\d+".toRegex() | ||
return pattern.findAll(log) | ||
.map { it.value } | ||
.distinct() | ||
.toList() | ||
} | ||
|
||
// Function adapted from: | ||
// https://stackoverflow.com/questions/35421699/how-to-invoke-external-command-from-within-kotlin-code | ||
fun runCommand(cmd: String, workingDir: File = File(".")): String { | ||
try { | ||
val parts = cmd.split(" ".toRegex()) | ||
debug { "Parts: $parts" } | ||
val proc = ProcessBuilder(*parts.toTypedArray()) | ||
.directory(workingDir) | ||
.redirectOutput(ProcessBuilder.Redirect.PIPE) | ||
.redirectError(ProcessBuilder.Redirect.PIPE) | ||
.start() | ||
proc.waitFor(10, TimeUnit.SECONDS) | ||
|
||
debug { "Err: ${proc.errorStream.bufferedReader().use { it.readText() }}" } | ||
|
||
return proc.inputStream.bufferedReader().use { it.readText() } | ||
} catch(e: IOException) { | ||
e.printStackTrace() | ||
throw(e) | ||
} | ||
} | ||
|
||
fun debug(block: () -> String) { | ||
if (DEBUG) println(block()) | ||
} |