Skip to content

Commit 9e7cb36

Browse files
committed
fixes #1559
1 parent 2ae3616 commit 9e7cb36

File tree

7 files changed

+105
-42
lines changed

7 files changed

+105
-42
lines changed

nbdev/_modidx.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@
164164
'nbdev.migrate._fp_fm': ('api/migrate.html#_fp_fm', 'nbdev/migrate.py'),
165165
'nbdev.migrate._fp_image': ('api/migrate.html#_fp_image', 'nbdev/migrate.py'),
166166
'nbdev.migrate._is_jekyll_post': ('api/migrate.html#_is_jekyll_post', 'nbdev/migrate.py'),
167+
'nbdev.migrate._migrate_workflows': ('api/migrate.html#_migrate_workflows', 'nbdev/migrate.py'),
167168
'nbdev.migrate._nbdev_migrate_config': ('api/migrate.html#_nbdev_migrate_config', 'nbdev/migrate.py'),
168169
'nbdev.migrate._py_val': ('api/migrate.html#_py_val', 'nbdev/migrate.py'),
169170
'nbdev.migrate._re_v1': ('api/migrate.html#_re_v1', 'nbdev/migrate.py'),

nbdev/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ def get_config(path=None, also_settings=False):
227227
# Check for old settings.ini and complain loudly
228228
old_cfg = cfg_file.parent / 'settings.ini'
229229
if old_cfg.exists() and not also_settings:
230-
raise ValueError(f"Found old settings.ini at {old_cfg}. Please migrate to pyproject.toml using `nbdev_migrate`")
230+
raise ValueError(f"Found old settings.ini at {old_cfg}. Please migrate to pyproject.toml using `nbdev_migrate`. See https://nbdev.fast.ai/getting_started.html for details.")
231231
d = _load_toml(cfg_file)
232232
user = _user_config()
233233
nbdev = {**user, **d.get('tool', {}).get('nbdev', {})}

nbdev/migrate.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,20 @@ def nbdev_migrate(
183183
# %% ../nbs/api/16_migrate.ipynb #ad76e503
184184
_license_map = {'apache2': 'Apache-2.0', 'mit': 'MIT', 'gpl2': 'GPL-2.0', 'gpl3': 'GPL-3.0', 'bsd3': 'BSD-3-Clause'}
185185

186+
# %% ../nbs/api/16_migrate.ipynb #7647b587
187+
def _migrate_workflows(path):
188+
"Update GitHub workflow files to use nbdev3 workflows"
189+
wf_path = Path(path) / '.github/workflows'
190+
if not wf_path.exists(): return
191+
replacements = [
192+
('fastai/workflows/quarto-ghp@', 'fastai/workflows/quarto-ghp3@'),
193+
('fastai/workflows/nbdev-ci@', 'fastai/workflows/nbdev-ci3@'),
194+
]
195+
for f in wf_path.glob('*.yml'):
196+
txt = f.read_text()
197+
for old, new in replacements: txt = txt.replace(old, new)
198+
f.write_text(txt)
199+
186200
# %% ../nbs/api/16_migrate.ipynb #1ca2d1b3
187201
def _toml_val(v):
188202
if v.lower() in ('true','false'): return v.lower()
@@ -245,6 +259,7 @@ def _nbdev_migrate_config(d, path): # Config dict from settings.ini
245259
if nbdev_settings:
246260
nbdev_toml = '\n'.join(f'{k} = {_toml_val(v)}' for k,v in nbdev_settings.items())
247261
txt = txt.rstrip() + '\n' + nbdev_toml + '\n'
262+
_migrate_workflows(path)
248263
return txt
249264

250265
# %% ../nbs/api/16_migrate.ipynb #a9534478

nbs/api/01_config.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@
439439
" # Check for old settings.ini and complain loudly\n",
440440
" old_cfg = cfg_file.parent / 'settings.ini'\n",
441441
" if old_cfg.exists() and not also_settings:\n",
442-
" raise ValueError(f\"Found old settings.ini at {old_cfg}. Please migrate to pyproject.toml using `nbdev_migrate`\")\n",
442+
" raise ValueError(f\"Found old settings.ini at {old_cfg}. Please migrate to pyproject.toml using `nbdev_migrate`. See https://nbdev.fast.ai/getting_started.html for details.\")\n",
443443
" d = _load_toml(cfg_file)\n",
444444
" user = _user_config()\n",
445445
" nbdev = {**user, **d.get('tool', {}).get('nbdev', {})}\n",

nbs/api/16_migrate.ipynb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,28 @@
11621162
"_license_map = {'apache2': 'Apache-2.0', 'mit': 'MIT', 'gpl2': 'GPL-2.0', 'gpl3': 'GPL-3.0', 'bsd3': 'BSD-3-Clause'}"
11631163
]
11641164
},
1165+
{
1166+
"cell_type": "code",
1167+
"execution_count": null,
1168+
"id": "7647b587",
1169+
"metadata": {},
1170+
"outputs": [],
1171+
"source": [
1172+
"#| export\n",
1173+
"def _migrate_workflows(path):\n",
1174+
" \"Update GitHub workflow files to use nbdev3 workflows\"\n",
1175+
" wf_path = Path(path) / '.github/workflows'\n",
1176+
" if not wf_path.exists(): return\n",
1177+
" replacements = [\n",
1178+
" ('fastai/workflows/quarto-ghp@', 'fastai/workflows/quarto-ghp3@'),\n",
1179+
" ('fastai/workflows/nbdev-ci@', 'fastai/workflows/nbdev-ci3@'),\n",
1180+
" ]\n",
1181+
" for f in wf_path.glob('*.yml'):\n",
1182+
" txt = f.read_text()\n",
1183+
" for old, new in replacements: txt = txt.replace(old, new)\n",
1184+
" f.write_text(txt)"
1185+
]
1186+
},
11651187
{
11661188
"cell_type": "code",
11671189
"execution_count": null,
@@ -1239,6 +1261,7 @@
12391261
" if nbdev_settings:\n",
12401262
" nbdev_toml = '\\n'.join(f'{k} = {_toml_val(v)}' for k,v in nbdev_settings.items())\n",
12411263
" txt = txt.rstrip() + '\\n' + nbdev_toml + '\\n'\n",
1264+
" _migrate_workflows(path)\n",
12421265
" return txt"
12431266
]
12441267
},

