validate-licenses.yml 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. name: Validate Plugin Licenses
  2. on:
  3. pull_request:
  4. paths:
  5. - 'plugins/**'
  6. push:
  7. branches: [main]
  8. paths:
  9. - 'plugins/**'
  10. permissions:
  11. contents: read
  12. jobs:
  13. validate-licenses:
  14. runs-on: ubuntu-latest
  15. steps:
  16. - uses: actions/checkout@v4
  17. - name: Check every plugin has an Apache 2.0 LICENSE file
  18. run: |
  19. set -euo pipefail
  20. # Plugins that intentionally ship a non-Apache LICENSE. claude-security
  21. # is deliberately proprietary (see #4427 — replacement rejected); it is
  22. # exempt from the Apache 2.0 content check but must still ship a LICENSE.
  23. exempt=("plugins/claude-security")
  24. missing=()
  25. wrong_content=()
  26. for plugin_dir in plugins/*/; do
  27. plugin="${plugin_dir%/}"
  28. if [[ ! -f "$plugin/LICENSE" ]]; then
  29. missing+=("$plugin")
  30. elif [[ " ${exempt[*]} " == *" $plugin "* ]]; then
  31. : # intentionally non-Apache — LICENSE presence already verified
  32. elif ! grep -q "Apache License" "$plugin/LICENSE" || \
  33. ! grep -q "Version 2.0" "$plugin/LICENSE"; then
  34. wrong_content+=("$plugin")
  35. fi
  36. done
  37. if [[ "${#missing[@]}" -gt 0 ]]; then
  38. echo "::error::The following plugins are missing a LICENSE file:"
  39. for p in "${missing[@]}"; do
  40. echo " - $p"
  41. done
  42. exit 1
  43. fi
  44. if [[ "${#wrong_content[@]}" -gt 0 ]]; then
  45. echo "::error::The following plugins have a LICENSE file that does not contain Apache 2.0 text:"
  46. for p in "${wrong_content[@]}"; do
  47. echo " - $p"
  48. done
  49. exit 1
  50. fi
  51. echo "All $(ls -d plugins/*/ | wc -l) plugins have a LICENSE file (Apache 2.0 except documented exemptions)."