Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
version: 2
updates:
# Python dependencies
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
day: "sunday"
time: "02:00"
open-pull-requests-limit: 5
reviewers:
- "DevCraftClub"
assignees:
- "DevCraftClub"
commit-message:
prefix: "chore"
include: "scope"
labels:
- "dependencies"
- "python"
ignore:
# Игнорируем major версии для критических зависимостей
- dependency-name: "mkdocs-material"
update-types: ["version-update:semver-major"]
- dependency-name: "mkdocs"
update-types: ["version-update:semver-major"]

# GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "03:00"
open-pull-requests-limit: 3
reviewers:
- "DevCraftClub"
assignees:
- "DevCraftClub"
commit-message:
prefix: "ci"
include: "scope"
labels:
- "dependencies"
- "github-actions"
121 changes: 121 additions & 0 deletions .github/workflows/changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
name: Generate Changelog

on:
push:
tags:
- "v*"

jobs:
changelog:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Generate changelog
id: changelog
uses: actions/github-script@v6
with:
script: |
const { data: commits } = await github.rest.repos.compareCommits({
owner: context.repo.owner,
repo: context.repo.repo,
base: 'main',
head: context.sha
});

let changelog = '# 📋 Changelog\n\n';
changelog += `## Version ${context.ref.replace('refs/tags/', '')}\n\n`;
changelog += `**Release Date:** ${new Date().toISOString().split('T')[0]}\n\n`;

const categories = {
'feat': '🚀 Features',
'fix': '🐛 Bug Fixes',
'docs': '📚 Documentation',
'style': '💄 Style',
'refactor': '♻️ Refactoring',
'test': '🧪 Tests',
'chore': '🔧 Chores',
'ci': '⚙️ CI/CD',
'perf': '⚡ Performance',
'build': '📦 Build',
'revert': '⏪ Reverts'
};

const categorizedCommits = {};

for (const commit of commits.commits) {
const message = commit.commit.message;
const lines = message.split('\n');
const firstLine = lines[0];

// Парсим conventional commits
const match = firstLine.match(/^(\w+)(?:\(([^)]+)\))?:\s*(.+)$/);

if (match) {
const [, type, scope, description] = match;
const category = categories[type] || '📝 Other';

if (!categorizedCommits[category]) {
categorizedCommits[category] = [];
}

const scopeText = scope ? `**${scope}:** ` : '';
categorizedCommits[category].push(`- ${scopeText}${description}`);
} else {
// Не conventional commit
if (!categorizedCommits['📝 Other']) {
categorizedCommits['📝 Other'] = [];
}
categorizedCommits['📝 Other'].push(`- ${firstLine}`);
}
}

// Добавляем категории в changelog
for (const [category, commits] of Object.entries(categorizedCommits)) {
if (commits.length > 0) {
changelog += `### ${category}\n\n`;
for (const commit of commits) {
changelog += `${commit}\n`;
}
changelog += '\n';
}
}

// Добавляем статистику
changelog += '## 📊 Statistics\n\n';
changelog += `- **Total commits:** ${commits.commits.length}\n`;
changelog += `- **Files changed:** ${commits.files ? commits.files.length : 'N/A'}\n`;
changelog += `- **Additions:** ${commits.stats ? commits.stats.additions : 'N/A'}\n`;
changelog += `- **Deletions:** ${commits.stats ? commits.stats.deletions : 'N/A'}\n\n`;

// Добавляем ссылки
changelog += '## 🔗 Links\n\n';
changelog += `- [Full diff](https://github.com/${context.repo.owner}/${context.repo.repo}/compare/main...${context.ref})\n`;
changelog += `- [Documentation](https://devcraftclub.github.io/mhdocs/)\n`;
changelog += `- [Readme DevCraft](https://readme.devcraft.club)\n`;

core.setOutput('changelog', changelog);
console.log('Generated changelog:', changelog);

- name: Create changelog file
run: |
echo "${{ steps.changelog.outputs.changelog }}" > CHANGELOG.md

