Skip to content

Build and publish safari browser extension - #681

Open
Siedlerchr wants to merge 62 commits into
mainfrom
safari
Open

Build and publish safari browser extension#681
Siedlerchr wants to merge 62 commits into
mainfrom
safari

Conversation

@Siedlerchr

@Siedlerchr Siedlerchr commented Jun 21, 2026

Copy link
Copy Markdown
Member
  • Create and publish and sign + notarize safari browser extensio
  • Safari extensions require some native code wrapper around the extension and need to be notarized + signed
  • native messaging happens via a Safari WebExtension Swift Bridge
  • After converting the browser code to an Xcode project, replace the Swift content and make sure our stuff is correctly added
  • Safari requires a background.html page and does not support all manifest JSON entries
  • Locally tested with Safari 26.5.2 on macOS Sequoia
  • Native messaging requires a signed and ideally notarized version of JabRef
  • Native messaging works best when JabRef is started, it can start JabRef and then will try to pass the command arguments (due to sandboxing)

@Siedlerchr
Siedlerchr requested a review from tobiasdiez June 21, 2026 19:19

@tobiasdiez tobiasdiez left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks a lot!

Looks like this PR contains a few unrelated/unnecessary or otherwise strange changes (AI generated??). Can you please revise this, or at least explain the need for the changes.

