Skip to content

Commit 4158fcc

Browse files
author
James Brundage
committed
Adding GitHub Action (#49)
1 parent a7e31cc commit 4158fcc

File tree

3 files changed

+396
-0
lines changed

3 files changed

+396
-0
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<#
2+
.Synopsis
3+
GitHub Action for PipeScript
4+
.Description
5+
GitHub Action for PipeScript. This will:
6+
7+
* Import PipeScript
8+
* Run all *.PipeScript.ps1 files beneath the workflow directory
9+
* Run a .PipeScriptScript parameter
10+
11+
Any files changed can be outputted by the script, and those changes can be checked back into the repo.
12+
Make sure to use the "persistCredentials" option with checkout.
13+
#>
14+
15+
param(
16+
# A PowerShell Script that uses PipeScript.
17+
# Any files outputted from the script will be added to the repository.
18+
# If those files have a .Message attached to them, they will be committed with that message.
19+
[string]
20+
$PipeScript,
21+
22+
# If set, will not run Build-PipeScript.
23+
[switch]
24+
$SkipBuild,
25+
26+
# If provided, will commit any remaining changes made to the workspace with this commit message.
27+
# If no commit message is provided, if a GitHub Event contains a commit message, that message will be used.
28+
# If no commit message is provided, and a commit message cannot be automatically detected, changes will not be committed.
29+
[string]
30+
$CommitMessage,
31+
32+
# The user email associated with a git commit.
33+
[string]
34+
$UserEmail,
35+
36+
# The user name associated with a git commit.
37+
[string]
38+
$UserName
39+
)
40+
41+
"::group::Parameters" | Out-Host
42+
[PSCustomObject]$PSBoundParameters | Format-List | Out-Host
43+
"::endgroup::" | Out-Host
44+
45+
$gitHubEvent = if ($env:GITHUB_EVENT_PATH) {
46+
[IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json
47+
} else { $null }
48+
49+
@"
50+
::group::GitHubEvent
51+
$($gitHubEvent | ConvertTo-Json -Depth 100)
52+
::endgroup::
53+
"@ | Out-Host
54+
55+
if ($env:GITHUB_ACTION_PATH) {
56+
$PipeScriptModulePath = Join-Path $env:GITHUB_ACTION_PATH 'PipeScript.psd1'
57+
if (Test-path $PipeScriptModulePath) {
58+
Import-Module $PipeScriptModulePath -Force -PassThru | Out-String
59+
} else {
60+
throw "PipeScript not found"
61+
}
62+
} elseif (-not (Get-Module PipeScript)) {
63+
throw "Action Path not found"
64+
}
65+
66+
"::notice title=ModuleLoaded::PipeScript Loaded from Path - $($PipeScriptModulePath)" | Out-Host
67+
68+
$anyFilesChanged = $false
69+
$processScriptOutput = { process {
70+
$out = $_
71+
$outItem = Get-Item -Path $out -ErrorAction SilentlyContinue
72+
$fullName, $shouldCommit =
73+
if ($out -is [IO.FileInfo]) {
74+
$out.FullName, (git status $out.Fullname -s)
75+
} elseif ($outItem) {
76+
$outItem.FullName, (git status $outItem.Fullname -s)
77+
}
78+
if ($shouldCommit) {
79+
git add $fullName
80+
if ($out.Message) {
81+
git commit -m "$($out.Message)"
82+
} elseif ($out.CommitMessage) {
83+
git commit -m "$($out.CommitMessage)"
84+
}
85+
elseif ($CommitMessage) {
86+
git commit -m $CommitMessage
87+
}
88+
elseif ($gitHubEvent.head_commit.message) {
89+
git commit -m "$($gitHubEvent.head_commit.message)"
90+
}
91+
$anyFilesChanged = $true
92+
}
93+
$out
94+
} }
95+
96+
97+
if (-not $UserName) { $UserName = $env:GITHUB_ACTOR }
98+
if (-not $UserEmail) { $UserEmail = "$UserName@github.com" }
99+
git config --global user.email $UserEmail
100+
git config --global user.name $UserName
101+
102+
if (-not $env:GITHUB_WORKSPACE) { throw "No GitHub workspace" }
103+
104+
git pull | Out-Host
105+
106+
$PipeScriptStart = [DateTime]::Now
107+
if ($PipeScript) {
108+
Invoke-PipeScript -Command $PipeScript |
109+
. $processScriptOutput |
110+
Out-Host
111+
}
112+
113+
$PipeScriptTook = [Datetime]::Now - $PipeScriptScriptStart
114+
"::set-output name=PipeScriptRuntime::$($PipeScriptScriptTook.TotalMilliseconds)" | Out-Host
115+
116+
$BuildPipeScriptStart = [DateTime]::Now
117+
if (-not $SkipBuild) {
118+
$buildOutputFiles = @(Build-Pipescript -InputPath $env:GITHUB_WORKSPACE)
119+
$buildOutputFiles |
120+
. $processScriptOutput |
121+
Out-Host
122+
}
123+
124+
$BuildPipeScriptEnd = [DateTime]::Now
125+
$BuildPipeScriptTook = $BuildPipeScriptEnd - $BuildPipeScriptStart
126+
"::set-output name=PipeScriptFilesBuiltCount::$($buildOutputFiles.Length)" | Out-Host
127+
"::set-output name=PipeScriptFilesBuilt::$($buildOutputFiles -join ';')" | Out-Host
128+
"::set-output name=PipeScriptBuildRuntime::$($BuildPipeScriptTook.TotalMilliseconds)" | Out-Host
129+
if ($CommitMessage -or $anyFilesChanged) {
130+
if ($CommitMessage) {
131+
dir $env:GITHUB_WORKSPACE -Recurse |
132+
ForEach-Object {
133+
$gitStatusOutput = git status $_.Fullname -s
134+
if ($gitStatusOutput) {
135+
git add $_.Fullname
136+
}
137+
}
138+
139+
git commit -m $ExecutionContext.SessionState.InvokeCommand.ExpandString($CommitMessage)
140+
}
141+
142+
$checkDetached = git symbolic-ref -q HEAD
143+
if (-not $LASTEXITCODE) {
144+
"::notice::Pushing Changes" | Out-Host
145+
git push
146+
"Git Push Output: $($gitPushed | Out-String)"
147+
} else {
148+
"::notice::Not pushing changes (on detached head)" | Out-Host
149+
$LASTEXITCODE = 0
150+
exit 0
151+
}
152+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#requires -Module PSDevOps
2+
#requires -Module PipeScript
3+
Import-BuildStep -ModuleName PipeScript
4+
New-GitHubAction -Name "BuildPipeScript" -Description 'Builds code using PipeScript' -Action PipeScriptAction -Icon code -ActionOutput ([Ordered]@{
5+
PipeScriptRuntime = [Ordered]@{
6+
description = "The time it took the .PipeScript parameter to run"
7+
value = '${{steps.PipeScriptAction.outputs.PipeScriptRuntime}}'
8+
}
9+
PipeScriptBuildRuntime = [Ordered]@{
10+
description = "The time it took Build-PipeScript to run"
11+
value = '${{steps.PipeScriptAction.outputs.PipeScriptBuildRuntime}}'
12+
}
13+
PipeScriptFilesBuilt = [Ordered]@{
14+
description = "The files built using PipeScript (separated by semicolons)"
15+
value = '${{steps.PipeScriptAction.outputs.PipeScriptFilesBuilt}}'
16+
}
17+
PipeScriptFilesBuiltCount = [Ordered]@{
18+
description = "The number of .PipeScript.ps1 files that were run"
19+
value = '${{steps.PipeScriptAction.outputs.PipeScriptFilesBuiltCount}}'
20+
}
21+
}) |
22+
Set-Content .\action.yml -Encoding UTF8 -PassThru

action.yml

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
2+
name: BuildPipeScript
3+
description: Builds code using PipeScript
4+
inputs:
5+
PipeScript:
6+
required: false
7+
description: |
8+
A PowerShell Script that uses PipeScript.
9+
Any files outputted from the script will be added to the repository.
10+
If those files have a .Message attached to them, they will be committed with that message.
11+
SkipBuild:
12+
required: false
13+
description: If set, will not run Build-PipeScript.
14+
CommitMessage:
15+
required: false
16+
description: |
17+
If provided, will commit any remaining changes made to the workspace with this commit message.
18+
If no commit message is provided, if a GitHub Event contains a commit message, that message will be used.
19+
If no commit message is provided, and a commit message cannot be automatically detected, changes will not be committed.
20+
UserEmail:
21+
required: false
22+
description: The user email associated with a git commit.
23+
UserName:
24+
required: false
25+
description: The user name associated with a git commit.
26+
branding:
27+
icon: code
28+
color: blue
29+
outputs:
30+
31+
PipeScriptRuntime:
32+
description: The time it took the .PipeScript parameter to run
33+
value: ${{steps.PipeScriptAction.outputs.PipeScriptRuntime}}
34+
PipeScriptBuildRuntime:
35+
description: The time it took Build-PipeScript to run
36+
value: ${{steps.PipeScriptAction.outputs.PipeScriptBuildRuntime}}
37+
PipeScriptFilesBuilt:
38+
description: The files built using PipeScript (separated by semicolons)
39+
value: ${{steps.PipeScriptAction.outputs.PipeScriptFilesBuilt}}
40+
PipeScriptFilesBuiltCount:
41+
description: The number of .PipeScript.ps1 files that were run
42+
value: ${{steps.PipeScriptAction.outputs.PipeScriptFilesBuiltCount}}
43+
runs:
44+
using: composite
45+
steps:
46+
- name: PipeScriptAction
47+
id: PipeScriptAction
48+
shell: pwsh
49+
env:
50+
SkipBuild: ${{inputs.SkipBuild}}
51+
CommitMessage: ${{inputs.CommitMessage}}
52+
PipeScript: ${{inputs.PipeScript}}
53+
UserEmail: ${{inputs.UserEmail}}
54+
UserName: ${{inputs.UserName}}
55+
run: |
56+
$Parameters = @{}
57+
$Parameters.PipeScript = ${env:PipeScript}
58+
$Parameters.SkipBuild = ${env:SkipBuild}
59+
$Parameters.SkipBuild = $parameters.SkipBuild -match 'true';
60+
$Parameters.CommitMessage = ${env:CommitMessage}
61+
$Parameters.UserEmail = ${env:UserEmail}
62+
$Parameters.UserName = ${env:UserName}
63+
foreach ($k in @($parameters.Keys)) {
64+
if ([String]::IsNullOrEmpty($parameters[$k])) {
65+
$parameters.Remove($k)
66+
}
67+
}
68+
Write-Host "::debug:: PipeScriptAction $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')"
69+
& {<#
70+
.Synopsis
71+
GitHub Action for PipeScript
72+
.Description
73+
GitHub Action for PipeScript. This will:
74+
75+
* Import PipeScript
76+
* Run all *.PipeScript.ps1 files beneath the workflow directory
77+
* Run a .PipeScriptScript parameter
78+
79+
Any files changed can be outputted by the script, and those changes can be checked back into the repo.
80+
Make sure to use the "persistCredentials" option with checkout.
81+
#>
82+
83+
param(
84+
# A PowerShell Script that uses PipeScript.
85+
# Any files outputted from the script will be added to the repository.
86+
# If those files have a .Message attached to them, they will be committed with that message.
87+
[string]
88+
$PipeScript,
89+
90+
# If set, will not run Build-PipeScript.
91+
[switch]
92+
$SkipBuild,
93+
94+
# If provided, will commit any remaining changes made to the workspace with this commit message.
95+
# If no commit message is provided, if a GitHub Event contains a commit message, that message will be used.
96+
# If no commit message is provided, and a commit message cannot be automatically detected, changes will not be committed.
97+
[string]
98+
$CommitMessage,
99+
100+
# The user email associated with a git commit.
101+
[string]
102+
$UserEmail,
103+
104+
# The user name associated with a git commit.
105+
[string]
106+
$UserName
107+
)
108+
109+
"::group::Parameters" | Out-Host
110+
[PSCustomObject]$PSBoundParameters | Format-List | Out-Host
111+
"::endgroup::" | Out-Host
112+
113+
$gitHubEvent = if ($env:GITHUB_EVENT_PATH) {
114+
[IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json
115+
} else { $null }
116+
117+
@"
118+
::group::GitHubEvent
119+
$($gitHubEvent | ConvertTo-Json -Depth 100)
120+
::endgroup::
121+
"@ | Out-Host
122+
123+
if ($env:GITHUB_ACTION_PATH) {
124+
$PipeScriptModulePath = Join-Path $env:GITHUB_ACTION_PATH 'PipeScript.psd1'
125+
if (Test-path $PipeScriptModulePath) {
126+
Import-Module $PipeScriptModulePath -Force -PassThru | Out-String
127+
} else {
128+
throw "PipeScript not found"
129+
}
130+
} elseif (-not (Get-Module PipeScript)) {
131+
throw "Action Path not found"
132+
}
133+
134+
"::notice title=ModuleLoaded::PipeScript Loaded from Path - $($PipeScriptModulePath)" | Out-Host
135+
136+
$anyFilesChanged = $false
137+
$processScriptOutput = { process {
138+
$out = $_
139+
$outItem = Get-Item -Path $out -ErrorAction SilentlyContinue
140+
$fullName, $shouldCommit =
141+
if ($out -is [IO.FileInfo]) {
142+
$out.FullName, (git status $out.Fullname -s)
143+
} elseif ($outItem) {
144+
$outItem.FullName, (git status $outItem.Fullname -s)
145+
}
146+
if ($shouldCommit) {
147+
git add $fullName
148+
if ($out.Message) {
149+
git commit -m "$($out.Message)"
150+
} elseif ($out.CommitMessage) {
151+
git commit -m "$($out.CommitMessage)"
152+
}
153+
elseif ($CommitMessage) {
154+
git commit -m $CommitMessage
155+
}
156+
elseif ($gitHubEvent.head_commit.message) {
157+
git commit -m "$($gitHubEvent.head_commit.message)"
158+
}
159+
$anyFilesChanged = $true
160+
}
161+
$out
162+
} }
163+
164+
165+
if (-not $UserName) { $UserName = $env:GITHUB_ACTOR }
166+
if (-not $UserEmail) { $UserEmail = "[email protected]" }
167+
git config --global user.email $UserEmail
168+
git config --global user.name $UserName
169+
170+
if (-not $env:GITHUB_WORKSPACE) { throw "No GitHub workspace" }
171+
172+
git pull | Out-Host
173+
174+
$PipeScriptStart = [DateTime]::Now
175+
if ($PipeScript) {
176+
Invoke-PipeScript -Command $PipeScript |
177+
. $processScriptOutput |
178+
Out-Host
179+
}
180+
181+
$PipeScriptTook = [Datetime]::Now - $PipeScriptScriptStart
182+
"::set-output name=PipeScriptRuntime::$($PipeScriptScriptTook.TotalMilliseconds)" | Out-Host
183+
184+
$BuildPipeScriptStart = [DateTime]::Now
185+
if (-not $SkipBuild) {
186+
$buildOutputFiles = @(Build-Pipescript -InputPath $env:GITHUB_WORKSPACE)
187+
$buildOutputFiles |
188+
. $processScriptOutput |
189+
Out-Host
190+
}
191+
192+
$BuildPipeScriptEnd = [DateTime]::Now
193+
$BuildPipeScriptTook = $BuildPipeScriptEnd - $BuildPipeScriptStart
194+
"::set-output name=PipeScriptFilesBuiltCount::$($buildOutputFiles.Length)" | Out-Host
195+
"::set-output name=PipeScriptFilesBuilt::$($buildOutputFiles -join ';')" | Out-Host
196+
"::set-output name=PipeScriptBuildRuntime::$($BuildPipeScriptTook.TotalMilliseconds)" | Out-Host
197+
if ($CommitMessage -or $anyFilesChanged) {
198+
if ($CommitMessage) {
199+
dir $env:GITHUB_WORKSPACE -Recurse |
200+
ForEach-Object {
201+
$gitStatusOutput = git status $_.Fullname -s
202+
if ($gitStatusOutput) {
203+
git add $_.Fullname
204+
}
205+
}
206+
207+
git commit -m $ExecutionContext.SessionState.InvokeCommand.ExpandString($CommitMessage)
208+
}
209+
210+
$checkDetached = git symbolic-ref -q HEAD
211+
if (-not $LASTEXITCODE) {
212+
"::notice::Pushing Changes" | Out-Host
213+
git push
214+
"Git Push Output: $($gitPushed | Out-String)"
215+
} else {
216+
"::notice::Not pushing changes (on detached head)" | Out-Host
217+
$LASTEXITCODE = 0
218+
exit 0
219+
}
220+
}
221+
} @Parameters
222+

0 commit comments

Comments
 (0)