Skip to content

Migrate from wails v2 to wails v3#25

Merged
amemya merged 15 commits into
mainfrom
chore/wails-v3
May 29, 2026
Merged

Migrate from wails v2 to wails v3#25
amemya merged 15 commits into
mainfrom
chore/wails-v3

Conversation

@amemya
Copy link
Copy Markdown
Owner

@amemya amemya commented May 28, 2026

Wails v3への移行作業を完了

resolved #23

@amemya amemya requested a review from Copilot May 28, 2026 15:17
@amemya amemya self-assigned this May 28, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7152afea-7711-4273-83f0-4dafd0839ffe

📥 Commits

Reviewing files that changed from the base of the PR and between 6ce85a6 and 47162a8.

📒 Files selected for processing (1)
  • .github/workflows/release.yml

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • 複数プラットフォーム(Windows/macOS/Linux/iOS/Android)向けの強化されたビルド/配布ワークフローを追加。
    • タスクベースのビルド・実行コマンド群を導入し、開発/パッケージ作業が簡素化。
  • Chores

    • ランタイムを v3 系へ移行。
    • Node.js を v22、Go を 1.25.0 に更新。
    • 開発用設定とCIのビルド手順を最適化。
  • User-facing

    • ネイティブのファイルダイアログや起動/終了挙動が新仕様に更新。

Walkthrough

Wails v2 から v3 へ移行し、フロントエンドを v3 binding 化。多プラットフォーム向け(darwin/linux/windows/ios/android)の Taskfile を追加し、CI・flake・build/config・.gitignore を更新、旧 v2 自動生成ランタイムを削除しました。

Changes

Wails v3 Migration

