From df563f7b20a66d5099bfb720f9e8fdc527fda601 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Mon, 13 Jul 2026 09:31:34 +0000 Subject: [PATCH] chore(sync): CI notify retry + JEXEC whole-file scan from Template-Generic --- .mokogitea/workflows/pr-check.yml | 107 +++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 15 deletions(-) diff --git a/.mokogitea/workflows/pr-check.yml b/.mokogitea/workflows/pr-check.yml index b935820..2874d60 100644 --- a/.mokogitea/workflows/pr-check.yml +++ b/.mokogitea/workflows/pr-check.yml @@ -3,10 +3,10 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow -# INGROUP: moko-platform.CI -# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/moko-platform -# PATH: /templates/workflows/universal/pr-check.yml.template +# DEFGROUP: MokoGitea.Workflow +# INGROUP: mokocli.CI +# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic +# PATH: /.mokogitea/workflows/pr-check.yml # VERSION: 09.23.00 # BRIEF: PR gate — branch policy + code validation before merge @@ -47,15 +47,15 @@ jobs: fi ;; fix/*|bugfix/*) - if [ "$BASE" != "dev" ]; then + if [ "$BASE" != "dev" ] && [ "$BASE" != "main" ]; then ALLOWED=false - REASON="Fix branches must target 'dev', not '${BASE}'" + REASON="Fix branches must target 'dev' or 'main', not '${BASE}'" fi ;; patch/*) - if [ "$BASE" != "dev" ] && [ "$BASE" != "rc" ]; then + if [ "$BASE" != "dev" ] && [ "$BASE" != "rc" ] && [ "$BASE" != "main" ]; then ALLOWED=false - REASON="Patch branches must target 'dev' or 'rc', not '${BASE}'" + REASON="Patch branches must target 'dev', 'rc', or 'main', not '${BASE}'" fi ;; hotfix/*) @@ -86,7 +86,8 @@ jobs: echo "" >> $GITHUB_STEP_SUMMARY echo "### Allowed merge paths:" >> $GITHUB_STEP_SUMMARY echo "- \`feature/*\` → \`dev\`" >> $GITHUB_STEP_SUMMARY - echo "- \`fix/*\` → \`dev\`" >> $GITHUB_STEP_SUMMARY + echo "- \`fix/*\` → \`dev\` or \`main\`" >> $GITHUB_STEP_SUMMARY + echo "- \`patch/*\` → \`dev\`, \`rc\`, or \`main\`" >> $GITHUB_STEP_SUMMARY echo "- \`hotfix/*\` → \`dev\` or \`main\`" >> $GITHUB_STEP_SUMMARY echo "- \`dev\` → \`main\`" >> $GITHUB_STEP_SUMMARY echo "- \`rc/*\` → \`main\`" >> $GITHUB_STEP_SUMMARY @@ -96,6 +97,80 @@ jobs: echo "Branch policy: OK (${HEAD} → ${BASE})" echo "## Branch Policy: Passed" >> $GITHUB_STEP_SUMMARY + # ── Docs Update Gate (main PRs) ───────────────────────────────────────── + require-docs: + name: Require Docs Update + runs-on: ubuntu-latest + # Enforce only on PRs merging into main: README.md + CHANGELOG.md must both be updated. + if: ${{ github.base_ref == 'main' }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Require README.md and CHANGELOG.md in the PR diff + run: | + BASE="${{ github.event.pull_request.base.sha }}" + HEAD="${{ github.event.pull_request.head.sha }}" + CHANGED="$(git diff --name-only "$BASE" "$HEAD" 2>/dev/null || true)" + if [ -z "$CHANGED" ]; then + git fetch -q origin "${{ github.base_ref }}" 2>/dev/null || true + CHANGED="$(git diff --name-only "origin/${{ github.base_ref }}...HEAD" 2>/dev/null || true)" + fi + echo "Changed files in PR:" + echo "$CHANGED" + MISSING="" + echo "$CHANGED" | grep -qxE 'README\.md' || MISSING="README.md" + echo "$CHANGED" | grep -qxE 'CHANGELOG\.md' || MISSING="${MISSING:+$MISSING, }CHANGELOG.md" + if [ -n "$MISSING" ]; then + echo "::error::PRs into main must update: ${MISSING}" + { + echo "## Docs Update Required" + echo "" + echo "PRs merging into \`main\` must update both **README.md** and **CHANGELOG.md**." + echo "" + echo "Not updated in this PR: **${MISSING}**" + } >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + echo "Docs update present (README.md + CHANGELOG.md)" + echo "## Docs Update: Passed" >> "$GITHUB_STEP_SUMMARY" + + # ── Wiki Update Reminder (main PRs, non-blocking) ─────────────────────── + wiki-reminder: + name: Wiki Update Reminder + runs-on: ubuntu-latest + if: ${{ github.base_ref == 'main' }} + steps: + - name: Remind to update the wiki + env: + TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + SERVER: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + REPO: ${{ github.repository }} + PR: ${{ github.event.pull_request.number }} + run: | + set -uo pipefail + { + echo "## Wiki Update Reminder" + echo "" + echo "Docs are **wiki-first** at MokoConsulting. If this change affects behavior, usage, configuration, or standards, update the repo wiki:" + echo "" + echo "- ${SERVER}/${REPO}/wiki" + echo "" + echo "_Non-blocking reminder._" + } >> "$GITHUB_STEP_SUMMARY" + # Post a single PR comment (idempotent via hidden marker); best-effort, never fails. + API="${SERVER}/api/v1/repos/${REPO}/issues/${PR}/comments" + if [ -n "${TOKEN:-}" ] && [ -n "${PR:-}" ]; then + existing="$(curl -sf -H "Authorization: token ${TOKEN}" "$API" 2>/dev/null | grep -c 'wiki-reminder' || true)" + if [ "${existing:-0}" -eq 0 ]; then + curl -sf -H "Authorization: token ${TOKEN}" -H "Content-Type: application/json" -X POST "$API" \ + -d '{"body":"\n\n**Wiki reminder:** docs are wiki-first -- if this PR changes behavior, usage, config, or standards, please update the repo wiki before/after merge. _(non-blocking)_"}' >/dev/null 2>&1 || true + fi + fi + echo "Wiki reminder emitted (non-blocking)." + # ── Secret Scanning ────────────────────────────────────────────────── gitleaks: name: Secret Scan @@ -135,7 +210,7 @@ jobs: - 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) + CONFLICTS=$(grep -rn '<<<<<<< \|>>>>>>> \|^=======$' --exclude-dir='.git' --exclude-dir='.mokogitea' --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 @@ -149,11 +224,12 @@ jobs: - name: Detect platform id: platform run: | - # Platform comes from the MokoGitea metadata API (public GET). + # Platform comes from the MokoGitea metadata API (public GET); manifest.xml is no longer used. 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" echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT" + echo "Detected platform: $PLATFORM" - name: Setup PHP if: steps.platform.outputs.platform == 'joomla' || steps.platform.outputs.platform == 'dolibarr' @@ -182,8 +258,9 @@ jobs: 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 + # Scan the whole file for the JEXEC/JPATH guard: it is placed after + # the SPDX/file-header docblock, which commonly runs past 20 lines. + if ! grep -qE "defined\s*\(\s*['\"](_JEXEC|JPATH_BASE|\\\\JPATH_PLATFORM)['\"]" "$file"; then echo "::error file=${file}::Missing JEXEC guard: ${file}" ERRORS=$((ERRORS + 1)) fi @@ -274,7 +351,7 @@ jobs: joomla) MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" -exec grep -l '/dev/null | head -1) if [ -z "$MANIFEST" ]; then - echo "::warning::No Joomla manifest found (WaaS site)" + echo "::warning::No Joomla manifest found (MokoSuite site)" exit 0 fi echo "Manifest: ${MANIFEST}" @@ -287,7 +364,7 @@ jobs: # 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 "::error::Manifest contains legacy raw/branch update server URL on MokoGitea. Use the MokoGitea Pages URL instead (e.g. /{REPO}/updates.xml not /{REPO}/raw/branch/main/updates.xml)" echo "$RAW_URLS" exit 1 fi