- name: Commit changelog
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add CHANGELOG.md
git commit -m "docs: update changelog for ${{ github.ref_name }}" || echo "No changes to commit"
git push

- name: Upload changelog as artifact
uses: actions/upload-artifact@v3
with:
name: changelog-${{ github.ref_name }}
path: CHANGELOG.md
retention-days: 90
41 changes: 41 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Deploy Documentation

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
build-and-deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Получаем полную историю для git-revision-date плагина

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.13"
cache: "pip"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Build documentation
run: |
mkdocs build -c
mkdocs gh-deploy --force

- name: Deploy to GitHub Pages
if: github.ref == 'refs/heads/main'
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./site
force_orphan: true
106 changes: 106 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: Security Check

on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
# Еженедельная проверка безопасности
- cron: "0 4 * * 1"

jobs:
security:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
cache: "pip"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install bandit safety

- name: Run Bandit security check
run: |
echo "Running Bandit security check..."
bandit -r . -f json -o bandit-report.json || true
bandit -r . -f txt -o bandit-report.txt || true

# Показываем результаты
if [ -f bandit-report.txt ]; then
echo "=== Bandit Security Report ==="
cat bandit-report.txt
fi

- name: Check for known vulnerabilities
run: |
echo "Checking for known vulnerabilities..."
safety check --json --output safety-report.json || true
safety check --output safety-report.txt || true

# Показываем результаты
if [ -f safety-report.txt ]; then
echo "=== Safety Vulnerability Report ==="
cat safety-report.txt
fi

- name: Upload security reports
uses: actions/upload-artifact@v4
if: always()
with:
name: security-reports
path: |
bandit-report.json
bandit-report.txt
safety-report.json
safety-report.txt
retention-days: 30

- name: Comment PR with security findings
if: github.event_name == 'pull_request'
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');

let comment = '## 🔒 Security Check Results\n\n';

// Bandit results
if (fs.existsSync('bandit-report.txt')) {
const banditContent = fs.readFileSync('bandit-report.txt', 'utf8');
if (banditContent.trim()) {
comment += '### 🚨 Bandit Security Issues\n\n';
comment += '```\n' + banditContent + '\n```\n\n';
} else {
comment += '✅ No Bandit security issues found\n\n';
}
}

// Safety results
if (fs.existsSync('safety-report.txt')) {
const safetyContent = fs.readFileSync('safety-report.txt', 'utf8');
if (safetyContent.trim()) {
comment += '### ⚠️ Known Vulnerabilities\n\n';
comment += '```\n' + safetyContent + '\n```\n\n';
} else {
comment += '✅ No known vulnerabilities found\n\n';
}
}

comment += '---\n*This report was generated automatically by GitHub Actions*';

github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
76 changes: 76 additions & 0 deletions .github/workflows/update-deps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Update Dependencies

on:
schedule:
# Запускается каждое воскресенье в 2:00 UTC
- cron: "0 2 * * 0"
workflow_dispatch: # Позволяет запускать вручную

jobs:
update-deps:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
cache: "pip"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pip-chill

- name: Update dependencies
run: |
echo "Updating dependencies..."
pip install --upgrade $(pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1)

- name: Update requirements.txt
run: |
echo "Updating requirements.txt..."
pip-chill --no-version > requirements.txt.new
if ! cmp -s requirements.txt requirements.txt.new; then
mv requirements.txt.new requirements.txt
echo "Requirements updated"
else
echo "No updates needed"
rm requirements.txt.new
fi

- name: Test build
run: |
echo "Testing build with updated dependencies..."
mkdocs build --strict

- name: Create Pull Request
if: success()
uses: peter-evans/create-pull-request@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "chore: update dependencies"
title: "🤖 Automated dependency update"
body: |
## 🔄 Automated Dependency Update

This PR was automatically created to update project dependencies.

### 📋 Changes
- Updated Python package dependencies
- Tested build with new dependencies

### ✅ Checks
- [x] Dependencies updated
- [x] Build tested successfully

### 🚀 Ready to merge
This PR is safe to merge as all tests pass.
branch: update-dependencies
delete-branch: true
Loading