This commit is contained in:
2025-12-08 18:27:04 +01:00
parent 61ffd2da74
commit 2e14a2f601
2 changed files with 141 additions and 154 deletions

View File

@@ -19,18 +19,12 @@ jobs:
REPO_OWNER: ${{ github.repository_owner }}
REPO_NAME: ${{ github.event.repository.name }}
PR_NUMBER: ${{ github.event.pull_request.number }}
OLLAMA_URL: "http://host.docker.internal:11434/api/generate"
OLLAMA_MODEL: "gemma3"
OLLAMA_URL: 'http://host.docker.internal:11434/api/generate'
OLLAMA_MODEL: 'gemma3'
run: |-
echo "🫖 DarkTeaOps awakens…"
node <<'EOF'
require("child_process").spawn("node", [".gitea/workflows/reviewer.js"], {
stdio: "inherit"
}).on("exit", code => {
if (code !== 0) {
console.error("💀 DarkTeaOps encountered turbulence and plunged deeper into the brew!");
process.exit(code);
}
});
EOF
node .gitea/workflows/reviewer.js
if [ $? -ne 0 ]; then
echo "💀 DarkTeaOps encountered turbulence and plunged deeper into the brew!"
exit 1
fi

View File

@@ -3,6 +3,9 @@
// Bound in the steeping shadows of this repository.
// ────────────────────────────────────────────────────────────
import http from 'http';
import https from 'https';
const config = {
token: process.env.GITEA_TOKEN,
apiUrl: process.env.GITEA_API_URL,
@@ -10,16 +13,16 @@ const config = {
repo: process.env.REPO_NAME,
pr: process.env.PR_NUMBER,
ollamaUrl: process.env.OLLAMA_URL,
model: process.env.OLLAMA_MODEL,
model: process.env.OLLAMA_MODEL
};
// ────────────────────────────────────────────────────────────
// DARKTEAOPS ERROR SYSTEM
// ────────────────────────────────────────────────────────────
function darkTeaOpsError(depth, message, details = "") {
function darkTeaOpsError(depth, message, details = '') {
const code = `BREW-DEPTH-${depth}`;
const header = `\n🜏 DARKTEAOPS ERROR: ${code}\n`;
const body = `${message}\n${details ? `\n> ${details}\n` : ""}`;
const body = `${message}\n${details ? `\n> ${details}\n` : ''}`;
console.error(header + body);
return new Error(`${code}: ${message}`);
}
@@ -29,21 +32,17 @@ function darkTeaOpsError(depth, message, details = "") {
// ────────────────────────────────────────────────────────────
function makeRequest(url, options, data = null) {
return new Promise((resolve, reject) => {
const lib = url.startsWith("https") ? require("https") : require("http");
const lib = url.startsWith('https') ? https : http;
const req = lib.request(url, options, (res) => {
let body = "";
res.on("data", (chunk) => (body += chunk));
res.on("end", () => resolve({ statusCode: res.statusCode, body }));
let body = '';
res.on('data', (chunk) => (body += chunk));
res.on('end', () => resolve({ statusCode: res.statusCode, body }));
});
req.on("error", (err) => {
req.on('error', (err) => {
reject(
darkTeaOpsError(
9,
"The network tunnels collapsed during the invocation.",
err.message,
),
darkTeaOpsError(9, 'The network tunnels collapsed during the invocation.', err.message)
);
});
@@ -61,19 +60,19 @@ async function fetchPRDiff() {
const res = await makeRequest(
`${config.apiUrl}/repos/${config.owner}/${config.repo}/pulls/${config.pr}.diff`,
{
method: "GET",
method: 'GET',
headers: {
Authorization: `token ${config.token}`,
Accept: "application/json",
},
},
Accept: 'application/json'
}
}
);
if (res.statusCode !== 200) {
throw darkTeaOpsError(
3,
"The diff could not be fetched. The vapors resisted.",
`Upstream responded with status ${res.statusCode}.`,
'The diff could not be fetched. The vapors resisted.',
`Upstream responded with status ${res.statusCode}.`
);
}
@@ -86,10 +85,8 @@ async function fetchPRDiff() {
function truncateDiff(diff, maxLength = 12000) {
if (!diff) return null;
if (diff.length > maxLength) {
console.warn(
"🫖 The brew thickens beyond mortal comprehension. Truncating diff.",
);
return diff.substring(0, maxLength) + "\n...(truncated)";
console.warn('🫖 The brew thickens beyond mortal comprehension. Truncating diff.');
return diff.substring(0, maxLength) + '\n...(truncated)';
}
return diff;
}
@@ -134,17 +131,17 @@ End of diff transmission.`;
const res = await makeRequest(
config.ollamaUrl,
{
method: "POST",
headers: { "Content-Type": "application/json" },
method: 'POST',
headers: { 'Content-Type': 'application/json' }
},
JSON.stringify({ model: config.model, prompt, stream: false }),
JSON.stringify({ model: config.model, prompt, stream: false })
);
if (res.statusCode !== 200) {
throw darkTeaOpsError(
7,
"Ollama broke the ritual circle and returned malformed essence.",
`Raw response: ${res.body}`,
'Ollama broke the ritual circle and returned malformed essence.',
`Raw response: ${res.body}`
);
}
@@ -152,27 +149,23 @@ End of diff transmission.`;
try {
parsed = JSON.parse(res.body).response;
} catch (e) {
throw darkTeaOpsError(
7,
"Ollama responded with a void where JSON should reside.",
e.message,
);
throw darkTeaOpsError(7, 'Ollama responded with a void where JSON should reside.', e.message);
}
const lines = parsed.trim().split("\n");
const lines = parsed.trim().split('\n');
let title = lines[0].trim();
const summary = lines.slice(2).join("\n").trim();
const summary = lines.slice(2).join('\n').trim();
// Random cursed override
if (Math.random() < 0.05) {
const cursedTitles = [
"Stitched Together With Thoughts I Regret",
"This PR Was Not Reviewed. It Was Summoned.",
"Improves the Code. Angers the Kettle.",
"I Saw What You Did in That For Loop.",
'Stitched Together With Thoughts I Regret',
'This PR Was Not Reviewed. It Was Summoned.',
'Improves the Code. Angers the Kettle.',
'I Saw What You Did in That For Loop.'
];
title = cursedTitles[Math.floor(Math.random() * cursedTitles.length)];
console.warn("💀 DarkTeaOps meddles: the PR title is now cursed.");
console.warn('💀 DarkTeaOps meddles: the PR title is now cursed.');
}
return { title, summary };
@@ -182,7 +175,7 @@ End of diff transmission.`;
// Post Comment to Gitea
// ────────────────────────────────────────────────────────────
async function postCommentToGitea(title, summary) {
console.log("🩸 Etching review into Gitea…");
console.log('🩸 Etching review into Gitea…');
const commentBody = `## 🫖✨ DARKTEAOPS EMERGES FROM THE STEEP ✨🫖
_(kneel, developer)_
@@ -198,20 +191,20 @@ ${summary}
const res = await makeRequest(
`${config.apiUrl}/repos/${config.owner}/${config.repo}/issues/${config.pr}/comments`,
{
method: "POST",
method: 'POST',
headers: {
Authorization: `token ${config.token}`,
"Content-Type": "application/json",
'Content-Type': 'application/json'
}
},
},
JSON.stringify({ body: commentBody }),
JSON.stringify({ body: commentBody })
);
if (res.statusCode !== 201) {
throw darkTeaOpsError(
5,
"Gitea rejected the incantation. The wards remain unbroken.",
`Returned: ${res.body}`,
'Gitea rejected the incantation. The wards remain unbroken.',
`Returned: ${res.body}`
);
}
}
@@ -225,22 +218,22 @@ async function run() {
const cleanDiff = truncateDiff(diff);
if (!cleanDiff) {
console.log("🫖 No diff detected. The brew grows silent.");
console.log('🫖 No diff detected. The brew grows silent.');
return;
}
const { title, summary } = await generatePRTitleAndSummary(cleanDiff);
await postCommentToGitea(title, summary);
console.log("🜏 Ritual completed. The brew is pleased.");
console.log('🜏 Ritual completed. The brew is pleased.');
} catch (err) {
console.error(
`\n🜏 DarkTeaOps whispers from the brew:\n${err.message}\n` +
`The shadows linger in /var/log/darkness...\n`,
`The shadows linger in /var/log/darkness...\n`
);
if (Math.random() < 0.12) {
console.error("A faint voice echoes: “Deeper… deeper into the brew…”\n");
console.error('A faint voice echoes: “Deeper… deeper into the brew…”\n');
}
process.exit(1);