Layer / File(s) Summary
Core migration: Go module, app lifecycle, menu, watcher
go.mod, main.go, app.go, watcher.go
Go モジュールを v3 へ更新し、アプリ生成/ランタイム呼び出し/メニュー/ウィンドウ生成を Wails v3 の application API に置換。App の startup/shutdown ライフサイクルと watcher のイベント発行経路を v3 に移行。
Frontend bindings and App changes
frontend/src/App.tsx, frontend/bindings/*
フロントエンドを binding 経路へ差替え。App.tsx のイベント購読/解除、設定取得、保存/API 呼出しを bindings(AppAPI/Settings)へ移行。
Removed autogenerated runtime/models
frontend/wailsjs/*
旧自動生成の runtime / models / Go JS/TS ラッパを削除し、bindings 生成に置換する変更。
Root Taskfile and build config
Taskfile.yml, build/Taskfile.yml, build/config.yml
ルート Taskfile を追加し共通 vars/includes を定義。build/Taskfile.yml で frontend ビルド・bindings 生成・icons・server/docker タスクなどを追加。build/config.yml を Wails v3 用設定で追加。
Platform Taskfiles
build/darwin/Taskfile.yml, build/linux/Taskfile.yml, build/windows/Taskfile.yml, build/ios/Taskfile.yml, build/android/Taskfile.yml
各 OS 向けのビルド/パッケージ/署名/デプロイ用タスクを Taskfile で定義(native/docker 分岐や署名手順を含む)。
CI / flake / misc
.github/workflows/release.yml, flake.nix, .gitignore, frontend/vite.config.ts, frontend/package.json
GitHub Actions の Node を 22 に更新、release workflow を Wails v3/bindings 生成と bin/ 出力前提へ変更。flake.nix の devShell と依存を更新、.gitignore に生成物を追加、Vite と package.json に小変更を適用。

Estimated code review effort:
🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed PRタイトルはチェンジセット全体の主要な変更を正確に反映しており、Wails v2からv3への移行という中心的な変更を簡潔かつ明確に伝えている。
Description check ✅ Passed PR説明はチェンジセットに関連しており、Wails v3への移行作業の完了とissue #23の解決を述べている。説明が簡潔だが、リンクされたissueと一貫性がある。
Linked Issues check ✅ Passed PR変更はissue #23の「Wails v3への移行」という要件を実装している。go.mod、main.go、app.go、watcher.goなどで、wails/v2からwails/v3へのAPIの置き換えが行われ、新しいビルドシステムとタスク管理が導入されている。
Out of Scope Changes check ✅ Passed 変更はすべてWails v3への移行に関連している。.gitignore、Taskfile.yml群、build/config.yml、フロントエンド設定の変更はすべて移行の一部であり、スコープ外の変更は見当たらない。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/wails-v3

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@amemya amemya changed the title Chore/wails v3 Migrate from wails v2 to wails v3 May 28, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR migrates ExifFrame from Wails v2 to Wails v3, updating backend runtime APIs, frontend runtime/bindings usage, and build/development tooling.

Changes:

  • Replaces Wails v2 app setup, runtime dialogs/events, and generated frontend bindings with Wails v3 equivalents.
  • Adds Wails v3 Taskfile-based build/package scaffolding and updates Go/Node/Nix dependencies.
  • Removes generated Wails v2 frontend runtime and binding files.

Reviewed changes

Copilot reviewed 21 out of 29 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
.gitignore Ignores Wails v3 build outputs and generated bindings.
app.go Migrates backend dialogs and lifecycle method names to Wails v3 APIs.
main.go Reworks application creation, menus, window setup, services, and asset serving for Wails v3.
watcher.go Migrates watcher event emission from Wails v2 runtime to Wails v3 application events.
go.mod Updates Go version and replaces Wails v2 dependency with Wails v3.
go.sum Updates dependency checksums for the Wails v3 dependency graph.
Taskfile.yml Adds top-level Wails v3 task orchestration.
build/Taskfile.yml Adds common Wails v3 build, frontend, bindings, icons, and helper tasks.
build/config.yml Adds Wails v3 project/build metadata configuration.
build/android/Taskfile.yml Adds Android build/package tasks.
build/darwin/Taskfile.yml Adds macOS build/package/signing tasks.
build/ios/Taskfile.yml Adds iOS build/package/run tasks.
build/linux/Taskfile.yml Adds Linux build/package/signing tasks.
build/windows/Taskfile.yml Adds Windows build/package/signing tasks.
flake.nix Updates dev shell dependencies for Wails v3 and installs the Wails v3 CLI.
flake.lock Removes the old pinned Wails v2 nixpkgs input.
frontend/package.json Adds Wails v3 runtime dependency and a dev build script.
frontend/package-lock.json Locks the added Wails v3 runtime package.
frontend/package.json.md5 Removes Wails v2 package cache artifact.
frontend/vite.config.ts Restricts Vite dev server host binding.
frontend/src/App.tsx Migrates frontend API/runtime imports, events, settings model usage, and window calls to Wails v3.
frontend/wailsjs/go/main/App.js Removes generated Wails v2 JS bindings.
frontend/wailsjs/go/main/App.d.ts Removes generated Wails v2 TypeScript bindings.
frontend/wailsjs/go/models.ts Removes generated Wails v2 model bindings.
frontend/wailsjs/runtime/runtime.js Removes generated Wails v2 runtime wrapper.
frontend/wailsjs/runtime/runtime.d.ts Removes generated Wails v2 runtime typings.
frontend/wailsjs/runtime/package.json Removes generated Wails v2 runtime package metadata.
Files not reviewed (1)
  • frontend/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread main.go Outdated
Comment on lines +69 to +75
// Let the App struct handle its own startup/shutdown via Wails Service interfaces if supported,
// or we can just call startup directly for now.
go func() {
// Temporary workaround for startup hook
appStruct.OnStartup()
}()

Comment thread main.go
Comment on lines +21 to +22
appleMenu.Add("Preferences...").SetAccelerator("CmdOrCtrl+,").OnClick(func(ctx *application.Context) {
go application.Get().Event.Emit("open_settings")
Comment thread main.go
Comment on lines +40 to +41
fileMenu.Add("Preferences...").SetAccelerator("CmdOrCtrl+,").OnClick(func(ctx *application.Context) {
go application.Get().Event.Emit("open_settings")
Comment thread main.go Outdated
wailsruntime.WindowShow(app.ctx)
}
appleMenu.Add("Hide Others").SetAccelerator("OptionOrAlt+h").OnClick(func(ctx *application.Context) {})
appleMenu.Add("Show All").OnClick(func(ctx *application.Context) {
Comment thread build/config.yml Outdated
Comment on lines +8 to +13
companyName: "My Company" # The name of the company
productName: "My Product" # The name of the application
productIdentifier: "com.mycompany.myproduct" # The unique product identifier
description: "A program that does X" # The application description
copyright: "(c) 2025, My Company" # Copyright text
comments: "Some Product Comments" # Comments
Comment thread flake.nix
Comment on lines +41 to +44
if ! command -v wails3 > /dev/null; then
echo "Installing Wails v3 CLI (wails3)..."
go install github.com/wailsapp/wails/v3/cmd/wails3@latest
fi
cmds:
- |-
wails3 tool msix \
--config "{{.ROOT_DIR}}/wails.json" \
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 14

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
app.go (1)

375-383: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

フォルダ選択の戻り値が本当にディレクトリか検証してください

  • SelectWatchFolder / SelectExportFolderCanChooseDirectories(true) のみで、Wails v3 側でもディレクトリ専用にしたい場合は CanChooseFiles(false) の明示を推奨しています。
  • 戻り値 path 取得後に os.Stat(path).IsDir() を確認し、ディレクトリでなければ "" を返す(同様に両関数へ)ようにしてください。
修正例
 func (a *App) SelectWatchFolder() string {
 	path, err := application.Get().Dialog.OpenFile().
 		SetTitle("Select Watch Folder").
 		CanChooseDirectories(true).
 		PromptForSingleSelection()
 	if err != nil {
 		log.Println("Error opening directory dialog:", err)
 		return ""
 	}
+	if path != "" {
+		info, statErr := os.Stat(path)
+		if statErr != nil || !info.IsDir() {
+			log.Println("Selected path is not a directory:", path)
+			return ""
+		}
+	}
 	return path
 }
🤖 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 `@app.go` around lines 375 - 383, Ensure SelectWatchFolder and
SelectExportFolder explicitly restrict the file dialog to directories by adding
CanChooseFiles(false) to the existing application.Get().Dialog.OpenFile() chain,
then defensively validate the returned path with os.Stat(path) and check
IsDir(); if stat fails or IsDir() is false, return "" instead of the path.
Locate the dialog call sites (SelectWatchFolder/SelectExportFolder) and update
the dialog options and post-PromptForSingleSelection() logic to perform the
os.Stat/is-dir check before returning the path.
frontend/src/App.tsx (1)

154-209: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

バックグラウンド画像ロード失敗時のハンドリングが不足しています。

img.onload はありますが img.onerror がないため、Line [208] の読み込み失敗時に無言で処理が落ちます。

💡 提案差分
                 img.onload = async () => {
                   const offscreenCanvas = document.createElement('canvas');
                   const exifData = {
@@
                     }, targetMime, 1.0);
                 };
+                img.onerror = () => {
+                    console.error("Background image load failed:", result.imageURL);
+                };
                 img.src = result.imageURL;
             }).catch((e: any) => console.error(e));
🤖 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 `@frontend/src/App.tsx` around lines 154 - 209, Add an img.onerror handler
alongside img.onload to catch image load failures: define img.onerror = (ev) =>
{ console.error("Image load failed", result.imageURL, ev); /* trigger existing
error path: reject the surrounding Promise or call the same handler used in the
.catch so the outer flow handles the failure and any cleanup */ }; This ensures
the Image instance (img) reports failures for result.imageURL and prevents
silent failures before offscreenCanvas/toBlob/SaveAutoImage logic runs.
🤖 Prompt for all review comments with 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.