nbs/getting_started.ipynb

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@
2222
":::"
2323
]
2424
},
25+
{
26+
"cell_type": "markdown",
27+
"id": "b56fe3f2",
28+
"metadata": {},
29+
"source": [
30+
"## 🛑**Jan 2026 Major Version Update -- Breaking Change**🛑\n",
31+
"\n",
32+
"**nbdev3 is here!** As many of you have been requesting, configuration has moved from `settings.ini` to `pyproject.toml`, following modern Python packaging standards ([PEP 621](https://peps.python.org/pep-0621/)). Your project metadata now lives in the standard `[project]` section, while nbdev-specific settings go in `[tool.nbdev]`.\n",
33+
"\n",
34+
"**Migrating from nbdev2:** Run `nbdev_migrate_config` in your project root to automatically convert your `settings.ini` to `pyproject.toml` and update your GitHub Actions workflows to use nbdev3-compatible versions. Your existing notebooks and code don't need any changes."
35+
]
36+
},
2537
{
2638
"cell_type": "markdown",
2739
"id": "c512bf61",
@@ -67,12 +79,6 @@
6779
"pip install nbdev\n",
6880
"```\n",
6981
"\n",
70-
"... or with conda (or mamba):\n",
71-
"\n",
72-
"```sh\n",
73-
"conda install -c fastai nbdev\n",
74-
"```\n",
75-
"\n",
7682
"Note that `nbdev` must be installed into the same Python environment that you use for both Jupyter and your project."
7783
]
7884
},
@@ -142,36 +148,40 @@
142148
"name": "stdout",
143149
"output_type": "stream",
144150
"text": [
145-
"\u001b[1m\u001b[94mnbdev_bump_version\u001b[22m\u001b[39m Increment version in settings.ini by one\n",
146-
"\u001b[1m\u001b[94mnbdev_changelog\u001b[22m\u001b[39m Create a CHANGELOG.md file from closed and labeled GitHub issues\n",
147-
"\u001b[1m\u001b[94mnbdev_clean\u001b[22m\u001b[39m Clean all notebooks in `fname` to avoid merge conflicts\n",
148-
"\u001b[1m\u001b[94mnbdev_conda\u001b[22m\u001b[39m Create a `meta.yaml` file ready to be built into a package, and optionally build and upload it\n",
149-
"\u001b[1m\u001b[94mnbdev_create_config\u001b[22m\u001b[39m Create a config file.\n",
150-
"\u001b[1m\u001b[94mnbdev_docs\u001b[22m\u001b[39m Create Quarto docs and README.md\n",
151-
"\u001b[1m\u001b[94mnbdev_export\u001b[22m\u001b[39m Export notebooks in `path` to Python modules\n",
152-
"\u001b[1m\u001b[94mnbdev_filter\u001b[22m\u001b[39m A notebook filter for Quarto\n",
153-
"\u001b[1m\u001b[94mnbdev_fix\u001b[22m\u001b[39m Create working notebook from conflicted notebook `nbname`\n",
154-
"\u001b[1m\u001b[94mnbdev_help\u001b[22m\u001b[39m Show help for all console scripts\n",
155-
"\u001b[1m\u001b[94mnbdev_install\u001b[22m\u001b[39m Install Quarto and the current library\n",
156-
"\u001b[1m\u001b[94mnbdev_install_hooks\u001b[22m\u001b[39m Install Jupyter and git hooks to automatically clean, trust, and fix merge conflicts in notebooks\n",
157-
"\u001b[1m\u001b[94mnbdev_install_quarto\u001b[22m\u001b[39m Install latest Quarto on macOS or Linux, prints instructions for Windows\n",
158-
"\u001b[1m\u001b[94mnbdev_merge\u001b[22m\u001b[39m Git merge driver for notebooks\n",
159-
"\u001b[1m\u001b[94mnbdev_migrate\u001b[22m\u001b[39m Convert all markdown and notebook files in `path` from v1 to v2\n",
160-
"\u001b[1m\u001b[94mnbdev_new\u001b[22m\u001b[39m Create an nbdev project.\n",
161-
"\u001b[1m\u001b[94mnbdev_prepare\u001b[22m\u001b[39m Export, test, and clean notebooks, and render README if needed\n",
162-
"\u001b[1m\u001b[94mnbdev_preview\u001b[22m\u001b[39m Preview docs locally\n",
163-
"\u001b[1m\u001b[94mnbdev_proc_nbs\u001b[22m\u001b[39m Process notebooks in `path` for docs rendering\n",
164-
"\u001b[1m\u001b[94mnbdev_pypi\u001b[22m\u001b[39m Create and upload Python package to PyPI\n",
165-
"\u001b[1m\u001b[94mnbdev_readme\u001b[22m\u001b[39m Create README.md from readme_nb (index.ipynb by default)\n",
166-
"\u001b[1m\u001b[94mnbdev_release_both\u001b[22m\u001b[39m Release both conda and PyPI packages\n",
167-
"\u001b[1m\u001b[94mnbdev_release_gh\u001b[22m\u001b[39m Calls `nbdev_changelog`, lets you edit the result, then pushes to git and calls `nbdev_release_git`\n",
168-
"\u001b[1m\u001b[94mnbdev_release_git\u001b[22m\u001b[39m Tag and create a release in GitHub for the current version\n",
169-
"\u001b[1m\u001b[94mnbdev_requirements\u001b[22m\u001b[39m Writes a `requirements.txt` file to `directory` based on settings.ini.\n",
170-
"\u001b[1m\u001b[94mnbdev_sidebar\u001b[22m\u001b[39m Create sidebar.yml\n",
171-
"\u001b[1m\u001b[94mnbdev_test\u001b[22m\u001b[39m Test in parallel notebooks matching `path`, passing along `flags`\n",
172-
"\u001b[1m\u001b[94mnbdev_trust\u001b[22m\u001b[39m Trust notebooks matching `fname`\n",
173-
"\u001b[1m\u001b[94mnbdev_update\u001b[22m\u001b[39m Propagate change in modules matching `fname` to notebooks that created them\n",
174-
"\u001b[1m\u001b[94mnbdev_update_license\u001b[22m\u001b[39m Allows you to update the license of your project.\n"
151+
"\u001b[1m\u001b[94mnb_export\u001b[22m\u001b[39m Export a single nbdev notebook to a python script.\r\n",
152+
"\u001b[1m\u001b[94mnbdev_bump_version\u001b[22m\u001b[39m Increment version in __init__.py by one\r\n",
153+
"\u001b[1m\u001b[94mnbdev_changelog\u001b[22m\u001b[39m Create a CHANGELOG.md file from closed and labeled GitHub issues\r\n",
154+
"\u001b[1m\u001b[94mnbdev_clean\u001b[22m\u001b[39m Clean all notebooks in `fname` to avoid merge conflicts\r\n",
155+
"\u001b[1m\u001b[94mnbdev_conda\u001b[22m\u001b[39m Create a `meta.yaml` file ready to be built into a package, and optionally build and upload it\r\n",
156+
"\u001b[1m\u001b[94mnbdev_contributing\u001b[22m\u001b[39m Create CONTRIBUTING.md from contributing_nb (defaults to 'contributing.ipynb' if present). Skips if the file doesn't exist.\r\n",
157+
"\u001b[1m\u001b[94mnbdev_create_config\u001b[22m\u001b[39m Create a pyproject.toml config file.\r\n",
158+
"\u001b[1m\u001b[94mnbdev_docs\u001b[22m\u001b[39m Create Quarto docs and README.md\r\n",
159+
"\u001b[1m\u001b[94mnbdev_export\u001b[22m\u001b[39m Export notebooks in `path` to Python modules\r\n",
160+
"\u001b[1m\u001b[94mnbdev_filter\u001b[22m\u001b[39m A notebook filter for Quarto\r\n",
161+
"\u001b[1m\u001b[94mnbdev_fix\u001b[22m\u001b[39m Create working notebook from conflicted notebook `nbname`\r\n",
162+
"\u001b[1m\u001b[94mnbdev_help\u001b[22m\u001b[39m Show help for all console scripts\r\n",
163+
"\u001b[1m\u001b[94mnbdev_install\u001b[22m\u001b[39m Install Quarto and the current library\r\n",
164+
"\u001b[1m\u001b[94mnbdev_install_hooks\u001b[22m\u001b[39m Install Jupyter and git hooks to automatically clean, trust, and fix merge conflicts in notebooks\r\n",
165+
"\u001b[1m\u001b[94mnbdev_install_quarto\u001b[22m\u001b[39m Install latest Quarto on macOS or Linux, prints instructions for Windows\r\n",
166+
"\u001b[1m\u001b[94mnbdev_merge\u001b[22m\u001b[39m Git merge driver for notebooks\r\n",
167+
"\u001b[1m\u001b[94mnbdev_migrate\u001b[22m\u001b[39m Convert all markdown and notebook files in `path` from v1 to v2\r\n",
168+
"\u001b[1m\u001b[94mnbdev_migrate_config\u001b[22m\u001b[39m Migrate settings.ini to pyproject.toml\r\n",
169+
"\u001b[1m\u001b[94mnbdev_new\u001b[22m\u001b[39m Create an nbdev project.\r\n",
170+
"\u001b[1m\u001b[94mnbdev_prepare\u001b[22m\u001b[39m Export, test, and clean notebooks, and render README if needed\r\n",
171+
"\u001b[1m\u001b[94mnbdev_preview\u001b[22m\u001b[39m Preview docs locally\r\n",
172+
"\u001b[1m\u001b[94mnbdev_proc_nbs\u001b[22m\u001b[39m Process notebooks in `path` for docs rendering\r\n",
173+
"\u001b[1m\u001b[94mnbdev_pypi\u001b[22m\u001b[39m Create and upload Python package to PyPI\r\n",
174+
"\u001b[1m\u001b[94mnbdev_readme\u001b[22m\u001b[39m Create README.md from readme_nb (index.ipynb by default)\r\n",
175+
"\u001b[1m\u001b[94mnbdev_release_both\u001b[22m\u001b[39m Release both conda and PyPI packages\r\n",
176+
"\u001b[1m\u001b[94mnbdev_release_gh\u001b[22m\u001b[39m Calls `nbdev_changelog`, lets you edit the result, then pushes to git and calls `nbdev_release_git`\r\n",
177+
"\u001b[1m\u001b[94mnbdev_release_git\u001b[22m\u001b[39m Tag and create a release in GitHub for the current version\r\n",
178+
"\u001b[1m\u001b[94mnbdev_requirements\u001b[22m\u001b[39m Writes a `requirements.txt` file to `directory` based on pyproject.toml.\r\n",
179+
"\u001b[1m\u001b[94mnbdev_sidebar\u001b[22m\u001b[39m Create sidebar.yml\r\n",
180+
"\u001b[1m\u001b[94mnbdev_test\u001b[22m\u001b[39m Test in parallel notebooks matching `path`, passing along `flags`\r\n",
181+
"\u001b[1m\u001b[94mnbdev_trust\u001b[22m\u001b[39m Trust notebooks matching `fname`.\r\n",
182+
"\u001b[1m\u001b[94mnbdev_update\u001b[22m\u001b[39m Propagate change in modules matching `fname` to notebooks that created them\r\n",
183+
"\u001b[1m\u001b[94mnbdev_update_license\u001b[22m\u001b[39m Allows you to update the license of your project.\r\n",
184+
"\u001b[1m\u001b[94mwatch_export\u001b[22m\u001b[39m Use `nb_export` on ipynb files in `nbs` directory on changes using nbdev config if available\r\n"
175185
]
176186
}
177187
],

