Repository: piccolo-orm/piccolo_admin (language: python)

Issue:
Add scripts folder
Following [this](https://github.com/piccolo-orm/piccolo/pull/133):

- Move all the scripts to the `scripts` folder
- Update github workflows to use the scripts


Discussion / hints:

Fix patch:
diff --git a/.flake8 b/.flake8
new file mode 100644
index 00000000..8da7550b
--- /dev/null
+++ b/.flake8
@@ -0,0 +1,3 @@
+[flake8]
+per-file-ignores = __init__.py:F401
+max-line-length = 79
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
new file mode 100644
index 00000000..ef5addf1
--- /dev/null
+++ b/.github/workflows/release.yaml
@@ -0,0 +1,24 @@
+name: Release
+
+on:
+  release:
+    types:
+      - created
+
+jobs:
+  release:
+    name: "Publish release"
+    runs-on: "ubuntu-latest"
+
+    steps:
+      - uses: "actions/checkout@v2"
+      - uses: "actions/setup-python@v1"
+        with:
+          python-version: 3.7
+      - name: "Install dependencies"
+        run: "pip install -r dev-requirements.txt"
+      - name: "Publish to PyPI"
+        run: "./scripts/release.sh"
+        env:
+          TWINE_USERNAME: __token__
+          TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 3368e031..c8a62444 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,8 @@ node_modules/
 *.egg-info/
 build/
 dist/
+.coverage
+coverage.xml
+htmlcov/
+.env/
+.venv/
diff --git a/dev-requirements.txt b/dev-requirements.txt
index f1037197..cc8b2138 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,3 +1,4 @@
+isort==5.9.2
 twine==3.4.1
 mypy==0.812
 pip-upgrader==1.4.15
diff --git a/piccolo_admin/endpoints.py b/piccolo_admin/endpoints.py
index 2daa4b3d..82233e1d 100644
--- a/piccolo_admin/endpoints.py
+++ b/piccolo_admin/endpoints.py
@@ -2,32 +2,32 @@
 Creates a basic wrapper around a Piccolo model, turning it into an ASGI app.
 """
 from __future__ import annotations
-from datetime import timedelta
-from functools import partial
+
 import os
 import typing as t
+from datetime import timedelta
+from functools import partial
 
+from fastapi import FastAPI
 from piccolo.apps.user.tables import BaseUser
-from piccolo_api.csrf.middleware import CSRFMiddleware
 from piccolo_api.crud.endpoints import PiccoloCRUD
-from piccolo_api.fastapi.endpoints import FastAPIWrapper, FastAPIKwargs
+from piccolo_api.csrf.middleware import CSRFMiddleware
+from piccolo_api.fastapi.endpoints import FastAPIKwargs, FastAPIWrapper
 from piccolo_api.openapi.endpoints import swagger_ui
 from piccolo_api.rate_limiting.middleware import (
+    InMemoryLimitProvider,
     RateLimitingMiddleware,
     RateLimitProvider,
-    InMemoryLimitProvider,
 )
 from piccolo_api.session_auth.endpoints import session_login, session_logout
-from piccolo_api.session_auth.tables import SessionsBase
 from piccolo_api.session_auth.middleware import SessionsAuthBackend
+from piccolo_api.session_auth.tables import SessionsBase
 from pydantic import BaseModel
-
-from fastapi import FastAPI
-from starlette.responses import HTMLResponse, JSONResponse
-from starlette.requests import Request
-from starlette.staticfiles import StaticFiles
 from starlette.exceptions import ExceptionMiddleware
 from starlette.middleware.authentication import AuthenticationMiddleware
+from starlette.requests import Request
+from starlette.responses import HTMLResponse, JSONResponse
+from starlette.staticfiles import StaticFiles
 
 from .version import __VERSION__ as PICCOLO_ADMIN_VERSION
 
@@ -200,7 +200,8 @@ async def get_root(self, request: Request) -> HTMLResponse:
 
     def get_user(self, request: Request) -> UserResponseModel:
         return UserResponseModel(
-            username=request.user.display_name, user_id=request.user.user_id,
+            username=request.user.display_name,
+            user_id=request.user.user_id,
         )
 
     ###########################################################################
diff --git a/piccolo_admin/example.py b/piccolo_admin/example.py
index 20a93415..ca5de436 100644
--- a/piccolo_admin/example.py
+++ b/piccolo_admin/example.py
@@ -12,32 +12,32 @@
 import random
 import typing as t
 
+import targ
 from hypercorn.asyncio import serve
 from hypercorn.config import Config
-from piccolo_api.session_auth.tables import SessionsBase
-from piccolo.engine.sqlite import SQLiteEngine
-from piccolo.engine.postgres import PostgresEngine
 from piccolo.apps.user.tables import BaseUser
-from piccolo.table import Table
 from piccolo.columns import (
     Array,
     BigInt,
-    Varchar,
-    Integer,
-    ForeignKey,
     Boolean,
+    ForeignKey,
+    Integer,
     Interval,
-    Text,
-    Timestamp,
     Numeric,
     Real,
     SmallInt,
+    Text,
+    Timestamp,
+    Varchar,
 )
 from piccolo.columns.readable import Readable
-import targ
+from piccolo.engine.postgres import PostgresEngine
+from piccolo.engine.sqlite import SQLiteEngine
+from piccolo.table import Table
+from piccolo_api.session_auth.tables import SessionsBase
 
 from piccolo_admin.endpoints import create_admin
-from piccolo_admin.example_data import DIRECTORS, MOVIES, MOVIE_WORDS
+from piccolo_admin.example_data import DIRECTORS, MOVIE_WORDS, MOVIES
 
 
 class Sessions(SessionsBase):
diff --git a/piccolo_admin/example_data.py b/piccolo_admin/example_data.py
index 9395e0e4..0c32505a 100644
--- a/piccolo_admin/example_data.py
+++ b/piccolo_admin/example_data.py
@@ -1,7 +1,6 @@
 import datetime
 from decimal import Decimal
 
-
 DIRECTORS = [
     {
         "id": 1,
diff --git a/piccolo_admin/piccolo_app.py b/piccolo_admin/piccolo_app.py
index 1885201e..f0833fc9 100644
--- a/piccolo_admin/piccolo_app.py
+++ b/piccolo_admin/piccolo_app.py
@@ -7,7 +7,6 @@
 
 from piccolo.conf.apps import AppConfig
 
-
 CURRENT_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
 
 
diff --git a/piccolo_admin/sandbox.py b/piccolo_admin/sandbox.py
index 71b5a2b1..87a32e4f 100644
--- a/piccolo_admin/sandbox.py
+++ b/piccolo_admin/sandbox.py
@@ -2,6 +2,9 @@
 Runs the admin in read only mode - useful for letting people evaluate the admin
 online without risk of abuse.
 """
+import targ
+import uvicorn
+
 from piccolo_admin.example import (
     Director,
     Movie,
@@ -12,9 +15,6 @@
     populate_data,
     set_engine,
 )
-import targ
-import uvicorn
-
 
 APP = create_admin(
     [Director, Movie], auth_table=User, session_table=Sessions, read_only=True
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 00000000..d84cc51b
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,6 @@
+[tool.black]
+line-length = 79
+
+[tool.isort]
+profile = "black"
+line_length = 79
diff --git a/scripts/README.md b/scripts/README.md
new file mode 100644
index 00000000..ebeea890
--- /dev/null
+++ b/scripts/README.md
@@ -0,0 +1,9 @@
+# Development Scripts
+
+The scripts follow GitHub's ["Scripts to Rule Them All"](https://github.com/github/scripts-to-rule-them-all).
+
+Call them from the root of the project, e.g. `./scripts/lint.sh`.
+
+* `scripts/lint.sh` - Run the automated code linting/formatting tools.
+* `scripts/release.sh` - Publish package to PyPI.
+* `scripts/run-tests.sh` - Run the test suite.
diff --git a/scripts/lint.sh b/scripts/lint.sh
new file mode 100755
index 00000000..fae09205
--- /dev/null
+++ b/scripts/lint.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+SOURCES="piccolo_admin tests"
+
+isort $SOURCES
+black $SOURCES
+flake8 $SOURCES
+# mypy $SOURCES
diff --git a/release.sh b/scripts/release.sh
similarity index 71%
rename from release.sh
rename to scripts/release.sh
index 492f7d67..6f94bb5b 100755
--- a/release.sh
+++ b/scripts/release.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-cd ./admin_ui && npm run build && cd ..
+npm run build && cd ..
 rm -rf ./build/*
 rm -rf ./dist/*
 python setup.py sdist bdist_wheel


Test patch:
diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
index a3de06e3..a0652e24 100644
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -1,6 +1,10 @@
-name: Python package
+name: Test Suite
 
-on: [push]
+on:
+  push:
+    branches: ["master"]
+  pull_request:
+    branches: ["master"]
 
 jobs:
     linters:
@@ -15,8 +19,8 @@ jobs:
               run: |
                   python -m pip install --upgrade pip
                   pip install -r tests/test-requirements.txt
-            - name: Flake8
-              run: flake8
+            - name: Lint
+              run: ./scripts/lint.sh
 
     test_sqlite:
         runs-on: ubuntu-latest
@@ -36,4 +40,6 @@ jobs:
                   pip install -r requirements.txt
                   pip install -r tests/test-requirements.txt
             - name: Test with pytest, SQLite
-              run: cd tests && ./run-tests.sh
+              run: ./scripts/run-tests.sh
+            - name: Upload coverage
+              uses: codecov/codecov-action@v1
diff --git a/tests/run-tests.sh b/scripts/run-tests.sh
similarity index 70%
rename from tests/run-tests.sh
rename to scripts/run-tests.sh
index 4233bbd3..6d22257d 100755
--- a/tests/run-tests.sh
+++ b/scripts/run-tests.sh
@@ -4,7 +4,5 @@
 # To run all in a class tests/test_foo.py::TestFoo
 # To run a single test tests/test_foo.py::TestFoo::test_foo
 
-cd ..
-
 export PICCOLO_CONF="tests.piccolo_conf"
-python -m pytest -s $@
+python -m pytest --cov=piccolo_admin --cov-report xml --cov-report html --cov-fail-under 23 -s $@
diff --git a/tests/piccolo_conf.py b/tests/piccolo_conf.py
index 3d2abbd5..be459dc7 100644
--- a/tests/piccolo_conf.py
+++ b/tests/piccolo_conf.py
@@ -1,4 +1,3 @@
 from piccolo.engine.sqlite import SQLiteEngine
 
-
 DB = SQLiteEngine(path="piccolo_api_test.sqlite")
diff --git a/tests/test-requirements.txt b/tests/test-requirements.txt
index 032ab018..86ecac53 100644
--- a/tests/test-requirements.txt
+++ b/tests/test-requirements.txt
@@ -1,2 +1,3 @@
 pytest==6.2.2
+pytest-cov==2.10.1
 flake8==3.9.0
diff --git a/tests/test_endpoints.py b/tests/test_endpoints.py
index 4855687e..4d77ca29 100644
--- a/tests/test_endpoints.py
+++ b/tests/test_endpoints.py
@@ -1,8 +1,9 @@
 from unittest import TestCase
 
-from piccolo_admin.endpoints import get_all_tables
-from piccolo.table import Table
 from piccolo.columns.column_types import ForeignKey, Varchar
+from piccolo.table import Table
+
+from piccolo_admin.endpoints import get_all_tables
 
 
 class TableA(Table):