Update repo_health.yml
This commit is contained in:
199
.github/workflows/repo_health.yml
vendored
199
.github/workflows/repo_health.yml
vendored
@@ -22,13 +22,12 @@
|
|||||||
# DEFGROUP: GitHub.Workflow
|
# DEFGROUP: GitHub.Workflow
|
||||||
# INGROUP: MokoStandards.Validation
|
# INGROUP: MokoStandards.Validation
|
||||||
# REPO: https://github.com/mokoconsulting-tech/MokoStandards
|
# REPO: https://github.com/mokoconsulting-tech/MokoStandards
|
||||||
# PATH: /.github/workflows/config_guardrails.yml
|
# PATH: /.github/workflows/repo_health.yml
|
||||||
# VERSION: 03.05.00
|
# VERSION: 03.05.00
|
||||||
# BRIEF: Validate that required repository secrets and variables exist for workflows and scripts.
|
# BRIEF: Enforces Joomla repository guardrails by validating release configuration, required validation scripts, tooling availability, and core repository health artifacts.
|
||||||
# NOTE: Secrets are never printed. This workflow only verifies presence and emits an audit JSON report.
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
name: Repo Health
|
name: Joomla Repo Health
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -188,7 +187,6 @@ jobs:
|
|||||||
echo "ERROR: Guardrails failed. Missing required release configuration." >> "${GITHUB_STEP_SUMMARY}"
|
echo "ERROR: Guardrails failed. Missing required release configuration." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
scripts_config:
|
scripts_config:
|
||||||
name: Scripts and tooling
|
name: Scripts and tooling
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -203,11 +201,11 @@ jobs:
|
|||||||
|
|
||||||
- name: Guardrails: script files and toolchain
|
- name: Guardrails: script files and toolchain
|
||||||
env:
|
env:
|
||||||
PROFILE: ${{ github.event.inputs.profile || 'all' }}
|
PROFILE_RAW: ${{ github.event.inputs.profile }}
|
||||||
run: |
|
run: |
|
||||||
set -euxo pipefail
|
set -euxo pipefail
|
||||||
|
|
||||||
profile="${PROFILE}"
|
profile="${PROFILE_RAW:-all}"
|
||||||
if [ "${profile}" != "all" ] && [ "${profile}" != "release" ] && [ "${profile}" != "scripts" ]; then
|
if [ "${profile}" != "all" ] && [ "${profile}" != "release" ] && [ "${profile}" != "scripts" ]; then
|
||||||
echo "ERROR: Unknown profile: ${profile}" >> "${GITHUB_STEP_SUMMARY}"
|
echo "ERROR: Unknown profile: ${profile}" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -253,7 +251,6 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Report legacy scripts if present so teams can clean up.
|
|
||||||
for f in "${legacy_script_files[@]}"; do
|
for f in "${legacy_script_files[@]}"; do
|
||||||
if [ -f "${f}" ]; then
|
if [ -f "${f}" ]; then
|
||||||
legacy_present+=("${f}")
|
legacy_present+=("${f}")
|
||||||
@@ -318,3 +315,189 @@ jobs:
|
|||||||
echo "ERROR: Guardrails failed. Missing required script files." >> "${GITHUB_STEP_SUMMARY}"
|
echo "ERROR: Guardrails failed. Missing required script files." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
repo_health:
|
||||||
|
name: Repository health
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Repo health checks
|
||||||
|
env:
|
||||||
|
PROFILE_RAW: ${{ github.event.inputs.profile }}
|
||||||
|
run: |
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
profile="${PROFILE_RAW:-all}"
|
||||||
|
if [ "${profile}" != "all" ] && [ "${profile}" != "release" ] && [ "${profile}" != "scripts" ]; then
|
||||||
|
echo "ERROR: Unknown profile: ${profile}" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Always run repo health for all profiles.
|
||||||
|
|
||||||
|
required_files=(
|
||||||
|
"README.md"
|
||||||
|
"LICENSE"
|
||||||
|
"CHANGELOG.md"
|
||||||
|
"CONTRIBUTING.md"
|
||||||
|
"CODE_OF_CONDUCT.md"
|
||||||
|
)
|
||||||
|
|
||||||
|
optional_files=(
|
||||||
|
"SECURITY.md"
|
||||||
|
"GOVERNANCE.md"
|
||||||
|
".editorconfig"
|
||||||
|
".gitattributes"
|
||||||
|
".gitignore"
|
||||||
|
)
|
||||||
|
|
||||||
|
required_paths=(
|
||||||
|
".github/workflows"
|
||||||
|
"scripts"
|
||||||
|
)
|
||||||
|
|
||||||
|
missing_required=()
|
||||||
|
missing_optional=()
|
||||||
|
|
||||||
|
for f in "${required_files[@]}"; do
|
||||||
|
if [ ! -f "${f}" ]; then
|
||||||
|
missing_required+=("${f}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for f in "${optional_files[@]}"; do
|
||||||
|
if [ ! -f "${f}" ]; then
|
||||||
|
missing_optional+=("${f}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for p in "${required_paths[@]}"; do
|
||||||
|
if [ ! -d "${p}" ]; then
|
||||||
|
missing_required+=("${p}/")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Branch topology health checks.
|
||||||
|
git fetch origin --prune
|
||||||
|
|
||||||
|
dev_paths=()
|
||||||
|
dev_branches=()
|
||||||
|
|
||||||
|
# Collect remote branches starting with dev/
|
||||||
|
while IFS= read -r b; do
|
||||||
|
name="${b#origin/}"
|
||||||
|
if [ "${name}" = "dev" ]; then
|
||||||
|
dev_branches+=("${name}")
|
||||||
|
else
|
||||||
|
dev_paths+=("${name}")
|
||||||
|
fi
|
||||||
|
done < <(git branch -r --list "origin/dev*" | sed 's/^ *//')
|
||||||
|
|
||||||
|
# Enforce at least one dev/* path branch
|
||||||
|
if [ "${#dev_paths[@]}" -eq 0 ]; then
|
||||||
|
missing_required+=("dev/* branch (e.g. dev/01.00.00)")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Enforce dev is not a concrete branch
|
||||||
|
if [ "${#dev_branches[@]}" -gt 0 ]; then
|
||||||
|
missing_required+=("invalid branch 'dev' (must be dev/<version>)")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Lightweight content health checks.
|
||||||
|
content_warnings=()
|
||||||
|
|
||||||
|
if [ -f "CHANGELOG.md" ]; then
|
||||||
|
if ! grep -Eq '^# Changelog' CHANGELOG.md; then
|
||||||
|
content_warnings+=("CHANGELOG.md missing '# Changelog' header")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "LICENSE" ]; then
|
||||||
|
if ! grep -qiE 'GNU GENERAL PUBLIC LICENSE|GPL' LICENSE; then
|
||||||
|
content_warnings+=("LICENSE does not look like a GPL text")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "README.md" ]; then
|
||||||
|
if ! grep -qiE 'moko|Moko' README.md; then
|
||||||
|
content_warnings+=("README.md missing expected brand keyword")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "### Guardrails: repository health"
|
||||||
|
echo ""
|
||||||
|
echo "### Guardrails report (JSON)"
|
||||||
|
echo "```json"
|
||||||
|
printf '{"profile":"%s","checked":{"required_files":[' "${profile}"
|
||||||
|
sep=""
|
||||||
|
for c in "${required_files[@]}"; do
|
||||||
|
printf '%s"%s"' "${sep}" "${c}"
|
||||||
|
sep=",";
|
||||||
|
done
|
||||||
|
printf '],"optional_files":['
|
||||||
|
sep=""
|
||||||
|
for c in "${optional_files[@]}"; do
|
||||||
|
printf '%s"%s"' "${sep}" "${c}"
|
||||||
|
sep=",";
|
||||||
|
done
|
||||||
|
printf '],"required_paths":['
|
||||||
|
sep=""
|
||||||
|
for c in "${required_paths[@]}"; do
|
||||||
|
printf '%s"%s"' "${sep}" "${c}"
|
||||||
|
sep=",";
|
||||||
|
done
|
||||||
|
printf ']},"missing_required":['
|
||||||
|
sep=""
|
||||||
|
for m in "${missing_required[@]}"; do
|
||||||
|
printf '%s"%s"' "${sep}" "${m}"
|
||||||
|
sep=",";
|
||||||
|
done
|
||||||
|
printf '],"missing_optional":['
|
||||||
|
sep=""
|
||||||
|
for m in "${missing_optional[@]}"; do
|
||||||
|
printf '%s"%s"' "${sep}" "${m}"
|
||||||
|
sep=",";
|
||||||
|
done
|
||||||
|
printf '],"content_warnings":['
|
||||||
|
sep=""
|
||||||
|
for m in "${content_warnings[@]}"; do
|
||||||
|
printf '%s"%s"' "${sep}" "${m}"
|
||||||
|
sep=",";
|
||||||
|
done
|
||||||
|
printf ']}'
|
||||||
|
echo
|
||||||
|
echo "```"
|
||||||
|
} >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
|
||||||
|
if [ "${#missing_required[@]}" -gt 0 ]; then
|
||||||
|
echo "### Missing required repo artifacts" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
for m in "${missing_required[@]}"; do
|
||||||
|
echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
done
|
||||||
|
echo "MISSING_REQUIRED: ${missing_required[*]}" >&2
|
||||||
|
echo "ERROR: Guardrails failed. Missing required repository artifacts." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${#missing_optional[@]}" -gt 0 ]; then
|
||||||
|
echo "### Missing optional repo artifacts" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
for m in "${missing_optional[@]}"; do
|
||||||
|
echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${#content_warnings[@]}" -gt 0 ]; then
|
||||||
|
echo "### Repo content warnings" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
for m in "${content_warnings[@]}"; do
|
||||||
|
echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user