Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
1ecaa97
⚙️ FEATURE-#34: Add pytest and code-quality poetry dependency groups
FernandoCelmer Aug 16, 2026
ff547dd
⚙️ FEATURE-#34: Add ruff and mypy configuration
FernandoCelmer Aug 16, 2026
98660ec
⬆️ CI/CD-#34: Fix poetry cache key and lock fallback in setup-poetry
FernandoCelmer Aug 16, 2026
adc9386
⬆️ CI/CD-#34: Add verify-version composite action
FernandoCelmer Aug 16, 2026
f017713
⬆️ CI/CD-#34: Add test workflow with pytest matrix
FernandoCelmer Aug 16, 2026
1b791de
⬆️ CI/CD-#34: Add code-quality workflow with ruff and mypy
FernandoCelmer Aug 16, 2026
ba5ef07
⬆️ CI/CD-#34: Gate PyPI release on tests and code quality
FernandoCelmer Aug 16, 2026
d06ed22
⬆️ CI/CD-#34: Gate TestPyPI deploy on tests and code quality
FernandoCelmer Aug 16, 2026
85ad166
❤️ TEST-#34: Add smoke tests for theme package
FernandoCelmer Aug 16, 2026
e7e980d
📝 PEP8-#34: Fix quote style in __init__.py per ruff format
FernandoCelmer Aug 16, 2026
3763855
🪲 BUG-#34: Fix auto-assign workflow failing on PR events with invalid…
FernandoCelmer Aug 16, 2026
7947c51
📦 PyPI-#34: Regenerate poetry.lock for dev/code-quality groups
FernandoCelmer Aug 16, 2026
0bc5e4c
❤️ TEST-#34: Add theme_dir pytest fixture
FernandoCelmer Aug 16, 2026
ebf3d70
❤️ TEST-#34: Add unittest coverage for package metadata
FernandoCelmer Aug 16, 2026
69d343c
❤️ TEST-#34: Add unittest coverage for mkdocs theme entry point
FernandoCelmer Aug 16, 2026
6f8c394
❤️ TEST-#34: Add unittest coverage for mkdocs_theme.yml config
FernandoCelmer Aug 16, 2026
de912a4
❤️ TEST-#34: Add unittest coverage for HTML templates
FernandoCelmer Aug 16, 2026
9878492
❤️ TEST-#34: Add unittest coverage for CSS/JS/image assets
FernandoCelmer Aug 16, 2026
638b7b7
❤️ TEST-#34: Split test_theme.py into per-concern unittest modules
FernandoCelmer Aug 16, 2026
3804ac9
🪲 BUG-#34: Fix entry_points() group kwarg incompatible with Python 3.9
FernandoCelmer Aug 16, 2026
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
24 changes: 24 additions & 0 deletions .code_quality/mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[mypy]
python_version = 3.9

warn_return_any = True
warn_unused_configs = True
disallow_untyped_defs = False
disallow_incomplete_defs = False
check_untyped_defs = True
disallow_untyped_decorators = False
no_implicit_optional = True
warn_redundant_casts = True
warn_unused_ignores = True
warn_no_return = True
warn_unreachable = True
strict_equality = True
show_error_codes = True

exclude = build/,dist/,venv/,.venv/

[mypy-mkdocs.*]
ignore_missing_imports = True

[mypy-tests.*]
disallow_untyped_defs = False
55 changes: 55 additions & 0 deletions .code_quality/ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Ruff configuration
# Modern and fast Python linter

# Line length
line-length = 79

# Target Python version
target-version = "py39"

# Exclude patterns
exclude = [
".git",
"__pycache__",
".venv",
"venv",
"build",
"dist",
"*.egg-info",
]

# Lint configuration
[lint]
# Enable specific rule sets
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
]

# Ignore specific rules
ignore = [
"B008", # Do not perform function calls in argument defaults
"E203", # Whitespace before ':' (flake8 compatibility - handled separately)
"E501",
]

# Allowed configurations for specific rules
[lint.per-file-ignores]
"__init__.py" = ["F401"] # Allow unused imports in __init__.py
"tests/**" = ["S101"] # Allow assert in tests

# Import sorting (isort)
[lint.isort]
known-first-party = ["mkdocs_dracula_theme"]
force-single-line = false

