diff --git a/.github/workflows/repo_health.yml b/.github/workflows/repo_health.yml index d3daece..09206e7 100644 --- a/.github/workflows/repo_health.yml +++ b/.github/workflows/repo_health.yml @@ -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.04.01 # 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 tag)") + else + # Check tag exists + if ! grep -qP '' "${MANIFEST}"; then + joomla_findings+=("XML manifest: 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 tag + if ! grep -qP '' "${MANIFEST}"; then + joomla_findings+=("XML manifest: tag missing") + fi + # Check tag + if ! grep -qP '' "${MANIFEST}"; then + joomla_findings+=("XML manifest: tag missing") + fi + # Check for Joomla 5+ + if ! grep -qP ' 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=()