diff --git a/.github/workflows/validate-new-issue.yml b/.github/workflows/validate-new-issue.yml index 3badef8..b17f2d9 100644 --- a/.github/workflows/validate-new-issue.yml +++ b/.github/workflows/validate-new-issue.yml @@ -1,94 +1,100 @@ name: Validate new issue on: issues: types: ["opened"] jobs: validate-new-issue: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: "Validate new issue" shell: bash env: GITHUB_TOKEN: ${{ github.token }} run: | issue_number=${{ github.event.issue.number }} echo "Validating issue #${issue_number}." # Trust users who belong to the getsentry org. if gh api "https://api.github.com/orgs/getsentry/members/${{ github.actor }}" >/dev/null 2>&1; then echo "Skipping validation, because ${{ github.actor }} is a member of the getsentry org." exit 0 else echo "${{ github.actor }} is not a member of the getsentry org. 🧐" fi + # Helper + function gh-issue-label() { + gh api "/repos/:owner/:repo/issues/${1}/labels" \ + -X POST \ + --input <(echo "{\"labels\":[\"$2\"]}") + } + # Prep reasons for error message comment. REASON="your issue does not properly use one of this repo's available issue templates" REASON_EXACT_MATCH="you created an issue from a template without filling in anything" REASON_EMPTY="you created an empty issue" BASE_CASE_TITLE="validation bot is confused" # Definition of valid: # - is a report about buggy validation 😅 or ... # - not empty (ignoring whitespace) # - matches a template # - all the headings are also in this issue # - extra headings in the issue are fine # - order doesn't matter # - case-sensitive tho # - not an *exact* match for a template (ignoring whitespace) jq -r .issue.title "$GITHUB_EVENT_PATH" > issue-title if diff issue-title <(echo "$BASE_CASE_TITLE") > /dev/null; then echo "Infinite recursion avoided." exit 0 fi function extract-headings { { sed 's/\r$//' "$1" | grep '^#' || echo -n ''; } | sort; } jq -r .issue.body "$GITHUB_EVENT_PATH" > issue if ! grep -q '[^[:space:]]' issue; then REASON="${REASON_EMPTY}" else extract-headings <(cat issue) > headings-in-issue for template in $(ls .github/ISSUE_TEMPLATE/*.md 2> /dev/null); do # Strip front matter. https://stackoverflow.com/a/29292490/14946704 sed -i'' '1{/^---$/!q;};1,/^---$/d' "$template" extract-headings "$template" > headings-in-template echo -n "$(basename $template)? " if [ ! -s headings-in-template ]; then echo "No headers in template. 🤷" elif [ -z "$(comm -23 headings-in-template headings-in-issue)" ]; then echo "Match! 👍 💃" if diff -Bw "$template" issue > /dev/null; then echo "... like, an /exact/ match. 😖" REASON="${REASON_EXACT_MATCH}" break else - gh api "/repos/:owner/:repo/issues/${issue_number}/labels" \ - -X POST \ - --input <(echo '{"labels":["Status: Unrouted"]}') + gh-issue-label "${issue_number}" "Status: Unrouted" exit 0 fi else echo "No match. 👎" fi done fi - # Failed validation! Close the issue with a comment. + # Failed validation! Close the issue with a comment and a label. cat << EOF > comment 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 }}). 😬) ---- [![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) ([log](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})) EOF echo -n "Commented: " - gh issue comment ${{ github.event.issue.number }} --body "$(cat comment)" - gh issue close ${{ github.event.issue.number }} + gh issue comment "${issue_number}" --body "$(cat comment)" + gh-issue-label "${issue_number}" "Status: Invalid" + gh issue close "${issue_number}" echo "Closed with: \"${REASON}.\""