Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c7ea43edcf | |||
| dbdb3a0e8a | |||
| 1127b23d1e | |||
| 1c646332e2 | |||
| 2deaa4faa4 | |||
| 629b8be470 | |||
| d2dd8a8da4 | |||
| ba90ce3365 | |||
| 2de8ab942b | |||
| 3ccad868bf | |||
| 4606f21a05 | |||
| aae23b46f0 | |||
| 08135beaf0 | |||
| 2cd83e0369 | |||
| a52ed25325 | |||
| 3c00fc2422 | |||
| c08015c324 | |||
| 90aa2cd58b | |||
| f17367456a | |||
| 92c4818410 | |||
| a5db8fba5b | |||
| a133d80f5f | |||
| 65cf9fbf9f | |||
| 29e5a8c85b | |||
| 17ff3ce702 |
@@ -4,7 +4,7 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: mokocli.Release
|
||||
# INGROUP: MokoCLI.Release
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
||||
# PATH: /.mokogitea/workflows/auto-bump.yml
|
||||
# VERSION: 09.02.00
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
token: ${{ secrets.MOKOGITEA_TOKEN }}
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Setup mokocli tools
|
||||
- name: Setup MokoCLI tools
|
||||
run: |
|
||||
if ! command -v composer &> /dev/null; then
|
||||
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer >/dev/null 2>&1
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
echo "MOKO_CLI=/opt/mokocli/cli" >> "$GITHUB_ENV"
|
||||
else
|
||||
git clone --depth 1 --branch main --quiet \
|
||||
"https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/MokoCLI.git" \
|
||||
"https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/mokocli.git" \
|
||||
/tmp/mokocli
|
||||
cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet
|
||||
echo "MOKO_CLI=/tmp/mokocli/cli" >> "$GITHUB_ENV"
|
||||
|
||||
@@ -4,17 +4,17 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: mokocli.Release
|
||||
# INGROUP: MokoCLI.Release
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
||||
# PATH: /.mokogitea/workflows/auto-release.yml
|
||||
# VERSION: 05.01.00
|
||||
# BRIEF: Universal build & release � detects platform from manifest.xml
|
||||
# BRIEF: Universal build & release � detects platform from metadata API
|
||||
#
|
||||
# +=======================================================================+
|
||||
# | UNIVERSAL BUILD & RELEASE PIPELINE |
|
||||
# +=======================================================================+
|
||||
# | |
|
||||
# | Reads manifest.xml (joomla|dolibarr|generic) to branch logic. |
|
||||
# | Reads metadata API (joomla|dolibarr|generic) to branch logic. |
|
||||
# | |
|
||||
# | Platform-specific: |
|
||||
# | joomla: XML manifest, type-prefixed packages |
|
||||
@@ -81,7 +81,7 @@ jobs:
|
||||
fetch-depth: 1
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup mokocli tools
|
||||
- name: Setup MokoCLI tools
|
||||
env:
|
||||
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
||||
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
|
||||
@@ -95,7 +95,7 @@ jobs:
|
||||
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1
|
||||
fi
|
||||
rm -rf /tmp/mokocli
|
||||
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/MokoCLI.git
|
||||
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
|
||||
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
|
||||
cd /tmp/mokocli
|
||||
composer install --no-dev --no-interaction --quiet
|
||||
@@ -115,20 +115,17 @@ jobs:
|
||||
SRC_SHA=$(printf '%s' "$SRC_JSON" | python3 -c "import sys, json; print(json.load(sys.stdin)['commit']['id'])" 2>/dev/null || true)
|
||||
[ -n "$SRC_SHA" ] || { echo "::error::Could not resolve HEAD of ${FROM}"; exit 1; }
|
||||
|
||||
# Point rc at the source commit. If rc already exists (a protected branch that
|
||||
# cannot be deleted), force-update its ref in place instead of delete+recreate:
|
||||
# deleting a protected branch fails, which then makes the recreate return HTTP 409.
|
||||
if curl -sf -o /dev/null -H "$AUTH" "${API_BASE}/branches/rc"; then
|
||||
echo "rc exists - force-updating to ${FROM} (${SRC_SHA})"
|
||||
curl -sf -X PATCH -H "$AUTH" -H "Content-Type: application/json" \
|
||||
"${API_BASE}/git/refs/heads/rc" -d "{\"sha\":\"${SRC_SHA}\",\"force\":true}" \
|
||||
|| { echo "::error::Failed to force-update rc (CI token needs force-push on the protected rc branch)"; exit 1; }
|
||||
else
|
||||
echo "Creating rc from ${FROM}"
|
||||
curl -sf -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
||||
"${API_BASE}/branches" -d "{\"new_branch_name\":\"rc\",\"old_branch_name\":\"${FROM}\"}" \
|
||||
|| { echo "::error::Failed to create rc from ${FROM}"; exit 1; }
|
||||
fi
|
||||
# Point rc at the source commit via git push. Gitea's git/refs PATCH API
|
||||
# returns HTTP 405 on ANY protected branch (force or not, even for a user in
|
||||
# the force-push allowlist), so it cannot move a protected rc. git push honors
|
||||
# the push + force-push allowlists and creates rc if it is absent.
|
||||
PUSH_URL="https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@${MOKOGITEA_URL#https://}/${GITEA_ORG}/${GITEA_REPO}.git"
|
||||
git config --global user.name "mokogitea-actions[bot]"
|
||||
git config --global user.email "actions@mokoconsulting.tech"
|
||||
git fetch --no-tags "$PUSH_URL" "${FROM}"
|
||||
git push --force "$PUSH_URL" "FETCH_HEAD:refs/heads/rc" \
|
||||
|| { echo "::error::Failed to point rc at ${FROM} (${SRC_SHA}) via git push"; exit 1; }
|
||||
echo "rc set to ${FROM} (${SRC_SHA})"
|
||||
|
||||
# Repoint the PR at rc, then delete the old source branch (non-fatal).
|
||||
if [ -n "$PR" ]; then
|
||||
@@ -231,7 +228,7 @@ jobs:
|
||||
fi
|
||||
echo "No conflict markers found"
|
||||
|
||||
- name: Setup mokocli tools
|
||||
- name: Setup MokoCLI tools
|
||||
env:
|
||||
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
||||
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
|
||||
@@ -246,7 +243,7 @@ jobs:
|
||||
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1
|
||||
fi
|
||||
rm -rf /tmp/mokocli
|
||||
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/MokoCLI.git
|
||||
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
|
||||
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
|
||||
cd /tmp/mokocli
|
||||
composer install --no-dev --no-interaction --quiet
|
||||
@@ -377,13 +374,47 @@ jobs:
|
||||
if [ -n "$VERSION" ] && [ -f "CHANGELOG.md" ]; then
|
||||
DATE=$(date +%Y-%m-%d)
|
||||
python3 -c "
|
||||
import sys
|
||||
import sys, re
|
||||
version, date = sys.argv[1], sys.argv[2]
|
||||
content = open('CHANGELOG.md').read()
|
||||
old = '## [Unreleased]'
|
||||
new = f'## [Unreleased]\n\n## [{version}] --- {date}'
|
||||
content = content if ('## [' + version + ']') in content else content.replace(old, new, 1)
|
||||
open('CHANGELOG.md', 'w').write(content)
|
||||
lines = open('CHANGELOG.md').read().split('\n')
|
||||
h2 = re.compile(r'^##\s+\[([^\]]+)\]')
|
||||
header, sections, cur = [], [], None
|
||||
for ln in lines:
|
||||
m = h2.match(ln)
|
||||
if m:
|
||||
if cur: sections.append(cur)
|
||||
cur = {'label': m.group(1).strip(), 'head': ln, 'body': []}
|
||||
elif cur is None:
|
||||
header.append(ln)
|
||||
else:
|
||||
cur['body'].append(ln)
|
||||
if cur: sections.append(cur)
|
||||
def nonempty(b): return any(x.strip() for x in b)
|
||||
def trim(b):
|
||||
b = b[:]
|
||||
while b and not b[0].strip(): b.pop(0)
|
||||
while b and not b[-1].strip(): b.pop()
|
||||
return b
|
||||
unreleased, order, bykey = [], [], {}
|
||||
for s in sections:
|
||||
key = s['label'].lower()
|
||||
if key == 'unreleased':
|
||||
if nonempty(s['body']): unreleased += s['body']
|
||||
continue
|
||||
if not nonempty(s['body']): continue # drop blank release sections
|
||||
if key in bykey: bykey[key]['body'] += [''] + s['body'] # merge duplicate heading (never drop content)
|
||||
else: bykey[key] = s; order.append(key)
|
||||
rest, seen = [bykey[k] for k in order], set(order)
|
||||
out = []
|
||||
htxt = '\n'.join(header).rstrip()
|
||||
if htxt: out += [htxt, '']
|
||||
out += ['## [Unreleased]', '']
|
||||
promote = bool(unreleased) and version.lower() not in seen
|
||||
if unreleased and not promote: out += trim(unreleased) + ['']
|
||||
if promote: out += ['## [%s] --- %s' % (version, date), ''] + trim(unreleased) + ['']
|
||||
for s in rest: out += [s['head'], ''] + trim(s['body']) + ['']
|
||||
res = re.sub(r'\n{3,}', '\n\n', '\n'.join(out)).rstrip('\n') + '\n'
|
||||
open('CHANGELOG.md', 'w').write(res)
|
||||
" "$VERSION" "$DATE"
|
||||
git add CHANGELOG.md
|
||||
git commit -m "chore: promote changelog [Unreleased] → [${VERSION}]" || true
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: MokoStandards.Universal
|
||||
# INGROUP: MokoCLI.Universal
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
||||
# PATH: /.mokogitea/workflows/branch-cleanup.yml
|
||||
# VERSION: 01.00.00
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: MokoStandards.Cascade
|
||||
# INGROUP: MokoCLI.Cascade
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
||||
# PATH: /.mokogitea/workflows/cascade-dev.yml
|
||||
# VERSION: 02.00.00
|
||||
# BRIEF: Cascade main -> dev via PR; auto-merge only if conflict-free, else notify
|
||||
# VERSION: 02.01.00
|
||||
# BRIEF: Cascade main -> dev; auto-merge clean, auto-resolve VERSION-stamp-only conflicts, else notify
|
||||
|
||||
name: "Cascade Main -> Dev"
|
||||
|
||||
@@ -16,6 +16,10 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
# Daily safety net: catches drift even when main only received [skip ci] pushes
|
||||
# (which never fire the push trigger above). Off-round minute to avoid a fleet-wide spike.
|
||||
schedule:
|
||||
- cron: '23 7 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
@@ -33,7 +37,13 @@ jobs:
|
||||
name: Cascade main -> dev
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Open main -> dev PR (auto-merge if clean, else notify)
|
||||
- name: Checkout (full history for merge/resolve)
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.MOKOGITEA_TOKEN }}
|
||||
|
||||
- name: Cascade main -> dev (auto-resolve version stamps, else notify)
|
||||
env:
|
||||
TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
||||
REPO: ${{ github.repository }}
|
||||
@@ -41,7 +51,7 @@ jobs:
|
||||
set -uo pipefail
|
||||
API="${MOKOGITEA_URL}/api/v1/repos/${REPO}"
|
||||
AUTH="Authorization: token ${TOKEN}"
|
||||
jqnum() { python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('$1',''))" 2>/dev/null; }
|
||||
jqget() { python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('$1',''))" 2>/dev/null; }
|
||||
|
||||
# 0. dev must exist
|
||||
if ! curl -sf -H "$AUTH" "${API}/branches/dev" >/dev/null 2>&1; then
|
||||
@@ -61,8 +71,8 @@ jobs:
|
||||
| python3 -c "import sys,json; d=json.load(sys.stdin); print(next((str(p['number']) for p in d if p.get('head',{}).get('ref')=='main'), ''))" 2>/dev/null || echo "")
|
||||
if [ -z "$PR" ]; then
|
||||
RESP=$(curl -s -H "$AUTH" -H "Content-Type: application/json" -X POST "${API}/pulls" \
|
||||
-d '{"head":"main","base":"dev","title":"chore(sync): cascade main -> dev","body":"Automated cascade of main into dev. Auto-merges only if conflict-free; otherwise left open for manual resolution."}')
|
||||
PR=$(printf '%s' "$RESP" | jqnum number)
|
||||
-d '{"head":"main","base":"dev","title":"chore(sync): cascade main -> dev","body":"Automated cascade of main into dev. Auto-merges when conflict-free, auto-resolves VERSION-stamp-only conflicts, otherwise left open for manual resolution."}')
|
||||
PR=$(printf '%s' "$RESP" | jqget number)
|
||||
if [ -z "$PR" ]; then
|
||||
echo "::warning::Could not open cascade PR: $RESP"; exit 0
|
||||
fi
|
||||
@@ -71,15 +81,6 @@ jobs:
|
||||
echo "Reusing open cascade PR #${PR}"
|
||||
fi
|
||||
|
||||
# 3. wait for MokoGitea to compute mergeability (conflict detection)
|
||||
MERGEABLE=""
|
||||
for _ in 1 2 3 4 5 6; do
|
||||
MERGEABLE=$(curl -sf -H "$AUTH" "${API}/pulls/${PR}" | jqnum mergeable)
|
||||
case "$MERGEABLE" in True|False) break ;; esac
|
||||
sleep 3
|
||||
done
|
||||
echo "mergeable=${MERGEABLE}"
|
||||
|
||||
notify() {
|
||||
curl -sS \
|
||||
-H "Title: ${REPO}: dev cascade needs manual merge" \
|
||||
@@ -90,17 +91,100 @@ jobs:
|
||||
"${NTFY_URL}/${NTFY_TOPIC}" || true
|
||||
}
|
||||
|
||||
# 4. auto-merge only if conflict-free; otherwise notify
|
||||
# 3. wait for MokoGitea to compute mergeability (conflict detection)
|
||||
MERGEABLE=""
|
||||
for _ in 1 2 3 4 5 6; do
|
||||
MERGEABLE=$(curl -sf -H "$AUTH" "${API}/pulls/${PR}" | jqget mergeable)
|
||||
case "$MERGEABLE" in True|False) break ;; esac
|
||||
sleep 3
|
||||
done
|
||||
echo "mergeable=${MERGEABLE}"
|
||||
|
||||
# 4a. conflict-free -> merge via API (existing behaviour)
|
||||
if [ "$MERGEABLE" = "True" ]; then
|
||||
CODE=$(curl -s -o /tmp/merge.json -w "%{http_code}" -H "$AUTH" -H "Content-Type: application/json" \
|
||||
-X POST "${API}/pulls/${PR}/merge" -d '{"Do":"merge","merge_when_checks_succeed":true}')
|
||||
if [ "$CODE" -ge 200 ] && [ "$CODE" -lt 300 ]; then
|
||||
echo "Cascade PR #${PR} merged (or scheduled to merge when checks pass)."
|
||||
else
|
||||
echo "::warning::Auto-merge returned HTTP ${CODE}: $(cat /tmp/merge.json)"
|
||||
notify "could not be auto-merged (HTTP ${CODE})."
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
echo "::warning::Cascade PR #${PR} has conflicts (mergeable=${MERGEABLE}); sending notification."
|
||||
notify "has conflicts and cannot be merged automatically."
|
||||
echo "::warning::Auto-merge returned HTTP ${CODE}: $(cat /tmp/merge.json)"
|
||||
notify "could not be auto-merged (HTTP ${CODE})."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 4b. conflicts -> try to auto-resolve if they are ONLY VERSION-stamp lines.
|
||||
echo "PR not cleanly mergeable; checking whether conflicts are VERSION-stamp-only..."
|
||||
git config user.name "MokoGitea Cascade"
|
||||
git config user.email "actions@mokoconsulting.tech"
|
||||
git fetch --quiet origin main dev
|
||||
git checkout -B dev origin/dev
|
||||
|
||||
if git merge --no-ff --no-commit origin/main >/dev/null 2>&1; then
|
||||
# Became clean at git level (e.g. mergeability was still computing) -> commit + push.
|
||||
git commit -m "chore(sync): cascade main -> dev [skip ci]" >/dev/null
|
||||
git push origin dev
|
||||
echo "Cascade merged cleanly at git level and pushed to dev."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
CONFLICTS=$(git diff --name-only --diff-filter=U)
|
||||
echo "Conflicted files:"; echo "${CONFLICTS}"
|
||||
|
||||
# A conflict is "stamp-only" when every line inside every conflict block matches
|
||||
# a version-stamp pattern (VERSION: header, <version> element, or CHANGELOG title).
|
||||
is_stamp_only() {
|
||||
awk '
|
||||
/^<<<<<<< / { inc=1; next }
|
||||
inc && /^=======$/ { next }
|
||||
/^>>>>>>> / { inc=0; next }
|
||||
inc { if ($0 !~ /(VERSION:|<version>|# Changelog)/) { bad=1 } }
|
||||
END { exit(bad ? 1 : 0) }
|
||||
' "$1"
|
||||
}
|
||||
# Resolve a stamp-only file by keeping dev (ours) for the conflicting lines,
|
||||
# preserving all auto-merged content around them.
|
||||
keep_ours() {
|
||||
awk '
|
||||
/^<<<<<<< / { inc=1; side="ours"; next }
|
||||
inc && /^=======$/ { side="theirs"; next }
|
||||
/^>>>>>>> / { inc=0; next }
|
||||
{ if (!inc) { print; next } if (side=="ours") print }
|
||||
' "$1" > "$1.resolved" && mv "$1.resolved" "$1"
|
||||
}
|
||||
|
||||
ALL_STAMP=1
|
||||
for f in ${CONFLICTS}; do
|
||||
if ! is_stamp_only "$f"; then
|
||||
echo "::notice::$f has non-stamp conflicts -> manual resolution required."
|
||||
ALL_STAMP=0; break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$ALL_STAMP" != "1" ]; then
|
||||
git merge --abort || true
|
||||
notify "has non-version-stamp conflicts and cannot be auto-resolved."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "All conflicts are VERSION-stamp-only; resolving in favour of dev."
|
||||
for f in ${CONFLICTS}; do
|
||||
keep_ours "$f"
|
||||
git add "$f"
|
||||
done
|
||||
|
||||
# Best-effort: normalise stamps to dev's version if mokocli is available.
|
||||
if [ -f /opt/mokocli/cli/version_check.php ]; then
|
||||
php /opt/mokocli/cli/version_check.php --fix || true
|
||||
git add -A
|
||||
fi
|
||||
|
||||
git commit -m "chore(sync): cascade main -> dev (auto-resolved version stamps) [skip ci]" >/dev/null
|
||||
git push origin dev
|
||||
echo "Cascade auto-resolved and pushed to dev."
|
||||
|
||||
# Close the now-redundant PR (its changes are in dev) with an explanatory comment.
|
||||
curl -s -H "$AUTH" -H "Content-Type: application/json" -X POST "${API}/issues/${PR}/comments" \
|
||||
-d '{"body":"Auto-resolved VERSION-stamp-only conflicts and pushed the merge to dev. Closing."}' >/dev/null || true
|
||||
curl -s -H "$AUTH" -H "Content-Type: application/json" -X PATCH "${API}/pulls/${PR}" \
|
||||
-d '{"state":"closed"}' >/dev/null || true
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: MokoStandards.CI
|
||||
# INGROUP: MokoCLI.CI
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
||||
# PATH: /.mokogitea/workflows/ci-generic.yml
|
||||
# VERSION: 01.00.00
|
||||
@@ -131,7 +131,7 @@ jobs:
|
||||
test:
|
||||
name: Tests
|
||||
runs-on: ubuntu-latest
|
||||
# Independent job (no `needs: lint`): the Gitea Actions scheduler does not
|
||||
# Independent job (no `needs: lint`): the MokoGitea Actions scheduler does not
|
||||
# offer the dependent 2nd job of a needs-chain to runners, so it stalls in
|
||||
# "waiting" and is reaped by ABANDONED_JOB_TIMEOUT. Guard template repos
|
||||
# directly (same condition lint uses) instead of gating on lint's result.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: mokocli.Universal
|
||||
# INGROUP: MokoCLI.Universal
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
||||
# PATH: /.mokogitea/workflows/ci-issue-reporter.yml
|
||||
# VERSION: 01.00.00
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
||||
run: |
|
||||
MOKOGITEA_URL="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}"
|
||||
git clone --depth 1 --filter=blob:none --sparse "${MOKOGITEA_URL}/MokoConsulting/MokoCLI.git" /tmp/mokocli
|
||||
git clone --depth 1 --filter=blob:none --sparse "${MOKOGITEA_URL}/MokoConsulting/mokocli.git" /tmp/mokocli
|
||||
cd /tmp/mokocli && git sparse-checkout set cli/ci_issue_reporter.sh
|
||||
|
||||
- name: Report CI failure
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: MokoStandards.Maintenance
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
|
||||
# INGROUP: MokoCLI.Maintenance
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
# PATH: /.mokogitea/workflows/cleanup.yml
|
||||
# VERSION: 01.00.00
|
||||
# BRIEF: Scheduled cleanup — delete merged branches and old workflow runs
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: MokoStandards.Security
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards-API
|
||||
# INGROUP: MokoCLI.Security
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
# PATH: /.mokogitea/workflows/gitleaks.yml
|
||||
# VERSION: 01.00.00
|
||||
# BRIEF: Secret scanning — detect leaked credentials, API keys, and tokens
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: mokocli.Automation
|
||||
# VERSION: 02.63.02
|
||||
# INGROUP: MokoCLI.Automation
|
||||
# VERSION: 01.00.00
|
||||
# BRIEF: Auto-create feature branch when an issue is opened
|
||||
|
||||
name: "Universal: Issue Branch"
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: MokoStandards.Notifications
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
|
||||
# INGROUP: MokoCLI.Notifications
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
# PATH: /.mokogitea/workflows/notify.yml
|
||||
# VERSION: 01.00.00
|
||||
# BRIEF: Push notifications via ntfy on release success or workflow failure
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: mokocli.CI
|
||||
# INGROUP: MokoCLI.CI
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
||||
# PATH: /.mokogitea/workflows/pr-check.yml
|
||||
# VERSION: 09.23.00
|
||||
@@ -224,7 +224,7 @@ jobs:
|
||||
- name: Detect platform
|
||||
id: platform
|
||||
run: |
|
||||
# Platform comes from the MokoGitea metadata API (public GET); manifest.xml is no longer used.
|
||||
# Platform comes from the MokoGitea metadata API (public GET).
|
||||
API="${GITHUB_SERVER_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${GITHUB_REPOSITORY}/metadata"
|
||||
PLATFORM="$(curl -sf "$API" 2>/dev/null | python3 -c "import sys, json; print(json.load(sys.stdin).get('platform') or '')" 2>/dev/null || true)"
|
||||
[ -z "$PLATFORM" ] && PLATFORM="generic"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: mokocli.Release
|
||||
# INGROUP: MokoCLI.Release
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
||||
# PATH: /.mokogitea/workflows/pre-release.yml
|
||||
# VERSION: 05.02.01
|
||||
@@ -69,7 +69,7 @@ jobs:
|
||||
run: |
|
||||
git submodule foreach --quiet 'git checkout main && git pull --quiet origin main' 2>/dev/null || true
|
||||
|
||||
- name: Setup mokocli tools
|
||||
- name: Setup MokoCLI tools
|
||||
env:
|
||||
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
||||
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
|
||||
@@ -84,7 +84,7 @@ jobs:
|
||||
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1
|
||||
fi
|
||||
rm -rf /tmp/mokocli
|
||||
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/MokoCLI.git
|
||||
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
|
||||
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
|
||||
cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet
|
||||
echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: mokocli.Universal
|
||||
# INGROUP: MokoCLI.Universal
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
||||
# PATH: /.mokogitea/workflows/rc-revert.yml
|
||||
# VERSION: 09.23.00
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: mokocli.Validation
|
||||
# INGROUP: MokoCLI.Validation
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
||||
# PATH: /.mokogitea/workflows/repo-health.yml
|
||||
# VERSION: 09.23.00
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,10 +12,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ startsWith(github.event.repository.name, 'Template-') }}
|
||||
steps:
|
||||
- name: Checkout mokocli
|
||||
- name: Checkout MokoCLI
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: MokoConsulting/MokoCLI
|
||||
repository: MokoConsulting/mokocli
|
||||
token: ${{ secrets.MOKOGITEA_TOKEN }}
|
||||
|
||||
- name: Setup PHP
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow.Template
|
||||
# INGROUP: MokoStandards.CI
|
||||
# INGROUP: MokoCLI.CI
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla
|
||||
# PATH: /.mokogitea/workflows/version-set.yml
|
||||
# VERSION: 01.00.00
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoGitea.Workflow
|
||||
# INGROUP: mokocli.Universal
|
||||
# INGROUP: MokoCLI.Universal
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
||||
# PATH: /.mokogitea/workflows/workflow-sync-trigger.yml
|
||||
# VERSION: 01.01.00
|
||||
@@ -48,12 +48,12 @@ jobs:
|
||||
echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT"
|
||||
echo "Platform: ${PLATFORM:-all}"
|
||||
|
||||
- name: Clone mokocli
|
||||
- name: Clone MokoCLI
|
||||
env:
|
||||
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
||||
run: |
|
||||
MOKOGITEA_URL="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}"
|
||||
git clone --depth 1 "${MOKOGITEA_URL}/MokoConsulting/MokoCLI.git" /tmp/mokocli
|
||||
git clone --depth 1 "${MOKOGITEA_URL}/MokoConsulting/mokocli.git" /tmp/mokocli
|
||||
|
||||
- name: Install PHP
|
||||
run: |
|
||||
|
||||
+2
-20
@@ -1,6 +1,8 @@
|
||||
# Changelog
|
||||
## [Unreleased]
|
||||
|
||||
## [02.63.00] --- 2026-07-13
|
||||
|
||||
## [02.62.00] --- 2026-07-13
|
||||
|
||||
## [02.61.00] --- 2026-07-13
|
||||
@@ -35,23 +37,3 @@
|
||||
- Archive names for **CLI/console-triggered backups** no longer come out as `joomla.invalid_…`. The `[HOST]` placeholder took `$_SERVER['HTTP_HOST']` verbatim, but Joomla's console fills that with the reserved sentinel host `joomla.invalid`; the resolver now treats that (like empty/`localhost`) as unusable and falls back to the configured `live_site` host, then the system hostname. (Set the site's *live_site* to get the exact domain in CLI-built names.)
|
||||
- Standalone restore script generation no longer aborts backups with `str_replace() expects at least 3 arguments, 2 given`. `MokoRestore::generateStandaloneScript()` had a `str_replace()` call (the "Backup Archive" pre-check rewrite) that was missing its `$php` subject argument, so **every** standalone-mode backup fatally errored while "Generating standalone restore.php…" — the archive still finalized and uploaded, but no `restore.php` was ever produced (the true root cause behind #226). (#226)
|
||||
- Remote upload: the standalone restore script upload is no longer silent — its result is now checked and logged, and a failed restore-script upload marks the backup as `warning` (previously the result was discarded, so a missing restore script on the remote went unreported while the archive still showed success). (#226)
|
||||
|
||||
## [02.58.00] --- 2026-07-06
|
||||
|
||||
### Added
|
||||
- SFTP destinations: **upload an SSH private key file** in the Add/Edit Destination modal instead of pasting it (reads the file into the key field client-side; pasting still works).
|
||||
|
||||
### Changed
|
||||
- Add/Edit Destination modal: wrap the content in a Bootstrap `.container-fluid` and give it a 1rem padding frame via the WAM stylesheet (Bootstrap's `.modal-content` has no padding of its own).
|
||||
|
||||
### Fixed
|
||||
- Pre-update backup now shows an admin notification on **every** outcome (success / warning / failure) — previously a *successful* pre-update backup fired nothing, so it looked like the notification wasn't working. (#192)
|
||||
|
||||
### Changed
|
||||
- Component admin CSS now loads via the Joomla **Web Asset Manager** (`media/com_mokosuitebackup/` + `joomla.asset.json`) instead of an inline `<style>` block.
|
||||
- "Keep local copy" is configured **per remote destination** (in the Add/Edit Destination modal); the redundant profile-level field and its "Remote" tab are removed.
|
||||
- Add/Edit Destination modal: cleaned up the cramped padding/margins.
|
||||
|
||||
### Fixed
|
||||
- Admin menu / duplicate-component fallout: (a) the orphaned `com_component-mokosuitebackup` is now removed in **preflight** too, so its "Backup" menu no longer collides on install ("The alias backup is already being used"); (b) `ensureSubmenuItems()` **recreates the top-level "Backup" menu** if it was deleted, instead of giving up — so Backup no longer disappears from the admin menu (and the cPanel module / MokoSuiteClient can find it again); (c) the component menu label now uses the short constant `COM_MOKOJOOMBACKUP_SHORT`. (#213 fallout)
|
||||
- Installer no longer aborts on MySQL 8 with "This command is not supported in the prepared statement protocol yet" (error 1295). The legacy remote-column purge migration (`02.56.01.sql`) used `PREPARE`/`EXECUTE`/`DEALLOCATE`, which Joomla's installer rejects; the drop now runs in the package installer script via an INFORMATION_SCHEMA-gated plain `ALTER` (portable across MariaDB and MySQL 8). (#213 update path)
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ DEFGROUP: Template-Joomla
|
||||
INGROUP: Template-Joomla.Documentation
|
||||
REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla
|
||||
PATH: /SECURITY.md
|
||||
VERSION: 02.63.02
|
||||
VERSION: 02.63.00
|
||||
BRIEF: Security vulnerability reporting and handling policy
|
||||
-->
|
||||
|
||||
|
||||
Submodule source/packages/MokoSuiteClient updated: b4e6a07083...81b2453e75
@@ -17,7 +17,7 @@
|
||||
display label there.
|
||||
-->
|
||||
<name>MokoSuiteBackup</name>
|
||||
<version>02.63.02</version>
|
||||
<version>02.63.00</version>
|
||||
<creationDate>2026-06-02</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
/* 02.62.04 — no schema changes */
|
||||
@@ -1 +0,0 @@
|
||||
/* 02.62.05 — no schema changes */
|
||||
@@ -0,0 +1 @@
|
||||
/* 02.63.00 — no schema changes */
|
||||
@@ -1 +0,0 @@
|
||||
/* 02.63.01 — no schema changes */
|
||||
@@ -1 +0,0 @@
|
||||
/* 02.63.02 — no schema changes */
|
||||
@@ -132,7 +132,7 @@ $this->getDocument()->addStyleSheet(Uri::root(true) . '/media/com_mokosuitebacku
|
||||
|
||||
<div id="msb-rb-actions" class="d-none mt-3">
|
||||
<button type="button" id="msb-rb-retry" class="btn btn-primary d-none"></button>
|
||||
<a href="#" id="msb-rb-record" class="btn btn-primary d-none" target="_blank" rel="noopener"></a>
|
||||
<a href="#" id="msb-rb-record" class="btn btn-primary d-none"></a>
|
||||
<a href="#" id="msb-rb-continue" class="btn btn-warning d-none"></a>
|
||||
<a href="<?php echo $dashboardUrl; ?>" id="msb-rb-dashboard" class="btn btn-secondary d-none"></a>
|
||||
</div>
|
||||
@@ -316,15 +316,9 @@ $this->getDocument()->addStyleSheet(Uri::root(true) . '/media/com_mokosuitebacku
|
||||
}
|
||||
}
|
||||
|
||||
/* Warn before closing/leaving the window while a backup is mid-flight.
|
||||
Return the message too — some browsers need it, others show a generic
|
||||
prompt, but any non-empty value triggers the confirmation dialog. */
|
||||
/* Warn before leaving while a backup is mid-flight. */
|
||||
window.addEventListener('beforeunload', function (e) {
|
||||
if (!running) { return undefined; }
|
||||
var msg = L.leaveWarn || 'A backup is in progress. Leaving now will cancel it.';
|
||||
e.preventDefault();
|
||||
e.returnValue = msg;
|
||||
return msg;
|
||||
if (running) { e.preventDefault(); e.returnValue = L.leaveWarn || ''; }
|
||||
});
|
||||
|
||||
if (CFG.autostart) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
-->
|
||||
<extension type="module" client="administrator" method="upgrade">
|
||||
<name>Module - MokoSuiteBackup - cPanel</name>
|
||||
<version>02.63.02</version>
|
||||
<version>02.63.00</version>
|
||||
<creationDate>2026-06-23</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
-->
|
||||
<extension type="plugin" group="actionlog" method="upgrade">
|
||||
<name>Action Log - MokoSuiteBackup</name>
|
||||
<version>02.63.02</version>
|
||||
<version>02.63.00</version>
|
||||
<creationDate>2026-06-04</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
-->
|
||||
<extension type="plugin" group="console" method="upgrade">
|
||||
<name>Console - MokoSuiteBackup</name>
|
||||
<version>02.63.02</version>
|
||||
<version>02.63.00</version>
|
||||
<creationDate>2026-06-04</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
-->
|
||||
<extension type="plugin" group="content" method="upgrade">
|
||||
<name>Content - MokoSuiteBackup</name>
|
||||
<version>02.63.02</version>
|
||||
<version>02.63.00</version>
|
||||
<creationDate>2026-06-04</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="quickicon" method="upgrade">
|
||||
<name>Quick Icon - MokoSuiteBackup</name>
|
||||
<version>02.63.02</version>
|
||||
<version>02.63.00</version>
|
||||
<creationDate>2026-06-02</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
-->
|
||||
<extension type="plugin" group="system" method="upgrade">
|
||||
<name>System - MokoSuiteBackup</name>
|
||||
<version>02.63.02</version>
|
||||
<version>02.63.00</version>
|
||||
<creationDate>2026-06-02</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
-->
|
||||
<extension type="plugin" group="task" method="upgrade">
|
||||
<name>Task - MokoSuiteBackup</name>
|
||||
<version>02.63.02</version>
|
||||
<version>02.63.00</version>
|
||||
<creationDate>2026-06-02</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
-->
|
||||
<extension type="plugin" group="webservices" method="upgrade">
|
||||
<name>Web Services - MokoSuiteBackup</name>
|
||||
<version>02.63.02</version>
|
||||
<version>02.63.00</version>
|
||||
<creationDate>2026-06-02</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<extension type="package" method="upgrade">
|
||||
<name>Package - MokoSuiteBackup</name>
|
||||
<packagename>mokosuitebackup</packagename>
|
||||
<version>02.63.02</version>
|
||||
<version>02.63.00</version>
|
||||
<creationDate>2026-06-02</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
Reference in New Issue
Block a user