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.
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Uploads dist/*.vsix to a release on Gitea.
|
||||
|
||||
.DESCRIPTION
|
||||
Creates the release for -Tag if it does not exist, then uploads each .vsix as an
|
||||
asset. An asset with the same name is deleted first, so re-publishing the same tag
|
||||
replaces the packages instead of piling up duplicates -- which is what makes the
|
||||
default rolling "latest" tag usable as the thing install.ps1 reads.
|
||||
|
||||
Needs a token with write:repository scope. See Get-GiteaToken in common.ps1 for
|
||||
where it is read from; it is never read from inside this repo.
|
||||
|
||||
.PARAMETER Tag
|
||||
The release tag. Defaults to "latest", a rolling release holding current builds.
|
||||
Use a version tag for a snapshot you want to keep.
|
||||
|
||||
.PARAMETER Build
|
||||
Run build.ps1 first.
|
||||
|
||||
.PARAMETER Notes
|
||||
Release body. Defaults to a list of the packages and their versions.
|
||||
|
||||
.EXAMPLE
|
||||
.\scripts\publish.ps1 -Build
|
||||
.\scripts\publish.ps1 -Tag v0.1.0 -Notes 'First cut of all three.'
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string] $Tag = 'latest',
|
||||
[string] $Token,
|
||||
[string] $Notes,
|
||||
[string] $Target,
|
||||
[switch] $Build,
|
||||
[switch] $Prerelease
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
. (Join-Path $PSScriptRoot 'common.ps1')
|
||||
|
||||
if ($Build) { & (Join-Path $PSScriptRoot 'build.ps1') | Out-Null }
|
||||
|
||||
$config = Get-SetupConfig
|
||||
$Token = Get-GiteaToken -Token $Token
|
||||
$dist = Get-DistDir
|
||||
$repoPath = "/repos/$($config.gitea.owner)/$($config.gitea.repo)"
|
||||
|
||||
$packages = @(Get-ChildItem -Path $dist -Filter '*.vsix' | Sort-Object Name)
|
||||
if ($packages.Count -eq 0) {
|
||||
throw "no .vsix files in $dist. Run build.ps1, or pass -Build."
|
||||
}
|
||||
|
||||
Write-Host "publishing $($packages.Count) package(s) to " -NoNewline
|
||||
Write-Host "$($config.gitea.url)/$($config.gitea.owner)/$($config.gitea.repo)@$Tag" -ForegroundColor Cyan
|
||||
|
||||
$release = Get-GiteaRelease -Tag $Tag -Token $Token
|
||||
if ($release) {
|
||||
Write-Host "reusing release $($release.id)" -ForegroundColor DarkGray
|
||||
} else {
|
||||
if (-not $Notes) {
|
||||
$lines = $packages | ForEach-Object {
|
||||
$name = $_.BaseName
|
||||
"- $name"
|
||||
}
|
||||
$Notes = @(
|
||||
'VS Code extensions, packaged as VSIX.',
|
||||
'',
|
||||
($lines -join "`n"),
|
||||
'',
|
||||
'Install them with scripts/install.ps1, or by hand:',
|
||||
'',
|
||||
' code --install-extension <file>.vsix --force'
|
||||
) -join "`n"
|
||||
}
|
||||
|
||||
$body = @{
|
||||
tag_name = $Tag
|
||||
name = "VS Code extensions ($Tag)"
|
||||
body = $Notes
|
||||
draft = $false
|
||||
prerelease = [bool] $Prerelease
|
||||
}
|
||||
# Omitted means Gitea creates the tag on the default branch.
|
||||
if ($Target) { $body.target_commitish = $Target }
|
||||
|
||||
$release = Invoke-Gitea -Token $Token -Method 'POST' -Path "$repoPath/releases" -Body $body
|
||||
Write-Host "created release $($release.id) for tag $Tag" -ForegroundColor DarkGray
|
||||
}
|
||||
|
||||
$existing = @()
|
||||
if ($release.PSObject.Properties.Name -contains 'assets' -and $release.assets) {
|
||||
$existing = @($release.assets)
|
||||
}
|
||||
|
||||
foreach ($package in $packages) {
|
||||
$clash = $existing | Where-Object { $_.name -eq $package.Name }
|
||||
foreach ($old in $clash) {
|
||||
Write-Host " replacing $($package.Name)" -ForegroundColor DarkGray
|
||||
Invoke-Gitea -Token $Token -Method 'DELETE' `
|
||||
-Path "$repoPath/releases/$($release.id)/assets/$($old.id)" | Out-Null
|
||||
}
|
||||
|
||||
$size = [math]::Round($package.Length / 1KB, 1)
|
||||
Write-Host " uploading $($package.Name) ($size KB)" -NoNewline
|
||||
$asset = Send-GiteaAsset -ReleaseId $release.id -FilePath $package.FullName -Token $Token
|
||||
Write-Host " ok" -ForegroundColor Green
|
||||
Write-Verbose " $($asset.browser_download_url)"
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host "done: $($config.gitea.url)/$($config.gitea.owner)/$($config.gitea.repo)/releases/tag/$Tag" -ForegroundColor Cyan
|
||||
Reference in New Issue
Block a user