BRIEF: How update files (update.txt and updates.xml) are generated per platform
-->
# Update Server Files
MokoStandards automatically generates platform-specific update server files on every release and dev/alpha/beta/rc deployment.
## Overview
| Platform | File | Format | Reference |
|----------|------|--------|-----------|
| Dolibarr (`crm-module`) | `update.txt` | Plain text version string (< 30 chars) | Dolibarr `url_last_version` check |
| Joomla (`waas-component`) | `updates.xml` | Multi-entry XML following Joomla update server spec | [Joomla Update Server Docs](https://docs.joomla.org/Deploying_an_Update_Server) |
## Stability Tags
Joomla's `updates.xml` contains **multiple `<update>` entries simultaneously** — one per stability level. Joomla filters which entries the admin sees based on the site's **Minimum Stability** setting (Extensions > Update > Options).
| Stability | Joomla `<tag>` | Who sees it | Source workflow |
The `update-server.yml` workflow triggers on **both direct pushes and PR merges** to the following branches:
-`dev` (bare branch — no sub-path required)
-`dev/**` (versioned dev branches like `dev/02.01`)
-`alpha/**`
-`beta/**`
-`rc/**`
Previously, the workflow only triggered on PR merges. The addition of push triggers ensures that direct commits to these branches (e.g., CI-generated version bumps, automated fixes) also update the `updates.xml` entries.
### Cascade Release Channels
Each stability level writes its own channel **and all lower channels** to `updates.xml`. This ensures Joomla sites on any "Minimum Stability" setting always see the latest available release:
| Release Stream | Channels written to updates.xml |
Without cascade, a site set to "Development" minimum stability would only see `<tag>development</tag>` entries and would miss stable releases entirely. The cascade ensures stable releases are visible to all sites regardless of their minimum stability setting.
For full cascade documentation, see [Cascade Release Channels](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/src/branch/main/docs/release-management/cascade-channels.md).
### Sync to Main
Since Joomla sites read `updates.xml` from the `main` branch, the `update-server.yml` workflow **syncs `updates.xml` to `main` via the Gitea API** after building on non-main branches. This ensures pre-release channel entries (dev, alpha, beta, rc) are visible to sites checking for updates, without requiring a PR merge to main.
Previously, `update-server.yml` only committed `updates.xml` to the current branch, so Joomla sites never saw dev/alpha/beta/rc releases until they were merged to main.
Joomla's update system reads all `<update>` entries from the XML file but only presents entries whose `<tag>` matches the site's minimum stability threshold:
- **Minimum Stability = Stable** (default): Only sees `<tag>stable</tag>` entries
- **Minimum Stability = RC**: Sees `stable` + `rc` entries
- **`alpha/**`**: *(Optional)* Early internal testing. Update files tagged as `alpha`. Can be skipped.
- **`beta/**`**: *(Optional)* Broader external testing. Update files tagged as `beta`. Can be skipped.
- **`rc/**`**: Release candidate. Update files tagged as `rc`. RC branches deploy to dev server for final testing.
- **`version/XX`**: Major version integration branch (major only). All minors and patches flow into the same major branch.
- **`main`**: Stable release. `auto-release.yml` creates GitHub Release and `vXX` tag. Update files tagged as `stable`.
- **Main merges back to `dev`** to start the next cycle.
## Dolibarr: `update.txt`
Dolibarr modules check for updates by fetching a plain-text file from the URL in `$this->url_last_version`. The file must contain only the version string (e.g., `01.02.03`) — no JSON, no XML, no newlines.
**On release (main):**
```
01.02.03
```
**On RC deploy (rc/**):**
```
01.02.03-rc
```
**On dev deploy (dev/**):**
```
development
```
The module descriptor's `url_last_version` should point to:
The `updates.xml` file contains **up to five stability entries at once** (one per stability level). Joomla reads the entire file and filters by the site's minimum stability setting.
| `update-server.yml` | Push to `rc/**` | `<tag>rc</tag>` — adds/updates the RC entry (+ cascaded lower channels) |
| `update-server.yml` | Push to `beta/**` | `<tag>beta</tag>` — adds/updates the beta entry (+ cascaded lower channels) |
| `update-server.yml` | Push to `alpha/**` | `<tag>alpha</tag>` — adds/updates the alpha entry (+ cascaded lower channels) |
| `update-server.yml` | Push to `dev` or `dev/**` | `<tag>development</tag>` — adds/updates the development entry |
The `auto-release.yml` workflow writes the stable entry and preserves any existing pre-release entries. The `update-server.yml` workflow writes its specific entry (and cascaded lower channels) and preserves the others.
**Important**: All `update-server.yml` runs also sync the updated `updates.xml` to `main` via the Gitea API, since Joomla sites read the update server XML from the `main` branch.
The `<updateservers>` tag tells Joomla where to check for updates. Both servers are declared for redundancy — Gitea (primary, priority 1) and GitHub mirror (fallback, priority 2).
## How It Works
### Joomla (updates.xml)
1.**On release** (`auto-release.yml` → main branch):
- Builds ZIP from `src/` directory
- Uploads ZIP to the `vXX` major release on GitHub
- Computes SHA-256 hash of the ZIP
- Writes/updates the `<tag>stable</tag>` entry in `updates.xml` with version, download URL, and SHA-256