# Hudra release builder # Reads the version from manifest.json, creates a clean release folder, # and produces a Chrome Web Store-ready ZIP. $ErrorActionPreference = "Stop" # Project locations $ProjectRoot = $PSScriptRoot $ManifestPath = Join-Path $ProjectRoot "manifest.json" $ReleaseRoot = Join-Path $ProjectRoot "release" # Check that manifest.json exists if (-not (Test-Path $ManifestPath)) { Write-Host "ERROR: manifest.json was not found." -ForegroundColor Red Write-Host "Place release.ps1 in the same folder as manifest.json." exit 1 } # Read extension name and version try { $Manifest = Get-Content $ManifestPath -Raw | ConvertFrom-Json } catch { Write-Host "ERROR: manifest.json is not valid JSON." -ForegroundColor Red exit 1 } $ExtensionName = $Manifest.name $Version = $Manifest.version if ([string]::IsNullOrWhiteSpace($ExtensionName)) { $ExtensionName = "Hudra" } if ([string]::IsNullOrWhiteSpace($Version)) { Write-Host "ERROR: No version was found in manifest.json." -ForegroundColor Red exit 1 } $SafeName = $ExtensionName -replace '[^a-zA-Z0-9_-]', '-' $ReleaseName = "$SafeName-v$Version" $StagingFolder = Join-Path $ReleaseRoot $ReleaseName $ZipPath = Join-Path $ReleaseRoot "$ReleaseName.zip" Write-Host "" Write-Host "Building $ExtensionName $Version..." -ForegroundColor Cyan Write-Host "" # Only files required by the browser extension at runtime belong in the ZIP. # Everything else is excluded by default, including release output, previous # releases, scripts, repository metadata, documentation and development files. $IncludedItems = @( "manifest.json", "background.js", "page-detection.js", "presenter.js", "controls.html", "controls.css", "controls.js", "icons" ) # Recreate the staging folder if (Test-Path $StagingFolder) { Remove-Item $StagingFolder -Recurse -Force } New-Item -ItemType Directory -Path $StagingFolder -Force | Out-Null # Copy only the allowlisted runtime files into the clean staging folder $IncludedItems | ForEach-Object { $SourcePath = Join-Path $ProjectRoot $_ if (-not (Test-Path $SourcePath)) { Write-Host "ERROR: Required runtime item was not found: $_" -ForegroundColor Red exit 1 } Copy-Item ` -Path $SourcePath ` -Destination $StagingFolder ` -Recurse ` -Force } # Confirm that the copied release contains manifest.json $CopiedManifest = Join-Path $StagingFolder "manifest.json" if (-not (Test-Path $CopiedManifest)) { Write-Host "ERROR: manifest.json was not copied into the release folder." -ForegroundColor Red exit 1 } # Remove any previous ZIP for this version if (Test-Path $ZipPath) { Remove-Item $ZipPath -Force } # ZIP the contents, ensuring manifest.json is at the ZIP root $FilesToZip = Join-Path $StagingFolder "*" Compress-Archive ` -Path $FilesToZip ` -DestinationPath $ZipPath ` -CompressionLevel Optimal ` -Force # Verify the ZIP was created if (-not (Test-Path $ZipPath)) { Write-Host "ERROR: The release ZIP could not be created." -ForegroundColor Red exit 1 } $ZipSize = [math]::Round((Get-Item $ZipPath).Length / 1KB, 1) Write-Host "Release created successfully!" -ForegroundColor Green Write-Host "" Write-Host "Release folder:" Write-Host " $StagingFolder" -ForegroundColor Yellow Write-Host "" Write-Host "ZIP file:" Write-Host " $ZipPath" -ForegroundColor Yellow Write-Host "" Write-Host "ZIP size: $ZipSize KB" Write-Host "" Write-Host "Ready for Gitea and the Chrome Web Store." -ForegroundColor Green