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
Binary file added .github/assets/screenshot1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/assets/screenshot2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
127 changes: 58 additions & 69 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,103 +11,92 @@ env:

jobs:
test:
name: Test
name: Test — ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, macos-latest, windows-latest]
rust: [stable]

steps:
- name: Checkout code
- name: Checkout
uses: actions/checkout@v4

- name: Install system dependencies (Linux)
- name: Install Linux system dependencies
if: matrix.os == 'ubuntu-22.04'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf

- name: Install Rust
uses: actions-rs/toolchain@v1
sudo apt-get install -y \
libgtk-3-dev \
libwebkit2gtk-4.0-dev \
libappindicator3-dev \
librsvg2-dev \
patchelf \
libssl-dev \
pkg-config

- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
profile: minimal
toolchain: ${{ matrix.rust }}
override: true
components: rustfmt, clippy

- name: Cache cargo registry
uses: actions/cache@v3
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}

- name: Cache cargo index
uses: actions/cache@v3
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}

- name: Cache cargo build
uses: actions/cache@v3
with:
path: target
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}

- name: Run cargo check
run: cargo check --all --verbose
- name: Cache Rust build
uses: Swatinem/rust-cache@v2

- name: Run cargo test
run: cargo test --all --verbose
# Run tests on all workspace crates except the Tauri desktop app
# (it requires a display server / windowing environment to build)
- name: Run tests
run: cargo test --workspace --exclude openpaste-desktop

- name: Run cargo clippy
run: cargo clippy --all -- -D warnings
- name: Run clippy
run: cargo clippy --workspace --exclude openpaste-desktop -- -D warnings

- name: Run cargo fmt
- name: Check formatting
run: cargo fmt --all -- --check

build:
name: Build
build-desktop:
name: Build desktop — ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, macos-latest, windows-latest]
rust: [stable]

steps:
- name: Checkout code
- name: Checkout
uses: actions/checkout@v4

- name: Install system dependencies (Linux)
- name: Install Linux system dependencies
if: matrix.os == 'ubuntu-22.04'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf

- name: Install Rust
uses: actions-rs/toolchain@v1
sudo apt-get install -y \
libgtk-3-dev \
libwebkit2gtk-4.0-dev \
libappindicator3-dev \
librsvg2-dev \
patchelf \
libssl-dev \
pkg-config

- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable

- name: Cache Rust build
uses: Swatinem/rust-cache@v2

- name: Setup Node.js
uses: actions/setup-node@v4
with:
profile: minimal
toolchain: ${{ matrix.rust }}
override: true

- name: Cache cargo registry
uses: actions/cache@v3
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}

- name: Cache cargo index
uses: actions/cache@v3
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}

- name: Cache cargo build
uses: actions/cache@v3
with:
path: target
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}

- name: Run cargo build
run: cargo build --all --release --verbose
node-version: '20'
cache: 'npm'
cache-dependency-path: apps/desktop/package-lock.json

- name: Install frontend dependencies
working-directory: apps/desktop
run: npm ci

# cargo check is enough for CI — tauri-action handles the full build in release.yml
- name: Check Tauri app
working-directory: apps/desktop/src-tauri
run: cargo check
117 changes: 117 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
name: Release

on:
push:
tags:
- 'v*'

permissions:
contents: write

env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1

