Skip to content

Package

Package #4

Workflow file for this run

name: PHP Tests & Coverage
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
permissions:
contents: write
pages: write
id-token: write
jobs:
test-and-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: mbstring, xml, xdebug
coverage: xdebug
tools: composer:v2
- name: Get composer cache directory
id: composer-cache-dir
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache Composer dependencies
uses: actions/cache@v3
id: composer-cache
with:
path: ${{ steps.composer-cache-dir.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install dependencies
run: |
composer install --no-progress --prefer-dist --optimize-autoloader
composer require --dev emuse/behat-html-formatter
- name: Run test suite with coverage
run: |
mkdir -p public/coverage
XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-html public/coverage --coverage-text
- name: Update Behat configuration
run: |
sed -i 's/Features/features/g' behat.yml
sed -i 's/Bootstrap/bootstrap/g' behat.yml
- name: Verify directory structure
run: |
echo "Verificando estructura actual..."
ls -R tests/BDD/
echo "Creando estructura de directorios si no existe..."
mkdir -p tests/BDD/features/bootstrap
- name: Run Behat tests
run: |
mkdir -p public/bdd
composer dump-autoload
vendor/bin/behat --config behat.yml --format pretty --format html --out std --out public/bdd || true
- name: Create main index.html
run: |
echo '<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Reportes de Pruebas</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 40px;
text-align: center;
background-color: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: white;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
h1 {
color: #333;
margin-bottom: 30px;
}
.buttons {
display: flex;
justify-content: center;
gap: 20px;
}
.button {
display: inline-block;
padding: 12px 24px;
color: white;
text-decoration: none;
border-radius: 5px;
transition: background-color 0.3s;
}
.coverage-btn {
background-color: #4CAF50;
}
.coverage-btn:hover {
background-color: #45a049;
}
.bdd-btn {
background-color: #2196F3;
}
.bdd-btn:hover {
background-color: #1976D2;
}
.sonar-btn {
background-color: #FF9800;
}
.sonar-btn:hover {
background-color: #F57C00;
}
</style>
</head>
<body>
<div class="container">
<h1>Proyecto SI784-2024-II</h1>
<div class="buttons">
<a href="coverage/index.html" class="button coverage-btn">Ver Reporte de Cobertura</a>
<a href="bdd/index.html" class="button bdd-btn">Ver Reporte BDD</a>
<a href="sonar/index.html" class="button sonar-btn">Ver Reporte SonarCloud</a>
</div>
</div>
</body>
</html>' > public/index.html
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
enable_jekyll: false
force_orphan: true
publish_branch: gh-pages
full_commit_message: 'docs: update test reports'
- name: Generate Sonar Report
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
run: |
mkdir -p public/sonar
echo '<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Reporte SonarCloud</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 40px;
line-height: 1.6;
background-color: #f5f5f5;
}
.container {
max-width: 1000px;
margin: 0 auto;
padding: 20px;
background-color: white;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
.metrics {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin: 20px 0;
}
.metric-card {
background: #f8f9fa;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
transition: transform 0.2s;
}
.metric-card:hover {
transform: translateY(-2px);
}
.metric-title {
color: #666;
font-size: 0.9em;
margin-bottom: 5px;
}
.metric-value {
font-size: 1.8em;
font-weight: bold;
color: #333;
}
.metric-trend {
font-size: 0.9em;
margin-top: 5px;
}
.trend-up { color: #dc3545; }
.trend-down { color: #28a745; }
.trend-neutral { color: #6c757d; }
.loading {
text-align: center;
padding: 20px;
color: #666;
}
.sonar-link {
display: inline-block;
margin-top: 20px;
padding: 10px 20px;
background-color: #2196F3;
color: white;
text-decoration: none;
border-radius: 5px;
transition: background-color 0.3s;
}
.sonar-link:hover {
background-color: #1976D2;
}
.error-message {
color: #dc3545;
text-align: center;
padding: 20px;
}
.last-analysis {
text-align: right;
color: #666;
font-size: 0.9em;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<h1>Reporte de Análisis SonarCloud</h1>
<div id="loading" class="loading">Cargando datos...</div>
<div id="error" class="error-message" style="display: none;"></div>
<div id="metrics" class="metrics" style="display: none;">
<div class="metric-card">
<div class="metric-title">Bugs</div>
<div class="metric-value" id="bugs">-</div>
<div class="metric-trend" id="bugs-trend"></div>
</div>
<div class="metric-card">
<div class="metric-title">Vulnerabilidades</div>
<div class="metric-value" id="vulnerabilities">-</div>
<div class="metric-trend" id="vulnerabilities-trend"></div>
</div>
<div class="metric-card">
<div class="metric-title">Code Smells</div>
<div class="metric-value" id="code-smells">-</div>
<div class="metric-trend" id="code-smells-trend"></div>
</div>
<div class="metric-card">
<div class="metric-title">Cobertura</div>
<div class="metric-value" id="coverage">-</div>
<div class="metric-trend" id="coverage-trend"></div>
</div>
<div class="metric-card">
<div class="metric-title">Duplicación</div>
<div class="metric-value" id="duplication">-</div>
<div class="metric-trend" id="duplication-trend"></div>
</div>
<div class="metric-card">
<div class="metric-title">Calidad</div>
<div class="metric-value" id="quality-gate">-</div>
</div>
</div>
<div id="last-analysis" class="last-analysis"></div>
<a href="https://sonarcloud.io/project/overview?id=upt-faing-epis_proyecto-si784-2024-ii-u2-chambilla_llantay" class="sonar-link" target="_blank">
Ver reporte completo en SonarCloud
</a>
<script>
const projectKey = "upt-faing-epis_proyecto-si784-2024-ii-u2-chambilla_llantay";
const metrics = [
"bugs",
"vulnerabilities",
"code_smells",
"coverage",
"duplicated_lines_density",
"quality_gate_status"
];
async function fetchSonarData() {
try {
const response = await fetch(`https://sonarcloud.io/api/measures/component?component=${projectKey}&metricKeys=${metrics.join(",")}`);
if (!response.ok) throw new Error("Error al obtener datos de SonarCloud");
const data = await response.json();
document.getElementById("loading").style.display = "none";
document.getElementById("metrics").style.display = "grid";
data.component.measures.forEach(measure => {
let value = measure.value;
let elementId = "";
switch(measure.metric) {
case "bugs":
elementId = "bugs";
break;
case "vulnerabilities":
elementId = "vulnerabilities";
break;
case "code_smells":
elementId = "code-smells";
break;
case "coverage":
elementId = "coverage";
value = value + "%";
break;
case "duplicated_lines_density":
elementId = "duplication";
value = value + "%";
break;
case "quality_gate_status":
elementId = "quality-gate";
value = value === "OK" ? "✅ Passed" : "❌ Failed";
break;
}
if (elementId) {
document.getElementById(elementId).textContent = value;
}
});
const date = new Date();
document.getElementById("last-analysis").textContent =
`Última actualización: ${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
} catch (error) {
document.getElementById("loading").style.display = "none";
document.getElementById("error").style.display = "block";
document.getElementById("error").textContent =
"Error al cargar los datos de SonarCloud. Por favor, intenta más tarde.";
console.error(error);
}
}
fetchSonarData();
</script>
</div>
</body>
</html>' > public/sonar/index.html
- name: Verify Sonar Report
run: |
echo "Verificando reporte de Sonar..."
if [ -f "public/sonar/index.html" ]; then
echo "✓ El archivo sonar/index.html existe"
ls -l public/sonar/
else
echo "✗ El archivo sonar/index.html NO existe"
echo "Contenido de public/:"
ls -R public/
fi