|
| 1 | +name: GA Modules |
| 2 | + |
| 3 | +on: |
| 4 | + workflow_dispatch: |
| 5 | + inputs: |
| 6 | + Modules: |
| 7 | + description: 'Modules to be GAed (split with ",")' |
| 8 | + required: true |
| 9 | + type: string |
| 10 | + Force: |
| 11 | + description: 'Force to go?' |
| 12 | + required: false |
| 13 | + type: boolean |
| 14 | + |
| 15 | +run-name: "GA ${{ inputs.Modules }}" |
| 16 | + |
| 17 | +jobs: |
| 18 | + GA_Modules: |
| 19 | + runs-on: ubuntu-latest |
| 20 | + steps: |
| 21 | + - name: GA ${{ inputs.Modules }} |
| 22 | + shell: pwsh |
| 23 | + env: |
| 24 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 25 | + GH_Repo: ${{ github.repository }} |
| 26 | + run: | |
| 27 | + $ErrorActionPreference = 'Stop' |
| 28 | + $repoFullName = $env:GH_Repo |
| 29 | + $ghRepo = ($env:GH_Repo -split '/')[1] |
| 30 | + $ghToken = $env:GH_TOKEN |
| 31 | + $force = "${{ inputs.Force }}".ToLower() -eq 'true' |
| 32 | +
|
| 33 | + git config --global user.email "github-actions[bot]@users.noreply.github.com" |
| 34 | + git config --global user.name "github-actions[bot]" |
| 35 | + |
| 36 | + if ("${{ inputs.Modules }}".Trim() -eq '') { |
| 37 | + throw "❌ 'Modules' is empty. Please set the 'Modules' input." |
| 38 | + } |
| 39 | + $Modules = "${{ inputs.Modules }}" -split ',' | ForEach-Object {$_.Trim()} |
| 40 | + if ($Modules.Count -eq 0) { |
| 41 | + throw "❌ No 'Modules' provided. Please set the 'Modules' input." |
| 42 | + } |
| 43 | + |
| 44 | + $baseBranch = "main" |
| 45 | + $newBranch = 'ga/' + ($Modules -join '_') |
| 46 | +
|
| 47 | + $MinimalVersionFile = "tools/VersionController/MinimalVersion.csv" |
| 48 | + $AzManifestPath = "tools/Az/Az.psd1" |
| 49 | +
|
| 50 | + gh repo clone "https://x-access-token:${ghToken}@github.com/${repoFullName}" -- --filter=blob:none --no-checkout |
| 51 | + Set-Location $ghRepo |
| 52 | + & git remote set-url origin "https://x-access-token:${ghToken}@github.com/${repoFullName}.git" |
| 53 | + git sparse-checkout init --cone |
| 54 | + $checkoutFiles = @($MinimalVersionFile, $AzManifestPath) |
| 55 | + $Modules | Foreach-Object { $checkoutFiles += "src/$_/$_/ChangeLog.md" } |
| 56 | + git sparse-checkout set @checkoutFiles |
| 57 | + git checkout -b "$newBranch" origin/main |
| 58 | + |
| 59 | + foreach ($Module in $Modules) { |
| 60 | + Write-Host "Update files for $Module" |
| 61 | + $ChangeLogPath = "src/$Module/$Module/ChangeLog.md" |
| 62 | + |
| 63 | + $newLine = "`"Az.$Module`",`"1.0.0`"" |
| 64 | + $content = Get-Content $MinimalVersionFile |
| 65 | + $alreadyExists = $content | Where-Object { $_ -eq $newLine } |
| 66 | + if (-not $alreadyExists) { |
| 67 | + Add-Content -Path $MinimalVersionFile -Value $newLine |
| 68 | + Write-Host " ✅ $MinimalVersionFile is updated for Az.$Module" |
| 69 | + } |
| 70 | + else { |
| 71 | + if($force){ |
| 72 | + Write-Host " ℹ️ Az.$Module is already in $MinimalVersionFile" |
| 73 | + } |
| 74 | + else { |
| 75 | + throw "Az.$Module is already in $MinimalVersionFile" |
| 76 | + } |
| 77 | + } |
| 78 | +
|
| 79 | + $LastVersionLine = Get-Content $ChangeLogPath | Where-Object { $_ -match '^## Version\s+(\d+\.\d+\.\d+)' } | Select-Object -First 1 |
| 80 | + if (-not $LastVersionLine) { |
| 81 | + throw "Last version is not found in $ChangeLogPath ." |
| 82 | + } |
| 83 | + $LastVersion = [regex]::Match($LastVersionLine, '\d+\.\d+\.\d+').Value |
| 84 | +
|
| 85 | + $AzManifest = Get-Content $AzManifestPath |
| 86 | + $startIndex = ($AzManifest | Select-String -Pattern '^\s*RequiredModules\s*=\s*@\(').LineNumber |
| 87 | + if (-not $startIndex) { |
| 88 | + throw "RequiredModules section not found in $AzManifestPath ." |
| 89 | + } |
| 90 | + $newLine = "@{ModuleName = 'Az." + $Module + "'; RequiredVersion = '" + $LastVersion + "'; }," |
| 91 | + $alreadyExists = $AzManifest | Where-Object { $_.Contains($newLine) } |
| 92 | + if (-not $alreadyExists) { |
| 93 | + $startIndex-- |
| 94 | + $LineModuleName = "" |
| 95 | + $InsertIndex = $startIndex + 1 |
| 96 | + for ($i = $startIndex + 1; $i -lt $AzManifest.Count; $i++) { |
| 97 | + $line = $AzManifest[$i] |
| 98 | + if ($line -eq '') { |
| 99 | + continue |
| 100 | + } |
| 101 | + if (($line -match "^\s*@{ModuleName\s*=")) { |
| 102 | + if ($line -match "ModuleName\s*=\s*'Az\.([^']+)'") { |
| 103 | + $LastModuleName = $LineModuleName |
| 104 | + $LineModuleName = $Matches[1] |
| 105 | + $SpaceCount = $line.IndexOf('@{ModuleName') |
| 106 | + if (($LastModuleName -lt $Module) -and ($Module -lt $LineModuleName)) { |
| 107 | + $InsertIndex = $i |
| 108 | + break |
| 109 | + } |
| 110 | + } |
| 111 | + } |
| 112 | + else { |
| 113 | + break |
| 114 | + } |
| 115 | + } |
| 116 | +
|
| 117 | + $newLine = ''.PadLeft($SpaceCount) + $newLine |
| 118 | + $newAzManifest = @() |
| 119 | + $newAzManifest += $AzManifest[0..($InsertIndex - 1)] |
| 120 | + $newAzManifest += $newLine |
| 121 | + $newAzManifest += $AzManifest[$InsertIndex..($AzManifest.Count - 1)] |
| 122 | + |
| 123 | + Set-Content -Path $AzManifestPath -Value $newAzManifest |
| 124 | + Write-Host " ✅ $AzManifestPath is updated for Az.$Module." |
| 125 | + } |
| 126 | + else { |
| 127 | + if($force){ |
| 128 | + Write-Host " ℹ️ Az.$Module is already in $AzManifestPath" |
| 129 | + } |
| 130 | + else { |
| 131 | + throw "Az.$Module is already in $AzManifestPath" |
| 132 | + } |
| 133 | + } |
| 134 | +
|
| 135 | + $changelogLines = Get-Content $ChangeLogPath |
| 136 | + $upcomingReleaseLine = $changelogLines | Where-Object { $_ -like "##*Upcoming Release*" } |
| 137 | + $upcomingReleaseLineIndex = $changelogLines.IndexOf($upcomingReleaseLine) |
| 138 | + if ($upcomingReleaseLineIndex -lt 0) { |
| 139 | + throw "'## Upcoming Release' section not found in $ChangeLogPath" |
| 140 | + } |
| 141 | + $newLine = "* General availability for module Az.$Module" |
| 142 | + $alreadyExists = $changelogLines | Where-Object { $_ -eq $newLine } |
| 143 | + if (-not $alreadyExists) { |
| 144 | + $newChangelogLines = @() |
| 145 | + $newChangelogLines += $changelogLines[0..$upcomingReleaseLineIndex] |
| 146 | + $newChangelogLines += $newLine |
| 147 | + $newChangelogLines += $changelogLines[($upcomingReleaseLineIndex + 1)..($changelogLines.Count - 1)] |
| 148 | +
|
| 149 | + Set-Content -Path $ChangeLogPath -Value $newChangelogLines |
| 150 | + Write-Host " ✅ $ChangeLogPath is updated" |
| 151 | + } |
| 152 | + else { |
| 153 | + if($force){ |
| 154 | + Write-Host " ℹ️ $ChangeLogPath is already updated." |
| 155 | + } |
| 156 | + else { |
| 157 | + throw "$ChangeLogPath is already updated." |
| 158 | + } |
| 159 | + } |
| 160 | + } |
| 161 | + |
| 162 | + $checkoutFiles | ForEach-Object {git add $_} |
| 163 | + $title = "GA $(($Modules | ForEach-Object {"Az.$_"}) -join ' and ')" |
| 164 | + $body = "This PR is going to GA $(($Modules | ForEach-Object {"Az.$_"}) -join ' and '). " |
| 165 | + |
| 166 | + git commit -m $title |
| 167 | + git push -u origin $newBranch -f |
| 168 | +
|
| 169 | + $pr = gh pr create --repo $repoFullName --base $baseBranch --head $newBranch --title $title --body $body |
| 170 | + Write-Host "✅ PR is created: $pr" |
| 171 | +
|
| 172 | + $summaryFile = $env:GITHUB_STEP_SUMMARY |
| 173 | + Add-Content -Path $summaryFile -Value "## Going to GA Modules:" |
| 174 | + $Modules | Foreach-Object { Add-Content -Path $summaryFile -Value "- **Az.${_}**" } |
| 175 | + Add-Content -Path $summaryFile -Value " " |
| 176 | + Add-Content -Path $summaryFile -Value "## PR is created:" |
| 177 | + Add-Content -Path $summaryFile -Value "- $pr" |
0 commit comments