The main issue is the whole scripts/makefile setup. In the wxt world, you solve this by "modules" that hook into the build progress and modify/postprocess the output. You might be able to reuse https://github.com/rxliuli/wxt-module-safari-xcode or at least get inspiration how its done.

Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/test.yml Outdated
Comment thread src/entrypoints/options/index.html Outdated
Comment thread wxt.config.ts
},
commands: {
_execute_page_action: {
_execute_action: {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

please revert

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Chrome was giving me warnings about this

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

safari is giving me errors with this

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There is a conceptual difference between an action and a page action...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Maybe but it's not working in safari. I tested all other browsers, they work

Comment thread wxt.config.ts
},
description:
"The JabRef browser extension imports new bibliographic information directly from the browser into JabRef.",
developer: {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why this change?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not supportes

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

for safari maybe... did you tested the other browsers?

Comment thread wxt.config.ts
@tobiasdiez

Copy link
Copy Markdown
Member

TODO: Deployment to Apple developer/registering of the extension

Can you do this please, and then configure the securities in the gh actions to actually be able to test the publish/notarize workflow.

@Siedlerchr

Copy link
Copy Markdown
Member Author

Uploading to apple app store connect works now.
Manual publishing the artifact requires some addtional setup now

@tobiasdiez

Copy link
Copy Markdown
Member

So you went through the code and reviewed/agreed with all those changes yourself? I don't want to invest a lot of time in reviewing AI created nonsense.

@Siedlerchr

Copy link
Copy Markdown
Member Author

I reviewed and tested all generated code. I added some more explanations to the Swift Bridge and its purpose

koppor added a commit to JabRef/JabRef-Browser-Extension-experimental that referenced this pull request Jul 29, 2026
Safari build/publish. The PR merges cleanly upstream; the conflicts are
sibling collisions on this integration branch, resolved as unions:

- release.yml, test.yml: #681 turns publish into a matrix over
  browser-stores/safari/safari-distribution, so the experimental artifact
  upload is now gated on the browser-stores target - it is the only one
  producing .output/*.zip. build-bridge, attach-bridge, bridge-smoke and
  experimental-prerelease keep their own jobs.
- package.json: experimental's newer vue/vue-tsc/wxt over #681's older
  base, plus its esbuild, spawn-sync and wxt-module-safari-xcode.
- pnpm-lock.yaml: regenerated with pnpm 10.34.1 rather than hand-merged.
- README.md: both new sections kept.
- safari-signing-test.yml: new in #681; git's modify/delete was rename
  detection, the file exists at neither the merge base nor experimental.

Verified: pnpm install --frozen-lockfile and vitest (1420 passed).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AiaGjSfwh9uqDGtbW8tLfU
Siedlerchr and others added 2 commits August 2, 2026 20:32
Conflicts were the version bumps main made to the pnpm/setup-node steps
this branch replaced with the setup-browser-extension composite action:
kept the composite action and moved the bumps into it, so it matches
lint.yml. package.json takes main's vue, typescript, vitest and wxt and
keeps this branch's esbuild, spawn-sync and wxt-module-safari-xcode;
pnpm-lock.yaml regenerated.

One fix beyond the conflicts, needed because main is now on wxt 0.21:
wxt 0.21 resolves `modules` entries with Node's import.meta.resolve,
whose importer argument is ignored, so the relative module paths
resolved inside wxt itself and `wxt prepare` failed. Absolute file URLs
work in both versions.

Verified: pnpm install, pnpm lint, pnpm test (1420 passed), pnpm build.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015DK61Z1E3cKxFbEun5UdD6
koppor pushed a commit to JabRef/JabRef-Browser-Extension-experimental that referenced this pull request Aug 5, 2026
@tobiasdiez
tobiasdiez requested a lite review from Copilot August 5, 2026 21:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The Safari native bridge currently relies on launching /Applications/JabRef.app/... from a sandboxed app/extension, which is likely to fail under App Sandbox constraints and break native messaging in production.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

This PR adds a Safari build pipeline for the JabRef Browser Extension, including WXT Safari/Xcode project generation, local signing/notarization helpers, and GitHub Actions workflows to package and publish the Safari app.

Changes:

  • Add Safari as a WXT target and generate an Xcode project/app bundle via wxt-module-safari-xcode, with post-processing hooks.
  • Introduce local scripts + entitlements for signing and notarization, plus documentation for Safari build/release steps.
  • Extend CI/release workflows to build, package, notarize, and publish the Safari extension (and upload a direct-distribution artifact).
File summaries
File Description
wxt.config.ts Adds Safari target, Safari Xcode configuration, and WXT module pipeline for Safari build/project patching.
scripts/sign_safari_local.sh Adds local Developer ID signing script for the generated Safari .app.
scripts/notarize_safari_local.sh Adds local notarization + stapling + zip packaging script for the signed Safari .app.
scripts/SafariWebExtensionHandler.swift Adds a Swift native-message bridge handler for Safari WebExtension native messaging.
scripts/JabRef Browser Extension.entitlements Adds app entitlements used during signing.
scripts/JabRef Browser Extension Extension.entitlements Adds extension entitlements used during signing.
README.md Documents Safari dev/build/sign/notarize flows and CI/release secret requirements.
CONTRIBUTING.md Adds Safari dev/build instructions plus CI/notarization notes.
modules/jabref-safari-prepare.module.ts Post-processes Safari build output (manifest cleanup + background page generation + staging).
modules/jabref-safari-xcode.module.ts Copies the Swift handler into the generated Xcode project after build.
package.json Adds Safari scripts (dev/build/app packaging/sign/notarize/zip) and adds Safari module dependency.
pnpm-workspace.yaml Allows pnpm build scripts for esbuild and spawn-sync.
pnpm-lock.yaml Locks new dependencies (notably wxt-module-safari-xcode, esbuild, spawn-sync).
.github/workflows/test.yml Adds a macOS matrix job to validate pnpm safari:build-app.
.github/workflows/release.yml Adds Safari packaging, signing, notarization, App Store Connect publishing, and release asset upload.
.github/workflows/safari-signing-test.yml Adds a manual workflow to test Safari signing/publish without modifying releases.
.github/actions/setup-browser-extension/action.yml Adds a composite action to standardize Node/pnpm setup across workflows.
Review details

Suppressed comments (1)

.github/workflows/release.yml:205

  • This checkout step pins actions/checkout to v6.0.3, but the workflow also uses v7.0.1 in other jobs. Prefer a single pinned SHA/version across the workflow for consistency and security updates.
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
  • Files reviewed: 16/17 changed files
  • Comments generated: 3
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Comment on lines +227 to +239
let process = Process()
process.executableURL = executableURL
process.arguments = arguments

let stdout = Pipe()
let stderr = Pipe()
process.standardOutput = stdout
process.standardError = stderr

do {
try process.run()
} catch {
throw JabRefBridgeError.processLaunchFailed(error.localizedDescription)

@Siedlerchr Siedlerchr Aug 11, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Apple App Store does not accept extensions without sandbox, only locally it is possible. so the extension can still use the http endpoint
@koppor Maybe we can solve this with the bridge in future ?

Comment thread .github/workflows/safari-signing-test.yml Outdated
Comment thread .github/workflows/release.yml Outdated

@tobiasdiez tobiasdiez left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sorry that it took me so long to review, but honestly speaking it's AI slop at its finest. I never understood why you guys were so annoyed by AI-created PRs in the JabRef repo, but now I better understand the pain.

My comments are perhaps formulated a bit meaner/more direct than if I were to address a person. I hope Claude can look over this.

Comment thread package.json Outdated
Comment thread .github/workflows/release.yml Outdated
Comment on lines +238 to +241
- name: Build Safari app
if: ${{ matrix.target == 'safari' && github.event_name != 'pull_request' }}
run: pnpm safari:build-app

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you please walk me through how this works together with the step "Download signed Safari distribution artifact" and the safari-webext-publish-action action in the next step.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We first build the *.app which is the foundation for both local distribution and app store distribution
However, they require different notarization and entitlements
And we separet notarization as its own job so it can be requeue when it fails for some reason. Can happen when apple is having issues

Comment thread .github/workflows/safari-signing-test.yml
Comment thread .github/workflows/test.yml Outdated

- name: Build Safari app
if: ${{ matrix.target == 'safari-build' }}
run: pnpm safari:build-app

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Always a good idea to have 3 workflows to run the same command...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Different workflows serve different purpose

Comment thread .github/workflows/test.yml Outdated
Comment thread README.md
Normally, you simply install the extension from the browser store and are ready to go.

> [Firefox](https://addons.mozilla.org/en-US/firefox/addon/jabref/?src=external-github) - [Chrome](https://chrome.google.com/webstore/detail/jabref-browser-extension/bifehkofibaamoeaopjglfkddgkijdlh) - [Edge](https://microsoftedge.microsoft.com/addons/detail/pgkajmkfgbehiomipedjhoddkejohfna) - [Vivaldi](https://chrome.google.com/webstore/detail/jabref-browser-extension/bifehkofibaamoeaopjglfkddgkijdlh)
> [Firefox](https://addons.mozilla.org/en-US/firefox/addon/jabref/?src=external-github) - [Chrome](https://chrome.google.com/webstore/detail/jabref-browser-extension/bifehkofibaamoeaopjglfkddgkijdlh) - [Edge](https://microsoftedge.microsoft.com/addons/detail/pgkajmkfgbehiomipedjhoddkejohfna) - [Vivaldi](https://chrome.google.com/webstore/detail/jabref-browser-extension/bifehkofibaamoeaopjglfkddgkijdlh) - Safari (build from source)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I thought you have publishing to the apple store now working?

@Siedlerchr Siedlerchr Aug 6, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Publishing to the apple store will require review from apple. This is an alternative way to provide the extension for download as a simple app

Comment thread README.md Outdated
Comment thread wxt.config.ts Outdated
Comment thread wxt.config.ts
},
commands: {
_execute_page_action: {
_execute_action: {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There is a conceptual difference between an action and a page action...

Comment thread wxt.config.ts
},
description:
"The JabRef browser extension imports new bibliographic information directly from the browser into JabRef.",
developer: {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

for safari maybe... did you tested the other browsers?

Siedlerchr and others added 7 commits August 11, 2026 22:28
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* origin/safari:
  Potential fix for pull request finding
  Potential fix for pull request finding
@Siedlerchr

Siedlerchr commented Aug 11, 2026

Copy link
Copy Markdown
Member Author

First of all, thanks for the review, but you are still talking to a human.

Sorry that the PR quality is not the best; my focus was on getting it working first. I reviewed and tested the changes and also verified with firefox/chrome.
And I used AI assistance to help me get it working because I am not an expert in JS/wxt config browser stuff. And it after trying out stuff based on your feedback, it seems the approach was not that bad.

Regarding page browser actions, seems like your knowledge regarding manifestv3 is not up to date
https://developer.chrome.com/blog/mv3-actions
Same applies for the developer key entry

* origin/main:
  docs: add git submodule hint (#697)
  chore: add .idea to .gitignore (#698)
  chore(deps): update dependency oxfmt to v0.61.0 (#709)
  chore(deps): update dependency vue-tsc to v3.3.8 (#705)
  chore(deps): update tailwindcss monorepo to v4.3.3 (#707)
  chore(deps): update dependency globals to v17.9.0 (#719)

# Conflicts:
#	CONTRIBUTING.md
#	package.json
#	pnpm-lock.yaml
* main:
  fix: Chrome native messaging (#700)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants