Skip to content

Commit 1643c9e

Browse files
Extract docs workflow logic into scripts
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent cd5b0ac commit 1643c9e

6 files changed

Lines changed: 361 additions & 345 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
param(
2+
[Parameter(Mandatory = $true)]
3+
[string]$Repository,
4+
[Parameter(Mandatory = $true)]
5+
[string]$Token,
6+
[Parameter(Mandatory = $true)]
7+
[int]$PullRequestNumber,
8+
[Parameter(Mandatory = $true)]
9+
[string]$PreviewUrl,
10+
[Parameter(Mandatory = $true)]
11+
[string]$EnvironmentName,
12+
[Parameter(Mandatory = $true)]
13+
[string]$HeadBranch,
14+
[string]$PagesDirectory = '_pages',
15+
[string]$BaseBranch = 'gh-pages'
16+
)
17+
18+
Set-StrictMode -Version Latest
19+
$ErrorActionPreference = 'Stop'
20+
21+
. "$PSScriptRoot/Shared.ps1"
22+
23+
$clonedPages = $true
24+
Invoke-Git -Arguments @(
25+
'clone',
26+
'--no-tags',
27+
'--depth', '1',
28+
'--branch', $BaseBranch,
29+
"https://x-access-token:$Token@github.com/$Repository.git",
30+
$PagesDirectory
31+
) -AllowFailure | Out-Null
32+
33+
if (-not (Test-Path -LiteralPath $PagesDirectory -PathType Container)) {
34+
$clonedPages = $false
35+
}
36+
37+
if ($clonedPages) {
38+
$previewDirectory = Join-Path $PagesDirectory "previews/pr-$PullRequestNumber"
39+
if (Test-Path -LiteralPath $previewDirectory) {
40+
Remove-Item -LiteralPath $previewDirectory -Recurse -Force
41+
}
42+
43+
Invoke-Git -Arguments @('-C', $PagesDirectory, 'config', 'user.name', 'scribbler-bot[bot]')
44+
Invoke-Git -Arguments @('-C', $PagesDirectory, 'config', 'user.email', 'scribe@psmodule.io')
45+
Invoke-Git -Arguments @('-C', $PagesDirectory, 'add', '-A')
46+
47+
$status = (& git -C $PagesDirectory status --porcelain)
48+
if (-not [string]::IsNullOrWhiteSpace($status)) {
49+
Invoke-Git -Arguments @('-C', $PagesDirectory, 'commit', '-m', "Remove docs preview for PR #$PullRequestNumber")
50+
Invoke-Git -Arguments @('-C', $PagesDirectory, 'push', '--force-with-lease', 'origin', "HEAD:refs/heads/$HeadBranch")
51+
52+
$env:GH_TOKEN = $Token
53+
$prNumber = Upsert-PullRequest `
54+
-Repository $Repository `
55+
-HeadBranch $HeadBranch `
56+
-BaseBranch $BaseBranch `
57+
-Title "docs(preview): cleanup PR #$PullRequestNumber" `
58+
-Body "Automated cleanup for preview URL: $PreviewUrl"
59+
Enable-PullRequestAutoMerge -Repository $Repository -PullRequestNumber $prNumber
60+
}
61+
}
62+
63+
$env:GH_TOKEN = $Token
64+
$deploymentsJson = Invoke-Gh -Arguments @('api', "repos/$Repository/deployments?environment=$EnvironmentName&per_page=100")
65+
$deployments = @($deploymentsJson | ConvertFrom-Json)
66+
67+
foreach ($deployment in $deployments) {
68+
Invoke-Gh -Arguments @('api', '--method', 'POST', "repos/$Repository/deployments/$($deployment.id)/statuses", '-f', 'state=inactive') | Out-Null
69+
Invoke-Gh -Arguments @('api', '--method', 'DELETE', "repos/$Repository/deployments/$($deployment.id)") | Out-Null
70+
}
71+
72+
$deleteEnvironmentExit = Invoke-Gh -Arguments @('api', '--method', 'DELETE', "repos/$Repository/environments/$EnvironmentName") -AllowFailure
73+
if ($LASTEXITCODE -ne 0) {
74+
$environmentCheckExit = Invoke-Gh -Arguments @('api', "repos/$Repository/environments/$EnvironmentName") -AllowFailure
75+
if ($LASTEXITCODE -eq 0) {
76+
throw "Failed to delete environment '$EnvironmentName'."
77+
}
78+
}
79+
80+
$commentBody = "<!-- docs-pr-preview -->`n🧹 Preview removed: $PreviewUrl"
81+
Upsert-IssueComment -Repository $Repository -IssueNumber $PullRequestNumber -Marker '<!-- docs-pr-preview -->' -Body $commentBody
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
param(
2+
[Parameter(Mandatory = $true)]
3+
[string]$Repository,
4+
[Parameter(Mandatory = $true)]
5+
[string]$Token,
6+
[Parameter(Mandatory = $true)]
7+
[string]$BuildDirectory,
8+
[Parameter(Mandatory = $true)]
9+
[string]$HeadBranch,
10+
[Parameter(Mandatory = $true)]
11+
[string]$CommitSha,
12+
[string]$PagesDirectory = '_pages',
13+
[string]$BaseBranch = 'gh-pages'
14+
)
15+
16+
Set-StrictMode -Version Latest
17+
$ErrorActionPreference = 'Stop'
18+
19+
. "$PSScriptRoot/Shared.ps1"
20+
21+
if (-not (Test-Path -LiteralPath $BuildDirectory -PathType Container)) {
22+
throw "Build directory '$BuildDirectory' does not exist."
23+
}
24+
25+
Invoke-Git -Arguments @(
26+
'clone',
27+
'--no-tags',
28+
'--depth', '1',
29+
'--branch', $BaseBranch,
30+
"https://x-access-token:$Token@github.com/$Repository.git",
31+
$PagesDirectory
32+
) -AllowFailure | Out-Null
33+
34+
if (-not (Test-Path -LiteralPath $PagesDirectory -PathType Container)) {
35+
throw "$BaseBranch branch is required for branch-based deployment."
36+
}
37+
38+
Get-ChildItem -LiteralPath $PagesDirectory -Force |
39+
Where-Object { $_.Name -notin @('.git', 'previews') } |
40+
Remove-Item -Recurse -Force
41+
42+
Get-ChildItem -LiteralPath $BuildDirectory -Force |
43+
ForEach-Object {
44+
Copy-Item -LiteralPath $_.FullName -Destination $PagesDirectory -Recurse -Force
45+
}
46+
47+
New-Item -Path (Join-Path $PagesDirectory '.nojekyll') -ItemType File -Force | Out-Null
48+
49+
Invoke-Git -Arguments @('-C', $PagesDirectory, 'config', 'user.name', 'scribbler-bot[bot]')
50+
Invoke-Git -Arguments @('-C', $PagesDirectory, 'config', 'user.email', 'scribe@psmodule.io')
51+
Invoke-Git -Arguments @('-C', $PagesDirectory, 'add', '-A')
52+
53+
$status = (& git -C $PagesDirectory status --porcelain)
54+
if ([string]::IsNullOrWhiteSpace($status)) {
55+
Set-WorkflowOutput -Name 'has_changes' -Value 'false'
56+
exit 0
57+
}
58+
59+
Invoke-Git -Arguments @('-C', $PagesDirectory, 'commit', '-m', "Deploy docs from $CommitSha")
60+
Invoke-Git -Arguments @('-C', $PagesDirectory, 'push', '--force-with-lease', 'origin', "HEAD:refs/heads/$HeadBranch")
61+
62+
$env:GH_TOKEN = $Token
63+
$prNumber = Upsert-PullRequest `
64+
-Repository $Repository `
65+
-HeadBranch $HeadBranch `
66+
-BaseBranch $BaseBranch `
67+
-Title 'docs(publish): update live docs' `
68+
-Body "Automated docs publish from `$CommitSha`nLive URL: https://psmodule.io/docs/"
69+
Enable-PullRequestAutoMerge -Repository $Repository -PullRequestNumber $prNumber
70+
71+
Set-WorkflowOutput -Name 'has_changes' -Value 'true'
72+
Set-WorkflowOutput -Name 'pr_number' -Value $prNumber
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
param(
2+
[Parameter(Mandatory = $true)]
3+
[string]$Repository,
4+
[Parameter(Mandatory = $true)]
5+
[string]$Token,
6+
[Parameter(Mandatory = $true)]
7+
[int]$PullRequestNumber,
8+
[Parameter(Mandatory = $true)]
9+
[string]$PreviewUrl,
10+
[Parameter(Mandatory = $true)]
11+
[string]$BuildDirectory,
12+
[Parameter(Mandatory = $true)]
13+
[string]$HeadBranch,
14+
[string]$PagesDirectory = '_pages',
15+
[string]$BaseBranch = 'gh-pages'
16+
)
17+
18+
Set-StrictMode -Version Latest
19+
$ErrorActionPreference = 'Stop'
20+
21+
. "$PSScriptRoot/Shared.ps1"
22+
23+
if (-not (Test-Path -LiteralPath $BuildDirectory -PathType Container)) {
24+
throw "Build directory '$BuildDirectory' does not exist."
25+
}
26+
27+
Invoke-Git -Arguments @(
28+
'clone',
29+
'--no-tags',
30+
'--depth', '1',
31+
'--branch', $BaseBranch,
32+
"https://x-access-token:$Token@github.com/$Repository.git",
33+
$PagesDirectory
34+
)
35+
36+
$previewDirectory = Join-Path $PagesDirectory "previews/pr-$PullRequestNumber"
37+
if (Test-Path -LiteralPath $previewDirectory) {
38+
Remove-Item -LiteralPath $previewDirectory -Recurse -Force
39+
}
40+
41+
New-Item -Path $previewDirectory -ItemType Directory -Force | Out-Null
42+
Get-ChildItem -LiteralPath $BuildDirectory -Force |
43+
ForEach-Object {
44+
Copy-Item -LiteralPath $_.FullName -Destination $previewDirectory -Recurse -Force
45+
}
46+
47+
New-Item -Path (Join-Path $PagesDirectory '.nojekyll') -ItemType File -Force | Out-Null
48+
49+
Invoke-Git -Arguments @('-C', $PagesDirectory, 'config', 'user.name', 'scribbler-bot[bot]')
50+
Invoke-Git -Arguments @('-C', $PagesDirectory, 'config', 'user.email', 'scribe@psmodule.io')
51+
Invoke-Git -Arguments @('-C', $PagesDirectory, 'add', '-A')
52+
53+
$status = (& git -C $PagesDirectory status --porcelain)
54+
if (-not [string]::IsNullOrWhiteSpace($status)) {
55+
Invoke-Git -Arguments @('-C', $PagesDirectory, 'commit', '-m', "Update docs preview for PR #$PullRequestNumber")
56+
Invoke-Git -Arguments @('-C', $PagesDirectory, 'push', '--force-with-lease', 'origin', "HEAD:refs/heads/$HeadBranch")
57+
58+
$env:GH_TOKEN = $Token
59+
$prNumber = Upsert-PullRequest `
60+
-Repository $Repository `
61+
-HeadBranch $HeadBranch `
62+
-BaseBranch $BaseBranch `
63+
-Title "docs(preview): PR #$PullRequestNumber" `
64+
-Body "Automated preview content update for #$PullRequestNumber`nPreview URL: $PreviewUrl"
65+
Enable-PullRequestAutoMerge -Repository $Repository -PullRequestNumber $prNumber
66+
}
67+
68+
$commentBody = "<!-- docs-pr-preview -->`n✅ Preview is ready: $PreviewUrl"
69+
$env:GH_TOKEN = $Token
70+
Upsert-IssueComment -Repository $Repository -IssueNumber $PullRequestNumber -Marker '<!-- docs-pr-preview -->' -Body $commentBody
71+
72+
Set-WorkflowOutput -Name 'url' -Value $PreviewUrl
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
param(
2+
[Parameter(Mandatory = $true)]
3+
[string]$ConfigPath,
4+
[Parameter(Mandatory = $true)]
5+
[string]$SiteUrl
6+
)
7+
8+
Set-StrictMode -Version Latest
9+
$ErrorActionPreference = 'Stop'
10+
11+
$content = Get-Content -LiteralPath $ConfigPath -Raw
12+
$updated = $content -replace '(?m)^site_url = ".*"$', "site_url = `"$SiteUrl`""
13+
Set-Content -LiteralPath $ConfigPath -Value $updated

.github/scripts/docs/Shared.ps1

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
Set-StrictMode -Version Latest
2+
$ErrorActionPreference = 'Stop'
3+
4+
function Invoke-Git {
5+
param(
6+
[Parameter(Mandatory = $true)]
7+
[string[]]$Arguments,
8+
[switch]$AllowFailure
9+
)
10+
11+
& git @Arguments
12+
$exitCode = $LASTEXITCODE
13+
if ($exitCode -ne 0 -and -not $AllowFailure) {
14+
throw "git $($Arguments -join ' ') failed with exit code $exitCode."
15+
}
16+
17+
return $exitCode
18+
}
19+
20+
function Set-WorkflowOutput {
21+
param(
22+
[Parameter(Mandatory = $true)]
23+
[string]$Name,
24+
[Parameter(Mandatory = $true)]
25+
[string]$Value
26+
)
27+
28+
if (-not $env:GITHUB_OUTPUT) {
29+
throw 'GITHUB_OUTPUT is not defined.'
30+
}
31+
32+
"$Name=$Value" >> $env:GITHUB_OUTPUT
33+
}
34+
35+
function Invoke-Gh {
36+
param(
37+
[Parameter(Mandatory = $true)]
38+
[string[]]$Arguments,
39+
[switch]$AllowFailure
40+
)
41+
42+
$output = & gh @Arguments
43+
$exitCode = $LASTEXITCODE
44+
if ($exitCode -ne 0 -and -not $AllowFailure) {
45+
throw "gh $($Arguments -join ' ') failed with exit code $exitCode."
46+
}
47+
48+
return $output
49+
}
50+
51+
function Upsert-PullRequest {
52+
param(
53+
[Parameter(Mandatory = $true)]
54+
[string]$Repository,
55+
[Parameter(Mandatory = $true)]
56+
[string]$HeadBranch,
57+
[Parameter(Mandatory = $true)]
58+
[string]$BaseBranch,
59+
[Parameter(Mandatory = $true)]
60+
[string]$Title,
61+
[Parameter(Mandatory = $true)]
62+
[string]$Body
63+
)
64+
65+
$existing = Invoke-Gh -Arguments @('pr', 'list', '--repo', $Repository, '--base', $BaseBranch, '--head', $HeadBranch, '--state', 'open', '--json', 'number', '--jq', '.[0].number')
66+
if ([string]::IsNullOrWhiteSpace($existing)) {
67+
return (Invoke-Gh -Arguments @('pr', 'create', '--repo', $Repository, '--base', $BaseBranch, '--head', $HeadBranch, '--title', $Title, '--body', $Body, '--json', 'number', '--jq', '.number'))
68+
}
69+
70+
Invoke-Gh -Arguments @('pr', 'edit', $existing, '--repo', $Repository, '--title', $Title, '--body', $Body) | Out-Null
71+
return $existing
72+
}
73+
74+
function Enable-PullRequestAutoMerge {
75+
param(
76+
[Parameter(Mandatory = $true)]
77+
[string]$Repository,
78+
[Parameter(Mandatory = $true)]
79+
[string]$PullRequestNumber
80+
)
81+
82+
Invoke-Gh -Arguments @('pr', 'merge', $PullRequestNumber, '--repo', $Repository, '--squash', '--auto', '--delete-branch') | Out-Null
83+
}
84+
85+
function Upsert-IssueComment {
86+
param(
87+
[Parameter(Mandatory = $true)]
88+
[string]$Repository,
89+
[Parameter(Mandatory = $true)]
90+
[int]$IssueNumber,
91+
[Parameter(Mandatory = $true)]
92+
[string]$Marker,
93+
[Parameter(Mandatory = $true)]
94+
[string]$Body
95+
)
96+
97+
$commentsJson = Invoke-Gh -Arguments @('api', "repos/$Repository/issues/$IssueNumber/comments?per_page=100")
98+
$comments = @($commentsJson | ConvertFrom-Json)
99+
$existing = $comments | Where-Object { $_.body -like "*$Marker*" } | Select-Object -First 1
100+
101+
if ($null -ne $existing) {
102+
Invoke-Gh -Arguments @('api', '--method', 'PATCH', "repos/$Repository/issues/comments/$($existing.id)", '-f', "body=$Body") | Out-Null
103+
return
104+
}
105+
106+
Invoke-Gh -Arguments @('api', '--method', 'POST', "repos/$Repository/issues/$IssueNumber/comments", '-f', "body=$Body") | Out-Null
107+
}

0 commit comments

Comments
 (0)