# Formatting (alternative to black)
[format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
6 changes: 3 additions & 3 deletions .github/actions/setup-poetry/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ runs:
path: |
.venv
~/.cache/pypoetry
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
key: ${{ runner.os }}-poetry-${{ inputs.python-version }}-${{ hashFiles('**/poetry.lock') }}
restore-keys: |
${{ runner.os }}-poetry-
${{ runner.os }}-poetry-${{ inputs.python-version }}-

- name: 🔒 Update lock file if needed
shell: bash
run: |
poetry lock --no-update || true
poetry lock --no-update 2>/dev/null || poetry lock

- name: ⚙️ Install dependencies
if: inputs.install-deps != ''
Expand Down
30 changes: 30 additions & 0 deletions .github/actions/verify-version/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Verify Version
description: Verify LAST_VERSION matches pyproject.toml and __init__.py

inputs:
expected:
description: Expected version to check against (defaults to __init__.py version)
required: false
default: ""

runs:
using: composite
steps:
- name: 🔍 Verify version
shell: bash
run: |
EXPECTED="${{ inputs.expected }}"
EXPECTED="${EXPECTED#v}"
if [ -z "$EXPECTED" ]; then
EXPECTED=$(grep -m1 '^__version__ = ' mkdocs_dracula_theme/__init__.py | sed 's/^__version__ = "\(.*\)"/\1/')
fi

echo "Expected version: $EXPECTED"
echo "LAST_VERSION: $(cat LAST_VERSION)"
echo "pyproject.toml: $(grep '^version = ' pyproject.toml | head -1)"
echo "__init__.py: $(grep '^__version__ = ' mkdocs_dracula_theme/__init__.py)"

if [ "$(cat LAST_VERSION)" != "$EXPECTED" ]; then
echo "ERROR: Version mismatch!"
exit 1
fi
4 changes: 0 additions & 4 deletions .github/workflows/auto-assign.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,14 @@ name: Auto Assign
on:
issues:
types: [opened]
pull_request:
types: [opened]
jobs:
run:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: 'Auto-assign issue'
uses: pozil/auto-assign-issue@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
assignees: FernandoCelmer
numOfAssignee: 1
46 changes: 46 additions & 0 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: 🔍 Code Quality

on:
pull_request:
branches: ["main", "master", "develop"]
workflow_dispatch:
workflow_call:

jobs:
code-quality:
name: Code Quality Checks
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]

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

- name: 📦 Setup Poetry
uses: ./.github/actions/setup-poetry
with:
python-version: ${{ matrix.python-version }}
install-deps: dev,code-quality

- name: 🔍 Ruff (Linting)
run: |
poetry run ruff check mkdocs_dracula_theme/ tests/ --config .code_quality/ruff.toml

- name: 🎨 Ruff (Format Check)
run: |
poetry run ruff format --check mkdocs_dracula_theme/ tests/ --config .code_quality/ruff.toml

- name: 🔍 MyPy (Type Checking)
continue-on-error: true
run: |
poetry run mypy mkdocs_dracula_theme/ --config-file .code_quality/mypy.ini

- name: ✅ Code Quality Summary
if: always()
run: |
echo "### Code Quality Checks Completed ✅" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Python Version: ${{ matrix.python-version }}" >> $GITHUB_STEP_SUMMARY
echo "All code quality tools have been executed." >> $GITHUB_STEP_SUMMARY
14 changes: 14 additions & 0 deletions .github/workflows/python-publish-pypi-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,19 @@ permissions:
id-token: write

jobs:
test:
name: Run Tests
uses: ./.github/workflows/test.yml
secrets: inherit

code-quality:
name: Code Quality Checks
uses: ./.github/workflows/code-quality.yml
secrets: inherit

deploy:
name: Deploy to TestPyPI
needs: [test, code-quality]
runs-on: ubuntu-latest

steps:
Expand All @@ -19,6 +30,9 @@ jobs:
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}

- name: 🔍 Verify version
uses: ./.github/actions/verify-version

- name: 📦 Build Package
uses: ./.github/actions/build-package
with:
Expand Down
103 changes: 51 additions & 52 deletions .github/workflows/python-publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,70 +14,69 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: 📥 Checkout code
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
ref: ${{ github.event.release.target_commitish }}
fetch-depth: 0

- name: 🔍 Determine branch
id: get_branch
run: |
TARGET="${{ github.event.release.target_commitish }}"
BRANCH="${TARGET#refs/heads/}"
BRANCH="${BRANCH#refs/tags/}"

