From 51a3ab8c35b865c0a930672c33be83993a79b565 Mon Sep 17 00:00:00 2001 From: Muhammad Labeeb <72980976+mlabeeb03@users.noreply.github.com> Date: Fri, 28 Mar 2025 13:49:10 +0500 Subject: [PATCH] feat: add ci --- .github/workflows/test.yml | 40 +++++++++++------------ tutordash/server/app.py | 56 ++++++++++++++++++--------------- tutordash/server/tutorclient.py | 2 +- 3 files changed, 52 insertions(+), 46 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cd6c8c5..8631a61 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,25 +1,25 @@ name: Run tests on: - pull_request: - branches: [master] + pull_request: + branches: [release, main] + push: + branches: [release, main] jobs: - tests: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ['3.9', '3.12'] - steps: - - uses: actions/checkout@v3 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: Upgrade pip - run: python -m pip install --upgrade pip - - name: Install dependencies - run: | - pip install .[dev] - - name: Test lint, types, and format - run: make test + tests: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.9", "3.12"] + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + pip install .[dev] + - name: Test lint, types, and format + run: make test diff --git a/tutordash/server/app.py b/tutordash/server/app.py index ebf7641..1a2d3cd 100644 --- a/tutordash/server/app.py +++ b/tutordash/server/app.py @@ -51,7 +51,7 @@ def run(root: str, **app_kwargs: t.Any) -> None: @app.before_request -async def before_request(): +async def before_request() -> None: # Shared views and template context g.installed_plugins = tutorclient.Client.installed_plugins() g.enabled_plugins = tutorclient.Client.enabled_plugins() @@ -75,7 +75,7 @@ async def plugin_installed() -> str: @app.get("/plugin/store/list") async def plugin_store_list() -> str: search_query = request.args.get("search", "") - plugins: list[dict[str, str]] = [ + plugins: list[dict[str, t.Any]] = [ { "name": p.name, "url": p.url, @@ -103,7 +103,7 @@ async def plugin_store_list() -> str: @app.get("/plugin/installed/list") async def plugin_installed_list() -> str: search_query = request.args.get("search", "") - plugins: list[dict[str, str]] = [ + plugins: list[dict[str, t.Any]] = [ { "name": p.name, "url": p.url, @@ -124,7 +124,7 @@ async def plugin_installed_list() -> str: @app.get("/plugin/") -async def plugin(name: str) -> str: +async def plugin(name: str) -> Response: # TODO check that plugin exists show_logs = request.args.get("show_logs") author = next( @@ -161,7 +161,7 @@ async def plugin(name: str) -> str: @app.post("/plugin//toggle") -async def plugin_toggle(name: str) -> WerkzeugResponse: +async def plugin_toggle(name: str) -> Response: # TODO check plugin exists form = await request.form enable_plugin = form.get("checked") == "on" @@ -169,13 +169,16 @@ async def plugin_toggle(name: str) -> WerkzeugResponse: tutorclient.CliPool.run_sequential(command) # TODO error management - response = await make_response( - redirect( - url_for( - "plugin", - name=name, + response = t.cast( + Response, + await make_response( + redirect( + url_for( + "plugin", + name=name, + ) ) - ) + ), ) if enable_plugin: response.set_cookie( @@ -190,7 +193,7 @@ async def plugin_toggle(name: str) -> WerkzeugResponse: @app.post("/plugin//install") async def plugin_install(name: str) -> WerkzeugResponse: - async def bg_install_and_reload(): + async def bg_install_and_reload() -> None: tutorclient.CliPool.run_parallel(app, ["plugins", "install", name]) while tutorclient.CliPool.THREAD and tutorclient.CliPool.THREAD.is_alive(): await asyncio.sleep(0.1) @@ -225,7 +228,7 @@ async def plugins_update() -> WerkzeugResponse: @app.post("/config//update") -async def config_update(name: str) -> WerkzeugResponse: +async def config_update(name: str) -> Response: form = await request.form unset = form.get("unset") @@ -241,13 +244,16 @@ async def config_update(name: str) -> WerkzeugResponse: cmd.extend(["--set", f"{key}={value}"]) tutorclient.CliPool.run_sequential(cmd) # TODO error management - response = await make_response( - redirect( - url_for( - "plugin", - name=name, + response = t.cast( + Response, + await make_response( + redirect( + url_for( + "plugin", + name=name, + ) ) - ) + ), ) response.set_cookie( f"{constants.WARNING_COOKIE_PREFIX}-{name}", @@ -265,7 +271,7 @@ async def local_launch_view() -> str: @app.post("/cli/local/launch") -async def cli_local_launch() -> WerkzeugResponse: +async def cli_local_launch() -> str: tutorclient.CliPool.run_parallel(app, ["local", "launch", "--non-interactive"]) return await render_template( "local_launch.html", @@ -273,7 +279,6 @@ async def cli_local_launch() -> WerkzeugResponse: ) - @app.get("/cli/logs/stream") async def cli_logs_stream() -> ResponseTypes: """ @@ -317,8 +322,9 @@ async def cli_logs_stream() -> ResponseTypes: @app.post("/cli/stop") -async def cli_stop() -> None: +async def cli_stop() -> Response: tutorclient.CliPool.stop() + return Response(status=200) @app.get("/advanced") @@ -330,7 +336,7 @@ async def advanced() -> str: @app.post("/suggest") -async def suggest(): +async def suggest() -> Response: data = await request.get_json() partial_command = data.get("command", "") suggestions = tutorclient.Client.autocomplete(partial_command) @@ -338,11 +344,11 @@ async def suggest(): @app.post("/command") -async def command() -> str: +async def command() -> WerkzeugResponse: form = await request.form command_string = form.get("command", "") command_args = command_string.split() if tutorclient.CliPool.is_thread_alive(): abort(400, description="Command execution already in progress") tutorclient.CliPool.run_parallel(app, command_args) - return await make_response(redirect(url_for("advanced"))) + return redirect(url_for("advanced")) diff --git a/tutordash/server/tutorclient.py b/tutordash/server/tutorclient.py index d0c00ca..d73fb4a 100644 --- a/tutordash/server/tutorclient.py +++ b/tutordash/server/tutorclient.py @@ -343,7 +343,7 @@ class Client: } @classmethod - def autocomplete(cls, partial_command: str) -> list[dict]: + def autocomplete(cls, partial_command: str) -> list[dict[str, str]]: cli = tutor.commands.cli.cli ctx = click.Context(cli, info_name=cli.name, parent=None) completer = click_repl.ClickCompleter(cli, ctx)