Files
actions/.github/workflows/auto-rebase.yml

184 lines
6.3 KiB
YAML

---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Auto Rebase
on:
push:
branches:
- main
- master
pull_request_target:
types:
- labeled
issue_comment:
types:
- created
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
auto-rebase:
name: 🔄 Auto Rebase
if: |
(github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
contains(github.event.comment.body, '/rebase')) ||
(github.event_name == 'pull_request_target' &&
contains(github.event.pull_request.labels.*.name, 'auto-rebase')) ||
github.event_name == 'push'
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: write
pull-requests: write
issues: write
steps:
- name: Check Required Secrets
id: check-secrets
run: |
if [ -z "${{ secrets.APP_ID }}" ] || [ -z "${{ secrets.APP_PRIVATE_KEY }}" ]; then
echo "::warning::GitHub App credentials not configured. Using GITHUB_TOKEN instead."
echo "use_github_token=true" >> "$GITHUB_OUTPUT"
if [ "${{ github.event_name }}" == "push" ]; then
echo "::warning::Running with GITHUB_TOKEN on push events may have limited functionality."
fi
else
echo "use_github_token=false" >> "$GITHUB_OUTPUT"
fi
- name: Generate Token
id: generate-token
if: steps.check-secrets.outputs.use_github_token == 'false'
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Add Initial Comment
uses: actions/github-script@v7
with:
github-token: ${{ steps.check-secrets.outputs.use_github_token == 'true' && github.token || steps.generate-token.outputs.token }}
script: |
const { repo, owner } = context.repo;
// Get PR number based on event type
let prNumber;
if (context.eventName === 'issue_comment') {
prNumber = context.payload.issue.number;
} else if (context.eventName === 'pull_request_target') {
prNumber = context.payload.pull_request.number;
}
if (prNumber) {
const token_type = '${{ steps.check-secrets.outputs.use_github_token }}' === 'true'
? 'GITHUB_TOKEN (limited permissions)'
: 'GitHub App token';
await github.rest.issues.createComment({
owner,
repo,
issue_number: prNumber,
body: `🔄 Attempting rebase using ${token_type}...`
});
}
- name: Checkout Repository
uses: actions/checkout@v4
with:
token: ${{ steps.check-secrets.outputs.use_github_token == 'true' && github.token || steps.generate-token.outputs.token }}
fetch-depth: 0
- name: Auto Rebase
id: rebase
continue-on-error: true
uses: cirrus-actions/rebase@1.8
env:
GITHUB_TOKEN: ${{ steps.check-secrets.outputs.use_github_token == 'true' && github.token || steps.generate-token.outputs.token }}
- name: Handle Rebase Result
uses: actions/github-script@v7
with:
github-token: ${{ steps.check-secrets.outputs.use_github_token == 'true' && github.token || steps.generate-token.outputs.token }}
script: |
const { repo, owner } = context.repo;
// Get PR number based on event type
let prNumber;
if (context.eventName === 'issue_comment') {
prNumber = context.payload.issue.number;
} else if (context.eventName === 'pull_request_target') {
prNumber = context.payload.pull_request.number;
}
if (prNumber) {
const rebaseSuccess = '${{ steps.rebase.outcome }}' === 'success';
const usingGithubToken = '${{ steps.check-secrets.outputs.use_github_token }}' === 'true';
let commentBody;
if (rebaseSuccess) {
commentBody = '✅ Rebase completed successfully!';
} else {
commentBody = '❌ Rebase failed.\n\n';
if (usingGithubToken) {
commentBody += '⚠️ Note: This workflow is running with reduced permissions (GITHUB_TOKEN).\n' +
'For better functionality, configure APP_ID and APP_PRIVATE_KEY secrets.\n\n';
}
commentBody += 'Please try to:\n' +
'1. Resolve any conflicts manually\n' +
'2. Ensure branch is not protected\n' +
'3. Verify you have proper permissions';
}
// Add result comment
await github.rest.issues.createComment({
owner,
repo,
issue_number: prNumber,
body: commentBody
});
// Handle labels
try {
// Remove auto-rebase label if it exists
await github.rest.issues.removeLabel({
owner,
repo,
issue_number: prNumber,
name: 'auto-rebase'
}).catch(e => console.log('auto-rebase label not found'));
// Add appropriate result label
const resultLabel = rebaseSuccess ? 'rebase-succeeded' : 'rebase-failed';
await github.rest.issues.addLabels({
owner,
repo,
issue_number: prNumber,
labels: [resultLabel]
});
} catch (error) {
console.log('Error handling labels:', error);
}
}
// Set action status based on rebase result
if ('${{ steps.rebase.outcome }}' !== 'success') {
core.setFailed('Rebase failed');
}
- name: Cleanup
if: always()
run: |
# Reset any pending changes
git reset --hard
git checkout main
# Clean up any temporary branches
git fetch --prune