Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b9bb0d1

Browse files
author
James Brundage
committedMar 16, 2025·
feat: JSON-LD module scaffolding and build ( Fixes #1, Fixes #3, Fixes #4 )
Fixing typo, adding workflow and FUNDING.yml
1 parent 6659541 commit b9bb0d1

File tree

3 files changed

+512
-1
lines changed

3 files changed

+512
-1
lines changed
 

‎.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
github: [StartAutomating]

‎.github/workflows/JSON-LD-Build.yml

Lines changed: 510 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,510 @@
1+
2+
name: oEmbed Module Build
3+
on:
4+
push:
5+
pull_request:
6+
workflow_dispatch:
7+
jobs:
8+
TestPowerShellOnLinux:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: InstallPester
12+
id: InstallPester
13+
shell: pwsh
14+
run: |
15+
$Parameters = @{}
16+
$Parameters.PesterMaxVersion = ${env:PesterMaxVersion}
17+
foreach ($k in @($parameters.Keys)) {
18+
if ([String]::IsNullOrEmpty($parameters[$k])) {
19+
$parameters.Remove($k)
20+
}
21+
}
22+
Write-Host "::debug:: InstallPester $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')"
23+
& {<#
24+
.Synopsis
25+
Installs Pester
26+
.Description
27+
Installs Pester
28+
#>
29+
param(
30+
# The maximum pester version. Defaults to 4.99.99.
31+
[string]
32+
$PesterMaxVersion = '4.99.99'
33+
)
34+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
35+
Install-Module -Name Pester -Repository PSGallery -Force -Scope CurrentUser -MaximumVersion $PesterMaxVersion -SkipPublisherCheck -AllowClobber
36+
Import-Module Pester -Force -PassThru -MaximumVersion $PesterMaxVersion} @Parameters
37+
- name: Check out repository
38+
uses: actions/checkout@v4
39+
- name: RunPester
40+
id: RunPester
41+
shell: pwsh
42+
run: |
43+
$Parameters = @{}
44+
$Parameters.ModulePath = ${env:ModulePath}
45+
$Parameters.PesterMaxVersion = ${env:PesterMaxVersion}
46+
$Parameters.NoCoverage = ${env:NoCoverage}
47+
$Parameters.NoCoverage = $parameters.NoCoverage -match 'true';
48+
foreach ($k in @($parameters.Keys)) {
49+
if ([String]::IsNullOrEmpty($parameters[$k])) {
50+
$parameters.Remove($k)
51+
}
52+
}
53+
Write-Host "::debug:: RunPester $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')"
54+
& {<#
55+
.Synopsis
56+
Runs Pester
57+
.Description
58+
Runs Pester tests after importing a PowerShell module
59+
#>
60+
param(
61+
# The module path. If not provided, will default to the second half of the repository ID.
62+
[string]
63+
$ModulePath,
64+
# The Pester max version. By default, this is pinned to 4.99.99.
65+
[string]
66+
$PesterMaxVersion = '4.99.99',
67+
68+
# If set, will not collect code coverage.
69+
[switch]
70+
$NoCoverage
71+
)
72+
73+
$global:ErrorActionPreference = 'continue'
74+
$global:ProgressPreference = 'silentlycontinue'
75+
76+
$orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/"
77+
if (-not $ModulePath) { $ModulePath = ".\$moduleName.psd1" }
78+
$importedPester = Import-Module Pester -Force -PassThru -MaximumVersion $PesterMaxVersion
79+
$importedModule = Import-Module $ModulePath -Force -PassThru
80+
$importedPester, $importedModule | Out-Host
81+
82+
$codeCoverageParameters = @{
83+
CodeCoverage = "$($importedModule | Split-Path)\*-*.ps1"
84+
CodeCoverageOutputFile = ".\$moduleName.Coverage.xml"
85+
}
86+
87+
if ($NoCoverage) {
88+
$codeCoverageParameters = @{}
89+
}
90+
91+
92+
$result =
93+
Invoke-Pester -PassThru -Verbose -OutputFile ".\$moduleName.TestResults.xml" -OutputFormat NUnitXml @codeCoverageParameters
94+
95+
if ($result.FailedCount -gt 0) {
96+
"::debug:: $($result.FailedCount) tests failed"
97+
foreach ($r in $result.TestResult) {
98+
if (-not $r.Passed) {
99+
"::error::$($r.describe, $r.context, $r.name -join ' ') $($r.FailureMessage)"
100+
}
101+
}
102+
throw "::error:: $($result.FailedCount) tests failed"
103+
}
104+
} @Parameters
105+
- name: PublishTestResults
106+
uses: actions/upload-artifact@main
107+
with:
108+
name: PesterResults
109+
path: '**.TestResults.xml'
110+
if: ${{always()}}
111+
TagReleaseAndPublish:
112+
runs-on: ubuntu-latest
113+
if: ${{ success() }}
114+
steps:
115+
- name: Check out repository
116+
uses: actions/checkout@v2
117+
- name: TagModuleVersion
118+
id: TagModuleVersion
119+
shell: pwsh
120+
run: |
121+
$Parameters = @{}
122+
$Parameters.ModulePath = ${env:ModulePath}
123+
$Parameters.UserEmail = ${env:UserEmail}
124+
$Parameters.UserName = ${env:UserName}
125+
$Parameters.TagVersionFormat = ${env:TagVersionFormat}
126+
$Parameters.TagAnnotationFormat = ${env:TagAnnotationFormat}
127+
foreach ($k in @($parameters.Keys)) {
128+
if ([String]::IsNullOrEmpty($parameters[$k])) {
129+
$parameters.Remove($k)
130+
}
131+
}
132+
Write-Host "::debug:: TagModuleVersion $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')"
133+
& {param(
134+
[string]
135+
$ModulePath,
136+
137+
# The user email associated with a git commit.
138+
[string]
139+
$UserEmail,
140+
141+
# The user name associated with a git commit.
142+
[string]
143+
$UserName,
144+
145+
# The tag version format (default value: 'v$(imported.Version)')
146+
# This can expand variables. $imported will contain the imported module.
147+
[string]
148+
$TagVersionFormat = 'v$($imported.Version)',
149+
150+
# The tag version format (default value: '$($imported.Name) $(imported.Version)')
151+
# This can expand variables. $imported will contain the imported module.
152+
[string]
153+
$TagAnnotationFormat = '$($imported.Name) $($imported.Version)'
154+
)
155+
156+
157+
$gitHubEvent = if ($env:GITHUB_EVENT_PATH) {
158+
[IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json
159+
} else { $null }
160+
161+
162+
@"
163+
::group::GitHubEvent
164+
$($gitHubEvent | ConvertTo-Json -Depth 100)
165+
::endgroup::
166+
"@ | Out-Host
167+
168+
if (-not ($gitHubEvent.head_commit.message -match "Merge Pull Request #(?<PRNumber>\d+)") -and
169+
(-not $gitHubEvent.psobject.properties['inputs'])) {
170+
"::warning::Pull Request has not merged, skipping Tagging" | Out-Host
171+
return
172+
}
173+
174+
175+
176+
$imported =
177+
if (-not $ModulePath) {
178+
$orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/"
179+
Import-Module ".\$moduleName.psd1" -Force -PassThru -Global
180+
} else {
181+
Import-Module $modulePath -Force -PassThru -Global
182+
}
183+
184+
if (-not $imported) { return }
185+
186+
$targetVersion =$ExecutionContext.InvokeCommand.ExpandString($TagVersionFormat)
187+
$existingTags = git tag --list
188+
189+
@"
190+
Target Version: $targetVersion
191+
192+
Existing Tags:
193+
$($existingTags -join [Environment]::NewLine)
194+
"@ | Out-Host
195+
196+
$versionTagExists = $existingTags | Where-Object { $_ -match $targetVersion }
197+
198+
if ($versionTagExists) {
199+
"::warning::Version $($versionTagExists)"
200+
return
201+
}
202+
203+
if (-not $UserName) { $UserName = $env:GITHUB_ACTOR }
204+
if (-not $UserEmail) { $UserEmail = "$UserName@github.com" }
205+
git config --global user.email $UserEmail
206+
git config --global user.name $UserName
207+
208+
git tag -a $targetVersion -m $ExecutionContext.InvokeCommand.ExpandString($TagAnnotationFormat)
209+
git push origin --tags
210+
211+
if ($env:GITHUB_ACTOR) {
212+
exit 0
213+
}} @Parameters
214+
- name: ReleaseModule
215+
id: ReleaseModule
216+
shell: pwsh
217+
run: |
218+
$Parameters = @{}
219+
$Parameters.ModulePath = ${env:ModulePath}
220+
$Parameters.UserEmail = ${env:UserEmail}
221+
$Parameters.UserName = ${env:UserName}
222+
$Parameters.TagVersionFormat = ${env:TagVersionFormat}
223+
$Parameters.ReleaseNameFormat = ${env:ReleaseNameFormat}
224+
$Parameters.ReleaseAsset = ${env:ReleaseAsset}
225+
$Parameters.ReleaseAsset = $parameters.ReleaseAsset -split ';' -replace '^[''"]' -replace '[''"]$'
226+
foreach ($k in @($parameters.Keys)) {
227+
if ([String]::IsNullOrEmpty($parameters[$k])) {
228+
$parameters.Remove($k)
229+
}
230+
}
231+
Write-Host "::debug:: ReleaseModule $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')"
232+
& {param(
233+
[string]
234+
$ModulePath,
235+
236+
# The user email associated with a git commit.
237+
[string]
238+
$UserEmail,
239+
240+
# The user name associated with a git commit.
241+
[string]
242+
$UserName,
243+
244+
# The tag version format (default value: 'v$(imported.Version)')
245+
# This can expand variables. $imported will contain the imported module.
246+
[string]
247+
$TagVersionFormat = 'v$($imported.Version)',
248+
249+
# The release name format (default value: '$($imported.Name) $($imported.Version)')
250+
[string]
251+
$ReleaseNameFormat = '$($imported.Name) $($imported.Version)',
252+
253+
# Any assets to attach to the release. Can be a wildcard or file name.
254+
[string[]]
255+
$ReleaseAsset
256+
)
257+
258+
259+
$gitHubEvent = if ($env:GITHUB_EVENT_PATH) {
260+
[IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json
261+
} else { $null }
262+
263+
264+
@"
265+
::group::GitHubEvent
266+
$($gitHubEvent | ConvertTo-Json -Depth 100)
267+
::endgroup::
268+
"@ | Out-Host
269+
270+
if (-not ($gitHubEvent.head_commit.message -match "Merge Pull Request #(?<PRNumber>\d+)") -and
271+
(-not $gitHubEvent.psobject.properties['inputs'])) {
272+
"::warning::Pull Request has not merged, skipping GitHub release" | Out-Host
273+
return
274+
}
275+
276+
277+
278+
$imported =
279+
if (-not $ModulePath) {
280+
$orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/"
281+
Import-Module ".\$moduleName.psd1" -Force -PassThru -Global
282+
} else {
283+
Import-Module $modulePath -Force -PassThru -Global
284+
}
285+
286+
if (-not $imported) { return }
287+
288+
$targetVersion =$ExecutionContext.InvokeCommand.ExpandString($TagVersionFormat)
289+
$targetReleaseName = $targetVersion
290+
$releasesURL = 'https://api.github.com/repos/${{github.repository}}/releases'
291+
"Release URL: $releasesURL" | Out-Host
292+
$listOfReleases = Invoke-RestMethod -Uri $releasesURL -Method Get -Headers @{
293+
"Accept" = "application/vnd.github.v3+json"
294+
"Authorization" = 'Bearer ${{ secrets.GITHUB_TOKEN }}'
295+
}
296+
297+
$releaseExists = $listOfReleases | Where-Object tag_name -eq $targetVersion
298+
299+
if ($releaseExists) {
300+
"::warning::Release '$($releaseExists.Name )' Already Exists" | Out-Host
301+
$releasedIt = $releaseExists
302+
} else {
303+
$releasedIt = Invoke-RestMethod -Uri $releasesURL -Method Post -Body (
304+
[Ordered]@{
305+
owner = '${{github.owner}}'
306+
repo = '${{github.repository}}'
307+
tag_name = $targetVersion
308+
name = $ExecutionContext.InvokeCommand.ExpandString($ReleaseNameFormat)
309+
body =
310+
if ($env:RELEASENOTES) {
311+
$env:RELEASENOTES
312+
} elseif ($imported.PrivateData.PSData.ReleaseNotes) {
313+
$imported.PrivateData.PSData.ReleaseNotes
314+
} else {
315+
"$($imported.Name) $targetVersion"
316+
}
317+
draft = if ($env:RELEASEISDRAFT) { [bool]::Parse($env:RELEASEISDRAFT) } else { $false }
318+
prerelease = if ($env:PRERELEASE) { [bool]::Parse($env:PRERELEASE) } else { $false }
319+
} | ConvertTo-Json
320+
) -Headers @{
321+
"Accept" = "application/vnd.github.v3+json"
322+
"Content-type" = "application/json"
323+
"Authorization" = 'Bearer ${{ secrets.GITHUB_TOKEN }}'
324+
}
325+
}
326+
327+
328+
329+
330+
331+
if (-not $releasedIt) {
332+
throw "Release failed"
333+
} else {
334+
$releasedIt | Out-Host
335+
}
336+
337+
$releaseUploadUrl = $releasedIt.upload_url -replace '\{.+$'
338+
339+
if ($ReleaseAsset) {
340+
$fileList = Get-ChildItem -Recurse
341+
$filesToRelease =
342+
@(:nextFile foreach ($file in $fileList) {
343+
foreach ($relAsset in $ReleaseAsset) {
344+
if ($relAsset -match '[\*\?]') {
345+
if ($file.Name -like $relAsset) {
346+
$file; continue nextFile
347+
}
348+
} elseif ($file.Name -eq $relAsset -or $file.FullName -eq $relAsset) {
349+
$file; continue nextFile
350+
}
351+
}
352+
})
353+
354+
$releasedFiles = @{}
355+
foreach ($file in $filesToRelease) {
356+
if ($releasedFiles[$file.Name]) {
357+
Write-Warning "Already attached file $($file.Name)"
358+
continue
359+
} else {
360+
$fileBytes = [IO.File]::ReadAllBytes($file.FullName)
361+
$releasedFiles[$file.Name] =
362+
Invoke-RestMethod -Uri "${releaseUploadUrl}?name=$($file.Name)" -Headers @{
363+
"Accept" = "application/vnd.github+json"
364+
"Authorization" = 'Bearer ${{ secrets.GITHUB_TOKEN }}'
365+
} -Body $fileBytes -ContentType Application/octet-stream
366+
$releasedFiles[$file.Name]
367+
}
368+
}
369+
370+
"Attached $($releasedFiles.Count) file(s) to release" | Out-Host
371+
}
372+
373+
374+
375+
} @Parameters
376+
- name: PublishPowerShellGallery
377+
id: PublishPowerShellGallery
378+
shell: pwsh
379+
run: |
380+
$Parameters = @{}
381+
$Parameters.ModulePath = ${env:ModulePath}
382+
$Parameters.Exclude = ${env:Exclude}
383+
$Parameters.Exclude = $parameters.Exclude -split ';' -replace '^[''"]' -replace '[''"]$'
384+
foreach ($k in @($parameters.Keys)) {
385+
if ([String]::IsNullOrEmpty($parameters[$k])) {
386+
$parameters.Remove($k)
387+
}
388+
}
389+
Write-Host "::debug:: PublishPowerShellGallery $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')"
390+
& {param(
391+
[string]
392+
$ModulePath,
393+
394+
[string[]]
395+
$Exclude = @('*.png', '*.mp4', '*.jpg','*.jpeg', '*.gif', 'docs[/\]*')
396+
)
397+
398+
$gitHubEvent = if ($env:GITHUB_EVENT_PATH) {
399+
[IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json
400+
} else { $null }
401+
402+
if (-not $Exclude) {
403+
$Exclude = @('*.png', '*.mp4', '*.jpg','*.jpeg', '*.gif','docs[/\]*')
404+
}
405+
406+
407+
@"
408+
::group::GitHubEvent
409+
$($gitHubEvent | ConvertTo-Json -Depth 100)
410+
::endgroup::
411+
"@ | Out-Host
412+
413+
@"
414+
::group::PSBoundParameters
415+
$($PSBoundParameters | ConvertTo-Json -Depth 100)
416+
::endgroup::
417+
"@ | Out-Host
418+
419+
if (-not ($gitHubEvent.head_commit.message -match "Merge Pull Request #(?<PRNumber>\d+)") -and
420+
(-not $gitHubEvent.psobject.properties['inputs'])) {
421+
"::warning::Pull Request has not merged, skipping Gallery Publish" | Out-Host
422+
return
423+
}
424+
425+
426+
$imported =
427+
if (-not $ModulePath) {
428+
$orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/"
429+
Import-Module ".\$moduleName.psd1" -Force -PassThru -Global
430+
} else {
431+
Import-Module $modulePath -Force -PassThru -Global
432+
}
433+
434+
if (-not $imported) { return }
435+
436+
$foundModule = try { Find-Module -Name $imported.Name -ErrorAction SilentlyContinue} catch {}
437+
438+
if ($foundModule -and (([Version]$foundModule.Version) -ge ([Version]$imported.Version))) {
439+
"::warning::Gallery Version of $moduleName is more recent ($($foundModule.Version) >= $($imported.Version))" | Out-Host
440+
} else {
441+
442+
$gk = '${{secrets.GALLERYKEY}}'
443+
444+
$rn = Get-Random
445+
$moduleTempFolder = Join-Path $pwd "$rn"
446+
$moduleTempPath = Join-Path $moduleTempFolder $moduleName
447+
New-Item -ItemType Directory -Path $moduleTempPath -Force | Out-Host
448+
449+
Write-Host "Staging Directory: $ModuleTempPath"
450+
451+
$imported | Split-Path |
452+
Get-ChildItem -Force |
453+
Where-Object Name -NE $rn |
454+
Copy-Item -Destination $moduleTempPath -Recurse
455+
456+
$moduleGitPath = Join-Path $moduleTempPath '.git'
457+
Write-Host "Removing .git directory"
458+
if (Test-Path $moduleGitPath) {
459+
Remove-Item -Recurse -Force $moduleGitPath
460+
}
461+
462+
if ($Exclude) {
463+
"::notice::Attempting to Exlcude $exclude" | Out-Host
464+
Get-ChildItem $moduleTempPath -Recurse |
465+
Where-Object {
466+
foreach ($ex in $exclude) {
467+
if ($_.FullName -like $ex) {
468+
"::notice::Excluding $($_.FullName)" | Out-Host
469+
return $true
470+
}
471+
}
472+
} |
473+
Remove-Item
474+
}
475+
476+
Write-Host "Module Files:"
477+
Get-ChildItem $moduleTempPath -Recurse
478+
Write-Host "Publishing $moduleName [$($imported.Version)] to Gallery"
479+
Publish-Module -Path $moduleTempPath -NuGetApiKey $gk
480+
if ($?) {
481+
Write-Host "Published to Gallery"
482+
} else {
483+
Write-Host "Gallery Publish Failed"
484+
exit 1
485+
}
486+
}
487+
} @Parameters
488+
JsonLD:
489+
runs-on: ubuntu-latest
490+
if: ${{ success() }}
491+
steps:
492+
- name: Check out repository
493+
uses: actions/checkout@v2
494+
- name: GitLogger
495+
uses: GitLogging/GitLoggerAction@main
496+
id: GitLogger
497+
- name: Use PSSVG Action
498+
uses: StartAutomating/PSSVG@main
499+
id: PSSVG
500+
- name: Use PipeScript Action
501+
uses: StartAutomating/PipeScript@main
502+
id: PipeScript
503+
- name: UseEZOut
504+
uses: StartAutomating/EZOut@master
505+
- name: UseHelpOut
506+
uses: StartAutomating/HelpOut@master
507+
- name: Use PSJekyll Action
508+
uses: PowerShellWeb/PSJekyll@main
509+
id: PSJekyll
510+

‎Build/JSON-LD.GitHubWorkflow.PSDevOps.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ Push-Location ($PSScriptRoot | Split-Path)
77
New-GitHubWorkflow -Name "oEmbed Module Build" -On Push,
88
PullRequest,
99
Demand -Job TestPowerShellOnLinux,
10-
TagReleaseAndPublish, JsonLD -OutputPath .\.github\workflows\oEmbed-Build.yml
10+
TagReleaseAndPublish, JsonLD -OutputPath .\.github\workflows\JSON-LD-Build.yml
1111

1212
Pop-Location

0 commit comments

Comments
 (0)
Please sign in to comment.