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.txtupdated after release? - ☑ GitHub release tagged correctly?
- ☑ Beta releases work with confirmation?
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.yamlat startup. - The updater works within the directory where the EXE is located.
- The release package is downloaded as a
.zipfrom GitHub. - The update logic differentiates between tool version and updater version.
Expected Files and Paths
The updater uses these local paths:
version.txtconfig/config.default.yamlconfig/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:
ToolVersionUpdaterVersion
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.31.21.2.3-beta1.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:
- The updater checks the current GitHub release.
- The tag version is read from
tag_name. - If the release has a
betatag, a confirmation prompt appears. - The
.zipasset from the release is downloaded. - The archive is extracted to
_update_tmp/. - 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:
update.exefrom the unpacked release is copied to the base directory asupdate_new.exe.- The new updater version is saved in
version.txt. - The current process is replaced via
os.execv(...)byupdate_new.exe. - 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.exeis 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:
corescriptsserverconfig
Allowed Root Files
Only these top-level files are copied:
version.txtREADME.mdLICENSEupdate.exeserver.exestart.exe
Additional Rules
update.exeis skipped during normal copying.config.yamlis 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
config/config.default.yamlis loaded as a template.config/config.yamlis loaded as user data.- If
config/config.yamlis missing, it is recreated from the default file. - A backup is created before migration:
config/config.yaml.bak
- The structure of the template is preserved.
- Only values that exist in the template are copied from the user version.
- Keys that only exist in the old user version are removed.
config_versionis 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.