Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -579,3 +579,43 @@ jobs:
# storage quota, so there is no storage argument for deleting them. If disk hygiene
# ever matters, prune Actions *artifacts* — never releases that a published package
# points at. Run-Tests section 206 asserts this workflow contains no release deletion.

# ─────────────────────────────────────────────────────────────────────────
# Antivirus false-positive submission reminder.
#
# Microsoft clears false positives PER HASH. A clearance covers exactly the
# binary it was granted for, so every release starts over with the
# machine-learning models regardless of how small the change was. v1.122.4
# was cleared on 2026-08-12 ("the detection has been removed") — that
# clearance does nothing for the next build.
#
# This writes the new hash and the submission link into the run summary so
# the obligation shows up exactly where the release is already being
# validated, rather than depending on someone remembering.
# ─────────────────────────────────────────────────────────────────────────
- name: Remind — submit this build to Microsoft
if: steps.vercheck.outputs.bumped == 'true' && steps.releasecheck.outputs.exists == 'false'
shell: pwsh
run: |
$ver = '${{ steps.vercheck.outputs.version }}'
$sha = (Get-FileHash 'builds\RackStack.exe' -Algorithm SHA256).Hash.ToLower()
$lines = @(
"## Submit v$ver to Microsoft"
""
"False-positive clearances are **per hash**, so this build is not covered by any"
"previous determination. Submit it, including for patch releases."
""
"| | |"
"|---|---|"
"| Version | ``$ver`` |"
"| SHA-256 | ``$sha`` |"
""
"1. https://www.microsoft.com/en-us/wdsi/filesubmission -> **Software developer**"
"2. Priority **Medium** — the default is Low, which states it *may never be processed by an analyst*"
"3. Upload the release asset verified against ``release-hashes.txt``, never a local ``builds/`` copy"
"4. Cite the prior clearance to speed review: submission ``665636df-07e9-4437-9f44-adb3030413ef``"
""
"Typical turnaround: about two days."
)
$lines -join "`n" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append -Encoding utf8
Write-Host "Submission reminder written to the run summary (SHA-256 $sha)."
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<a href="https://www.bestpractices.dev/projects/12921"><img alt="OpenSSF Best Practices" src="https://www.bestpractices.dev/projects/12921/badge"></a>
<a href="https://codecov.io/gh/TheAbider/RackStack"><img alt="codecov" src="https://codecov.io/gh/TheAbider/RackStack/branch/master/graph/badge.svg"></a>
<img alt="PSScriptAnalyzer 0 errors" src="https://img.shields.io/badge/PSScriptAnalyzer-0%20errors-brightgreen">
<img alt="5485 structural tests" src="https://img.shields.io/badge/structural%20tests-5485-brightgreen">
<img alt="5493 structural tests" src="https://img.shields.io/badge/structural%20tests-5493-brightgreen">
<img alt="Pester 312 tests" src="https://img.shields.io/badge/Pester-312%20tests-brightgreen">
<img alt="SLSA Level 3" src="https://slsa.dev/images/gh-badge-level3.svg">
</p>
Expand Down
33 changes: 32 additions & 1 deletion Tests/Run-Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -10774,7 +10774,13 @@ Write-SectionHeader "SECTION 209: BUILD METADATA INTEGRITY"
try {
$ciPath209 = Join-Path $script:ModuleRoot '.github\workflows\ci.yml'
if (Test-Path -LiteralPath $ciPath209) {
$ci209 = Get-Content -LiteralPath $ciPath209 -Raw
# -Encoding UTF8 is load-bearing. ci.yml has no BOM, and Windows PowerShell
# 5.1 decodes BOM-less files as ANSI, so its em-dashes and box-drawing
# characters arrive as mojibake while pwsh 7 reads them correctly. The suite
# is run BOTH ways — directly under pwsh, and under powershell.exe by
# local/Validate-Release.ps1 — so without this, assertions that touch any
# non-ASCII text in this file pass in one host and fail in the other.
$ci209 = Get-Content -LiteralPath $ciPath209 -Raw -Encoding UTF8

# Compiler must be pinned to an exact version, never floating.
Write-TestResult "Build: ps2exe is pinned to an explicit version" `
Expand Down Expand Up @@ -10804,6 +10810,31 @@ try {
Write-TestResult "Build: EXE CompanyName matches RackStack.psd1 ('$psdCompany209')" `
($psdCompany209 -and $exeCompany209 -and $psdCompany209 -eq $exeCompany209) `
"psd1='$psdCompany209' exe='$exeCompany209'"

# Antivirus FP clearances are granted per hash, so every release — patches
# included — has to be resubmitted. Depending on memory for that failed
# once already; the release job prints the obligation, with the new hash,
# into the run summary that gets read while validating the release.
# Anchor on ASCII only. The step name contains an em-dash; matching it would
# re-introduce the host-dependent decoding problem above even with -Encoding
# set, and 'name: Remind' is already unique in this workflow.
$reminder209 = [regex]::Match($ci209, '(?s)- name: Remind.*?(?=\r?\n\s{6}- name:|\r?\n\s{0,4}\S|\z)')
Write-TestResult "Build: release job carries the Microsoft submission reminder" `
$reminder209.Success "no reminder step found in ci.yml release job"
$rBody209 = $reminder209.Value
Write-TestResult "Build: reminder links the WDSI submission portal" `
($reminder209.Success -and $rBody209 -match 'wdsi/filesubmission')
# Single-quoted so the backslash in builds\RackStack.exe stays literal — the
# first cut of this used a double-quoted pattern whose over-escaped \\\\
# required two backslashes and never matched the one that is actually there.
Write-TestResult "Build: reminder publishes the new SHA-256" `
($reminder209.Success -and $rBody209 -match 'Get-FileHash' -and `
$rBody209 -match 'SHA256' -and $rBody209 -match 'RackStack\.exe')
Write-TestResult "Build: reminder writes to the run summary" `
($reminder209.Success -and $rBody209 -match 'GITHUB_STEP_SUMMARY')
# Only meaningful on an actual release — must carry the same gate as the build steps.
Write-TestResult "Build: reminder is gated on a version bump" `
($reminder209.Success -and $rBody209 -match "steps\.vercheck\.outputs\.bumped == 'true'")
}
else {
Write-TestResult "Build: metadata integrity" -Skipped -Message "no .github/workflows in this layout"
Expand Down
16 changes: 16 additions & 0 deletions dist/winget/1.122.4/TheAbider.RackStack.installer.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.6.0.schema.json
PackageIdentifier: TheAbider.RackStack
PackageVersion: 1.122.4
Platform:
- Windows.Desktop
MinimumOSVersion: 6.1.0.0
InstallerType: portable
Commands:
- rackstack
ReleaseDate: 2026-08-10
Installers:
- Architecture: x64
InstallerUrl: https://github.com/TheAbider/RackStack/releases/download/v1.122.4/RackStack.exe
InstallerSha256: 658EDCC53D5139CE0A0F4DF167FA3F3CB293111DFF851BE300D8E4B788323034
ManifestType: installer
ManifestVersion: 1.6.0
33 changes: 33 additions & 0 deletions dist/winget/1.122.4/TheAbider.RackStack.locale.en-US.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.6.0.schema.json
PackageIdentifier: TheAbider.RackStack
PackageVersion: 1.122.4
PackageLocale: en-US
Publisher: TheAbider
PublisherUrl: https://github.com/TheAbider
PublisherSupportUrl: https://github.com/TheAbider/RackStack/issues
PackageName: RackStack
PackageUrl: https://github.com/TheAbider/RackStack
License: MIT
LicenseUrl: https://github.com/TheAbider/RackStack/blob/master/LICENSE
Copyright: Copyright (c) 2026 TheAbider
ShortDescription: PowerShell automation toolkit for configuring Windows Server hosts.
Description: |-
RackStack is a menu-driven PowerShell tool that automates everything between
"Windows is installed" and "server is in production." It provides 201 CLI
actions and 60+ interactive menus covering networking, Hyper-V, SAN/iSCSI,
clustering, VM deployment, cloud onboarding, and batch automation, all with
undo, transaction rollback, and audit logging. Built for MSPs, sysadmins,
and infrastructure teams who build Windows Servers repeatedly.
Moniker: rackstack
Tags:
- windows-server
- hyper-v
- iscsi
- clustering
- powershell
- sysadmin
- automation
- msp
ReleaseNotesUrl: https://github.com/TheAbider/RackStack/releases/tag/v1.122.4
ManifestType: defaultLocale
ManifestVersion: 1.6.0
6 changes: 6 additions & 0 deletions dist/winget/1.122.4/TheAbider.RackStack.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.6.0.schema.json
PackageIdentifier: TheAbider.RackStack
PackageVersion: 1.122.4
DefaultLocale: en-US
ManifestType: version
ManifestVersion: 1.6.0