Initial commit

This commit is contained in:
Evercatch
2026-02-13 15:15:20 +00:00
commit 27c69d201f
10 changed files with 507 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
name: PR Management Bot
on:
pull_request:
types: [opened, edited, synchronize, reopened]
branches: [main]
jobs:
pr-bot:
runs-on: ubuntu-latest
env:
API_TOKEN: ${{ secrets.BOT_ACCESS_TOKEN }}
API_BASE_URL: https://git.psmattas.com/api/v1
REPO: ${{ gitea.repository }}
PR_NUMBER: ${{ gitea.event.pull_request.number }}
PR_AUTHOR: ${{ gitea.actor }}
steps:
- name: Check out repository
uses: https://gitea.com/actions/checkout@v4
with:
fetch-depth: 0
- name: Auto-label from commit messages
run: |
API_URL="$API_BASE_URL/repos/$REPO/pulls/$PR_NUMBER/commits"
MESSAGES=$(curl -s -H "Authorization: token $API_TOKEN" "$API_URL" | jq -r '.[].commit.message')
UNIQUE_TYPES=$(echo "$MESSAGES" | grep -oP '^EC-\d+: \K(FEAT|FIX|DOCS|STYLE|REFACTOR|PERF|TEST|CHORE)' | sort -u)
if [[ -z "$UNIQUE_TYPES" ]]; then exit 0; fi
LABELS_JSON=$(echo "$UNIQUE_TYPES" | jq -R '("type: " + (. | ascii_downcase))' | jq -s '{"labels": .}')
ISSUES_API_URL="$API_BASE_URL/repos/$REPO/issues/$PR_NUMBER/labels"
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$LABELS_JSON" "$ISSUES_API_URL"
- name: Auto-assign author
if: gitea.event.pull_request.assignees_count == 0 && gitea.actor != 'gitea-actions' && gitea.actor != 'EC-bot'
run: |
ISSUES_EDIT_API_URL="$API_BASE_URL/repos/$REPO/issues/$PR_NUMBER"
JSON_PAYLOAD=$(echo "$PR_AUTHOR" | jq -R '{"assignees": [.]}')
curl -s -f -X PATCH -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$JSON_PAYLOAD" "$ISSUES_EDIT_API_URL"
- name: Add conflict label and comment
if: gitea.event.pull_request.merge_status == 'CONFLICT'
run: |
COMMENT_BODY="🚨 **Merge Conflict Detected** 🚨\n\nHi @$PR_AUTHOR, this pull request has merge conflicts with the \`main\` branch. Please resolve them by rebasing or merging \`main\` into your branch so the PR can be reviewed."
COMMENT_JSON=$(jq -n --arg body "$COMMENT_BODY" '{"body": $body}')
ISSUES_API_URL="$API_BASE_URL/repos/$REPO/issues/$PR_NUMBER/comments"
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$COMMENT_JSON" "$ISSUES_API_URL"
LABEL_JSON='{ "labels": ["status: needs-rebase"] }'
LABELS_API_URL="$API_BASE_URL/repos/$REPO/issues/$PR_NUMBER/labels"
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$LABEL_JSON" "$LABELS_API_URL"
- name: Remove 'needs-rebase' label if clean
if: gitea.event.pull_request.merge_status != 'CONFLICT'
run: |
LABEL_TO_REMOVE="status: needs-rebase"
ISSUES_API_URL="$API_BASE_URL/repos/$REPO/issues/$PR_NUMBER"
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')
# Only try to delete the label if we found its ID
if [ -n "$LABEL_ID" ]; then
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"
fi
- name: Auto-assign reviewers
run: |
REVIEWERS_JSON='{ "reviewers": ["psmattas"] }'
if [[ -n "$REVIEWERS_JSON" ]]; then
echo "Requesting review from: $REVIEWERS_JSON"
API_URL="$API_BASE_URL/repos/$REPO/pulls/$PR_NUMBER/requested_reviewers"
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$REVIEWERS_JSON" "$API_URL"
fi

View File

