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
40 changes: 22 additions & 18 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,26 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Install poetry
run: pipx install poetry
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
cache-dependency-glob: uv.lock

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
python-version-file: pyproject.toml

- name: Install dependencies and build project
- name: Install and build project
run: |
poetry install --without docs,test
poetry build
uv sync --locked --no-default-groups
uv build

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: poetry-build
name: jekyllnb-build
path: dist/

github:
Expand All @@ -46,7 +49,7 @@ jobs:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: poetry-build
name: jekyllnb-build
path: dist

- name: Get changes
Expand Down Expand Up @@ -75,6 +78,7 @@ jobs:
pypi:
name: PyPI
runs-on: ubuntu-latest
environment: pypi
needs: build

steps:
Expand All @@ -84,26 +88,26 @@ jobs:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: poetry-build
name: jekyllnb-build
path: dist

- name: Install poetry
run: pipx install poetry
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
cache-dependency-glob: uv.lock

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
python-version-file: pyproject.toml

- name: Publish to PyPI
if: success() && github.event_name == 'push'
run: poetry publish
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}
run: uv publish

- name: Publish to TestPyPI
if: success() && github.event_name == 'workflow_dispatch'
run: poetry publish -r test-pypi
run: uv publish
env:
POETRY_REPOSITORIES_TEST_PYPI_URL: https://test.pypi.org/legacy/
POETRY_PYPI_TOKEN_TEST_PYPI: ${{ secrets.TEST_PYPI_TOKEN }}
UV_PUBLISH_URL: https://test.pypi.org/legacy/
55 changes: 46 additions & 9 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,42 @@ on:
pull_request:

jobs:
linting:
name: Linting
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
cache-dependency-glob: uv.lock

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: pyproject.toml

- name: Test lock
run: uv lock --check

- name: Install project
run: uv sync --locked --all-extras --dev

- name: Format
run: uv run ruff format --check

- name: Check
run: uv run ruff check

- name: Type check
run: uv run pyright jekyllnb

test:
name: ${{ matrix.os.name }} / ${{ matrix.python-version }}
needs: linting
runs-on: ${{ matrix.os.image }}
defaults:
run:
Expand All @@ -30,34 +64,37 @@ jobs:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
fail-fast: false

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

- name: Install poetry
run: pipx install poetry
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
cache-dependency-glob: uv.lock

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: poetry

- name: Install dependencies
- name: Install project
run: |
poetry install
pip install pytest-github-actions-annotate-failures
uv sync --locked --all-extras --dev
uv pip install pytest-github-actions-annotate-failures

- name: Run tests
run: poetry run pytest --cov-report xml:coverage.xml
run: uv run pytest --cov-report xml:coverage.xml

- name: Upload coverage report
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v5
if: success()
with:
file: coverage.xml
files: coverage.xml
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}

Expand Down
11 changes: 0 additions & 11 deletions .pre-commit-config.yaml

This file was deleted.

9 changes: 6 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@
### Changed

