Files
moko-platform/docs/workflows/update-server.md
T
Jonathan Miller b9109c51bc docs: update release cycle — Gitea-only pre-release, dual stable downloads
- Added platform distribution table (stable=dual, pre-release=Gitea only)
- Updated all example URLs from GitHub to Gitea
- Stable gets dual <downloadurl> (Gitea + GitHub)
- RC/Beta/Alpha/Dev get single <downloadurl> (Gitea only)
- Updated targetplatform to [56].*
- Updated Dolibarr update.txt URL to Gitea
- Removed sha256/client fields from examples (not used)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-19 13:04:32 -05:00

16 KiB

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

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
Stable <tag>stable</tag> All sites (default) auto-release.yml on main
Release Candidate <tag>rc</tag> Sites set to RC or lower update-server.yml on rc/** push
Beta <tag>beta</tag> Sites set to Beta or lower update-server.yml on beta/** push
Alpha <tag>alpha</tag> Sites set to Alpha or lower update-server.yml on alpha/** push
Development <tag>development</tag> Sites set to Development update-server.yml on dev/** push

Note: Alpha and beta are optional stages. Not every release cycle will have alpha/beta entries.

How Joomla Filters Updates

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
  • Minimum Stability = Beta: Sees stable + rc + beta entries
  • Minimum Stability = Alpha: Sees stable + rc + beta + alpha entries
  • Minimum Stability = Development: Sees all entries (stable + rc + beta + alpha + development)

The admin always gets the highest version among visible entries.

Dolibarr Stability

Workflow Branch update.txt content
auto-release.yml main XX.YY.ZZ (real version)
deploy-dev.yml rc/** XX.YY.ZZ-rc
deploy-dev.yml beta/** XX.YY.ZZ-beta
deploy-dev.yml alpha/** XX.YY.ZZ-alpha
deploy-dev.yml dev/** development

Branch Lifecycle

dev → [alpha] → [beta] → rc → version/XX → main → dev
       optional   optional     (integration)  (production)  (feedback)
  • dev/**: Active development. Update files tagged as development.
  • 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:

https://git.mokoconsulting.tech/MokoConsulting/{repo}/raw/branch/main/update.txt

Joomla: updates.xml (Multi-Entry)

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.

Platform Distribution

Release Type Gitea Release GitHub Release Download URLs
Stable Yes Yes (via mirror) Dual (Gitea + GitHub)
RC Yes No Single (Gitea only)
Beta Yes No Single (Gitea only)
Alpha Yes No Single (Gitea only)
Development Yes No Single (Gitea only)

Pre-release builds stay on Gitea for internal testing. Only stable releases are mirrored to GitHub.

Complete Multi-Entry Example

<?xml version="1.0" encoding="utf-8"?>
<updates>
    <!-- Stable: dual download (Gitea + GitHub), visible to all sites -->
    <update>
        <name>My Extension</name>
        <description>My Extension stable release</description>
        <element>com_myextension</element>
        <type>component</type>
        <version>01.02.03</version>
        <tags>
            <tag>stable</tag>
        </tags>
        <infourl title="My Extension">https://git.mokoconsulting.tech/MokoConsulting/MyExtension/releases</infourl>
        <downloads>
            <downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MyExtension/releases/download/v01/com_myextension-01.02.03.zip</downloadurl>
            <downloadurl type="full" format="zip">https://github.com/mokoconsulting-tech/MyExtension/releases/download/v01/com_myextension-01.02.03.zip</downloadurl>
        </downloads>
        <targetplatform name="joomla" version="((4\.[3-9])|(5\.[0-9]))" />
        <maintainer>Moko Consulting</maintainer>
        <maintainerurl>https://mokoconsulting.tech</maintainerurl>
    </update>

    <!-- RC: Gitea only, visible to sites with minimum stability = RC or lower -->
    <update>
        <name>My Extension</name>
        <description>My Extension release candidate</description>
        <element>com_myextension</element>
        <type>component</type>
        <version>01.03.01-rc</version>
        <tags>
            <tag>rc</tag>
        </tags>
        <infourl title="My Extension">https://git.mokoconsulting.tech/MokoConsulting/MyExtension/src/branch/rc</infourl>
        <downloads>
            <downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MyExtension/releases/download/rc/com_myextension-01.03.01-rc.zip</downloadurl>
        </downloads>
        <targetplatform name="joomla" version="((4\.[3-9])|(5\.[0-9]))" />
        <maintainer>Moko Consulting</maintainer>
        <maintainerurl>https://mokoconsulting.tech</maintainerurl>
    </update>

    <!-- Beta: Gitea only, visible to sites with minimum stability = Beta or lower -->
    <update>
        <name>My Extension</name>
        <description>My Extension beta build</description>
        <element>com_myextension</element>
        <type>component</type>
        <version>01.03.01-beta</version>
        <tags>
            <tag>beta</tag>
        </tags>
        <infourl title="My Extension">https://git.mokoconsulting.tech/MokoConsulting/MyExtension/src/branch/beta</infourl>
        <downloads>
            <downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MyExtension/releases/download/beta/com_myextension-01.03.01-beta.zip</downloadurl>
        </downloads>
        <targetplatform name="joomla" version="((4\.[3-9])|(5\.[0-9]))" />
        <maintainer>Moko Consulting</maintainer>
        <maintainerurl>https://mokoconsulting.tech</maintainerurl>
    </update>

    <!-- Alpha: Gitea only, visible to sites with minimum stability = Alpha or lower -->
    <update>
        <name>My Extension</name>
        <description>My Extension alpha build</description>
        <element>com_myextension</element>
        <type>component</type>
        <version>01.03.01-alpha</version>
        <tags>
            <tag>alpha</tag>
        </tags>
        <infourl title="My Extension">https://git.mokoconsulting.tech/MokoConsulting/MyExtension/src/branch/alpha</infourl>
        <downloads>
            <downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MyExtension/releases/download/alpha/com_myextension-01.03.01-alpha.zip</downloadurl>
        </downloads>
        <targetplatform name="joomla" version="((4\.[3-9])|(5\.[0-9]))" />
        <maintainer>Moko Consulting</maintainer>
        <maintainerurl>https://mokoconsulting.tech</maintainerurl>
    </update>

    <!-- Development entry: visible to sites with minimum stability = Development -->
    <update>
        <name>My Extension</name>
        <description>My Extension development build</description>
        <element>com_myextension</element>
        <type>component</type>
        <version>01.04.00-dev</version>
        <tags>
            <tag>development</tag>
        </tags>
        <infourl title="My Extension">https://github.com/org/repo/tree/dev/01.04</infourl>
        <downloads>
            <downloadurl type="full" format="zip">https://github.com/org/repo/archive/refs/heads/dev/01.04.zip</downloadurl>
        </downloads>
        <targetplatform name="joomla" version="((4\.[3-9])|(5\.[0-9]))" />
        <maintainer>Moko Consulting</maintainer>
        <maintainerurl>https://mokoconsulting.tech</maintainerurl>
    </update>
</updates>

Which Workflow Writes Which Entry

Workflow Trigger Entry written
auto-release.yml Push to main <tag>stable</tag> — writes the stable entry with SHA-256 hash of the ZIP
update-server.yml Push to rc/** <tag>rc</tag> — adds/updates the RC entry
update-server.yml Push to beta/** <tag>beta</tag> — adds/updates the beta entry
update-server.yml Push to alpha/** <tag>alpha</tag> — adds/updates the alpha entry
update-server.yml Push to 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 only its specific entry (rc, beta, alpha, or dev) and preserves the others.

XML Elements

All metadata is auto-extracted from the extension's XML manifest at build time:

Element Source Notes
<name> <name> in manifest Extension display name
<element> <element> in manifest, or manifest filename Must match installed extension
<type> type attribute on <extension> component, module, plugin, library, package, template
<client> client attribute on <extension> site or administratorrequired for plugins and modules
<folder> group attribute on <extension> Plugin group (e.g., system, content) — required for plugins
<version> README.md VERSION field Real version on release, development on dev
<tags><tag> Workflow determines stable on release, development on dev
<targetplatform> <targetplatform> in manifest Falls back to Joomla 5.x / 6.x
<php_minimum> <php_minimum> in manifest Optional, included if present
<infourl> GitHub release/branch URL Links to release page or branch
<downloads><downloadurl> GitHub release asset or branch archive type="full" format="zip"

Extension Manifest Setup

For the updates.xml generation to work correctly, your Joomla extension manifest must include:

<extension type="component" client="site" method="upgrade">
    <name>My Extension</name>
    <element>com_myextension</element>
    <!-- ... -->
    <updateservers>
        <server type="extension" priority="1" name="My Extension Update Server (Gitea)">
            https://git.mokoconsulting.tech/mokoconsulting-tech/{repo}/raw/branch/main/updates.xml
        </server>
        <server type="extension" priority="2" name="My Extension Update Server (GitHub)">
            https://raw.githubusercontent.com/mokoconsulting-tech/{repo}/main/updates.xml
        </server>
    </updateservers>
</extension>

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
    • Preserves any existing rc/dev entries in the file
    • Commits updated updates.xml to main
  2. On RC push (update-server.yml → rc/** branches):

    • Writes/updates the <tag>rc</tag> entry in updates.xml
    • Download URL points to the branch archive ZIP
    • Preserves all other stability entries
    • Commits updated updates.xml to the rc branch
  3. On beta push (update-server.yml → beta/** branches):

    • Writes/updates the <tag>beta</tag> entry in updates.xml
    • Download URL points to the branch archive ZIP
    • Preserves all other stability entries
    • Commits updated updates.xml to the beta branch
  4. On alpha push (update-server.yml → alpha/** branches):

    • Writes/updates the <tag>alpha</tag> entry in updates.xml
    • Download URL points to the branch archive ZIP
    • Preserves all other stability entries
    • Commits updated updates.xml to the alpha branch
  5. On dev push (update-server.yml → dev/** branches):

    • Writes/updates the <tag>development</tag> entry in updates.xml
    • Download URL points to the branch archive ZIP
    • Preserves all other stability entries
    • Commits updated updates.xml to the dev branch

Dolibarr (update.txt)

  1. On release (auto-release.yml → main): writes real version to update.txt
  2. On RC deploy (deploy-dev.yml → rc/**): writes XX.YY.ZZ-rc to update.txt
  3. On beta deploy (deploy-dev.yml → beta/**): writes XX.YY.ZZ-beta to update.txt
  4. On alpha deploy (deploy-dev.yml → alpha/**): writes XX.YY.ZZ-alpha to update.txt
  5. On dev deploy (deploy-dev.yml → dev/**): writes development to update.txt

RC --> Main Flow

When a release candidate is ready:

  1. rc/XX.YY.ZZ branch is tested with <tag>rc</tag> update entries
  2. RC branch is merged to main via PR
  3. Push to main triggers auto-release.yml → GitHub Release + vXX tag
  4. updates.xml on main gets a new/updated <tag>stable</tag> entry
  5. version/XX archive branch is auto-created

Health Checks

The platform-specific repo_health.yml workflows verify:

  • Dolibarr: update.txt exists in root, module descriptor valid, url_last_version correct
  • Joomla: updates.xml exists in root, XML manifest valid, language files present

Rulesets

Branch protection rulesets (applied via sync_rulesets.php):

  • MAIN: prevents deletion, non-fast-forward, requires PRs
  • VERSION: immutable — prevents updates, deletion, force-push
  • DEV: prevents deletion, non-fast-forward
  • ALPHA: prevents deletion, non-fast-forward
  • BETA: prevents deletion, non-fast-forward
  • RC: prevents deletion, non-fast-forward