Update repo_health.yml
This commit is contained in:
226
.github/workflows/repo_health.yml
vendored
226
.github/workflows/repo_health.yml
vendored
@@ -46,6 +46,8 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- ".github/workflows/**"
|
- ".github/workflows/**"
|
||||||
- "scripts/**"
|
- "scripts/**"
|
||||||
|
- "docs/**"
|
||||||
|
- "dev/**"
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@@ -62,7 +64,7 @@ jobs:
|
|||||||
permission: ${{ steps.perm.outputs.permission }}
|
permission: ${{ steps.perm.outputs.permission }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check actor permission (admin or maintain only)
|
- name: Check actor permission (admin only)
|
||||||
id: perm
|
id: perm
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
@@ -110,7 +112,11 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Guardrails: release secrets and vars"
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Guardrails: release secrets and vars
|
||||||
env:
|
env:
|
||||||
PROFILE_RAW: "${{ github.event.inputs.profile }}"
|
PROFILE_RAW: "${{ github.event.inputs.profile }}"
|
||||||
FTP_HOST: "${{ secrets.FTP_HOST }}"
|
FTP_HOST: "${{ secrets.FTP_HOST }}"
|
||||||
@@ -134,7 +140,7 @@ jobs:
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
if [ "${profile}" = "scripts" ] || [ "${profile}" = "repo" ]; then
|
if [ "${profile}" = "scripts" ] || [ "${profile}" = "repo" ]; then
|
||||||
echo "Profile scripts selected. Skipping release configuration checks." >> "${GITHUB_STEP_SUMMARY}"
|
echo "Profile ${profile} selected. Skipping release configuration checks." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -159,17 +165,24 @@ jobs:
|
|||||||
missing+=("FTP_PROTOCOL_INVALID")
|
missing+=("FTP_PROTOCOL_INVALID")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "${#missing_optional[@]}" -gt 0 ]; then
|
||||||
|
echo "### Missing optional release configuration" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
for m in "${missing_optional[@]}"; do echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"; done
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "${#missing[@]}" -gt 0 ]; then
|
if [ "${#missing[@]}" -gt 0 ]; then
|
||||||
echo "### Missing required release configuration" >> "${GITHUB_STEP_SUMMARY}"
|
echo "### Missing required release configuration" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
for m in "${missing[@]}"; do echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"; done
|
for m in "${missing[@]}"; do echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"; done
|
||||||
|
echo "ERROR: Guardrails failed. Missing required release configuration." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "### Guardrails: release configuration" >> "${GITHUB_STEP_SUMMARY}"
|
echo "### Guardrails: release configuration" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
echo "All required release variables present." >> "${GITHUB_STEP_SUMMARY}"
|
echo "All required release variables present." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
|
||||||
- name: "Guardrails: SFTP connectivity"
|
- name: Guardrails: SFTP connectivity
|
||||||
env:
|
env:
|
||||||
|
PROFILE_RAW: "${{ github.event.inputs.profile }}"
|
||||||
FTP_HOST: "${{ secrets.FTP_HOST }}"
|
FTP_HOST: "${{ secrets.FTP_HOST }}"
|
||||||
FTP_USER: "${{ secrets.FTP_USER }}"
|
FTP_USER: "${{ secrets.FTP_USER }}"
|
||||||
FTP_KEY: "${{ secrets.FTP_KEY }}"
|
FTP_KEY: "${{ secrets.FTP_KEY }}"
|
||||||
@@ -177,6 +190,20 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
profile="${PROFILE_RAW:-all}"
|
||||||
|
case "${profile}" in
|
||||||
|
all|release|scripts|repo) ;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: Unknown profile: ${profile}" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "${profile}" = "scripts" ] || [ "${profile}" = "repo" ]; then
|
||||||
|
echo "Profile ${profile} selected. Skipping SFTP connectivity check." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
mkdir -p "$HOME/.ssh"
|
mkdir -p "$HOME/.ssh"
|
||||||
key_file="$HOME/.ssh/ci_sftp_key"
|
key_file="$HOME/.ssh/ci_sftp_key"
|
||||||
printf '%s\n' "${FTP_KEY}" > "${key_file}"
|
printf '%s\n' "${FTP_KEY}" > "${key_file}"
|
||||||
@@ -208,7 +235,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: "Guardrails: script files and toolchain"
|
- name: Guardrails: scripts folder governance
|
||||||
env:
|
env:
|
||||||
PROFILE_RAW: "${{ github.event.inputs.profile }}"
|
PROFILE_RAW: "${{ github.event.inputs.profile }}"
|
||||||
run: |
|
run: |
|
||||||
@@ -224,7 +251,7 @@ jobs:
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
if [ "${profile}" = "release" ] || [ "${profile}" = "repo" ]; then
|
if [ "${profile}" = "release" ] || [ "${profile}" = "repo" ]; then
|
||||||
echo "Profile release selected. Skipping scripts checks." >> "${GITHUB_STEP_SUMMARY}"
|
echo "Profile ${profile} selected. Skipping scripts checks." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -249,44 +276,34 @@ jobs:
|
|||||||
"scripts/validate/license_headers.sh"
|
"scripts/validate/license_headers.sh"
|
||||||
)
|
)
|
||||||
|
|
||||||
legacy_script_files=(
|
|
||||||
"scripts/validate_manifest.sh"
|
|
||||||
"scripts/validate_xml_wellformed.sh"
|
|
||||||
"scripts/validate_changelog.sh"
|
|
||||||
"scripts/validate_tabs.sh"
|
|
||||||
"scripts/validate_paths.sh"
|
|
||||||
"scripts/validate_version_alignment.sh"
|
|
||||||
"scripts/validate_language_structure.sh"
|
|
||||||
"scripts/validate_php_syntax.sh"
|
|
||||||
"scripts/validate_no_secrets.sh"
|
|
||||||
"scripts/validate_license_headers.sh"
|
|
||||||
)
|
|
||||||
|
|
||||||
missing_files=()
|
|
||||||
missing_dirs=()
|
missing_dirs=()
|
||||||
legacy_present=()
|
missing_files=()
|
||||||
|
|
||||||
for d in "${required_script_dirs[@]}"; do
|
for d in "${required_script_dirs[@]}"; do
|
||||||
if [ ! -d "${d}" ]; then
|
[ ! -d "${d}" ] && missing_dirs+=("${d}/")
|
||||||
missing_dirs+=("${d}/")
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
|
||||||
|
unapproved_dirs=()
|
||||||
|
while IFS= read -r d; do
|
||||||
|
case "${d}" in
|
||||||
|
scripts|scripts/fix|scripts/lib|scripts/release|scripts/run|scripts/validate) ;;
|
||||||
|
*) unapproved_dirs+=("${d}/") ;;
|
||||||
|
esac
|
||||||
|
done < <(find scripts -maxdepth 1 -mindepth 1 -type d 2>/dev/null | sed 's#^\./##')
|
||||||
|
|
||||||
for f in "${required_script_files[@]}"; do
|
for f in "${required_script_files[@]}"; do
|
||||||
if [ ! -f "${f}" ]; then
|
[ ! -f "${f}" ] && missing_files+=("${f}")
|
||||||
missing_files+=("${f}")
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
|
||||||
for f in "${legacy_script_files[@]}"; do
|
legacy_glob_found=()
|
||||||
if [ -f "${f}" ]; then
|
while IFS= read -r f; do
|
||||||
legacy_present+=("${f}")
|
[ -n "${f}" ] && legacy_glob_found+=("${f}")
|
||||||
fi
|
done < <(find scripts -maxdepth 1 -type f -name 'validate_*.sh' 2>/dev/null || true)
|
||||||
done
|
|
||||||
|
|
||||||
tools_to_install=()
|
tools_to_install=()
|
||||||
command -v php >/dev/null 2>&1 || tools_to_install+=("php-cli")
|
command -v php >/dev/null 2>&1 || tools_to_install+=("php-cli")
|
||||||
command -v xmllint >/dev/null 2>&1 || tools_to_install+=("libxml2-utils")
|
command -v xmllint >/dev/null 2>&1 || tools_to_install+=("libxml2-utils")
|
||||||
|
command -v shellcheck >/dev/null 2>&1 || tools_to_install+=("shellcheck")
|
||||||
|
|
||||||
if [ "${#tools_to_install[@]}" -gt 0 ]; then
|
if [ "${#tools_to_install[@]}" -gt 0 ]; then
|
||||||
echo "Installing missing tools: ${tools_to_install[*]}" >> "${GITHUB_STEP_SUMMARY}"
|
echo "Installing missing tools: ${tools_to_install[*]}" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
@@ -297,10 +314,10 @@ jobs:
|
|||||||
tool_status=()
|
tool_status=()
|
||||||
command -v php >/dev/null 2>&1 && tool_status+=("php") || true
|
command -v php >/dev/null 2>&1 && tool_status+=("php") || true
|
||||||
command -v xmllint >/dev/null 2>&1 && tool_status+=("xmllint") || true
|
command -v xmllint >/dev/null 2>&1 && tool_status+=("xmllint") || true
|
||||||
|
command -v shellcheck >/dev/null 2>&1 && tool_status+=("shellcheck") || true
|
||||||
|
|
||||||
export MISSING_DIRS="$(printf '%s\\n' "${missing_dirs[@]:-}")"
|
export MISSING_DIRS="$(printf '%s\n' "${missing_dirs[@]:-}")"
|
||||||
export MISSING_FILES="$(printf '%s\\n' "${missing_files[@]:-}")"
|
export MISSING_FILES="$(printf '%s\n' "${missing_files[@]:-}")"
|
||||||
export LEGACY_PRESENT="$(printf '%s\\n' "${legacy_present[@]:-}")"
|
|
||||||
export TOOLS="${tool_status[*]:-}"
|
export TOOLS="${tool_status[*]:-}"
|
||||||
|
|
||||||
report_json="$(python3 - <<'PY'
|
report_json="$(python3 - <<'PY'
|
||||||
@@ -326,40 +343,22 @@ required_script_files = [
|
|||||||
"scripts/validate/no_secrets.sh",
|
"scripts/validate/no_secrets.sh",
|
||||||
"scripts/validate/license_headers.sh",
|
"scripts/validate/license_headers.sh",
|
||||||
]
|
]
|
||||||
legacy_script_files = [
|
missing_dirs = os.environ.get('MISSING_DIRS','').split('\n') if os.environ.get('MISSING_DIRS') else []
|
||||||
"scripts/validate_manifest.sh",
|
missing_files = os.environ.get('MISSING_FILES','').split('\n') if os.environ.get('MISSING_FILES') else []
|
||||||
"scripts/validate_xml_wellformed.sh",
|
|
||||||
"scripts/validate_changelog.sh",
|
|
||||||
"scripts/validate_tabs.sh",
|
|
||||||
"scripts/validate_paths.sh",
|
|
||||||
"scripts/validate_version_alignment.sh",
|
|
||||||
"scripts/validate_language_structure.sh",
|
|
||||||
"scripts/validate_php_syntax.sh",
|
|
||||||
"scripts/validate_no_secrets.sh",
|
|
||||||
"scripts/validate_license_headers.sh",
|
|
||||||
]
|
|
||||||
missing_dirs = os.environ.get('MISSING_DIRS','').split('
|
|
||||||
') if os.environ.get('MISSING_DIRS') else []
|
|
||||||
missing_files = os.environ.get('MISSING_FILES','').split('
|
|
||||||
') if os.environ.get('MISSING_FILES') else []
|
|
||||||
legacy_present = os.environ.get('LEGACY_PRESENT','').split('
|
|
||||||
') if os.environ.get('LEGACY_PRESENT') else []
|
|
||||||
tools = os.environ.get('TOOLS','').split() if os.environ.get('TOOLS') else []
|
tools = os.environ.get('TOOLS','').split() if os.environ.get('TOOLS') else []
|
||||||
out = {
|
out = {
|
||||||
"profile": profile,
|
"profile": profile,
|
||||||
"checked": {
|
"checked": {
|
||||||
"required_script_dirs": required_script_dirs,
|
"required_script_dirs": required_script_dirs,
|
||||||
"required_script_files": required_script_files,
|
"required_script_files": required_script_files,
|
||||||
"legacy_script_files": legacy_script_files,
|
|
||||||
},
|
},
|
||||||
"missing_dirs": [x for x in missing_dirs if x],
|
"missing_dirs": [x for x in missing_dirs if x],
|
||||||
"missing_files": [x for x in missing_files if x],
|
"missing_files": [x for x in missing_files if x],
|
||||||
"legacy_present": [x for x in legacy_present if x],
|
|
||||||
"tools_available": tools,
|
"tools_available": tools,
|
||||||
}
|
}
|
||||||
print(json.dumps(out, indent=2))
|
print(json.dumps(out, indent=2))
|
||||||
PY
|
PY
|
||||||
)"
|
)"
|
||||||
|
|
||||||
{
|
{
|
||||||
echo "### Guardrails: scripts and tooling"
|
echo "### Guardrails: scripts and tooling"
|
||||||
@@ -373,45 +372,53 @@ PY
|
|||||||
|
|
||||||
if [ "${#missing_dirs[@]}" -gt 0 ]; then
|
if [ "${#missing_dirs[@]}" -gt 0 ]; then
|
||||||
echo "### Missing required script directories" >> "${GITHUB_STEP_SUMMARY}"
|
echo "### Missing required script directories" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
for m in "${missing_dirs[@]}"; do
|
for m in "${missing_dirs[@]}"; do echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"; done
|
||||||
echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"
|
|
||||||
done
|
|
||||||
echo "ERROR: Guardrails failed. Missing required script directories." >> "${GITHUB_STEP_SUMMARY}"
|
echo "ERROR: Guardrails failed. Missing required script directories." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "${#unapproved_dirs[@]}" -gt 0 ]; then
|
||||||
|
echo "### Unapproved script directories detected" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
for m in "${unapproved_dirs[@]}"; do echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"; done
|
||||||
|
echo "ERROR: Guardrails failed. Only fix, lib, release, run, validate directories are allowed under scripts/." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "${#missing_files[@]}" -gt 0 ]; then
|
if [ "${#missing_files[@]}" -gt 0 ]; then
|
||||||
echo "### Missing script files" >> "${GITHUB_STEP_SUMMARY}"
|
echo "### Missing script files" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
for m in "${missing_files[@]}"; do
|
for m in "${missing_files[@]}"; do echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"; done
|
||||||
echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"
|
|
||||||
done
|
|
||||||
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
|
||||||
|
|
||||||
if [ "${#legacy_present[@]}" -gt 0 ]; then
|
|
||||||
echo "### Legacy scripts detected (disallowed)" >> "${GITHUB_STEP_SUMMARY}"
|
|
||||||
for m in "${legacy_present[@]}"; do
|
|
||||||
echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"
|
|
||||||
done
|
|
||||||
echo "ERROR: Guardrails failed. Legacy script files must be removed." >> "${GITHUB_STEP_SUMMARY}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
legacy_glob_found=()
|
|
||||||
while IFS= read -r f; do
|
|
||||||
[ -n "${f}" ] && legacy_glob_found+=("${f}")
|
|
||||||
done < <(find scripts -maxdepth 1 -type f -name 'validate_*.sh' 2>/dev/null || true)
|
|
||||||
|
|
||||||
if [ "${#legacy_glob_found[@]}" -gt 0 ]; then
|
if [ "${#legacy_glob_found[@]}" -gt 0 ]; then
|
||||||
echo "### Legacy validate_* scripts detected at scripts/ root (disallowed)" >> "${GITHUB_STEP_SUMMARY}"
|
echo "### Legacy validate_* scripts detected at scripts/ root (disallowed)" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
for m in "${legacy_glob_found[@]}"; do
|
for m in "${legacy_glob_found[@]}"; do echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"; done
|
||||||
echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"
|
|
||||||
done
|
|
||||||
echo "ERROR: Guardrails failed. Move scripts into scripts/validate/ with approved filenames." >> "${GITHUB_STEP_SUMMARY}"
|
echo "ERROR: Guardrails failed. Move scripts into scripts/validate/ with approved filenames." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
non_exec=()
|
||||||
|
while IFS= read -r f; do
|
||||||
|
[ -n "${f}" ] && non_exec+=("${f}")
|
||||||
|
done < <(find scripts -type f -name '*.sh' ! -perm -u=x 2>/dev/null || true)
|
||||||
|
|
||||||
|
if [ "${#non_exec[@]}" -gt 0 ]; then
|
||||||
|
echo "### Non-executable shell scripts detected" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
for m in "${non_exec[@]}"; do echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"; done
|
||||||
|
echo "ERROR: Guardrails failed. All scripts/**/*.sh must be executable." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r f; do
|
||||||
|
[ -z "${f}" ] && continue
|
||||||
|
bash -n "${f}"
|
||||||
|
done < <(find scripts -type f -name '*.sh' 2>/dev/null)
|
||||||
|
|
||||||
|
shellcheck -x $(find scripts -type f -name '*.sh' 2>/dev/null)
|
||||||
|
|
||||||
|
echo "Shell quality gate passed." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
|
||||||
repo_health:
|
repo_health:
|
||||||
name: Repository health
|
name: Repository health
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -460,29 +467,30 @@ PY
|
|||||||
required_paths=(
|
required_paths=(
|
||||||
".github/workflows"
|
".github/workflows"
|
||||||
"scripts"
|
"scripts"
|
||||||
|
"docs"
|
||||||
|
"dev"
|
||||||
)
|
)
|
||||||
|
|
||||||
missing_required=()
|
missing_required=()
|
||||||
missing_optional=()
|
missing_optional=()
|
||||||
|
|
||||||
for f in "${required_files[@]}"; do
|
for f in "${required_files[@]}"; do
|
||||||
if [ ! -f "${f}" ]; then
|
[ ! -f "${f}" ] && missing_required+=("${f}")
|
||||||
missing_required+=("${f}")
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
|
||||||
for f in "${optional_files[@]}"; do
|
for f in "${optional_files[@]}"; do
|
||||||
if [ ! -f "${f}" ]; then
|
[ ! -f "${f}" ] && missing_optional+=("${f}")
|
||||||
missing_optional+=("${f}")
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
|
||||||
for p in "${required_paths[@]}"; do
|
for p in "${required_paths[@]}"; do
|
||||||
if [ ! -d "${p}" ]; then
|
[ ! -d "${p}" ] && missing_required+=("${p}/")
|
||||||
missing_required+=("${p}/")
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# dev/ is the only source root. src/ must not exist.
|
||||||
|
if [ -d "src" ]; then
|
||||||
|
missing_required+=("src/ (disallowed, use dev/ only)")
|
||||||
|
fi
|
||||||
|
|
||||||
git fetch origin --prune
|
git fetch origin --prune
|
||||||
|
|
||||||
dev_paths=()
|
dev_paths=()
|
||||||
@@ -507,31 +515,29 @@ PY
|
|||||||
|
|
||||||
content_warnings=()
|
content_warnings=()
|
||||||
|
|
||||||
if [ -f "CHANGELOG.md" ]; then
|
if [ -f "CHANGELOG.md" ] && ! grep -Eq '^# Changelog' CHANGELOG.md; then
|
||||||
if ! grep -Eq '^# Changelog' CHANGELOG.md; then
|
content_warnings+=("CHANGELOG.md missing '# Changelog' header")
|
||||||
content_warnings+=("CHANGELOG.md missing '# Changelog' header")
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f "LICENSE" ]; then
|
if [ -f "LICENSE" ] && ! grep -qiE 'GNU GENERAL PUBLIC LICENSE|GPL' LICENSE; then
|
||||||
if ! grep -qiE 'GNU GENERAL PUBLIC LICENSE|GPL' LICENSE; then
|
content_warnings+=("LICENSE does not look like a GPL text")
|
||||||
content_warnings+=("LICENSE does not look like a GPL text")
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f "README.md" ]; then
|
if [ -f "README.md" ] && ! grep -qiE 'moko|Moko' README.md; then
|
||||||
if ! grep -qiE 'moko|Moko' README.md; then
|
content_warnings+=("README.md missing expected brand keyword")
|
||||||
content_warnings+=("README.md missing expected brand keyword")
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
export MISSING_REQUIRED="$(printf '%s\n' "${missing_required[@]:-}")"
|
||||||
|
export MISSING_OPTIONAL="$(printf '%s\n' "${missing_optional[@]:-}")"
|
||||||
|
export CONTENT_WARNINGS="$(printf '%s\n' "${content_warnings[@]:-}")"
|
||||||
|
|
||||||
report_json="$(python3 - <<'PY'
|
report_json="$(python3 - <<'PY'
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
profile = os.environ.get('PROFILE_RAW') or 'all'
|
profile = os.environ.get('PROFILE_RAW') or 'all'
|
||||||
required_files = ["README.md","LICENSE","CHANGELOG.md","CONTRIBUTING.md","CODE_OF_CONDUCT.md"]
|
required_files = ["README.md","LICENSE","CHANGELOG.md","CONTRIBUTING.md","CODE_OF_CONDUCT.md"]
|
||||||
optional_files = ["SECURITY.md","GOVERNANCE.md",".editorconfig",".gitattributes",".gitignore"]
|
optional_files = ["SECURITY.md","GOVERNANCE.md",".editorconfig",".gitattributes",".gitignore"]
|
||||||
required_paths = [".github/workflows","scripts"]
|
required_paths = [".github/workflows","scripts","docs","dev"]
|
||||||
missing_required = os.environ.get('MISSING_REQUIRED','').split('\n') if os.environ.get('MISSING_REQUIRED') else []
|
missing_required = os.environ.get('MISSING_REQUIRED','').split('\n') if os.environ.get('MISSING_REQUIRED') else []
|
||||||
missing_optional = os.environ.get('MISSING_OPTIONAL','').split('\n') if os.environ.get('MISSING_OPTIONAL') else []
|
missing_optional = os.environ.get('MISSING_OPTIONAL','').split('\n') if os.environ.get('MISSING_OPTIONAL') else []
|
||||||
content_warnings = os.environ.get('CONTENT_WARNINGS','').split('\n') if os.environ.get('CONTENT_WARNINGS') else []
|
content_warnings = os.environ.get('CONTENT_WARNINGS','').split('\n') if os.environ.get('CONTENT_WARNINGS') else []
|
||||||
@@ -542,9 +548,9 @@ out = {
|
|||||||
"optional_files": optional_files,
|
"optional_files": optional_files,
|
||||||
"required_paths": required_paths,
|
"required_paths": required_paths,
|
||||||
},
|
},
|
||||||
"missing_required": missing_required,
|
"missing_required": [x for x in missing_required if x],
|
||||||
"missing_optional": missing_optional,
|
"missing_optional": [x for x in missing_optional if x],
|
||||||
"content_warnings": content_warnings,
|
"content_warnings": [x for x in content_warnings if x],
|
||||||
}
|
}
|
||||||
print(json.dumps(out, indent=2))
|
print(json.dumps(out, indent=2))
|
||||||
PY
|
PY
|
||||||
@@ -561,23 +567,17 @@ PY
|
|||||||
|
|
||||||
if [ "${#missing_required[@]}" -gt 0 ]; then
|
if [ "${#missing_required[@]}" -gt 0 ]; then
|
||||||
echo "### Missing required repo artifacts" >> "${GITHUB_STEP_SUMMARY}"
|
echo "### Missing required repo artifacts" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
for m in "${missing_required[@]}"; do
|
for m in "${missing_required[@]}"; do echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"; done
|
||||||
echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"
|
|
||||||
done
|
|
||||||
echo "ERROR: Guardrails failed. Missing required repository artifacts." >> "${GITHUB_STEP_SUMMARY}"
|
echo "ERROR: Guardrails failed. Missing required repository artifacts." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${#missing_optional[@]}" -gt 0 ]; then
|
if [ "${#missing_optional[@]}" -gt 0 ]; then
|
||||||
echo "### Missing optional repo artifacts" >> "${GITHUB_STEP_SUMMARY}"
|
echo "### Missing optional repo artifacts" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
for m in "${missing_optional[@]}"; do
|
for m in "${missing_optional[@]}"; do echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"; done
|
||||||
echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"
|
|
||||||
done
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${#content_warnings[@]}" -gt 0 ]; then
|
if [ "${#content_warnings[@]}" -gt 0 ]; then
|
||||||
echo "### Repo content warnings" >> "${GITHUB_STEP_SUMMARY}"
|
echo "### Repo content warnings" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
for m in "${content_warnings[@]}"; do
|
for m in "${content_warnings[@]}"; do echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"; done
|
||||||
echo "- ${m}" >> "${GITHUB_STEP_SUMMARY}"
|
|
||||||
done
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user