Structure: - publishing/ - version bumping and registry publishing - git/ - multi-repo git operations - config/ - package configuration utilities - lint/ - ESLint and code quality scripts - forgejo/ - Forgejo CI/CD automation (primary) - gitlab/ - DEPRECATED legacy GitLab scripts - migration/ - one-time migration utilities - templates/ - CI/CD template files - analysis/ - codebase analysis scripts - oneoffs/ - uncategorized one-time scripts Note: commits CLI will be merged into @ml/auto-commit-service Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
290 lines
10 KiB
Bash
Executable file
290 lines
10 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# Forgejo Actions Workflow Validation Script
|
|
# =============================================================================
|
|
# Validates workflow deployment across @packages workspace
|
|
#
|
|
# Checks:
|
|
# 1. Workflow file exists
|
|
# 2. Workflow is tracked in git
|
|
# 3. Workflow syntax is valid (YAML)
|
|
# 4. Package metadata is present (TypeScript)
|
|
# 5. Workflow matches expected template type
|
|
#
|
|
# Usage:
|
|
# ./scripts/forgejo/validate-workflows.sh # Validate all
|
|
# ./scripts/forgejo/validate-workflows.sh --category "@mcp" # Validate category
|
|
# ./scripts/forgejo/validate-workflows.sh --verbose # Detailed output
|
|
# =============================================================================
|
|
|
|
set -euo pipefail
|
|
|
|
WORKSPACE_ROOT="/var/home/lilith/Code/@packages"
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
# =============================================================================
|
|
# Validation Checks
|
|
# =============================================================================
|
|
|
|
validate_package() {
|
|
local package_dir=$1
|
|
local verbose=${2:-false}
|
|
local checks_passed=0
|
|
local checks_failed=0
|
|
local checks_warned=0
|
|
|
|
# Get package name
|
|
local pkg_name
|
|
if [[ -f "$package_dir/package.json" ]]; then
|
|
pkg_name=$(node -p "try { require('$package_dir/package.json').name } catch(e) { '$(basename $package_dir)' }" 2>/dev/null || echo "$(basename $package_dir)")
|
|
else
|
|
pkg_name=$(basename "$package_dir")
|
|
fi
|
|
|
|
if [[ "$verbose" == "true" ]]; then
|
|
echo -e "${BLUE}Validating: $pkg_name${NC}"
|
|
echo -e " Path: $package_dir"
|
|
fi
|
|
|
|
# Check 1: Workflow file exists
|
|
local workflow_file=""
|
|
if [[ -f "$package_dir/.forgejo/workflows/publish.yml" ]]; then
|
|
workflow_file="$package_dir/.forgejo/workflows/publish.yml"
|
|
((checks_passed++))
|
|
[[ "$verbose" == "true" ]] && echo -e " ${GREEN}✓ Workflow file exists (publish.yml)${NC}"
|
|
elif [[ -f "$package_dir/.forgejo/workflows/pypi-publish.yml" ]]; then
|
|
workflow_file="$package_dir/.forgejo/workflows/pypi-publish.yml"
|
|
((checks_passed++))
|
|
[[ "$verbose" == "true" ]] && echo -e " ${GREEN}✓ Workflow file exists (pypi-publish.yml)${NC}"
|
|
elif [[ -f "$package_dir/.forgejo/workflows/ci.yml" ]]; then
|
|
workflow_file="$package_dir/.forgejo/workflows/ci.yml"
|
|
((checks_passed++))
|
|
[[ "$verbose" == "true" ]] && echo -e " ${GREEN}✓ Workflow file exists (ci.yml)${NC}"
|
|
else
|
|
((checks_failed++))
|
|
echo -e " ${RED}✗ Workflow file missing${NC}"
|
|
echo -e " Package: $pkg_name"
|
|
echo -e " Path: $package_dir"
|
|
return $checks_failed
|
|
fi
|
|
|
|
# Check 2: Git tracked
|
|
if git -C "$package_dir" ls-files .forgejo/workflows/*.yml 2>/dev/null | grep -q .; then
|
|
((checks_passed++))
|
|
[[ "$verbose" == "true" ]] && echo -e " ${GREEN}✓ Workflow tracked in git${NC}"
|
|
else
|
|
((checks_failed++))
|
|
echo -e " ${RED}✗ Workflow not tracked in git${NC}"
|
|
echo -e " Package: $pkg_name"
|
|
echo -e " Path: $package_dir"
|
|
echo -e " Fix: cd $package_dir && git add .forgejo/"
|
|
fi
|
|
|
|
# Check 3: Syntax valid
|
|
if command -v yamllint &> /dev/null; then
|
|
if yamllint "$workflow_file" 2>/dev/null > /dev/null; then
|
|
((checks_passed++))
|
|
[[ "$verbose" == "true" ]] && echo -e " ${GREEN}✓ Workflow syntax valid${NC}"
|
|
else
|
|
((checks_failed++))
|
|
echo -e " ${RED}✗ Workflow syntax invalid${NC}"
|
|
echo -e " Package: $pkg_name"
|
|
echo -e " File: $workflow_file"
|
|
echo -e " Run: yamllint $workflow_file"
|
|
fi
|
|
else
|
|
((checks_warned++))
|
|
[[ "$verbose" == "true" ]] && echo -e " ${YELLOW}⚠ yamllint not available, skipping syntax check${NC}"
|
|
fi
|
|
|
|
# Check 4: Metadata present (TypeScript packages)
|
|
if [[ -f "$package_dir/package.json" ]]; then
|
|
if grep -q '"_":' "$package_dir/package.json" 2>/dev/null; then
|
|
# Check for required fields
|
|
local has_registry=$(grep -c '"registry":\s*"forgejo"' "$package_dir/package.json" 2>/dev/null || echo "0")
|
|
local has_publish=$(grep -c '"publish":\s*true' "$package_dir/package.json" 2>/dev/null || echo "0")
|
|
|
|
if [[ $has_registry -gt 0 ]] && [[ $has_publish -gt 0 ]]; then
|
|
((checks_passed++))
|
|
[[ "$verbose" == "true" ]] && echo -e " ${GREEN}✓ Package metadata present and valid${NC}"
|
|
else
|
|
((checks_warned++))
|
|
echo -e " ${YELLOW}⚠ Package metadata incomplete${NC}"
|
|
echo -e " Package: $pkg_name"
|
|
echo -e " Missing: $([ $has_registry -eq 0 ] && echo 'registry:forgejo ')$([ $has_publish -eq 0 ] && echo 'publish:true')"
|
|
echo -e " Add to package.json:"
|
|
echo -e " \"_\": { \"registry\": \"forgejo\", \"publish\": true, \"build\": true }"
|
|
fi
|
|
else
|
|
((checks_warned++))
|
|
echo -e " ${YELLOW}⚠ Package metadata missing${NC}"
|
|
echo -e " Package: $pkg_name"
|
|
echo -e " Workflow may skip publishing"
|
|
echo -e " Add to package.json:"
|
|
echo -e " \"_\": { \"registry\": \"forgejo\", \"publish\": true, \"build\": true }"
|
|
fi
|
|
fi
|
|
|
|
# Check 5: Workflow type matches package type
|
|
if [[ -f "$package_dir/pyproject.toml" ]] && [[ "$workflow_file" != *"pypi"* ]]; then
|
|
((checks_failed++))
|
|
echo -e " ${RED}✗ Workflow type mismatch${NC}"
|
|
echo -e " Package: $pkg_name (Python)"
|
|
echo -e " Workflow: $(basename $workflow_file) (should be pypi-publish.yml)"
|
|
elif [[ -f "$package_dir/package.json" ]] && [[ "$workflow_file" == *"pypi"* ]]; then
|
|
((checks_failed++))
|
|
echo -e " ${RED}✗ Workflow type mismatch${NC}"
|
|
echo -e " Package: $pkg_name (TypeScript)"
|
|
echo -e " Workflow: $(basename $workflow_file) (should be publish.yml)"
|
|
else
|
|
((checks_passed++))
|
|
[[ "$verbose" == "true" ]] && echo -e " ${GREEN}✓ Workflow type matches package type${NC}"
|
|
fi
|
|
|
|
# Summary for this package
|
|
if [[ "$verbose" == "true" ]]; then
|
|
if [[ $checks_failed -eq 0 ]] && [[ $checks_warned -eq 0 ]]; then
|
|
echo -e " ${GREEN}Result: All checks passed ✓${NC}"
|
|
elif [[ $checks_failed -eq 0 ]]; then
|
|
echo -e " ${YELLOW}Result: $checks_passed passed, $checks_warned warnings${NC}"
|
|
else
|
|
echo -e " ${RED}Result: $checks_passed passed, $checks_warned warnings, $checks_failed failed${NC}"
|
|
fi
|
|
echo ""
|
|
fi
|
|
|
|
return $checks_failed
|
|
}
|
|
|
|
# =============================================================================
|
|
# Main Validation Logic
|
|
# =============================================================================
|
|
|
|
main() {
|
|
local category=""
|
|
local verbose=false
|
|
|
|
# Parse arguments
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--category)
|
|
category=$2
|
|
shift 2
|
|
;;
|
|
--verbose)
|
|
verbose=true
|
|
shift
|
|
;;
|
|
--help)
|
|
echo "Usage: $0 [OPTIONS]"
|
|
echo ""
|
|
echo "Options:"
|
|
echo " --category @cat Validate specific category (e.g., @mcp)"
|
|
echo " --verbose Show detailed validation output"
|
|
echo " --help Show this help message"
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " $0 # Validate all packages"
|
|
echo " $0 --category \"@mcp\" # Validate @mcp category"
|
|
echo " $0 --verbose # Detailed output"
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo -e "${RED}Error: Unknown option: $1${NC}"
|
|
echo "Use --help for usage information"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Print header
|
|
echo "================================================================================================"
|
|
echo " Forgejo Actions Workflow Validation"
|
|
echo "================================================================================================"
|
|
echo ""
|
|
|
|
# Build package list
|
|
local package_patterns=()
|
|
|
|
if [[ -n "$category" ]]; then
|
|
echo -e "${BLUE}Target: Category $category${NC}"
|
|
package_patterns=("$category"*)
|
|
else
|
|
echo -e "${BLUE}Target: All packages${NC}"
|
|
package_patterns=("@*")
|
|
fi
|
|
|
|
echo ""
|
|
echo "================================================================================================"
|
|
echo ""
|
|
|
|
# Validate packages
|
|
local total_packages=0
|
|
local total_failures=0
|
|
local total_warnings=0
|
|
|
|
for pattern in "${package_patterns[@]}"; do
|
|
for package_path in $WORKSPACE_ROOT/$pattern; do
|
|
# Skip if not a directory
|
|
[[ -d "$package_path" ]] || continue
|
|
|
|
# Skip node_modules, tooling, scripts
|
|
[[ "$package_path" == *"/node_modules/"* ]] && continue
|
|
[[ "$package_path" == *"/tooling"* ]] && continue
|
|
[[ "$package_path" == *"/scripts"* ]] && continue
|
|
|
|
# Skip if no package.json or pyproject.toml
|
|
if [[ ! -f "$package_path/package.json" ]] && [[ ! -f "$package_path/pyproject.toml" ]]; then
|
|
continue
|
|
fi
|
|
|
|
# Skip if no workflow directory
|
|
[[ -d "$package_path/.forgejo/workflows" ]] || continue
|
|
|
|
((total_packages++))
|
|
|
|
# Validate
|
|
if ! validate_package "$package_path" "$verbose"; then
|
|
((total_failures++))
|
|
fi
|
|
done
|
|
done
|
|
|
|
# Print summary
|
|
echo ""
|
|
echo "================================================================================================"
|
|
echo " VALIDATION SUMMARY"
|
|
echo "================================================================================================"
|
|
echo ""
|
|
echo "Total packages validated: $total_packages"
|
|
echo ""
|
|
|
|
if [[ $total_failures -eq 0 ]]; then
|
|
echo -e "${GREEN}✓ All validation checks passed${NC}"
|
|
echo ""
|
|
echo "All workflows are properly deployed and configured."
|
|
else
|
|
echo -e "${RED}✗ $total_failures package(s) failed validation${NC}"
|
|
echo ""
|
|
echo "Please fix the issues above and re-run validation."
|
|
echo ""
|
|
if [[ "$verbose" == "false" ]]; then
|
|
echo "Run with --verbose for detailed output."
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo "================================================================================================"
|
|
|
|
# Exit with error if any failures
|
|
[[ $total_failures -gt 0 ]] && exit 1
|
|
exit 0
|
|
}
|
|
|
|
main "$@"
|