The installer can update itself in place from a GitHub repository. Only the files that belong to the installer (src/ plus an optional updater_source_path) are touched. The user configuration, var/, and the target directory are never modified by the self-update.
For the broader architecture see architecture.md. For security considerations see security.md.
- architecture.md – where the self-update handler sits.
- security.md – HTTPS, GitHub tokens, downgrade policy.
Open the installer, go to Installer management in the dashboard. From there you can list branches and tags of the configured repository and install any of them.
The installer version that is currently running is shown at the top of the page. After a successful self-update, the installer reloads (the next page request already runs the new version).
| Config key | Default | Notes |
|---|---|---|
installer_repository |
oakengine/installer |
The GitHub repo to pull from. |
installer_version |
empty | Optional. When set, the installer remembers a specific version after a successful self-update. |
installer_commit |
empty | Companion to installer_version. Stores the commit hash for branches. |
github_token |
empty | Optional. Increases the rate limit for unauthenticated requests. |
updater_source_path |
src |
Path inside the archive that contains the installer files to copy. |
api_base_url |
https://api.github.com |
Override for GitHub Enterprise. |
The archive that GitHub returns has a top-level directory named after the repo (<repo>-<sha>). The installer looks inside that directory for updater_source_path (default src/) and copies that subtree into the installer's own root.
So for oakengine/installer with the default updater_source_path=src, the self-update copies oakengine-installer-<sha>/src/* into the installer's own src/.
Not every file under src/ is copied. updateUpdaterFromTag() filters the archive entries through isAllowedUpdaterFile:
.htaccessat the root.config.phpis never copied (user-specific).- Any single PHP file at the root (e.g.
index.php). - Any single PHP file directly under
app/(e.g.app/InstallerApplication.php). - Any
.phpfile underlang/. - Any
.svg,.png,.js, or.aifile underlogo/.
Everything else is skipped and reported back to the user as skipped_files.
The currently installed version comes from one of these sources, in order:
config.phpkeyinstaller_version(orinstaller_commit).- The
versionfield in the installer's owncomposer.json. - The literal string
unknown.
Branch refs are stored as installer_version=<branch> and installer_commit=<full sha>. Semver tags are stored as the tag name itself (e.g. 1.4.0).
resolveInstallerVersion() appends the first 7 characters of installer_commit to the branch name when the version is not a semver tag, so that the displayed version uniquely identifies the installed commit. Semver tags are returned unchanged.
canUpdateInstallerToTag($current, $target) blocks updates that go backwards in semver:
- If either side is not a semver tag (e.g. a branch name), the update is always allowed.
- If both are semver tags, the target must be
>=the current version.
The check is used for informational purposes; the dashboard button itself does not enforce it. The user can still type any tag or branch into the form.
POST /index.php
self_update = 1
ref = <branch or tag>
ref_commit = <sha>
ref_type = branch | tag (optional)
1. getCachedGitHubRepositoryRefs(...) → list of tags and branches.
2. Validate that $ref exists in the cached list.
3. Call canUpdateInstallerToTag(...) (advisory).
4. downloadArchive(repo, ref, ref_type) via GitHub.
5. Extract into a temp directory.
6. Walk the archive under <updater_source_path>.
7. Copy every allowed file over the installer's own file.
8. Remove the temp directory.
9. Update config.php with the new version + commit.
10. Render the result page with updated_files and skipped_files.
Implementation: updateUpdaterFromTag().
config.php is rewritten via writeConfigValues() with the two new values:
[
'installer_version' => $tag,
'installer_commit' => $refCommit,
]The function merges the new values into the existing array (other keys are preserved) and pretty-prints the file with var_export.
GitHub tag and branch listings are cached under <installer>/var/cache/github-api/... by GitHubRefsCache. The cache TTL is 15 minutes by default. Refresh it by reloading the Installer management page after the TTL has elapsed, or by re-running the self-update action.
The self-update pipeline explicitly does not touch:
config.php(except for the version keys, and only via the merge above).- Anything outside
src/in the installer directory. - Anything in the target directory.
- The manifest files inside the target directory (runner / plugin / data).
So a self-update followed by a project install is fully independent.