|
@@ -1,100 +0,0 @@
|
|
|
-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
|
|
|
- # - at least one of 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 [ "$(comm -12 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-issue-label "${issue_number}" "Status: Unrouted"
|
|
|
- exit 0
|
|
|
- fi
|
|
|
- else
|
|
|
- echo "No match. π"
|
|
|
- fi
|
|
|
- done
|
|
|
- fi
|
|
|
-
|
|
|
- # 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 }}). π¬)
|
|
|
-
|
|
|
- ----
|
|
|
-
|
|
|
- [](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 "${issue_number}" --body "$(cat comment)"
|
|
|
- gh-issue-label "${issue_number}" "Status: Invalid"
|
|
|
- gh issue close "${issue_number}"
|
|
|
- echo "Closed with: \"${REASON}.\""
|