nbs/tutorials/migrating.ipynb

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,34 @@
1414
},
1515
{
1616
"cell_type": "markdown",
17-
"id": "9a3e390f",
17+
"id": "f091724e",
1818
"metadata": {},
1919
"source": [
20-
"nbdev v2 is a new from-scratch rewrite of nbdev that's not backwards compatible. This page describes the changes you need to make to upgrade your nbdev v1 repo to work with the new version. The steps shown here should work on macOS or Linux (including Windows WSL)\n",
20+
"## 🛑**Jan 2026 Major Version Update -- Breaking Change**🛑\n",
2121
"\n",
22-
"The biggest change is that nbdev2 uses [Quarto](https://quarto.org/) to generate your website, whereas nbdev1 used nbconvert and jekyll. You can use all of Quarto's features directly in nbdev, so checkout the Quarto website to see all the amazing functionality it supports."
22+
"**nbdev3 is here!** As many of you have been requesting, configuration has moved from `settings.ini` to `pyproject.toml`, following modern Python packaging standards ([PEP 621](https://peps.python.org/pep-0621/)). Your project metadata now lives in the standard `[project]` section, while nbdev-specific settings go in `[tool.nbdev]`.\n",
23+
"\n",
24+
"**Migrating from nbdev2:** Run `nbdev_migrate_config` in your project root to automatically convert your `settings.ini` to `pyproject.toml` and update your GitHub Actions workflows to use nbdev3-compatible versions. Your existing notebooks and code don't need any changes.\n",
25+
"\n",
26+
"**Status of this document:** The rest of this doc describes migration from the *very* old nbdev1 to nbdev2, and is not likely to be relevant to most folks who haven't been frozen in tundra for the last few years."
2327
]
2428
},
2529
{
2630
"cell_type": "markdown",
2731
"id": "df136f1c",
2832
"metadata": {},
2933
"source": [
30-
"## Initial setup"
34+
"## Nbdev2 - Initial setup"
35+
]
36+
},
37+
{
38+
"cell_type": "markdown",
39+
"id": "130d9727",
40+
"metadata": {},
41+
"source": [
42+
"nbdev v2 is a new from-scratch rewrite of nbdev that's not backwards compatible. This page describes the changes you need to make to upgrade your nbdev v1 repo to work with the new version. The steps shown here should work on macOS or Linux (including Windows WSL)\n",
43+
"\n",
44+
"The biggest change is that nbdev2 uses [Quarto](https://quarto.org/) to generate your website, whereas nbdev1 used nbconvert and jekyll. You can use all of Quarto's features directly in nbdev, so checkout the Quarto website to see all the amazing functionality it supports."
3145
]
3246
},
3347
{

0 commit comments

Comments
 (0)