@@ -126,6 +126,10 @@ Function Get-GraphQlProjectWithNodes($Organization, $Number) {
126126 pageInfo { hasNextPage endCursor }
127127 nodes {
128128 id
129+ type
130+ title: fieldValueByName(name: "Title") {
131+ ... on ProjectV2ItemFieldTextValue { text }
132+ }
129133 status: fieldValueByName(name: "Status") {
130134 ... on ProjectV2ItemFieldSingleSelectValue { name }
131135 }
@@ -161,6 +165,96 @@ Function Get-GraphQlProjectWithNodes($Organization, $Number) {
161165 $Project
162166}
163167
168+ Enum ServicingStatus {
169+ Unknown
170+ ToConsider
171+ ToCherryPick
172+ CherryPicked
173+ Validated
174+ Shipped
175+ Rejected
176+ }
177+
178+ Enum ServicingItemType {
179+ Unknown
180+ DraftIssue
181+ Issue
182+ PullRequest
183+ Redacted
184+ }
185+
186+ Class ServicingCard {
187+ [String ]$Id
188+ [Int ]$Number
189+ [String ]$Title
190+ [String ]$Commit
191+ [ServicingStatus ]$Status
192+ [ServicingItemType ]$Type
193+ static [ServicingItemType ]TypeFromString($name ) {
194+ $v = Switch - Exact ($name ) {
195+ " DRAFT_ISSUE" { [ServicingItemType ]::DraftIssue }
196+ " ISSUE" { [ServicingItemType ]::Issue }
197+ " PULL_REQUEST" { [ServicingItemType ]::PullRequest }
198+ " REDACTED" { [ServicingItemType ]::Redacted }
199+ Default { [ServicingItemType ]::Unknown }
200+ }
201+ Return $v
202+ }
203+
204+ static [ServicingStatus ]StatusFromString($name ) {
205+ $v = Switch - Exact ($name ) {
206+ " To Consider" { [ServicingStatus ]::ToConsider }
207+ " To Cherry Pick" { [ServicingStatus ]::ToCherryPick }
208+ " Cherry Picked" { [ServicingStatus ]::CherryPicked }
209+ " Validated" { [ServicingStatus ]::Validated }
210+ " Shipped" { [ServicingStatus ]::Shipped }
211+ " Rejected" { [ServicingStatus ]::Rejected }
212+ Default { [ServicingStatus ]::Unknown }
213+ }
214+ Return $v
215+ }
216+
217+ ServicingCard([object ]$node ) {
218+ $this.Id = $node.id
219+ $this.Title = $node.title.text
220+ If (-Not [String ]::IsNullOrEmpty($node.content.mergeCommit.oid )) {
221+ $this.Commit = $node.content.mergeCommit.oid
222+ } ElseIf (-Not [String ]::IsNullOrEmpty($node.content.closedByPullRequestsReferences.nodes.mergeCommit.oid )) {
223+ $this.Commit = $node.content.closedByPullRequestsReferences.nodes.mergeCommit.oid
224+ }
225+ If (-Not [String ]::IsNullOrEmpty($node.content.number )) {
226+ $this.Number = [Int ]$node.content.number
227+ }
228+ $this.Status = [ServicingCard ]::StatusFromString($node.status.name )
229+ $this.Type = [ServicingCard ]::TypeFromString($node.type )
230+ }
231+
232+ [string ]Format() {
233+ $color = Switch - Exact ($this.Status ) {
234+ ([ServicingStatus ]::ToConsider) { " `e [38:5:166m" }
235+ ([ServicingStatus ]::ToCherryPick) { " `e [38:5:28m" }
236+ ([ServicingStatus ]::CherryPicked) { " `e [38:5:20m" }
237+ ([ServicingStatus ]::Validated) { " `e [38:5:126m" }
238+ ([ServicingStatus ]::Shipped) { " `e [38:5:92m" }
239+ ([ServicingStatus ]::Rejected) { " `e [38:5:160m" }
240+ Default { " `e [m" }
241+ }
242+ $symbol = Switch - Exact ($this.Type ) {
243+ ([ServicingItemType ]::DraftIssue) { " `u{25cb} " } # white circle
244+ ([ServicingItemType ]::Issue) { " `u{2b24} " } # black circle
245+ ([ServicingItemType ]::PullRequest) { " `u{25c0} " } # black left triangle
246+ ([ServicingItemType ]::Redacted) { " `u{25ec} " } # triangle with dot
247+ Default { " `u{2b24} " }
248+ }
249+ $localTitle = $this.Title
250+ If ($this.Number -Gt 0 ) {
251+ $localTitle = " [`e ]8;;https://github.com/microsoft/terminal/issues/{1}`e \Link`e ]8;;`e \] {0} (#{1})" -f ($this.Title , $this.Number )
252+ }
253+ Return " {0}{1}`e [m ({2}) {3}" -f ($color , $symbol , $this.Status , $localTitle )
254+ }
255+ }
256+
257+
164258If ([String ]::IsNullOrEmpty($Version )) {
165259 $BranchVersionRegex = [Regex ]" ^release-(\d+(\.\d+)+)$"
166260 $Branch = & git rev- parse -- abbrev- ref HEAD
@@ -209,20 +303,50 @@ $StatusFieldId = $StatusField.id
209303$StatusRejectOptionId = $StatusField.options | Where-Object name -eq $script :RejectStatusName | Select-Object - Expand id
210304$StatusDoneOptionId = $StatusField.options | Where-Object name -eq $script :DoneStatusName | Select-Object - Expand id
211305
212- $ToPickList = $Project.organization.projectV2.items.nodes | Where-Object { $_.status.name -eq $TodoStatusName }
306+ # Create ServicingCards out of each node, but filter out the ones with no commits.
307+ $cards = $Project.organization.projectV2.items.nodes | ForEach-Object { [ServicingCard ]::new($_ ) }
308+
309+ $incompleteCards = $cards | Where-Object { [String ]::IsNullOrEmpty($_.Commit ) -And $_.Status -Eq ([ServicingStatus ]::ToCherryPick) }
310+ If ($incompleteCards.Length -Gt 0 ) {
311+ Write-Host " Cards to cherry pick are not associated with commits:"
312+ $incompleteCards | ForEach-Object {
313+ Write-Host " - $ ( $_.Format ()) "
314+ }
315+ Write-Host " "
316+ }
317+
318+ $considerCards = $cards | Where-Object Status -Eq ([ServicingStatus ]::ToConsider)
319+ If ($considerCards.Length -Gt 0 ) {
320+ Write-Host " `e [7m CONSIDERATION QUEUE `e [27m"
321+ $considerCards | ForEach-Object {
322+ Write-Host " - $ ( $_.Format ()) "
323+ }
324+ Write-Host " "
325+ }
213326
327+ $commitGroups = $cards | Where-Object { -Not [String ]::IsNullOrEmpty($_.Commit ) } | Group-Object Commit
214328$commits = New-Object System.Collections.ArrayList
215- $cards = [System.Collections.Generic.Dictionary [String , String []]]::new()
216- $ToPickList | ForEach-Object {
217- If (-Not [String ]::IsNullOrEmpty($_.content.mergeCommit.oid )) {
218- $co = $_.content.mergeCommit.oid
219- } ElseIf (-Not [String ]::IsNullOrEmpty($_.content.closedByPullRequestsReferences.nodes.mergeCommit.oid )) {
220- $co = $_.content.closedByPullRequestsReferences.nodes.mergeCommit.oid
329+ $finalCardsForCommit = [System.Collections.Generic.Dictionary [String , ServicingCard []]]::new()
330+
331+ $commitGroups | ForEach-Object {
332+ $statuses = $_.Group | Select-Object - Unique Status
333+ If ($statuses.Length -Gt 1 ) {
334+ Write-Host " Commit $ ( $_.Name ) is present in more than one column:"
335+ $_.Group | ForEach-Object {
336+ Write-Host " - $ ( $_.Format ()) "
337+ }
338+ Write-Host " `e [1mIt will be ignored.`e [m`n "
221339 } Else {
222- Return
340+ If ($statuses [0 ].Status -eq ([ServicingStatus ]::ToCherryPick)) {
341+ $null = $commits.Add ($_.Name )
342+ $finalCardsForCommit [$_.Name ] = $_.Group
343+ }
223344 }
224- $null = $commits.Add ($co )
225- $cards [$co ] += $_.id
345+ }
346+
347+ If ($commits.Count -Eq 0 ) {
348+ Write-Host " Nothing to do."
349+ Exit
226350}
227351
228352$sortedAllCommits = & git rev- list -- no- walk= sorted $commits
@@ -235,6 +359,9 @@ If ($GpgSign) {
235359
236360$sortedAllCommits | ForEach-Object {
237361 Write-Host " `e [96m`e [1;7mPICK`e [22;27m`e [m $ ( & git show - q -- pretty= oneline $_ ) "
362+ ForEach ($card In $finalCardsForCommit [$_ ]) {
363+ Write-Host $card.Format ()
364+ }
238365 $null = & git cherry- pick - x $_ 2>&1
239366 $Err = " "
240367 While ($True ) {
@@ -249,8 +376,8 @@ $sortedAllCommits | ForEach-Object {
249376 }
250377
251378 If ($Global :Reject ) {
252- ForEach ($card In $cards [$_ ]) {
253- Set-GraphQlProjectEntryStatus - Project $Project.organization.projectV2.id - Item $card - Field $StatusFieldId - Value $StatusRejectOptionId
379+ ForEach ($card In $finalCardsForCommit [$_ ]) {
380+ Set-GraphQlProjectEntryStatus - Project $Project.organization.projectV2.id - Item $card.Id - Field $StatusFieldId - Value $StatusRejectOptionId
254381 }
255382 # Fall through to Skip
256383 }
@@ -262,10 +389,10 @@ $sortedAllCommits | ForEach-Object {
262389
263390 $Err = & git cherry- pick -- continue -- no- edit
264391 } Else {
265- & git commit @PickArgs -- amend -- no- edit -- trailer " Service-Card-Id:$ ( $cards [$_ ]) " -- trailer " Service-Version:$Version " | Out-Null
392+ & git commit @PickArgs -- amend -- no- edit -- trailer " Service-Card-Id:$ ( $finalCardsForCommit [$_ ].Id ) " -- trailer " Service-Version:$Version " | Out-Null
266393 Write-Host " `e [92;1;7m OK `e [m"
267- ForEach ($card In $cards [$_ ]) {
268- Set-GraphQlProjectEntryStatus - Project $Project.organization.projectV2.id - Item $card - Field $StatusFieldId - Value $StatusDoneOptionId
394+ ForEach ($card In $finalCardsForCommit [$_ ]) {
395+ Set-GraphQlProjectEntryStatus - Project $Project.organization.projectV2.id - Item $card.Id - Field $StatusFieldId - Value $StatusDoneOptionId
269396 }
270397 Break
271398 }
0 commit comments