This commit renames the 'laborious' package to 'model_manager' across the entire project. This includes renaming directories, modules, references in code, configuration files, and documentation to reflect the new package name. This change improves clarity and consistency within the project.
210 lines
8.7 KiB
YAML
210 lines
8.7 KiB
YAML
name: Quality gate
|
|
|
|
on:
|
|
# push:
|
|
# branches:
|
|
# - main
|
|
pull_request:
|
|
branches:
|
|
- main
|
|
types: [ opened, synchronize, reopened ]
|
|
|
|
jobs:
|
|
sonar:
|
|
name: SonarQube Analysis
|
|
runs-on: ubuntu-latest
|
|
permissions: write-all
|
|
steps:
|
|
- name: ⬇️ Checkout Code
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
persist-credentials: false
|
|
|
|
- name: Calculate Version
|
|
id: calculate-version
|
|
if: github.event_name == 'pull_request'
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const fs = require('fs');
|
|
|
|
// Função para calcular nova versão baseada no branch
|
|
function calculateVersion(lastVersion, branchName) {
|
|
const parseVersion = (v) => {
|
|
const match = v.match(/^(\d+)\.(\d+)\.(\d+)(?:-rc(\d+))?$/);
|
|
if (!match) throw new Error(`Invalid version format: ${v}`);
|
|
return {
|
|
major: parseInt(match[1]),
|
|
minor: parseInt(match[2]),
|
|
patch: parseInt(match[3]),
|
|
rc: match[4] ? parseInt(match[4]) : null
|
|
};
|
|
};
|
|
|
|
const current = parseVersion(lastVersion);
|
|
|
|
if (branchName.startsWith('release/')) {
|
|
return `${current.major + 1}.0.0`;
|
|
} else if (branchName.startsWith('feature/')) {
|
|
return `${current.major}.${current.minor + 1}.0`;
|
|
} else if (branchName.startsWith('fix/')) {
|
|
return `${current.major}.${current.minor}.${current.patch + 1}`;
|
|
} else if (branchName.startsWith('rc/')) {
|
|
if (current.rc !== null) {
|
|
return `${current.major}.${current.minor}.${current.patch}-rc${current.rc + 1}`;
|
|
} else {
|
|
return `${current.major}.${current.minor}.${current.patch}-rc1`;
|
|
}
|
|
}
|
|
|
|
return null; // Não sugerir para outros tipos de branch
|
|
}
|
|
|
|
try {
|
|
const branchName = context.payload.pull_request.head.ref;
|
|
console.log(`Branch name: ${branchName}`);
|
|
|
|
// Validar se o branch segue os padrões aceitos
|
|
const validPrefixes = ['release/', 'feature/', 'fix/', 'rc/'];
|
|
const isValidBranch = validPrefixes.some(prefix => branchName.startsWith(prefix));
|
|
|
|
if (!isValidBranch) {
|
|
const errorMessage = `## 🚨 Erro: Nome do Branch Inválido\n\n` +
|
|
`O branch \`${branchName}\` não segue os padrões de nomenclatura aceitos.\n\n` +
|
|
`### 📝 Padrões Aceitos:\n` +
|
|
`- \`release/*\`: Para releases de major version (ex: release/v2.0.0)\n` +
|
|
`- \`feature/*\`: Para novas funcionalidades (ex: feature/nova-funcionalidade)\n` +
|
|
`- \`fix/*\`: Para correções de bugs (ex: fix/correcao-bug)\n` +
|
|
`- \`rc/*\`: Para release candidates (ex: rc/v1.2.0-rc1)\n\n` +
|
|
`### 🔧 Como corrigir:\n` +
|
|
`1. Renomeie o branch para seguir um dos padrões acima\n` +
|
|
`2. Ou crie um novo branch com o nome correto\n`;
|
|
|
|
const prNumber = context.issue.number;
|
|
await github.rest.issues.createComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: prNumber,
|
|
body: errorMessage
|
|
});
|
|
|
|
core.setFailed(`Invalid branch name: ${branchName}. Must start with release/, feature/, fix/, or rc/`);
|
|
return;
|
|
}
|
|
|
|
// Obter a última tag de release
|
|
console.log('Fetching latest release tag...');
|
|
const { data: releases } = await github.rest.repos.listReleases({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
per_page: 1
|
|
});
|
|
|
|
let lastReleaseVersion = '0.0.0';
|
|
if (releases.length > 0) {
|
|
lastReleaseVersion = releases[0].tag_name.replace(/^v/, '');
|
|
console.log(`Latest release version: ${lastReleaseVersion}`);
|
|
} else {
|
|
console.log('No releases found, using 0.0.0 as baseline');
|
|
}
|
|
|
|
// Calcular a nova versão baseada no branch
|
|
const newVersion = calculateVersion(lastReleaseVersion, branchName);
|
|
console.log(`Calculated version: ${newVersion}`);
|
|
|
|
// Exportar a versão como output
|
|
core.setOutput('version', newVersion);
|
|
|
|
// Adicionar comentário informativo no PR
|
|
const prNumber = context.issue.number;
|
|
const infoMessage = `## ✅ Versão Calculada Automaticamente\n\n` +
|
|
`**Branch:** \`${branchName}\`\n` +
|
|
`**Última release:** \`${lastReleaseVersion}\`\n` +
|
|
`**Nova versão:** \`${newVersion}\`\n\n` +
|
|
`### 📝 Regras Aplicadas:\n` +
|
|
`- \`release/*\`: Aumenta major, zera minor e patch (ex: 2.0.0)\n` +
|
|
`- \`feature/*\`: Mantém major, aumenta minor, zera patch (ex: 1.2.0)\n` +
|
|
`- \`fix/*\`: Mantém major e minor, aumenta patch (ex: 1.1.3)\n` +
|
|
`- \`rc/*\`: Mantém versão base, aumenta RC (ex: 1.1.2-rc2)\n`;
|
|
|
|
await github.rest.issues.createComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: prNumber,
|
|
body: infoMessage
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('Error during version calculation:', error);
|
|
|
|
const prNumber = context.issue.number;
|
|
const errorMessage = `## 🚨 Erro no Cálculo de Versão\n\n` +
|
|
`Ocorreu um erro durante o cálculo da versão:\n\n\`\`\`\n${error.message}\n\`\`\`\n\n` +
|
|
`Por favor, verifique se o nome do branch está correto e tente novamente.`;
|
|
|
|
await github.rest.issues.createComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: prNumber,
|
|
body: errorMessage
|
|
});
|
|
|
|
core.setFailed(`Version calculation error: ${error.message}`);
|
|
}
|
|
|
|
- name: Generate App Token
|
|
id: generate-app-token
|
|
uses: actions/create-github-app-token@v1
|
|
with:
|
|
app-id: ${{ secrets.APP_ID }}
|
|
private-key: ${{ secrets.APP_PRIVATE_KEY }}
|
|
owner: 'Aignosi'
|
|
repositories: 'sientia-dataops-library,sientia-mlops-library'
|
|
|
|
- name: Prepare requirements.txt
|
|
id: prepare-requirements
|
|
run: |
|
|
sed -e "s|git+ssh://git@github.com/|git+https://github.com/|g" \
|
|
-e "s|git@github.com:|git+https://github.com/|g" \
|
|
requirements.txt > requirements_prepared.txt
|
|
echo "PROCESSED_REQUIREMENTS_FILE=requirements_prepared.txt" >> $GITHUB_OUTPUT
|
|
|
|
- name: Configure Git to use App Token
|
|
env:
|
|
GH_APP_TOKEN: ${{ steps.generate-app-token.outputs.token }}
|
|
run: |
|
|
git config --global url."https://oauth2:${GH_APP_TOKEN}@github.com/".insteadOf "https://github.com/"
|
|
|
|
- name: 🔧 Setup Python
|
|
uses: actions/setup-python@v4
|
|
with:
|
|
python-version: "3.11"
|
|
|
|
- name: 🗄️ Cache Python dependencies
|
|
uses: actions/cache@v3
|
|
with:
|
|
path: ~/.cache/pip
|
|
key: ${{ runner.os }}-pip-${{ hashFiles(steps.prepare-requirements.outputs.PROCESSED_REQUIREMENTS_FILE) }}
|
|
restore-keys: |
|
|
${{ runner.os }}-pip-
|
|
|
|
- name: 📦 Install Dependencies
|
|
run: |
|
|
python -m pip install --upgrade pip
|
|
pip install -r ${{ steps.prepare-requirements.outputs.PROCESSED_REQUIREMENTS_FILE }}
|
|
pip install pytest pytest-cov pytest-asyncio
|
|
|
|
- name: 🧪 Run Tests with Pytest
|
|
run: |
|
|
pytest tests --junitxml=pytest.xml --cov=model_manager --cov-report=xml --cov-report=term
|
|
|
|
- name: Run SonarQube Analysis
|
|
uses: SonarSource/sonarqube-scan-action@v5
|
|
env:
|
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
|
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
|
with:
|
|
args: >
|
|
-Dsonar.projectVersion=${{ steps.calculate-version.outputs.version || '0.0.0' }}
|