Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 0 additions & 87 deletions .github/workflows/release-trigger.yml

This file was deleted.

80 changes: 71 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,67 @@
name: Release

on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
bump_type:
description: 'Version bump'
type: choice
required: true
default: 'patch'
options:
- major
- minor
- patch
- none

permissions:
contents: write

jobs:
build-and-release:
# macOS 26 SDK is required to compile NSGlassEffectView (Liquid Glass).
release:
name: Bump, build & publish
runs-on: macos-26

steps:
- name: Checkout repository
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
fetch-depth: 0

- name: Configure git (github-actions bot)
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Compute new version
id: version
run: |
chmod +x Scripts/bump_version.sh
NEW_VERSION="$(Scripts/bump_version.sh "${{ inputs.bump_type }}")"
echo "version=$NEW_VERSION" >> "$GITHUB_OUTPUT"
echo "tag=v$NEW_VERSION" >> "$GITHUB_OUTPUT"
echo "Releasing v$NEW_VERSION (bump: ${{ inputs.bump_type }})"

- name: Guard — tag must not already exist
run: |
if git rev-parse "refs/tags/${{ steps.version.outputs.tag }}" >/dev/null 2>&1; then
echo "::error::Tag ${{ steps.version.outputs.tag }} already exists."
exit 1
fi

- name: Commit version bump
run: |
git add Sources/ClapCore/ClapVersion.swift
if git diff --cached --quiet; then
if [ "${{ inputs.bump_type }}" != "none" ]; then
echo "::error::Version bump changed nothing — unexpected."
exit 1
fi
echo "No version change for bump type 'none'."
else
git commit -m "Bump version to ${{ steps.version.outputs.tag }}"
fi

- name: Select Xcode
uses: maxim-lobanov/setup-xcode@v1
Expand All @@ -29,21 +75,37 @@ jobs:
run: |
chmod +x Scripts/make_app.sh
./Scripts/make_app.sh dist
TAG_NAME="${GITHUB_REF#refs/tags/}"

TAG_NAME="${{ steps.version.outputs.tag }}"
ZIP_NAME="clap-${TAG_NAME}.zip"

cd dist
zip -r -y "../${ZIP_NAME}" clap.app
cd ..
shasum -a 256 "${ZIP_NAME}" > "${ZIP_NAME}.sha256"

- name: Push commit and tag (only after a successful build)
run: |
git push origin "HEAD:${{ github.ref_name }}"
git tag "${{ steps.version.outputs.tag }}"
git push origin "${{ steps.version.outputs.tag }}"

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.version.outputs.tag }}
files: |
clap-*.zip
clap-*.zip.sha256
draft: false
prerelease: false
generate_release_notes: true

- name: Summary
run: |
{
echo "## Release published 🚀"
echo "- Tag: \`${{ steps.version.outputs.tag }}\`"
echo "- Bump: \`${{ inputs.bump_type }}\`"
echo "- Assets: zip + sha256 attached to the GitHub Release."
} >> "$GITHUB_STEP_SUMMARY"
2 changes: 1 addition & 1 deletion Scripts/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.2.1</string>
<string>0.0.0-PLACEHOLDER</string>
<key>CFBundleVersion</key>
<string>5</string>
<key>LSMinimumSystemVersion</key>
Expand Down
9 changes: 3 additions & 6 deletions Scripts/bump_version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ if [[ ! "$BUMP" =~ ^(major|minor|patch|none)$ ]]; then
exit 2
fi

CLI_FILE="Sources/ClapCLIKit/ClapCLI.swift"
CURRENT="$(sed -n 's/^ public static let version = "\([0-9]*\.[0-9]*\.[0-9]*\)"/\1/p' "$CLI_FILE")"
CLI_FILE="Sources/ClapCore/ClapVersion.swift"
CURRENT="$(sed -n 's/^ public static let current = "\([0-9]*\.[0-9]*\.[0-9]*\)"/\1/p' "$CLI_FILE")"
if [[ -z "$CURRENT" ]]; then
echo "error: could not read current version from $CLI_FILE" >&2
exit 1
Expand All @@ -35,8 +35,5 @@ substitute_inplace() {
sed "$pattern" "$file" > "$file.tmp" && mv "$file.tmp" "$file"
}