jobs:
# ── Build + release matrix ─────────────────────────────────────────────────
build:
name: Build — ${{ matrix.label }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
# macOS Apple Silicon
- os: macos-latest
label: macOS-arm64
target: aarch64-apple-darwin
tauri_args: --target aarch64-apple-darwin

# macOS Intel
- os: macos-13

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check GitHub Actions runner availability for macos-13
# Also verify the latest available Intel macOS runner labels
gh api /repos/{owner}/{repo}/actions/runners --paginate 2>/dev/null | \
  jq '.runners[].labels[].name' 2>/dev/null | sort -u || \
  echo "Unable to query runners — verify manually at https://github.com/actions/runner-images"

Repository: anonfedora/openpaste

Length of output: 158


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the workflow and inspect the relevant job section
ast-grep outline .github/workflows/release.yml --view expanded || true
echo '---'
cat -n .github/workflows/release.yml | sed -n '1,140p'

echo '--- runner label references ---'
rg -n 'macos-13|macos-15-intel|macOS-x64|x86_64-apple-darwin' .github/workflows .github || true

Repository: anonfedora/openpaste

Length of output: 5289


🌐 Web query:

GitHub Actions macOS runner labels macos-13 deprecation current availability macos-15-intel docs

💡 Result:

The macOS 13 GitHub Actions runner image has been fully retired since December 4, 2025 [1][2]. Any workflows pinned to the macos-13 label will fail immediately [2][3]. Regarding the macos-15-intel runner: - Availability: It is currently available as a GitHub-hosted runner [4][5]. - Purpose: It provides an x86_64 (Intel) environment on macOS 15, intended as a replacement for users migrating from the deprecated macos-13 runners [5]. - Support Lifecycle: This runner is scheduled for retirement in August 2027 [2][4][5]. GitHub has stated that after this date, the x86_64 architecture will no longer be supported for GitHub-hosted macOS runners [5]. For workflows requiring Intel-based macOS runners, macos-15-intel is the designated long-term solution until its scheduled retirement [5][6]. Users are otherwise encouraged to migrate to Apple Silicon (ARM64) runners, such as macos-14 or macos-15, where possible [7][2].

Citations:


Replace macos-13 with macos-15-intel for the Intel macOS build
macos-13 is retired, so this matrix entry won’t get a GitHub-hosted runner and the x64 release job will fail to start.

🧰 Tools
🪛 actionlint (1.7.12)

[error] 31-31: label "macos-13" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2025-vs2026", "windows-2022", "windows-11-arm", "ubuntu-slim", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xlarge", "macos-latest-large", "macos-26-intel", "macos-26-xlarge", "macos-26-large", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xlarge", "macos-14-large", "macos-14", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml at line 31, Update the Intel macOS matrix
entry in the release workflow from macos-13 to macos-15-intel so the x64 release
job uses an available GitHub-hosted runner.

Source: Linters/SAST tools

label: macOS-x64
target: x86_64-apple-darwin
tauri_args: --target x86_64-apple-darwin

# Windows x64
- os: windows-latest
label: Windows-x64
target: x86_64-pc-windows-msvc
tauri_args: ''

# Linux x64 (AppImage + deb)
- os: ubuntu-22.04
label: Linux-x64
target: x86_64-unknown-linux-gnu
tauri_args: ''

steps:
- name: Checkout
uses: actions/checkout@v4

# ── System dependencies ─────────────────────────────────────────────
- name: Install Linux system dependencies
if: matrix.os == 'ubuntu-22.04'
run: |
sudo apt-get update
sudo apt-get install -y \
libgtk-3-dev \
libwebkit2gtk-4.0-dev \
libappindicator3-dev \
librsvg2-dev \
patchelf \
libssl-dev \
pkg-config

# ── Rust ────────────────────────────────────────────────────────────
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}

- name: Cache Rust build
uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}

# ── Node ────────────────────────────────────────────────────────────
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: apps/desktop/package-lock.json

- name: Install frontend dependencies
working-directory: apps/desktop
run: npm ci

# ── Build daemon (must exist before Tauri build so the app can spawn it)
- name: Build daemon
run: cargo build --bin openpaste-daemon --release --target ${{ matrix.target }}

# ── Tauri build ─────────────────────────────────────────────────────
- name: Build Tauri app
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Code-signing (optional — set these secrets to sign your builds)
# macOS
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
# Windows
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
with:
projectPath: apps/desktop
tagName: ${{ github.ref_name }}
releaseName: 'OpenPaste ${{ github.ref_name }}'
releaseBody: |
See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) for details.
releaseDraft: true
prerelease: false
args: ${{ matrix.tauri_args }}
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Changelog

All notable changes to OpenPaste are documented here.

The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
OpenPaste uses [Semantic Versioning](https://semver.org/).

---

## [Unreleased]

## [0.1.0] — 2026-07-10

### Added
- Clipboard history capture with 500 ms polling (text + images)
- SQLite storage with FTS5 full-text search
- AES-256-GCM encryption with Argon2id key derivation
- Auto-lock vault after configurable inactivity timeout
- Pin and favorite items
- Color-coded tags with sidebar filter
- WASM plugin system (wasmtime sandbox) — auto-loads `.wasm` files from the plugins directory
- Cross-device sync via HTTP push/pull relay server (`clipboard-api`)
- Global shortcuts: `⌘⇧V` show/hide, `⌘⇧C` quick-paste
- System tray with Show, Quick Paste, and Quit menu items
- Hide-to-tray on window close
- Launch at login (macOS LaunchAgent)
- `openpaste` CLI: list, search, copy, get, pin, favorite, delete, status
- Daemon auto-spawned by the desktop app; probe-before-spawn avoids double-start
- Settings panel: max items, retention days, refresh interval, notifications, encryption toggle
- Sync configuration UI (server URL, API token, enable toggle, Sync Now)
- Plugin Manager UI (load from file picker, list loaded plugins, unload)
- 26 automated tests (clipboard-db + clipboard-encryption)
- GitHub Actions CI (test + build-desktop, all platforms)
- GitHub Actions release workflow (macOS arm64/x64, Windows x64, Linux x64)
Loading
Loading