1+ name : Validate profile metadata
2+
3+ on :
4+ push :
5+ branches : [main, master]
6+ workflow_dispatch :
7+
8+ permissions :
9+ contents : read
10+
11+ jobs :
12+ metadata-check :
13+ name : Description + topics + leak guard
14+ runs-on : ubuntu-latest
15+ steps :
16+ - name : Fetch repo metadata via API
17+ env :
18+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
19+ REPO : ${{ github.repository }}
20+ run : |
21+ set -euo pipefail
22+ META=$(gh api "repos/${REPO}" --jq '{description: .description, topics: [.topics[]]}')
23+ echo "::group::Fetched metadata"
24+ echo "${META}"
25+ echo "::endgroup::"
26+
27+ DESC=$(echo "${META}" | jq -r '.description // ""')
28+ TOPIC_COUNT=$(echo "${META}" | jq -r '.topics | length')
29+
30+ # Description checks
31+ if [[ -z "${DESC}" || "${DESC}" == "null" ]]; then
32+ echo "::error::Description is empty. Set one via: gh repo edit <owner>/<repo> --description '...'"
33+ exit 1
34+ fi
35+ if [[ ${#DESC} -lt 20 ]]; then
36+ echo "::error::Description too short (${#DESC} chars, min 20): '${DESC}'"
37+ exit 1
38+ fi
39+ if [[ ! "${DESC}" =~ ^[A-Z] ]]; then
40+ echo "::error::Description must start with a capital letter: '${DESC}'"
41+ exit 1
42+ fi
43+
44+ # Topic checks
45+ if (( TOPIC_COUNT < 3 )); then
46+ echo "::error::Need at least 3 topics (have ${TOPIC_COUNT}). Add via: gh repo edit <owner>/<repo> --add-topic foo"
47+ exit 1
48+ fi
49+
50+ # Internal-leak guard: block accidental exposure of internal/corporate language
51+ LEAKS="company|bedrock|corporate|corp\\.|sanitized fork of a private|internal tool|not for distribution|do not share"
52+ if [[ "${DESC,,}" =~ ${LEAKS} ]]; then
53+ echo "::error::Description contains internal-leak phrase: '${DESC}'"
54+ exit 1
55+ fi
56+ for t in $(echo "${META}" | jq -r '.topics[]'); do
57+ if [[ "${t,,}" =~ ${LEAKS} ]]; then
58+ echo "::error::Topic '${t}' matches internal-leak pattern"
59+ exit 1
60+ fi
61+ done
62+
63+ echo "OK: description + topics passed all checks."
0 commit comments