- Dropped support for Python 3.6-3.8 ([#251](https://github.com/klane/jekyllnb/pull/251)).
- Updated dependencies ([#251](https://github.com/klane/jekyllnb/pull/251)).
- Removed `pytest-lazy-fixture` as a dev dependency since it [does not support `pytest` 8](https://github.com/TvoroG/pytest-lazy-fixture/issues/65) ([#251](https://github.com/klane/jekyllnb/pull/251)).
- Updated dependencies ([#251](https://github.com/klane/jekyllnb/pull/251), [#259](https://github.com/klane/jekyllnb/pull/259)).
- Removed `tox` as a dev dependency ([#251](https://github.com/klane/jekyllnb/pull/251)).
- Migrated code formatting and linting to ruff ([#251](https://github.com/klane/jekyllnb/pull/251)).
- Migrated code formatting and linting to `ruff` ([#251](https://github.com/klane/jekyllnb/pull/251)).
- Migrated type checking to `pyright` ([#259](https://github.com/klane/jekyllnb/pull/259)).
- Migrated project management to `uv` ([#259](https://github.com/klane/jekyllnb/pull/259)).
- Removed `pre-commit` as a dev dependency ([#259](https://github.com/klane/jekyllnb/pull/259)).

### Fixed

- Fixed CI pipelines that were broken due to the [deprecated `set-output` command](https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/) ([#251](https://github.com/klane/jekyllnb/pull/251)).
- Replaced `pytest-lazy-fixture` with `pytest-lazy-fixtures` since `pytest-lazy-fixture` [does not support `pytest` 8](https://github.com/TvoroG/pytest-lazy-fixture/issues/65) ([#251](https://github.com/klane/jekyllnb/pull/251), [#259](https://github.com/klane/jekyllnb/pull/259)).

## [0.3.1]

Expand Down
2 changes: 1 addition & 1 deletion jekyllnb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
from .exporter import JekyllExporter
from .preprocessor import JekyllPreprocessor

__all__ = ["__version__", "JekyllExporter", "JekyllPreprocessor"]
__all__ = ["JekyllExporter", "JekyllPreprocessor", "__version__"]
35 changes: 20 additions & 15 deletions jekyllnb/exporter.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
from collections.abc import ItemsView
from pathlib import Path
from typing import Any, Callable, ClassVar, Literal, Optional
from typing import Any, ClassVar, Literal, Optional

from nbconvert.exporters import MarkdownExporter
from nbconvert.filters.strings import path2url
from traitlets import default
from traitlets.config import Config
from typing_extensions import override


class JekyllExporter(MarkdownExporter):
"""Exporter to write Markdown with Jekyll metadata."""

# path to available template files
extra_template_basedirs: ClassVar[list[str]] = [
str(Path(__file__).parent / "templates")
]

# enabled preprocessors
preprocessors: ClassVar[list[str]] = ["jekyllnb.JekyllPreprocessor"]

# placeholder to store notebook resources
resources: ClassVar[dict[str, Any]] = {}

@override
def from_filename(
self, filename: str, resources: Optional[dict[str, Any]] = None, **kwargs
) -> tuple[str, dict[str, Any]]:
Expand All @@ -41,12 +36,22 @@ def from_filename(

return super().from_filename(filename, resources=resources, **kwargs)

@override
@default("extra_template_basedirs")
def _default_extra_template_basedirs(self) -> list[str]:
return [str(Path(__file__).parent / "templates")]

@default("preprocessors")
def _default_preprocessors(self) -> list[Any]:
return ["jekyllnb.JekyllPreprocessor"]

@default("template_name")
def _template_name_default(self) -> Literal["jekyll"]:
def _default_template_name(self) -> Literal["jekyll"]:
"""Specify default template name."""
return "jekyll"

@property
@override
def default_config(self) -> Config:
"""Specify default configuration."""
config = Config({"JekyllPreprocessor": {"enabled": True}})
Expand All @@ -62,10 +67,10 @@ def _jekyll_path(self, path: str) -> str:

return f"{{{{ site.baseurl }}}}/{path2url(path)}"

def default_filters(self) -> list[tuple[str, Callable]]:
@override
def default_filters(self) -> ItemsView[str, Any]: # type:ignore[override]
"""Specify default filters."""
# convert image path to one compatible with Jekyll
return [
*super().default_filters(),
("jekyllpath", self._jekyll_path),
]
filters = dict(super().default_filters())
filters["jekyllpath"] = self._jekyll_path
return filters.items()
11 changes: 8 additions & 3 deletions jekyllnb/jekyllnb.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
from typing import Any, Literal, Optional

from nbconvert.nbconvertapp import NbConvertApp, nbconvert_aliases, nbconvert_flags
from nbconvert.writers.files import FilesWriter
from traitlets import Bool, Unicode, default, observe
from traitlets.config import catch_config_error
from typing_extensions import override

from .__version__ import __version__

Expand Down Expand Up @@ -48,31 +50,34 @@ class JekyllNB(NbConvertApp):
).tag(config=True)

@default("export_format")
def _export_format_default(self) -> Literal["jekyll"]:
def _default_export_format(self) -> Literal["jekyll"]:
"""Specify default export format."""
return "jekyll"

@observe("export_format")
def _export_format_changed(self, change: dict[str, Any]) -> None:
"""Ensure export format is jekyll."""
default_format = self._export_format_default()
default_format = self._default_export_format()

if change["new"].lower() != default_format:
raise ValueError(
f"Invalid export format {change['new']}, value must be {default_format}"
)

@override
@catch_config_error
def initialize(self, argv: Optional[Any] = None) -> None:
"""Initialize application, notebooks, writer, and postprocessor."""
super().initialize(argv)
self.writer.build_directory = os.path.join(self.site_dir, self.page_dir)
if isinstance(self.writer, FilesWriter):
self.writer.build_directory = os.path.join(self.site_dir, self.page_dir)

if self.auto_folder:
self.output_files_dir = os.path.join(
super().output_files_dir, "{notebook_name}"
)

@override
def init_single_notebook_resources(self, notebook_filename: str) -> dict[str, Any]:
"""Initialize resources.

Expand Down
2 changes: 2 additions & 0 deletions jekyllnb/preprocessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

from nbconvert.preprocessors import Preprocessor
from nbformat import NotebookNode
from typing_extensions import override


class JekyllPreprocessor(Preprocessor):
"""Preprocessor to add Jekyll metadata."""

@override
def preprocess(
self, nb: NotebookNode, resources: dict[str, Any]
) -> tuple[NotebookNode, dict[str, Any]]:
Expand Down
Loading
Loading