diff --git a/.mokogitea/workflows/pr-check.yml b/.mokogitea/workflows/pr-check.yml index 6da762a8..2cd896ca 100644 --- a/.mokogitea/workflows/pr-check.yml +++ b/.mokogitea/workflows/pr-check.yml @@ -5,8 +5,8 @@ # FILE INFORMATION # DEFGROUP: MokoGitea.Workflow # INGROUP: MokoCLI.CI -# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic -# PATH: /.mokogitea/workflows/pr-check.yml +# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli +# PATH: /templates/workflows/universal/pr-check.yml.template # VERSION: 09.23.00 # BRIEF: PR gate — branch policy + code validation before merge @@ -47,15 +47,15 @@ jobs: fi ;; fix/*|bugfix/*) - if [ "$BASE" != "dev" ] && [ "$BASE" != "main" ]; then + if [ "$BASE" != "dev" ]; then ALLOWED=false - REASON="Fix branches must target 'dev' or 'main', not '${BASE}'" + REASON="Fix branches must target 'dev', not '${BASE}'" fi ;; patch/*) - if [ "$BASE" != "dev" ] && [ "$BASE" != "rc" ] && [ "$BASE" != "main" ]; then + if [ "$BASE" != "dev" ] && [ "$BASE" != "rc" ]; then ALLOWED=false - REASON="Patch branches must target 'dev', 'rc', or 'main', not '${BASE}'" + REASON="Patch branches must target 'dev' or 'rc', not '${BASE}'" fi ;; hotfix/*) @@ -86,8 +86,7 @@ jobs: echo "" >> $GITHUB_STEP_SUMMARY echo "### Allowed merge paths:" >> $GITHUB_STEP_SUMMARY echo "- \`feature/*\` → \`dev\`" >> $GITHUB_STEP_SUMMARY - echo "- \`fix/*\` → \`dev\` or \`main\`" >> $GITHUB_STEP_SUMMARY - echo "- \`patch/*\` → \`dev\`, \`rc\`, or \`main\`" >> $GITHUB_STEP_SUMMARY + echo "- \`fix/*\` → \`dev\`" >> $GITHUB_STEP_SUMMARY echo "- \`hotfix/*\` → \`dev\` or \`main\`" >> $GITHUB_STEP_SUMMARY echo "- \`dev\` → \`main\`" >> $GITHUB_STEP_SUMMARY echo "- \`rc/*\` → \`main\`" >> $GITHUB_STEP_SUMMARY @@ -97,80 +96,6 @@ 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 @@ -210,7 +135,7 @@ jobs: - name: Check for merge conflict markers run: | - 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) + 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 @@ -224,7 +149,7 @@ 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" @@ -258,9 +183,8 @@ 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 - # 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 + # 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 @@ -351,7 +275,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 (MokoSuite site)" + echo "::warning::No Joomla manifest found (WaaS site)" exit 0 fi echo "Manifest: ${MANIFEST}"