Skip to content

Commit 10132a4

Browse files
committed
Fix CI/CD workflow secret handling and update .gitignore
- Fixed POWERSHELL_GALLERY_API_KEY secret access in GitHub Actions workflow - Moved secret to env section for better security practices - Updated .gitignore to allow GitHub workflow files (*.yml) to be tracked - Added comprehensive AD-Audit module files and documentation
1 parent 79dedee commit 10132a4

33 files changed

Lines changed: 15055 additions & 416 deletions

.github/workflows/ci-cd.yml

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
name: CI/CD Pipeline
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main ]
8+
release:
9+
types: [ published ]
10+
11+
jobs:
12+
test:
13+
runs-on: windows-latest
14+
strategy:
15+
matrix:
16+
pwsh-version: ['7.4', '5.1']
17+
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v4
21+
22+
- name: Setup PowerShell Core
23+
if: matrix.pwsh-version != '5.1'
24+
shell: pwsh
25+
run: |
26+
Write-Host "Using PowerShell Core ${{ matrix.pwsh-version }}"
27+
$PSVersionTable
28+
29+
- name: Setup Windows PowerShell
30+
if: matrix.pwsh-version == '5.1'
31+
shell: powershell
32+
run: |
33+
Write-Host "Using Windows PowerShell ${{ matrix.pwsh-version }}"
34+
$PSVersionTable
35+
36+
- name: Install Pester
37+
shell: pwsh
38+
run: |
39+
Install-Module -Name Pester -Force -SkipPublisherCheck
40+
Install-Module -Name PSScriptAnalyzer -Force -SkipPublisherCheck
41+
42+
- name: Run PSScriptAnalyzer
43+
shell: pwsh
44+
run: |
45+
$results = Invoke-ScriptAnalyzer -Path . -Recurse -Severity @('Error', 'Warning')
46+
if ($results) {
47+
Write-Host "ScriptAnalyzer found $($results.Count) issues:"
48+
$results | ForEach-Object { Write-Host " $($_.Severity): $($_.Message) at $($_.ScriptPath):$($_.Line)" }
49+
exit 1
50+
} else {
51+
Write-Host "No ScriptAnalyzer issues found"
52+
}
53+
54+
- name: Run Pester Tests
55+
shell: pwsh
56+
run: |
57+
$testResults = Invoke-Pester -Path .\Tests\ -OutputFile TestResults.xml -OutputFormat NUnitXml -PassThru
58+
if ($testResults.FailedCount -gt 0) {
59+
Write-Host "Pester tests failed: $($testResults.FailedCount) failures"
60+
exit 1
61+
} else {
62+
Write-Host "All Pester tests passed: $($testResults.PassedCount) tests"
63+
}
64+
65+
- name: Upload Test Results
66+
uses: actions/upload-artifact@v3
67+
if: always()
68+
with:
69+
name: test-results-${{ matrix.pwsh-version }}
70+
path: TestResults.xml
71+
72+
- name: Test Module Import
73+
shell: pwsh
74+
run: |
75+
try {
76+
Import-Module .\AD-Audit.psd1 -Force
77+
Write-Host "Module imported successfully"
78+
79+
# Test exported functions
80+
$exportedFunctions = (Get-Module AD-Audit).ExportedFunctions.Keys
81+
Write-Host "Exported functions: $($exportedFunctions.Count)"
82+
$exportedFunctions | ForEach-Object { Write-Host " - $_" }
83+
84+
} catch {
85+
Write-Host "Module import failed: $_"
86+
exit 1
87+
}
88+
89+
build:
90+
runs-on: windows-latest
91+
needs: test
92+
93+
steps:
94+
- name: Checkout code
95+
uses: actions/checkout@v4
96+
97+
- name: Create Release Package
98+
shell: pwsh
99+
run: |
100+
# Create release directory
101+
$releaseDir = ".\Release"
102+
New-Item -Path $releaseDir -ItemType Directory -Force
103+
104+
# Copy module files
105+
Copy-Item -Path ".\AD-Audit.psd1" -Destination $releaseDir
106+
Copy-Item -Path ".\Modules" -Destination $releaseDir -Recurse
107+
Copy-Item -Path ".\Libraries" -Destination $releaseDir -Recurse
108+
Copy-Item -Path ".\Utilities" -Destination $releaseDir -Recurse
109+
Copy-Item -Path ".\docs" -Destination $releaseDir -Recurse
110+
Copy-Item -Path ".\Tests" -Destination $releaseDir -Recurse
111+
Copy-Item -Path ".\README.md" -Destination $releaseDir
112+
Copy-Item -Path ".\LICENSE" -Destination $releaseDir
113+
Copy-Item -Path ".\CHANGELOG.md" -Destination $releaseDir
114+
115+
# Create ZIP package
116+
Compress-Archive -Path "$releaseDir\*" -DestinationPath "AD-Audit-v$env:GITHUB_REF_NAME.zip" -Force
117+
118+
Write-Host "Release package created: AD-Audit-v$env:GITHUB_REF_NAME.zip"
119+
120+
- name: Upload Release Package
121+
uses: actions/upload-artifact@v3
122+
with:
123+
name: AD-Audit-Release
124+
path: AD-Audit-v${{ github.ref_name }}.zip
125+
126+
publish-gallery:
127+
runs-on: windows-latest
128+
needs: [test, build]
129+
if: github.event_name == 'release'
130+
131+
steps:
132+
- name: Checkout code
133+
uses: actions/checkout@v4
134+
135+
- name: Install PowerShellGet
136+
shell: pwsh
137+
run: |
138+
Install-Module -Name PowerShellGet -Force -SkipPublisherCheck
139+
140+
- name: Publish to PowerShell Gallery
141+
shell: pwsh
142+
env:
143+
POWERSHELL_GALLERY_API_KEY: ${{ secrets.POWERSHELL_GALLERY_API_KEY }}
144+
run: |
145+
if (-not $env:POWERSHELL_GALLERY_API_KEY) {
146+
Write-Host "Error: POWERSHELL_GALLERY_API_KEY secret is not configured"
147+
Write-Host "Please add the secret in GitHub repository settings under Settings > Secrets and variables > Actions"
148+
exit 1
149+
}
150+
151+
try {
152+
Publish-Module -Path . -NuGetApiKey $env:POWERSHELL_GALLERY_API_KEY -Force
153+
Write-Host "Module published to PowerShell Gallery successfully"
154+
} catch {
155+
Write-Host "Failed to publish module: $_"
156+
exit 1
157+
}
158+
159+
security-scan:
160+
runs-on: windows-latest
161+
needs: test
162+
163+
steps:
164+
- name: Checkout code
165+
uses: actions/checkout@v4
166+
167+
- name: Run Security Scan
168+
shell: pwsh
169+
run: |
170+
# Check for sensitive information
171+
$sensitivePatterns = @(
172+
'password\s*=\s*["''"][^"''"\\s]+["''"\\s]',
173+
'pwd\s*=\s*["''"][^"''"\\s]+["''"\\s]',
174+
'pass\s*=\s*["''"][^"''"\\s]+["''"\\s]',
175+
'secret\s*=\s*["''"][^"''"\\s]+["''"\\s]',
176+
'key\s*=\s*["''"][^"''"\\s]+["''"\\s]',
177+
'token\s*=\s*["''"][^"''"\\s]+["''"\\s]'
178+
)
179+
180+
$issues = @()
181+
Get-ChildItem -Path . -Recurse -Include "*.ps1", "*.psd1", "*.psm1" | ForEach-Object {
182+
$content = Get-Content $_.FullName -Raw
183+
foreach ($pattern in $sensitivePatterns) {
184+
if ($content -match $pattern) {
185+
$issues += "Potential sensitive information in $($_.FullName): $($matches[0])"
186+
}
187+
}
188+
}
189+
190+
if ($issues.Count -gt 0) {
191+
Write-Host "Security scan found potential issues:"
192+
$issues | ForEach-Object { Write-Host " $_" }
193+
exit 1
194+
} else {
195+
Write-Host "Security scan passed - no sensitive information detected"
196+
}
197+
198+
documentation:
199+
runs-on: windows-latest
200+
needs: test
201+
202+
steps:
203+
- name: Checkout code
204+
uses: actions/checkout@v4
205+
206+
- name: Validate Documentation
207+
shell: pwsh
208+
run: |
209+
# Check for required documentation files
210+
$requiredDocs = @(
211+
'README.md',
212+
'LICENSE',
213+
'CHANGELOG.md',
214+
'CONTRIBUTING.md',
215+
'docs\USER_GUIDE.md',
216+
'docs\INSTALLATION.md',
217+
'docs\TROUBLESHOOTING.md'
218+
)
219+
220+
$missingDocs = @()
221+
foreach ($doc in $requiredDocs) {
222+
if (-not (Test-Path $doc)) {
223+
$missingDocs += $doc
224+
}
225+
}
226+
227+
if ($missingDocs.Count -gt 0) {
228+
Write-Host "Missing required documentation files:"
229+
$missingDocs | ForEach-Object { Write-Host " $_" }
230+
exit 1
231+
} else {
232+
Write-Host "All required documentation files present"
233+
}
234+
235+
# Validate README.md has required sections
236+
$readmeContent = Get-Content 'README.md' -Raw
237+
$requiredSections = @(
238+
'## 🚀 Features',
239+
'## 📋 Prerequisites',
240+
'## 🚀 Installation',
241+
'## 📖 Quick Start',
242+
'## 📊 Microsoft Compliance',
243+
'## 📚 Documentation'
244+
)
245+
246+
$missingSections = @()
247+
foreach ($section in $requiredSections) {
248+
if ($readmeContent -notmatch [regex]::Escape($section)) {
249+
$missingSections += $section
250+
}
251+
}
252+
253+
if ($missingSections.Count -gt 0) {
254+
Write-Host "Missing required README sections:"
255+
$missingSections | ForEach-Object { Write-Host " $_" }
256+
exit 1
257+
} else {
258+
Write-Host "All required README sections present"
259+
}

0 commit comments

Comments
 (0)