170 lines
5.5 KiB
YAML
170 lines
5.5 KiB
YAML
name: Release
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- "v*.*.*"
|
|
workflow_dispatch:
|
|
inputs:
|
|
publish:
|
|
description: "Publish to npm. Leave unchecked to run release verification only."
|
|
required: true
|
|
default: false
|
|
type: boolean
|
|
npm_dist_tag:
|
|
description: "npm dist-tag to publish under when publish is enabled."
|
|
required: false
|
|
default: latest
|
|
type: string
|
|
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
|
|
concurrency:
|
|
group: release-${{ github.workflow }}
|
|
cancel-in-progress: false
|
|
|
|
env:
|
|
# npm trusted publishing requires Node 22.14.0+ and npm 11.5.1+.
|
|
NODE_VERSION: "24"
|
|
PACKAGE_NAME: "skvlt"
|
|
NPM_DIST_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.npm_dist_tag || 'latest' }}
|
|
|
|
jobs:
|
|
publish:
|
|
name: Verify and publish
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 20
|
|
environment:
|
|
name: npm
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
registry-url: https://registry.npmjs.org
|
|
|
|
- name: Show npm runtime
|
|
shell: pwsh
|
|
run: |
|
|
"Node: $(node --version)"
|
|
"npm: $(npm --version)"
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
|
|
|
|
- name: Install dependencies
|
|
run: bun install --frozen-lockfile
|
|
|
|
- name: Verify tag matches package version
|
|
if: github.event_name == 'push'
|
|
shell: pwsh
|
|
run: |
|
|
$tagVersion = "${{ github.ref_name }}".Substring(1)
|
|
$packageVersion = (node -p "require('./package.json').version").Trim()
|
|
|
|
if ($tagVersion -ne $packageVersion) {
|
|
throw "Tag version '$tagVersion' did not match package version '$packageVersion'."
|
|
}
|
|
|
|
- name: Run release checks
|
|
run: bun run check
|
|
|
|
- name: Pack npm tarball
|
|
id: pack
|
|
shell: pwsh
|
|
run: |
|
|
$tarball = (npm pack | Select-Object -Last 1).Trim()
|
|
if (-not $tarball) {
|
|
throw "npm pack did not produce a tarball filename."
|
|
}
|
|
|
|
"tarball=$tarball" >> $env:GITHUB_OUTPUT
|
|
|
|
- name: Smoke test installed CLI
|
|
shell: pwsh
|
|
run: |
|
|
$prefix = Join-Path $PWD ".tmp-release-smoke"
|
|
$tarballPath = Join-Path $PWD "${{ steps.pack.outputs.tarball }}"
|
|
$expectedVersion = (node -p "require('./package.json').version").Trim()
|
|
|
|
npm install --prefix $prefix $tarballPath
|
|
|
|
$binPath = Join-Path $prefix "node_modules/.bin/skvlt"
|
|
& $binPath --help
|
|
|
|
$actualVersion = (& $binPath --version | Out-String).Trim()
|
|
if ($actualVersion -ne $expectedVersion) {
|
|
throw "Installed CLI version '$actualVersion' did not match package version '$expectedVersion'."
|
|
}
|
|
|
|
- name: Check whether this npm version is already published
|
|
id: npm_version
|
|
if: github.event_name == 'push' || inputs.publish == true
|
|
shell: bash
|
|
run: |
|
|
package_version="$(node -p "require('./package.json').version")"
|
|
published_version=""
|
|
exact_version_published="false"
|
|
|
|
if published_version="$(npm view "${PACKAGE_NAME}@${package_version}" version 2>/dev/null)"; then
|
|
published_version="${published_version//$'\n'/}"
|
|
else
|
|
published_version=""
|
|
fi
|
|
|
|
if [[ "$published_version" == "$package_version" ]]; then
|
|
exact_version_published="true"
|
|
echo "Version '$package_version' is already published to npm. Skipping publish."
|
|
else
|
|
echo "Version '$package_version' is not published yet. Proceeding to publish."
|
|
fi
|
|
|
|
echo "package_version=$package_version" >> "$GITHUB_OUTPUT"
|
|
echo "exact_version_published=$exact_version_published" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Publish to npm
|
|
if: (github.event_name == 'push' || inputs.publish == true) && steps.npm_version.outputs.exact_version_published != 'true'
|
|
# Trusted publishing uses GitHub OIDC and does not require NPM_TOKEN.
|
|
# Configure npm package settings with this workflow as a trusted publisher.
|
|
shell: pwsh
|
|
run: |
|
|
$output = & npm publish --access public --tag "${{ env.NPM_DIST_TAG }}" 2>&1 | Out-String
|
|
$exitCode = $LASTEXITCODE
|
|
|
|
$output.TrimEnd()
|
|
|
|
if ($exitCode -eq 0) {
|
|
exit 0
|
|
}
|
|
|
|
if ($output -match "Cannot publish over previously published version") {
|
|
"Version is immutable on npm already. Treating publish as complete."
|
|
exit 0
|
|
}
|
|
|
|
throw "npm publish failed with exit code $exitCode."
|
|
|
|
- name: Write workflow summary
|
|
if: always()
|
|
shell: pwsh
|
|
run: |
|
|
$packageVersion = (node -p "require('./package.json').version").Trim()
|
|
$mode = if ("${{ github.event_name }}" -eq "push") { "tag publish" } elseif ("${{ inputs.publish }}" -eq "true") { "manual publish" } else { "manual verification" }
|
|
|
|
@"
|
|
## Release summary
|
|
|
|
- Mode: $mode
|
|
- Package: $env:PACKAGE_NAME
|
|
- Version: $packageVersion
|
|
- Dist-tag: $env:NPM_DIST_TAG
|
|
- Ref: ${{ github.ref }}
|
|
- Publish skipped: ${{ steps.npm_version.outputs.exact_version_published == 'true' }}
|
|
"@ >> $env:GITHUB_STEP_SUMMARY
|