Skip to content
Draft
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
7 changes: 5 additions & 2 deletions .github/workflows/flatpak.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

# NOTE: appstreamcli ships in the builder image (Fedora-based) at
# /usr/bin/appstreamcli — do not add a package-manager step here. The image
# has dnf, not apt-get; an apt-get step fails the whole release job.
- name: Validate Flatpak manifest
run: bash tests/packaging/flatpak_validate.sh

Expand All @@ -39,11 +42,11 @@ jobs:
--install-deps-from=flathub \
--force-clean \
builddir \
packaging/flatpak/io.github.thewrz.HonkHonk.yml
packaging/flatpak/io.github.wrzonance.HonkHonk.yml

- name: Bundle
run: |
flatpak build-bundle repo honkhonk.flatpak io.github.thewrz.HonkHonk
flatpak build-bundle repo honkhonk.flatpak io.github.wrzonance.HonkHonk

- name: Upload Flatpak artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
Expand Down
13 changes: 13 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,19 @@ jobs:
exit 1
fi

# ─── Packaging identity ─────────────────────────────────────────────
# Runs on every PR, unfiltered by path: the drift this guards against (the
# old Flatpak app-id reappearing) can land in any file, so a paths: filter
# would defeat it. Needs no toolchain — bash, git and grep only.
identity-sweep:
name: Flatpak identity sweep
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Sweep for stale Flatpak identity
run: bash tests/packaging/flatpak_identity_sweep.sh

# ─── LOC Check ──────────────────────────────────────────────────────
# Only runs on pull requests — measures LOC delta vs base branch.
loc-check:
Expand Down
4 changes: 2 additions & 2 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ honkhonk/
│ └── fixtures/ # Short audio files for decode tests
├── packaging/
│ ├── flatpak/
│ │ └── io.github.thewrz.HonkHonk.yml
│ │ └── io.github.wrzonance.HonkHonk.yml
│ ├── aur/
│ │ └── PKGBUILD
│ ├── debian/
Expand Down Expand Up @@ -575,7 +575,7 @@ Portal-based apps work naturally in Flatpak's sandbox.

