chore(qa): restore reusable workflow with Gitea compatibility fixes
Some checks failed
🚀 Build & Deploy / 🔍 Prepare (push) Successful in 8s
Nightly QA / call-qa-workflow (push) Failing after 1m34s
🚀 Build & Deploy / 🧪 QA (push) Has been cancelled
🚀 Build & Deploy / 🚀 Deploy (push) Has been cancelled
🚀 Build & Deploy / 🏗️ Build (push) Has been cancelled
🚀 Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
🚀 Build & Deploy / 🔔 Notify (push) Has been cancelled

This commit is contained in:
2026-04-25 19:13:49 +02:00
parent 5ffd78d60f
commit 73cb55ee8d
6 changed files with 241 additions and 334 deletions

View File

@@ -1,45 +1,49 @@
import axios from 'axios';
import * as cheerio from 'cheerio';
import * as fs from 'fs';
import * as path from 'path';
import { execSync } from 'child_process';
import axios from "axios";
import * as cheerio from "cheerio";
import * as fs from "fs";
import * as path from "path";
import { execSync } from "child_process";
const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000';
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'mbgrid';
const targetUrl =
process.argv[2] ||
process.env.NEXT_PUBLIC_BASE_URL ||
"http://localhost:3000";
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || "mbgrid";
async function main() {
console.log(`\n🚀 Starting HTML Validation for: ${targetUrl}`);
console.log(`📊 Limit: None (Full Sitemap)\n`);
try {
const sitemapUrl = `${targetUrl.replace(/\/$/, '')}/sitemap.xml`;
const sitemapUrl = `${targetUrl.replace(/\/$/, "")}/sitemap.xml`;
console.log(`📥 Fetching sitemap from ${sitemapUrl}...`);
const response = await axios.get(sitemapUrl, {
headers: { Cookie: `mb_gatekeeper_session=${gatekeeperPassword}` },
headers: { Cookie: `mintel_gatekeeper_session=${gatekeeperPassword}` },
validateStatus: (status) => status < 400,
});
const $ = cheerio.load(response.data, { xmlMode: true });
let urls = $('url loc')
let urls = $("url loc")
.map((i, el) => $(el).text())
.get();
const urlPattern = /https?:\/\/[^\/]+/;
urls = [...new Set(urls)]
.filter((u) => u.startsWith('http'))
.map((u) => u.replace(urlPattern, targetUrl.replace(/\/$/, '')))
.filter((u) => u.startsWith("http"))
.map((u) => u.replace(urlPattern, targetUrl.replace(/\/$/, "")))
.sort();
console.log(`✅ Found ${urls.length} URLs in sitemap.`);
if (urls.length === 0) {
console.error('❌ No URLs found in sitemap. Is the site up?');
console.error("❌ No URLs found in sitemap. Is the site up?");
process.exit(1);
}
const outputDir = path.join(process.cwd(), '.htmlvalidate-tmp');
if (fs.existsSync(outputDir)) fs.rmSync(outputDir, { recursive: true, force: true });
const outputDir = path.join(process.cwd(), ".htmlvalidate-tmp");
if (fs.existsSync(outputDir))
fs.rmSync(outputDir, { recursive: true, force: true });
fs.mkdirSync(outputDir, { recursive: true });
console.log(`📥 Fetching HTML for ${urls.length} pages...`);
@@ -47,14 +51,19 @@ async function main() {
const u = urls[i];
try {
const res = await axios.get(u, {
headers: { Cookie: `mb_gatekeeper_session=${gatekeeperPassword}` },
headers: {
Cookie: `mintel_gatekeeper_session=${gatekeeperPassword}`,
},
validateStatus: (status) => status < 400,
});
// Generate a safe filename that retains URL information
const urlStr = new URL(u);
const safePath = (urlStr.pathname + urlStr.search).replace(/[^a-zA-Z0-9]/g, '_');
const filename = `${safePath || 'index'}.html`;
const safePath = (urlStr.pathname + urlStr.search).replace(
/[^a-zA-Z0-9]/g,
"_",
);
const filename = `${safePath || "index"}.html`;
fs.writeFileSync(path.join(outputDir, filename), res.data);
} catch (err: unknown) {
@@ -66,7 +75,9 @@ async function main() {
console.log(`\n💻 Executing html-validate...`);
try {
execSync(`npx html-validate .htmlvalidate-tmp/*.html`, { stdio: 'inherit' });
execSync(`npx html-validate .htmlvalidate-tmp/*.html`, {
stdio: "inherit",
});
console.log(`✅ HTML Validation passed perfectly!`);
} catch {
console.error(`❌ HTML Validation found issues.`);
@@ -77,8 +88,9 @@ async function main() {
console.error(`\n❌ Error during HTML Validation:`, errorBody);
process.exit(1);
} finally {
const outputDir = path.join(process.cwd(), '.htmlvalidate-tmp');
if (fs.existsSync(outputDir)) fs.rmSync(outputDir, { recursive: true, force: true });
const outputDir = path.join(process.cwd(), ".htmlvalidate-tmp");
if (fs.existsSync(outputDir))
fs.rmSync(outputDir, { recursive: true, force: true });
}
}