fix(ci): prioritize PPA chromium over snap wrapper and pass explicit chrome path to lhci
Some checks failed
Build & Deploy KLZ Cables / 🔍 Prepare Environment (push) Successful in 21s
Build & Deploy KLZ Cables / 🧪 Quality Assurance (push) Successful in 1m30s
Build & Deploy KLZ Cables / 🏗️ Build & Push (push) Successful in 2m52s
Build & Deploy KLZ Cables / 🚀 Deploy (push) Successful in 40s
Build & Deploy KLZ Cables / ⚡ PageSpeed (push) Failing after 1m6s
Build & Deploy KLZ Cables / 🔔 Notifications (push) Successful in 2s
Some checks failed
Build & Deploy KLZ Cables / 🔍 Prepare Environment (push) Successful in 21s
Build & Deploy KLZ Cables / 🧪 Quality Assurance (push) Successful in 1m30s
Build & Deploy KLZ Cables / 🏗️ Build & Push (push) Successful in 2m52s
Build & Deploy KLZ Cables / 🚀 Deploy (push) Successful in 40s
Build & Deploy KLZ Cables / ⚡ PageSpeed (push) Failing after 1m6s
Build & Deploy KLZ Cables / 🔔 Notifications (push) Successful in 2s
This commit is contained in:
@@ -358,29 +358,28 @@ jobs:
|
|||||||
echo "🎯 Debian detected - installing native chromium"
|
echo "🎯 Debian detected - installing native chromium"
|
||||||
apt-get install -y chromium
|
apt-get install -y chromium
|
||||||
else
|
else
|
||||||
echo "🎯 Ubuntu detected - adding xtradeb PPA for native chromium (non-snap)"
|
echo "🎯 Ubuntu detected - adding xtradeb PPA"
|
||||||
mkdir -p /etc/apt/keyrings
|
mkdir -p /etc/apt/keyrings
|
||||||
# Robust key fetch with retries and fallback servers
|
|
||||||
for server in "hkp://keyserver.ubuntu.com:80" "hkp://keyserver.ubuntu.com:11371"; do
|
|
||||||
echo "Trying keyserver: $server"
|
|
||||||
if gpg --homedir /tmp --no-default-keyring --keyring /tmp/xtradeb-temp.gpg --keyserver "$server" --recv-keys 290D73D2240900B5; then
|
|
||||||
gpg --homedir /tmp --no-default-keyring --keyring /tmp/xtradeb-temp.gpg --export > /etc/apt/keyrings/xtradeb.gpg
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -f /etc/apt/keyrings/xtradeb.gpg ]; then
|
# Use direct HTTPS fetch for GPG key (most reliable in Docker)
|
||||||
echo "deb [signed-by=/etc/apt/keyrings/xtradeb.gpg] http://ppa.launchpad.net/xtradeb/apps/ubuntu $CODENAME main" > /etc/apt/sources.list.d/xtradeb-ppa.list
|
wget -qO- "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x290d73d2240900b5" | gpg --dearmor > /etc/apt/keyrings/xtradeb.gpg || true
|
||||||
apt-get update
|
|
||||||
apt-get install -y chromium || apt-get install -y chromium-browser
|
echo "deb [signed-by=/etc/apt/keyrings/xtradeb.gpg] http://ppa.launchpad.net/xtradeb/apps/ubuntu $CODENAME main" > /etc/apt/sources.list.d/xtradeb-ppa.list
|
||||||
else
|
|
||||||
echo "⚠️ Could not fetch GPG key, trying fallback install..."
|
# PRIORITY PINNING: Force Apt to use the PPA version over the Snap-filler
|
||||||
apt-get install -y chromium || apt-get install -y chromium-browser
|
printf "Package: *\nPin: release o=LP-PPA-xtradeb-apps\nPin-Priority: 1001\n" > /etc/apt/preferences.d/xtradeb
|
||||||
fi
|
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y --allow-downgrades chromium || apt-get install -y chromium-browser
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ensure consistent paths for Lighthouse
|
# Force clean paths (remove existing dead links/files if they are snap wrappers)
|
||||||
[ -f /usr/bin/chromium ] && ln -sf /usr/bin/chromium /usr/bin/chromium-browser || true
|
rm -f /usr/bin/google-chrome /usr/bin/chromium-browser
|
||||||
|
[ -f /usr/bin/chromium ] && ln -sf /usr/bin/chromium /usr/bin/google-chrome
|
||||||
|
[ -f /usr/bin/chromium ] && ln -sf /usr/bin/chromium /usr/bin/chromium-browser
|
||||||
|
|
||||||
|
echo "✅ Binary check:"
|
||||||
|
ls -l /usr/bin/chromium* /usr/bin/google-chrome || true
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: 🧪 Run PageSpeed (Lighthouse)
|
- name: 🧪 Run PageSpeed (Lighthouse)
|
||||||
|
|||||||
@@ -12,104 +12,110 @@ import * as path from 'path';
|
|||||||
* 3. Runs Lighthouse CI on those URLs
|
* 3. Runs Lighthouse CI on those URLs
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'https://testing.klz-cables.com';
|
const targetUrl =
|
||||||
|
process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'https://testing.klz-cables.com';
|
||||||
const limit = process.env.PAGESPEED_LIMIT ? parseInt(process.env.PAGESPEED_LIMIT) : 20; // Default limit to avoid infinite runs
|
const limit = process.env.PAGESPEED_LIMIT ? parseInt(process.env.PAGESPEED_LIMIT) : 20; // Default limit to avoid infinite runs
|
||||||
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026';
|
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026';
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
console.log(`\n🚀 Starting PageSpeed test for: ${targetUrl}`);
|
console.log(`\n🚀 Starting PageSpeed test for: ${targetUrl}`);
|
||||||
console.log(`📊 Limit: ${limit} pages\n`);
|
console.log(`📊 Limit: ${limit} pages\n`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. Fetch Sitemap
|
||||||
|
const sitemapUrl = `${targetUrl.replace(/\/$/, '')}/sitemap.xml`;
|
||||||
|
console.log(`📥 Fetching sitemap from ${sitemapUrl}...`);
|
||||||
|
|
||||||
|
// We might need to bypass gatekeeper for the sitemap fetch too
|
||||||
|
const response = await axios.get(sitemapUrl, {
|
||||||
|
headers: {
|
||||||
|
Cookie: `klz_gatekeeper_session=${gatekeeperPassword}`,
|
||||||
|
},
|
||||||
|
validateStatus: (status) => status < 400,
|
||||||
|
});
|
||||||
|
|
||||||
|
const $ = cheerio.load(response.data, { xmlMode: true });
|
||||||
|
let urls = $('url loc')
|
||||||
|
.map((i, el) => $(el).text())
|
||||||
|
.get();
|
||||||
|
|
||||||
|
// Cleanup and filter
|
||||||
|
urls = [...new Set(urls)].filter((u) => u.startsWith('http')).sort();
|
||||||
|
|
||||||
|
console.log(`✅ Found ${urls.length} URLs in sitemap.`);
|
||||||
|
|
||||||
|
if (urls.length === 0) {
|
||||||
|
console.error('❌ No URLs found in sitemap. Is the site up?');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (urls.length > limit) {
|
||||||
|
console.log(
|
||||||
|
`⚠️ Too many pages (${urls.length}). Limiting to ${limit} representative pages.`,
|
||||||
|
);
|
||||||
|
// Try to pick a variety: home, some products, some blog posts
|
||||||
|
const home = urls.filter((u) => u.endsWith('/de') || u.endsWith('/en') || u === targetUrl);
|
||||||
|
const others = urls.filter((u) => !home.includes(u));
|
||||||
|
urls = [...home, ...others.slice(0, limit - home.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`🧪 Pages to be tested:`);
|
||||||
|
urls.forEach((u) => console.log(` - ${u}`));
|
||||||
|
|
||||||
|
// 2. Prepare LHCI command
|
||||||
|
// We use --collect.url multiple times
|
||||||
|
const urlArgs = urls.map((u) => `--collect.url="${u}"`).join(' ');
|
||||||
|
|
||||||
|
// Handle authentication for staging/testing
|
||||||
|
// Lighthouse can set cookies via --collect.settings.extraHeaders
|
||||||
|
const extraHeaders = JSON.stringify({
|
||||||
|
Cookie: `klz_gatekeeper_session=${gatekeeperPassword}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const chromePath = process.env.CHROME_PATH || process.env.PUPPETEER_EXECUTABLE_PATH;
|
||||||
|
const chromePathArg = chromePath ? `--collect.chromePath="${chromePath}"` : '';
|
||||||
|
|
||||||
|
// Using a more robust way to execute and capture output
|
||||||
|
const lhciCommand = `npx lhci collect ${urlArgs} ${chromePathArg} --collect.settings.chromeFlags='--no-sandbox --disable-setuid-sandbox' --collect.settings.extraHeaders='${extraHeaders}' && npx lhci assert && npx lhci upload`;
|
||||||
|
|
||||||
|
console.log(`💻 Executing LHCI...`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 1. Fetch Sitemap
|
const output = execSync(lhciCommand, {
|
||||||
const sitemapUrl = `${targetUrl.replace(/\/$/, '')}/sitemap.xml`;
|
encoding: 'utf8',
|
||||||
console.log(`📥 Fetching sitemap from ${sitemapUrl}...`);
|
stdio: ['inherit', 'pipe', 'inherit'], // Pipe stdout so we can parse it
|
||||||
|
});
|
||||||
|
|
||||||
// We might need to bypass gatekeeper for the sitemap fetch too
|
console.log(output);
|
||||||
const response = await axios.get(sitemapUrl, {
|
|
||||||
headers: {
|
|
||||||
'Cookie': `klz_gatekeeper_session=${gatekeeperPassword}`
|
|
||||||
},
|
|
||||||
validateStatus: (status) => status < 400
|
|
||||||
});
|
|
||||||
|
|
||||||
const $ = cheerio.load(response.data, { xmlMode: true });
|
// Extract report URL from LHCI output
|
||||||
let urls = $('url loc').map((i, el) => $(el).text()).get();
|
const reportMatch = output.match(
|
||||||
|
/Sent to (https:\/\/storage\.googleapis\.com\/lighthouse-infrastructure\.appspot\.com\/reports\/[^\s]+)/,
|
||||||
// Cleanup and filter
|
);
|
||||||
urls = [...new Set(urls)].filter(u => u.startsWith('http')).sort();
|
if (reportMatch && reportMatch[1]) {
|
||||||
|
const reportUrl = reportMatch[1];
|
||||||
console.log(`✅ Found ${urls.length} URLs in sitemap.`);
|
console.log(`\n📊 Report URL: ${reportUrl}`);
|
||||||
|
fs.writeFileSync('pagespeed-report-url.txt', reportUrl);
|
||||||
if (urls.length === 0) {
|
}
|
||||||
console.error('❌ No URLs found in sitemap. Is the site up?');
|
} catch (err: any) {
|
||||||
process.exit(1);
|
console.error('❌ LHCI execution failed.');
|
||||||
}
|
if (err.stdout) console.log(err.stdout);
|
||||||
|
if (err.stderr) console.error(err.stderr);
|
||||||
if (urls.length > limit) {
|
throw err;
|
||||||
console.log(`⚠️ Too many pages (${urls.length}). Limiting to ${limit} representative pages.`);
|
|
||||||
// Try to pick a variety: home, some products, some blog posts
|
|
||||||
const home = urls.filter(u => u.endsWith('/de') || u.endsWith('/en') || u === targetUrl);
|
|
||||||
const others = urls.filter(u => !home.includes(u));
|
|
||||||
urls = [...home, ...others.slice(0, limit - home.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`🧪 Pages to be tested:`);
|
|
||||||
urls.forEach(u => console.log(` - ${u}`));
|
|
||||||
|
|
||||||
// 2. Prepare LHCI command
|
|
||||||
// We use --collect.url multiple times
|
|
||||||
const urlArgs = urls.map(u => `--collect.url="${u}"`).join(' ');
|
|
||||||
|
|
||||||
// Handle authentication for staging/testing
|
|
||||||
// Lighthouse can set cookies via --collect.settings.extraHeaders
|
|
||||||
const extraHeaders = JSON.stringify({
|
|
||||||
'Cookie': `klz_gatekeeper_session=${gatekeeperPassword}`
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(`\n🏗️ Running Lighthouse CI...`);
|
|
||||||
|
|
||||||
// Using a more robust way to execute and capture output
|
|
||||||
const lhciCommand = `npx lhci collect ${urlArgs} --collect.settings.chromeFlags='--no-sandbox --disable-setuid-sandbox' --collect.settings.extraHeaders='${extraHeaders}' && npx lhci assert && npx lhci upload`;
|
|
||||||
|
|
||||||
console.log(`💻 Executing LHCI...`);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const output = execSync(lhciCommand, {
|
|
||||||
encoding: 'utf8',
|
|
||||||
stdio: ['inherit', 'pipe', 'inherit'] // Pipe stdout so we can parse it
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(output);
|
|
||||||
|
|
||||||
// Extract report URL from LHCI output
|
|
||||||
const reportMatch = output.match(/Sent to (https:\/\/storage\.googleapis\.com\/lighthouse-infrastructure\.appspot\.com\/reports\/[^\s]+)/);
|
|
||||||
if (reportMatch && reportMatch[1]) {
|
|
||||||
const reportUrl = reportMatch[1];
|
|
||||||
console.log(`\n📊 Report URL: ${reportUrl}`);
|
|
||||||
fs.writeFileSync('pagespeed-report-url.txt', reportUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err: any) {
|
|
||||||
console.error('❌ LHCI execution failed.');
|
|
||||||
if (err.stdout) console.log(err.stdout);
|
|
||||||
if (err.stderr) console.error(err.stderr);
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`\n✨ PageSpeed tests completed successfully!`);
|
|
||||||
|
|
||||||
} catch (error: any) {
|
|
||||||
console.error(`\n❌ Error during PageSpeed test:`);
|
|
||||||
if (axios.isAxiosError(error)) {
|
|
||||||
console.error(`Status: ${error.response?.status}`);
|
|
||||||
console.error(`StatusText: ${error.response?.statusText}`);
|
|
||||||
console.error(`URL: ${error.config?.url}`);
|
|
||||||
} else {
|
|
||||||
console.error(error.message);
|
|
||||||
}
|
|
||||||
process.exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(`\n✨ PageSpeed tests completed successfully!`);
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error(`\n❌ Error during PageSpeed test:`);
|
||||||
|
if (axios.isAxiosError(error)) {
|
||||||
|
console.error(`Status: ${error.response?.status}`);
|
||||||
|
console.error(`StatusText: ${error.response?.statusText}`);
|
||||||
|
console.error(`URL: ${error.config?.url}`);
|
||||||
|
} else {
|
||||||
|
console.error(error.message);
|
||||||
|
}
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|||||||
Reference in New Issue
Block a user