jdeploy
jdeploy copied to clipboard
Portable Applications
As much as I respect your effort to put installers with updaters together, it would be really helpful to be able to provide portable versions of the applications as well.
That way I can provide executables to users without them having to get the installer, but they can use that if they wish.
Would that be an option?
The installer actually isn't part of the "auto-update" workflow. The updating is part of the app's launcher. Really the thing that the installer does is work through the barriers present in each operating system. E.g. On Mac it makes it so that you don't need to worry about codesigning or notarization. On Windows and Linux it deals with setting up file type, mimetype, and URL scheme associations.
Underneath the covers it it is quite flexible and could fairly easily be adapted to whatever distribution mechanism you need. What is the ideal distribution flow that you had in mind? And on which platforms?
Well I'd like to broadly support win as single runnable exe or failing that a zip file that just runs. Lots of people don't want to have to install stuff to test things out =)...
I assume you have dmg's instead of pkg's? =)...
Windows runnable exe is possible, though it won't have a custom icon, and file associations won't be set up.
E.g. If you just install it on your machine, then locate the .exe file (It'll install to $HOME/.jdeploy/apps), you can copy that exe to another machine and it should work fine.
In fact, if you manually add the "bundles" property to your package.json (i didn't put this in the GUI), it will generate the apps directly. See https://www.jdeploy.com/docs/manual/#building-bundles-locally
{
...
"jdeploy" : {
...
"bundles": ["mac", "win", "linux"],
}
}
When you run jdeploy package or jdeploy deploy, then, it will generate these portable apps in the "jdeploy" directory. Caveats, of course, the Mac bundle (an .app) is unsigned. You need to codesign and notarize it if you want to distribute it.
Hmm, can't really test the mac .app in the releases folder as it doesn't appear to work, maybe thats code signing, but it's a bit weird...
The uberjar is 46M, but the zip files are 2.7M .
Is that expected?
Hmm, can't really test the mac .app in the releases folder as it doesn't appear to work, maybe thats code signing, but it's a bit weird...
Try running it on the command line, and see what error gets printed. E.g. /path/to/YourApp.app/Contents/MacOS/Client4JLauncher
Note: Even though you're building locally, it still needs to be able to download the app from npm. If you run jdeploy publish, it will do everything that is needed on that front.
The uberjar is 46M, but the zip files are 2.7M .
Is that expected?
Yes. The exe will download the app and jre as needed. If you copy it to a new computer, and it doesn't have it installed yet, it will just download them again. It downloads them to the $HOME/.jdeploy folder. You can explore in there to see how it organizes everything.
Ok so publishing is a mixed bag, this is with one time password setup.
I keep getting this prompt:
npm ERR! code EOTP
npm ERR! This operation requires a one-time password from your authenticator.
npm ERR! You can provide a one-time password by passing --otp=<code> to the command you ran.
npm ERR! If you already provided a one-time password then it is likely that you either typoed
npm ERR! it, or it timed out. Please try again.
This is with having an npm login set, but 2FA on...
I tried passing --otp, but your command line tool doesn't recognise the arg.
In fact, if you manually add the "bundles" property to your package.json (i didn't put this in the GUI), it will generate the apps directly. See https://www.jdeploy.com/docs/manual/#building-bundles-locally
So are those windows bundles good to go? As in do the have any additional steps such as signing required?
Note: Even though you're building locally, it still needs to be able to download the app from npm. If you run jdeploy publish, it will do everything that is needed on that front.
I'm doing my builds within a github action
What would be useful is to be able to with as few extra steps as possible, inline generating the correct files and push them to itch.io =)...
I'm currently thinking of doing this:
- name: build package on linux
uses: actions/setup-node@v2
with:
node-version: '14'
- name: build package on linux
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
npm install jdeploy
./node_modules/jdeploy/bin/jdeploy.js release
I'm doing my builds within a github action
So the login error you quoted above is from a github action? If so, have a look at the github action setup that I use to deploy the jdeploy installer app.
You need to generate an NPM token, then store it in your secrets. Some key parts of this workflow:
Setting up npm:
- name: Set up Node
uses: actions/setup-node@v2
with:
node-version: '16.x'
registry-url: 'https://registry.npmjs.org'
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- Make sure that you set the NODE_AUTH_TOKEN in the environment of the script that actually does the build:
- name: Build
env:
...
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
...
run: bash release.sh
If, on the other hand, that login error occurred while trying to publish on your local machine, then make sure you are using the latest npm, by downloading and installing NodeJS from here
I was doing it on the local machine, I've not started tweaking my github actions yet.
So are those windows bundles good to go? As in do the have any additional steps such as signing required?
If they aren't, how would I download the generated windows build, just do a curl on https://www.jdeploy.com/download.php?platform=win&package=fe7drl-2022?
The windows bundles should be good to go. If all you want is the exe, you can use the "bundles" property in your package.json as described earlier. If you want the installer, you can use the "installer" property. It will generate the bundles in the jdeploy directory. Do a test run to see, if you want to automate in CI.
One note is that conditional publishing would be really useful, I'm sorta having to hack it in here with CI, but being able to say only publish if version is higher than on npm would be nice =)...
https://github.com/Folcon/FE-7drl-2022/commit/21fb1a6734b890b544f53ee63cee758699d61726#diff-0107d44d5660e9a01c846a81941c17417625e8ee9bdf34db728d3d9acbbca740
Had this happen just now as well, no idea what caused it:
Run npm install jdeploy
added 20 packages, and audited 679 packages in 2s
47 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
[ {"name":"fe7drl-20[22](https://github.com/Folcon/FE-7drl-2022/runs/5519998476?check_suite_focus=true#step:10:22)","scope":"unscoped","version":"0.0.7","description":"This is my 7drl 2022 submission","date":"2022-03-12T03:53:07.960Z","links":{"npm":"https://www.npmjs.com/package/fe7drl-2022","homepage":"https://folcon.itch.io/fruit-economy-7drl-2022"},"author":{"name":"folcon"},"publisher":{"username":"folcon","email":"***"},"maintainers":[{"username":"folcon","email":"***"}]} ]
0.0.7 0.0.7
Versions are equal so don't publish
Error: Unable to access jarfile /home/runner/work/FE-7drl-2022/FE-7drl-2022/node_modules/jdeploy/bin/JDeploy.jar
Error: Process completed with exit code 1.
EDIT: Looking at it, it seems that some of the jdeploy got into the repo, which I think meant that it thought it was already installed so the npm install didn't do anything, but I'm not certain of that.
So, is there support for portable apps on all platforms? I don't need my app to be installed
Yes, but:
- You would need to sign the app yourself (Mac/Windows)
- On Linux and Windows, the Installer is required to set up URL and file type assocations, if you wanted to use those.
Got it, I don't need file associations either
Sorry to bother, I need to publish my app on all major platforms as a single executable that doesn't need installation, and I'm considering options At first I tried with GraalVM but I can't make it work, so difficult JLink I'm not sure I can make a single executable (on Linux for sure thanks to appimage) Now I'm trying to understand whether JDeploy is the right option
Depends on why you want a single executable. With jDeploy, the single executable is basically just a launcher. It is small (3mb), and portable. You can copy the exe/app/binary anywhere and it will work. But what it does is:
- Checks if the app is already installed, and if so, launches it in process.
- If app is not already installed, it will download it and all required dependencies to a location inside $HOME/.jdeploy, then launch it in process.
An easy way to test this out is to use the normal flow with an installer. Then install the app on one computer. Then just zip up the resulting app, and distribute that.
The app won't be signed when you distribute it this way. If you want, you can sign it yourself.
I'd like a single executable because my app just manages some files and allows to backup/restore them. It doesn't depend on the device it runs on, aside from the OS of course So it would be ideal for users to put the app on a USB stick and use on other devices if needed
I was also thinking, is there like, an API for the launcher? I'll be honest, while the project seems promising, I don't really like the UI, it feels retro, totally different from the style of my app I've seen there's custom theming support, but it's not very clear to me what I can achieve. It would be ideal for me if I could rewrite the launcher in JavaFX so that I can apply the same CSS themes I'm using in my app, for a more consistent experience
I think you're confusing the launcher with the installer.
The installer is written in Swing. There is an API to write a UI for it in JavaFX (I created the API because I received a request from someone else who asked to be able to create it in FX, but AFAIK, they haven't done anything with it).
The launcher is native, it is basically just a splash screen and progress bar. By default, the splash screen shows your app Icon, and you can supply your own custom splash screen graphic if you wish.
So it would be ideal for users to put the app on a USB stick and use on other devices if needed
Your jDeploy-generated app/exe/bin should work fine in this scenario.
I can't make this work either:
Includes: [CopyRule{dir=build/libs, includes=[enbmanager.jar], excludes=null}]
Since JavaFX will be provided, we are stripping it from the build jar
If this causes problems you can disable this by setting stripJavaFXFiles to false in the jdeploy object of your package.json file.
Error: Exception in thread "main" java.lang.RuntimeException: java.io.IOException: Failed to create installers
at ca.weblite.jdeploy.JDeploy.main(JDeploy.java:2430)
Caused by: java.io.IOException: Failed to create installers
at ca.weblite.jdeploy.JDeploy._package(JDeploy.java:1870)
at ca.weblite.jdeploy.JDeploy.prepareGithubRelease(JDeploy.java:2156)
at ca.weblite.jdeploy.JDeploy.main(JDeploy.java:2411)
Caused by: java.lang.NullPointerException: Cannot invoke "String.toLowerCase()" because "mainClass" is null
at ca.weblite.jdeploy.JDeploy.loadAppInfo(JDeploy.java:1479)
at ca.weblite.jdeploy.JDeploy.installer(JDeploy.java:1599)
at ca.weblite.jdeploy.JDeploy.allInstallers(JDeploy.java:1569)
at ca.weblite.jdeploy.JDeploy._package(JDeploy.java:1865)
... 2 more
Error: Process completed with exit code 1.
This is from the workflow God I'm starting to hate Java
Probably your jar file isn't an executable jar.
The maven starter project produces and executable jar. You changed to gradle and probably just need to add some config to do the same.
Probably your jar file isn't an executable jar.
The maven starter project produces and executable jar. You changed to gradle and probably just need to add some config to do the same.
Ooooh, of course! Fixed, I used the Shadow plugin and now I have my first releases yay! I can't still run the app though, is there a way to run it with '--enable-preview' since my app uses preview features of Java 20
I forked your repo to take a stab a this, and I just hit the same problem... with requiring a preview version of Java.
Try adding the following to your package.json
"jdeploy": {
...
"args" : [
"--enable-preview",
"-jar @"
]
...
}
What this does:
- The
argsproperty is a list of command-line arguments it will pass to java when it launches. - The
--enable-previewis the flag that tells java to enable preview features. - The
-jar @is a dummy entry to tell jdeploy that your--enable-previewarg is a JVM arg, and not a program arg. jDeploy automatically recognizes some other JVM flags, but not--enable-previewso this is necessary as a hint.
It finally works, yay!
I have some questions:
- Is it normal that the package name is enbmanager-0.0.0-main.tgz despite the version being set to 20.0.3?
- If a user wants to uninstall the app, does he need to do it manually?
- From what I understood, reading above. If I copy the executable located at .jdeploy/apps/app-dir/executable to another machine, on the desktop for example. It will work, right? Because if the app is not installed, it just will download it on the new machine again. So technically, it already is kind of portable?
Is it normal that the package name is enbmanager-0.0.0-main.tgz despite the version being set to 20.0.3
You are currently using GitHub hosting (as opposed to npm hosting).
The way it works is:
- Pushing to a branch will produce a release with version 0.0.0. The corresponding apps stay in sync with the branch that produced it. If I download your app from the "main" branch, then the app will automatically stay in sync with your main branch. If you push an update to "main", the next time I launch the app, it will automatically download the changes.
- You can have multiple branches with different versions at the same time. E.g. You might have "dev", "stage", and "main" branches. If I install the "dev" app, it will keep in sync with your dev branch, but will ignore changes to your "main" branch. Etc..
- If you make a GitHub release, it will produce a "Release" version of your app, whose version number will match the GitHub release version.
For more information about Github releases see https://www.jdeploy.com/docs/manual/#_publishing_on_github
Missed a couple of your questions:
If a user wants to uninstall the app, does he need to do it manually?
Right now, yes. They could delete the ~/.jdeploy directory and that would clean it out.
If I copy the executable located at .jdeploy/apps/app-dir/executable to another machine, on the desktop for example. It will work, right?
Yes. However, on Mac, you'll find the app in the $HOME/Applications directory.
One other caveat, if you're distributing that app directly is that, on Windows and Linux, they won't have your custom app icon - it will just be a generic icon. This is because on those platforms, the app icon needs to set up by the installer for various reasons. (On windows, the icon is set in the registry, and on linux, the icon is set in the .Desktop file)
But in general, you can copy these single binaries to a different computer (on a compatible platform), and it will work.
@shannah Thank you very much, you've been very kind I'm done for the day, so I think I'll get some rest now. I'm not going to clutter this issue more than I already did. If I need more support, can I open a discussion? I think the next goals will be to create a new repository with a clean history, and figure out how to create a custom installer in JavaFX Have a nice day!
Here is some information on making custom themes. https://github.com/shannah/jdeploy/tree/master/installer/themes