Git Repository

Stackyard

Stackyard scannt lokale Entwicklungsordner und bündelt Projekte, Git-Status, TODOs, Toolchains, Docker-Compose-Setups, Datei- und Launcher-Funktionen sowie Operations-Informationen in einer lokalen WebUI.

Projektseite ↗
HTTPShttps://zanvex.de/git/stackyard.git

build.ps1

[CmdletBinding()]
param(
    [ValidatePattern('^[A-Za-z0-9][A-Za-z0-9._-]*$')]
    [string]$Version = 'dev'
)

$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest

$ProjectRoot = $PSScriptRoot
$DistRoot = Join-Path $ProjectRoot 'dist'
$StagingRoot = Join-Path $DistRoot '.staging'

$Targets = @(
    [pscustomobject]@{ OS = 'windows'; Arch = 'amd64'; Extension = '.exe' },
    [pscustomobject]@{ OS = 'windows'; Arch = 'arm64'; Extension = '.exe' },
    [pscustomobject]@{ OS = 'linux';   Arch = 'amd64'; Extension = '' },
    [pscustomobject]@{ OS = 'linux';   Arch = 'arm64'; Extension = '' },
    [pscustomobject]@{ OS = 'darwin';  Arch = 'amd64'; Extension = '' },
    [pscustomobject]@{ OS = 'darwin';  Arch = 'arm64'; Extension = '' }
)

function Invoke-Go {
    param([Parameter(Mandatory)][string[]]$Arguments)

    if (Get-Command 'go' -ErrorAction SilentlyContinue) {
        & go @Arguments
    }
    elseif (Get-Command 'mise' -ErrorAction SilentlyContinue) {
        & mise exec -- go @Arguments
    }
    else {
        throw 'Go wurde weder direkt noch über mise gefunden.'
    }

    if ($LASTEXITCODE -ne 0) {
        throw "Go ist mit Exit-Code $LASTEXITCODE fehlgeschlagen."
    }
}

function Remove-ValidatedStagingDirectory {
    if (-not (Test-Path -LiteralPath $StagingRoot)) {
        return
    }

    $ResolvedDist = [IO.Path]::GetFullPath($DistRoot).TrimEnd([IO.Path]::DirectorySeparatorChar)
    $ResolvedStaging = [IO.Path]::GetFullPath($StagingRoot)
    $ExpectedPrefix = $ResolvedDist + [IO.Path]::DirectorySeparatorChar
    if (-not $ResolvedStaging.StartsWith($ExpectedPrefix, [StringComparison]::OrdinalIgnoreCase)) {
        throw "Unsicherer Staging-Pfad: $ResolvedStaging"
    }

    Remove-Item -LiteralPath $ResolvedStaging -Recurse -Force
}

Push-Location $ProjectRoot
$PreviousGoOS = $env:GOOS
$PreviousGoArch = $env:GOARCH
$PreviousCgoEnabled = $env:CGO_ENABLED

try {
    New-Item -ItemType Directory -Path $DistRoot -Force | Out-Null
    Remove-ValidatedStagingDirectory
    New-Item -ItemType Directory -Path $StagingRoot -Force | Out-Null

    Write-Host 'Prüfe Tests ...'
    Invoke-Go -Arguments @('test', './...')

    foreach ($Target in $Targets) {
        $ArtifactName = "stackyard-$Version-$($Target.OS)-$($Target.Arch)"
        $PackageDirectory = Join-Path $StagingRoot $ArtifactName
        $BinaryPath = Join-Path $PackageDirectory ("stackyard$($Target.Extension)")
        $ArchivePath = Join-Path $DistRoot "$ArtifactName.zip"

        New-Item -ItemType Directory -Path $PackageDirectory -Force | Out-Null
        Copy-Item -LiteralPath (Join-Path $ProjectRoot 'app/release.config.yaml') -Destination (Join-Path $PackageDirectory 'config.yaml')
        Copy-Item -LiteralPath (Join-Path $ProjectRoot 'README.md') -Destination $PackageDirectory
        $ProjectsDirectory = Join-Path $PackageDirectory 'projects'
        New-Item -ItemType Directory -Path $ProjectsDirectory -Force | Out-Null
        New-Item -ItemType File -Path (Join-Path $ProjectsDirectory '.keep') -Force | Out-Null

        $env:GOOS = $Target.OS
        $env:GOARCH = $Target.Arch
        $env:CGO_ENABLED = '0'

        Write-Host "Baue $($Target.OS)/$($Target.Arch) ..."
        Invoke-Go -Arguments @('build', '-trimpath', '-ldflags=-s -w', '-o', $BinaryPath, './cmd/stackyard')

        Compress-Archive -Path (Join-Path $PackageDirectory '*') -DestinationPath $ArchivePath -CompressionLevel Optimal -Force
        Write-Host "Erstellt: $ArchivePath"
    }
}
finally {
    $env:GOOS = $PreviousGoOS
    $env:GOARCH = $PreviousGoArch
    $env:CGO_ENABLED = $PreviousCgoEnabled
    Remove-ValidatedStagingDirectory
    Pop-Location
}

Write-Host "Fertig: $($Targets.Count) ZIP-Artefakte unter $DistRoot"