unsloth/.github/scripts/assert-nobuild.ps1
danielhanchen f09a1e71a9 Tighten the clean-machine CI comments
Comments only, no assertion logic, pins or leg definitions touched.

Reflowed every rationale block to denser wording and removed the
duplication that had built up across repeated steps: the desktop
workflow repeated the fork-PR skip, the desktop-v* tag resolution and
the restore-runner note once per platform, and the installer workflow
repeated its path-filter rationale in both the pull_request and push
blocks. Those now point at the first copy.

Every WHY is kept: why the masked legs avoid install.sh --local, what
UNSLOTH_CI_SOURCE_OVERLAY is for, why `absent` tests "must not work"
rather than command -v, why the .venv_t5_* sidecars are in the macho
scan scope, why the signature check is main-executables-only, why each
nobuild allowlist entry is a pure-Python sdist, why the WSL job gates
and what the pipe truncation was, and why the virgin container's
overlay=false row is still pinned.

Proved comments-only three ways: both workflow revisions parsed with
yaml.safe_load_all and every leaf walked (only `run:` scalars differ);
every changed bash body and .sh compared byte-for-byte after
`bash --pretty-print -n`; every changed pwsh body and .ps1 compared as
a token stream with Comment and NewLine tokens dropped. A negative
control injecting one non-comment line into each layer makes all of
them fail.
2026-07-29 06:33:16 +00:00

65 lines
3.4 KiB
PowerShell

# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
# The `nobuild` contract from clean-machine-assert.sh, for Windows. A port and not
# `shell: bash`: the scrub drops every `*\Git\*` PATH entry and the bash version needs
# sed/grep/tr/sort out of Git's usr/bin, and it also runs inside the servercore
# container, which has no bash. Both Windows lanes call this one file so the sdist
# allowlist cannot drift.
#
# Usage: assert-nobuild.ps1 -LogPath logs/install.log (exit 1 = a source build)
[CmdletBinding()]
param([Parameter(Mandatory = $true)][string] $LogPath)
if (-not (Test-Path -LiteralPath $LogPath)) {
Write-Host "::error::nobuild requested but $LogPath is missing"
exit 1
}
# "Built an sdist" is NOT "needed a compiler": every name here was verified against its
# own sdist -- setuptools.build_meta backend, no ext_modules, no .c/.cpp/.pyx/.rs file
# -- so its PEP 517 build is a pure-Python copy step. Identical to
# clean-machine-assert.sh, which carries the per-name rationale.
$allow = @('openai-whisper', 'argbind', 'randomname', 'antlr4-python3-runtime', 'triton-kernels')
if ($env:UNSLOTH_ALLOW_SDIST) {
$allow += ($env:UNSLOTH_ALLOW_SDIST -split '\s+' | Where-Object { $_ })
}
# Lowercased and underscore-folded on both sides: a distribution name and the name uv
# prints can disagree on the separator (triton_kernels vs triton-kernels).
$allow = @($allow | ForEach-Object { $_.ToLowerInvariant() -replace '_', '-' })
# [char]27, not "`e": that escape is PowerShell 6+, and under Windows PowerShell 5.1
# it degrades to a literal "e" and the strip eats real text instead of ANSI codes.
$esc = [char]27
$text = (Get-Content -LiteralPath $LogPath -Raw) -replace "$esc\[[0-9;]*[A-Za-z]", ''
$built = @()
foreach ($line in ($text -split "`r?`n")) {
# A local-path build is one the caller pointed at (the CI source overlay), never
# one resolution chose; index dependencies always print `==<version>`.
if ($line -imatch 'building [a-z0-9._-]+ @ file://') { continue }
# pip prints `Building wheel for <pkg>`, uv prints `Building <pkg>==<ver>`
# (astral-sh/uv#11165); the `==` or ` @ ` requirement keeps this off the
# installer's own lowercase "building frontend..." text.
foreach ($m in [regex]::Matches($line, '(?i)building wheel for ([a-z0-9._-]+)|building ([a-z0-9._-]+)(==| @ )')) {
$name = if ($m.Groups[1].Success) { $m.Groups[1].Value } else { $m.Groups[2].Value }
$built += ($name.ToLowerInvariant() -replace '_', '-')
}
}
$built = @($built | Sort-Object -Unique)
$bad = @($built | Where-Object { $allow -notcontains $_ })
$rc = 0
if ($bad.Count -gt 0) {
Write-Host "::error::built from source: $($bad -join ' ') -- these must resolve to wheels on a clean machine"
$rc = 1
} else {
Write-Host "[assert] OK no non-allowlisted source build (built: $(if ($built) { $built -join ' ' } else { 'none' }))"
}
# Independent of package names: a compiler error means a toolchain was needed.
$compilerErr = Select-String -Path $LogPath -Pattern "error: command '(cc|gcc|clang|cl)' failed", 'clang: error', 'cargo: not found', 'Microsoft Visual C\+\+ 14.0 or greater is required'
if ($compilerErr) {
Write-Host '::error::compiler invocation appears in the install log'
$compilerErr | Select-Object -First 10 | ForEach-Object { Write-Host " $($_.Line)" }
$rc = 1
}
exit $rc