```yaml
# Flatpak manifest key points
app-id: io.github.thewrz.HonkHonk
app-id: io.github.wrzonance.HonkHonk
runtime: org.freedesktop.Platform
sdk: org.freedesktop.Sdk
finish-args:
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2024"
rust-version = "1.89"
license = "MIT"
description = "Wayland-native Linux soundboard"
repository = "https://github.com/thewrz/HonkHonk"
repository = "https://github.com/wrzonance/HonkHonk"

[lints.clippy]
cognitive_complexity = "warn"
Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ If you discover a security vulnerability in HonkHonk, please report it responsib

**Do NOT open a public GitHub issue for security vulnerabilities.**

Instead, use [GitHub's private vulnerability reporting](https://github.com/thewrz/HonkHonk/security/advisories/new) to submit a report directly through the repository.
Instead, use [GitHub's private vulnerability reporting](https://github.com/wrzonance/HonkHonk/security/advisories/new) to submit a report directly through the repository.

Alternatively, email: **djfreaq@gmail.com**

Expand Down
Binary file added assets/screenshots/main-window.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 0 additions & 42 deletions packaging/flatpak/io.github.thewrz.HonkHonk.metainfo.xml

This file was deleted.

92 changes: 92 additions & 0 deletions packaging/flatpak/io.github.wrzonance.HonkHonk.metainfo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2026 Adam Wrzeski -->
<component type="desktop-application">
<id>io.github.wrzonance.HonkHonk</id>
<name>HonkHonk</name>
<summary>Wayland-native Linux soundboard</summary>
<metadata_license>CC0-1.0</metadata_license>
<project_license>MIT</project_license>

<developer id="io.github.wrzonance">
<name>wrzonance</name>
</developer>

<description>
<p>
HonkHonk is a Wayland-native soundboard for Linux. Play sounds directly
into your microphone via a PipeWire virtual mic — works with Discord,
Mumble, and any PulseAudio-compatible application.
</p>
</description>

<launchable type="desktop-id">io.github.wrzonance.HonkHonk.desktop</launchable>

<!-- Rename migration (#207): 0.1.0 and v0.1.0-alpha.1 shipped a Flatpak
bundle under io.github.thewrz.HonkHonk. Declaring the old ID lets
software centres treat this as the same application and upgrade in
place instead of offering it as a second, parallel install. These are
the ONLY sanctioned occurrences of the old ID in the tree — see
tests/packaging/flatpak_identity_sweep.sh. -->
<provides>
<id>io.github.thewrz.HonkHonk</id>
</provides>
<replaces>
<id>io.github.thewrz.HonkHonk</id>
</replaces>

<url type="homepage">https://github.com/wrzonance/HonkHonk</url>
<url type="bugtracker">https://github.com/wrzonance/HonkHonk/issues</url>

<categories>
<category>Audio</category>
<category>AudioVideo</category>
</categories>

<recommends>
<display_length compare="ge">768</display_length>
</recommends>

<screenshots>
<screenshot type="default">
<caption>HonkHonk's main window, showing the sound grid</caption>
<image type="source" width="1348" height="983">https://raw.githubusercontent.com/wrzonance/HonkHonk/main/assets/screenshots/main-window.png</image>
</screenshot>
</screenshots>

<releases>
<release version="0.1.0" date="2026-06-10">
<description><p>Initial release.</p></description>
</release>
</releases>

<content_rating type="oars-1.1">
<content_attribute id="violence-cartoon">none</content_attribute>
<content_attribute id="violence-fantasy">none</content_attribute>
<content_attribute id="violence-realistic">none</content_attribute>
<content_attribute id="violence-bloodshed">none</content_attribute>
<content_attribute id="violence-sexual">none</content_attribute>
<content_attribute id="violence-desecration">none</content_attribute>
<content_attribute id="violence-slavery">none</content_attribute>
<content_attribute id="violence-worship">none</content_attribute>
<content_attribute id="drugs-alcohol">none</content_attribute>
<content_attribute id="drugs-narcotics">none</content_attribute>
<content_attribute id="drugs-tobacco">none</content_attribute>
<content_attribute id="sex-nudity">none</content_attribute>
<content_attribute id="sex-themes">none</content_attribute>
<content_attribute id="sex-homosexuality">none</content_attribute>
<content_attribute id="sex-prostitution">none</content_attribute>
<content_attribute id="sex-adultery">none</content_attribute>
<content_attribute id="sex-appearance">none</content_attribute>
<content_attribute id="language-profanity">none</content_attribute>
<content_attribute id="language-humor">none</content_attribute>
<content_attribute id="language-discrimination">none</content_attribute>
<content_attribute id="money-purchasing">none</content_attribute>
<content_attribute id="money-advertising">none</content_attribute>
<content_attribute id="money-gambling">none</content_attribute>
<content_attribute id="social-chat">none</content_attribute>
<content_attribute id="social-info">none</content_attribute>
<content_attribute id="social-audio">none</content_attribute>
<content_attribute id="social-location">none</content_attribute>
<content_attribute id="social-contacts">none</content_attribute>
</content_rating>
</component>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
app-id: io.github.thewrz.HonkHonk
app-id: io.github.wrzonance.HonkHonk
runtime: org.freedesktop.Platform
runtime-version: '24.08'
sdk: org.freedesktop.Sdk
Expand Down Expand Up @@ -28,9 +28,10 @@ finish-args:
- --talk-name=org.kde.StatusNotifierWatcher
# Sound library: read-only access to user's music folder
- --filesystem=xdg-music:ro
# User config and data dirs (XDG paths used by honkhonk)
- --filesystem=xdg-config/honkhonk:create
- --filesystem=xdg-data/honkhonk:create
# NOTE: no xdg-config/xdg-data grants. Flatpak redirects the XDG base dirs to
# ~/.var/app/<app-id>/, which is what `directories::ProjectDirs` resolves to
# inside the sandbox — the app never reads the host ~/.config/honkhonk, so
# granting it would widen the sandbox without changing behavior.

modules:
- name: honkhonk
Expand All @@ -41,15 +42,23 @@ modules:
# Install binary — /app/bin is on PATH inside the sandbox
- install -Dm755 target/x86_64-unknown-linux-gnu/release/honkhonk
/app/bin/honkhonk
# Install .desktop entry — /app/share is in XDG_DATA_DIRS
- install -Dm644 assets/honkhonk.desktop
/app/share/applications/io.github.thewrz.HonkHonk.desktop
# Install icon
- install -Dm644 assets/icons/hicolor/256x256/apps/honkhonk.png
/app/share/icons/hicolor/256x256/apps/honkhonk.png
# Install .desktop entry — rewrite Icon= to the full app-id in a scratch
# copy so we never mutate assets/honkhonk.desktop (deb/appimage packaging
# asserts it stays generic; see tests/packaging/deb_validate.sh).
- sed 's/^Icon=honkhonk$/Icon=io.github.wrzonance.HonkHonk/'
assets/honkhonk.desktop > /tmp/io.github.wrzonance.HonkHonk.desktop
- install -Dm644 /tmp/io.github.wrzonance.HonkHonk.desktop
/app/share/applications/io.github.wrzonance.HonkHonk.desktop
# Install the full app-id-named icon set (all sizes + scalable + symbolic).
# Create the theme dir first and copy the CONTENTS into it: a bare
# `cp -r hicolor /app/share/icons/` collapses the theme level to
# /app/share/icons/64x64/... when /app/share/icons does not yet exist,
# and the icons are then never found.
- install -d /app/share/icons/hicolor
- cp -r assets/icons/generated/hicolor/. /app/share/icons/hicolor/
# Install AppStream metainfo
- install -Dm644 packaging/flatpak/io.github.thewrz.HonkHonk.metainfo.xml
/app/share/metainfo/io.github.thewrz.HonkHonk.metainfo.xml
- install -Dm644 packaging/flatpak/io.github.wrzonance.HonkHonk.metainfo.xml
/app/share/metainfo/io.github.wrzonance.HonkHonk.metainfo.xml
# NOTE (issue #49): the persistent PipeWire conf.d drop-in is NOT installed
# in the Flatpak. The sandbox cannot write host PipeWire config, and the
# app talks to PipeWire via the pulseaudio socket. The app's first-run
Expand Down
126 changes: 126 additions & 0 deletions tests/packaging/flatpak_identity_sweep.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/usr/bin/env bash
# Repo-wide regression guard for the io.github.thewrz -> io.github.wrzonance
# Flatpak identity rename (#207).
#
# Pins two invariants:
# 1. The old app-id appears in NO tracked file content and NO tracked
# filename, except an explicit allowlist (see ALLOWLIST below).
# 2. Every canonical identity-bearing field names the NEW app-id, and the
# metainfo still declares the rename migration.
#
# Invariant 1 is deliberately a whole-repo sweep rather than a list of known
# files: the failure mode being guarded against is the old ID reappearing
# somewhere nobody thought to enumerate.
# Exits non-zero if any check fails.
set -euo pipefail

PASS=0
FAIL=0

OLD_ID="io.github.thewrz.HonkHonk"
NEW_ID="io.github.wrzonance.HonkHonk"
MANIFEST="packaging/flatpak/$NEW_ID.yml"
METAINFO="packaging/flatpak/$NEW_ID.metainfo.xml"

# Files permitted to name the old ID, and why:
# - this script and flatpak_validate.sh assert the ID's ABSENCE, so they
# must quote it to do so;
# - the metainfo declares it as <provides>/<replaces> so software centres
# upgrade the shipped 0.1.0 bundle in place (checked structurally below);
# - docs/superpowers/** are dated, historical plan and spec documents —
# rewriting them would falsify the record of what was decided when.
ALLOWLIST=(
tests/packaging/flatpak_identity_sweep.sh
tests/packaging/flatpak_validate.sh
"$METAINFO"
docs/superpowers
)

check() {
local desc="$1"
local result="$2"
if [ "$result" = "ok" ]; then
echo " PASS $desc"
PASS=$((PASS + 1))
else
echo " FAIL $desc — $result"
FAIL=$((FAIL + 1))
fi
}

# True when $1 is, or lives under, an allowlisted path.
is_allowlisted() {
local path="$1" allowed
for allowed in "${ALLOWLIST[@]}"; do
[ "$path" = "$allowed" ] && return 0
case "$path" in "$allowed"/*) return 0 ;; esac
done
return 1
}

echo "=== Flatpak identity sweep (#207) ==="

# ── Invariant 1a: no stale ID in any tracked file's CONTENT ───────────
content_hits=""
while IFS= read -r f; do
[ -n "$f" ] || continue
is_allowlisted "$f" || content_hits="$content_hits $f"
done < <(git grep -l --fixed-strings -- "$OLD_ID" -- . || true)

if [ -z "$content_hits" ]; then
check "no tracked file content names $OLD_ID (outside the allowlist)" "ok"
else
check "no tracked file content names $OLD_ID (outside the allowlist)" \
"found in:$content_hits"
fi

# ── Invariant 1b: no stale ID in any tracked FILENAME ─────────────────
# Catches the rename being reverted by moving a file back, which a
# content-only sweep would silently pass.
name_hits=$(git ls-files -- . | grep -F -- "$OLD_ID" || true)
if [ -z "$name_hits" ]; then
check "no tracked filename contains $OLD_ID" "ok"
else
check "no tracked filename contains $OLD_ID" \
"found: $(echo "$name_hits" | tr '\n' ' ')"
fi

# ── Invariant 2: canonical identity fields name the new ID ────────────
# Each check names an exact file, and a MISSING file is a failure — never a
# silent pass, which is how a sweep over "files that happen to exist" gets
# defeated by deleting or renaming its own targets.
expect_file_contains() {
local desc="$1" file="$2" needle="$3"
if [ ! -f "$file" ]; then
check "$desc" "missing: $file"
elif grep -qF -- "$needle" "$file"; then
check "$desc" "ok"
else
check "$desc" "$file does not contain '$needle'"
fi
}

expect_file_contains "manifest is named for the new ID" "$MANIFEST" "app-id: $NEW_ID"
expect_file_contains "metainfo is named for the new ID" "$METAINFO" "<id>$NEW_ID</id>"
expect_file_contains "metainfo launchable matches the desktop ID" \
"$METAINFO" "<launchable type=\"desktop-id\">$NEW_ID.desktop</launchable>"
expect_file_contains "metainfo declares <provides> for the old ID" \
"$METAINFO" "<id>$OLD_ID</id>"
expect_file_contains "release workflow builds the new-ID manifest" \
".github/workflows/flatpak.yml" "$MANIFEST"
expect_file_contains "release workflow bundles the new ID" \
".github/workflows/flatpak.yml" "flatpak build-bundle repo honkhonk.flatpak $NEW_ID"

# The icon set must be installed under the app-id, or the desktop entry's
# Icon= key resolves to nothing.
if [ -f "assets/icons/generated/hicolor/64x64/apps/$NEW_ID.png" ]; then
check "generated icons are named for the new ID" "ok"
else
check "generated icons are named for the new ID" \
"missing assets/icons/generated/hicolor/64x64/apps/$NEW_ID.png"
fi

# ── Summary ───────────────────────────────────────────────────────────
echo ""
echo "Results: $PASS passed, $FAIL failed"
[ "$FAIL" -eq 0 ]
Loading
Loading