-
-
Notifications
You must be signed in to change notification settings - Fork 93
Project Update v5 - Clean Slate #320
Comments
@NicklasTegner @dennisvang |
Fantastic.
In addition, if you need help approving code, managing the documentation, feel free to tag me or any of the sorts. |
@NicklasTegner
Will do a the help is greatly appreciated! |
@JMSwag nice. Looking forward to a roadmap / todo list of some kind. |
@JMSwag Looks like a good plan. :) I particularly like the idea of minimizing third-party dependencies and simplifying where possible. Some steps towards simplifying the code base:
It might also be worth having a discussion about the data structure for the
A clear definition of "release channels" would also help guide further development:
In the meantime I've started fixing some of the issues related to the 4.0 release. I think that's coming along reasonably well, but I've taken a lot of liberty there, as you can see e.g. in PR #316... |
@JMSwag Could you help me understand the reasoning behind the current structure of the version manifest, as in Here's an example what it looks like, currently: {
"latest": {
"Acme": {
"alpha": {"win": "1.0.2.0.0"},
"stable": {"win": "1.0.1.2.0"}
}
},
"updates": {
"Acme": {
"1.0.0.2.0": {
"win": {
"file_hash": "***",
"file_size": 279320368,
"filename": "Acme-win-1.0.0.zip"
}
},
"1.1.0.2.0": {
"win": {
"file_hash": "***",
"file_size": 275047978,
"filename": "Acme-win-1.1.0.zip",
"patch_hash": "***",
"patch_name": "Acme-win-stable-0",
"patch_size": 3063604
}
},
"1.2.0.0.0": {
"win": {
"file_hash": "***",
"file_size": 301965712,
"filename": "Acme-win-1.2.0-alpha.zip"
}
}
}
},
"signature": "***"
} Now, I'm wondering:
The reason I'm asking is this: Following the discussion around issue #255, I'm thinking of an alternative implementation, along the lines of separate manifest files for each app and supported platform, with a simplified, shallower, structure. For example something like this: {
"app_name": "Acme",
"platform": "win",
"signature": "***",
"archives": [
{
"version": "1.0.0",
"hash": "***",
"size": 279320368,
"filename": "Acme-win-1.0.0.zip"
},
{
"version": "1.1.0",
"hash": "***",
"size": 275047978,
"filename": "Acme-win-1.1.0.zip"
},
{
"version": "1.2.0a0",
"hash": "***",
"size": 301965712,
"filename": "Acme-win-1.2.0a0.zip"
}
],
"patches": [
{
"version": "1.1.0",
"hash": "***",
"size": 3063604,
"filename": "Acme-win-0"
},
{
"version": "1.2.0a0",
"hash": "***",
"size": 2487417,
"filename": "Acme-win-1"
}
]
} This puts the version string inside the archive/patch objects, instead of using the version as a key. This may be slightly less convenient, but it ensures that we always know which version corresponds with the object. In addition, JSON objects are unordered, whereas arrays are ordered. We could then do things like: import json
from packaging.version import Version
manifest = json.load(<manifest file defined above>)
current_version = Version("1.0.0")
latest_version = Version("1.2.0a0")
# we can easily collect the patches required to update from current to latest version
required_patches = [
patch for patch in manifest["patches"]
if current_version < Version(patch["version"]) <= latest_version
]
# patches can be sorted like this, whenever necessary
required_patches.sort(key=lambda patch: Version(patch["version"])) To improve cohesion, I'm also thinking about something like a For backward compatibility, the structure above can be converted to a separate file in the old format. What do you think? |
@dennisvang I have always wondered about that myself. As for the application names, that could (but I'm not sure) be because PyUpdater also supports tracking and updating of asset files, hence why I don't think your suggested implementation would work. |
@NicklasTegner Thanks, those are good points. :) |
@dennisvang I coded around my workflow. At the time of writing, I was using PyUpdater by syncing source code to VMs for each supported platform, then building and packaging. Syncing artifacts back to my main dev machine then signing and uploading. This was before the CI/CD craze. When PyUpdater usage picked up and people started wanting to use it in CI, the --split-version option was added. Never needed it personally for my use case. PyUpdater supports versioned assets with are treated as another app internally. |
@JMSwag Thanks for the explanation. That provides some insight into possible workflows for multiple platforms. @NicklasTegner I think it should be possible to use a simplified version manifest like the one I described above. Maybe not exactly the same, but similar. At the very least I think we should aim to remove as much nesting as possible from the manifest (as in my example), or, alternatively, change the order of nesting so that app name and platform are at the top level. I don't think the app name or platform can change within one "session", right? If so, then, both on the client side and on the package-creation side, the app name and platform should only be needed once, viz. at the start of the "session", to load the version data from the manifest for that specific combination of app name and platform. This way, we don't need the For example, version information in the current manifest is nested like this {"updates": {"Acme": {"1.0.0.2.0": {"win": {}}}}} So we need to do It would already be a great improvement if the order were different: {"updates": {"Acme": {"win": {"1.0.0.2.0": {}}}}} Then we could assign I'm convinced a simplification of the manifest structure would greatly improve code readability. |
@dennisvang I concur. |
@dennisvang On Windows you cannot overwrite the exe from a running process. This is a workaround to simulate the behavior on Linux/Mac. |
@JMSwag: Thanks. Does that mean it won't work if you don't hide the file on windows? Another question, to help us understand the reasoning behind the cryptographic approach. As I see it, currently, the I wonder why this approach was chosen, instead of just signing all individual package files? I'm asking because I think removing the hash part, and just signing all files instead, would enable another significant simplification of the code (and workflow). Based on a quick timing comparison, verifying a The relative time difference is large, but it occurs only incidentally: before deploying a new update, on the dev side, and after downloading a new update, on the client side. Moreover, compared with e.g. download time, it can probably be neglected. What do you think? |
@dennisvang NP! It will still work but the old executable will be visible next to the current executable. It was a solution copied form youtube-dl. I was a noob at the time and figured it was sufficient. If signing each file individually simplifies the implementation, I'm all for it! |
@JMSwag Thanks again for clarifying. :-) |
@dennisvang My pleasure 😉 |
@JMSwag @dennisvang how would I start writing code/documentation or anything else for this? Please correct me, if I'm wrong :) |
Also another suggestions. Would it maybe be a good idea to split PyUpdater app updates and PyUpdater assets updates (think it's called library updates) into separate packages, as I think (but I'm not sure) that the majority of people using PyUpdater are using it for the application update capabilities? |
@NicklasTegner you're right, but you can create a new branch in your own fork, for the time being. |
@NicklasTegner Although I've never used the asset update capability myself, I'm not sure it is worth moving it into a separate repo. The asset updates do not require that much extra code. On the client side, On the dev/build/server side (whatever you call it in this context), the actual workflow for creating asset updates is slightly different from that for app updates, but the asset-specific code is mostly limited to True, there is some juggling with app-name/asset-name throughout the rest of the codebase, but that can be taken care of by a simplified implementation of the file manifest. |
@JMSwag @NicklasTegner I suppose it would be useful to create a list of minimum requirements:
Based on that, we could set some targets, etc. Also:
|
That just seems very problematic, if everyone starts writing their own implementation/code. |
I see your point with this comment, but it definitely neds a cleanup :) |
Personally I think it would be very useful to have a few different ideas and implementations to compare. As long as there is no clear tactical plan... |
I'd say that existing functionality is essential. Not sure of anything that could be dropped. We'd want to support any supported version of Python. 3.7+ at this point in time. At a minimum we should support Linux, Mac & Windows. I don't think explicit support for a particular CI/CD is needed as long as PyUpdater is flexible enough to be used in CI/CD. |
any updates on this? |
@JMSwag As a potential user, is the current release fit for use? |
@NicklasTegner While awaiting guidance here, I've been working on an alternative implementation that uses a version manifest structured as a flat JSON array of file-info objects, as follows: [
{"filename": "Acme-win-1.0.zip", "file_size": 12345, "file_hash": "...."},
{"filename": "Acme-win-1.1a0.zip", "file_size": 13456, "file_hash": "...."},
{"filename": "Acme-win-1.1a0.patch", "file_size": 1111, "file_hash": "...."},
...,
] App/asset name, platform, version (and release channel), and file type are parsed from the filenames. App archives, patches, and asset archives, for different platforms and release channels, all co-exist peacefully in the same array. No nesting. Although the work is far from finished, I am about ready to publish to my fork. At the very least, I'm hoping that will spark the discussion here. |
@dennisvang @NicklasTegner I think I've responded to the outstanding questions. Please let me know if otherwise. |
@JMSwag I guess above comment from @NicklasTegner is the only one that has not been answered yet. :-) I think the main question is: How would you like to proceed? Do you have any specific tasks in mind that we could work on? |
@JMSwag @NicklasTegner It turns out python-tuf, i.e. the reference implementation for TUF (The Update Framework), has recently reached version 1.0.0, and is now production-ready. I'm just wondering, would it be an option to build on top of that? It would allow pyupdater to focus on high-level functionality. |
@dennisvang seems like a fantastic idea |
Any updates on the progress of v5? Very interested in building on top of this! Thanks! |
Any updates? |
Project is dead |
Hey All,
v4 was a cluster of my own making. Essentially not giving the project enough of my time. My sinceriest apologies. There is some good news though. I've finally got over my fear of front end development and have been learning quiet a lot in that area and have some cool projects under my belt. I finally feel like a half way complete developer. 😅
I initially wrote this project while learning how to code. Shotly after going though learn python the hard way. Shout out to Zed Shaw.
Ok let's get down to business.
Lots of thinks I'd like to improve on.
PyUpdater v5 will be a clean break, saving the good stuff. Thinking in the since of a toolkit where parts are easily replaced.
Gaols
Questions / Comments / Concerns are very welccome.
The text was updated successfully, but these errors were encountered: