Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: don't unneccessarily rebuild dev assets #39

Draft
wants to merge 21 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
6549442
security: add upstream security patch in Open edX image (#1100)
DawoudSheraz Jul 26, 2024
044eede
Merge remote-tracking branch 'origin/master' into nightly
Jul 26, 2024
1c5d54a
docs: fix mysql version on RUN_MYSQL=false (#1104)
regisb Jul 30, 2024
55d8289
Merge remote-tracking branch 'origin/master' into nightly
Jul 30, 2024
b259376
v18.1.2
DawoudSheraz Jul 26, 2024
ba666e3
Merge remote-tracking branch 'origin/master' into nightly
Jul 30, 2024
a97a7b0
refactor: move uswgi out of platform directory (#1036)
DawoudSheraz Jul 30, 2024
27117e3
Merge remote-tracking branch 'origin/master' into nightly
Jul 30, 2024
8aed225
docs: warning message indentation in upgrade
regisb Jul 26, 2024
91bffc9
Merge remote-tracking branch 'origin/master' into nightly
Aug 8, 2024
354dfc6
feat: update to redwood.2
DawoudSheraz Aug 12, 2024
3143335
v18.1.3
DawoudSheraz Aug 13, 2024
7bec007
Merge remote-tracking branch 'origin/master' into nightly
Aug 13, 2024
eccb4d1
chore: upgrade zipp, urllib3, certifi reqs (#1107)
regisb Aug 20, 2024
1b1e20f
Merge remote-tracking branch 'origin/master' into nightly
Aug 20, 2024
6cdeddd
feat: set `EDXAPP_TEST_MONGO_HOST=mongodb` in openedx-dev (#1083)
kdmccormick Aug 27, 2024
bbd5207
Merge remote-tracking branch 'origin/master' into nightly
Aug 27, 2024
46b4016
feat: cleanup flag (#1086)
CodeWithEmad Aug 27, 2024
5f1e6be
Merge remote-tracking branch 'origin/master' into nightly
Aug 27, 2024
5ac32bc
perf: don't unneccessarily rebuild dev assets
kdmccormick May 31, 2024
8d35aa6
feat: separate pip-install-mounted script
kdmccormick Jul 22, 2024
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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ instructions, because git commits are used to generate release notes:

<!-- scriv-insert-here -->

<a id='changelog-18.1.3'></a>
## v18.1.3 (2024-08-13)

- [Feature] Update to redwood.2 tag (by @dawoudsheraz)

<a id='changelog-18.1.2'></a>
## v18.1.2 (2024-07-26)

- [Security] Add upstream security fix as patch in Open edX image (by @dawoudsheraz)

<a id='changelog-18.1.1'></a>
## v18.1.1 (2024-07-04)

Expand Down
1 change: 1 addition & 0 deletions changelog.d/20240624_105125_kyle_test_mongo_host.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[Improvement] Set `EDXAPP_TEST_MONGO_HOST` env var in the openedx-dev image so that it no longer needs to be set by hand when running edx-platform unit tests (by @kdmccormick).
1 change: 1 addition & 0 deletions changelog.d/20240629_120748_codewithemad_cleanup_flag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- [Feature] Added `-c` or `--clean` option to tutor config save: For plugin developers and advanced users, this option cleans the `env/` folder before saving, ensuring a fresh environment for testing and development. (by @CodeWithEmad)
4 changes: 2 additions & 2 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ Open edX customisation

This defines the git repository from which you install Open edX platform code. If you run an Open edX fork with custom patches, set this to your own git repository. You may also override this configuration parameter at build time, by providing a ``--build-arg`` option.

- ``OPENEDX_COMMON_VERSION`` (default: ``"open-release/redwood.1"``, or ``master`` in :ref:`nightly <nightly>`)
- ``OPENEDX_COMMON_VERSION`` (default: ``"open-release/redwood.2"``, or ``master`` in :ref:`nightly <nightly>`)

This defines the default version that will be pulled from all Open edX git repositories.

Expand Down Expand Up @@ -226,7 +226,7 @@ By default, a running Open edX platform deployed with Tutor includes all necessa
MYSQL_ROOT_PASSWORD: <root user password>

.. note::
When configuring an external MySQL database, please make sure it is using version 5.7.
When configuring an external MySQL database, please make sure it is using version 8.4.

Elasticsearch
*************
Expand Down
3 changes: 1 addition & 2 deletions docs/tutorials/edx-platform.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ You should then re-build the "openedx" Docker image to pick up your changes::

tutor images build openedx-dev

Then, whenever you run ``tutor dev start``, the "lms" and "cms" container should automatically hot-reload your changes.
Then, whenever you run ``tutor dev start``, the "lms" and "cms" containers should automatically hot-reload your changes.

To push your changes in production, you should do the same with ``tutor local`` and the "openedx" image::

Expand Down Expand Up @@ -151,7 +151,6 @@ Then, run unit tests with ``pytest`` commands::
# Run tests on common apps
unset DJANGO_SETTINGS_MODULE
unset SERVICE_VARIANT
export EDXAPP_TEST_MONGO_HOST=mongodb
pytest common
pytest openedx
pytest xmodule
Expand Down
6 changes: 3 additions & 3 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ appdirs==1.4.4
# via -r requirements/base.in
cachetools==5.3.2
# via google-auth
certifi==2023.7.22
certifi==2024.7.4
# via
# kubernetes
# requests
Expand Down Expand Up @@ -70,13 +70,13 @@ typing-extensions==4.8.0
# via
# -r requirements/base.in
# mypy
urllib3==1.26.18
urllib3==1.26.19
# via
# kubernetes
# requests
websocket-client==1.6.4
# via kubernetes
zipp==3.17.0
zipp==3.19.2
# via
# importlib-metadata
# importlib-resources
6 changes: 3 additions & 3 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ cachetools==5.3.2
# via
# -r requirements/base.txt
# google-auth
certifi==2023.7.22
certifi==2024.7.4
# via
# -r requirements/base.txt
# kubernetes
Expand Down Expand Up @@ -221,7 +221,7 @@ typing-extensions==4.8.0
# mypy
# pylint
# rich
urllib3==1.26.18
urllib3==1.26.19
# via
# -r requirements/base.txt
# kubernetes
Expand All @@ -233,7 +233,7 @@ websocket-client==1.6.4
# kubernetes
wheel==0.41.2
# via pip-tools
zipp==3.17.0
zipp==3.19.2
# via
# -r requirements/base.txt
# importlib-metadata
Expand Down
6 changes: 3 additions & 3 deletions requirements/docs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ cachetools==5.3.2
# via
# -r requirements/base.txt
# google-auth
certifi==2023.7.22
certifi==2024.7.4
# via
# -r requirements/base.txt
# kubernetes
Expand Down Expand Up @@ -147,7 +147,7 @@ typing-extensions==4.8.0
# via
# -r requirements/base.txt
# mypy
urllib3==1.26.18
urllib3==1.26.19
# via
# -r requirements/base.txt
# kubernetes
Expand All @@ -156,7 +156,7 @@ websocket-client==1.6.4
# via
# -r requirements/base.txt
# kubernetes
zipp==3.17.0
zipp==3.19.2
# via
# -r requirements/base.txt
# importlib-metadata
Expand Down
5 changes: 5 additions & 0 deletions tests/commands/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ def test_config_save(self) -> None:
self.assertFalse(result.exception)
self.assertEqual(0, result.exit_code)

def test_config_save_cleanup_env_dir(self) -> None:
result = self.invoke(["config", "save", "-c"])
self.assertFalse(result.exception)
self.assertEqual(0, result.exit_code)

def test_config_save_interactive(self) -> None:
result = self.invoke(["config", "save", "-i"])
self.assertFalse(result.exception)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def mock_prompt(*_args: None, **kwargs: str) -> str:
with patch.object(click, "prompt", new=mock_prompt):
with patch.object(click, "confirm", new=mock_prompt):
config = tutor_config.load_minimal(rootdir)
interactive.ask_questions(config)
interactive.ask_questions(config, rootdir)

self.assertIn("MYSQL_ROOT_PASSWORD", config)
self.assertEqual(8, len(get_typed(config, "MYSQL_ROOT_PASSWORD", str)))
Expand Down
2 changes: 1 addition & 1 deletion tutor/__about__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Increment this version number to trigger a new release. See
# docs/tutor.html#versioning for information on the versioning scheme.
__version__ = "18.1.1"
__version__ = "18.1.3"

# The version suffix will be appended to the actual version, separated by a
# dash. Use this suffix to differentiate between the actual released version and
Expand Down
22 changes: 14 additions & 8 deletions tutor/commands/compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,27 +172,33 @@ def interactive_upgrade(
if interactive:
question = f"""Your platform is being upgraded from {run_upgrade_from_release.capitalize()}.

If you run custom Docker images, you must rebuild them now by running the following command in a different shell:
If you run custom Docker images, you must rebuild them now by running the following command in a different shell:

tutor images build all # list your custom images here
tutor images build all # list your custom images here

See the documentation for more information:
See the documentation for more information:

https://docs.tutor.edly.io/install.html#upgrading-to-a-new-open-edx-release
https://docs.tutor.edly.io/install.html#upgrading-to-a-new-open-edx-release

Press enter when you are ready to continue"""
Press enter when you are ready to continue"""
click.confirm(
fmt.question(question), default=True, abort=True, prompt_suffix=" "
)


def interactive_configuration(
context: click.Context, interactive: bool, run_for_prod: t.Optional[bool] = None
context: click.Context,
interactive: bool,
run_for_prod: t.Optional[bool] = None,
) -> None:
click.echo(fmt.title("Interactive platform configuration"))
config = tutor_config.load_minimal(context.obj.root)
if interactive:
interactive_config.ask_questions(config, run_for_prod=run_for_prod)
click.echo(fmt.title("Interactive platform configuration"))
interactive_config.ask_questions(
config,
context.obj.root,
run_for_prod=run_for_prod,
)
tutor_config.save_config_file(context.obj.root, config)
config = tutor_config.load_full(context.obj.root)
tutor_env.save(context.obj.root, config)
Expand Down
12 changes: 11 additions & 1 deletion tutor/commands/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ def _candidate_config_items(self) -> t.Iterable[tuple[str, ConfigValue]]:
@click.option(
"-e", "--env-only", "env_only", is_flag=True, help="Skip updating config.yml"
)
@click.option(
"-c",
"--clean",
"clean_env",
is_flag=True,
help="Remove everything in the env directory before save",
)
@click.pass_obj
def save(
context: Context,
Expand All @@ -145,10 +152,13 @@ def save(
remove_vars: list[tuple[str, t.Any]],
unset_vars: list[str],
env_only: bool,
clean_env: bool,
) -> None:
config = tutor_config.load_minimal(context.root)
if interactive:
interactive_config.ask_questions(config)
interactive_config.ask_questions(config, context.root, clean_env_prompt=True)
if clean_env:
env.delete_env_dir(context.root)
if set_vars:
for key, value in set_vars:
config[key] = env.render_unknown(config, value)
Expand Down
4 changes: 2 additions & 2 deletions tutor/commands/k8s.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,10 @@ def launch(context: click.Context, non_interactive: bool) -> None:
from_release=tutor_env.get_env_release(context.obj.root),
)

click.echo(fmt.title("Interactive platform configuration"))
config = tutor_config.load_minimal(context.obj.root)
if not non_interactive:
interactive_config.ask_questions(config, run_for_prod=True)
click.echo(fmt.title("Interactive platform configuration"))
interactive_config.ask_questions(config, context.obj.root, run_for_prod=True)
tutor_config.save_config_file(context.obj.root, config)
config = tutor_config.load_full(context.obj.root)
tutor_env.save(context.obj.root, config)
Expand Down
2 changes: 1 addition & 1 deletion tutor/commands/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def plugins_command() -> None:

@click.command(
short_help="Print the location of file-based plugins",
help=f"""Print the location of yaml-based plugins: nboth python v1 and yaml v0 plugins. This location can be manually
help=f"""Print the location of yaml-based plugins: both python v1 and yaml v0 plugins. This location can be manually
defined by setting the {PLUGINS_ROOT_ENV_VAR_NAME} environment variable""",
)
def printroot() -> None:
Expand Down
14 changes: 14 additions & 0 deletions tutor/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,20 @@ def root_dir(root: str) -> str:
return os.path.abspath(root)


def delete_env_dir(root: str) -> None:
env_path = base_dir(root)

try:
shutil.rmtree(env_path)
fmt.echo_alert(f"Removed existing Tutor environment at: {env_path}")
except PermissionError:
raise exceptions.TutorError(
f"Permission Denied while trying to remove existing Tutor environment at: {env_path}"
)
except FileNotFoundError:
fmt.echo_info(f"No existing Tutor environment to remove at: {env_path}")


@hooks.Actions.PLUGIN_UNLOADED.add()
def _delete_plugin_templates(plugin: str, root: str, _config: Config) -> None:
"""
Expand Down
19 changes: 18 additions & 1 deletion tutor/interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,23 @@
from .types import Config, get_typed


def ask_questions(config: Config, run_for_prod: Optional[bool] = None) -> None:
def ask_questions(
config: Config,
root: str,
run_for_prod: Optional[bool] = None,
clean_env_prompt: bool = False,
) -> None:
"""
Interactively ask questions to collect configuration values from the user.

Arguments:
config: Existing (or minimal) configuration. Modified in-place.
run_for_prod: Whether platform should be configured for production.
If None, then ask the user.
clean_env_prompt: Whether to show the clean environment prompt before running.
defaults to False.
Returns:
None
"""
defaults = tutor_config.get_defaults()
if run_for_prod is None:
Expand Down Expand Up @@ -148,6 +157,14 @@ def ask_questions(config: Config, run_for_prod: Optional[bool] = None) -> None:
config,
defaults,
)
if clean_env_prompt:
run_clean = click.confirm(
fmt.question("Remove existing Tutor environment directory?"),
prompt_suffix=" ",
default=True,
)
if run_clean:
env.delete_env_dir(root)

hooks.Actions.CONFIG_INTERACTIVE.do(config)

Expand Down
Loading
Loading