Files
SillyTavern/.github/workflows/pr-auto-manager.yml
T
Wolfsblvt f88ba369dd Workflows: Replace ISSUES_BOT_TOKEN with GitHub App for labeling + 'against release' auto comment (#4621)
* ci: replace ISSUES_BOT_TOKEN with GitHub App authentication for PR auto-labeling workflow

* Update PR auto comments for target branch guidance

Added note about changing target branch for PRs.

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2025-10-07 16:55:15 +03:00

292 lines
10 KiB
YAML

name: 🔀 Pull Request Manager
on:
workflow_dispatch: # Allow to manually call this workflow
pull_request_target:
types: [opened, synchronize, reopened, edited, labeled, unlabeled, closed]
pull_request_review_comment:
types: [created]
permissions:
contents: read
pull-requests: write
jobs:
app-auth:
name: 🔑 Mint App token
runs-on: ubuntu-latest
if: always()
outputs:
app_token: ${{ steps.app.outputs.token }}
steps:
- name: Create GitHub App Token
# Create a GitHub App token
# https://github.com/marketplace/actions/create-github-app-token
uses: actions/create-github-app-token@v2
id: app
with:
app-id: ${{ vars.ST_BOT_APP_ID }}
private-key: ${{ secrets.ST_BOT_SECRET }}
owner: ${{ github.repository_owner }}
run-eslint:
name: ✅ Check ESLint on PR
runs-on: ubuntu-latest
# Only needs to run when code is changed
if: github.event.action == 'opened' || github.event.action == 'synchronize'
# Override permissions, linter likely needs write access to issues
permissions:
contents: read
issues: write
pull-requests: write
steps:
- name: Checkout Repository
# Checkout
# https://github.com/marketplace/actions/checkout
uses: actions/checkout@v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Setup Node.js
# Setup Node.js environment
# https://github.com/marketplace/actions/setup-node-js-environment
uses: actions/setup-node@v4.3.0
with:
node-version: 20
- name: Run npm install
run: npm ci
- name: Run ESLint
# Action ESLint
# https://github.com/marketplace/actions/action-eslint
uses: sibiraj-s/action-eslint@v3.0.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
eslint-args: '--ignore-path=.gitignore --quiet'
extensions: 'js'
annotations: true
ignore-patterns: |
dist/
lib/
label-by-size:
name: 🏷️ Label PR by Size
# This job should run after all others, to prevent possible concurrency issues
needs: [app-auth, label-by-branches, label-by-files, remove-stale-label, check-merge-blocking-labels, write-auto-comments]
runs-on: ubuntu-latest
# Only needs to run when code is changed
if: always() && (github.event.action == 'opened' || github.event.action == 'synchronize')
# Override permissions, the labeler needs issues write access
permissions:
contents: read
issues: write
pull-requests: write
steps:
- name: Label PR Size
# Pull Request Size Labeler
# https://github.com/marketplace/actions/pull-request-size-labeler
uses: codelytv/pr-size-labeler@v1.10.2
with:
GITHUB_TOKEN: ${{ needs.app-auth.outputs.app_token }}
xs_label: '🟩 ⬤○○○○'
xs_max_size: '20'
s_label: '🟩 ⬤⬤○○○'
s_max_size: '100'
m_label: '🟨 ⬤⬤⬤○○'
m_max_size: '500'
l_label: '🟧 ⬤⬤⬤⬤○'
l_max_size: '1000'
xl_label: '🟥 ⬤⬤⬤⬤⬤'
fail_if_xl: 'false'
files_to_ignore: |
"package-lock.json"
"public/lib/*"
label-by-branches:
name: 🏷️ Label PR by Branches
needs: [app-auth]
runs-on: ubuntu-latest
# Only label once when PR is created or when base branch is changed, to allow manual label removal
if: github.event.action == 'opened' || (github.event.action == 'synchronize' && github.event.changes.base)
steps:
- name: Checkout Repository
# Checkout
# https://github.com/marketplace/actions/checkout
uses: actions/checkout@v4.2.2
- name: Apply Labels Based on Branch Name and Target Branch
# Pull Request Labeler
# https://github.com/marketplace/actions/labeler
uses: actions/labeler@v5.0.0
with:
configuration-path: .github/pr-auto-labels-by-branch.yml
repo-token: ${{ needs.app-auth.outputs.app_token }}
label-by-files:
name: 🏷️ Label PR by Files
needs: [app-auth]
runs-on: ubuntu-latest
# Only needs to run when code is changed
if: github.event.action == 'opened' || github.event.action == 'synchronize'
steps:
- name: Checkout Repository
# Checkout
# https://github.com/marketplace/actions/checkout
uses: actions/checkout@v4.2.2
- name: Apply Labels Based on Changed Files
# Pull Request Labeler
# https://github.com/marketplace/actions/labeler
uses: actions/labeler@v5.0.0
with:
configuration-path: .github/pr-auto-labels-by-files.yml
repo-token: ${{ needs.app-auth.outputs.app_token }}
remove-stale-label:
name: 🗑️ Remove Stale Label on Comment
runs-on: ubuntu-latest
# Only runs on comments not done by the github actions bot
if: github.event_name == 'pull_request_review_comment' && github.actor != 'github-actions[bot]'
# Override permissions, issue labeler needs issues write access
permissions:
contents: read
issues: write
pull-requests: write
steps:
- name: Remove Stale Label
# 🤖 Issues Helper
# https://github.com/marketplace/actions/issues-helper
uses: actions-cool/issues-helper@v3.6.0
with:
actions: 'remove-labels'
token: ${{ secrets.ISSUES_BOT_TOKEN }}
issue-number: ${{ github.event.pull_request.number }}
labels: '⚰️ Stale'
check-merge-blocking-labels:
name: 🚫 Check Merge Blocking Labels
needs: [label-by-branches, label-by-files]
runs-on: ubuntu-latest
# Run, even if the previous jobs were skipped/failed
if: always()
# Override permissions, as this needs to write a check
permissions:
checks: write
contents: read
pull-requests: read
steps:
- name: Check Merge Blocking
# GitHub Script
# https://github.com/marketplace/actions/github-script
id: label-check
uses: actions/github-script@v7.0.1
with:
script: |
const prLabels = context.payload.pull_request.labels.map(label => label.name);
const blockingLabels = [
"⛔ Don't Merge",
"🔨 Needs Work",
"🔬 Needs Testing",
"⛔ Waiting For External/Upstream",
"❗ Against Release Branch",
"💥💣 Breaking Changes"
];
const hasBlockingLabel = prLabels.some(label => blockingLabels.includes(label));
if (hasBlockingLabel) {
console.log("Blocking label detected. Setting warning status.");
await github.rest.checks.create({
owner: context.repo.owner,
repo: context.repo.repo,
name: "PR Label Warning",
head_sha: context.payload.pull_request.head.sha,
status: "completed",
conclusion: "neutral",
output: {
title: "Potential Merge Issue",
summary: "This PR has a merge-blocking label. Proceed with caution."
}
});
} else {
console.log("No merge-blocking labels found.");
}
write-auto-comments:
name: 💬 Post PR Comments Based on Labels
needs: [label-by-branches, label-by-files]
runs-on: ubuntu-latest
# Run, even if the previous jobs were skipped/failed
if: always()
steps:
- name: Checkout Repository
# Checkout
# https://github.com/marketplace/actions/checkout
uses: actions/checkout@v4.2.2
- name: Post PR Comments Based on Labels
# Label Commenter for PRs
# https://github.com/marketplace/actions/label-commenter
uses: peaceiris/actions-label-commenter@v1.10.0
with:
config_file: .github/pr-auto-comments.yml
github_token: ${{ secrets.GITHUB_TOKEN }}
# This runs on merged PRs to staging, reading the PR body and directly linked issues. Check `issues-updates-on-merge.yml`:`update-linked-issues` for commit-based updates.
update-linked-issues:
name: 🔗 Mark Linked Issues Done on Staging Merge
runs-on: ubuntu-latest
if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'staging'
# Override permissions, We need to be able to write to issues
permissions:
contents: read
issues: write
pull-requests: write
steps:
- name: Extract Linked Issues From PR Description
id: extract_issues
run: |
ISSUES=$(jq -r '.pull_request.body' "$GITHUB_EVENT_PATH" | grep -oiE '(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved) #([0-9]+)' | awk '{print $2}' | tr -d '#' | jq -R -s -c 'split("\n")[:-1]')
echo "issues=$ISSUES" >> $GITHUB_ENV
- name: Fetch Directly Linked Issues
id: fetch_linked_issues
run: |
PR_NUMBER=${{ github.event.pull_request.number }}
REPO=${{ github.repository }}
API_URL="https://api.github.com/repos/$REPO/pulls/$PR_NUMBER/issues"
ISSUES=$(curl -s -H "Authorization: token ${{ secrets.ISSUES_BOT_TOKEN }}" "$API_URL" | jq -r '.[].number' | jq -R -s -c 'split("\n")[:-1]')
echo "linked_issues=$ISSUES" >> $GITHUB_ENV
- name: Merge Issue Lists
id: merge_issues
run: |
ISSUES=$(jq -c -n --argjson a "$issues" --argjson b "$linked_issues" '$a + $b | unique')
echo "final_issues=$ISSUES" >> $GITHUB_ENV
- name: Label Linked Issues
id: label_linked_issues
env:
GH_TOKEN: ${{ secrets.ISSUES_BOT_TOKEN }}
run: |
for ISSUE in $(echo $final_issues | jq -r '.[]'); do
gh issue edit $ISSUE -R ${{ github.repository }} --add-label "✅ Done (staging)" --remove-label "🧑‍💻 In Progress"
echo "Added label '✅ Done (staging)' (and removed '🧑‍💻 In Progress' if present) in issue #$ISSUE"
done