Proyecto #3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |