Migrations & Updates
This upgrade brings a couple of changes:
- Permission update to allow curators more rights
- Share button added to deposition form
- Authentication interface for providers (for Kerberos support planned for v14)
- Unified facets for several search pages
- Support for extra checks (integrating invenio-checks), including AI-based checks
- Citation updates (InvenioRDM)
- New metadata.description field with its future mapping to CCMM descriptions fields
- Refactored configuration to oarepo_config
| Affected | Not affected |
|---|---|
Repositories on oarepo-app <= 6.2.0 upgrading to 6.3.0 | Repositories already on oarepo-app >= 6.3.0 |
Show migration steps
- Inside
invenio.cfg, locatefrom oarepo import configand replace it withimport oarepo_config as config - Inside pyproject.toml, change the dependency from
oarepo-app==6.2.0tooarepo-app==6.3.0 - Run
./run.sh upgradeto bring in new libraries - Run
./run.sh invenio rdm rebuild-all-indices
This upgrade moves a repository across the 5.0.0, 6.0.0, 6.1.0 and 6.2.0 releases in a single step. For the full list of package changes, see the oarepo-app changelog . The largest change is the Invenio major-version bump that ships with oarepo-app 6.0.0 (invenio-rdm-records 28.x → 32.x, invenio-communities 26.x → 28.x), which brings database migrations and changed search mappings. Repositories generated from nrp-app-copier use the stable oarepo.config and oarepo_workflows APIs, and the generated model UI (templates, React/JS imports and Python UI component imports) is compatible with the new oarepo-ui and oarepo-rdm versions, so no code changes are required — only a dependency bump, a database migration and an index rebuild.
| Affected | Not affected |
|---|---|
Repositories on oarepo-app == 4.0.0 upgrading to 6.2.0 | Repositories already on oarepo-app >= 6.0.0 |
Repositories that catch MissingCommunitiesError or MissingDefaultCommunityError from community permission generators | Standard nrp-app-copier generated repositories (they do not catch these exceptions) |
Show migration steps
1. Update pyproject.toml
Bump the oarepo-app dependency to 6.2.0. If your dependency is a range such as oarepo-app[production,ccmm]>=2.0.1,<3.0.0, replace it with an exact pin.
Before:
dependencies = [
"oarepo[s3,rdm]>=14.0.0b1,<15.0.0",
"oarepo-app[production,ccmm]==4.0.0",
]After:
dependencies = [
"oarepo[s3,rdm]>=14.0.0b1,<15.0.0",
"oarepo-app[production,ccmm]==6.2.0",
]The oarepo[s3,rdm] line needs no change — its range already covers the oarepo version pulled in by the production extra. The production extra now also includes oarepo-related-resources, so that package is installed automatically.
2. Reinstall and reinitialize the database and index
The invenio-rdm-records major bump changed the database schema and the search mappings, so the database and indices need to be brought in line with the new versions. Follow Database and index reinitialization:
- Local development:
./run.sh reset— wipes all data and performs a full reinstall and reinitialization in one step. It includes the reinstall that./run.sh upgradedoes, so no separate upgrade is needed. - Production: reinstall, then migrate the database and rebuild the index to preserve data:
./run.sh upgrade # reinstall with the new versions ./run.sh invenio alembic upgrade # run database migrations ./run.sh index rebuild # drop, recreate and reindex OpenSearch ./run.sh run # so Celery workers process the reindex queue
The production Alembic migration procedure is still work in progress. See the ./run.sh reference for command details.
3. Review behavioral changes and new features
The upgrade introduces several behavioral changes that may affect your repository:
-
RDM file service configs now apply. Models using the RDM preset now use
RDMFileServiceandRDMFileServiceConfig(oarepo-rdm 8.1.0) instead of the baseFileService. This means RDM file-related configuration — such asRDM_RECORDS_MAX_FILES_COUNT(file count limit) — is now enforced. If your repository previously had no file count limits, review the RDM file config defaults and adjust if needed. -
PID/DOI field in the deposit form. The “General information” section of the deposit form now includes a PID/DOI field (via
RDMPIDsConfigComponent, oarepo-rdm 8.1.0). The field appears when DOI providers are configured. To disable it, either don’t configure DOI providers or override thePIDFieldoverridable component in your model’s deposit form. -
Export sidebar filters by
display. The export sidebar now only shows exporters wheredisplay=True(oarepo-ui 13.2.3). TheExportdataclass defaultsdisplay=True, so most exports are unaffected. But exports registered withdisplay=False(e.g., OAI-only exports) are no longer visible in the UI. To show an export, setdisplay=Trueon theExportinstance orAddMetadataExportcustomization in your model definition. -
ZIP content previewing (invenio-app-rdm 14.0.0rc2). ZIP files can now be browsed and their contents previewed inline. Enabled by default; controlled by
PREVIEWABLE_ZIP_PREVIEWER_NATIVE_EXTENSIONS(default["zip"]). No action needed unless you want to disable it. -
/uploads/newmodel selection page (oarepo-rdm 8.1.0). The/uploads/newroute now shows a model selection page when multiple models exist, or redirects directly when only one model exists. Additive; no action needed. -
RDM-specific behaviour moved out of
RecordsUIResource(oarepo-ui 13.0+). RDM-specific behaviour (defaultfiles.enabled,pidsinitialisation,APP_RDM_DEPOSIT_FORM_DEFAULTS, parent-DOI injection for preview, and DOI-required checks) was removed from the baseRecordsUIResourceinoarepo-uiand moved into separate UI components that ship withoarepo-rdm:FilesEnabledComponent,EmptyRecordPidsComponent,DepositFormDefaultsComponent,InjectParentDoiComponent,DoiRequiredComponent, andRDMPIDsConfigComponent. If your UI resource and config inherit directly from the genericRecordsUIResource/RecordsUIResourceConfig(inoarepo_ui.resources.records), the new-record form will silently lose default files/PIDs/DOI handling — you must switch your base class. Editui/<model_name>/__init__.py(for example,ui/datasets/__init__.py).For a CCMM-based model — inherit from
CCMMRecordsUIResourceConfigandCCMMRecordsUIResource, imported from:from ccmm_invenio.ui.config import CCMMRecordsUIResourceConfigfrom ccmm_invenio.ui.resource import CCMMRecordsUIResource
ui/<model_name>/__init__.py# Before from oarepo_ui.resources.records.config import RecordsUIResourceConfig from oarepo_ui.resources.records.resource import RecordsUIResource class DatasetsUIResourceConfig(RecordsUIResourceConfig): ... class DatasetsUIResource(RecordsUIResource): pass # After from ccmm_invenio.ui.config import CCMMRecordsUIResourceConfig from ccmm_invenio.ui.resource import CCMMRecordsUIResource class DatasetsUIResourceConfig(CCMMRecordsUIResourceConfig): ... class DatasetsUIResource(CCMMRecordsUIResource): passFor a plain RDM-based model — inherit from
RDMRecordsUIResourceConfigandRDMRecordsUIResource, imported from:from oarepo_rdm.ui.config import RDMRecordsUIResourceConfigfrom oarepo_rdm.ui.resource import RDMRecordsUIResource
ui/<model_name>/__init__.py# Before from oarepo_ui.resources.records.config import RecordsUIResourceConfig from oarepo_ui.resources.records.resource import RecordsUIResource class DatasetsUIResourceConfig(RecordsUIResourceConfig): ... class DatasetsUIResource(RecordsUIResource): pass # After from oarepo_rdm.ui.config import RDMRecordsUIResourceConfig from oarepo_rdm.ui.resource import RDMRecordsUIResource class DatasetsUIResourceConfig(RDMRecordsUIResourceConfig): ... class DatasetsUIResource(RDMRecordsUIResource): passIf you compose
componentsin your config, keep using*<NewBase>.componentsso the new RDM components are included. -
Search app: default two-column layout (oarepo-ui 13.0+, PR #460 ). The default search app layout changed for repositories whose search bar lives in the content area (not in the page header). The page is now rendered as a two-column layout: facets on the left, results on the right, with the search bar sitting in the right-hand column. If your repository keeps the search bar in the page header (Invenio’s default), the rendered page is unchanged and there is nothing to do.
Old layout (search bar in content):
New layout (search bar in content):
Several exported search components were renamed or removed:
ActiveFiltersElement→ActiveFilters,SearchAppResultOptions→ResultOptions,SearchAppSort→Sort;SearchAppLayoutWithSearchbarHOCandSearchAppResultViewWithSearchbarwere removed (useSearchAppLayoutdirectly). These changes only affect custom search code that imports the old component names directly — the copier-generatedsearch/index.jsis unaffected because it only usesparseSearchAppConfigsandcreateSearchAppsInit, which exist in both versions. AScroll to topbutton is now rendered by default; if you do not want it, hide it via CSS (#scroll-to-top-button { display: none; }). -
invenio_url_forandModel.api_urlno longer accept_external=True(oarepo-runtime 4.0.0+). Both helpers now always return an absolute (external) URL. Passing_external=Trueis no longer accepted and will raise (Model.api_urlcallsinvenio_url_forunder the hood and fails for the same reason). Drop_external=Truefrom these calls — the returned URL is already absolute.# Before url = invenio_url_for("vocabularies.search", type="languages", _external=True) api = model.api_url("search", type=alias, _external=True) # After url = invenio_url_for("vocabularies.search", type="languages") api = model.api_url("search", type=alias)
4. Review community permission exception handling
From oarepo-communities 8.1.3 (shipped with oarepo-app 5.0.0) and 9.0.0 (shipped with oarepo-app 6.2.0), the community permission generators no longer raise MissingCommunitiesError or MissingDefaultCommunityError — they return an empty list instead. Both exception classes are deprecated — their constructors emit a DeprecationWarning.
If your code catches these exceptions, that branch is now dead code. Review and update it:
# These are deprecated and no longer raised by the community permission
# generators (OARepoCommunityRoles etc. return [] instead).
from oarepo_communities.errors import (
MissingCommunitiesError, # deprecated
MissingDefaultCommunityError, # deprecated
)
# Any branch like this is now dead code:
# except MissingCommunitiesError: ...
# Handle the empty-list case directly instead.Standard nrp-app-copier generated repositories do not catch these exceptions, so no action is needed for them.
5. Consider migrating to the simplified workflows
See simplified workflows for a more streamlined approach to workflow configuration.
In oarepo-app v4.0.0, CCMM dependencies were moved to a separate optional dependency extra. Repositories that use CCMM must enable the ccmm extra explicitly.
| Affected | Not affected |
|---|---|
| Repositories using CCMM | Repositories not using CCMM |
Repositories upgrading to oarepo-app >= 4.0.0 | Repositories using older oarepo-app versions |
Show migration steps
Update pyproject.toml
In pyproject.toml, update the oarepo-app dependency extra from production to production,ccmm.
Before:
dependencies = [
"oarepo-app[production]==4.0.0",
]After:
dependencies = [
"oarepo-app[production,ccmm]==4.0.0",
]Run ./run.sh upgrade to update the lock file.
This breaking change introduces the oarepo-app library in version 2.3.0. This release includes all Invenio changes released before 2026-05-01, including the introduction of CCMM vocabularies.
| Affected | Not affected |
|---|---|
| Repositories created before 2026-05-11 | Repositories created after 2026-05-11 |
Repositories using oarepo-app <= 2.3.0, or not using oarepo-app at all | --- |
Show migration steps
Update pyproject.toml
- In
pyproject.toml, remove alloarepo-*dependencies and replace them with the newoarepo-applibrary. Do not remove theoarepo[s3,rdm]dependency.
Before:
dependencies = [
"oarepo[s3,rdm]>=14.0.0,<14.1.9",
"oarepo-runtime>=2.0.0dev0,<3.0.0",
"oarepo-ui>=7.0.0dev0,<8.0.0",
...
]After:
dependencies = [
"oarepo[s3,rdm]>=14.2.1b10.dev6,<15.0.0",
"oarepo-app[production]==2.3.0", # <---- here
]- Update the version of the
oarepolibrary:
dependencies = [
"oarepo[s3,rdm]>=14.2.1b10.dev6,<15.0.0", # <---- here
"oarepo-app[production]==2.3.0",
]- Make sure you use Python 3.14 in the
requires-pythonsection.
requires-python = ">=3.14,<3.15"-
Remove the top-level
package.jsonif it exists. -
Run
./run.sh upgradeto update the lock file. -
Run
./run.sh resetto reset your local instance because of the CCMM vocabularies. -
If you have sample data, you will need to update it to use CCMM vocabularies. See your
https://127.0.0.1:5000/vocabularieswhich values are permitted.For example:
- Change the resource type ID from
datasettoc_ddb1. - Change the
createdtime reference toCreated(capitalized first letter). - Change the
cc0-1.0license toCC0-1.0(capitalizedCC).
- Change the resource type ID from
For inspiration, see invenio-fzu PR #22
If you are already running a production instance, please contact us first.
Make sure you have run the older migrations first.
The model create command now places the backend part of new models inside a models/ folder
(e.g. models/datasets/) instead of creating them as top-level directories (e.g. datasets/).
This keeps the repository structure cleaner as the number of models grows. New models are placed under models/ automatically, so no action is needed for them — the steps below only apply to existing models that still live at the repository root.
Existing repositories with models already at the top level will continue to work.
However, for a consistent folder structure we recommend moving existing models into models/ as well.
| Affected | Not affected |
|---|---|
| Repositories with models created at the top level before 2026-04-15 | Newly created repositories |
| Repositories adding new models alongside existing top-level models | Repositories with no models yet |
Show migration steps
1. Move existing top-level models into models/
mv datasets models/Repeat for every model that currently lives at the repository root.
2. Update invenio.cfg
Update the model import paths. For example, if you have a model called datasets:
# Before
from datasets import datasets_model
datasets_model.register()
# After
from models.datasets import datasets_model
datasets_model.register()3. Update pyproject.toml
In the module-name section of pyproject.toml, remove the entry for the model folder you just moved
(e.g. remove datasets). The model is now discovered from models/ automatically.
oarepo-ui v7.0+ package requires base template files in your model’s UI module. These templates must extend the oarepo-ui base templates. See Record landing page documentation for the complete template inheritance flow.
| Affected | Not affected |
|---|---|
| Model UIs created before 2026-02-18 | Model UIs generated after 2026-02-18 |
| Using default templates | Custom page templates configured |
| oarepo-ui >= 7.0 | older versions |
Show migration steps
Option 1: Use model update (Recommended)
Run the model update command from your repository root:
./run.sh model update <model_name>Option 2: Create files manually
If you prefer not to use model update, you can create the required template files manually in ui/mymodel/templates/semantic-ui/mymodel/. See the model copier template for the complete list of required files.
Common issues:
TemplateNotFound: mymodel/record_detail.html→ Create base template file- Partials not showing → Check that
mymodel/record_detail/main.htmlexist