Inline comments:
In `@build/android/Taskfile.yml`:
- Around line 107-120: The "package" and "package:fat" tasks call assemble:apk
which produces a debug APK; update these tasks so they invoke the release
assembler (or pass the release flag/env) instead of assemble:apk — e.g. call
assemble:release (or ensure PRODUCTION: "true" / BUILD_VARIANT: "release" is
passed to the assemble task) and do the same for package:fat (and any duplicated
blocks referencing assemble:apk such as the section around
assemble:apk/compile:go:all-archs) so the produced APK is a release build.

In `@build/config.yml`:
- Around line 8-14: config.yml の配布メタデータがテンプレート値のまま残っているため、companyName,
productName, productIdentifier, version の各フィールドを実アプリの値に置き換えてください;具体的には
companyName と productName を正しい法人/製品名に、productIdentifier
を組織ドメインに基づくユニークな逆ドメイン名に、version をリリースバージョン(SemVer 例: 1.2.0
等)に更新し、変更後に署名や配布・アップデート処理で期待通り動作するか(パッケージ IDs と一致するか)確認してください。

In `@build/ios/Taskfile.yml`:
- Around line 66-81: The package flow currently stops at build (producing a .a)
and create:app:bundle expects an executable named {{.APP_NAME}}, while
compile:ios emits {{.APP_NAME | lower}}; update the Taskfile so the
package/create:app:bundle depends on the compile step that produces the
executable (e.g., add a dependency on the compile:ios task or include it in the
package deps) and make the copy targets consistent by using the exact output
name from compile:ios (either change compile:ios to output {{.APP_NAME}} or
change the bundle copy commands to use {{.APP_NAME | lower}} and ensure the
executable is created under {{.BIN_DIR}} before copying), and ensure the build
step produces an executable not just a .a.

In `@build/linux/Taskfile.yml`:
- Line 194: The command invoking the wails3 sign tool uses a quoted glob
("{{.BIN_DIR}}/{{.APP_NAME}}*.deb" / "*.rpm") so the shell won't expand the
wildcard and signing can fail; update the Taskfile command that calls wails3
(the line containing: wails3 tool sign --input "{{.BIN_DIR}}/{{.APP_NAME}}*.deb"
--pgp-key {{.PGP_KEY}} {{if .SIGN_ROLE}}--role {{.SIGN_ROLE}}{{end}}) to pass an
unquoted glob (remove the surrounding quotes) or explicitly expand files (e.g.,
use a shell glob expansion via sh -c or iterate over files) so that
{{.BIN_DIR}}/{{.APP_NAME}}*.deb and the corresponding *.rpm are expanded before
being handed to wails3.

In `@build/Taskfile.yml`:
- Around line 164-166: 空行が連続しており YAML lint の empty-lines
ルールに違反していますので、Taskfile.yml の generate:bindings
セクション付近の余分な空行を削除して連続空行を1行以下にしてください(連続する空行を取り除き、必要なら1つの空行に統一して YAML
構造を崩さないようにする)。
- Line 258: The default TAG templating uses {{.TAG | default (printf "%s:latest"
.APP_NAME)}} which can emit uppercase repository names (e.g., ExifFrame:latest)
and break Docker; update the template to normalize to lowercase (e.g., use
(lower .APP_NAME) or equivalent lowercase function) or make TAG mandatory and
remove the default; apply this change to both places where the template is used
(the docker build -t and docker run -t occurrences) so repository/name is always
lowercase.
- Around line 139-147: The build script currently curls Puppertino assets
directly from raw.githubusercontent.com using the branch "main"; change the
download commands that target frontend/public/puppertino/puppertino.css and
frontend/public/puppertino/LICENSE to fetch a specific immutable git tag or
commit SHA (replace the `main` URL segment with the chosen SHA or tag) and add
integrity verification: after download, compute a checksum (e.g., sha256) of the
downloaded file and compare it to a committed expected hash, failing the
download step only if the checksum mismatches (but keep the existing non-fatal
fallback behavior when curl cannot fetch); update the curl calls and add the
checksum comparison logic around the existing curl/echo branches so the
filenames (frontend/public/puppertino/puppertino.css and .../LICENSE) and
behavior remain the same.