substitute_inplace "s/public static let version = \"$CURRENT\"/public static let version = \"$NEW\"/" "$CLI_FILE"
substitute_inplace "s/clipboard & shell history manager · v$CURRENT/clipboard & shell history manager · v$NEW/" \
Sources/ClapApp/SettingsView.swift
substitute_inplace "s/<string>$CURRENT<\/string>/<string>$NEW<\/string>/" Scripts/Info.plist
substitute_inplace "s/public static let current = \"$CURRENT\"/public static let current = \"$NEW\"/" "$CLI_FILE"
echo "$NEW"
9 changes: 8 additions & 1 deletion Scripts/make_app.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@ rm -rf "$APP"
mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources"
cp "$BIN/ClapApp" "$APP/Contents/MacOS/ClapApp"
cp "$BIN/clap" "$APP/Contents/MacOS/clap"
cp "$ROOT/Scripts/Info.plist" "$APP/Contents/Info.plist"
APP_VERSION="$(sed -n 's/^ public static let current = "\([0-9.]*\)"/\1/p' \
"$ROOT/Sources/ClapCore/ClapVersion.swift")"
if [ -z "$APP_VERSION" ]; then
echo "error: could not read version from ClapVersion.swift" >&2
exit 1
fi
sed "s|<string>0\.0\.0-PLACEHOLDER</string>|<string>$APP_VERSION</string>|" \
"$ROOT/Scripts/Info.plist" > "$APP/Contents/Info.plist"
if [ -d "$ROOT/Resources" ]; then
cp -R "$ROOT/Resources/"* "$APP/Contents/Resources/" 2>/dev/null || true
fi
Expand Down
2 changes: 1 addition & 1 deletion Sources/ClapApp/AppState+Pasteboard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ extension AppState {
pasteboard.clearContents()
pasteboard.setString(text, forType: .string)
await self.perform("Capture transformed text") {
try await self.store.captureText(text, sourceApp: "clap")
try await self.store.captureText(text, sourceApp: ClapIdentity.bundleID)
}
IPC.post(.storeChanged)
self.reload()
Expand Down
12 changes: 11 additions & 1 deletion Sources/ClapApp/PreviewPanel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,17 @@ struct PreviewView: View {
guard let url = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleID) else {
return bundleID
}
return FileManager.default.displayName(atPath: url.path)
// Prefer the bundle's localized display name; the on-disk name
// carries a ".app" suffix nobody wants in the UI.
if let bundle = Bundle(url: url) {
if let displayName = bundle.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String {
return displayName
}
if let name = bundle.object(forInfoDictionaryKey: "CFBundleName") as? String {
return name
}
}
return url.deletingPathExtension().lastPathComponent
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/ClapApp/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ struct SettingsView: View {
VStack(alignment: .leading, spacing: 2) {
Text("Clap")
.font(.title2.weight(.bold))
Text("Local-first clipboard & shell history manager · v0.2.1")
Text("Local-first clipboard & shell history manager · v\(ClapVersion.current)")
.font(.system(size: 11))
.foregroundStyle(.secondary)
}
Expand Down
3 changes: 2 additions & 1 deletion Sources/ClapCLIKit/ClapCLI.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import Foundation
import ClapCore

/// clap — clipboard manager CLI dispatcher.
///
/// Hand-rolled argument parsing, no external dependencies.
/// Global flags (`--data-dir <path>`) are accepted anywhere on the line and
/// extracted before command dispatch.
public enum ClapCLI {
public static let version = "0.2.1"
public static var version: String { ClapVersion.current }

/// Command dispatch table. Hidden/scripting commands are marked in help
/// comments only.
Expand Down
10 changes: 10 additions & 0 deletions Sources/ClapCore/ClapVersion.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/// Single source of truth for the release version.
///
/// Everything else derives from here:
/// - CLI `--version` and the Settings header read `ClapVersion.current`.
/// - `Scripts/make_app.sh` injects it into Info.plist's
/// CFBundleShortVersionString at packaging time.
/// - `Scripts/bump_version.sh` updates ONLY this file.
public enum ClapVersion {
public static let current = "0.2.0"
}
Loading