# `/reopen` command (GH #388): GitHub only lets issue authors reopen issues # they closed themselves — once a maintainer closes, the author is locked out # and ends up filing duplicates. This workflow restores that ability: the # original author comments `/reopen` and the issue reopens automatically. # # Matching is deliberately relaxed (`contains`, not `startsWith`): people # write "Please /reopen" or bury the command mid-comment (GH #388 feedback). # False positives are bounded — only the original author on their own closed # issue can trigger it, and the worst case is an issue reopening. # # Issues closed as "not planned" are excluded on purpose: that close state is # a maintainer decision, so the command answers with a hint instead. # # Security: no checkout, comment body is only used in the `if` expression # (never interpolated into shell), token scope is issues:write only. name: Issue reopen command on: issue_comment: types: [created] permissions: issues: write jobs: reopen: if: >- !github.event.issue.pull_request && github.event.issue.state == 'closed' && github.event.comment.user.login == github.event.issue.user.login && contains(github.event.comment.body, '/reopen') runs-on: ubuntu-latest steps: - name: Reopen issue (or explain why not) env: GH_TOKEN: ${{ github.token }} ISSUE: ${{ github.event.issue.number }} run: | set -euo pipefail reason=$(gh api "repos/$GITHUB_REPOSITORY/issues/$ISSUE" --jq '.state_reason // "completed"') if [ "$reason" = "not_planned" ]; then gh issue comment "$ISSUE" --repo "$GITHUB_REPOSITORY" --body \ "This issue was closed as **not planned**, which is a maintainer decision, so \`/reopen\` does not apply here. A maintainer will review this request." else gh issue reopen "$ISSUE" --repo "$GITHUB_REPOSITORY" \ --comment "Reopened at the author's request via \`/reopen\`." fi