In `@flake.nix`:
- Around line 41-44: Replace the unchecked latest install of the Wails v3 CLI so
it matches the pinned library version in go.mod; instead of running go install
github.com/wailsapp/wails/v3/cmd/wails3@latest (the current wails3 install
command), pin the CLI to the same version used in go.mod (v3.0.0-alpha.96) or
source the version from a single variable, ensuring the wails3 installer
invocation uses `@v3.0.0-alpha.96` so CLI and library versions remain in sync.
- Around line 15-18: The flake.nix change replacing webkitgtk with webkitgtk_4_1
is correct for Wails v3's Linux default, but you should either add an explicit
fallback to webkitgtk_4_0 for older environments or document the ABI
requirement; update the linuxDeps block that currently lists gtk3 and
webkitgtk_4_1 to conditionally include webkitgtk_4_0 when webkitgtk_4_1 isn't
available (or add a comment explaining the ABI 4.1 requirement and that
gtk4/tagged stacks are separate) so consumers know the supported ABI and
alternative.

In `@frontend/package.json`:
- Line 13: Package version mismatch: frontend's dependency "`@wailsio/runtime`" is
^3.0.0-alpha.79 while the Go module github.com/wailsapp/wails/v3 is
v3.0.0-alpha.96, causing potential runtime API incompatibilities; update the
frontend dependency "`@wailsio/runtime`" in package.json to the same alpha
generation (e.g., ^3.0.0-alpha.96) or alternatively pin the Go module in go.mod
to match alpha.79, and if opting to keep different generations add a clear
compatibility note in README or package.json describing the intended
cross-version support and tested pair (reference symbols: "`@wailsio/runtime`" and
github.com/wailsapp/wails/v3).

In `@frontend/src/App.tsx`:
- Around line 148-150: Guard against missing or malformed payloads before
accessing event.data[0] in the Events.On("process_file", ...) handler: check
that event is defined, event.data is an array with length > 0 and that
event.data[0] is an object (and optionally that it contains the expected keys
used later like result and export) and return or log and skip processing if
these checks fail; update the block that currently creates unsubProcess and
destructures { result, export: exportFolderStr } to perform these guards first
to avoid runtime exceptions on unexpected payloads.

In `@go.mod`:
- Around line 46-48: Update the indirect module versions in go.mod to the fixed
versions addressing GO-2026: change golang.org/x/crypto to v0.52.0,
golang.org/x/net to v0.55.0, and golang.org/x/sys to v0.44.0, then run `go mod
tidy` to reconcile dependencies (ensure this preserves Wails v3 alpha
compatibility); target the lines referencing golang.org/x/crypto,
golang.org/x/net, and golang.org/x/sys when making the edits.

In `@main.go`:
- Line 11: The build fails because main.go contains a compile-time embed
directive "//go:embed all:frontend/dist" that requires frontend/dist to exist;
either remove or guard that embed or ensure the assets are produced before Go
build. Fix options: (A) remove or comment out the "//go:embed all:frontend/dist"
line and the associated embed.FS usage in main.go until the frontend build step
is added, or (B) keep the embed but update CI/build pipeline to run the frontend
build (generate frontend/dist) before running go build so the pattern matches;
reference the "//go:embed all:frontend/dist" directive and any embed.FS or
variable in main.go when making the change.
- Around line 69-74: Current code manually spawns a goroutine to call
appStruct.OnStartup(), which bypasses Wails v3 lifecycle; remove the manual
goroutine call and instead implement the Wails service lifecycle method(s) on
your App struct (implement ServiceStartup(ctx, options) and optionally
ServiceShutdown(ctx, options) on the same type) and rely on
application.NewService(appStruct) to register it so Wails will call
startup/shutdown hooks correctly; update any callers of OnStartup/OnShutdown to
use the lifecycle methods or invoke them from inside
ServiceStartup/ServiceShutdown if you need to keep existing logic.

---

Outside diff comments:
In `@app.go`:
- Around line 375-383: Ensure SelectWatchFolder and SelectExportFolder
explicitly restrict the file dialog to directories by adding
CanChooseFiles(false) to the existing application.Get().Dialog.OpenFile() chain,
then defensively validate the returned path with os.Stat(path) and check
IsDir(); if stat fails or IsDir() is false, return "" instead of the path.
Locate the dialog call sites (SelectWatchFolder/SelectExportFolder) and update
the dialog options and post-PromptForSingleSelection() logic to perform the
os.Stat/is-dir check before returning the path.

