Skip to content

chore: Update version number to 0.2.6 #37

chore: Update version number to 0.2.6

chore: Update version number to 0.2.6 #37

Workflow file for this run

name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: 'Tag to release (required when manually triggering from a branch)'
required: false
type: string
jobs:
prepare-release:
permissions:
contents: write
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate Changelog
uses: orhun/git-cliff-action@v4
id: git_cliff
with:
config: cliff.toml
args: --verbose --latest --strip header
env:
OUTPUT: CHANGELOG.md
- name: Create or Update Draft Release
uses: actions/github-script@v7
env:
TAG_NAME: ${{ inputs.tag || github.ref_name }}
RELEASE_BODY: ${{ steps.git_cliff.outputs.content || 'See the assets to download this version and install.' }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const tag = process.env.TAG_NAME;
const owner = context.repo.owner;
const repo = context.repo.repo;
const body = process.env.RELEASE_BODY;
const releaseName = `DbPaw ${tag}`;
const manualTag = context.payload?.inputs?.tag;
if (context.eventName === "workflow_dispatch" && !manualTag) {
throw new Error("workflow_dispatch requires input 'tag' (e.g. v0.1.5).")
}
if (!tag) {
throw new Error("Tag is empty. For workflow_dispatch, provide the 'tag' input.")
}
try {
const { data: existing } = await github.rest.repos.getReleaseByTag({ owner, repo, tag });
await github.rest.repos.updateRelease({
owner,
repo,
release_id: existing.id,
tag_name: tag,
name: releaseName,
body,
draft: true,
prerelease: false,
});
} catch (error) {
if (error.status !== 404) throw error;
await github.rest.repos.createRelease({
owner,
repo,
tag_name: tag,
name: releaseName,
body,
draft: true,
prerelease: false,
});
}
build:
needs: prepare-release
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- platform: macos-latest
target: aarch64-apple-darwin
- platform: macos-latest
target: x86_64-apple-darwin
- platform: ubuntu-22.04
target: x86_64-unknown-linux-gnu
- platform: windows-latest
target: x86_64-pc-windows-msvc
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Install dependencies (Ubuntu only)
if: matrix.platform == 'ubuntu-22.04'
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev \
build-essential \
curl \
wget \
file \
libssl-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-dev
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Cache Bun dependencies
uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
node_modules
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }}
restore-keys: |
${{ runner.os }}-bun-
- name: Install frontend dependencies
run: bun install
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Cache Rust build artifacts
uses: Swatinem/rust-cache@v2
with:
workspaces: |
src-tauri -> target
- name: Install Rust target
run: rustup target add ${{ matrix.target }}
- name: Build app (non-Windows)
if: matrix.platform != 'windows-latest'
run: bun run tauri build --target ${{ matrix.target }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
- name: Build app (Windows)
if: matrix.platform == 'windows-latest'
shell: pwsh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: |
$ErrorActionPreference = 'Continue'
for ($i = 1; $i -le 3; $i++) {
bun run tauri build --target ${{ matrix.target }}
if ($LASTEXITCODE -eq 0) {
exit 0
}
if ($i -lt 3) {
Write-Host "Build failed (attempt $i/3). Retrying in 10 seconds..."
Start-Sleep -Seconds 10
}
}
exit $LASTEXITCODE
- name: Resolve artifact paths
id: paths
shell: bash
run: |
set -euo pipefail
bundle_dir=""
if [ -d "src-tauri/target/${{ matrix.target }}/release/bundle" ]; then
bundle_dir="src-tauri/target/${{ matrix.target }}/release/bundle"
elif [ -d "src-tauri/target/release/bundle" ]; then
bundle_dir="src-tauri/target/release/bundle"
fi
if [ -z "$bundle_dir" ]; then
echo "No bundle directory found for target ${{ matrix.target }}"
find src-tauri/target -maxdepth 6 -type d -name bundle -print || true
exit 1
fi
echo "bundle_dir=$bundle_dir" >> "$GITHUB_OUTPUT"
- name: Normalize macOS updater bundle names
if: matrix.target == 'aarch64-apple-darwin' || matrix.target == 'x86_64-apple-darwin'
shell: bash
run: |
set -euo pipefail
bundle_dir="${{ steps.paths.outputs.bundle_dir }}"
src="$(find "$bundle_dir/macos" -maxdepth 1 -type f -name '*.app.tar.gz' | head -n 1 || true)"
if [ -z "$src" ]; then
exit 0
fi
dst="$bundle_dir/macos/DbPaw-${{ matrix.target }}.app.tar.gz"
if [ "$src" != "$dst" ] && [ ! -f "$dst" ]; then
mv "$src" "$dst"
fi
if [ -f "${src}.sig" ] && [ ! -f "${dst}.sig" ]; then
mv "${src}.sig" "${dst}.sig"
fi
- name: Generate updater metadata
shell: bash
env:
TAG_NAME: ${{ inputs.tag || github.ref_name }}
BUNDLE_DIR: ${{ steps.paths.outputs.bundle_dir }}
TARGET_TRIPLE: ${{ matrix.target }}
run: |
set -euo pipefail
python3 - <<'PY'
import datetime
import json
import os
import pathlib
import sys
bundle_dir = pathlib.Path(os.environ["BUNDLE_DIR"])
target = os.environ["TARGET_TRIPLE"]
tag = os.environ["TAG_NAME"]
repo = os.environ["GITHUB_REPOSITORY"]
base_url = f"https://github.com/{repo}/releases/download/{tag}"
def pick(patterns: list[str]) -> pathlib.Path | None:
for pattern in patterns:
matches = sorted(bundle_dir.glob(pattern))
if matches:
return matches[0]
return None
if target in ("aarch64-apple-darwin", "x86_64-apple-darwin"):
platform = "darwin-aarch64" if target.startswith("aarch64") else "darwin-x86_64"
bundle = pick(["macos/*.app.tar.gz"])
elif target == "x86_64-unknown-linux-gnu":
platform = "linux-x86_64"
bundle = pick(["appimage/*.AppImage"])
elif target == "x86_64-pc-windows-msvc":
platform = "windows-x86_64"
bundle = pick(["nsis/*.exe", "msi/*.msi"])
else:
raise SystemExit(f"Unsupported target triple: {target}")
if bundle is None:
print(f"No updater bundle found for target {target}", file=sys.stderr)
print(f"Searched in: {bundle_dir}", file=sys.stderr)
for p in sorted(bundle_dir.rglob("*")):
if p.is_file():
print(p.relative_to(bundle_dir), file=sys.stderr)
raise SystemExit(1)
sig_path = pathlib.Path(str(bundle) + ".sig")
if not sig_path.exists():
print(f"Signature file not found: {sig_path}", file=sys.stderr)
raise SystemExit(1)
signature = sig_path.read_text(encoding="utf-8").strip()
pub_date = datetime.datetime.utcnow().replace(microsecond=0).isoformat() + "Z"
url = f"{base_url}/{bundle.name}"
data = {
"version": tag,
"notes": "See the assets to download this version and install.",
"pub_date": pub_date,
"platforms": {platform: {"url": url, "signature": signature}},
}
out_dir = pathlib.Path("updater-json")
out_dir.mkdir(parents=True, exist_ok=True)
out_path = out_dir / f"latest-{target}.json"
out_path.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
print(f"Wrote {out_path}")
PY
- name: Upload bundle artifacts (macOS)
if: matrix.target == 'aarch64-apple-darwin' || matrix.target == 'x86_64-apple-darwin'
uses: actions/upload-artifact@v4
with:
name: bundle-${{ matrix.target }}
path: |
${{ steps.paths.outputs.bundle_dir }}/dmg/**/*.dmg
${{ steps.paths.outputs.bundle_dir }}/macos/**/*.app.tar.gz*
if-no-files-found: error
- name: Upload bundle artifacts (Linux)
if: matrix.target == 'x86_64-unknown-linux-gnu'
uses: actions/upload-artifact@v4
with:
name: bundle-${{ matrix.target }}
path: |
${{ steps.paths.outputs.bundle_dir }}/appimage/**/*.AppImage*
${{ steps.paths.outputs.bundle_dir }}/deb/**/*.deb
${{ steps.paths.outputs.bundle_dir }}/rpm/**/*.rpm
if-no-files-found: error
- name: Upload bundle artifacts (Windows)
if: matrix.target == 'x86_64-pc-windows-msvc'
uses: actions/upload-artifact@v4
with:
name: bundle-${{ matrix.target }}
path: |
${{ steps.paths.outputs.bundle_dir }}/msi/**/*.msi*
${{ steps.paths.outputs.bundle_dir }}/nsis/**/*.exe*
if-no-files-found: error
- name: Upload updater metadata artifact
uses: actions/upload-artifact@v4
with:
name: updater-json-${{ matrix.target }}
path: updater-json/latest-${{ matrix.target }}.json
if-no-files-found: error
release:
needs: build
permissions:
contents: write
runs-on: ubuntu-22.04
steps:
- name: Download bundle artifacts
uses: actions/download-artifact@v4
with:
pattern: bundle-*
path: artifacts
merge-multiple: true
- name: Download updater metadata artifacts
uses: actions/download-artifact@v4
with:
pattern: updater-json-*
path: updater-json
- name: Merge latest.json platforms
shell: bash
run: |
set -euo pipefail
mapfile -t files < <(find updater-json -type f -name '*.json')
if [ "${#files[@]}" -eq 0 ]; then
echo "No updater json files found in artifacts."
exit 1
fi
mkdir -p merged
jq -s '
reduce .[] as $item (
{version: null, notes: null, pub_date: null, platforms: {}};
.version = (.version // $item.version) |
.notes = (.notes // $item.notes) |
.pub_date = (.pub_date // $item.pub_date) |
.platforms += ($item.platforms // {})
)
' "${files[@]}" > merged/latest.json
echo "Merged platform keys:"
jq '.platforms | keys' merged/latest.json
- name: Remove per-platform latest json assets
shell: bash
run: find artifacts -type f -name 'latest*.json' -delete
- name: Upload release assets
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ inputs.tag || github.ref_name }}
draft: true
prerelease: false
overwrite_files: true
files: |
artifacts/**/*
merged/latest.json
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}