Software upgrade software suggestion?

#1

We are looking for a tool that can upgrade the Windows software system we develop, replacing the cumbersome and error prone method we currently use.

Our current process is a combination of batch, powershell, and Groovy scripts that literally copy/replace files, does SED text replacements, and unzips new/overwrites files to their destination. Obviously this is extremely time consuming to maintain and prone to human error.

Can anyone suggest a system that can patch by possibly analyzing a before and after system state, producing some diff that is applied to an existing installation?

Our system is several web services running as Windows serviced, some old native x64 code, a pretty simple db, single machine install target.

We have these requirements:

  • Windows

  • Can analyze old system and new and produce some diff that can upgrade older versions (doesn’t need to function exactly like this, but all I can envision atm). Something semi or mostly automated.

  • Allows for some logic control, say “my version is detected as xyz, so add this or that, or delete this but not that”

  • Can delete/replace/add files/dirs

  • Offline mode only!! My searches revealed countless systems that are both CM and deployment, but do so via online deployers. Our environment is a private closed network, that never sees the web or any other network.

  • Hopefully not relaint on specific cm or build processes.

Thank you

#2

I would take a look at Octopus Deploy and see if that meets your needs, I know they have a self hosted version.

Though I would seriously take a look first at revamping the app(s) to separate your data, config and code directories so you can just do a straight replace. This removes most of the error prone behavior you probably observe.

#3

Forgive me if you already know this stuff and I’m teaching you to suck eggs…

What you are describing is automated build and continuous integration. The idea is that you write a build process that is in code, typically using some kind of interpreted and/or DSL (domain specific language) dedicated to this purpose. Your build process becomes just another code file that you include in your project, you store and manage versions in the same way as your other code (ala Git/SVN etc). Every code change that you commit to your project the build process is automatically executed and and the build process itself and resulting binaries (artifacts) are tested. Obviously this method has some initial setup overhead.

CI typically adheres to a few rules:

  1. Always build directly from source (never copy/replace existing binaries)
    Your code should always be your single source of truth.
  2. Build binaries in a clean environment, ideally on a machine specifically dedicated to this task and then deploy to your test/production environments
    This allows you to manage linked dependencies and prevent contamination from development environments

For build DSLs you have many options. I like to use Gulp/JavaScript (or TypeScript) as a task runner/build language. If you’re using C# then Cakebuild is popular.
https://www.npmjs.com/package/gulp
https://cakebuild.net/

For CI servers you have many options. I like to use Jenkins as it’s free but CircleCi is also very popular.
https://jenkins.io/
https://circleci.com/

For databases you’ll want to use migration scripts. Again, these scripts should be included along with your other project code. The migration script tool depends on which database/ORM you’re using.
https://en.wikipedia.org/wiki/Schema_migration

If you’ve read all this and you’re shaking your head at it all then you might be able to cobble something together using Advanced Installer. I don’t recommend this approach at all though. You’re much better off biting the bullet and creating a proper CI process.
https://www.advancedinstaller.com/

Hope this helps :)

#4

Good information. I forgot to mention our CI environment, as that certainly would be useful to know. We use RTC (Rational Team Concert) through Eclipse, with typical CI cycles including nightly SNAPSHOT builds and installers (InstallShield).

Our problem mostly revolves around one customer, of many, that requires a custom build comprised of a baseline version that’s several months/years old that also contains features they hand-pick from the main dev baseline. This customer usually requires patches to existing installations instead of upgrading to the latest version or a pinned older version. Adding to this mess is their private network, which we can never see or access.

Thus, we deliver this customer a patch of what I originally described, a suite of scripts that cobbles together a custom version by copying/deleting/overwriting/SEDing around the installation. These scripts interrogate existing files to determine upgrade course. Our thought was that we’d find a tool that could create a patch of a BEFORE and AFTER state (we know what they have installed and know the Frankenstein build they are upgrading to) relieving us having to maintain our fugly upgrade scripts.

#5

I’m sorry. That sounds horrific - I have dealt with similar problems but that is taken to 11.

Have you looked at git? There are many similarities between what it does and what you described as needing. So for your problem company you could create a branch that they can switch to and merge and patch as needed. But git can get quite complicated just by itself, though the new good news is it’s hard to permanently shoot yourself in the foot.

This seems like an extreme abuse of git but I got nothing else except my original point - you need to separate out everything that changes per deployment (your state) from that which does not (immutable) before things would ever approach sanity.

#6

I am barely following recent DevOps developments but if you are deploying/updating a server application I think Docker might be useful to you. Docker is mostly used on Linux so check out https://blog.sixeyed.com/how-to-dockerize-windows-applications/ for a windows specific example. If it is a desktop application you might consider some kind of disk imaging tool like clonezilla requiring you to separate your application and it’s data to different partitions.

Overall I think you would benefit from using images instead of worrying about diff scripts for upgrade/downgrade. If it is impossible to separate the application and it’s data, meaning the application image cannot be upgraded without messing with the data then you could possibly set up a VM environment where you could take snapshots before and after updating.

#7

Thanks all, I’ll look into all of your suggestions.