if git rev-parse --verify "$BRANCH"^{tag} >/dev/null 2>&1 2>&1 || [[ "$TARGET" == refs/tags/* ]]; then
if git rev-parse --verify "$BRANCH"^{tag} >/dev/null 2>&1 || [[ "$TARGET" == refs/tags/* ]]; then
git fetch --all --tags
TAG_NAME="${TARGET#refs/tags/}"
BRANCH=$(git branch -r --contains "$TAG_NAME" | grep -E "(main|master)" | head -1 | sed 's|origin/||' | xargs || \
BRANCH=$(git branch -r --contains "$TAG_NAME" | grep -E "(main|master|develop)" | head -1 | sed 's|origin/||' | xargs || \
git branch -r --contains "$TAG_NAME" | head -1 | sed 's|origin/||' | xargs || \
echo "master")
fi

echo "branch=$BRANCH" >> $GITHUB_OUTPUT
echo "Using branch: $BRANCH"

- name: 📥 Checkout code
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
ref: ${{ steps.get_branch.outputs.branch }}
fetch-depth: 0
- name: 🔄 Checkout resolved branch
run: |
git checkout ${{ steps.get_branch.outputs.branch }}
git pull origin ${{ steps.get_branch.outputs.branch }}

- name: 🔍 Extract version from tag
id: extract_version
run: |
VERSION="${{ github.event.release.tag_name }}"
VERSION="${VERSION#v}"
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Tag: ${{ github.event.release.tag_name }}"
echo "Version: $VERSION"
uses: ./.github/actions/extract-version
with:
tag: ${{ github.event.release.tag_name }}

- name: 📝 Update LAST_VERSION
run: |
echo "${{ steps.extract_version.outputs.version }}" > LAST_VERSION
- name: 📝 Update version files
uses: ./.github/actions/update-version
with:
version: ${{ steps.extract_version.outputs.version }}

- name: 📝 Update pyproject.toml
run: |
VERSION="${{ steps.extract_version.outputs.version }}"
sed -i '/^\[project\]/,/^\[/s/^version = ".*"/version = "'"$VERSION"'"/' pyproject.toml
sed -i '/^\[tool\.poetry\]/,/^\[/s/^version = ".*"/version = "'"$VERSION"'"/' pyproject.toml
- name: 💾 Commit and push
uses: ./.github/actions/commit-push
with:
message: "📦 PyPI: Update version to ${{ steps.extract_version.outputs.version }}"
files: "LAST_VERSION pyproject.toml mkdocs_dracula_theme/__init__.py"
branch: ${{ steps.get_branch.outputs.branch }}

- name: 📝 Update __init__.py
run: |
VERSION="${{ steps.extract_version.outputs.version }}"
sed -i "s/^__version__ = \".*\"/__version__ = \"$VERSION\"/" mkdocs_dracula_theme/__init__.py
test:
name: Run Tests
needs: [update-version]
uses: ./.github/workflows/test.yml
secrets: inherit

- name: 💾 Commit and push
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add LAST_VERSION pyproject.toml mkdocs_dracula_theme/__init__.py
if git diff --staged --quiet; then
echo "No changes to commit"
else
git commit -m "📦 PyPI: Update version to ${{ steps.extract_version.outputs.version }}"
git push origin ${{ steps.get_branch.outputs.branch }}
fi
code-quality:
name: Code Quality Checks
needs: [update-version]
uses: ./.github/workflows/code-quality.yml
secrets: inherit

deploy:
name: Deploy to PyPI
needs: [update-version]
name: Deploy to ${{ github.event.release.prerelease && 'TestPyPI' || 'PyPI' }}
needs: [update-version, test, code-quality]
runs-on: ubuntu-latest

steps:
Expand All @@ -95,7 +94,7 @@ jobs:

if [[ "$TARGET" == refs/tags/* ]] || git rev-parse --verify "$BRANCH"^{tag} >/dev/null 2>&1; then
TAG_NAME="${TARGET#refs/tags/}"
BRANCH=$(git branch -r --contains "$TAG_NAME" | grep -E "(main|master)" | head -1 | sed 's|origin/||' | xargs || \
BRANCH=$(git branch -r --contains "$TAG_NAME" | grep -E "(main|master|develop)" | head -1 | sed 's|origin/||' | xargs || \
git branch -r --contains "$TAG_NAME" | head -1 | sed 's|origin/||' | xargs || \
echo "master")
fi
Expand All @@ -109,23 +108,23 @@ jobs:
git pull origin ${{ steps.get_branch_deploy.outputs.branch }}

- name: 🔍 Verify version
run: |
EXPECTED="${{ github.event.release.tag_name }}"
EXPECTED="${EXPECTED#v}"
echo "Expected version: $EXPECTED"
echo "LAST_VERSION: $(cat LAST_VERSION)"
echo "pyproject.toml: $(grep '^version = ' pyproject.toml | head -1)"
echo "__init__.py: $(grep '^__version__ = ' mkdocs_dracula_theme/__init__.py)"

if [ "$(cat LAST_VERSION)" != "$EXPECTED" ]; then
echo "ERROR: Version mismatch!"
exit 1
fi
uses: ./.github/actions/verify-version
with:
expected: ${{ github.event.release.tag_name }}

- name: 📦 Build Package
uses: ./.github/actions/build-package
with:
python-version: "3.10"

- name: 📦 Publish Package to TestPyPI
if: github.event.release.prerelease == true
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
skip-existing: true
verbose: true

- name: 📦 Publish Package to PyPI
if: github.event.release.prerelease == false
uses: pypa/gh-action-pypi-publish@release/v1
Loading
Loading