Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1a4958b34 |
@@ -70,94 +70,134 @@ chmod 600 "$AUTH_FILE"
|
||||
echo "Configured provider: ${PI_PROVIDER}"
|
||||
echo "::endgroup::"
|
||||
|
||||
# ─── Phase 2: Generate diff ───────────────────────────────────────────────────
|
||||
echo "::group::Generate diff"
|
||||
# ─── Phase 2: Fetch diff via API ───────────────────────────────────────────────
|
||||
echo "Generate diff"
|
||||
|
||||
# Configure git auth using the provided token, so we can fetch inside Docker.
|
||||
# actions/checkout@v5 stores credentials in $RUNNER_TEMP which isn't mounted
|
||||
# into the container, so we re-authenticate using the token input.
|
||||
if [ -n "${PI_TOKEN}" ]; then
|
||||
REMOTE_URL=$(git remote get-url origin 2>/dev/null || echo "")
|
||||
if echo "$REMOTE_URL" | grep -q '://'; then
|
||||
# HTTP(S) remote: inject token into URL
|
||||
# e.g. https://git.example.com/owner/repo.git → https://token:xxx@git.example.com/owner/repo.git
|
||||
PROTOCOL=$(echo "$REMOTE_URL" | sed -E 's|^(https?://).*|\1|')
|
||||
HOST_PATH=$(echo "$REMOTE_URL" | sed -E 's|^https?://||')
|
||||
git remote set-url origin "${PROTOCOL}token:${PI_TOKEN}@${HOST_PATH}"
|
||||
echo "Git auth configured via remote URL"
|
||||
fi
|
||||
# Git operations inside the Docker container have no auth credentials
|
||||
# (actions/checkout@v5 stores them in $RUNNER_TEMP, which isn't mounted).
|
||||
# Instead, we get the diff directly from the Gitea/GitHub API using the token
|
||||
# we already have for posting comments.
|
||||
|
||||
# Detect platform and resolve PR info
|
||||
if [ -n "${GITEA_SERVER_URL:-}" ]; then
|
||||
API_BASE="${GITEA_SERVER_URL}/api/v1"
|
||||
PR_NUMBER="${GITEA_EVENT_PULL_REQUEST_NUMBER:-}"
|
||||
REPO="${GITEA_REPOSITORY:-}"
|
||||
echo "Platform: Gitea (${GITEA_SERVER_URL})"
|
||||
else
|
||||
API_BASE="${GITHUB_API_URL:-https://api.github.com}"
|
||||
PR_NUMBER="${GITHUB_EVENT_PULL_REQUEST_NUMBER:-}"
|
||||
REPO="${GITHUB_REPOSITORY:-}"
|
||||
echo "Platform: GitHub"
|
||||
fi
|
||||
|
||||
# Now find the base branch. With auth configured, fetch should work.
|
||||
BASE=""
|
||||
echo "Repo: ${REPO}, PR: ${PR_NUMBER}"
|
||||
|
||||
# 1. Check if remote tracking refs already exist (from a pre-step)
|
||||
for candidate in origin/main origin/master; do
|
||||
if git rev-parse --verify "$candidate" >/dev/null 2>&1; then
|
||||
BASE="$candidate"
|
||||
echo "Found existing ref: ${BASE}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# 2. Try Gitea/GitHub event context for target branch name
|
||||
if [ -z "$BASE" ]; then
|
||||
TARGET_BRANCH="${GITEA_BASE_REF:-${GITHUB_BASE_REF:-}}"
|
||||
if [ -n "${TARGET_BRANCH}" ] && git rev-parse --verify "origin/${TARGET_BRANCH}" >/dev/null 2>&1; then
|
||||
BASE="origin/${TARGET_BRANCH}"
|
||||
echo "Found target branch from event: ${BASE}"
|
||||
fi
|
||||
if [ -z "$PR_NUMBER" ]; then
|
||||
echo "Not a pull request event. Skipping review."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 3. Fetch the base branch (now works with auth)
|
||||
if [ -z "$BASE" ]; then
|
||||
echo "No base ref found locally. Fetching..."
|
||||
git fetch --unshallow origin 2>/dev/null || true
|
||||
for branch in main master; do
|
||||
if git fetch origin "+refs/heads/${branch}:refs/remotes/origin/${branch}" 2>/dev/null; then
|
||||
BASE="origin/${branch}"
|
||||
echo "Fetched: ${BASE}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
# Also try the target branch from event context
|
||||
if [ -z "$BASE" ] && [ -n "${TARGET_BRANCH}" ]; then
|
||||
if git fetch origin "+refs/heads/${TARGET_BRANCH}:refs/remotes/origin/${TARGET_BRANCH}" 2>/dev/null; then
|
||||
BASE="origin/${TARGET_BRANCH}"
|
||||
echo "Fetched target: ${BASE}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
# Fetch diff via API — works regardless of git auth inside the container.
|
||||
# Gitea: GET /repos/{owner}/{repo}/pulls/{index}.diff
|
||||
# GitHub: GET /repos/{owner}/{repo}/pulls/{index} (Accept: application/diff)
|
||||
node -e "
|
||||
const http = require('http');
|
||||
const https = require('https');
|
||||
|
||||
if [ -z "$BASE" ]; then
|
||||
echo "::error::Could not determine base branch. Ensure 'token' input has repo read access."
|
||||
exit 1
|
||||
fi
|
||||
const apiBase = '${API_BASE}';
|
||||
const repo = '${REPO}';
|
||||
const prNumber = '${PR_NUMBER}';
|
||||
const token = '${PI_TOKEN}';
|
||||
const maxBytes = ${PI_MAX_DIFF:-80000};
|
||||
|
||||
echo "Base ref: ${BASE} -> $(git rev-parse --short "${BASE}" 2>/dev/null || echo 'NOT FOUND')"
|
||||
echo "HEAD: $(git rev-parse --short HEAD)"
|
||||
echo "Files changed:"
|
||||
git diff --stat "${BASE}...HEAD" 2>/dev/null | tail -3 || echo "(could not stat diff)"
|
||||
function fetchDiff() {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Try Gitea diff endpoint first
|
||||
const giteaPath = '/repos/' + repo + '/pulls/' + prNumber + '.diff';
|
||||
const githubPath = '/repos/' + repo + '/pulls/' + prNumber;
|
||||
|
||||
# Build exclude pathspecs
|
||||
EXCLUDE_ARGS=""
|
||||
for pattern in $PI_EXCLUDE; do
|
||||
EXCLUDE_ARGS="$EXCLUDE_ARGS ':!$pattern'"
|
||||
done
|
||||
const url = new URL(apiBase + giteaPath);
|
||||
const transport = url.protocol === 'http:' ? http : https;
|
||||
|
||||
eval "git diff ${BASE}...HEAD ${EXCLUDE_ARGS}" > /tmp/pi-diff.txt 2>/dev/null || true
|
||||
const options = {
|
||||
hostname: url.hostname,
|
||||
port: url.port || (url.protocol === 'http:' ? 80 : 443),
|
||||
path: url.pathname,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': 'token ' + token,
|
||||
'Accept': 'text/plain',
|
||||
},
|
||||
};
|
||||
|
||||
# Truncate if needed
|
||||
if [ "${PI_MAX_DIFF}" -gt 0 ]; then
|
||||
head -c "${PI_MAX_DIFF}" /tmp/pi-diff.txt > /tmp/pi-diff-trunc.txt
|
||||
mv /tmp/pi-diff-trunc.txt /tmp/pi-diff.txt
|
||||
fi
|
||||
const req = transport.request(options, (res) => {
|
||||
if (res.statusCode === 404 && apiBase.indexOf('github.com') !== -1) {
|
||||
// Fallback to GitHub diff format
|
||||
reject(new Error('GitHub fallback not implemented'));
|
||||
return;
|
||||
}
|
||||
if (res.statusCode < 200 || res.statusCode >= 300) {
|
||||
let body = '';
|
||||
res.on('data', (c) => { body += c; });
|
||||
res.on('end', () => { reject(new Error('API ' + res.statusCode + ': ' + body.slice(0, 200))); });
|
||||
return;
|
||||
}
|
||||
|
||||
DIFF_SIZE=$(wc -c < /tmp/pi-diff.txt || echo 0)
|
||||
echo "Diff size: ${DIFF_SIZE} bytes"
|
||||
echo "::endgroup::"
|
||||
let data = '';
|
||||
let bytes = 0;
|
||||
res.on('data', (chunk) => {
|
||||
bytes += chunk.length;
|
||||
if (maxBytes > 0 && bytes <= maxBytes) {
|
||||
data += chunk;
|
||||
}
|
||||
});
|
||||
res.on('end', () => {
|
||||
if (maxBytes > 0 && data.length >= maxBytes) {
|
||||
data = data.slice(0, maxBytes) + '\\n... (truncated at ' + maxBytes + ' bytes)';
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
req.on('error', (e) => { reject(e); });
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
if [ "${DIFF_SIZE}" -eq 0 ]; then
|
||||
fetchDiff().then((diff) => {
|
||||
const fs = require('fs');
|
||||
|
||||
// Filter out excluded patterns (lockfiles, generated code, etc.)
|
||||
const excludePatterns = '${PI_EXCLUDE}'.split(' ').filter(Boolean);
|
||||
if (excludePatterns.length > 0) {
|
||||
const lines = diff.split('\\n');
|
||||
const filtered = [];
|
||||
let skipFile = false;
|
||||
for (const line of lines) {
|
||||
if (line.startsWith('diff --git')) {
|
||||
skipFile = excludePatterns.some(p => {
|
||||
const glob = p.replace(/\\./g, '\\\\.').replace(/\\*/g, '.*');
|
||||
return new RegExp(glob).test(line);
|
||||
});
|
||||
}
|
||||
if (!skipFile) filtered.push(line);
|
||||
}
|
||||
diff = filtered.join('\\n');
|
||||
}
|
||||
|
||||
if (maxBytes > 0 && diff.length > maxBytes) {
|
||||
diff = diff.slice(0, maxBytes) + '\\n... (truncated at ' + maxBytes + ' bytes)';
|
||||
}
|
||||
|
||||
fs.writeFileSync('/tmp/pi-diff.txt', diff);
|
||||
console.log('Diff fetched: ' + diff.length + ' bytes');
|
||||
}).catch((e) => {
|
||||
console.error('Failed to fetch diff: ' + e.message);
|
||||
process.exit(1);
|
||||
});
|
||||
"
|
||||
|
||||
if [ ! -s /tmp/pi-diff.txt ]; then
|
||||
echo "No changes to review. Skipping."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user