Files
max d45639bf2f Build, publish to Gitea releases, and install the three extensions
Answers two things: how to install these without a marketplace, and how to keep
settings in sync when VS Code's Settings Sync cannot be pointed at Gitea.

- build.ps1 packages each extension into dist/
- publish.ps1 creates a release and uploads them, replacing same-named assets so a
  rolling "latest" tag stays clean
- install.ps1 downloads a release's assets and installs them, or -Local from dist/
- settings.ps1 copies User/ between the repo and the machine, and installs the
  marketplace extensions recorded in extensions.txt
- dev-link.ps1 junctions the sources into ~/.vscode/extensions for development
- ci-release.sh plus a Gitea Actions workflow do the build and publish on a tag push

Settings are copied, not symlinked: an atomic save replaces a symlink with a regular
file and the sync stops without looking broken.

vsce/ pins vsce and undici so packaging works on Node 18, which current vsce does not
support.

test/run.ps1 drives the real scripts against a stub of the Gitea release API. It
caught the multipart Content-Disposition being unquoted on .NET Framework, and
Invoke-WebRequest dropping the Authorization header across a redirect.
2026-09-07 19:35:20 +02:00

99 lines
3.4 KiB
PowerShell

<#
.SYNOPSIS
Packages the extensions into dist/*.vsix.
.DESCRIPTION
For each extension in config.json: install dependencies if they are missing, then
run vsce, which compiles through the vscode:prepublish script. The .vsix files land
in dist/, which publish.ps1 uploads and install.ps1 can install from directly.
.PARAMETER Only
Build just these extension ids.
.PARAMETER Clone
Clone any extension whose configured path does not exist yet, from its Gitea repo.
.PARAMETER Pull
git pull each extension before building.
.EXAMPLE
.\scripts\build.ps1
.\scripts\build.ps1 -Only vertical-tabs
.\scripts\build.ps1 -Clone -Pull
#>
[CmdletBinding()]
param(
[string[]] $Only,
[switch] $Clone,
[switch] $Pull
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
. (Join-Path $PSScriptRoot 'common.ps1')
$config = Get-SetupConfig
$dist = Get-DistDir
$vsce = Get-VsceCommand
$extensions = $config.extensions
if ($Only) {
$extensions = $extensions | Where-Object { $Only -contains $_.id }
$missing = $Only | Where-Object { $config.extensions.id -notcontains $_ }
if ($missing) { throw "not in config.json: $($missing -join ', ')" }
}
$built = @()
foreach ($extension in $extensions) {
$path = Get-ExtensionPath $extension
Write-Host ''
Write-Host "=== $($extension.id)" -ForegroundColor Cyan
if (-not (Test-Path $path)) {
if (-not $Clone) {
throw ("$path does not exist. Pass -Clone to clone it from " +
"$($config.gitea.url)/$($config.gitea.owner)/$($extension.repo).")
}
$url = "$($config.gitea.url)/$($config.gitea.owner)/$($extension.repo).git"
Write-Host "cloning $url" -ForegroundColor DarkGray
& git clone $url $path
if ($LASTEXITCODE -ne 0) { throw "git clone failed for $($extension.id)" }
} elseif ($Pull) {
Write-Host 'git pull' -ForegroundColor DarkGray
& git -C $path pull --ff-only
if ($LASTEXITCODE -ne 0) { throw "git pull failed for $($extension.id)" }
}
$manifestPath = Join-Path $path 'package.json'
if (-not (Test-Path $manifestPath)) { throw "no package.json in $path" }
$manifest = Get-Content $manifestPath -Raw | ConvertFrom-Json
Push-Location $path
try {
if (-not (Test-Path (Join-Path $path 'node_modules'))) {
Write-Host 'installing dependencies...' -ForegroundColor DarkGray
if (Test-Path (Join-Path $path 'package-lock.json')) {
& npm ci --silent --no-audit --no-fund
} else {
& npm install --silent --no-audit --no-fund
}
if ($LASTEXITCODE -ne 0) { throw "dependency install failed for $($extension.id)" }
}
# vsce runs vscode:prepublish, so this compiles as well as packages.
# --allow-missing-repository keeps it from refusing a package.json with no
# repository field; it is harmless once that field is filled in.
$out = Join-Path $dist "$($manifest.name)-$($manifest.version).vsix"
& node $vsce package --out $out --allow-missing-repository
if ($LASTEXITCODE -ne 0) { throw "vsce package failed for $($extension.id)" }
$size = [math]::Round((Get-Item $out).Length / 1KB, 1)
Write-Host " -> $(Split-Path -Leaf $out) ($size KB)" -ForegroundColor Green
$built += $out
} finally { Pop-Location }
}
Write-Host ''
Write-Host "$($built.Count) package(s) in $dist" -ForegroundColor Cyan
$built