validate-new-issue.yml 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. name: Validate new issue
  2. on:
  3. issues:
  4. types: ["opened"]
  5. jobs:
  6. validate-new-issue:
  7. runs-on: ubuntu-latest
  8. steps:
  9. - uses: actions/checkout@v2
  10. - name: "Validate new issue"
  11. shell: bash
  12. env:
  13. GITHUB_TOKEN: ${{ github.token }}
  14. run: |
  15. issue_number=${{ github.event.issue.number }}
  16. echo "Validating issue #${issue_number}."
  17. # Trust users who belong to the getsentry org.
  18. if gh api "https://api.github.com/orgs/getsentry/members/${{ github.actor }}" >/dev/null 2>&1; then
  19. echo "Skipping validation, because ${{ github.actor }} is a member of the getsentry org."
  20. exit 0
  21. else
  22. echo "${{ github.actor }} is not a member of the getsentry org. 🧐"
  23. fi
  24. # Helper
  25. function gh-issue-label() {
  26. gh api "/repos/:owner/:repo/issues/${1}/labels" \
  27. -X POST \
  28. --input <(echo "{\"labels\":[\"$2\"]}")
  29. }
  30. # Prep reasons for error message comment.
  31. REASON="your issue does not properly use one of this repo's available issue templates"
  32. REASON_EXACT_MATCH="you created an issue from a template without filling in anything"
  33. REASON_EMPTY="you created an empty issue"
  34. BASE_CASE_TITLE="validation bot is confused"
  35. # Definition of valid:
  36. # - is a report about buggy validation πŸ˜… or ...
  37. # - not empty (ignoring whitespace)
  38. # - matches a template
  39. # - at least one of the headings are also in this issue
  40. # - extra headings in the issue are fine
  41. # - order doesn't matter
  42. # - case-sensitive tho
  43. # - not an *exact* match for a template (ignoring whitespace)
  44. jq -r .issue.title "$GITHUB_EVENT_PATH" > issue-title
  45. if diff issue-title <(echo "$BASE_CASE_TITLE") > /dev/null; then
  46. echo "Infinite recursion avoided."
  47. exit 0
  48. fi
  49. function extract-headings { { sed 's/\r$//' "$1" | grep '^#' || echo -n ''; } | sort; }
  50. jq -r .issue.body "$GITHUB_EVENT_PATH" > issue
  51. if ! grep -q '[^[:space:]]' issue; then
  52. REASON="${REASON_EMPTY}"
  53. else
  54. extract-headings <(cat issue) > headings-in-issue
  55. for template in $(ls .github/ISSUE_TEMPLATE/*.md 2> /dev/null); do
  56. # Strip front matter. https://stackoverflow.com/a/29292490/14946704
  57. sed -i'' '1{/^---$/!q;};1,/^---$/d' "$template"
  58. extract-headings "$template" > headings-in-template
  59. echo -n "$(basename $template)? "
  60. if [ ! -s headings-in-template ]; then
  61. echo "No headers in template. 🀷"
  62. elif [ "$(comm -12 headings-in-template headings-in-issue)" ]; then
  63. echo "Match! πŸ‘ πŸ’ƒ"
  64. if diff -Bw "$template" issue > /dev/null; then
  65. echo "... like, an /exact/ match. πŸ˜–"
  66. REASON="${REASON_EXACT_MATCH}"
  67. break
  68. else
  69. gh-issue-label "${issue_number}" "Status: Unrouted"
  70. exit 0
  71. fi
  72. else
  73. echo "No match. πŸ‘Ž"
  74. fi
  75. done
  76. fi
  77. # Failed validation! Close the issue with a comment and a label.
  78. cat << EOF > comment
  79. Sorry, friend. As far as this ol' bot can tell, ${REASON}. Please [try again](https://github.com/${{ github.repository }}/issues/new/choose), if you like. (And if I'm confused, please [let us know](https://github.com/getsentry/.github/issues/new?title=$(echo "$BASE_CASE_TITLE" | tr ' ' '+')&body=${{ github.event.issue.html_url }}). 😬)
  80. ----
  81. [![Did you see the memo about this?](https://user-images.githubusercontent.com/134455/104515469-e04a9c80-55c0-11eb-8e15-ffe9c0b8dd7f.gif)](https://www.youtube.com/watch?v=Fy3rjQGc6lA)
  82. ([log](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}))
  83. EOF
  84. echo -n "Commented: "
  85. gh issue comment "${issue_number}" --body "$(cat comment)"
  86. gh-issue-label "${issue_number}" "Status: Invalid"
  87. gh issue close "${issue_number}"
  88. echo "Closed with: \"${REASON}.\""