Some checks failed
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Failing after 31s
CD Pipeline / build-and-deploy (push) Has been skipped
CD Pipeline / post-deploy-checks (push) Has been skipped
93 lines
3.0 KiB
JavaScript
Executable File
93 lines
3.0 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
/*
|
|
* Guard against putting secrets directly in executable Gitea workflow text.
|
|
* Gitea/act_runner renders `run:` scripts before masking is effective, so
|
|
* `${{ secrets.* }}` must stay out of shell bodies and action `with:` inputs.
|
|
* Narrow step `env:` is the least-bad transport here because the printed shell
|
|
* body can reference only variable names.
|
|
*/
|
|
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
const root = path.resolve(__dirname, "../..");
|
|
const workflowDir = path.join(root, ".gitea", "workflows");
|
|
const violations = [];
|
|
const routeViolations = [];
|
|
const secretExprPattern = /\$\{\{\s*secrets\./;
|
|
|
|
for (const fileName of fs.readdirSync(workflowDir).sort()) {
|
|
if (!fileName.endsWith(".yml") && !fileName.endsWith(".yaml")) {
|
|
continue;
|
|
}
|
|
|
|
const filePath = path.join(workflowDir, fileName);
|
|
const content = fs.readFileSync(filePath, "utf8");
|
|
const lines = content.split(/\r?\n/);
|
|
let block = null;
|
|
|
|
if (content.includes("TELEGRAM_ALERT_CHAT_ID")) {
|
|
routeViolations.push(`${filePath}: legacy TELEGRAM_ALERT_CHAT_ID is not allowed; use SRE_GROUP_CHAT_ID`);
|
|
}
|
|
|
|
if (content.includes("TELEGRAM_CHAT_ID")) {
|
|
routeViolations.push(`${filePath}: legacy TELEGRAM_CHAT_ID is not allowed for alert routing; use SRE_GROUP_CHAT_ID`);
|
|
}
|
|
|
|
let lineOffset = 0;
|
|
lines.forEach((line, index) => {
|
|
if (
|
|
line.includes("api.telegram.org/bot")
|
|
&& !content.slice(Math.max(0, lineOffset - 700), lineOffset + line.length + 1200).includes("SRE_GROUP_CHAT_ID")
|
|
) {
|
|
routeViolations.push(`${filePath}:${index + 1}: direct Telegram fallback must target SRE_GROUP_CHAT_ID`);
|
|
}
|
|
lineOffset += line.length + 1;
|
|
});
|
|
|
|
lines.forEach((line, index) => {
|
|
const indent = line.match(/^\s*/)[0].length;
|
|
const trimmed = line.trim();
|
|
|
|
if (block && trimmed && indent <= block.indent) {
|
|
block = null;
|
|
}
|
|
|
|
if ((trimmed.startsWith("run:") || trimmed.startsWith("with:")) && secretExprPattern.test(line)) {
|
|
const inlineSection = trimmed.startsWith("with:") ? "with" : "run";
|
|
violations.push(`${filePath}:${index + 1}:${inlineSection}`);
|
|
}
|
|
|
|
const blockMatch = line.match(/^(\s*)(env|with|run):\s*(?:[>|].*)?$/);
|
|
if (blockMatch) {
|
|
block = {
|
|
indent: blockMatch[1].length,
|
|
section: blockMatch[2],
|
|
};
|
|
return;
|
|
}
|
|
|
|
if (block && block.section !== "env" && secretExprPattern.test(line)) {
|
|
violations.push(`${filePath}:${index + 1}:${block.section}`);
|
|
}
|
|
});
|
|
}
|
|
|
|
if (violations.length > 0) {
|
|
console.error("Gitea workflow exposes secrets through run/with text:");
|
|
for (const violation of violations) {
|
|
console.error(` - ${violation}`);
|
|
}
|
|
process.exit(1);
|
|
}
|
|
|
|
if (routeViolations.length > 0) {
|
|
console.error("Gitea workflow Telegram route must converge on AwoooI SRE war room:");
|
|
for (const violation of routeViolations) {
|
|
console.error(` - ${violation}`);
|
|
}
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log("no Gitea run/with secrets or legacy Telegram routes");
|