Disgaea 3: Absence of Detention [PCSE00022] #7111
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # this code adapted from https://github.com/xenia-project/game-compatibility/blob/master/.github/workflows/autoclose.yml | |
| # Modifyied for Vita3K | |
| # TODO: add check screenshots and log provide. | |
| name: Compatibility bot | |
| on: | |
| issues: | |
| types: [opened, edited] | |
| issue_comment: | |
| type: created | |
| jobs: | |
| automoderation: | |
| runs-on: ubuntu-latest | |
| if: github.repository == 'Vita3K/compatibility' && (github.event.action != 'edited' || github.event.changes.title.from == null) ## Don't run on edited issue title | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: checking an issue | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| issue_number: ${{ github.event.issue.number }} | |
| issue_author: ${{ github.event.issue.user.login }} | |
| issue_title: ${{ github.event.issue.title }} | |
| issue_labels: ${{ join(github.event.issue.labels.*.name) }} | |
| issue_body: ${{ github.event.issue.body }} | |
| issue_state: ${{ github.event.issue.state }} | |
| issue_comment_author: ${{ github.event.comment.user.login }} | |
| issue_comment_body: ${{ github.event.comment.body }} | |
| run: | | |
| case $GITHUB_EVENT_NAME in | |
| issues) | |
| github_event_name_friendly=issue | |
| ## can be make this better? | |
| issue_body_trim1() { | |
| issue_body_trim1=$(echo "$issue_body" | grep -i "$1") | |
| } | |
| issue_body_trim2() { | |
| issue_body_trim2=$(echo "$issue_body" | grep -i "$1" -A 10) | |
| };; | |
| issue_comment) | |
| issue_comment_body_trim() { | |
| issue_comment_body_trim=$(echo "$issue_comment_body" | grep -i "$1" -A 10) | |
| } | |
| issue_comment_author_whitelist=(Zangetsu38 othmanead nishinji Macdu illusionMan1212 EXtremeExploit GamingDucking Croden1999 saturnsky tasle1001 spacemul gymzatan Slade1972) | |
| for whitelisted_author in "${issue_comment_author_whitelist[@]}"; do | |
| if [[ "$issue_comment_author" = "$whitelisted_author" && -z "$issue_comment_author_whitelisted" ]]; then | |
| issue_comment_author_whitelisted=1 | |
| break | |
| fi | |
| done | |
| github_event_name_friendly='issue comment';; | |
| esac | |
| compatibility_report_invalidate() { | |
| echo "$1" | |
| compatibility_report_invalid_reasons+=$'\n'" * $1" | |
| } | |
| if [ $GITHUB_EVENT_NAME != issue_comment ]; then | |
| # Check issue title | |
| if [[ "$issue_title" =~ ^(.+ \[PCS[A-Z]{1}[0-9]{5}\]|.+ \[NPXS10007\])$ ]]; then | |
| echo 'Title is valid.' | |
| # Check for duplicate(s) | |
| if [ ${{ github.event.action }} = opened ]; then | |
| repository_issues_json=$(gh api graphql --jq '.data.repository[]' --paginate -f query=' | |
| query($endCursor: String) { | |
| repository(owner: "Vita3K", name: "compatibility") { | |
| issues(first:100, states:OPEN, after:$endCursor) { | |
| nodes { | |
| number | |
| title | |
| } | |
| pageInfo { | |
| hasNextPage | |
| endCursor | |
| } | |
| } | |
| } | |
| } | |
| ') | |
| readarray -t issue_numbers < <(jq -r '.nodes[].number' <<<"$repository_issues_json") | |
| readarray -t issue_titles < <(jq -r '.nodes[].title' <<<"${repository_issues_json,,}") | |
| issue_title_lowercase="${issue_title,,}" | |
| ## Skip 1 to skip empty entry (TODO: Is this a hack?) | |
| for (( i = 0; i <= $(( ${#issue_numbers[@]} - 1 )); i++ )); do | |
| if [[ "$issue_title_lowercase" =~ "${issue_titles[$i]}" && "$issue_number" != "${issue_numbers[$i]}" ]]; then | |
| issue_duplicates=$'\n'" * #${issue_numbers[$i]}" | |
| fi | |
| done | |
| fi | |
| if [ -z "$issue_duplicates" ]; then | |
| echo "Issue probably isn't a duplicate." | |
| else | |
| compatibility_report_invalidate "Issue is a duplicate of:$issue_duplicates" | |
| fi | |
| elif [ $GITHUB_EVENT_NAME = issues ]; then | |
| compatibility_report_invalidate 'Title is invalid.' | |
| fi | |
| if [ $GITHUB_EVENT_NAME = issues ]; then | |
| # Check Vita3K version | |
| if [[ "${issue_body,,}" =~ "commit hash" ]]; then | |
| issue_body_trim1 'Commit hash' | |
| if [[ "${issue_body_trim1,,}" =~ (.+ https://github.com/vita3k/vita3k/commit/[0-9a-f]{5,40}) ]]; then | |
| echo 'Commit hash is valid.' | |
| else | |
| compatibility_report_invalidate 'Commit hash is invalid or missing.' | |
| fi | |
| else | |
| compatibility_report_invalidate "Issue doesn't follow the template. (Commit hash)" | |
| fi | |
| # Check Android issue | |
| if [[ "${issue_body,,}" =~ "os" ]]; then | |
| issue_body_trim1 'OS' | |
| if [[ "$issue_body_trim1" =~ (.+ Android) ]]; then | |
| compatibility_report_invalidate 'Android issue detected.' | |
| else | |
| echo 'Android is not detected' | |
| fi | |
| else | |
| compatibility_report_invalidate "Issue doesn't follow the template. (OS)" | |
| fi | |
| fi | |
| fi | |
| # Check Labels | |
| readarray -t repository_labels < <(gh api graphql --paginate --jq '.data.repository.labels.nodes[].name' -f query=' | |
| query($endCursor: String) { | |
| repository(owner: "Vita3K", name: "compatibility") { | |
| labels(first:100, after:$endCursor) { | |
| nodes { | |
| name | |
| } | |
| pageInfo { | |
| hasNextPage | |
| endCursor | |
| } | |
| } | |
| } | |
| } | |
| ') | |
| repository_labels_invalid=("invalid issue" "duplicate issue" ) | |
| case $GITHUB_EVENT_NAME in | |
| issues) | |
| if [[ "${issue_body,,}" =~ "recommended labels" ]]; then | |
| issue_body_trim2 'Recommended labels' | |
| issue_labels_body=$(echo "$issue_body_trim2" | sed '/# Recommended labels/d'| sed '/<!--[^>]*-->/d') | |
| for repository_label in "${repository_labels[@]}"; do | |
| if [[ "${issue_labels_body,,}" =~ "${repository_label,,}" ]]; then | |
| echo "Valid label detected: $repository_label" | |
| labels_to_add+=("$repository_label") | |
| fi | |
| done | |
| if [ -n "$labels_to_add" ]; then | |
| status_label_list=("Nothing" "Bootable" "Intro" "Menu" "Ingame -" "Ingame +" "Playable") | |
| issue_labels_state_count=0 | |
| for status_labels in "${status_label_list[@]}"; do | |
| for adding_labels in "${labels_to_add[@]}"; do | |
| if [[ "$status_labels" == "$adding_labels" ]]; then | |
| issue_labels_state_count=$((issue_labels_state_count + 1)) | |
| fi | |
| done | |
| done | |
| echo "Status label count: $issue_labels_state_count" | |
| if [[ $issue_labels_state_count -eq 1 ]]; then | |
| echo 'State label was provided.' | |
| elif [ $issue_labels_state_count -gt 1 ]; then | |
| compatibility_report_invalidate 'Multiple state labels were provided.' | |
| else | |
| compatibility_report_invalidate 'State label is invalid or missing.' | |
| fi | |
| else | |
| compatibility_report_invalidate 'Labels are invalid or missing.' | |
| fi | |
| else | |
| compatibility_report_invalidate "Issue doesn't follow the template. (Recommended labels)" | |
| fi;; | |
| # code for comment | |
| issue_comment) | |
| if [ -n "$issue_comment_author_whitelisted" ]; then | |
| if [[ "${issue_comment_body,,}" =~ "recommended labels" ]]; then | |
| issue_comment_body_trim 'Recommended labels' | |
| issue_comment_labels_body=$(echo "${issue_comment_body_trim,,}" | sed '/# recommended labels/d' | sed '/<!--[^>]*-->/d') | |
| echo "issue comment labels body: $issue_comment_labels_body" | |
| for repository_label in "${repository_labels[@]}"; do | |
| if [[ "${issue_comment_labels_body,,}" =~ "${repository_label,,}" ]]; then | |
| if [[ ! "${repository_labels_invalid[@]}" =~ "$repository_label" ]]; then | |
| echo "Valid label detected: $repository_label" | |
| labels_to_add+=("$repository_label") | |
| else | |
| issue_labels_invalid_used+=$'\n'" * $repository_label" | |
| fi | |
| fi | |
| done | |
| else | |
| echo "Issue comment didn't suggest any label." | |
| fi | |
| if [ -z "$issue_labels_invalid_used" ]; then | |
| echo 'No invalid labels were used.' | |
| if [ -n "$labels_to_add" ]; then | |
| status_label_list=("Nothing" "Bootable" "Intro" "Menu" "Ingame -" "Ingame +" "Playable") | |
| issue_labels_state_count=0 | |
| for status_labels in "${status_label_list[@]}"; do | |
| for adding_labels in "${labels_to_add[@]}"; do | |
| if [[ "$status_labels" == "$adding_labels" ]]; then | |
| issue_labels_state_count=$((issue_labels_state_count + 1)) | |
| fi | |
| done | |
| done | |
| echo "Status label count: $issue_labels_state_count" | |
| if [[ $issue_labels_state_count -eq 1 ]]; then | |
| echo 'State label was provided. Removing old labels' | |
| echo "Removing label(s): ${issue_labels[@]}" | |
| for removing_labels in "${issue_labels[@]}"; do | |
| gh issue edit $issue_number --remove-label "${removing_labels}" | |
| done | |
| elif [ $issue_labels_state_count -gt 1 ]; then | |
| unset labels_to_add ## TODO: Is there a better way of doing this? | |
| compatibility_report_invalidate 'Multiple state labels were provided.' | |
| else | |
| echo 'State label is missing.' | |
| fi | |
| fi | |
| else | |
| unset labels_to_add ## TODO: Is there a better way of doing this? | |
| compatibility_report_invalidate "Invalid label(s) provided;$issue_labels_invalid_used" | |
| fi | |
| fi;; | |
| esac | |
| if [ -z "$compatibility_report_invalid_reasons" ]; then | |
| echo "$github_event_name_friendly is valid." | |
| if [[ $issue_state = closed && "$issue_labels" =~ ${repository_labels_invalid[0]}|${repository_labels_invalid[1]} && $GITHUB_EVENT_NAME != issue_comment ]]; then ## Don't reopen by issue comment | |
| ## TODO: Hide (or delete) the close comment if issue is reopened | |
| gh issue edit $issue_number --remove-label "${repository_labels_invalid[0]},${repository_labels_invalid[1]}" | |
| gh issue reopen $issue_number | |
| fi | |
| else | |
| unset labels_to_add ## TODO: Is there a better way of doing this? | |
| echo "$github_event_name_friendly is invalid." | |
| ## Closing "invalid" (i.e. potentially outdated) edited issues is too risky | |
| if [[ ${{ github.event.action }} = opened && $GITHUB_EVENT_NAME != issue_comment ]]; then ## Only comment on 'opened' to prevent duplicate comments | |
| gh ${github_event_name_friendly,,} close $issue_number | |
| comment_close_body="@$issue_author your ${github_event_name_friendly,,} was automatically closed because it didn't follow the issue templates." | |
| comment_close_body+=$'\n'"Here is what's wrong with your compatibility report:" | |
| comment_close_body+="$compatibility_report_invalid_reasons" | |
| comment_close_body+=$'\n\n'"**Don't submit a new issue.** Just edit this one and if it's valid it will be automatically reopened." | |
| comment_close_body+=$'\n\n'"If you want help with Vita3K and/or your game go to our Discord server's #help channel: https://discord.gg/6aGwQzh" | |
| gh "${github_event_name_friendly,,}" comment $issue_number -b "$comment_close_body" | |
| if [ -n "$issue_duplicates" ]; then | |
| labels_to_add="${repository_labels_invalid[1]}" | |
| else | |
| labels_to_add="${repository_labels_invalid[0]}" | |
| fi | |
| fi | |
| fi | |
| if [ -n "$labels_to_add" ]; then | |
| echo "Adding label(s): ${labels_to_add[@]}" | |
| for adding_labels in "${labels_to_add[@]}"; do | |
| ## + and - are special characters in bash, so we need to escape them | |
| if [[ "$adding_labels" =~ "Ingame -" ]]; then | |
| gh issue edit $issue_number --add-label 'Ingame -' | |
| elif [[ "$adding_labels" =~ "Ingame +" ]]; then | |
| gh issue edit $issue_number --add-label 'Ingame +' | |
| else | |
| gh issue edit $issue_number --add-label "${adding_labels}" | |
| fi | |
| done | |
| fi |