Skip to content

Commit 2e6d52d

Browse files
committed
Update devcontainer to Ubuntu 24.04 and streamline development setup
- Upgrade base image from Ubuntu 22.04 to 24.04 - Simplify VS Code extensions to essential PowerShell development tools - Add conditional .NET build logic to skip when no C# files present - Enhance build script with task-based commands (Build, Test, Analyze, Clean, Docs) - Update test configurations and improve development workflow
1 parent 107b78a commit 2e6d52d

9 files changed

+230
-55
lines changed

.devcontainer/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Multi-stage Dockerfile for OSDCloudCustomBuilder Development
2-
FROM mcr.microsoft.com/devcontainers/base:ubuntu-22.04 AS base
2+
FROM mcr.microsoft.com/devcontainers/base:dev-ubuntu-24.04 AS base
33

44
# Set environment variables
55
ENV DEBIAN_FRONTEND=noninteractive

.devcontainer/devcontainer.json

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
{
2-
"name": "OSDCloudCustomBuilder DevContainer",
2+
// See https://aka.ms/vscode-remote/devcontainer.json for format details.
3+
"name": "OSDCloudCustomBuilder (.NET Core 8.0, including pwsh)",
34
"build": {
45
"dockerfile": "Dockerfile",
56
"context": "."
67
},
8+
// Configure tool-specific properties.
79
"features": {
810
"ghcr.io/devcontainers/features/dotnet:2": {
911
"version": "8.0",
@@ -60,33 +62,22 @@
6062
}
6163
]
6264
},
65+
// Streamlined extensions based on PowerShell repository best practices
6366
"extensions": [
6467
"ms-vscode.powershell",
6568
"ms-dotnettools.csharp",
66-
"ms-dotnettools.vscode-dotnet-runtime",
67-
"formulahendry.dotnet-test-explorer",
68-
"jmrog.vscode-nuget-package-manager",
69-
"ironmansoftware.powershell-pro-tools",
70-
"vscode-icons-team.vscode-icons",
69+
"davidanson.vscode-markdownlint",
7170
"eamodio.gitlens",
72-
"streetsidesoftware.code-spell-checker",
73-
"github.copilot",
7471
"github.vscode-pull-request-github",
75-
"redhat.vscode-yaml",
76-
"ms-vscode.test-adapter-converter",
77-
"hbenl.vscode-test-explorer",
78-
"ryanluker.vscode-coverage-gutters",
79-
"humao.rest-client",
80-
"davidanson.vscode-markdownlint",
81-
"yzhang.markdown-all-in-one",
82-
"ms-vscode.vscode-json",
83-
"tamasfe.even-better-toml",
84-
"bradlc.vscode-tailwindcss"
72+
"streetsidesoftware.code-spell-checker"
8573
]
8674
}
8775
},
76+
// Use the existing postCreate script
8877
"postCreateCommand": "bash .devcontainer/postCreate.sh",
89-
"postStartCommand": "pwsh -NoProfile -Command 'Write-Host \"🚀 OSDCloudCustomBuilder DevContainer Ready!\"; Get-Module -ListAvailable | Where-Object {$_.Name -match \"Pester|PSScriptAnalyzer|InvokeBuild\"} | Format-Table Name, Version'",
78+
// Simplified startup message
79+
"postStartCommand": "pwsh -NoProfile -Command 'Write-Host \"🚀 OSDCloudCustomBuilder DevContainer Ready!\"'",
80+
// Essential mounts only
9081
"mounts": [
9182
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind",
9283
"source=${localWorkspaceFolder}/.devcontainer/cache,target=/home/vscode/.cache,type=bind,consistency=cached"

.devcontainer/postCreate.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,12 @@ function Invoke-FullTest {
142142
function Invoke-FullBuild {
143143
Write-Host \"🔨 Building OSDCloudCustomBuilder...\" -ForegroundColor Yellow
144144
145-
# .NET build
146-
if (Test-Path './OSDCloudCustomBuilder.csproj') {
145+
# .NET build - only if .cs source files exist
146+
if ((Test-Path './OSDCloudCustomBuilder.csproj') -and (Get-ChildItem -Path . -Filter "*.cs" -Recurse)) {
147147
Write-Host \"\\n📦 Building .NET project...\"
148148
dotnet build --configuration Release
149+
} else {
150+
Write-Host \"\\n📦 Skipping .NET build (no .cs files found)...\"
149151
}
150152
151153
# PowerShell module build

build.ps1

Lines changed: 123 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,130 @@ $ErrorActionPreference = 'Stop'
44
Import-Module "$PSScriptRoot\OSDCloudCustomBuilder.psd1" -Force
55
Write-Host "Building OSDCloudCustomBuilder module..."
66

7-
# Perform validations or build packaging
8-
$PesterConfig = @{
9-
Run = @{
10-
Path = './tests'
7+
# Process command-line arguments
8+
param(
9+
[Parameter(Position = 0)]
10+
[ValidateSet('Build', 'Test', 'Analyze', 'Clean', 'Docs')]
11+
[string]$Task = 'Build'
12+
)
13+
14+
# Determine what to do based on the task
15+
switch ($Task) {
16+
'Test' {
17+
Write-Host "Running tests..." -ForegroundColor Cyan
18+
19+
# Create test helper directories if they don't exist
20+
$testHelpersPath = Join-Path $PSScriptRoot 'tests\TestHelpers'
21+
if (-not (Test-Path $testHelpersPath)) {
22+
New-Item -Path $testHelpersPath -ItemType Directory -Force | Out-Null
23+
}
24+
25+
# Configure Pester
26+
$PesterConfig = @{
27+
Run = @{
28+
Path = './tests'
29+
ExcludePath = './tests/TestHelpers' # Exclude the helper modules from being run as tests
30+
}
31+
CodeCoverage = @{
32+
Enabled = $true
33+
Path = @('./Public/*.ps1', './Private/*.ps1', './Shared/*.ps1')
34+
OutputPath = './coverage.xml'
35+
OutputFormat = 'JaCoCo'
36+
}
37+
Output = @{
38+
Verbosity = 'Detailed'
39+
}
40+
TestResult = @{
41+
Enabled = $true
42+
OutputPath = './testResults.xml'
43+
OutputFormat = 'NUnitXml'
44+
}
45+
}
46+
47+
# Run Pester tests
48+
Invoke-Pester -Configuration $PesterConfig
1149
}
12-
CodeCoverage = @{
13-
Enabled = $true
14-
Path = @('./Public/*.ps1', './Private/*.ps1', './Shared/*.ps1')
50+
51+
'Analyze' {
52+
Write-Host "Analyzing code quality..." -ForegroundColor Cyan
53+
54+
# Ensure PSScriptAnalyzer is installed
55+
if (-not (Get-Module -ListAvailable -Name PSScriptAnalyzer)) {
56+
Write-Host "Installing PSScriptAnalyzer..." -ForegroundColor Yellow
57+
Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser
58+
}
59+
60+
# Run PSScriptAnalyzer
61+
Invoke-ScriptAnalyzer -Path $PSScriptRoot -Recurse -Settings (Join-Path $PSScriptRoot 'PSScriptAnalyzer.settings.psd1')
1562
}
16-
Output = @{
17-
Verbosity = 'Detailed'
63+
64+
'Clean' {
65+
Write-Host "Cleaning build artifacts..." -ForegroundColor Cyan
66+
67+
# List of artifacts to remove
68+
$artifactPaths = @(
69+
'./output',
70+
'./coverage.xml',
71+
'./testResults.xml',
72+
'./artifacts'
73+
)
74+
75+
# Remove each artifact
76+
foreach ($path in $artifactPaths) {
77+
$fullPath = Join-Path $PSScriptRoot $path
78+
if (Test-Path $fullPath) {
79+
Remove-Item -Path $fullPath -Recurse -Force
80+
Write-Host "Removed: $path" -ForegroundColor Gray
81+
}
82+
}
1883
}
19-
}
2084

21-
Invoke-Pester -Configuration $PesterConfig
85+
'Docs' {
86+
Write-Host "Generating documentation..." -ForegroundColor Cyan
87+
88+
# Check for PlatyPS module
89+
if (-not (Get-Module -ListAvailable -Name PlatyPS)) {
90+
Write-Host "Installing PlatyPS..." -ForegroundColor Yellow
91+
Install-Module -Name PlatyPS -Force -Scope CurrentUser
92+
}
93+
94+
# Generate documentation
95+
$docsPath = Join-Path $PSScriptRoot 'docs'
96+
if (-not (Test-Path $docsPath)) {
97+
New-Item -Path $docsPath -ItemType Directory -Force | Out-Null
98+
}
99+
100+
# Generate documentation for each public function
101+
$publicFunctions = Get-ChildItem -Path (Join-Path $PSScriptRoot 'Public') -Filter "*.ps1"
102+
foreach ($function in $publicFunctions) {
103+
$functionName = $function.BaseName
104+
$docPath = Join-Path $docsPath "$functionName.md"
105+
106+
# Only generate if it doesn't exist or is older than the function file
107+
if (-not (Test-Path $docPath) -or
108+
(Get-Item $docPath).LastWriteTime -lt $function.LastWriteTime) {
109+
Write-Host "Generating documentation for $functionName..." -ForegroundColor Gray
110+
$null = New-MarkdownHelp -Command $functionName -OutputFolder $docsPath -Force
111+
}
112+
}
113+
}
114+
115+
default {
116+
# 'Build'
117+
Write-Host "Building module..." -ForegroundColor Cyan
118+
119+
# Run versioning from build.settings.ps1
120+
. (Join-Path $PSScriptRoot 'build.settings.ps1')
121+
122+
# Copy any required files to output if needed
123+
$outputPath = Join-Path $PSScriptRoot 'output'
124+
if (-not (Test-Path $outputPath)) {
125+
New-Item -Path $outputPath -ItemType Directory -Force | Out-Null
126+
}
127+
128+
# You can add more build steps here
129+
130+
# Run tests as part of the build
131+
& $PSCommandPath -Task Test
132+
}
133+
}

build.settings.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# build.settings.ps1
22
$ModuleName = "OSDCloudCustomBuilder"
3-
$SourcePath = "$PSScriptRoot\src"
3+
$SourcePath = $PSScriptRoot # Now pointing to the root where the module files are
44
$OutputPath = "$PSScriptRoot\output"
55

66
# Auto-Versioning Configuration
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
cb58beff20d1a807fa2067d65e2b7ad502dbeb5d4e4a945a9ed8dba699ea59bd
1+
100eae837e67efa1b7b224521fd71878cade75482a12c69e30e287dbdd1e446b
Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,42 @@
1+
# MSBuild EditorConfig for OSDCloudCustomBuilder
2+
# This file is generated automatically by MSBuild and contains build properties
3+
# used by the editor and analysis tools
4+
15
is_global = true
6+
7+
# Target Framework Configuration
28
build_property.TargetFramework = net8.0
3-
build_property.TargetFramework = net8.0
4-
build_property.TargetPlatformMinVersion =
5-
build_property.TargetPlatformMinVersion =
6-
build_property.UsingMicrosoftNETSdkWeb =
7-
build_property.UsingMicrosoftNETSdkWeb =
8-
build_property.ProjectTypeGuids =
9-
build_property.ProjectTypeGuids =
10-
build_property.InvariantGlobalization =
11-
build_property.InvariantGlobalization =
12-
build_property.PlatformNeutralAssembly =
13-
build_property.PlatformNeutralAssembly =
14-
build_property.EnforceExtendedAnalyzerRules =
15-
build_property.EnforceExtendedAnalyzerRules =
16-
build_property._SupportedPlatformList = Linux,macOS,Windows
9+
build_property.TargetFrameworkIdentifier = .NETCoreApp
10+
build_property.TargetFrameworkVersion = 8.0
11+
12+
# Platform Configuration
13+
build_property.TargetPlatformMinVersion = 7.0
1714
build_property._SupportedPlatformList = Linux,macOS,Windows
15+
16+
# SDK Configuration
17+
build_property.UsingMicrosoftNETSdkWeb = false
18+
build_property.EnableDefaultCompileItems = true
19+
build_property.EnableDefaultItems = true
20+
21+
# Project Configuration
22+
build_property.ProjectTypeGuids =
1823
build_property.RootNamespace = OSDCloudCustomBuilder
19-
build_property.ProjectDir = H:\OSDCloudCustomBuilder\
20-
build_property.EnableComHosting =
21-
build_property.EnableGeneratedComInterfaceComImportInterop =
24+
build_property.ProjectDir = $(MSBuildProjectDirectory)\
25+
build_property.EnableComHosting = false
26+
27+
# Globalization Settings
28+
build_property.InvariantGlobalization = false
29+
build_property.NeutralLanguage = en-US
30+
31+
# Assembly Configuration
32+
build_property.PlatformNeutralAssembly = false
33+
build_property.PublishSingleFile = false
34+
35+
# Analysis Configuration
36+
build_property.EnforceExtendedAnalyzerRules = true
37+
build_property.AnalysisLevel = latest
38+
build_property.EnableNETAnalyzers = true
39+
40+
# COM Interop Configuration
41+
build_property.EnableComHosting = false
42+
build_property.EnableGeneratedComInterfaceComImportInterop = false

tests/All-PublicFunctions.Tests.ps1

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,31 @@
11
# Import the module before testing
22
Import-Module (Join-Path $PSScriptRoot '..\OSDCloudCustomBuilder.psd1') -Force
33

4+
# Import test helper modules
5+
Import-Module (Join-Path $PSScriptRoot 'TestHelpers\Admin-MockHelper.psm1') -Force
6+
Import-Module (Join-Path $PSScriptRoot 'TestHelpers\Interactive-MockHelper.psm1') -Force
7+
8+
BeforeAll {
9+
# Set up admin context mock
10+
Set-TestAdminContext -IsAdmin $true
11+
12+
# Initialize the logger
13+
Initialize-TestLogger
14+
}
15+
416
Describe "Add-OSDCloudCustomDriver Tests" {
17+
BeforeEach {
18+
# Set up mocked parameters
19+
Set-MockedParameter -CommandName 'Add-OSDCloudCustomDriver' -Parameters @{
20+
DriverPath = 'C:\TestDrivers'
21+
}
22+
23+
# Mock file system
24+
Mock-FileSystem -MockedDirectories @('C:\TestDrivers')
25+
}
26+
527
It "Should run Add-OSDCloudCustomDriver without error" {
6-
{ Add-OSDCloudCustomDriver } | Should -Not -Throw
28+
{ Add-OSDCloudCustomDriver -DriverPath 'C:\TestDrivers' } | Should -Not -Throw
729
}
830

931
It "Should throw on invalid input (if applicable)" {

tests/New-OSDCloudCustomMedia.Tests.ps1

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,41 @@
11
# Import the module before testing
22
Import-Module (Join-Path $PSScriptRoot '..\OSDCloudCustomBuilder.psd1') -Force
33

4+
# Import test helper modules
5+
Import-Module (Join-Path $PSScriptRoot 'TestHelpers\Admin-MockHelper.psm1') -Force
6+
Import-Module (Join-Path $PSScriptRoot 'TestHelpers\Interactive-MockHelper.psm1') -Force
7+
8+
BeforeAll {
9+
# Set up admin context mock
10+
Set-TestAdminContext -IsAdmin $true
11+
12+
# Initialize the logger
13+
Initialize-TestLogger
14+
}
15+
416
Describe "New-OSDCloudCustomMedia Tests" {
517
BeforeEach {
618
$TestPath = "$TestDrive\Media"
7-
New-Item -Path $TestPath -ItemType Directory | Out-Null
19+
20+
# Mock directory creation instead of actually creating it
21+
Mock -CommandName New-Item -MockWith {
22+
return [PSCustomObject]@{
23+
FullName = $TestPath
24+
}
25+
}
26+
27+
# Set up mocked parameters
28+
Set-MockedParameter -CommandName 'New-OSDCloudCustomMedia' -Parameters @{
29+
Name = 'TestMedia'
30+
Path = $TestPath
31+
}
32+
33+
# Mock test for admin privileges
34+
Mock -CommandName Test-IsAdmin -MockWith { return $true }
835
}
936

1037
It "Should create media in valid path" {
11-
{ New-OSDCloudCustomMedia -Path $TestPath } | Should -Not -Throw
38+
{ New-OSDCloudCustomMedia -Name 'TestMedia' -Path $TestPath } | Should -Not -Throw
1239
}
1340

1441
It "Should fail on invalid path" {

0 commit comments

Comments
 (0)