Update Process: How Is the Software Updated?

[!WARNING] This part of the documentation is only lightly maintained. Content may be out of date or may have been partially generated by AI and could therefore contain errors.

Concept: Automatic Updates Without Data Loss

The updater downloads new versions from GitHub without deleting user data:

User clicks "Check for Updates"
        ↓
Updater checks GitHub Release API
        ↓
       New version found?
    ↙              ↘
  Yes              No
  ↓                 ↓
Download        No change
+ Extract
  ↓
Migration:
  New keys → config
  User values remain
  Old keys → delete
  ↓
Restart → Done!

Updater Architecture

GitHub Release (Tag = Version)
    │
    ├─ version.txt          (Tool Version + Updater Version)
    ├─ update.exe            (self-updatable updater)
    ├─ app.exe               (main program)
    ├─ core/                 (plugins, runtimes)
    ├─ config.default.yaml
    └─ README.md
         │
         ↓ (Download + Extract)
    _update_tmp/             (temporary)
         │
         ↓ (version check)
    Updater self-update?
         │
         ↓ (No or Done)
    Copy files to ./core/    (with whitelist)
         ↓
    config/config.yaml migration
         ↓
    Update version.txt
         ↓
    Restart

Update Flow: 3 Scenarios

Scenario 1: Normal Update

1. Download release (.zip from GitHub)
2. Extract to _update_tmp/
3. Check: read version.txt
4. If updater itself is new: copy update.exe → update_new.exe
5. Start update_new.exe with --resume _update_tmp/
6. (Updater restarts itself)
7. Then update app.exe

Scenario 2: Updater Needs to Update Itself

1. Check: UpdaterVersion in release > local version?
2. Yes → update.exe → update_new.exe
3. Run update_new.exe with --resume
4. Old process ends
5. New process continues
6. (Prevents conflict when updating the running .exe)

Scenario 3: Config Migration

1. Check: config_version in default
2. Is it greater than in user?
3. Merge new keys from default
4. User values are retained
5. Old keys are deleted

Version Format

# version.txt
ToolVersion: 1.2.3
UpdaterVersion: 1.0.2

# Regex pattern (accepted):
# 1.2.3
# 1.2.3-beta
# 1.2.3-alpha
# 1.2

# Comparison: "1.2.3" > "1.2.0" = True
# Comparison: "1.2.3-beta" > "1.2.3" = False (pre-release is older)

What Gets Overwritten?

WILL be overwritten (safe):

  • core/ (EXEs, runtime)
  • config/config.default.yaml (it's just a template)
  • Plugin EXEs in core/
  • Documentation (README)

WILL NOT be overwritten (user data!):

  • config/config.yaml (your settings)
  • data/ (counters, logs, states)
  • plugins/ (user plugins)

Checklist: Update-Safe

  • ☑ Important user data in ./data/
  • ☑ Configuration only in config/config.yaml
  • version.txt updated after release?
  • ☑ GitHub release tagged correctly?
  • ☑ Beta releases work with confirmation?

Back to Appendix

The updater downloads the current version from GitHub, unpacks the release package, and copies the released files to the target directory.

The following basic rules apply:

  • User data must not be overwritten.
  • The updater reads the local version from version.txt.
  • The configuration is loaded from config/config.yaml at startup.
  • The updater works within the directory where the EXE is located.
  • The release package is downloaded as a .zip from GitHub.
  • The update logic differentiates between tool version and updater version.

Expected Files and Paths

The updater uses these local paths:

  • version.txt
  • config/config.default.yaml
  • config/config.yaml
  • _update_tmp/ as a temporary working directory

Additionally, it uses the GitHub Release API for this repository:

  • TechnikLey/Streaming_Tool

GitHub is accessed via the latest release API.
For API and asset requests, an optional GITHUB_TOKEN can be loaded from the environment.


Version Management

The file version.txt contains two entries:

  • ToolVersion
  • UpdaterVersion

The updater reads both values and compares them with the versions from the current GitHub release.

Version evaluation uses a regex pattern that detects versions in these formats:

  • 1.2.3
  • 1.2
  • 1.2.3-beta
  • 1.2.3-alpha

If the online tool version is not newer than the local tool version, the updater exits without making any changes.


Update Process

1. Normal Start

If no --resume flag has been passed, the following happens:

  1. The updater checks the current GitHub release.
  2. The tag version is read from tag_name.
  3. If the release has a beta tag, a confirmation prompt appears.
  4. The .zip asset from the release is downloaded.
  5. The archive is extracted to _update_tmp/.
  6. If the archive contains only a single root folder, that folder is used as the base.

2. Resume Mode

If --resume <path> has been passed, the updater directly uses the already extracted files from that path.
In this case, the entire download step is skipped.


Self-Update of the Updater

The updater first checks whether a newer UpdaterVersion is included in the release than is installed locally.

If so:

  1. update.exe from the unpacked release is copied to the base directory as update_new.exe.
  2. The new updater version is saved in version.txt.
  3. The current process is replaced via os.execv(...) by update_new.exe.
  4. The new process continues with --resume <extracted_root>.

This means:

  • The updater updates itself before the actual tool update.
  • The tool update only continues in the new process.
  • The running update.exe is not overwritten during the running process.

Tool Update

After the self-update (or if no new update.exe is needed), the actual tool update follows.

Before copying, a signal file is written:

update_signal.tmp

This file is created in the current working directory. The updater then waits briefly so that the start process has time to finish.

The updater then copies the files from the release to the target directory.


What Gets Copied

The updater works with a whitelist.

Allowed Directories

Only these top-level directories are processed:

  • core
  • scripts
  • server
  • config

Allowed Root Files

Only these top-level files are copied:

  • version.txt
  • README.md
  • LICENSE
  • update.exe
  • server.exe
  • start.exe

Additional Rules

  • update.exe is skipped during normal copying.
  • config.yaml is skipped during normal copying.
  • All other files outside the whitelist are ignored.

The update therefore only affects areas that have been explicitly whitelisted.

WHITELIST_DIRS = {"core", "scripts", "server", "config"}
WHITELIST_FILES = {"version.txt", "README.md", "LICENSE", "update.exe", "server.exe", "start.exe"}

Configuration Migration

If auto_update_config is enabled in the loaded configuration, the updater performs a configuration migration.

Migration Process

  1. config/config.default.yaml is loaded as a template.
  2. config/config.yaml is loaded as user data.
  3. If config/config.yaml is missing, it is recreated from the default file.
  4. A backup is created before migration:
config/config.yaml.bak
  1. The structure of the template is preserved.
  2. Only values that exist in the template are copied from the user version.
  3. Keys that only exist in the old user version are removed.
  4. config_version is set to the version of the template.

Important Property

Migration is strict:

  • The structure comes from the default file.
  • User values are only adopted where the template has a matching key.
  • Additional old keys are not retained.