@@ -0,0 +1,105 @@
name: PR Title Checker
on:
pull_request:
types: [opened, edited, synchronize]
jobs:
enforce-pr-title:
name: Validate PR Title Format
runs-on: ubuntu-latest
steps:
- name: Check PR Title and Manage Labels/Comments
env:
API_TOKEN: ${{ secrets.BOT_ACCESS_TOKEN }}
API_BASE_URL: https://git.psmattas.com/api/v1
REPO: ${{ gitea.repository }}
PR_NUMBER: ${{ gitea.event.pull_request.number }}
PR_TITLE: ${{ gitea.event.pull_request.title }}
COMMENT_BODY_INVALID: |
Hi @${{ gitea.actor }}, thanks for the contribution!
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:
**`EC-[JIRA_NUMBER]: [TYPE]: [Your Description]`**
- **Valid [TYPE] values are:** `FEAT`, `FIX`, `DOCS`, `REFACTOR`, `STYLE`, `PERF`, `TEST`, `CHORE`
- **Example:** `EC-42: FEAT: Add new user login endpoint`
Once you have updated the title, this check will re-run automatically and remove the blocking label.
<!-- PR_TITLE_VALIDATOR_COMMENT -->
COMMENT_BODY_WIP: |
Hi @${{ gitea.actor }}, this pull request has been marked as a **Work in Progress**.
While in this state, it is **blocked from merging**.
When the PR is ready for review, please remove the `WIP:` prefix from the title. This check will re-run automatically and remove the blocking label.
<!-- WIP_VALIDATOR_COMMENT -->
run: |
WIP_LABEL="status: work-in-progress"
INVALID_LABEL="INVALID-TITLE-DO-NOT-MERGE"
WIP_REGEX="^WIP:"
FORMAT_REGEX="^EC-[0-9]+: (FEAT|FIX|DOCS|REFACTOR|STYLE|PERF|TEST|CHORE): .+$"
ISSUES_API_URL="$API_BASE_URL/repos/$REPO/issues/$PR_NUMBER"
if [ -z "$PR_NUMBER" ]; then
echo "::error::Could not determine PR Number. Aborting."
exit 1
fi
if [[ "$PR_TITLE" =~ $WIP_REGEX ]]; then
echo " PR is marked as a Work in Progress."
LABEL_JSON=$(echo "$WIP_LABEL" | jq -R '{"labels": [.]}')
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$LABEL_JSON" "$ISSUES_API_URL/labels"
WIP_COMMENT_IDENTIFIER="<!-- WIP_VALIDATOR_COMMENT -->"
EXISTING_COMMENTS=$(curl -s -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/comments")
if ! echo "$EXISTING_COMMENTS" | grep -q "$WIP_COMMENT_IDENTIFIER"; then
echo "Posting WIP comment."
COMMENT_JSON=$(jq -n --arg body "$COMMENT_BODY_WIP" '{"body": $body}')
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$COMMENT_JSON" "$ISSUES_API_URL/comments"
fi
exit 1
elif [[ "$PR_TITLE" =~ $FORMAT_REGEX ]]; then
echo "✅ PR title format is correct and not a WIP."
echo "Checking for labels to remove..."
CURRENT_LABELS_JSON=$(curl -s -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/labels")
INVALID_LABEL_ID=$(echo "$CURRENT_LABELS_JSON" | jq --arg name "$INVALID_LABEL" '.[] | select(.name == $name) | .id')
if [ -n "$INVALID_LABEL_ID" ]; then
echo "Found and removing '$INVALID_LABEL' (ID: $INVALID_LABEL_ID)..."
curl -s -f -X DELETE -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/labels/$INVALID_LABEL_ID"
fi
WIP_LABEL_ID=$(echo "$CURRENT_LABELS_JSON" | jq --arg name "$WIP_LABEL" '.[] | select(.name == $name) | .id')
if [ -n "$WIP_LABEL_ID" ]; then
echo "Found and removing '$WIP_LABEL' (ID: $WIP_LABEL_ID)..."
curl -s -f -X DELETE -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/labels/$WIP_LABEL_ID"
fi
exit 0
else
echo "❌ ERROR: PR title does not match the required format."
echo "Adding '$INVALID_LABEL' label..."
LABEL_JSON=$(echo "$INVALID_LABEL" | jq -R '{"labels": [.]}')
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$LABEL_JSON" "$ISSUES_API_URL/labels"
# Remove WIP label just in case
ENCODED_WIP_LABEL=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$WIP_LABEL'))")
curl -s -X DELETE -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/labels/$ENCODED_WIP_LABEL" || true
INVALID_COMMENT_IDENTIFIER="<!-- PR_TITLE_VALIDATOR_COMMENT -->"
EXISTING_COMMENTS=$(curl -s -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/comments")
if ! echo "$EXISTING_COMMENTS" | grep -q "$INVALID_COMMENT_IDENTIFIER"; then
echo "Posting invalid title comment."
COMMENT_JSON=$(jq -n --arg body "$COMMENT_BODY_INVALID" '{"body": $body}')
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$COMMENT_JSON" "$ISSUES_API_URL/comments"
fi
exit 1
fi