14 Commits

Author SHA1 Message Date
jmiller af82b46fe0 chore: add dlid and blockChildUninstall to package manifest [skip ci] 2026-06-04 22:02:32 +00:00
jmiller 02d8bfb089 chore: sync .mokogitea/workflows/pr-check.yml from moko-platform [skip ci] 2026-06-04 15:58:52 +00:00
jmiller 6aebfc1953 chore: sync .mokogitea/workflows/pr-check.yml from moko-platform [skip ci] 2026-06-04 15:41:45 +00:00
jmiller 8fb3262eb3 chore: sync .mokogitea/workflows/pr-check.yml from moko-platform [skip ci] 2026-06-04 15:32:55 +00:00
jmiller 03b53d937a chore: remove updates.xml [skip ci] 2026-06-04 15:27:06 +00:00
jmiller eb5513f4af chore: sync .mokogitea/workflows/pr-check.yml from moko-platform [skip ci] 2026-06-04 15:19:46 +00:00
jmiller 003e9617a0 feat(update): migrate update server URL to Gitea Pages [skip ci] 2026-06-04 14:34:14 +00:00
jmiller 01139c6fd4 chore: sync .mokogitea/workflows/auto-release.yml from moko-platform [skip ci] 2026-06-04 14:24:01 +00:00
jmiller a6d843fd9b chore: sync updates.xml from development [skip ci] 2026-06-04 13:57:48 +00:00
jmiller b40482d8a5 chore: sync .mokogitea/workflows/repo-health.yml from moko-platform [skip ci] 2026-06-04 13:47:45 +00:00
jmiller 8ebbfa7aed chore: sync updates.xml from development [skip ci] 2026-06-04 13:16:03 +00:00
jmiller 83b47ce849 chore: sync updates.xml from development [skip ci] 2026-06-04 13:02:06 +00:00
jmiller d383d1fc09 chore: sync updates.xml from development [skip ci] 2026-06-04 12:41:04 +00:00
jmiller 31941e80c3 chore: sync updates.xml 01.02.00-rc from rc [skip ci] 2026-06-04 12:13:17 +00:00
5 changed files with 1507 additions and 1380 deletions
+5 -3
View File
@@ -102,13 +102,14 @@ jobs:
run: | run: |
php /tmp/moko-platform-api/cli/release_publish.php \ php /tmp/moko-platform-api/cli/release_publish.php \
--path . --stability rc --bump minor --branch rc \ --path . --stability rc --bump minor --branch rc \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --token "${{ secrets.MOKOGITEA_TOKEN }}" \
--skip-update-stream
- name: Summary - name: Summary
if: always() if: always()
run: | run: |
echo "## Promoted to Release Candidate" >> $GITHUB_STEP_SUMMARY echo "## Promoted to Release Candidate" >> $GITHUB_STEP_SUMMARY
echo "Branch renamed to rc, minor bump, RC + lesser stream releases built, updates.xml synced" >> $GITHUB_STEP_SUMMARY echo "Branch renamed to rc, minor bump, RC release built (updates.xml managed by Gitea Pages)" >> $GITHUB_STEP_SUMMARY
# ── Merged PR → Build & Release (or promote RC to stable) ──────────────────── # ── Merged PR → Build & Release (or promote RC to stable) ────────────────────
release: release:
@@ -167,7 +168,8 @@ jobs:
run: | run: |
php /tmp/moko-platform-api/cli/release_publish.php \ php /tmp/moko-platform-api/cli/release_publish.php \
--path . --stability stable --bump minor --branch main \ --path . --stability stable --bump minor --branch main \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --token "${{ secrets.MOKOGITEA_TOKEN }}" \
--skip-update-stream
# -- STEP 9: Mirror to GitHub (stable only) -------------------------------- # -- STEP 9: Mirror to GitHub (stable only) --------------------------------
- name: "Step 9: Mirror release to GitHub" - name: "Step 9: Mirror release to GitHub"
+244
View File
@@ -105,6 +105,19 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Check for merge conflict markers
run: |
CONFLICTS=$(grep -rn '<<<<<<< \|>>>>>>> \|^=======$' --include='*.php' --include='*.xml' --include='*.css' --include='*.js' --include='*.json' --include='*.md' --include='*.yml' --include='*.yaml' --include='*.ini' --include='*.txt' . 2>/dev/null | grep -v '.git/' || true)
if [ -n "$CONFLICTS" ]; then
echo "::error::Merge conflict markers found in source files"
echo "## Conflict Markers Found" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "$CONFLICTS" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
exit 1
fi
echo "No conflict markers found"
- name: Detect platform - name: Detect platform
id: platform id: platform
run: | run: |
@@ -134,6 +147,98 @@ jobs:
echo "PHP lint: ${ERRORS} error(s)" echo "PHP lint: ${ERRORS} error(s)"
[ "$ERRORS" -eq 0 ] || { echo "::error::PHP syntax errors found"; exit 1; } [ "$ERRORS" -eq 0 ] || { echo "::error::PHP syntax errors found"; exit 1; }
- name: Joomla JEXEC guard check
if: steps.platform.outputs.platform == 'joomla'
run: |
ERRORS=0
while IFS= read -r -d '' file; do
# Skip vendor, node_modules, and index.html stub files
case "$file" in ./vendor/*|./node_modules/*) continue ;; esac
# Check first 10 lines for JEXEC or JPATH guard
if ! head -20 "$file" | grep -qE "defined\s*\(\s*['\"](_JEXEC|JPATH_BASE|\\\\JPATH_PLATFORM)['\"]"; then
echo "::error file=${file}::Missing JEXEC guard: ${file}"
ERRORS=$((ERRORS + 1))
fi
done < <(find . -name "*.php" -path "*/src/*" -not -path "./.git/*" -not -path "./vendor/*" -print0)
if [ "$ERRORS" -gt 0 ]; then
echo "::error::${ERRORS} PHP file(s) missing defined('_JEXEC') or die guard"
echo "## JEXEC Guard Check: Failed" >> $GITHUB_STEP_SUMMARY
echo "${ERRORS} file(s) in src/ are missing the Joomla execution guard." >> $GITHUB_STEP_SUMMARY
exit 1
fi
echo "JEXEC guard: OK"
- name: Joomla directory listing protection
if: steps.platform.outputs.platform == 'joomla'
run: |
MISSING=0
SOURCE_DIR="src"
[ ! -d "$SOURCE_DIR" ] && exit 0
while IFS= read -r dir; do
if [ ! -f "${dir}/index.html" ]; then
echo "::warning::Missing index.html in ${dir} (directory listing protection)"
MISSING=$((MISSING + 1))
fi
done < <(find "$SOURCE_DIR" -type d -not -path "./.git/*" -not -path "*/vendor/*" -not -path "*/node_modules/*")
if [ "$MISSING" -gt 0 ]; then
echo "## Directory Protection" >> $GITHUB_STEP_SUMMARY
echo "${MISSING} director(ies) missing index.html" >> $GITHUB_STEP_SUMMARY
fi
echo "Directory protection: ${MISSING} missing (advisory)"
- name: Joomla script file and asset checks
if: steps.platform.outputs.platform == 'joomla'
run: |
ERRORS=0
MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" -exec grep -l '<extension' {} \; 2>/dev/null | head -1)
[ -z "$MANIFEST" ] && exit 0
MANIFEST_DIR=$(dirname "$MANIFEST")
# Check scriptfile exists if declared
SCRIPTFILE=$(sed -n 's/.*<scriptfile>\([^<]*\)<\/scriptfile>.*/\1/p' "$MANIFEST" 2>/dev/null)
if [ -n "$SCRIPTFILE" ]; then
if [ ! -f "${MANIFEST_DIR}/${SCRIPTFILE}" ]; then
echo "::error::Manifest declares <scriptfile>${SCRIPTFILE}</scriptfile> but file not found at ${MANIFEST_DIR}/${SCRIPTFILE}"
ERRORS=$((ERRORS + 1))
else
echo "Script file: ${MANIFEST_DIR}/${SCRIPTFILE} (OK)"
fi
fi
# Require joomla.asset.json and validate it
ASSET_JSON=$(find "$MANIFEST_DIR" -name "joomla.asset.json" -not -path "./.git/*" 2>/dev/null | head -1)
if [ -z "$ASSET_JSON" ]; then
echo "::error::joomla.asset.json not found — Joomla asset system is required"
ERRORS=$((ERRORS + 1))
else
if command -v php &> /dev/null; then
php -r "json_decode(file_get_contents('$ASSET_JSON')); if(json_last_error()!==JSON_ERROR_NONE){echo json_last_error_msg();exit(1);}" 2>&1 || {
echo "::error::joomla.asset.json is not valid JSON"
ERRORS=$((ERRORS + 1))
}
fi
echo "joomla.asset.json: valid"
fi
# Validate all XML files in src/ are well-formed
XML_ERRORS=0
if command -v php &> /dev/null; then
while IFS= read -r -d '' xmlfile; do
if ! php -r "libxml_use_internal_errors(true); \$x = simplexml_load_file('$xmlfile'); if(!\$x){foreach(libxml_get_errors() as \$e) echo trim(\$e->message) . ' in $xmlfile'; exit(1);}" 2>&1; then
XML_ERRORS=$((XML_ERRORS + 1))
fi
done < <(find "$MANIFEST_DIR" -name "*.xml" -not -path "./.git/*" -print0)
fi
if [ "$XML_ERRORS" -gt 0 ]; then
echo "::error::${XML_ERRORS} XML file(s) are malformed"
ERRORS=$((ERRORS + 1))
else
echo "XML well-formedness: OK"
fi
[ "$ERRORS" -gt 0 ] && exit 1
echo "Joomla asset checks: OK"
- name: Validate platform manifest - name: Validate platform manifest
run: | run: |
PLATFORM="${{ steps.platform.outputs.platform }}" PLATFORM="${{ steps.platform.outputs.platform }}"
@@ -151,6 +256,13 @@ jobs:
for ELEMENT in name version description; do for ELEMENT in name version description; do
grep -q "<${ELEMENT}>" "$MANIFEST" || { echo "::error::Missing <${ELEMENT}> in manifest"; exit 1; } grep -q "<${ELEMENT}>" "$MANIFEST" || { echo "::error::Missing <${ELEMENT}> in manifest"; exit 1; }
done done
# Block legacy raw/branch update server URLs on MokoGitea
RAW_URLS=$(grep -n 'raw/branch' "$MANIFEST" | grep -i 'mokoconsulting\|mokogitea\|git\.mokoconsulting\.tech' || true)
if [ -n "$RAW_URLS" ]; then
echo "::error::Manifest contains legacy raw/branch update server URL on MokoGitea. Use the Gitea Pages URL instead (e.g. /{REPO}/updates.xml not /{REPO}/raw/branch/main/updates.xml)"
echo "$RAW_URLS"
exit 1
fi
echo "Joomla manifest valid" echo "Joomla manifest valid"
;; ;;
dolibarr) dolibarr)
@@ -183,6 +295,138 @@ jobs:
;; ;;
esac esac
- name: Validate Joomla language files
if: steps.platform.outputs.platform == 'joomla'
run: |
ERRORS=0
WARNINGS=0
# Require both en-GB and en-US language directories
LANG_ROOT=$(find . -path "*/language" -type d -not -path "./.git/*" 2>/dev/null | head -1)
if [ -z "$LANG_ROOT" ]; then
echo "No language/ directory found — skipping"
exit 0
fi
if [ ! -d "$LANG_ROOT/en-GB" ]; then
echo "::error::Missing en-GB language directory (${LANG_ROOT}/en-GB)"
ERRORS=$((ERRORS + 1))
fi
if [ ! -d "$LANG_ROOT/en-US" ]; then
echo "::error::Missing en-US language directory (${LANG_ROOT}/en-US)"
ERRORS=$((ERRORS + 1))
fi
# Check that en-GB and en-US have matching .ini files
if [ -d "$LANG_ROOT/en-GB" ] && [ -d "$LANG_ROOT/en-US" ]; then
for GB_INI in "$LANG_ROOT/en-GB"/*.ini; do
[ ! -f "$GB_INI" ] && continue
US_INI="$LANG_ROOT/en-US/$(basename "$GB_INI")"
if [ ! -f "$US_INI" ]; then
echo "::error::$(basename "$GB_INI") exists in en-GB but missing from en-US"
ERRORS=$((ERRORS + 1))
fi
done
for US_INI in "$LANG_ROOT/en-US"/*.ini; do
[ ! -f "$US_INI" ] && continue
GB_INI="$LANG_ROOT/en-GB/$(basename "$US_INI")"
if [ ! -f "$GB_INI" ]; then
echo "::error::$(basename "$US_INI") exists in en-US but missing from en-GB"
ERRORS=$((ERRORS + 1))
fi
done
fi
# Find all .ini language files
INI_FILES=$(find . -path "*/language/*/*.ini" -not -path "./.git/*" 2>/dev/null)
if [ -z "$INI_FILES" ]; then
echo "No .ini language files found"
[ "$ERRORS" -gt 0 ] && exit 1
exit 0
fi
echo "Found $(echo "$INI_FILES" | wc -l) language file(s)"
for FILE in $INI_FILES; do
FNAME=$(basename "$FILE")
LINENUM=0
SEEN_KEYS=""
while IFS= read -r line || [ -n "$line" ]; do
LINENUM=$((LINENUM + 1))
# Skip empty lines and comments
[ -z "$line" ] && continue
echo "$line" | grep -qE '^\s*;' && continue
echo "$line" | grep -qE '^\s*$' && continue
# Must match KEY="VALUE" format
if ! echo "$line" | grep -qE '^[A-Z_][A-Z0-9_]*=".*"$'; then
echo "::error file=${FILE},line=${LINENUM}::Malformed line: ${line}"
ERRORS=$((ERRORS + 1))
continue
fi
# Extract key and check for duplicates
KEY=$(echo "$line" | sed 's/=.*//')
if echo "$SEEN_KEYS" | grep -qx "$KEY"; then
echo "::error file=${FILE},line=${LINENUM}::Duplicate key: ${KEY}"
ERRORS=$((ERRORS + 1))
fi
SEEN_KEYS="${SEEN_KEYS}
${KEY}"
done < "$FILE"
echo " ${FILE}: checked ${LINENUM} lines"
done
# Cross-check en-GB vs en-US key consistency
GB_DIR=$(find . -path "*/language/en-GB" -type d -not -path "./.git/*" 2>/dev/null | head -1)
US_DIR=$(find . -path "*/language/en-US" -type d -not -path "./.git/*" 2>/dev/null | head -1)
if [ -n "$GB_DIR" ] && [ -n "$US_DIR" ]; then
for GB_FILE in "$GB_DIR"/*.ini; do
[ ! -f "$GB_FILE" ] && continue
FNAME=$(basename "$GB_FILE")
US_FILE="$US_DIR/$FNAME"
[ ! -f "$US_FILE" ] && continue
GB_KEYS=$(grep -oP '^[A-Z_][A-Z0-9_]*(?==)' "$GB_FILE" 2>/dev/null | sort)
US_KEYS=$(grep -oP '^[A-Z_][A-Z0-9_]*(?==)' "$US_FILE" 2>/dev/null | sort)
# Keys in en-GB but not en-US
MISSING_US=$(comm -23 <(echo "$GB_KEYS") <(echo "$US_KEYS"))
if [ -n "$MISSING_US" ]; then
echo "::warning::Keys in en-GB/$FNAME but missing from en-US/$FNAME:"
echo "$MISSING_US" | while read -r k; do echo " - $k"; done
WARNINGS=$((WARNINGS + 1))
fi
# Keys in en-US but not en-GB
MISSING_GB=$(comm -13 <(echo "$GB_KEYS") <(echo "$US_KEYS"))
if [ -n "$MISSING_GB" ]; then
echo "::warning::Keys in en-US/$FNAME but missing from en-GB/$FNAME:"
echo "$MISSING_GB" | while read -r k; do echo " - $k"; done
WARNINGS=$((WARNINGS + 1))
fi
done
fi
{
echo "### Language File Validation"
echo "| Metric | Count |"
echo "|---|---|"
echo "| Files checked | $(echo "$INI_FILES" | wc -l) |"
echo "| Errors | ${ERRORS} |"
echo "| Warnings | ${WARNINGS} |"
} >> $GITHUB_STEP_SUMMARY
if [ "$ERRORS" -gt 0 ]; then
echo "::error::Language validation failed with ${ERRORS} error(s)"
exit 1
fi
echo "Language files: OK (${WARNINGS} warning(s))"
- name: Check changelog has unreleased entry - name: Check changelog has unreleased entry
run: | run: |
if [ ! -f "CHANGELOG.md" ]; then if [ ! -f "CHANGELOG.md" ]; then
+9 -115
View File
@@ -11,7 +11,7 @@
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/moko-platform # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/moko-platform
# PATH: /templates/workflows/joomla/repo_health.yml.template # PATH: /templates/workflows/joomla/repo_health.yml.template
# VERSION: 09.23.00 # VERSION: 09.23.00
# BRIEF: Enforces repository guardrails by validating release configuration, scripts governance, tooling availability, and core repository health artifacts. # BRIEF: Enforces repository guardrails by validating scripts governance, tooling availability, and core repository health artifacts.
# ============================================================================ # ============================================================================
name: "Generic: Repo Health" name: "Generic: Repo Health"
@@ -24,13 +24,12 @@ on:
workflow_dispatch: workflow_dispatch:
inputs: inputs:
profile: profile:
description: 'Validation profile: all, release, scripts, or repo' description: 'Validation profile: all, scripts, or repo'
required: true required: true
default: all default: all
type: choice type: choice
options: options:
- all - all
- release
- scripts - scripts
- repo - repo
pull_request: pull_request:
@@ -40,10 +39,6 @@ permissions:
contents: read contents: read
env: env:
# Release policy - Repository Variables Only
RELEASE_REQUIRED_REPO_VARS: RS_FTP_PATH_SUFFIX
RELEASE_OPTIONAL_REPO_VARS: DEV_FTP_SUFFIX
# Scripts governance policy # Scripts governance policy
SCRIPTS_REQUIRED_DIRS: SCRIPTS_REQUIRED_DIRS:
SCRIPTS_ALLOWED_DIRS: scripts,scripts/fix,scripts/lib,scripts/release,scripts/run,scripts/validate SCRIPTS_ALLOWED_DIRS: scripts,scripts/fix,scripts/lib,scripts/release,scripts/run,scripts/validate
@@ -138,101 +133,6 @@ jobs:
printf '%s\n' 'ERROR: Access denied. Admin permission required.' >> "${GITHUB_STEP_SUMMARY}" printf '%s\n' 'ERROR: Access denied. Admin permission required.' >> "${GITHUB_STEP_SUMMARY}"
exit 1 exit 1
release_config:
name: Release configuration
needs: access_check
if: ${{ needs.access_check.outputs.allowed == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
- name: Guardrails release vars
env:
PROFILE_RAW: ${{ github.event.inputs.profile }}
RS_FTP_PATH_SUFFIX: ${{ vars.RS_FTP_PATH_SUFFIX }}
DEV_FTP_SUFFIX: ${{ vars.DEV_FTP_SUFFIX }}
run: |
set -euo pipefail
profile="${PROFILE_RAW:-all}"
case "${profile}" in
all|release|scripts|repo) ;;
*)
printf '%s\n' "ERROR: Unknown profile: ${profile}" >> "${GITHUB_STEP_SUMMARY}"
exit 1
;;
esac
if [ "${profile}" = 'scripts' ] || [ "${profile}" = 'repo' ]; then
{
printf '%s\n' '### Release configuration (Repository Variables)'
printf '%s\n' "Profile: ${profile}"
printf '%s\n' 'Status: SKIPPED'
printf '%s\n' 'Reason: profile excludes release validation'
printf '\n'
} >> "${GITHUB_STEP_SUMMARY}"
exit 0
fi
IFS=',' read -r -a required <<< "${RELEASE_REQUIRED_REPO_VARS}"
IFS=',' read -r -a optional <<< "${RELEASE_OPTIONAL_REPO_VARS}"
missing=()
missing_optional=()
for k in "${required[@]}"; do
v="${!k:-}"
[ -z "${v}" ] && missing+=("${k}")
done
for k in "${optional[@]}"; do
v="${!k:-}"
[ -z "${v}" ] && missing_optional+=("${k}")
done
{
printf '%s\n' '### Release configuration (Repository Variables)'
printf '%s\n' "Profile: ${profile}"
printf '%s\n' '| Variable | Status |'
printf '%s\n' '|---|---|'
printf '%s\n' "| RS_FTP_PATH_SUFFIX | ${RS_FTP_PATH_SUFFIX:-NOT SET} |"
printf '%s\n' "| DEV_FTP_SUFFIX | ${DEV_FTP_SUFFIX:-NOT SET} |"
printf '\n'
} >> "${GITHUB_STEP_SUMMARY}"
if [ "${#missing_optional[@]}" -gt 0 ]; then
{
printf '%s\n' '### Missing optional repository variables'
for m in "${missing_optional[@]}"; do printf '%s\n' "- ${m}"; done
printf '\n'
} >> "${GITHUB_STEP_SUMMARY}"
fi
if [ "${#missing[@]}" -gt 0 ]; then
{
printf '%s\n' '### Missing required repository variables'
for m in "${missing[@]}"; do printf '%s\n' "- ${m}"; done
printf '%s\n' 'ERROR: Guardrails failed. Missing required repository variables.'
} >> "${GITHUB_STEP_SUMMARY}"
exit 1
fi
{
printf '%s\n' '### Repository variables validation result'
printf '%s\n' 'Status: OK'
printf '%s\n' 'All required repository variables present.'
printf '%s\n' ''
printf '%s\n' '**Note**: Organization secrets (RS_FTP_HOST, RS_FTP_USER, etc.) are validated at deployment time, not in repository health checks.'
printf '\n'
} >> "${GITHUB_STEP_SUMMARY}"
scripts_governance: scripts_governance:
name: Scripts governance name: Scripts governance
needs: access_check needs: access_check
@@ -256,14 +156,14 @@ jobs:
profile="${PROFILE_RAW:-all}" profile="${PROFILE_RAW:-all}"
case "${profile}" in case "${profile}" in
all|release|scripts|repo) ;; all|scripts|repo) ;;
*) *)
printf '%s\n' "ERROR: Unknown profile: ${profile}" >> "${GITHUB_STEP_SUMMARY}" printf '%s\n' "ERROR: Unknown profile: ${profile}" >> "${GITHUB_STEP_SUMMARY}"
exit 1 exit 1
;; ;;
esac esac
if [ "${profile}" = 'release' ] || [ "${profile}" = 'repo' ]; then if [ "${profile}" = 'repo' ]; then
{ {
printf '%s\n' '### Scripts governance' printf '%s\n' '### Scripts governance'
printf '%s\n' "Profile: ${profile}" printf '%s\n' "Profile: ${profile}"
@@ -370,14 +270,14 @@ jobs:
profile="${PROFILE_RAW:-all}" profile="${PROFILE_RAW:-all}"
case "${profile}" in case "${profile}" in
all|release|scripts|repo) ;; all|scripts|repo) ;;
*) *)
printf '%s\n' "ERROR: Unknown profile: ${profile}" >> "${GITHUB_STEP_SUMMARY}" printf '%s\n' "ERROR: Unknown profile: ${profile}" >> "${GITHUB_STEP_SUMMARY}"
exit 1 exit 1
;; ;;
esac esac
if [ "${profile}" = 'release' ] || [ "${profile}" = 'scripts' ]; then if [ "${profile}" = 'scripts' ]; then
{ {
printf '%s\n' '### Repository health' printf '%s\n' '### Repository health'
printf '%s\n' "Profile: ${profile}" printf '%s\n' "Profile: ${profile}"
@@ -704,7 +604,7 @@ jobs:
printf '%s\n' '| Domain | Status | Notes |' printf '%s\n' '| Domain | Status | Notes |'
printf '%s\n' '|---|---|---|' printf '%s\n' '|---|---|---|'
printf '%s\n' '| Access control | OK | Admin-only execution gate |' printf '%s\n' '| Access control | OK | Admin-only execution gate |'
printf '%s\n' '| Release variables | OK | Repository variables validation |' printf '%s\n' '| Release policy | N/A | Releases handled by MokoGitea |'
printf '%s\n' '| Scripts governance | OK | Directory policy and advisory reporting |' printf '%s\n' '| Scripts governance | OK | Directory policy and advisory reporting |'
printf '%s\n' '| Repo required artifacts | OK | Required, optional, disallowed enforcement |' printf '%s\n' '| Repo required artifacts | OK | Required, optional, disallowed enforcement |'
printf '%s\n' '| Repo content heuristics | OK | Brand, license, changelog structure |' printf '%s\n' '| Repo content heuristics | OK | Brand, license, changelog structure |'
@@ -773,11 +673,10 @@ jobs:
report-issues: report-issues:
name: "Report Issues" name: "Report Issues"
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [access_check, release_config, scripts_governance, repo_health] needs: [access_check, scripts_governance, repo_health]
if: >- if: >-
always() && always() &&
(needs.release_config.result == 'failure' || (needs.scripts_governance.result == 'failure' ||
needs.scripts_governance.result == 'failure' ||
needs.repo_health.result == 'failure') needs.repo_health.result == 'failure')
steps: steps:
@@ -803,10 +702,6 @@ jobs:
fi fi
} }
report_gate "Release Configuration" \
"${{ needs.release_config.result }}" \
"Required repository variables are missing (RS_FTP_PATH_SUFFIX). Check repository settings."
report_gate "Scripts Governance" \ report_gate "Scripts Governance" \
"${{ needs.scripts_governance.result }}" \ "${{ needs.scripts_governance.result }}" \
"Scripts directory policy violations detected. Review required and allowed directories." "Scripts directory policy violations detected. Review required and allowed directories."
@@ -814,4 +709,3 @@ jobs:
report_gate "Repository Health" \ report_gate "Repository Health" \
"${{ needs.repo_health.result }}" \ "${{ needs.repo_health.result }}" \
"Repository health checks failed — missing required artifacts, disallowed files, or content warnings. Check the CI run summary." "Repository health checks failed — missing required artifacts, disallowed files, or content warnings. Check the CI run summary."
+3 -1
View File
@@ -32,6 +32,8 @@
</languages> </languages>
<updateservers> <updateservers>
<server type="extension" name="MokoJoomBackup Updates">https://git.mokoconsulting.tech/MokoConsulting/MokoJoomBackup/raw/branch/main/updates.xml</server> <server type="extension" name="MokoJoomBackup Updates">https://git.mokoconsulting.tech/MokoConsulting/MokoJoomBackup/updates.xml</server>
</updateservers> </updateservers>
<dlid prefix="dlid=" suffix=""/>
<blockChildUninstall>true</blockChildUninstall>
</extension> </extension>
-15
View File
@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<updates>
<update>
<name>Package - MokoJoomBackup</name>
<description>Full-site backup and restore for Joomla</description>
<element>mokobackup</element>
<type>package</type>
<version>01.00.00</version>
<infourl title="Changelog">https://git.mokoconsulting.tech/MokoConsulting/MokoJoomBackup/releases/tag/v01.00.00</infourl>
<downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoJoomBackup/releases/download/v01.00.00/pkg_mokobackup-01.00.00.zip</downloadurl>
<sha256></sha256>
<targetplatform name="joomla" version="[45]\.\d+"/>
<php_minimum>8.1.0</php_minimum>
</update>
</updates>