Skip to content

docs(release): prepare v1.0.95 #103

docs(release): prepare v1.0.95

docs(release): prepare v1.0.95 #103

Workflow file for this run

name: Release CLI
on:
push:
tags:
- "v*.*.*"
jobs:
meta:
name: Resolve tag metadata
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.resolve.outputs.tag }}
version: ${{ steps.resolve.outputs.version }}
prerelease: ${{ steps.resolve.outputs.prerelease }}
steps:
- id: resolve
shell: bash
run: |
set -euo pipefail
tag="${GITHUB_REF_NAME}"
if [[ ! "$tag" =~ ^v([0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?)$ ]]; then
echo "Tag '$tag' is not a valid semver release tag (expected vX.Y.Z)." >&2
exit 1
fi
version="${BASH_REMATCH[1]}"
prerelease="false"
if [[ "$version" == *"-"* ]]; then
prerelease="true"
fi
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "prerelease=$prerelease" >> "$GITHUB_OUTPUT"
publish_npm:
name: Publish @pushpalsdev/cli to npm
runs-on: ubuntu-latest
needs:
- meta
- build_binaries
- build_runtime_binaries
- smoke_windows_runtime
permissions:
contents: read
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
registry-url: "https://registry.npmjs.org"
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.9"
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Set CLI package version from tag
shell: bash
run: |
node -e "const fs=require('fs');const path='packages/cli/package.json';const pkg=JSON.parse(fs.readFileSync(path,'utf8'));pkg.version='${{ needs.meta.outputs.version }}';fs.writeFileSync(path,JSON.stringify(pkg,null,2)+'\n');"
- name: Check whether CLI version is already published
id: npm_publish_check
shell: bash
run: |
published_version="$(npm view "@pushpalsdev/cli@${{ needs.meta.outputs.version }}" version 2>/dev/null || true)"
if [ "$published_version" = "${{ needs.meta.outputs.version }}" ]; then
echo "already_published=true" >> "$GITHUB_OUTPUT"
echo "@pushpalsdev/cli@${{ needs.meta.outputs.version }} is already published on npm; skipping publish job."
else
echo "already_published=false" >> "$GITHUB_OUTPUT"
fi
- name: Verify npm publish token
if: steps.npm_publish_check.outputs.already_published != 'true'
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
shell: bash
run: |
set -euo pipefail
if [ -z "${NODE_AUTH_TOKEN:-}" ]; then
echo "::error::NPM_TOKEN secret is required to publish @pushpalsdev/cli." >&2
exit 1
fi
whoami_stderr="$RUNNER_TEMP/npm-whoami.stderr"
token_user="$(npm whoami --registry=https://registry.npmjs.org 2>"$whoami_stderr" || true)"
if [ -z "$token_user" ]; then
echo "::error::NPM_TOKEN is set, but npm whoami failed. The token is invalid, expired, or not accepted by registry.npmjs.org." >&2
cat "$whoami_stderr" >&2 || true
exit 1
fi
echo "NPM_TOKEN authenticates as npm user: ${token_user}"
owners_stderr="$RUNNER_TEMP/npm-owner-ls.stderr"
owners="$(npm owner ls @pushpalsdev/cli --registry=https://registry.npmjs.org 2>"$owners_stderr" || true)"
if [ -z "$owners" ]; then
echo "::error::Could not read @pushpalsdev/cli npm owners. The token may not be able to access the package." >&2
cat "$owners_stderr" >&2 || true
exit 1
fi
if ! printf '%s\n' "$owners" | awk '{print $1}' | grep -Fxq "$token_user"; then
echo "::error::NPM_TOKEN authenticates as '${token_user}', but that user is not listed as an owner for @pushpalsdev/cli. Create the secret from a package owner or grant this npm user publish rights." >&2
echo "Current @pushpalsdev/cli owners:" >&2
printf '%s\n' "$owners" >&2
exit 1
fi
access_json="$RUNNER_TEMP/npm-access-collaborators.json"
access_stderr="$RUNNER_TEMP/npm-access-collaborators.stderr"
if npm access list collaborators @pushpalsdev/cli --json --registry=https://registry.npmjs.org >"$access_json" 2>"$access_stderr"; then
ACCESS_JSON="$access_json" TOKEN_USER="$token_user" node <<'JS'
const fs = require("fs");
const raw = fs.readFileSync(process.env.ACCESS_JSON, "utf8").replace(/^\uFEFF/, "");
const access = JSON.parse(raw);
const permission = access[process.env.TOKEN_USER];
if (!permission || !String(permission).includes("write")) {
console.error(
`::error::NPM_TOKEN user ${process.env.TOKEN_USER} does not have write access to @pushpalsdev/cli. Observed permission: ${permission || "(none)"}.`,
);
process.exit(1);
}
console.log(`Verified npm write access for @pushpalsdev/cli: ${permission}`);
JS
else
echo "::warning::Could not verify @pushpalsdev/cli collaborator permissions through npm access. Package-scoped granular tokens can be blocked from metadata endpoints; continuing to npm publish after owner verification." >&2
cat "$access_stderr" >&2 || true
fi
- name: Build CLI package payload
if: steps.npm_publish_check.outputs.already_published != 'true'
run: bun run --cwd packages/cli build
- name: Publish to npm
if: steps.npm_publish_check.outputs.already_published != 'true'
working-directory: packages/cli
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
if [ -z "${NODE_AUTH_TOKEN:-}" ]; then
echo "NPM_TOKEN secret is required to publish @pushpalsdev/cli." >&2
exit 1
fi
npm publish --access public --provenance
smoke_published_cli_linux:
name: Smoke published CLI package on Linux
runs-on: ubuntu-latest
needs:
- meta
- publish_npm
- publish_release
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.9"
- name: Run installed-package Linux smoke
run: |
bun run scripts/release-installed-cli-smoke.ts \
--package-spec @pushpalsdev/cli@${{ needs.meta.outputs.version }}
smoke_published_cli_windows:
name: Smoke published CLI package on Windows
runs-on: windows-2022
needs:
- meta
- publish_npm
- publish_release
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.9"
- name: Run installed-package Windows smoke
shell: pwsh
run: |
bun run scripts/release-installed-cli-smoke.ts `
--package-spec @pushpalsdev/cli@${{ needs.meta.outputs.version }}
build_binaries:
name: Build standalone CLI binaries
needs: meta
env:
WINDOWS_CODESIGN_PFX_BASE64: ${{ secrets.WINDOWS_CODESIGN_PFX_BASE64 }}
WINDOWS_CODESIGN_PFX_PASSWORD: ${{ secrets.WINDOWS_CODESIGN_PFX_PASSWORD }}
MACOS_CODESIGN_CERT_P12_BASE64: ${{ secrets.MACOS_CODESIGN_CERT_P12_BASE64 }}
MACOS_CODESIGN_CERT_PASSWORD: ${{ secrets.MACOS_CODESIGN_CERT_PASSWORD }}
MACOS_CODESIGN_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_CODESIGN_KEYCHAIN_PASSWORD }}
MACOS_CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
strategy:
fail-fast: false
matrix:
include:
- target: bun-linux-x64
output_name: pushpals-linux-x64
runs_on: ubuntu-latest
- target: bun-windows-x64
output_name: pushpals-windows-x64.exe
runs_on: windows-2022
- target: bun-darwin-x64
output_name: pushpals-macos-x64
runs_on: macos-14
- target: bun-darwin-arm64
output_name: pushpals-macos-arm64
runs_on: macos-14
runs-on: ${{ matrix.runs_on }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.9"
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Build standalone binary
shell: bash
run: |
set -euo pipefail
mkdir -p dist
output="dist/${{ matrix.output_name }}"
bun build scripts/pushpals-cli.ts --compile --target=${{ matrix.target }} --outfile "$output"
if [[ "${{ matrix.target }}" != "bun-windows-x64" ]]; then
chmod +x "$output"
fi
- name: Install Windows signing tool
if: matrix.target == 'bun-windows-x64' && env.WINDOWS_CODESIGN_PFX_BASE64 != '' && runner.os != 'Windows'
run: |
sudo apt-get update
sudo apt-get install -y osslsigncode
- name: Sign Windows CLI binary
if: matrix.target == 'bun-windows-x64' && env.WINDOWS_CODESIGN_PFX_BASE64 != '' && runner.os != 'Windows'
shell: bash
env:
WINDOWS_CODESIGN_TIMESTAMP_URL: ${{ vars.WINDOWS_CODESIGN_TIMESTAMP_URL }}
run: |
set -euo pipefail
cert_path="$(mktemp)"
printf '%s' "$WINDOWS_CODESIGN_PFX_BASE64" | base64 -d > "$cert_path"
output="dist/${{ matrix.output_name }}"
signed_output="${output}.signed"
timestamp_url="${WINDOWS_CODESIGN_TIMESTAMP_URL:-http://timestamp.digicert.com}"
osslsigncode sign \
-pkcs12 "$cert_path" \
-pass "$WINDOWS_CODESIGN_PFX_PASSWORD" \
-h sha256 \
-n "PushPals CLI" \
-i "https://github.com/PushPalsDev/pushpals" \
-ts "$timestamp_url" \
-in "$output" \
-out "$signed_output"
mv "$signed_output" "$output"
rm -f "$cert_path"
- name: Sign Windows CLI binary (signtool)
if: matrix.target == 'bun-windows-x64' && env.WINDOWS_CODESIGN_PFX_BASE64 != '' && runner.os == 'Windows'
shell: pwsh
env:
WINDOWS_CODESIGN_TIMESTAMP_URL: ${{ vars.WINDOWS_CODESIGN_TIMESTAMP_URL }}
run: |
$ErrorActionPreference = 'Stop'
$certPath = Join-Path $env:RUNNER_TEMP 'pushpals-cli-codesign-cert.pfx'
[System.IO.File]::WriteAllBytes(
$certPath,
[System.Convert]::FromBase64String($env:WINDOWS_CODESIGN_PFX_BASE64)
)
$signtool = Get-ChildItem 'C:\Program Files (x86)\Windows Kits\10\bin' -Recurse -Filter signtool.exe |
Sort-Object FullName -Descending |
Select-Object -First 1 -ExpandProperty FullName
if (-not $signtool) {
throw 'signtool.exe not found on runner.'
}
$timestampUrl = if ($env:WINDOWS_CODESIGN_TIMESTAMP_URL) {
$env:WINDOWS_CODESIGN_TIMESTAMP_URL
} else {
'http://timestamp.digicert.com'
}
& $signtool sign `
/f $certPath `
/p $env:WINDOWS_CODESIGN_PFX_PASSWORD `
/fd SHA256 `
/td SHA256 `
/tr $timestampUrl `
/d 'PushPals CLI' `
/du 'https://github.com/PushPalsDev/pushpals' `
"dist/${{ matrix.output_name }}"
if ($LASTEXITCODE -ne 0) {
throw "signtool failed with exit code $LASTEXITCODE"
}
- name: Import macOS signing certificate
if: startsWith(matrix.target, 'bun-darwin-') && env.MACOS_CODESIGN_CERT_P12_BASE64 != ''
shell: bash
run: |
set -euo pipefail
cert_path="$RUNNER_TEMP/pushpals-codesign-cert.p12"
keychain_path="$RUNNER_TEMP/pushpals-signing.keychain-db"
python3 - <<'PY'
import base64, os, pathlib
pathlib.Path(os.environ["RUNNER_TEMP"], "pushpals-codesign-cert.p12").write_bytes(
base64.b64decode(os.environ["MACOS_CODESIGN_CERT_P12_BASE64"])
)
PY
security create-keychain -p "$MACOS_CODESIGN_KEYCHAIN_PASSWORD" "$keychain_path"
security set-keychain-settings -lut 21600 "$keychain_path"
security unlock-keychain -p "$MACOS_CODESIGN_KEYCHAIN_PASSWORD" "$keychain_path"
security import "$cert_path" \
-k "$keychain_path" \
-P "$MACOS_CODESIGN_CERT_PASSWORD" \
-T /usr/bin/codesign \
-T /usr/bin/security
security set-key-partition-list \
-S apple-tool:,apple:,codesign: \
-s \
-k "$MACOS_CODESIGN_KEYCHAIN_PASSWORD" \
"$keychain_path"
security list-keychains -d user -s "$keychain_path"
- name: Sign macOS CLI binary
if: startsWith(matrix.target, 'bun-darwin-') && env.MACOS_CODESIGN_CERT_P12_BASE64 != ''
shell: bash
run: |
set -euo pipefail
output="dist/${{ matrix.output_name }}"
codesign --force --sign "$MACOS_CODESIGN_IDENTITY" --timestamp --options runtime "$output"
codesign --verify --verbose "$output"
- name: Upload binary artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.output_name }}
path: dist/${{ matrix.output_name }}
build_runtime_binaries:
name: Build standalone runtime service binaries
needs: meta
env:
WINDOWS_CODESIGN_PFX_BASE64: ${{ secrets.WINDOWS_CODESIGN_PFX_BASE64 }}
WINDOWS_CODESIGN_PFX_PASSWORD: ${{ secrets.WINDOWS_CODESIGN_PFX_PASSWORD }}
MACOS_CODESIGN_CERT_P12_BASE64: ${{ secrets.MACOS_CODESIGN_CERT_P12_BASE64 }}
MACOS_CODESIGN_CERT_PASSWORD: ${{ secrets.MACOS_CODESIGN_CERT_PASSWORD }}
MACOS_CODESIGN_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_CODESIGN_KEYCHAIN_PASSWORD }}
MACOS_CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
strategy:
fail-fast: false
matrix:
include:
- target: bun-linux-x64
platform_key: linux-x64
runs_on: ubuntu-latest
- target: bun-windows-x64
platform_key: windows-x64
runs_on: windows-2022
- target: bun-darwin-x64
platform_key: macos-x64
runs_on: macos-14
- target: bun-darwin-arm64
platform_key: macos-arm64
runs_on: macos-14
runs-on: ${{ matrix.runs_on }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.9"
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Build protocol workspace artifacts
run: bun run protocol:build
- name: Build runtime binaries
shell: bash
run: |
set -euo pipefail
mkdir -p dist
ext=""
if [[ "${{ matrix.platform_key }}" == windows-* ]]; then
ext=".exe"
fi
bun build apps/server/src/server_main.ts --compile --target=${{ matrix.target }} --outfile "dist/pushpals-runtime-server-${{ matrix.platform_key }}${ext}"
bun build apps/localbuddy/src/localbuddy_main.ts --compile --target=${{ matrix.target }} --outfile "dist/pushpals-runtime-localbuddy-${{ matrix.platform_key }}${ext}"
bun build apps/remotebuddy/src/remotebuddy_main.ts --compile --target=${{ matrix.target }} --outfile "dist/pushpals-runtime-remotebuddy-${{ matrix.platform_key }}${ext}"
bun build apps/workerpals/src/workerpals_main.ts --compile --target=${{ matrix.target }} --outfile "dist/pushpals-runtime-workerpals-${{ matrix.platform_key }}${ext}"
bun build apps/source_control_manager/src/source_control_manager_main.ts --compile --target=${{ matrix.target }} --outfile "dist/pushpals-runtime-source-control-manager-${{ matrix.platform_key }}${ext}"
if [[ "${{ matrix.platform_key }}" != windows-* ]]; then
chmod +x dist/pushpals-runtime-*-${{ matrix.platform_key }}
fi
- name: Install Windows signing tool
if: startsWith(matrix.platform_key, 'windows-') && env.WINDOWS_CODESIGN_PFX_BASE64 != '' && runner.os != 'Windows'
run: |
sudo apt-get update
sudo apt-get install -y osslsigncode
- name: Sign Windows runtime binaries
if: startsWith(matrix.platform_key, 'windows-') && env.WINDOWS_CODESIGN_PFX_BASE64 != '' && runner.os != 'Windows'
shell: bash
env:
WINDOWS_CODESIGN_TIMESTAMP_URL: ${{ vars.WINDOWS_CODESIGN_TIMESTAMP_URL }}
run: |
set -euo pipefail
cert_path="$(mktemp)"
printf '%s' "$WINDOWS_CODESIGN_PFX_BASE64" | base64 -d > "$cert_path"
timestamp_url="${WINDOWS_CODESIGN_TIMESTAMP_URL:-http://timestamp.digicert.com}"
for output in dist/pushpals-runtime-*-${{ matrix.platform_key }}.exe; do
signed_output="${output}.signed"
osslsigncode sign \
-pkcs12 "$cert_path" \
-pass "$WINDOWS_CODESIGN_PFX_PASSWORD" \
-h sha256 \
-n "PushPals Runtime" \
-i "https://github.com/PushPalsDev/pushpals" \
-ts "$timestamp_url" \
-in "$output" \
-out "$signed_output"
mv "$signed_output" "$output"
done
rm -f "$cert_path"
- name: Sign Windows runtime binaries (signtool)
if: startsWith(matrix.platform_key, 'windows-') && env.WINDOWS_CODESIGN_PFX_BASE64 != '' && runner.os == 'Windows'
shell: pwsh
env:
WINDOWS_CODESIGN_TIMESTAMP_URL: ${{ vars.WINDOWS_CODESIGN_TIMESTAMP_URL }}
run: |
$ErrorActionPreference = 'Stop'
$certPath = Join-Path $env:RUNNER_TEMP 'pushpals-runtime-codesign-cert.pfx'
[System.IO.File]::WriteAllBytes(
$certPath,
[System.Convert]::FromBase64String($env:WINDOWS_CODESIGN_PFX_BASE64)
)
$signtool = Get-ChildItem 'C:\Program Files (x86)\Windows Kits\10\bin' -Recurse -Filter signtool.exe |
Sort-Object FullName -Descending |
Select-Object -First 1 -ExpandProperty FullName
if (-not $signtool) {
throw 'signtool.exe not found on runner.'
}
$timestampUrl = if ($env:WINDOWS_CODESIGN_TIMESTAMP_URL) {
$env:WINDOWS_CODESIGN_TIMESTAMP_URL
} else {
'http://timestamp.digicert.com'
}
Get-ChildItem 'dist\pushpals-runtime-*-windows-x64.exe' | ForEach-Object {
& $signtool sign `
/f $certPath `
/p $env:WINDOWS_CODESIGN_PFX_PASSWORD `
/fd SHA256 `
/td SHA256 `
/tr $timestampUrl `
/d 'PushPals Runtime' `
/du 'https://github.com/PushPalsDev/pushpals' `
$_.FullName
if ($LASTEXITCODE -ne 0) {
throw "signtool failed for $($_.FullName) with exit code $LASTEXITCODE"
}
}
- name: Import macOS signing certificate
if: startsWith(matrix.platform_key, 'macos-') && env.MACOS_CODESIGN_CERT_P12_BASE64 != ''
shell: bash
run: |
set -euo pipefail
cert_path="$RUNNER_TEMP/pushpals-codesign-cert.p12"
keychain_path="$RUNNER_TEMP/pushpals-signing.keychain-db"
python3 - <<'PY'
import base64, os, pathlib
pathlib.Path(os.environ["RUNNER_TEMP"], "pushpals-codesign-cert.p12").write_bytes(
base64.b64decode(os.environ["MACOS_CODESIGN_CERT_P12_BASE64"])
)
PY
security create-keychain -p "$MACOS_CODESIGN_KEYCHAIN_PASSWORD" "$keychain_path"
security set-keychain-settings -lut 21600 "$keychain_path"
security unlock-keychain -p "$MACOS_CODESIGN_KEYCHAIN_PASSWORD" "$keychain_path"
security import "$cert_path" \
-k "$keychain_path" \
-P "$MACOS_CODESIGN_CERT_PASSWORD" \
-T /usr/bin/codesign \
-T /usr/bin/security
security set-key-partition-list \
-S apple-tool:,apple:,codesign: \
-s \
-k "$MACOS_CODESIGN_KEYCHAIN_PASSWORD" \
"$keychain_path"
security list-keychains -d user -s "$keychain_path"
- name: Sign macOS runtime binaries
if: startsWith(matrix.platform_key, 'macos-') && env.MACOS_CODESIGN_CERT_P12_BASE64 != ''
shell: bash
run: |
set -euo pipefail
for output in dist/pushpals-runtime-*-${{ matrix.platform_key }}; do
codesign --force --sign "$MACOS_CODESIGN_IDENTITY" --timestamp --options runtime "$output"
codesign --verify --verbose "$output"
done
- name: Upload runtime artifacts
uses: actions/upload-artifact@v4
with:
name: runtime-${{ matrix.platform_key }}
path: dist/pushpals-runtime-*
smoke_windows_runtime:
name: Smoke Windows runtime binaries
needs:
- meta
- build_runtime_binaries
runs-on: windows-2022
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.9"
- name: Download Windows runtime artifacts
uses: actions/download-artifact@v4
with:
name: runtime-windows-x64
path: dist/runtime-windows-x64
- name: Run autonomy-enabled Windows runtime smoke
shell: pwsh
run: |
bun run scripts/release-windows-runtime-smoke.ts `
--runtime-bin-dir dist/runtime-windows-x64 `
--prompts-root .
publish_release:
name: Publish GitHub release assets
runs-on: ubuntu-latest
needs:
- meta
- build_binaries
- build_runtime_binaries
- smoke_windows_runtime
- publish_npm
env:
LINUX_RELEASE_GPG_PRIVATE_KEY_BASE64: ${{ secrets.LINUX_RELEASE_GPG_PRIVATE_KEY_BASE64 }}
LINUX_RELEASE_GPG_PASSPHRASE: ${{ secrets.LINUX_RELEASE_GPG_PASSPHRASE }}
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download binaries
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- name: Generate checksums
shell: bash
run: |
cd dist
sha256sum pushpals-* > SHA256SUMS.txt
- name: Import Linux release signing key
if: env.LINUX_RELEASE_GPG_PRIVATE_KEY_BASE64 != ''
shell: bash
run: |
set -euo pipefail
export GNUPGHOME="$RUNNER_TEMP/gnupg"
mkdir -p "$GNUPGHOME"
chmod 700 "$GNUPGHOME"
python3 - <<'PY'
import base64, os, pathlib
pathlib.Path(os.environ["RUNNER_TEMP"], "pushpals-linux-release.key").write_bytes(
base64.b64decode(os.environ["LINUX_RELEASE_GPG_PRIVATE_KEY_BASE64"])
)
PY
gpg --batch --import "$RUNNER_TEMP/pushpals-linux-release.key"
- name: Sign Linux release artifacts
if: env.LINUX_RELEASE_GPG_PRIVATE_KEY_BASE64 != ''
shell: bash
run: |
set -euo pipefail
export GNUPGHOME="$RUNNER_TEMP/gnupg"
shopt -s nullglob
for artifact in dist/*linux* dist/SHA256SUMS.txt; do
if [[ -f "$artifact" ]]; then
gpg --batch --yes --pinentry-mode loopback \
--passphrase "$LINUX_RELEASE_GPG_PASSPHRASE" \
--armor --detach-sign "$artifact"
fi
done
- name: Resolve release log file
id: release_log
shell: bash
run: |
path="release_log.md"
if [[ -f "$path" ]]; then
echo "found=true" >> "$GITHUB_OUTPUT"
echo "path=$path" >> "$GITHUB_OUTPUT"
echo "Using release log at $path"
else
echo "found=false" >> "$GITHUB_OUTPUT"
echo "path=" >> "$GITHUB_OUTPUT"
echo "No release log found at $path; using default release body."
fi
- name: Create GitHub release (release log)
if: steps.release_log.outputs.found == 'true'
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.meta.outputs.tag }}
name: PushPals CLI ${{ needs.meta.outputs.tag }}
prerelease: ${{ needs.meta.outputs.prerelease == 'true' }}
generate_release_notes: true
body_path: ${{ steps.release_log.outputs.path }}
files: |
dist/pushpals-*
dist/SHA256SUMS.txt
dist/*.asc
- name: Create GitHub release (default body)
if: steps.release_log.outputs.found != 'true'
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.meta.outputs.tag }}
name: PushPals CLI ${{ needs.meta.outputs.tag }}
prerelease: ${{ needs.meta.outputs.prerelease == 'true' }}
generate_release_notes: true
body: |
## Install
- npm: `npm i -g @pushpalsdev/cli`
- bun: `bun install -g @pushpalsdev/cli`
## Direct downloads
Use the platform binaries attached to this release when npm/Bun is unavailable.
files: |
dist/pushpals-*
dist/SHA256SUMS.txt
dist/*.asc