chore: Sync MokoStandards 04.01.00 #100
244
.github/workflows/repository-cleanup.yml
vendored
Normal file
244
.github/workflows/repository-cleanup.yml
vendored
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||||
|
#
|
||||||
|
# This file is part of a Moko Consulting project.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
#
|
||||||
|
# FILE INFORMATION
|
||||||
|
# DEFGROUP: GitHub.Workflow
|
||||||
|
# INGROUP: MokoStandards.Maintenance
|
||||||
|
# REPO: https://github.com/mokoconsulting-tech/MokoStandards
|
||||||
|
# PATH: /templates/workflows/shared/repository-cleanup.yml
|
||||||
|
# VERSION: 04.01.00
|
||||||
|
# BRIEF: One-time repository cleanup — reset labels, strip issue template headers, delete old branches
|
||||||
|
# NOTE: Synced via bulk-repo-sync to .github/workflows/repository-cleanup.yml in all governed repos.
|
||||||
|
# Run manually via workflow_dispatch. Safe to re-run — all operations are idempotent.
|
||||||
|
|
||||||
|
name: Repository Cleanup
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
reset_labels:
|
||||||
|
description: 'Delete ALL existing labels and recreate the standard 54-label set'
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
clean_branches:
|
||||||
|
description: 'Delete old chore/sync-mokostandards-* branches (keeps current versioned branch only)'
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
fix_templates:
|
||||||
|
description: 'Strip copyright comment blocks from issue templates'
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cleanup:
|
||||||
|
name: Repository Cleanup
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
|
|
||||||
|
- name: Check actor permission
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
|
run: |
|
||||||
|
ACTOR="${{ github.actor }}"
|
||||||
|
AUTHORIZED_USERS="jmiller-moko github-actions[bot]"
|
||||||
|
for user in $AUTHORIZED_USERS; do
|
||||||
|
if [ "$ACTOR" = "$user" ]; then
|
||||||
|
echo "✅ ${ACTOR} authorized"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
PERMISSION=$(gh api "repos/${{ github.repository }}/collaborators/${ACTOR}/permission" \
|
||||||
|
--jq '.permission' 2>/dev/null)
|
||||||
|
case "$PERMISSION" in
|
||||||
|
admin|maintain) echo "✅ ${ACTOR} has ${PERMISSION}" ;;
|
||||||
|
*) echo "❌ Admin or maintain required"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# ── LABEL RESET ──────────────────────────────────────────────────────
|
||||||
|
- name: Reset labels to standard set
|
||||||
|
if: inputs.reset_labels == true
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
|
run: |
|
||||||
|
REPO="${{ github.repository }}"
|
||||||
|
echo "## 🏷️ Label Reset" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
# Delete all existing labels
|
||||||
|
echo "Deleting existing labels..."
|
||||||
|
DELETED=0
|
||||||
|
gh api "repos/${REPO}/labels?per_page=100" --paginate --jq '.[].name' | while read -r label; do
|
||||||
|
ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$label', safe=''))")
|
||||||
|
gh api -X DELETE "repos/${REPO}/labels/${ENCODED}" --silent 2>/dev/null && DELETED=$((DELETED+1)) || true
|
||||||
|
done
|
||||||
|
echo "Deleted existing labels" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
# Create the standard 54-label set
|
||||||
|
echo "Creating standard labels..."
|
||||||
|
CREATED=0
|
||||||
|
while IFS='|' read -r name color description; do
|
||||||
|
[ -z "$name" ] && continue
|
||||||
|
gh api "repos/${REPO}/labels" \
|
||||||
|
-f name="$name" -f color="$color" -f description="$description" \
|
||||||
|
--silent 2>/dev/null && CREATED=$((CREATED+1)) || true
|
||||||
|
done << 'LABELS'
|
||||||
|
joomla|7F52FF|Joomla extension or component
|
||||||
|
dolibarr|FF6B6B|Dolibarr module or extension
|
||||||
|
generic|808080|Generic project or library
|
||||||
|
php|4F5D95|PHP code changes
|
||||||
|
javascript|F7DF1E|JavaScript code changes
|
||||||
|
typescript|3178C6|TypeScript code changes
|
||||||
|
python|3776AB|Python code changes
|
||||||
|
css|1572B6|CSS/styling changes
|
||||||
|
html|E34F26|HTML template changes
|
||||||
|
documentation|0075CA|Documentation changes
|
||||||
|
ci-cd|000000|CI/CD pipeline changes
|
||||||
|
docker|2496ED|Docker configuration changes
|
||||||
|
tests|00FF00|Test suite changes
|
||||||
|
security|FF0000|Security-related changes
|
||||||
|
dependencies|0366D6|Dependency updates
|
||||||
|
config|F9D0C4|Configuration file changes
|
||||||
|
build|FFA500|Build system changes
|
||||||
|
automation|8B4513|Automated processes or scripts
|
||||||
|
mokostandards|B60205|MokoStandards compliance
|
||||||
|
needs-review|FBCA04|Awaiting code review
|
||||||
|
work-in-progress|D93F0B|Work in progress, not ready for merge
|
||||||
|
breaking-change|D73A4A|Breaking API or functionality change
|
||||||
|
priority: critical|B60205|Critical priority, must be addressed immediately
|
||||||
|
priority: high|D93F0B|High priority
|
||||||
|
priority: medium|FBCA04|Medium priority
|
||||||
|
priority: low|0E8A16|Low priority
|
||||||
|
type: bug|D73A4A|Something isn't working
|
||||||
|
type: feature|A2EEEF|New feature or request
|
||||||
|
type: enhancement|84B6EB|Enhancement to existing feature
|
||||||
|
type: refactor|F9D0C4|Code refactoring
|
||||||
|
type: chore|FEF2C0|Maintenance tasks
|
||||||
|
status: pending|FBCA04|Pending action or decision
|
||||||
|
status: in-progress|0E8A16|Currently being worked on
|
||||||
|
status: blocked|B60205|Blocked by another issue or dependency
|
||||||
|
status: on-hold|D4C5F9|Temporarily on hold
|
||||||
|
status: wontfix|FFFFFF|This will not be worked on
|
||||||
|
size/xs|C5DEF5|Extra small change (1-10 lines)
|
||||||
|
size/s|6FD1E2|Small change (11-30 lines)
|
||||||
|
size/m|F9DD72|Medium change (31-100 lines)
|
||||||
|
size/l|FFA07A|Large change (101-300 lines)
|
||||||
|
size/xl|FF6B6B|Extra large change (301-1000 lines)
|
||||||
|
size/xxl|B60205|Extremely large change (1000+ lines)
|
||||||
|
health: excellent|0E8A16|Health score 90-100
|
||||||
|
health: good|FBCA04|Health score 70-89
|
||||||
|
health: fair|FFA500|Health score 50-69
|
||||||
|
health: poor|FF6B6B|Health score below 50
|
||||||
|
standards-update|B60205|MokoStandards sync update
|
||||||
|
standards-drift|FBCA04|Repository drifted from MokoStandards
|
||||||
|
sync-report|0075CA|Bulk sync run report
|
||||||
|
sync-failure|D73A4A|Bulk sync failure requiring attention
|
||||||
|
push-failure|D73A4A|File push failure requiring attention
|
||||||
|
health-check|0E8A16|Repository health check results
|
||||||
|
version-drift|FFA500|Version mismatch detected
|
||||||
|
deploy-failure|CC0000|Automated deploy failure tracking
|
||||||
|
template-validation-failure|D73A4A|Template workflow validation failure
|
||||||
|
LABELS
|
||||||
|
|
||||||
|
echo "✅ Standard labels created" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
# ── BRANCH CLEANUP ───────────────────────────────────────────────────
|
||||||
|
- name: Delete old sync branches
|
||||||
|
if: inputs.clean_branches == true
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
|
run: |
|
||||||
|
REPO="${{ github.repository }}"
|
||||||
|
CURRENT="chore/sync-mokostandards-v04.01.00"
|
||||||
|
echo "## 🌿 Branch Cleanup" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
DELETED=0
|
||||||
|
gh api "repos/${REPO}/branches?per_page=100" --jq '.[].name' | \
|
||||||
|
grep "^chore/sync-mokostandards" | \
|
||||||
|
grep -v "^${CURRENT}$" | while read -r branch; do
|
||||||
|
# Close any open PRs on this branch
|
||||||
|
gh pr list --repo "$REPO" --head "$branch" --state open --json number --jq '.[].number' 2>/dev/null | while read -r pr; do
|
||||||
|
gh pr close "$pr" --repo "$REPO" --comment "Superseded by \`${CURRENT}\`" 2>/dev/null || true
|
||||||
|
echo " Closed PR #${pr}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
done
|
||||||
|
# Delete the branch
|
||||||
|
gh api -X DELETE "repos/${REPO}/git/refs/heads/${branch}" --silent 2>/dev/null || true
|
||||||
|
echo " Deleted: \`${branch}\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
DELETED=$((DELETED+1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$DELETED" -eq 0 ] 2>/dev/null; then
|
||||||
|
echo "✅ No old sync branches found" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "✅ Cleanup complete" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── ISSUE TEMPLATE FIX ──────────────────────────────────────────────
|
||||||
|
- name: Strip copyright headers from issue templates
|
||||||
|
if: inputs.fix_templates == true
|
||||||
|
run: |
|
||||||
|
echo "## 📋 Issue Template Cleanup" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
FIXED=0
|
||||||
|
for f in .github/ISSUE_TEMPLATE/*.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
if grep -q '^<!--$' "$f"; then
|
||||||
|
sed -i '/^<!--$/,/^-->$/d' "$f"
|
||||||
|
echo " Cleaned: \`$(basename $f)\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
FIXED=$((FIXED+1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$FIXED" -gt 0 ]; then
|
||||||
|
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
git config --local user.name "github-actions[bot]"
|
||||||
|
git add .github/ISSUE_TEMPLATE/
|
||||||
|
git commit -m "fix: strip copyright comment blocks from issue templates [skip ci]" \
|
||||||
|
--author="github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
|
||||||
|
git push
|
||||||
|
echo "✅ ${FIXED} template(s) cleaned and committed" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "✅ No templates need cleaning" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── SELF-DELETE ─────────────────────────────────────────────────────
|
||||||
|
- name: Delete this workflow (one-time use)
|
||||||
|
if: success()
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
|
run: |
|
||||||
|
echo "## 🗑️ Self-Cleanup" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
WORKFLOW_FILE=".github/workflows/repository-cleanup.yml"
|
||||||
|
if [ -f "$WORKFLOW_FILE" ]; then
|
||||||
|
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
git config --local user.name "github-actions[bot]"
|
||||||
|
git rm "$WORKFLOW_FILE"
|
||||||
|
git commit -m "chore: remove repository-cleanup.yml after successful run [skip ci]" \
|
||||||
|
--author="github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
|
||||||
|
git push
|
||||||
|
echo "✅ Workflow file deleted — it will not appear in future syncs" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "ℹ️ Workflow file already removed" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Summary
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "---" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "*Run by @${{ github.actor }} via workflow_dispatch*" >> $GITHUB_STEP_SUMMARY
|
||||||
Reference in New Issue
Block a user