chore: Sync MokoStandards v04.04 #110
21
.github/.mokostandards
vendored
21
.github/.mokostandards
vendored
@@ -1,20 +1 @@
|
||||
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: MokoStandards.Templates.Config
|
||||
# INGROUP: MokoStandards.Templates
|
||||
# REPO: https://github.com/mokoconsulting-tech/MokoStandards
|
||||
# PATH: /templates/configs/moko-standards.yml
|
||||
# VERSION: 04.04.01
|
||||
# BRIEF: Governance attachment template — synced to .mokostandards in every governed repository
|
||||
# NOTE: Tokens replaced at sync time: mokoconsulting-tech, MokoCassiopeia, waas-component, 04.04.00
|
||||
#
|
||||
# This file is managed automatically by MokoStandards bulk sync.
|
||||
# Do not edit manually — changes will be overwritten on the next sync.
|
||||
# To update governance settings, open a PR in MokoStandards instead:
|
||||
# https://github.com/mokoconsulting-tech/MokoStandards
|
||||
|
||||
standards_source: "https://github.com/mokoconsulting-tech/MokoStandards"
|
||||
standards_version: "04.04.00"
|
||||
platform: "waas-component"
|
||||
governed_repo: "mokoconsulting-tech/MokoCassiopeia"
|
||||
platform: waas-component
|
||||
|
||||
2
.github/workflows/auto-release.yml
vendored
2
.github/workflows/auto-release.yml
vendored
@@ -64,7 +64,7 @@ jobs:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}'
|
||||
run: |
|
||||
git clone --depth 1 --branch version/04.04 --quiet \
|
||||
git clone --depth 1 --branch version/04.05 --quiet \
|
||||
"https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \
|
||||
/tmp/mokostandards
|
||||
cd /tmp/mokostandards
|
||||
|
||||
37
.github/workflows/deploy-demo.yml
vendored
37
.github/workflows/deploy-demo.yml
vendored
@@ -36,10 +36,9 @@ name: Deploy to Demo Server (SFTP)
|
||||
# Optional org-level variable: DEMO_FTP_PORT (auto-detected from host or defaults to 22)
|
||||
# Optional org/repo variable: DEMO_FTP_SUFFIX — when set, appended to DEMO_FTP_PATH to form the
|
||||
# full remote destination: DEMO_FTP_PATH/DEMO_FTP_SUFFIX
|
||||
# Ignore rules: Place a .ftp_ignore file in the repository root. Each non-empty,
|
||||
# non-comment line is a regex pattern tested against the relative path
|
||||
# of each file (e.g. "subdir/file.txt"). The .gitignore is also
|
||||
# respected automatically.
|
||||
# Ignore rules: Place a .ftpignore file in the repository root. Each non-empty,
|
||||
# non-comment line is a glob pattern tested against the relative path
|
||||
# of each file (e.g. "subdir/file.txt"). The .gitignore is NOT used.
|
||||
# Required org-level secret: DEMO_FTP_KEY (preferred) or DEMO_FTP_PASSWORD
|
||||
#
|
||||
# Access control: only users with admin or maintain role on the repository may deploy.
|
||||
@@ -195,8 +194,8 @@ jobs:
|
||||
env:
|
||||
SOURCE_DIR: ${{ steps.source.outputs.dir }}
|
||||
run: |
|
||||
# ── Convert a gitignore-style glob line to an ERE pattern ──────────────
|
||||
ftp_ignore_to_regex() {
|
||||
# ── Convert a ftpignore-style glob line to an ERE pattern ──────────────
|
||||
ftpignore_to_regex() {
|
||||
local line="$1"
|
||||
local anchored=false
|
||||
# Strip inline comments and whitespace
|
||||
@@ -226,15 +225,15 @@ jobs:
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Read .ftp_ignore (gitignore-style globs) ─────────────────────────
|
||||
# ── Read .ftpignore (ftpignore-style globs) ─────────────────────────
|
||||
IGNORE_PATTERNS=()
|
||||
IGNORE_SOURCES=()
|
||||
if [ -f ".ftp_ignore" ]; then
|
||||
if [ -f ".ftpignore" ]; then
|
||||
while IFS= read -r line; do
|
||||
[[ "$line" =~ ^[[:space:]]*$ || "$line" =~ ^[[:space:]]*# ]] && continue
|
||||
regex=$(ftp_ignore_to_regex "$line")
|
||||
regex=$(ftpignore_to_regex "$line")
|
||||
[ -n "$regex" ] && IGNORE_PATTERNS+=("$regex") && IGNORE_SOURCES+=("$line")
|
||||
done < ".ftp_ignore"
|
||||
done < ".ftpignore"
|
||||
fi
|
||||
|
||||
# ── Walk src/ and classify every file ────────────────────────────────
|
||||
@@ -245,17 +244,11 @@ jobs:
|
||||
SKIP=false
|
||||
for i in "${!IGNORE_PATTERNS[@]}"; do
|
||||
if echo "$rel" | grep -qE "${IGNORE_PATTERNS[$i]}" 2>/dev/null; then
|
||||
IGNORED_FILES+=("$rel | .ftp_ignore \`${IGNORE_SOURCES[$i]}\`")
|
||||
IGNORED_FILES+=("$rel | .ftpignore \`${IGNORE_SOURCES[$i]}\`")
|
||||
SKIP=true; break
|
||||
fi
|
||||
done
|
||||
$SKIP && continue
|
||||
if [ -f ".gitignore" ]; then
|
||||
git check-ignore -q "$rel" 2>/dev/null && {
|
||||
IGNORED_FILES+=("$rel | .gitignore")
|
||||
continue
|
||||
} || true
|
||||
fi
|
||||
WILL_UPLOAD+=("$rel")
|
||||
done < <(find "$SOURCE_DIR" -type f -print0 | sort -z)
|
||||
|
||||
@@ -426,7 +419,7 @@ jobs:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}'
|
||||
run: |
|
||||
git clone --depth 1 --branch version/04.04 --quiet \
|
||||
git clone --depth 1 --branch version/04.05 --quiet \
|
||||
"https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \
|
||||
/tmp/mokostandards
|
||||
cd /tmp/mokostandards
|
||||
@@ -637,8 +630,12 @@ jobs:
|
||||
DEPLOY_ARGS+=(--key-passphrase "$SFTP_PASSWORD")
|
||||
fi
|
||||
|
||||
php /tmp/mokostandards/api/deploy/deploy-sftp.php "${DEPLOY_ARGS[@]}"
|
||||
# (deploy-sftp.php handles dotfile skipping and .ftp_ignore natively)
|
||||
PLATFORM=$(php /tmp/mokostandards/api/cli/platform_detect.php --path . 2>/dev/null || true)
|
||||
if [ "$PLATFORM" = "waas-component" ] && [ -f "/tmp/mokostandards/api/deploy/deploy-joomla.php" ]; then
|
||||
php /tmp/mokostandards/api/deploy/deploy-joomla.php "${DEPLOY_ARGS[@]}"
|
||||
else
|
||||
php /tmp/mokostandards/api/deploy/deploy-sftp.php "${DEPLOY_ARGS[@]}"
|
||||
fi
|
||||
# Remove temp files that should never be left behind
|
||||
rm -f /tmp/deploy_key /tmp/sftp-config.json
|
||||
|
||||
|
||||
44
.github/workflows/deploy-dev.yml
vendored
44
.github/workflows/deploy-dev.yml
vendored
@@ -37,10 +37,9 @@ name: Deploy to Dev Server (SFTP)
|
||||
# Optional org-level variable: DEV_FTP_PORT (auto-detected from host or defaults to 22)
|
||||
# Optional org/repo variable: DEV_FTP_SUFFIX — when set, appended to DEV_FTP_PATH to form the
|
||||
# full remote destination: DEV_FTP_PATH/DEV_FTP_SUFFIX
|
||||
# Ignore rules: Place a .ftp_ignore file in the repository root. Each non-empty,
|
||||
# non-comment line is a regex pattern tested against the relative path
|
||||
# of each file (e.g. "subdir/file.txt"). The .gitignore is also
|
||||
# respected automatically.
|
||||
# Ignore rules: Place a .ftpignore file in the repository root. Each non-empty,
|
||||
# non-comment line is a glob pattern tested against the relative path
|
||||
# of each file (e.g. "subdir/file.txt"). The .gitignore is NOT used.
|
||||
# Required org-level secret: DEV_FTP_KEY (preferred) or DEV_FTP_PASSWORD
|
||||
#
|
||||
# Access control: only users with admin or maintain role on the repository may deploy.
|
||||
@@ -200,8 +199,8 @@ jobs:
|
||||
env:
|
||||
SOURCE_DIR: ${{ steps.source.outputs.dir }}
|
||||
run: |
|
||||
# ── Convert a gitignore-style glob line to an ERE pattern ──────────────
|
||||
ftp_ignore_to_regex() {
|
||||
# ── Convert a ftpignore-style glob line to an ERE pattern ──────────────
|
||||
ftpignore_to_regex() {
|
||||
local line="$1"
|
||||
local anchored=false
|
||||
# Strip inline comments and whitespace
|
||||
@@ -231,15 +230,15 @@ jobs:
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Read .ftp_ignore (gitignore-style globs) ─────────────────────────
|
||||
# ── Read .ftpignore (ftpignore-style globs) ─────────────────────────
|
||||
IGNORE_PATTERNS=()
|
||||
IGNORE_SOURCES=()
|
||||
if [ -f ".ftp_ignore" ]; then
|
||||
if [ -f ".ftpignore" ]; then
|
||||
while IFS= read -r line; do
|
||||
[[ "$line" =~ ^[[:space:]]*$ || "$line" =~ ^[[:space:]]*# ]] && continue
|
||||
regex=$(ftp_ignore_to_regex "$line")
|
||||
regex=$(ftpignore_to_regex "$line")
|
||||
[ -n "$regex" ] && IGNORE_PATTERNS+=("$regex") && IGNORE_SOURCES+=("$line")
|
||||
done < ".ftp_ignore"
|
||||
done < ".ftpignore"
|
||||
fi
|
||||
|
||||
# ── Walk src/ and classify every file ────────────────────────────────
|
||||
@@ -250,17 +249,11 @@ jobs:
|
||||
SKIP=false
|
||||
for i in "${!IGNORE_PATTERNS[@]}"; do
|
||||
if echo "$rel" | grep -qE "${IGNORE_PATTERNS[$i]}" 2>/dev/null; then
|
||||
IGNORED_FILES+=("$rel | .ftp_ignore \`${IGNORE_SOURCES[$i]}\`")
|
||||
IGNORED_FILES+=("$rel | .ftpignore \`${IGNORE_SOURCES[$i]}\`")
|
||||
SKIP=true; break
|
||||
fi
|
||||
done
|
||||
$SKIP && continue
|
||||
if [ -f ".gitignore" ]; then
|
||||
git check-ignore -q "$rel" 2>/dev/null && {
|
||||
IGNORED_FILES+=("$rel | .gitignore")
|
||||
continue
|
||||
} || true
|
||||
fi
|
||||
WILL_UPLOAD+=("$rel")
|
||||
done < <(find "$SOURCE_DIR" -type f -print0 | sort -z)
|
||||
|
||||
@@ -431,7 +424,7 @@ jobs:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}'
|
||||
run: |
|
||||
git clone --depth 1 --branch version/04.04 --quiet \
|
||||
git clone --depth 1 --branch version/04.05 --quiet \
|
||||
"https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \
|
||||
/tmp/mokostandards
|
||||
cd /tmp/mokostandards
|
||||
@@ -583,8 +576,8 @@ jobs:
|
||||
fi
|
||||
|
||||
# Dev deploys skip minified files — use unminified sources for debugging
|
||||
echo "*.min.js" >> .ftp_ignore
|
||||
echo "*.min.css" >> .ftp_ignore
|
||||
echo "*.min.js" >> .ftpignore
|
||||
echo "*.min.css" >> .ftpignore
|
||||
|
||||
# ── Run deploy-sftp.php from MokoStandards ────────────────────────────
|
||||
DEPLOY_ARGS=(--path . --src-dir "$SOURCE_DIR" --config /tmp/sftp-config.json)
|
||||
@@ -666,8 +659,15 @@ jobs:
|
||||
fi
|
||||
fi
|
||||
|
||||
php /tmp/mokostandards/api/deploy/deploy-sftp.php "${DEPLOY_ARGS[@]}"
|
||||
# (deploy-sftp.php handles dotfile skipping and .ftp_ignore natively)
|
||||
# Use Joomla-aware deploy for waas-component (routes files to correct Joomla dirs)
|
||||
# Use standard SFTP deploy for everything else
|
||||
PLATFORM=$(php /tmp/mokostandards/api/cli/platform_detect.php --path . 2>/dev/null || true)
|
||||
if [ "$PLATFORM" = "waas-component" ] && [ -f "/tmp/mokostandards/api/deploy/deploy-joomla.php" ]; then
|
||||
php /tmp/mokostandards/api/deploy/deploy-joomla.php "${DEPLOY_ARGS[@]}"
|
||||
else
|
||||
php /tmp/mokostandards/api/deploy/deploy-sftp.php "${DEPLOY_ARGS[@]}"
|
||||
fi
|
||||
# (both scripts handle dotfile skipping and .ftpignore natively)
|
||||
# Remove temp files that should never be left behind
|
||||
rm -f /tmp/deploy_key /tmp/sftp-config.json
|
||||
|
||||
|
||||
37
.github/workflows/deploy-rs.yml
vendored
37
.github/workflows/deploy-rs.yml
vendored
@@ -36,10 +36,9 @@ name: Deploy to RS Server (SFTP)
|
||||
# Optional org-level variable: RS_FTP_PORT (auto-detected from host or defaults to 22)
|
||||
# Optional org/repo variable: RS_FTP_SUFFIX — when set, appended to RS_FTP_PATH to form the
|
||||
# full remote destination: RS_FTP_PATH/RS_FTP_SUFFIX
|
||||
# Ignore rules: Place a .ftp_ignore file in the repository root. Each non-empty,
|
||||
# non-comment line is a regex pattern tested against the relative path
|
||||
# of each file (e.g. "subdir/file.txt"). The .gitignore is also
|
||||
# respected automatically.
|
||||
# Ignore rules: Place a .ftpignore file in the repository root. Each non-empty,
|
||||
# non-comment line is a glob pattern tested against the relative path
|
||||
# of each file (e.g. "subdir/file.txt"). The .gitignore is NOT used.
|
||||
# Required org-level secret: RS_FTP_KEY (preferred) or RS_FTP_PASSWORD
|
||||
#
|
||||
# Access control: only users with admin or maintain role on the repository may deploy.
|
||||
@@ -195,8 +194,8 @@ jobs:
|
||||
env:
|
||||
SOURCE_DIR: ${{ steps.source.outputs.dir }}
|
||||
run: |
|
||||
# ── Convert a gitignore-style glob line to an ERE pattern ──────────────
|
||||
ftp_ignore_to_regex() {
|
||||
# ── Convert a ftpignore-style glob line to an ERE pattern ──────────────
|
||||
ftpignore_to_regex() {
|
||||
local line="$1"
|
||||
local anchored=false
|
||||
# Strip inline comments and whitespace
|
||||
@@ -226,15 +225,15 @@ jobs:
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Read .ftp_ignore (gitignore-style globs) ─────────────────────────
|
||||
# ── Read .ftpignore (ftpignore-style globs) ─────────────────────────
|
||||
IGNORE_PATTERNS=()
|
||||
IGNORE_SOURCES=()
|
||||
if [ -f ".ftp_ignore" ]; then
|
||||
if [ -f ".ftpignore" ]; then
|
||||
while IFS= read -r line; do
|
||||
[[ "$line" =~ ^[[:space:]]*$ || "$line" =~ ^[[:space:]]*# ]] && continue
|
||||
regex=$(ftp_ignore_to_regex "$line")
|
||||
regex=$(ftpignore_to_regex "$line")
|
||||
[ -n "$regex" ] && IGNORE_PATTERNS+=("$regex") && IGNORE_SOURCES+=("$line")
|
||||
done < ".ftp_ignore"
|
||||
done < ".ftpignore"
|
||||
fi
|
||||
|
||||
# ── Walk src/ and classify every file ────────────────────────────────
|
||||
@@ -245,17 +244,11 @@ jobs:
|
||||
SKIP=false
|
||||
for i in "${!IGNORE_PATTERNS[@]}"; do
|
||||
if echo "$rel" | grep -qE "${IGNORE_PATTERNS[$i]}" 2>/dev/null; then
|
||||
IGNORED_FILES+=("$rel | .ftp_ignore \`${IGNORE_SOURCES[$i]}\`")
|
||||
IGNORED_FILES+=("$rel | .ftpignore \`${IGNORE_SOURCES[$i]}\`")
|
||||
SKIP=true; break
|
||||
fi
|
||||
done
|
||||
$SKIP && continue
|
||||
if [ -f ".gitignore" ]; then
|
||||
git check-ignore -q "$rel" 2>/dev/null && {
|
||||
IGNORED_FILES+=("$rel | .gitignore")
|
||||
continue
|
||||
} || true
|
||||
fi
|
||||
WILL_UPLOAD+=("$rel")
|
||||
done < <(find "$SOURCE_DIR" -type f -print0 | sort -z)
|
||||
|
||||
@@ -407,7 +400,7 @@ jobs:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}'
|
||||
run: |
|
||||
git clone --depth 1 --branch version/04.04 --quiet \
|
||||
git clone --depth 1 --branch version/04.05 --quiet \
|
||||
"https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \
|
||||
/tmp/mokostandards
|
||||
cd /tmp/mokostandards
|
||||
@@ -564,8 +557,12 @@ jobs:
|
||||
DEPLOY_ARGS+=(--key-passphrase "$SFTP_PASSWORD")
|
||||
fi
|
||||
|
||||
php /tmp/mokostandards/api/deploy/deploy-sftp.php "${DEPLOY_ARGS[@]}"
|
||||
# (deploy-sftp.php handles dotfile skipping and .ftp_ignore natively)
|
||||
PLATFORM=$(php /tmp/mokostandards/api/cli/platform_detect.php --path . 2>/dev/null || true)
|
||||
if [ "$PLATFORM" = "waas-component" ] && [ -f "/tmp/mokostandards/api/deploy/deploy-joomla.php" ]; then
|
||||
php /tmp/mokostandards/api/deploy/deploy-joomla.php "${DEPLOY_ARGS[@]}"
|
||||
else
|
||||
php /tmp/mokostandards/api/deploy/deploy-sftp.php "${DEPLOY_ARGS[@]}"
|
||||
fi
|
||||
# Remove temp files that should never be left behind
|
||||
rm -f /tmp/deploy_key /tmp/sftp-config.json
|
||||
|
||||
|
||||
95
.github/workflows/repo_health.yml
vendored
95
.github/workflows/repo_health.yml
vendored
@@ -10,7 +10,7 @@
|
||||
# INGROUP: MokoStandards.Validation
|
||||
# REPO: https://github.com/mokoconsulting-tech/MokoStandards
|
||||
# PATH: /.github/workflows/repo_health.yml
|
||||
# VERSION: 04.01.00
|
||||
# VERSION: 04.05.00
|
||||
# BRIEF: Enforces repository guardrails by validating release configuration, scripts governance, tooling availability, and core repository health artifacts.
|
||||
# NOTE: Field is user-managed.
|
||||
# ============================================================================
|
||||
@@ -29,7 +29,7 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
profile:
|
||||
description: Which configuration profile to validate. release checks SFTP variables used by release pipeline. scripts checks baseline script prerequisites. repo runs repository health only. al[...]
|
||||
description: 'Validation profile: all, release, scripts, or repo'
|
||||
required: true
|
||||
default: all
|
||||
type: choice
|
||||
@@ -39,19 +39,7 @@ on:
|
||||
- scripts
|
||||
- repo
|
||||
pull_request:
|
||||
paths:
|
||||
- .github/workflows/**
|
||||
- scripts/**
|
||||
- docs/**
|
||||
- dev/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- .github/workflows/**
|
||||
- scripts/**
|
||||
- docs/**
|
||||
- dev/**
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -68,7 +56,7 @@ env:
|
||||
|
||||
# Repo health policy
|
||||
# Files are listed as-is; directories must end with a trailing slash.
|
||||
REPO_REQUIRED_ARTIFACTS: README.md,LICENSE,CHANGELOG.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,.github/workflows/,src/
|
||||
REPO_REQUIRED_ARTIFACTS: README.md,LICENSE,CHANGELOG.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,.github/workflows/
|
||||
REPO_OPTIONAL_FILES: SECURITY.md,GOVERNANCE.md,.editorconfig,.gitattributes,.gitignore,README.md,docs/
|
||||
REPO_DISALLOWED_DIRS:
|
||||
REPO_DISALLOWED_FILES: TODO.md,todo.md
|
||||
@@ -82,6 +70,7 @@ env:
|
||||
WORKFLOWS_DIR: .github/workflows
|
||||
SHELLCHECK_PATTERN: '*.sh'
|
||||
SPDX_FILE_GLOBS: '*.sh,*.php,*.js,*.ts,*.css,*.xml,*.yml,*.yaml'
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||
|
||||
jobs:
|
||||
access_check:
|
||||
@@ -412,6 +401,15 @@ jobs:
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Source directory: src/ or htdocs/ (either is valid)
|
||||
if [ -d "src" ]; then
|
||||
SOURCE_DIR="src"
|
||||
elif [ -d "htdocs" ]; then
|
||||
SOURCE_DIR="htdocs"
|
||||
else
|
||||
missing_required+=("src/ or htdocs/ (source directory required)")
|
||||
fi
|
||||
|
||||
IFS=',' read -r -a required_artifacts <<< "${REPO_REQUIRED_ARTIFACTS}"
|
||||
IFS=',' read -r -a optional_files <<< "${REPO_OPTIONAL_FILES}"
|
||||
IFS=',' read -r -a disallowed_dirs <<< "${REPO_DISALLOWED_DIRS}"
|
||||
@@ -561,6 +559,73 @@ jobs:
|
||||
} >> "${GITHUB_STEP_SUMMARY}"
|
||||
fi
|
||||
|
||||
# ── Joomla-specific checks ───────────────────────────────────────
|
||||
joomla_findings=()
|
||||
|
||||
# XML manifest: find any XML file containing <extension
|
||||
MANIFEST="$(find . -maxdepth 2 -name '*.xml' -exec grep -l '<extension' {} \; 2>/dev/null | head -1 || true)"
|
||||
if [ -z "${MANIFEST}" ]; then
|
||||
joomla_findings+=("Joomla XML manifest not found (no *.xml with <extension> tag)")
|
||||
else
|
||||
# Check <version> tag exists
|
||||
if ! grep -qP '<version>' "${MANIFEST}"; then
|
||||
joomla_findings+=("XML manifest: <version> tag missing")
|
||||
fi
|
||||
# Check extension type attribute
|
||||
if ! grep -qP 'type="(component|module|plugin|library|package|template|language)"' "${MANIFEST}"; then
|
||||
joomla_findings+=("XML manifest: type attribute missing or invalid")
|
||||
fi
|
||||
# Check <name> tag
|
||||
if ! grep -qP '<name>' "${MANIFEST}"; then
|
||||
joomla_findings+=("XML manifest: <name> tag missing")
|
||||
fi
|
||||
# Check <author> tag
|
||||
if ! grep -qP '<author>' "${MANIFEST}"; then
|
||||
joomla_findings+=("XML manifest: <author> tag missing")
|
||||
fi
|
||||
# Check <namespace> for Joomla 5+
|
||||
if ! grep -qP '<namespace' "${MANIFEST}"; then
|
||||
joomla_findings+=("XML manifest: <namespace> missing (required for Joomla 5+)")
|
||||
fi
|
||||
fi
|
||||
|
||||
# Language files: check for at least one .ini file
|
||||
INI_COUNT="$(find . -name '*.ini' -type f 2>/dev/null | wc -l)"
|
||||
if [ "${INI_COUNT}" -eq 0 ]; then
|
||||
joomla_findings+=("No .ini language files found")
|
||||
fi
|
||||
|
||||
# update.xml must exist in root (Joomla update server)
|
||||
if [ ! -f 'update.xml' ]; then
|
||||
joomla_findings+=("update.xml missing in root (required for Joomla update server)")
|
||||
fi
|
||||
|
||||
# index.html files for directory listing protection
|
||||
INDEX_DIRS=("${SOURCE_DIR}" "${SOURCE_DIR}/admin" "${SOURCE_DIR}/site")
|
||||
for dir in "${INDEX_DIRS[@]}"; do
|
||||
if [ -d "${dir}" ] && [ ! -f "${dir}/index.html" ]; then
|
||||
joomla_findings+=("${dir}/index.html missing (directory listing protection)")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "${#joomla_findings[@]}" -gt 0 ]; then
|
||||
{
|
||||
printf '%s\n' '### Joomla extension checks'
|
||||
printf '%s\n' '| Check | Status |'
|
||||
printf '%s\n' '|---|---|'
|
||||
for f in "${joomla_findings[@]}"; do
|
||||
printf '%s\n' "| ${f} | Warning |"
|
||||
done
|
||||
printf '\n'
|
||||
} >> "${GITHUB_STEP_SUMMARY}"
|
||||
else
|
||||
{
|
||||
printf '%s\n' '### Joomla extension checks'
|
||||
printf '%s\n' 'All Joomla-specific checks passed.'
|
||||
printf '\n'
|
||||
} >> "${GITHUB_STEP_SUMMARY}"
|
||||
fi
|
||||
|
||||
extended_enabled="${EXTENDED_CHECKS:-true}"
|
||||
extended_findings=()
|
||||
|
||||
|
||||
8
.github/workflows/standards-compliance.yml
vendored
8
.github/workflows/standards-compliance.yml
vendored
@@ -165,7 +165,9 @@ jobs:
|
||||
grep -v -E '(test|example|sample|getenv|getString|getArgument|config\[|/\.\*/|^\s*//|^\s*\*|CREDENTIAL_PATTERNS|SecurityValidator|SECRET_PATTERN|===|!==|ApiClient|str_contains|gen_wrappers)' | \
|
||||
grep -v "= ''" | grep -v '= ""' | grep -v '\$this->config' | \
|
||||
grep -v 'type="password"' | grep -v 'type="text"' | grep -v 'name="password"' | grep -v 'name="secretkey"' | \
|
||||
grep -v '<input ' | grep -v '<label ' | grep -v 'for="' > /tmp/secrets1.txt 2>/dev/null || true
|
||||
grep -v '<input ' | grep -v '<label ' | grep -v 'for="' | \
|
||||
grep -v 'index\.php?option=' | grep -v 'Route::_' | grep -v 'lostpassword' | \
|
||||
grep -v 'resetpassword' | grep -v 'JRoute' | grep -v 'href=' > /tmp/secrets1.txt 2>/dev/null || true
|
||||
scan_pattern "Secret assignments" "⚠️" /tmp/secrets1.txt
|
||||
|
||||
# Pattern 2: Private keys
|
||||
@@ -2532,8 +2534,8 @@ jobs:
|
||||
echo ""
|
||||
echo "✅ SUCCESS: Repository is fully MokoStandards compliant"
|
||||
|
||||
- name: Create tracking issue for standards violations
|
||||
if: failure() && github.event_name == 'push'
|
||||
- name: Create or reopen tracking issue for standards violations
|
||||
if: failure()
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||
run: |
|
||||
|
||||
2
.github/workflows/sync-version-on-merge.yml
vendored
2
.github/workflows/sync-version-on-merge.yml
vendored
@@ -58,7 +58,7 @@ jobs:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}'
|
||||
run: |
|
||||
git clone --depth 1 --branch version/04.04 --quiet \
|
||||
git clone --depth 1 --branch version/04.05 --quiet \
|
||||
"https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \
|
||||
/tmp/mokostandards
|
||||
cd /tmp/mokostandards
|
||||
|
||||
Reference in New Issue
Block a user