Files
moko-platform/docs/workflows/update-server.md
T
Jonathan Miller 96c7bd9e46 docs: update all references to MokoConsulting org and Gitea URLs
- mokoconsulting-tech → MokoConsulting across all docs
- github.com → git.mokoconsulting.tech
- CLI examples updated with new org name

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 22:21:59 -05:00

15 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://raw.githubusercontent.com/{org}/{repo}/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.

Complete Multi-Entry Example

<?xml version="1.0" encoding="utf-8"?>
<updates>
    <!-- Stable entry: visible to all sites (default minimum stability) -->
    <update>
        <name>My Extension</name>
        <description>My Extension stable release</description>
        <element>com_myextension</element>
        <type>component</type>
        <version>01.02.03</version>
        <client>site</client>
        <tags>
            <tag>stable</tag>
        </tags>
        <infourl title="My Extension">https://github.com/org/repo/releases/tag/v01</infourl>
        <downloads>
            <downloadurl type="full" format="zip">https://github.com/org/repo/releases/download/v01/com_myextension-01.02.03.zip</downloadurl>
        </downloads>
        <sha256>abc123...full-hash-here</sha256>
        <targetplatform name="joomla" version="((4\.[3-9])|(5\.[0-9]))" />
        <maintainer>Moko Consulting</maintainer>
        <maintainerurl>https://mokoconsulting.tech</maintainerurl>
    </update>

    <!-- RC entry: 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>
        <client>site</client>
        <tags>
            <tag>rc</tag>
        </tags>
        <infourl title="My Extension">https://github.com/org/repo/tree/rc/01.03.01</infourl>
        <downloads>
            <downloadurl type="full" format="zip">https://github.com/org/repo/archive/refs/heads/rc/01.03.01.zip</downloadurl>
        </downloads>
        <targetplatform name="joomla" version="((4\.[3-9])|(5\.[0-9]))" />
        <maintainer>Moko Consulting</maintainer>
        <maintainerurl>https://mokoconsulting.tech</maintainerurl>
    </update>

    <!-- Beta entry: 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>
        <client>site</client>
        <tags>
            <tag>beta</tag>
        </tags>
        <infourl title="My Extension">https://github.com/org/repo/tree/beta/01.03.01</infourl>
        <downloads>
            <downloadurl type="full" format="zip">https://github.com/org/repo/archive/refs/heads/beta/01.03.01.zip</downloadurl>
        </downloads>
        <targetplatform name="joomla" version="((4\.[3-9])|(5\.[0-9]))" />
        <maintainer>Moko Consulting</maintainer>
        <maintainerurl>https://mokoconsulting.tech</maintainerurl>
    </update>

    <!-- Alpha entry: 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>
        <client>site</client>
        <tags>
            <tag>alpha</tag>
        </tags>
        <infourl title="My Extension">https://github.com/org/repo/tree/alpha/01.03.01</infourl>
        <downloads>
            <downloadurl type="full" format="zip">https://github.com/org/repo/archive/refs/heads/alpha/01.03.01.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>
        <client>site</client>
        <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