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.
99 lines
3.4 KiB
PowerShell
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
|