Files
jimmyabvandClaude Sonnet 4.6 8400f0563b Add Unity test and PR conflict-check workflows
Registers both workflows on the default branch so GitHub Actions picks
them up (a new workflow file only triggers once it exists on main).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 01:38:19 -03:00

125 lines
4.5 KiB
YAML

name: PR Conflict Check
# Detects merge conflicts between a PR branch and its base branch BEFORE the PR is
# merged (Unity .unity/.asset YAML files are especially prone to ugly conflicts).
# If the conflict check (or the workflow itself) fails, an issue is opened
# automatically so the conflict doesn't sit silently in a red PR check.
on:
pull_request:
types: [opened, synchronize, reopened]
branches: [main]
permissions:
contents: read
issues: write
concurrency:
group: pr-conflict-check-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
check-conflicts:
name: Check for merge conflicts with ${{ github.event.pull_request.base.ref }}
runs-on: ubuntu-latest
outputs:
conflicted_files: ${{ steps.merge_check.outputs.conflicted_files }}
steps:
- name: Checkout PR head
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Attempt merge with base branch
id: merge_check
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git fetch origin "${{ github.event.pull_request.base.ref }}"
if git merge --no-commit --no-ff "origin/${{ github.event.pull_request.base.ref }}"; then
echo "No conflicts. Clean merge with base branch confirmed."
git merge --abort || true
exit 0
fi
echo "::error::Merge conflict detected against ${{ github.event.pull_request.base.ref }}"
files=$(git diff --name-only --diff-filter=U)
echo "Conflicted files:"
echo "$files"
{
echo "conflicted_files<<EOF"
echo "$files"
echo "EOF"
} >> "$GITHUB_OUTPUT"
git merge --abort || true
exit 1
report-failure:
name: Open issue on failure
needs: check-conflicts
if: failure()
runs-on: ubuntu-latest
steps:
- name: Create or update tracking issue
uses: actions/github-script@v7
with:
script: |
const prNumber = context.payload.pull_request.number;
const prTitle = context.payload.pull_request.title;
const prUrl = context.payload.pull_request.html_url;
const baseRef = context.payload.pull_request.base.ref;
const headRef = context.payload.pull_request.head.ref;
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
const conflictedFiles = `${{ needs.check-conflicts.outputs.conflicted_files }}`.trim();
const title = `Merge conflict: PR #${prNumber} vs ${baseRef}`;
const fileList = conflictedFiles
? conflictedFiles.split('\n').filter(Boolean).map(f => `- \`${f}\``).join('\n')
: '_The conflict check workflow itself failed before listing files — see the run log._';
const body = [
`The **PR Conflict Check** workflow failed for [PR #${prNumber}](${prUrl}) ("${prTitle}").`,
'',
`**Branch**: \`${headRef}\` → \`${baseRef}\``,
`**Workflow run**: ${runUrl}`,
'',
'**Conflicted files:**',
fileList,
'',
'Rebase or merge the base branch into this PR branch locally and resolve the',
'conflicts above, then push again. This issue will stay open until a follow-up',
'run of the conflict check passes — close it manually once resolved.',
].join('\n');
const { data: existing } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'merge-conflict',
});
const match = existing.find(issue => issue.title === title);
if (match) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: match.number,
body: `Conflict still present as of ${runUrl}.\n\n${body}`,
});
} else {
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title,
body,
labels: ['merge-conflict', 'ci-failure'],
});
}