Added PR/Issue management actions
This commit is contained in:
73
.gitea/workflows/issue-management.yml
Normal file
73
.gitea/workflows/issue-management.yml
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
name: Issue Management Bot
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [opened, edited, labeled, unlabeled]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
issue-triage:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
API_TOKEN: ${{ secrets.BOT_ACCESS_TOKEN }}
|
||||||
|
API_BASE_URL: https://git.psmattas.com/api/v1
|
||||||
|
REPO: ${{ gitea.repository }}
|
||||||
|
ISSUE_NUMBER: ${{ gitea.event.issue.number }}
|
||||||
|
ISSUE_AUTHOR: ${{ gitea.event.issue.user.login }}
|
||||||
|
ISSUE_TITLE: ${{ gitea.event.issue.title }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Welcome new contributors
|
||||||
|
if: gitea.event.action == 'opened'
|
||||||
|
run: |
|
||||||
|
# Check if this is the user's first issue
|
||||||
|
AUTHOR_ISSUES=$(curl -s -H "Authorization: token $API_TOKEN" "$API_BASE_URL/repos/$REPO/issues?state=all&created_by=$ISSUE_AUTHOR" | jq '. | length')
|
||||||
|
|
||||||
|
if [ "$AUTHOR_ISSUES" -eq 1 ]; then
|
||||||
|
WELCOME_MSG="👋 Welcome @$ISSUE_AUTHOR! Thanks for opening your first issue in Evercatch!\n\nOur team will review this shortly. In the meantime:\n- Check our [documentation](https://docs.evercatch.dev) for common solutions\n- Join our [community](https://community.evercatch.dev) for discussions\n- Review our [Code of Conduct](CODE_OF_CONDUCT.md)\n\nWe appreciate your contribution! 🎉"
|
||||||
|
COMMENT_JSON=$(jq -n --arg body "$WELCOME_MSG" '{"body": $body}')
|
||||||
|
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$COMMENT_JSON" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER/comments"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Auto-label bug reports
|
||||||
|
if: contains(gitea.event.issue.title, '[BUG]') || contains(gitea.event.issue.labels.*.name, 'bug')
|
||||||
|
run: |
|
||||||
|
LABELS='{"labels": ["bug", "status: investigating"]}'
|
||||||
|
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$LABELS" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER/labels"
|
||||||
|
|
||||||
|
- name: Auto-label feature requests
|
||||||
|
if: contains(gitea.event.issue.title, '[FEATURE]') || contains(gitea.event.issue.labels.*.name, 'feature')
|
||||||
|
run: |
|
||||||
|
LABELS='{"labels": ["feature", "status: under-review"]}'
|
||||||
|
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$LABELS" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER/labels"
|
||||||
|
|
||||||
|
- name: Auto-label support requests
|
||||||
|
if: contains(gitea.event.issue.title, '[SUPPORT]') || contains(gitea.event.issue.labels.*.name, 'question')
|
||||||
|
run: |
|
||||||
|
LABELS='{"labels": ["question", "status: needs-response"]}'
|
||||||
|
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$LABELS" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER/labels"
|
||||||
|
|
||||||
|
- name: Auto-label documentation issues
|
||||||
|
if: contains(gitea.event.issue.title, '[DOCS]') || contains(gitea.event.issue.labels.*.name, 'documentation')
|
||||||
|
run: |
|
||||||
|
LABELS='{"labels": ["documentation", "status: under-review"]}'
|
||||||
|
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$LABELS" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER/labels"
|
||||||
|
|
||||||
|
- name: Assign to team for critical bugs
|
||||||
|
if: contains(gitea.event.issue.labels.*.name, 'priority: critical')
|
||||||
|
run: |
|
||||||
|
ASSIGNEES='{"assignees": ["psmattas"]}'
|
||||||
|
curl -s -f -X PATCH -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$ASSIGNEES" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER"
|
||||||
|
|
||||||
|
URGENT_MSG="🚨 **Critical Issue Detected**\n\nThis issue has been marked as critical and assigned to @psmattas for immediate attention.\n\nExpected response time: **4 hours**"
|
||||||
|
COMMENT_JSON=$(jq -n --arg body "$URGENT_MSG" '{"body": $body}')
|
||||||
|
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$COMMENT_JSON" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER/comments"
|
||||||
|
|
||||||
|
- name: Request more info for incomplete issues
|
||||||
|
if: gitea.event.action == 'opened' && !contains(gitea.event.issue.body, 'Steps to Reproduce') && contains(gitea.event.issue.labels.*.name, 'bug')
|
||||||
|
run: |
|
||||||
|
INFO_MSG="Hi @$ISSUE_AUTHOR! 👋\n\nTo help us investigate this bug, could you please provide:\n\n1. **Steps to reproduce** the issue\n2. **Expected behavior** vs **actual behavior**\n3. Your **subscription tier**\n4. **Event IDs** or **timestamps** (if applicable)\n\nThis will help us resolve the issue faster. Thanks!"
|
||||||
|
COMMENT_JSON=$(jq -n --arg body "$INFO_MSG" '{"body": $body}')
|
||||||
|
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$COMMENT_JSON" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER/comments"
|
||||||
|
|
||||||
|
LABELS='{"labels": ["status: needs-info"]}'
|
||||||
|
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$LABELS" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER/labels"
|
||||||
@@ -59,7 +59,6 @@ jobs:
|
|||||||
CURRENT_LABELS_JSON=$(curl -s -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/labels")
|
CURRENT_LABELS_JSON=$(curl -s -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/labels")
|
||||||
LABEL_ID=$(echo "$CURRENT_LABELS_JSON" | jq --arg name "$LABEL_TO_REMOVE" '.[] | select(.name == $name) | .id')
|
LABEL_ID=$(echo "$CURRENT_LABELS_JSON" | jq --arg name "$LABEL_TO_REMOVE" '.[] | select(.name == $name) | .id')
|
||||||
|
|
||||||
# Only try to delete the label if we found its ID
|
|
||||||
if [ -n "$LABEL_ID" ]; then
|
if [ -n "$LABEL_ID" ]; then
|
||||||
echo "Found and removing '$LABEL_TO_REMOVE' (ID: $LABEL_ID)..."
|
echo "Found and removing '$LABEL_TO_REMOVE' (ID: $LABEL_ID)..."
|
||||||
curl -s -f -X DELETE -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/labels/$LABEL_ID"
|
curl -s -f -X DELETE -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/labels/$LABEL_ID"
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ jobs:
|
|||||||
The title of this pull request does not follow the required format. This PR is currently **blocked from merging**.
|
The title of this pull request does not follow the required format. This PR is currently **blocked from merging**.
|
||||||
|
|
||||||
To fix this, please update the title to match the following structure:
|
To fix this, please update the title to match the following structure:
|
||||||
**`EC-[JIRA_NUMBER]: [TYPE]: [Your Description]`**
|
**`EC-[ISSUE_NUMBER]: [TYPE]: [Your Description]`**
|
||||||
|
|
||||||
- **Valid [TYPE] values are:** `FEAT`, `FIX`, `DOCS`, `REFACTOR`, `STYLE`, `PERF`, `TEST`, `CHORE`
|
- **Valid [TYPE] values are:** `FEAT`, `FIX`, `DOCS`, `REFACTOR`, `STYLE`, `PERF`, `TEST`, `CHORE`
|
||||||
- **Example:** `EC-42: FEAT: Add new user login endpoint`
|
- **Example:** `EC-42: FEAT: Add new user login endpoint`
|
||||||
@@ -40,7 +40,7 @@ jobs:
|
|||||||
<!-- WIP_VALIDATOR_COMMENT -->
|
<!-- WIP_VALIDATOR_COMMENT -->
|
||||||
run: |
|
run: |
|
||||||
WIP_LABEL="status: work-in-progress"
|
WIP_LABEL="status: work-in-progress"
|
||||||
INVALID_LABEL="INVALID-TITLE-DO-NOT-MERGE"
|
INVALID_LABEL="status: invalid-title"
|
||||||
WIP_REGEX="^WIP:"
|
WIP_REGEX="^WIP:"
|
||||||
FORMAT_REGEX="^EC-[0-9]+: (FEAT|FIX|DOCS|REFACTOR|STYLE|PERF|TEST|CHORE): .+$"
|
FORMAT_REGEX="^EC-[0-9]+: (FEAT|FIX|DOCS|REFACTOR|STYLE|PERF|TEST|CHORE): .+$"
|
||||||
ISSUES_API_URL="$API_BASE_URL/repos/$REPO/issues/$PR_NUMBER"
|
ISSUES_API_URL="$API_BASE_URL/repos/$REPO/issues/$PR_NUMBER"
|
||||||
|
|||||||
98
.gitea/workflows/stale-issues.yml
Normal file
98
.gitea/workflows/stale-issues.yml
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
name: Close Stale Issues
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * *' # Daily at midnight UTC
|
||||||
|
workflow_dispatch: # Manual trigger
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stale:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
API_TOKEN: ${{ secrets.BOT_ACCESS_TOKEN }}
|
||||||
|
API_BASE_URL: https://git.psmattas.com/api/v1
|
||||||
|
REPO: ${{ gitea.repository }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Mark stale issues
|
||||||
|
run: |
|
||||||
|
# Issues with no activity for 30 days
|
||||||
|
THIRTY_DAYS_AGO=$(date -u -d '30 days ago' '+%Y-%m-%dT%H:%M:%SZ')
|
||||||
|
|
||||||
|
# Get all open issues updated before 30 days ago
|
||||||
|
ISSUES=$(curl -s -H "Authorization: token $API_TOKEN" "$API_BASE_URL/repos/$REPO/issues?state=open&since=$THIRTY_DAYS_AGO&sort=updated&order=asc" | jq -c '.[]')
|
||||||
|
|
||||||
|
echo "$ISSUES" | while IFS= read -r issue; do
|
||||||
|
ISSUE_NUMBER=$(echo "$issue" | jq -r '.number')
|
||||||
|
UPDATED_AT=$(echo "$issue" | jq -r '.updated_at')
|
||||||
|
HAS_STALE_LABEL=$(echo "$issue" | jq -r '.labels[] | select(.name == "status: stale") | .name')
|
||||||
|
|
||||||
|
# Skip if already has stale label
|
||||||
|
if [ -n "$HAS_STALE_LABEL" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Marking issue #$ISSUE_NUMBER as stale (last updated: $UPDATED_AT)"
|
||||||
|
|
||||||
|
# Add stale label
|
||||||
|
LABELS='{"labels": ["status: stale"]}'
|
||||||
|
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$LABELS" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER/labels"
|
||||||
|
|
||||||
|
# Add stale comment
|
||||||
|
STALE_MSG="This issue has been automatically marked as stale because it has not had recent activity.\n\nIt will be closed in **14 days** if no further activity occurs.\n\nIf this issue is still relevant, please:\n- Add a comment with updates\n- Remove the \`status: stale\` label\n\nThank you for your contributions! 🙏"
|
||||||
|
COMMENT_JSON=$(jq -n --arg body "$STALE_MSG" '{"body": $body}')
|
||||||
|
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$COMMENT_JSON" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER/comments"
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Close stale issues
|
||||||
|
run: |
|
||||||
|
# Issues marked stale for 14+ days
|
||||||
|
FOURTEEN_DAYS_AGO=$(date -u -d '14 days ago' '+%Y-%m-%dT%H:%M:%SZ')
|
||||||
|
|
||||||
|
# Get stale issues
|
||||||
|
ISSUES=$(curl -s -H "Authorization: token $API_TOKEN" "$API_BASE_URL/repos/$REPO/issues?state=open&labels=status:stale" | jq -c '.[]')
|
||||||
|
|
||||||
|
echo "$ISSUES" | while IFS= read -r issue; do
|
||||||
|
ISSUE_NUMBER=$(echo "$issue" | jq -r '.number')
|
||||||
|
UPDATED_AT=$(echo "$issue" | jq -r '.updated_at')
|
||||||
|
|
||||||
|
# Check if updated_at is older than 14 days
|
||||||
|
if [[ "$UPDATED_AT" < "$FOURTEEN_DAYS_AGO" ]]; then
|
||||||
|
echo "Closing stale issue #$ISSUE_NUMBER (last updated: $UPDATED_AT)"
|
||||||
|
|
||||||
|
# Close the issue
|
||||||
|
CLOSE_JSON='{"state": "closed"}'
|
||||||
|
curl -s -f -X PATCH -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$CLOSE_JSON" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER"
|
||||||
|
|
||||||
|
# Add closing comment
|
||||||
|
CLOSE_MSG="This issue was automatically closed due to inactivity.\n\nIf you believe this was closed in error, please:\n1. Reopen the issue\n2. Provide updated information\n3. Remove the \`status: stale\` label\n\nThank you! 🙏"
|
||||||
|
COMMENT_JSON=$(jq -n --arg body "$CLOSE_MSG" '{"body": $body}')
|
||||||
|
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$COMMENT_JSON" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER/comments"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Remove stale label on activity
|
||||||
|
run: |
|
||||||
|
# Get stale issues that were recently updated
|
||||||
|
ISSUES=$(curl -s -H "Authorization: token $API_TOKEN" "$API_BASE_URL/repos/$REPO/issues?state=open&labels=status:stale" | jq -c '.[]')
|
||||||
|
|
||||||
|
echo "$ISSUES" | while IFS= read -r issue; do
|
||||||
|
ISSUE_NUMBER=$(echo "$issue" | jq -r '.number')
|
||||||
|
|
||||||
|
# Get comments
|
||||||
|
COMMENTS=$(curl -s -H "Authorization: token $API_TOKEN" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER/comments")
|
||||||
|
LATEST_COMMENT_AUTHOR=$(echo "$COMMENTS" | jq -r '.[-1].user.login')
|
||||||
|
|
||||||
|
# If latest comment is not from bot, remove stale label
|
||||||
|
if [ "$LATEST_COMMENT_AUTHOR" != "EC-bot" ] && [ "$LATEST_COMMENT_AUTHOR" != "gitea-actions" ]; then
|
||||||
|
echo "Removing stale label from issue #$ISSUE_NUMBER (recent activity detected)"
|
||||||
|
|
||||||
|
# Get label ID
|
||||||
|
LABELS=$(curl -s -H "Authorization: token $API_TOKEN" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER/labels")
|
||||||
|
STALE_LABEL_ID=$(echo "$LABELS" | jq -r '.[] | select(.name == "status: stale") | .id')
|
||||||
|
|
||||||
|
if [ -n "$STALE_LABEL_ID" ]; then
|
||||||
|
curl -s -f -X DELETE -H "Authorization: token $API_TOKEN" "$API_BASE_URL/repos/$REPO/issues/$ISSUE_NUMBER/labels/$STALE_LABEL_ID"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
Reference in New Issue
Block a user