-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/mac sandbox pre release pyinstaller #7803
Conversation
PyInstaller has [recently][symlinks] landed a change that should restore the webengine sandbox on macOS builds. With a bit more testing we are hoping that we can go ahead releasing builds based on that in-development PyInstaller codebase even before they've made a release. This commit pins our pyinstaller dependency to be the latest commit on their develop branch. [symlinks]: pyinstaller/pyinstaller#7619
Since we are pulling down PyInstaller off of the develop branch we need to recompile the bootloader, because upstream only commits a new one back to the branch on releases. Luckily all the compiler requirements seem to already be installed on CI. For the record the macOS CI is currently failing with dlopen: dlopen(/Users/runner/work/qutebrowser/qutebrowser/dist/qutebrowser.app/Contents/MacOS/libpython3.10.dylib, 10): image not found And upon inspection of dist/ that file seems to be at ./qutebrowser.app/Contents/Resources/libpython3.10.dylib ./qutebrowser.app/Contents/Frameworks/libpython3.10.dylib ./qutebrowser/_internal/libpython3.10.dylib
pyinstaller patches importlib_resources now so it should transparently handle this special case for us. ref: https://pyinstaller.org/en/stable/CHANGES.html?highlight=importlib.resources#id94
Not that we are looking up resources via importlib_resources for pyinstaller builds too we need to change where the data files are installed to to match what importlib_resources is expecting. There was a comment in the previous resource lookup special case complaining about the data files being at the top level so it seems this is a change for the better anyhow. Observed paths: requested file: qutebrowser.app/Contents/Frameworks/qutebrowser/config/configdata.yml actual file : qutebrowser.app/Contents/Frameworks/config/configdata.yml
In the past various workarounds have been put in place to move/copy/symlink files in the macOS app build to make PyQt work and let us sign it. As of pyinstaller/pyinstaller#7619 our downstream patching should not be required. The application seems to run fine. The app size is 155 MB. Signing is still to be verified.
92fb2d9
to
4ff4b70
Compare
I've pushed again to:
While looking through the spec file I saw this note and that the comment it refers to was removed a couple of years ago in pyinstaller/pyinstaller@af23dcceb3f997bda40. So it might not be needed anymore. I'll update the PR description with potential testing notes based off of looking through the spec file. |
This looks like a work-around for PyInstaller butchering the It should be safe to replace that ID with your actual bundle ID now that the .framework bundles are preserved. |
Trying to switch the bundle ID again and see if that makes things work. Will need to check 5.15 too. ref: #7803 (comment) Closes: #5180
I updated the bundle ID and went through my manual testing stuff and everything seemed to work 🎉. Although I'm not sure how I'm supposed to reproduce the original failure, did it just stop the app from starting? Also realized there is the macOS sandbox warning page which is probably unneeded now? Or at least should have references to the PyInstaller issue removed. More interestingly the extensions are no longer being loaded on macOS. Resulting in messages like: "scroll-to-perc: no such command" and "reload: no such command".
However The workaround of using the PyInstaller importer toc manually (removed in dd2fc8e) seems like it'll still work though:
|
Restored from dd2fc8e Now that we are putting our data files in the qutebrowser/ directory again pkgutil/importlib is getting confused by that dir existing and returning us a FileLoader for `qutebrowser.components`, I think that's what's happening anyway. Should try reverting that and this commit and see if extensions get loaded right again. So bring back this workaround of using the toc on the PyInstaller loader to get the list of component modules for now. ref: #7803
Now that we aren't patching the build we shouldn't have to try to re-sign in.
Trying to switch the bundle ID again and see if that makes things work. Will need to check 5.15 too. ref: #7803 (comment) Closes: #5180
Restored from dd2fc8e Now that we are putting our data files in the qutebrowser/ directory again pkgutil/importlib is getting confused by that dir existing and returning us a FileLoader for `qutebrowser.components`, I think that's what's happening anyway. Should try reverting that and this commit and see if extensions get loaded right again. So bring back this workaround of using the toc on the PyInstaller loader to get the list of component modules for now. ref: #7803
2a5e5b7
to
906d5b4
Compare
Restored from dd2fc8e Now that we are putting our data files in the qutebrowser/ directory again pkgutil/importlib is getting confused by that dir existing and returning us a FileLoader for `qutebrowser.components`, I think that's what's happening anyway. Should try reverting that and this commit and see if extensions get loaded right again. So bring back this workaround of using the toc on the PyInstaller loader to get the list of component modules for now. ref: #7803
906d5b4
to
e468766
Compare
Thanks for all the great work, this definitely gets us a big step closer! <3
Works for me.
Nice catch!
I do indeed to ensure I have a consistent environment with everything it needs. So I suppose dd86483 and 8a327be could be reverted?
I believe renderer processes just didn't start, yeah.
Yep, reverting that was the right call IMHO!
That's weird! Might be good to try and see if we can get a more minimal reproducer to report this as a PyInstaller regression? pyinstaller/pyinstaller#5959 comes with a testcase which hasn't had any changes and still seems to pass, so I'm not sure what it is that we do differently? |
I don't want to deal with having to review development changes of pyinstaller every week. So pin to one commit for now that we can actually test. I'm subscribed to release notifications on github so I'll manually change this back to point to the pyinstaller pypi package ones it does.
Trying to switch the bundle ID again and see if that makes things work. Will need to check 5.15 too. ref: #7803 (comment) Closes: #5180
Restored from dd2fc8e Now that we are putting our data files in the qutebrowser/ directory again pkgutil/importlib is getting confused by that dir existing and returning us a FileLoader for `qutebrowser.components`, I think that's what's happening anyway. Should try reverting that and this commit and see if extensions get loaded right again. So bring back this workaround of using the toc on the PyInstaller loader to get the list of component modules for now. ref: #7803
…e_release_pyinstaller Only conflict was the removal of support for 32bit builds in build_release.py
e468766
to
98e0a37
Compare
Alright, last call for comments on this one! Latest changes:
Too old win10 warning (before I dropped the requirement lower): Error dialog on launch after installing the Qt5 version over the Qt6 version: Testing the autoselect logic with the above issue (after starting with Tomorrow I'll look at doing a new test case for pyinstaller and move to main my changes around getting better smoke test error logs, but that's all the stuff I have planned for this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bitraid could you give this a look?
@@ -1 +1 @@ | |||
PyInstaller | |||
pyinstaller @ git+https://github.com/pyinstaller/pyinstaller.git@79f62ef29822169ae00cd4271390d0e3175476ad |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you plan on doing another round of testing with your latest changes, maybe worth bumping up this again? If you'd rather not, I'm fine with that too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've done more testing but I don't plan on updating the commit. I've been checking in on subsequent commits and I don't see anything relevant to us.
def _walk_pyinstaller() -> Iterator[ExtensionInfo]: | ||
"""Walk extensions when using PyInstaller. | ||
|
||
See https://github.com/pyinstaller/pyinstaller/issues/1905 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to self, we still should try to figure out whether this has regressed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it has, but I'm not sure if we can test it on an old version because of the workarounds we had to do symlinking stuff around. I suppose this might be an issue with the upstream fix for that stuff breaking this use case.
This only started happening with c0d31d3 where the data files changed to be under /Frameworks/qutebrowser/
. That's the same path that the python files are reported to be under so the issue is that somehow the /Frameworks/qutebrowser/
folder existing is causing importlib to use the file loader instead of the frozen ones. But it seems to work fine on Windows (TODO: triple check with https://github.com/qutebrowser/qutebrowser/actions/runs/5846907490), so it might be some mac specific workaround going wonky.
I tried to make an upstream test fail here, but it didn't. I think the script in that test as the right structure (a folder with data files at the same level as a folder with python files). I might switch tack and try to do a minimal reproducer based on qutebrowser (including spec file).
Anyway, I don't intend to treat this oddity as blocking (I really want to see all the nightly tests working again!). So I'll probably merge this PR tomorrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be fixed by pyinstaller/pyinstaller#7885.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like that fixes it indeed. Data files and dynamic modules are both being loaded fine with no special casing for frozen builds from us! Yet another issue that gets solved with me doing nothing but procrastinating 😂
I just did a quick build to check. Will double check in more detail tomorrow.
As for the "empty PyQt6 dir" thing: I've seen that too, and considered changing the logic to account for that - but then decided this is one of the "user's environment is in a weird inconsistent thing" situations I'd much rather report to the user rather than just painting over it and assuming something. |
The Qt docs for 6.5 say that the minimum supported version is Windows 10 1809. Experimentally it seems qutebrowser and it's dependencies work fine on a version as early 1607. There should be no change in OS version requirements for the Qt5 build, although we've dropped 32 bit support already and in a future version of the installer we may bring the minimum OS version support in line with the Qt6 requirements for simplicity too. Added a new QT5 version into the NSIS scripts so we can do the different version check per installer build. It just uses the python bool serialization format so should always be "True" or "False", but I've added a fallback anyway for consistency.
We dropped 32bit support in #7804 and as a result removed the arch suffix from the binary that pyinstaller produces. This commit removes it form the lookup path in the installer too. Note that we are leaving the arch string in the installer itself for now. Mostly because it'll be removed as part of a later change when the installer itself is refreshed. But it might also be useful to clarify in the installer names what the arch is? Maybe, that reasoning might not fit with the previous change to remove the arch strings.
The CheckPlatform macro will prompt the user user to use the 32bit installer if they are on a 32bit system. But we don't provide a 32bit installer anymore. This commit changes the OS version check for Qt5 builds to be based on checking version numbers ourselves too, so that we can have our own error message. Also moves the Qt5 conditionals to be compile time ones.
98e0a37
to
7599dbc
Compare
Switch to PyInstaller develop branch to get v6.0 changes which brings:
This is a pretty standard adaptation to a new major version of a dependency except in this case the major version isn't released yet, so I'm pointing at a specific commit on their develop branch (the latest commit as of today).
In my opinion we probably want to do a little more testing of the resulting binaries before committing to this. Although I don't think the testing surface area is huge? Like it runs, resource files can be loaded, it can be signed? There are binaries here, based of this test branch with a custom CI job.
Potential testing checklist:
TODO:
Should I, GitHub, should I? 🤔
Testing (it seems userscripts are not packaged):
Windows (10)
* tested with jitsi meet
* https://www.ipcc.ch/site/assets/uploads/2021/06/Fact_sheet_AR6.pdf
* the reload command is registered
macOS (11.7.8)
* tested with jitsi meet
* https://www.ipcc.ch/site/assets/uploads/2021/06/Fact_sheet_AR6.pdf
* the reload command is registered
Closes: #7278