In `@frontend/src/App.tsx`:
- Around line 154-209: Add an img.onerror handler alongside img.onload to catch
image load failures: define img.onerror = (ev) => { console.error("Image load
failed", result.imageURL, ev); /* trigger existing error path: reject the
surrounding Promise or call the same handler used in the .catch so the outer
flow handles the failure and any cleanup */ }; This ensures the Image instance
(img) reports failures for result.imageURL and prevents silent failures before
offscreenCanvas/toBlob/SaveAutoImage logic runs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 61a4349a-0e52-4f75-8f82-81cc4f32ec7d

📥 Commits

Reviewing files that changed from the base of the PR and between 7f08fef and 6b1afb5.

⛔ Files ignored due to path filters (4)
  • build/windows/icon.ico is excluded by !**/*.ico
  • flake.lock is excluded by !**/*.lock
  • frontend/package-lock.json is excluded by !**/package-lock.json
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (25)
  • .gitignore
  • Taskfile.yml
  • app.go
  • build/Taskfile.yml
  • build/android/Taskfile.yml
  • build/config.yml
  • build/darwin/Taskfile.yml
  • build/darwin/icons.icns
  • build/ios/Taskfile.yml
  • build/linux/Taskfile.yml
  • build/windows/Taskfile.yml
  • flake.nix
  • frontend/package.json
  • frontend/package.json.md5
  • frontend/src/App.tsx
  • frontend/vite.config.ts
  • frontend/wailsjs/go/main/App.d.ts
  • frontend/wailsjs/go/main/App.js
  • frontend/wailsjs/go/models.ts
  • frontend/wailsjs/runtime/package.json
  • frontend/wailsjs/runtime/runtime.d.ts
  • frontend/wailsjs/runtime/runtime.js
  • go.mod
  • main.go
  • watcher.go
💤 Files with no reviewable changes (7)
  • frontend/package.json.md5
  • frontend/wailsjs/runtime/package.json
  • frontend/wailsjs/go/models.ts
  • frontend/wailsjs/go/main/App.d.ts
  • frontend/wailsjs/go/main/App.js
  • frontend/wailsjs/runtime/runtime.js
  • frontend/wailsjs/runtime/runtime.d.ts

Comment thread build/android/Taskfile.yml
Comment thread build/config.yml Outdated
Comment thread build/ios/Taskfile.yml
Comment thread build/linux/Taskfile.yml
Comment thread build/Taskfile.yml
Comment thread frontend/package.json
Comment thread frontend/src/App.tsx
Comment thread go.mod Outdated
Comment thread main.go
Comment thread main.go Outdated
- Implement Wails v3 ServiceStartup/ServiceShutdown lifecycle interfaces
  to fix watcher resource leak (OnShutdown was never called)
- Restore window-show behavior on Preferences menu click (lost in v2→v3)
- Implement 'Show All' menu action (was no-op)
- Update CI workflow for Wails v3 (wails3 CLI, webkitgtk-4.1, build flow)
- Replace scaffold placeholder values in build/config.yml
- Pin wails3 CLI version to v3.0.0-alpha.96 in flake.nix
- Align @wailsio/runtime to ^3.0.0-alpha.96
- Add CanChooseFiles(false) to directory picker dialogs
- Add event.data guard and img.onerror in process_file handler
- Update golang.org/x/{crypto,net,sys} for security advisories
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
main.go (1)

19-29: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

macOSメニューの空 OnClick を標準ロールで実装してください。

  • main.go(19)「About ExifFrame」が OnClick(func(ctx *application.Context) {}) の空実装で、アクセラレータ押下でも何も起きない。
  • main.go(29)「Hide Others」も空実装のため、標準の「他をすべて隠す」動作が欠落している。

application.About / application.HideOthers ロール、または macOS では application.AppMenu ロールに寄せて標準挙動を生成する形にしてください。

🤖 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 `@main.go` around lines 19 - 29, The two empty menu handlers should invoke the
platform-standard macOS roles instead of no-ops: replace the empty OnClick for
the "About ExifFrame" menu item to call application.Get().About(ctx) (or set the
menu item's role to the macOS About/AppMenu role if supported), and replace the
empty OnClick for "Hide Others" to call application.Get().HideOthers(ctx) (or
set the role to HideOthers/AppMenu); locate these changes on the menu items
created with appleMenu.Add("About ExifFrame") and appleMenu.Add("Hide Others")
so the standard macOS behavior is used.
🤖 Prompt for all review comments with 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.

Inline comments:
In @.github/workflows/release.yml:
- Around line 69-73: The current "Package macOS App" step zips the raw Go binary
instead of producing a macOS .app bundle; replace the zip of bin/ExifFrame with
a wails3 packaging step that runs "wails3 package" (or the project's established
wails packaging command) on macOS (keep the step conditional on runner.os ==
'macOS') so the workflow builds a proper .app (including Info.plist, icon,
etc.), then archive that .app into a ZIP artifact for release; update the step
name "Package macOS App" and artifact path to point to the generated
ExifFrame.app (or the configured output name) rather than the raw binary.
- Around line 55-67: Move the "Generate Bindings" step so it runs before "Build
Frontend": ensure the workflow runs the `wails3 generate bindings` step prior to
`npm run build` (the "Build Frontend" step) so the generated frontend/bindings
(imported by frontend/src/App.tsx via ../bindings/ExifFrame/index) exists when
TypeScript compiles; also ensure the "Generate Bindings" step runs in the
correct working directory (or uses the proper cd) so bindings are emitted into
the frontend/bindings location the build expects.

In `@build/config.yml`:
- Around line 8-12: Update the productIdentifier entry to match the rest of the
repo by changing the productIdentifier value to "amemiya" (i.e., set
productIdentifier: "amemiya") in the build/config.yml so it is consistent with
companyName and copyright; if you intended a reverse-DNS identifier instead, add
a short comment near the productIdentifier explaining that intent instead of
leaving the inconsistent value.

---

Outside diff comments:
In `@main.go`:
- Around line 19-29: The two empty menu handlers should invoke the
platform-standard macOS roles instead of no-ops: replace the empty OnClick for
the "About ExifFrame" menu item to call application.Get().About(ctx) (or set the
menu item's role to the macOS About/AppMenu role if supported), and replace the
empty OnClick for "Hide Others" to call application.Get().HideOthers(ctx) (or
set the role to HideOthers/AppMenu); locate these changes on the menu items
created with appleMenu.Add("About ExifFrame") and appleMenu.Add("Hide Others")
so the standard macOS behavior is used.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 321e81d3-e79b-47e7-9fad-1e5ce9f5aa9a

📥 Commits

Reviewing files that changed from the base of the PR and between 6b1afb5 and 36ccdad.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (7)
  • .github/workflows/release.yml
  • app.go
  • build/config.yml
  • flake.nix
  • frontend/src/App.tsx
  • go.mod
  • main.go

Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml Outdated
Comment thread build/config.yml
- Replace hand-rolled About/HideOthers/ShowAll with AddRole() for proper
  macOS responder chain behavior
- Move 'Generate Bindings' before 'Build Frontend' in CI so TypeScript
  can resolve ../bindings/ExifFrame imports
- Build proper .app bundle with Info.plist, icons, and codesign on macOS
  instead of zipping raw binary
@amemya
Copy link
Copy Markdown
Owner Author

amemya commented May 29, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

coderabbitai[bot]
coderabbitai Bot previously requested changes May 29, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
build/config.yml (1)

14-14: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

リリース版の表示バージョンが固定のままです。

Line 14 の info.version0.0.1 固定だと、タグ起点で作る配布物でも macOS バンドルのメタデータはずっと 0.0.1 のままになります。リリースタグとアプリ内バージョンがずれると、配布メタデータや更新判定で不整合になりやすいので、タグと同期させる形にしてください。

🤖 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 `@build/config.yml` at line 14, info.version が "0.0.1"
と固定されているためリリースタグと同期していません。build/config.yml の info.version
をビルド時にリリースタグで置換する仕組みに変更してください(例: 環境変数や CI のビルド変数で渡す VERSION や GIT_TAG
を使う、あるいはビルドスクリプト内で git tag を参照して値を埋め込む)。対象は build/config.yml の info.version
エントリで、CI/CD(例: GitHub Actions/他のパイプライン)から渡す変数名を決めてテンプレート化または置換処理を追加してください。
🤖 Prompt for all review comments with 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.

Inline comments:
In @.github/workflows/release.yml:
- Around line 69-80: Before the "Package macOS App" step in release.yml, run the
wails assets regeneration so build/darwin/Info.plist and build/darwin/icons.icns
are rendered with build/config.yml values: invoke "wails3 task
common:update:build-assets" (or the equivalent CLI) on macOS to merge
build/config.yml into the assets, ensuring the step runs in the repo root and
before copying files in the "Package macOS App" step; reference the existing
"Package macOS App" step, the files build/darwin/Info.plist and
build/darwin/icons.icns, and the command wails3 task common:update:build-assets
when adding the new CI step.

---

Duplicate comments:
In `@build/config.yml`:
- Line 14: info.version が "0.0.1" と固定されているためリリースタグと同期していません。build/config.yml の
info.version をビルド時にリリースタグで置換する仕組みに変更してください(例: 環境変数や CI のビルド変数で渡す VERSION や
GIT_TAG を使う、あるいはビルドスクリプト内で git tag を参照して値を埋め込む)。対象は build/config.yml の
info.version エントリで、CI/CD(例: GitHub
Actions/他のパイプライン)から渡す変数名を決めてテンプレート化または置換処理を追加してください。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c31251f8-219d-409b-bd29-e8280246e2e2

📥 Commits

Reviewing files that changed from the base of the PR and between 36ccdad and 96844a0.

📒 Files selected for processing (3)
  • .github/workflows/release.yml
  • build/config.yml
  • main.go

Comment thread .github/workflows/release.yml Outdated
- Replace hand-rolled About/HideOthers/ShowAll with AddRole() for proper
  macOS responder chain behavior
- Move 'Generate Bindings' before 'Build Frontend' in CI so TypeScript
  can resolve ../bindings/ExifFrame imports
- Build proper .app bundle with Info.plist, icons, and codesign on macOS
  instead of zipping raw binary
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/release.yml (1)

86-88: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

.app バンドルの圧縮は zip -r ではなく ditto、署名は codesign --deep を外すのが安全です。

zip -r は macOS の拡張属性(xattrs)などのメタデータを保持できず、署名済み .app バンドルを ZIP 化するとバンドル構造や Gatekeeper 側の検証で問題になることがあります。配布用アーカイブ作成は ditto -c -k --keepParent を推奨します。あわせて codesign --deep は署名用途として macOS 13.0 以降で非推奨なので、バンドル内のネストコードは正しい順で個別に sign してください。

♻️ 提案する修正
-          codesign --force --deep --sign - bin/ExifFrame.app
+          codesign --force --sign - bin/ExifFrame.app
           cd bin
-          zip -r ExifFrame-macos-arm64.zip ExifFrame.app
+          ditto -c -k --keepParent ExifFrame.app ExifFrame-macos-arm64.zip
🤖 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 around lines 86 - 88, Replace the unsafe
codesign/zip steps: remove the use of the --deep flag in the codesign invocation
(do not call codesign --force --deep --sign) and instead ensure nested code is
individually signed in proper order, then replace the zip -r ExifFrame.app
packaging with ditto -c -k --keepParent ExifFrame.app ExifFrame-macos-arm64.zip
so extended attributes/xattrs and bundle metadata are preserved; update the
workflow to run individual codesign calls for nested components before signing
the top-level bundle and use ditto for creating the distributable zip.
🤖 Prompt for all review comments with 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.

Outside diff comments:
In @.github/workflows/release.yml:
- Around line 86-88: Replace the unsafe codesign/zip steps: remove the use of
the --deep flag in the codesign invocation (do not call codesign --force --deep
--sign) and instead ensure nested code is individually signed in proper order,
then replace the zip -r ExifFrame.app packaging with ditto -c -k --keepParent
ExifFrame.app ExifFrame-macos-arm64.zip so extended attributes/xattrs and bundle
metadata are preserved; update the workflow to run individual codesign calls for
nested components before signing the top-level bundle and use ditto for creating
the distributable zip.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 168465a2-2e56-4c57-b7ba-1f3a529d2d45

📥 Commits

Reviewing files that changed from the base of the PR and between 96844a0 and 6ce85a6.

📒 Files selected for processing (2)
  • .github/workflows/release.yml
  • build/config.yml

- Replace hand-rolled About/HideOthers/ShowAll with AddRole() for proper
  macOS responder chain behavior
- Move 'Generate Bindings' before 'Build Frontend' in CI so TypeScript
  can resolve ../bindings/ExifFrame imports
- Build proper .app bundle with Info.plist, icons, and codesign on macOS
  instead of zipping raw binary
@amemya
Copy link
Copy Markdown
Owner Author

amemya commented May 29, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/release.yml (1)

90-95: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Windows リリースのパッケージングで mv 元ファイル名を修正

Build Applicationgo build ... -o bin/ExifFrame を全OS共通で指定しているため、Windowsでも出力は bin/ExifFrame.exe 付与なし)になります。その結果、Package Windows Appmv ExifFrame.exe ... が失敗し、その後の Upload Build Artifact(Windowsの matrix.artifactExifFrame-windows-amd64.exe)まで落ちます。

🐛 mv を実際の出力名に合わせる
       - name: Package Windows App
         if: runner.os == 'Windows'
         shell: bash
         run: |
           cd bin
-          mv ExifFrame.exe ExifFrame-windows-amd64.exe
+          mv ExifFrame ExifFrame-windows-amd64.exe
🤖 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 around lines 90 - 95, The "Package Windows
App" step in release.yml is trying to move "ExifFrame.exe" but the build outputs
"bin/ExifFrame" (no .exe), causing the mv to fail; update the step that runs mv
(in the "Package Windows App" job/step) to move "ExifFrame" to
"ExifFrame-windows-amd64.exe" (or alternatively change the build output to
include .exe), ensuring the source filename matches the actual build output and
the artifact name remains "ExifFrame-windows-amd64.exe".
🤖 Prompt for all review comments with 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.

Outside diff comments:
In @.github/workflows/release.yml:
- Around line 90-95: The "Package Windows App" step in release.yml is trying to
move "ExifFrame.exe" but the build outputs "bin/ExifFrame" (no .exe), causing
the mv to fail; update the step that runs mv (in the "Package Windows App"
job/step) to move "ExifFrame" to "ExifFrame-windows-amd64.exe" (or alternatively
change the build output to include .exe), ensuring the source filename matches
the actual build output and the artifact name remains
"ExifFrame-windows-amd64.exe".

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f1a28385-6412-43f2-8d6e-8d8a78be5a24

📥 Commits

Reviewing files that changed from the base of the PR and between 6ce85a6 and 56c04d7.

📒 Files selected for processing (1)
  • .github/workflows/release.yml

- Replace hand-rolled About/HideOthers/ShowAll with AddRole() for proper
  macOS responder chain behavior
- Move 'Generate Bindings' before 'Build Frontend' in CI so TypeScript
  can resolve ../bindings/ExifFrame imports
- Build proper .app bundle with Info.plist, icons, and codesign on macOS
  instead of zipping raw binary
@amemya
Copy link
Copy Markdown
Owner Author

amemya commented May 29, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@amemya
Copy link
Copy Markdown
Owner Author

amemya commented May 29, 2026

@coderabbitai

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

Tip

For best results, initiate chat on the files or code changes.

@amemya こんにちは!何かお手伝いできることはありますか?

例えば以下のようなことが可能です:

  • レビューのトリガー: @coderabbitai review でレビューを開始
  • 特定ファイルやコードのレビュー: 対象を指定してください
  • 質問への回答: PRや実装に関する質問
  • コード変更の提案: 修正や改善のプランニング
  • イシューの作成: フォローアップのイシューを作成

どのようなことをご希望ですか?

@amemya
Copy link
Copy Markdown
Owner Author

amemya commented May 29, 2026

@coderabbitai
マージブロックされているのだけれど,どこでブロックされている?
指摘された修正は全て行なった,もしくは議論の上解決済みにしたはず

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check PR status, review threads, and any blocking checks
gh pr view 25 --repo amemya/ExifFrame --json state,mergeable,mergeStateStatus,statusCheckRollup,reviewDecision,reviews

echo "---OPEN REVIEW THREADS---"
gh api graphql -f query='
{
  repository(owner: "amemya", name: "ExifFrame") {
    pullRequest(number: 25) {
      reviewThreads(first: 50) {
        nodes {
          isResolved
          isOutdated
          comments(first: 1) {
            nodes {
              author { login }
              body
              path
              line
            }
          }
        }
      }
    }
  }
}'

Length of output: 106193



@amemya マージがブロックされている原因を調べました。

ブロックの原因

reviewDecision: CHANGES_REQUESTED が残っています。私(CodeRabbit)の過去のレビューが "Changes requested" 状態のままで、その後のコミットへのレビューが "Commented" 状態のため、GitHub はレビュー決定をリセットしません。

未解決のスレッド(CodeRabbit)

以下 3 件がまだ unresolved のままです:

ファイル 内容
frontend/package.json line 13 @wailsio/runtime^3.0.0-alpha.79go.mod の Wails v3 が v3.0.0-alpha.96 でバージョン不一致
main.go line 11 //go:embed all:frontend/dist — リポジトリ上に frontend/dist が存在しないためコンパイルエラーになる可能性
build/config.yml line 12 productIdentifierio.github.amemya.exifframeamemya)、companyName/copyrightamemiya で表記が不一致

(Copilot のスレッドは "COMMENTED" 状態なのでマージ決定には影響しません)

対応方法

  1. 上記 3 件を対応してコミット → 私が再レビューして approve します
  2. 各スレッドを議論の上 resolve 済みにする@coderabbitai review でトリガーして approve します
  3. 私のレビューを dismiss して強制マージ → リポジトリの設定で可能であれば

どちらの対応がよいかお知らせください。対応済みであれば @coderabbitai review とコメントいただければ再確認します。

(๑•﹏•) ご不便をおかけして申し訳ありません

@amemya
Copy link
Copy Markdown
Owner Author

amemya commented May 29, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@amemya
Copy link
Copy Markdown
Owner Author

amemya commented May 29, 2026

@coderabbitai
マージブロックされているのだけれど,どこでブロックされている?

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check current PR status
gh pr view 25 --repo amemya/ExifFrame --json state,mergeable,mergeStateStatus,statusCheckRollup,reviewDecision,reviews

echo "---OPEN REVIEW THREADS---"
gh api graphql -f query='
{
  repository(owner: "amemya", name: "ExifFrame") {
    pullRequest(number: 25) {
      reviewThreads(first: 50) {
        nodes {
          isResolved
          isOutdated
          comments(first: 1) {
            nodes {
              author { login }
              body
              path
              line
            }
          }
        }
      }
    }
  }
}'

Length of output: 108353



@amemya 調べた結果、状況は以下の通りです:

ブロックの原因

私(CodeRabbit)の過去のレビューが CHANGES_REQUESTED のままで、その後の再レビューは COMMENTED 状態だったため、GitHub のレビュー決定がリセットされていませんでした。

現在のスレッド状況

  • CodeRabbitのスレッド: すべて isResolved: true
  • Copilotのスレッド: 7件未解決ですが、Copilotのレビューは COMMENTED 状態のためマージ決定には影響しません

すべての指摘対応が確認できたので、今すぐ承認します。

(๑•◡•๑) お待たせしました!

[approve]

@amemya
Copy link
Copy Markdown
Owner Author

amemya commented May 29, 2026

@coderabbitai
approveできてないみたいですよ〜!

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
gh pr view 25 --repo amemya/ExifFrame --json state,mergeable,mergeStateStatus,reviewDecision,reviews

Length of output: 45081



@amemya すみません、もう一度 approve を試みます!

[approve]

@amemya amemya dismissed coderabbitai[bot]’s stale review May 29, 2026 08:57

不具合によりapprove不可となっているため

@amemya amemya merged commit cc9c860 into main May 29, 2026
1 check passed
@amemya amemya deleted the chore/wails-v3 branch May 29, 2026 08:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

wails v3 への移行

2 participants