Skip to content

Commit 3420293

Browse files
committed
Switch to Earthly build
1 parent 5e211f8 commit 3420293

9 files changed

+303
-20
lines changed

.github/workflows/build.yml

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
name: CI
2+
3+
on:
4+
push: {}
5+
pull_request:
6+
branches: [ main ]
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
env:
12+
FORCE_COLOR: 1
13+
steps:
14+
- uses: earthly/actions-setup@v1
15+
with:
16+
github-token: ${{ secrets.GITHUB_TOKEN }}
17+
18+
- uses: actions/checkout@v4
19+
with:
20+
submodules: true
21+
fetch-depth: 0
22+
23+
- name: earthly +test
24+
if: github.ref != 'refs/heads/main'
25+
run: earthly --strict +test
26+
27+
- name: earthly +push
28+
if: github.ref == 'refs/heads/main'
29+
run: earthly --push --secret NUGET_API_KEY --secret PSGALLERY_API_KEY --strict +all
30+
env:
31+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32+
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
33+
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
34+
35+
- uses: actions/upload-artifact@v4
36+
with:
37+
name: ModuleBuilder
38+
path: Modules/ModuleBuilder
39+
40+
- uses: actions/upload-artifact@v4
41+
with:
42+
name: TestResults
43+
path: Modules/ModuleBuilder-TestResults
44+
45+
- uses: actions/upload-artifact@v4
46+
with:
47+
name: Packages
48+
path: Modules/ModuleBuilder-Packages
49+
50+
- name: Upload Tests
51+
uses: actions/upload-artifact@v4
52+
with:
53+
name: PesterTests
54+
path: ${{github.workspace}}/Tests
55+
- name: Upload RequiredModules.psd1
56+
uses: actions/upload-artifact@v4
57+
with:
58+
name: RequiredModules
59+
path: ${{github.workspace}}/RequiredModules.psd1
60+
test:
61+
needs: build
62+
runs-on: ${{ matrix.os }}
63+
strategy:
64+
fail-fast: false
65+
matrix:
66+
os: [windows-latest, ubuntu-latest, macos-latest]
67+
steps:
68+
- name: Download Build Output
69+
uses: actions/download-artifact@v4
70+
with:
71+
name: ModuleBuilder
72+
path: Modules/ModuleBuilder
73+
- name: Download Pester Tests
74+
uses: actions/download-artifact@v4
75+
with:
76+
name: PesterTests
77+
path: PesterTests
78+
- name: Download RequiredModules
79+
uses: actions/download-artifact@v4
80+
with:
81+
name: RequiredModules
82+
83+
- uses: PoshCode/Actions/install-requiredmodules@v1
84+
- uses: PoshCode/Actions/pester@v1
85+
with:
86+
codeCoveragePath: Modules/ModuleBuilder
87+
moduleUnderTest: ModuleBuilder
88+
additionalModulePaths: ${{github.workspace}}/Modules
89+
- name: Publish Test Results
90+
uses: zyborg/dotnet-tests-report@v1
91+
with:
92+
test_results_path: results.xml
93+
- name: Upload Results
94+
uses: actions/upload-artifact@v2
95+
with:
96+
name: Pester Results
97+
path: ${{github.workspace}}/*.xml

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
output/
2+
Modules/

Build.build.ps1

+30-16
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,42 @@
44
.EXAMPLE
55
Invoke-Build
66
.NOTES
7-
0.5.0 - Parameterize
8-
Add parameters to this script to control the build
7+
0.7.0 - Now works with Earthly
8+
0.6.0 - Add PesterFilter for the Pester tass
9+
0.5.0 - Add Parameters to control the build (Clean, CollectCoverage)
10+
These are actually used by the Invoke-Build Tasks
911
#>
1012
[CmdletBinding()]
1113
param(
12-
# dotnet build configuration parameter (Debug or Release)
13-
[ValidateSet('Debug', 'Release')]
14-
[string]$Configuration = 'Release',
15-
1614
# Add the clean task before the default build
1715
[switch]$Clean,
1816

1917
# Collect code coverage when tests are run
20-
[switch]$CollectCoverage
18+
[switch]$CollectCoverage,
19+
20+
# The PesterFilter from New-PesterConfiguration.
21+
# Supports specifying any of:
22+
# Tag: Tags of Describe, Context or It to be run.
23+
# ExcludeTag: Tags of Describe, Context or It to be excluded from the run.
24+
# Line: Filter by file and scriptblock start line, useful to run parsed tests programmatically to avoid problems with expanded names. Example: 'C:\tests\file1.Tests.ps1:37'
25+
# ExcludeLine: Exclude by file and scriptblock start line, takes precedence over Line.
26+
# FullName: Full name of test with -like wildcards, joined by dot. Example: '*.describe Get-Item.test1'
27+
[hashtable]$PesterFilter
2128
)
2229
$InformationPreference = "Continue"
30+
$ErrorView = 'DetailedView'
2331

24-
$BuildTasks = "BuildTasks", "../BuildTasks", "../../BuildTasks" | Convert-Path -ErrorAction Ignore | Select-Object -First 1
32+
# The name of the module to publish
33+
$script:PSModuleName = "TerminalBlocks"
34+
$script:RequiredCodeCoverage = 0.85
35+
# Use Env because then Earthly can override it
36+
$Env:OUTPUT_ROOT ??= Join-Path $BuildRoot Modules
2537

38+
$Tasks = "Tasks", "../Tasks", "../../Tasks" | Convert-Path -ErrorAction Ignore | Select-Object -First 1
39+
Write-Information "$($PSStyle.Foreground.BrightCyan)Found shared tasks in $Tasks" -Tag "InvokeBuild"
2640
## Self-contained build script - can be invoked directly or via Invoke-Build
2741
if ($MyInvocation.ScriptName -notlike '*Invoke-Build.ps1') {
28-
& "$BuildTasks/_Bootstrap.ps1"
42+
& "$Tasks/_Bootstrap.ps1"
2943

3044
Invoke-Build -File $MyInvocation.MyCommand.Path @PSBoundParameters -Result Result
3145

@@ -36,12 +50,12 @@ if ($MyInvocation.ScriptName -notlike '*Invoke-Build.ps1') {
3650
exit 0
3751
}
3852

39-
## The first task defined is the default task
40-
if ($Clean) {
41-
Add-BuildTask . Clean, Test
42-
} else {
43-
Add-BuildTask . Test
53+
## The first task defined is the default task,
54+
if ($dotnetProjects -and $Clean) {
55+
Add-BuildTask CleanBuild Clean, ($Task ?? "Test")
56+
} elseif ($Clean) {
57+
Add-BuildTask CleanBuild Clean, ($Task ?? "Test")
4458
}
4559

46-
## Initialize the build variables, and import shared tasks, including DotNet tasks
47-
. "$BuildTasks/_Initialize.ps1" -PSModuleTasks
60+
## Initialize the build variables, and import shared tasks
61+
. "$Tasks/_Initialize.ps1"

Earthfile

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
VERSION 0.7
2+
IMPORT github.com/poshcode/tasks
3+
FROM mcr.microsoft.com/dotnet/sdk:8.0
4+
WORKDIR /work
5+
6+
ARG --global EARTHLY_GIT_ORIGIN_URL
7+
ARG --global EARTHLY_BUILD_SHA
8+
ARG --global EARTHLY_GIT_BRANCH
9+
# These are my common paths, used in my shared /Tasks repo
10+
ARG --global OUTPUT_ROOT=/Modules
11+
ARG --global TEST_ROOT=/Tests
12+
ARG --global TEMP_ROOT=/temp
13+
# These are my common build args, used in my shared /Tasks repo
14+
ARG --global MODULE_NAME=ErrorView
15+
ARG --global CONFIGURATION=Release
16+
17+
# This works on Linux, and speeds things up dramatically because I don't need my .git folder
18+
# But "LOCALLY" doesn't work on Windows (yet), and that's my main dev environment
19+
# version:
20+
# COPY --if-exists GitVersion.yml .
21+
# IF [ -f ./GitVersion.yml ]
22+
# ELSE
23+
# LOCALLY
24+
# COPY tasks+tasks/tasks/GitVersion.yml .
25+
# END
26+
# LOCALLY
27+
# RUN dotnet tool update GitVersion.Tool --version 5.12.0 --global && \
28+
# dotnet gitversion > version.json
29+
# SAVE ARTIFACT ./version.json
30+
31+
worker:
32+
# Dotnet tools and scripts installed by PSGet
33+
ENV PATH=$HOME/.dotnet/tools:$HOME/.local/share/powershell/Scripts:$PATH
34+
RUN mkdir /Tasks \
35+
&& git config --global user.email "[email protected]" \
36+
&& git config --global user.name "Earthly Build"
37+
# I'm using Invoke-Build tasks from this other repo which rarely changes
38+
COPY tasks+tasks/* /Tasks
39+
# Dealing with dependencies first allows docker to cache packages for us
40+
# So the dependency cach only re-builds when you add a new dependency
41+
COPY RequiredModules.psd1 .
42+
# COPY --if-exists *.csproj .
43+
RUN ["pwsh", "-File", "/Tasks/_Bootstrap.ps1", "-RequiredModulesPath", "RequiredModules.psd1"]
44+
45+
build:
46+
FROM +worker
47+
RUN mkdir $OUTPUT_ROOT $TEST_ROOT $TEMP_ROOT
48+
# On Linux we could use the version: task, we wouldn't need .git/ here and
49+
# we could avoid re-running this every time there was a commit
50+
# we could copying the source and Invoke-Build script to improve caching
51+
COPY --if-exists --dir .git/ source/ build.psd1 Build.build.ps1 GitVersion.yml nuget.config /work
52+
RUN ["pwsh", "-Command", "Invoke-Build", "-Task", "Build", "-File", "Build.build.ps1"]
53+
54+
# SAVE ARTIFACT [--keep-ts] [--keep-own] [--if-exists] [--force] <src> [<artifact-dest-path>] [AS LOCAL <local-path>]
55+
SAVE ARTIFACT $OUTPUT_ROOT/$MODULE_NAME AS LOCAL ./Modules/$MODULE_NAME
56+
57+
test:
58+
# If we run a target as a reference in FROM or COPY, it's outputs will not be produced
59+
# BUILD +build
60+
FROM +build
61+
# Copy the test files here, so we can avoid rebuilding when iterating on tests
62+
COPY --if-exists --dir Tests/ ScriptAnalyzerSettings.psd1 /work
63+
RUN ["pwsh", "-Command", "Invoke-Build", "-Task", "Test", "-File", "Build.build.ps1"]
64+
65+
# SAVE ARTIFACT [--keep-ts] [--keep-own] [--if-exists] [--force] <src> [<artifact-dest-path>] [AS LOCAL <local-path>]
66+
SAVE ARTIFACT $TEST_ROOT AS LOCAL ./Modules/$MODULE_NAME-TestResults
67+
68+
# pack:
69+
# BUILD +test # So that we get the module artifact from build too
70+
# FROM +test
71+
# RUN ["pwsh", "-Command", "Invoke-Build", "-Task", "Pack", "-File", "Build.build.ps1", "-Verbose"]
72+
# SAVE ARTIFACT $OUTPUT_ROOT/publish/*.nupkg AS LOCAL ./Modules/$MODULE_NAME-Packages/
73+
74+
push:
75+
FROM +build
76+
RUN --push --secret NUGET_API_KEY --secret PSGALLERY_API_KEY -- \
77+
pwsh -Command Invoke-Build -Task Push -File Build.build.ps1 -Verbose
78+
79+
all:
80+
# BUILD +build
81+
BUILD +test
82+
BUILD +push

RequiredModules.psd1

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# NOTE: follow nuget syntax for versions: https://docs.microsoft.com/en-us/nuget/reference/package-versioning#version-ranges-and-wildcards
2+
@{
3+
Configuration = "[1.5.0, 2.0)"
4+
Metadata = "[1.5.1, 2.0)"
5+
Pester = "[5.6.1, 6.0)"
6+
ModuleBuilder = "[3.0.0, 4.0)"
7+
PSScriptAnalyzer = "[1.21.0,2.0)"
8+
PowerShellGet = "2.0.4"
9+
InvokeBuild = "[5.10.4,6.0)"
10+
}

build.psd1

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@{
2-
ModuleManifest = ".\Source\ErrorView.psd1"
2+
ModuleManifest = "./source/ErrorView.psd1"
33
CopyPaths = 'ErrorView.format.ps1xml'
44
Prefix = 'prefix.ps1'
55
# The rest of the paths are relative to the manifest

source/ErrorView.psd1

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
@{
2-
Description = 'Enhances formatting ability for Errors'
2+
Description = 'Enhances formatting of Errors, and provides compatibility for older versions of PowerShell'
33
GUID = '5857f85c-8a0a-44e1-8da5-c8ff352167e0'
44
Author = 'Joel Bennett'
55
CompanyName = 'PoshCode'
66

77
ModuleToProcess = 'ErrorView.psm1'
8-
ModuleVersion = '0.0.2'
8+
ModuleVersion = '0.0.3'
99

1010
Copyright = '(c) Joel Bennett. All rights reserved.'
1111

@@ -30,7 +30,7 @@
3030
# IconUri = ''
3131

3232
# ReleaseNotes of this module
33-
ReleaseNotes = 'I wrote this module to enhace ErrorViews for Windows PowerShell (without waiting for PS7+)'
33+
ReleaseNotes = 'I wrote this module to enhance ErrorViews for PowerShell (without waiting for PS7+)'
3434

3535
} # End of PSData hashtable
3636

tests/Compatibility.Tests.ps1

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#requires -Module Pansies
2+
Describe "Format-Error produces the same results" {
3+
BeforeAll {
4+
$_cacheErrorView = $global:ErrorView
5+
try {
6+
Invoke-Expression '$R = "$([char]27)]8;;{0}`a{0}$([char]27)]8;;`a" -f $pwd, Split-Path -Leaf $pwd'
7+
} catch { }
8+
$TestError = $Error[0]
9+
10+
# Try to clear our ErrorView format data
11+
Remove-Item "$PSScriptRoot/../output/ErrorView/ErrorView.backup" -ErrorAction Ignore
12+
Rename-Item "$PSScriptRoot/../output/ErrorView/ErrorView.format.ps1xml" "ErrorView.backup"
13+
Set-Content "$PSScriptRoot/../output/ErrorView/ErrorView.format.ps1xml" (
14+
'<?xml version="1.0" encoding="utf-8" ?>' + "`n" +
15+
'<Configuration><ViewDefinitions></ViewDefinitions></Configuration>')
16+
Remove-Module ErrorView -ErrorAction SilentlyContinue
17+
Update-FormatData
18+
19+
20+
[System.Management.Automation.ErrorView]$global:ErrorView = 'ConciseView'
21+
$ExpectedConciseView = $TestError | Out-String
22+
Write-Host "$($PSStyle.Foreground.Red)ExpectedConciseView: " $PSStyle.Reset $ExpectedConciseView
23+
24+
[System.Management.Automation.ErrorView]$global:ErrorView = 'NormalView'
25+
$ExpectedNormalView = $TestError | Out-String
26+
Write-Host "$($PSStyle.Foreground.Red)ExpectedNormalView: " $PSStyle.Reset $ExpectedNormalView
27+
28+
[System.Management.Automation.ErrorView]$global:ErrorView = 'CategoryView'
29+
$ExpectedCategoryView = $TestError | Out-String
30+
Write-Host "$($PSStyle.Foreground.Red)ExpectedCategoryView: " $PSStyle.Reset $ExpectedCategoryView
31+
32+
[System.Management.Automation.ErrorView]$global:ErrorView = 'DetailedView'
33+
$ExpectedDetailedView = $TestError | Out-String
34+
# Write-Host "$($PSStyle.Foreground.Red)ExpectedDetailedView: " $PSStyle.Reset $ExpectedDetailedView
35+
36+
Remove-Item "$PSScriptRoot/../output/ErrorView/ErrorView.format.ps1xml" -ErrorAction Ignore
37+
Rename-Item "$PSScriptRoot/../output/ErrorView/ErrorView.backup" "ErrorView.format.ps1xml"
38+
Import-Module $PSScriptRoot/../output/ErrorView/ErrorView.psd1 -Force
39+
40+
}
41+
AfterAll {
42+
$global:ErrorView = $_cacheErrorView
43+
}
44+
45+
It 'As the default CategoryView' {
46+
$actual = $TestError | Format-Error -View CategoryView | Out-String
47+
$actual | Should -Be $ExpectedCategoryView
48+
}
49+
It 'As the default ConciseView' {
50+
$actual = $TestError | Format-Error -View ConciseView | Out-String
51+
$actual | Should -Be $ExpectedConciseView
52+
}
53+
It 'As the default NormalView' {
54+
$actual = $TestError | Format-Error -View NormalView | Out-String
55+
$actual | Should -Be $ExpectedNormalView
56+
}
57+
It 'As the default DetailedView' {
58+
$actual = $TestError | Format-Error -View DetailedView | Out-String
59+
$actual | Should -Be $ExpectedDetailedView
60+
}
61+
62+
}

tests/WrapString.Tests.ps1

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#requires -Module Pansies
2+
Describe WrapString {
3+
BeforeAll {
4+
$CommandUnderTest = & (Get-Module ErrorView) { Get-Command WrapString }
5+
}
6+
7+
It "Word-wraps text to keep it under a specified width" {
8+
"The quick brown fox jumped over the lazy dog and then ran away with the unicorn." |
9+
& $CommandUnderTest -Width 20 <# -Verbose #> |
10+
Should -Be "The quick brown fox", "jumped over the lazy", "dog and then ran", "away with the", "unicorn."
11+
}
12+
It "Does not count ANSI escape sequences as characters" {
13+
"The quick brown ${fg:red}fox${fg:clear} jumped over the lazy ${fg:green}dog and then ran away with the unicorn.${fg:clear}" |
14+
& $CommandUnderTest -Width 20 <# -Verbose #> |
15+
Should -Be "The quick brown ${fg:red}fox${fg:clear}", "jumped over the lazy", "${fg:green}dog and then ran", "away with the", "unicorn.${fg:clear}"
16+
}
17+
}

0 commit comments

Comments
 (0)