* feat: use new version of openedx-core
* feat: Use openedx_catalog app, backfill it with all known courses
* feat: properly set "created" timestamp on course runs during backfill
* fix: better normalization of language codes
* feat: keep courses in sync with CourseRun/CatalogCourse
* feat: delete CourseRun/CatalogCourse when deleting a course
* refactor: course_id -> course_key, run -> run_code, display_name -> title
* fix: don't use SplitModulestoreCourseIndex for getting list of all courses
* feat: add ruff and configure it to match current pycodestyle rules
Adds ruff to testing requirements and configures it in pyproject.toml
to enforce the same E/W rules that pycodestyle 2.8.x was enforcing.
Two additional rules (E714, E721) that pycodestyle 2.8.x did not enforce
are explicitly ignored for now and can be cleaned up in a follow-up.
Part of the migration from pycodestyle → ruff.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add ruff Makefile target
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add ruff to quality CI workflow alongside pycodestyle
Runs ruff alongside pycodestyle so we can validate parity before
removing pycodestyle in the next commit.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: remove pycodestyle, replaced by ruff
- Remove pycodestyle from requirements
- Remove pycodestyle version constraint (pinned to <2.9.0 due to a
false positive E275 bug that is no longer relevant)
- Remove [pycodestyle] config from setup.cfg (config now lives in
pyproject.toml under [tool.ruff])
- Remove pycodestyle Makefile target
- Remove make pycodestyle from quality CI workflow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* style: Apply suggestions from code review
Remove unnecessary ignores.
Co-authored-by: Braden MacDonald <braden@opencraft.com>
* style: Fix a style isusue and remove ignores.
Most of these ignores are unnecessary as we're passing them now and we
want to check them in the future. E714 only had one fixable violation so
we just fixed it.
* style: Update ruff config and workflows
* Update the call to `ruff` so that it outputs in a github friendly
manner.
* Remove ruff exclusions that are already covered by .gitignore which
ruff respects.
* chore: Recompile requirements.
Update the requirements to drop pycodestyle and add ruff.
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
In karma 6, files matched by earlier patterns aren't overridden by later
patterns. The sourceFiles patterns like `cms/**/!(*spec|djangojs).js`
matched test entry files (e.g., `cms/js/spec/main.js`) because they
don't end with "spec" or "djangojs". This prevented runFiles from
setting `included: true` on these files, so tests never started.
Split the sourceFiles patterns to precisely exclude spec/main*.js test
entry points while still serving other source files:
- Direct children of the js directory
- Subdirectories except spec/
- spec/ subdirectory, excluding main* files
This allows runFiles to control test entry point inclusion.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update documentation, comments, and docstrings throughout the codebase
to reflect the migration from setup.py to pyproject.toml:
- Transformer class docstrings: changed to reference "entry point name
in the package configuration" for better future-proofing
- Block structure module docs: updated to reference pyproject.toml
- Test file comments: updated entry point references
- Config files (tox.ini, pytest.ini): updated references
- Documentation (extension_points.rst, course apps ADRs): updated to
reference pyproject.toml with inclusive language for external packages
- Requirements documentation (github.in): updated with inclusive language
- edxmako README: modernized install command to use pip install
Historical ADRs and references to external packages that may still use
setup.py were intentionally left unchanged or updated with inclusive
language acknowledging both pyproject.toml and setup.py.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The legacy video uploads page in Studio has been replaced with a new
view in the Authoring MFE. The legacy page has not been available for
some time, so it's all dead code. This PR removes it.
Please note that there's a waffle flag which enables the MFE version
of the video uploads page: `contentstore.new_studio_mfe.use_new_video_uploads_page`.
Unlike the other Studio MFE waffles, we're NOT going to remove this one now,
because the video uploads page has always been broken for sites other
than edx.org (or sites that have reverse-engineered their video pipeline) so
we'd like to keep the flag until it's either fixed for the community or
removed (https://github.com/openedx/openedx-platform/issues/37972).
This work is part of https://github.com/openedx/edx-platform/issues/36108
Co-Authored-By: Kyle McCormick <kyle@axim.org>
BREAKING CHANGE: this forces course IDs in modulestore to be unique (case insensitive). This was always supposed to be the case, but it wasn't working properly on MySQL. Upgrading past this commit may cause a migration failure if you have conflicting course IDs - see the migration 0004 docstring for details.
refactor: remove some 'max_length=255' to be more DRY
feat: example of making an OpaqueKeyField case_sensitive (modulestore_migrator)
test: update test now that we're using case-insensitive collation on SQLite
Update our calls to the openedx_content API to reflect 0.35.0's shift
in terminology from "contents" to "media".
---------
Co-authored-by: Kyle McCormick <kyle@axim.org>
build!: Switch to openedx-core (renamed from openedx-learning)
Instead of installing openedx-learning==0.32.0, we install openedx-core==0.34.1.
We update various class names, function names, docstrings, and comments to
represent the rename:
* We say "openedx-core" when referring to the whole repo or PyPI project
* or occasionally "Open edX Core" if we want it to look nice in the docs.
* We say "openedx_content" to refer to the Content API within openedx-core,
which is actually the thing we have been calling "Learning Core" all along.
* In snake-case code, it's `*_openedx_content_*`.
* In camel-case code, it's `*OpenedXContent*`
For consistency's sake we avoid anything else like oex_core, OeXCore,
OpenEdXCore, OexContent, openedx-content, OpenEdxContent, etc.
There should be no more references to learning_core, learning-core, Learning Core,
Learning-Core, LC, openedx-learning, openedx_learning, etc.
BREAKING CHANGE: for openedx-learning/openedx-core developers:
You may need to uninstall openedx-learning and re-install openedx-core
from your venv. If running tutor, you may need to un-mount openedx-learning,
rename the directory to openedx-core, re-mount it, and re-build.
The code APIs themselves are fully backwards-compatible.
Part of: https://github.com/openedx/openedx-core/issues/470
- Styles to make component cards selectable.
- Action to select a component and send a message to the parent of the iframe
- Handler for a "deselect all" message and for selecting a specific component
- Returns top parent key instead of boolean in upstream info api
- Adds edited_on raw time in course outline api
- Adds has_changes to course details api
The openedx-learning repo was recently refactored to consolidate its
authoring apps into a single openedx_content app:
https://github.com/openedx/openedx-platform/pull/37924
This commit makes the following changes to accommodate this:
- Bumps the openedx-learning version to 0.31.0 to get the changes.
- Creates new migrations in content_libraries, contentstore, and
modulestore_migrator to foreign key references to authoring apps
to point to the new openedx_content app. This is done without
actually making database changes, since the openedx_content app
models are taking over the existing tables that the authoring apps
once pointed to.
- Creates new squashed migrations in these apps that create these
foreign keys to reference openedx_content app models from the start.
The full rationale for how and why this was done is in the following
openedx-learning ADR:
https://github.com/openedx/openedx-learning/blob/main/docs/decisions/0020-merge-authoring-apps-into-openedx-content.rst
These migrations should run fine from either a from-scratch scenario
(i.e. a new install or CI), or when upgrading from an Ulmo-or-later
database state. If you have a database state that comes from the middle
of the Ulmo development cycle (e.g. October 2025), you may encounter
migration errors in content_libraries, contentstore, or
modulestore_migrator, with an error message complaining about missing
tables. If you receive this message, run the following command:
python manage.py lms migrate openedx_content 0001
Then try to run the migrations for the app that failed. Repeat if
necessary for multiple apps.
- Add GET /api/instructor/v2/courses/{course_id}/group_configurations
- Add GET /api/instructor/v2/courses/{course_id}/group_configurations/{id}
- Create shared constants module for course groups
* refactor: moved remaining feature dicts settings into top-level settings.
* refactor: moved remaining feature dicts settings into top-level settings.
* fix: fixed the test files
* fix: fixed tehe pylint errors
* fix: fixation of the cms ci failure
* fix: fixed remaining feature settings for cms
* fix: added fix for requirements
* fix: added fix for lms tests
* fix: resolved the test views issue
* fix: configured views file and test_views
* fix: fixed lint errors and assertion issues
* fix: added fix for base url issue in test view
* fix: added fix for base_url and assertion issue
* fix: added configurations for base utl fix
* fix: handled none issue for mfe config
* fix: corrected override settings in test views
* fix: added getattr defensive technique for view settings
* fix: reverted views and test_views file
* fix: added settings in views file
* fix: added with patch within functions in test view
* fix: rearranged the features in default_legacy_config
* fix: fixing the tests with clearing cache
* fix: reverted test views to verify the CI check
* fix: added cache clear in mfe config test
* fix: fixed the patch toggles to override settings
* fix: fixed the lint errors
* fix: changed patch toggle to override settings
Adding transcripts to Videos now goes through the new VideoConfigService
instead of direct calls from the VideoBlock. However, the VideoConfigService
was not added to Studio. This patch fixes transcript uploading by adding
the service to Studio.
refactor: move editor_saved to VideoConfigService (#37829)
* This moves edx-platform-specific logic out of the VideoBlock,
in preparation for the VideoBlock extraction
Adds API to fetch all legacy library content blocks that are ready to be updated to use library v2 and convert to item banks.
Also adds API to update all the references via a user celery task and to fetch its status.
Prior to this, if ENABLE_ORGANIZATION_STAFF_ACCESS_FOR_CONTENT_LIBRARIES
was enabled, we would not return the orgs that someone had course
creator rights on, even if ENABLE_CREATOR_GROUP was enabled. (For the
moment, we are conflating "can create courses" with "can create
libraries" for a given org, even though we should probably eventually
split those apart.)
For legacy library_content references in courses, this PR:
- **Removes the spurious sync after updating a reference to a migrated
library**, so that users don't need to "update" their content _after_
updating their reference, _unless_ there were real content edits that
happened since they last synced. We do this by correctly associating a
DraftChangeLogRecord with the ModulestoreBlockSource migration artifact,
and then comparing that version information before offering a sync.
(related issue:
https://github.com/openedx/frontend-app-authoring/issues/2626).
- **Prompts users to update a reference to a migrated library with higher
priority than prompting them to sync legacy content updates for that
reference**, so that users don't end up needing to accept legacy content
updates in order to get a to a point where they can update to V2 content.
- **Ensures the library references in courses always follow the correct
migration,** as defined by the data `forwarded` fields in the data model,
which are populated based on the REST API spec and the stated product UI
requirements.
* For the migration itself, this PR:
- **Allows non-admins to migrate libraries**, fixing:
https://github.com/openedx/edx-platform/issues/37774
- **When triggered via the UI, ensures the migration uses nice title-based
target slugs instead of ugly source-hash-based slugs.** We've had this as an
option for a long time, but preserve_url_slugs defaulted to True instead of
False in the REST API serializer, so we weren't taking advantage of it.
- **Unifies logic between single-source and bulk migration**. These were
implement as two separate code paths, with drift in their implementations. In
particular, the collection update-vs-create-new logic was completely
different for single-souce vs. bulk.
- **When using the Skip or Update strategies for repeats, it consistently
follows mappings established by the latest successful migration** rather than
following mappings across arbitrary previous migrations.
- **We log unexpected exceptions more often**, although there is so much more
room for improvement here.
- **Adds more validation to the REST API** so that client mistakes more often
become 400s with validation messages rather than 500s.
For developers, this PR:
- Adds unit tests to the REST API
- Ensures that all migration business logic now goes through a general-purpose
Python API.
- Ensures that the data model (specifically `forwarded`, and
`change_log_record`) is now populated and respected.
- Adds more type annotations.