Skip to content

Commit c2481c3

Browse files
azure-sdkCopilothaolingdong-msftweshaggard
authored
Sync eng/common directory with azure-sdk-tools for PR 13097 (#36774)
Sync eng/common directory with azure-sdk-tools for PR Azure/azure-sdk-tools#13097 See [eng/common workflow](https://github.com/Azure/azure-sdk-tools/blob/main/eng/common/README.md#workflow) --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: haolingdong-msft <[email protected]> Co-authored-by: weshaggard <[email protected]>
1 parent 4ab715a commit c2481c3

File tree

1 file changed

+143
-2
lines changed

1 file changed

+143
-2
lines changed

eng/common/scripts/ChangeLog-Operations.ps1

Lines changed: 143 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ $CHANGELOG_UNRELEASED_STATUS = "(Unreleased)"
88
$CHANGELOG_DATE_FORMAT = "yyyy-MM-dd"
99
$RecommendedSectionHeaders = @("Features Added", "Breaking Changes", "Bugs Fixed", "Other Changes")
1010

11+
# Helper function to build the section header regex pattern
12+
function Get-SectionHeaderRegex {
13+
param(
14+
[Parameter(Mandatory = $true)]
15+
[string]$InitialAtxHeader
16+
)
17+
return "^${InitialAtxHeader}${SECTION_HEADER_REGEX_SUFFIX}"
18+
}
19+
1120
# Returns a Collection of changeLogEntry object containing changelog info for all versions present in the gived CHANGELOG
1221
function Get-ChangeLogEntries {
1322
param (
@@ -49,7 +58,7 @@ function Get-ChangeLogEntriesFromContent {
4958
$initialAtxHeader = $matches["HeaderLevel"]
5059
}
5160

52-
$sectionHeaderRegex = "^${initialAtxHeader}${SECTION_HEADER_REGEX_SUFFIX}"
61+
$sectionHeaderRegex = Get-SectionHeaderRegex -InitialAtxHeader $initialAtxHeader
5362
$changeLogEntries | Add-Member -NotePropertyName "InitialAtxHeader" -NotePropertyValue $initialAtxHeader
5463
$releaseTitleAtxHeader = $initialAtxHeader + "#"
5564
$headerLines = @()
@@ -301,7 +310,7 @@ function Remove-EmptySections {
301310
$InitialAtxHeader = "#"
302311
)
303312

304-
$sectionHeaderRegex = "^${InitialAtxHeader}${SECTION_HEADER_REGEX_SUFFIX}"
313+
$sectionHeaderRegex = Get-SectionHeaderRegex -InitialAtxHeader $InitialAtxHeader
305314
$releaseContent = $ChangeLogEntry.ReleaseContent
306315

307316
if ($releaseContent.Count -gt 0)
@@ -460,3 +469,135 @@ function Confirm-ChangeLogForRelease {
460469
}
461470
return $ChangeLogStatus.IsValid
462471
}
472+
473+
function Parse-ChangelogContent {
474+
<#
475+
.SYNOPSIS
476+
Parses raw changelog text into structured content with sections.
477+
478+
.DESCRIPTION
479+
Takes raw changelog text and parses it into structured arrays containing
480+
ReleaseContent (all lines) and Sections (organized by section headers).
481+
This function only generates content structure without modifying any files.
482+
483+
.PARAMETER ChangelogText
484+
The new changelog text containing sections (e.g., "### Breaking Changes", "### Features Added").
485+
486+
.PARAMETER InitialAtxHeader
487+
The markdown header level used in the changelog (e.g., "#" for H1, "##" for H2).
488+
Defaults to "#".
489+
490+
.OUTPUTS
491+
PSCustomObject with ReleaseContent and Sections properties.
492+
493+
.EXAMPLE
494+
$content = Parse-ChangelogContent -ChangelogText $changelogText -InitialAtxHeader "#"
495+
$content.ReleaseContent # Array of all lines
496+
$content.Sections # Hashtable of section name to content lines
497+
#>
498+
[CmdletBinding()]
499+
param(
500+
[Parameter(Mandatory = $true)]
501+
[ValidateNotNullOrEmpty()]
502+
[string]$ChangelogText,
503+
504+
[Parameter(Mandatory = $false)]
505+
[ValidateNotNullOrEmpty()]
506+
[string]$InitialAtxHeader = "#"
507+
)
508+
509+
Write-Verbose "Parsing changelog text into structured content..."
510+
511+
# Parse the new changelog content into lines
512+
$changelogLines = $ChangelogText -split "`r?`n"
513+
514+
# Initialize content structure
515+
$releaseContent = @()
516+
$sections = @{}
517+
518+
# Add an empty line after the version header
519+
$releaseContent += ""
520+
521+
# Parse the changelog content
522+
# InitialAtxHeader represents the markdown header level (e.g., "#" for H1, "##" for H2)
523+
# Section headers are two levels deeper than the changelog title
524+
# (e.g., "### Breaking Changes" if InitialAtxHeader is "#")
525+
$currentSection = $null
526+
$sectionHeaderRegex = Get-SectionHeaderRegex -InitialAtxHeader $InitialAtxHeader
527+
528+
foreach ($line in $changelogLines) {
529+
if ($line.Trim() -match $sectionHeaderRegex) {
530+
$currentSection = $matches["sectionName"].Trim()
531+
$sections[$currentSection] = @()
532+
$releaseContent += $line
533+
Write-Verbose " Found section: $currentSection"
534+
}
535+
elseif ($currentSection) {
536+
$sections[$currentSection] += $line
537+
$releaseContent += $line
538+
}
539+
else {
540+
$releaseContent += $line
541+
}
542+
}
543+
544+
Write-Verbose " Parsed $($sections.Count) section(s)"
545+
546+
# Return structured content
547+
return [PSCustomObject]@{
548+
ReleaseContent = $releaseContent
549+
Sections = $sections
550+
}
551+
}
552+
553+
function Set-ChangeLogEntryContent {
554+
<#
555+
.SYNOPSIS
556+
Updates a changelog entry with new content.
557+
558+
.DESCRIPTION
559+
Takes a changelog entry object and new changelog text, parses the text into
560+
structured content, and updates the entry's ReleaseContent and Sections properties.
561+
562+
.PARAMETER ChangeLogEntry
563+
The changelog entry object to update (from Get-ChangeLogEntries).
564+
565+
.PARAMETER NewContent
566+
The new changelog text containing sections.
567+
568+
.PARAMETER InitialAtxHeader
569+
The markdown header level used in the changelog. Defaults to "#".
570+
571+
.OUTPUTS
572+
The updated changelog entry object.
573+
574+
.EXAMPLE
575+
$entries = Get-ChangeLogEntries -ChangeLogLocation $changelogPath
576+
$entry = $entries["1.0.0"]
577+
Set-ChangeLogEntryContent -ChangeLogEntry $entry -NewContent $newText -InitialAtxHeader $entries.InitialAtxHeader
578+
Set-ChangeLogContent -ChangeLogLocation $changelogPath -ChangeLogEntries $entries
579+
#>
580+
[CmdletBinding()]
581+
param(
582+
[Parameter(Mandatory = $true)]
583+
[ValidateNotNull()]
584+
[PSCustomObject]$ChangeLogEntry,
585+
586+
[Parameter(Mandatory = $true)]
587+
[ValidateNotNullOrEmpty()]
588+
[string]$NewContent,
589+
590+
[Parameter(Mandatory = $false)]
591+
[ValidateNotNullOrEmpty()]
592+
[string]$InitialAtxHeader = "#"
593+
)
594+
595+
# Parse the new content into structured format
596+
$parsedContent = Parse-ChangelogContent -ChangelogText $NewContent -InitialAtxHeader $InitialAtxHeader
597+
598+
# Update the entry with the parsed content
599+
$ChangeLogEntry.ReleaseContent = $parsedContent.ReleaseContent
600+
$ChangeLogEntry.Sections = $parsedContent.Sections
601+
602+
return $ChangeLogEntry
603+
}

0 commit comments

Comments
 (0)