quite-admin 0.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. quite_admin-0.4.1/.github/workflows/ci.yml +37 -0
  2. quite_admin-0.4.1/.github/workflows/compatibility.yml +80 -0
  3. quite_admin-0.4.1/.github/workflows/databases.yml +81 -0
  4. quite_admin-0.4.1/.github/workflows/pages.yml +90 -0
  5. quite_admin-0.4.1/.github/workflows/pypi.yml +121 -0
  6. quite_admin-0.4.1/.github/workflows/release.yml +57 -0
  7. quite_admin-0.4.1/.github/workflows/security.yml +50 -0
  8. quite_admin-0.4.1/.github/workflows/tests.yml +98 -0
  9. quite_admin-0.4.1/.gitignore +17 -0
  10. quite_admin-0.4.1/AGENTS.md +25 -0
  11. quite_admin-0.4.1/CHANGELOG.md +231 -0
  12. quite_admin-0.4.1/LICENSE +21 -0
  13. quite_admin-0.4.1/PKG-INFO +172 -0
  14. quite_admin-0.4.1/README.md +122 -0
  15. quite_admin-0.4.1/SECURITY.md +18 -0
  16. quite_admin-0.4.1/api/core-0.4.json +2541 -0
  17. quite_admin-0.4.1/api/gino-0.4.json +270 -0
  18. quite_admin-0.4.1/api/modern-0.4.json +1116 -0
  19. quite_admin-0.4.1/demo/app.js +366 -0
  20. quite_admin-0.4.1/demo/demo.css +26 -0
  21. quite_admin-0.4.1/demo/index.html +26 -0
  22. quite_admin-0.4.1/demo/store.mjs +261 -0
  23. quite_admin-0.4.1/docs/.yfm +15 -0
  24. quite_admin-0.4.1/docs/assets/screenshots/database-schema.png +0 -0
  25. quite_admin-0.4.1/docs/assets/screenshots/fields.png +0 -0
  26. quite_admin-0.4.1/docs/assets/screenshots/filters.png +0 -0
  27. quite_admin-0.4.1/docs/assets/screenshots/overview.png +0 -0
  28. quite_admin-0.4.1/docs/assets/screenshots/products.png +0 -0
  29. quite_admin-0.4.1/docs/assets/screenshots/record.png +0 -0
  30. quite_admin-0.4.1/docs/assets/screenshots/relationships.png +0 -0
  31. quite_admin-0.4.1/docs/assets/walkthrough.gif +0 -0
  32. quite_admin-0.4.1/docs/assets/walkthrough.mp4 +0 -0
  33. quite_admin-0.4.1/docs/en/api-stability.md +124 -0
  34. quite_admin-0.4.1/docs/en/architecture.md +111 -0
  35. quite_admin-0.4.1/docs/en/authentication.md +69 -0
  36. quite_admin-0.4.1/docs/en/browser-demo.md +51 -0
  37. quite_admin-0.4.1/docs/en/configuration.md +219 -0
  38. quite_admin-0.4.1/docs/en/custom-adapters.md +188 -0
  39. quite_admin-0.4.1/docs/en/custom-pages.md +57 -0
  40. quite_admin-0.4.1/docs/en/customization.md +167 -0
  41. quite_admin-0.4.1/docs/en/data-safety.md +127 -0
  42. quite_admin-0.4.1/docs/en/database-schema.md +79 -0
  43. quite_admin-0.4.1/docs/en/dependency-compatibility.md +108 -0
  44. quite_admin-0.4.1/docs/en/development.md +129 -0
  45. quite_admin-0.4.1/docs/en/exports.md +52 -0
  46. quite_admin-0.4.1/docs/en/extensions.md +73 -0
  47. quite_admin-0.4.1/docs/en/field-widgets.md +43 -0
  48. quite_admin-0.4.1/docs/en/filters.md +131 -0
  49. quite_admin-0.4.1/docs/en/gino.md +126 -0
  50. quite_admin-0.4.1/docs/en/index.md +79 -0
  51. quite_admin-0.4.1/docs/en/integration.md +143 -0
  52. quite_admin-0.4.1/docs/en/logging.md +203 -0
  53. quite_admin-0.4.1/docs/en/quickstart.md +99 -0
  54. quite_admin-0.4.1/docs/en/relationships.md +81 -0
  55. quite_admin-0.4.1/docs/en/releases.md +129 -0
  56. quite_admin-0.4.1/docs/en/styling.md +152 -0
  57. quite_admin-0.4.1/docs/en/toc.yaml +65 -0
  58. quite_admin-0.4.1/docs/ru/api-stability.md +129 -0
  59. quite_admin-0.4.1/docs/ru/architecture.md +108 -0
  60. quite_admin-0.4.1/docs/ru/authentication.md +56 -0
  61. quite_admin-0.4.1/docs/ru/browser-demo.md +51 -0
  62. quite_admin-0.4.1/docs/ru/configuration.md +219 -0
  63. quite_admin-0.4.1/docs/ru/custom-adapters.md +149 -0
  64. quite_admin-0.4.1/docs/ru/custom-pages.md +46 -0
  65. quite_admin-0.4.1/docs/ru/customization.md +171 -0
  66. quite_admin-0.4.1/docs/ru/data-safety.md +124 -0
  67. quite_admin-0.4.1/docs/ru/database-schema.md +81 -0
  68. quite_admin-0.4.1/docs/ru/dependency-compatibility.md +110 -0
  69. quite_admin-0.4.1/docs/ru/development.md +104 -0
  70. quite_admin-0.4.1/docs/ru/exports.md +53 -0
  71. quite_admin-0.4.1/docs/ru/extensions.md +73 -0
  72. quite_admin-0.4.1/docs/ru/field-widgets.md +42 -0
  73. quite_admin-0.4.1/docs/ru/filters.md +133 -0
  74. quite_admin-0.4.1/docs/ru/gino.md +129 -0
  75. quite_admin-0.4.1/docs/ru/index.md +79 -0
  76. quite_admin-0.4.1/docs/ru/integration.md +134 -0
  77. quite_admin-0.4.1/docs/ru/logging.md +204 -0
  78. quite_admin-0.4.1/docs/ru/quickstart.md +99 -0
  79. quite_admin-0.4.1/docs/ru/relationships.md +82 -0
  80. quite_admin-0.4.1/docs/ru/releases.md +127 -0
  81. quite_admin-0.4.1/docs/ru/styling.md +149 -0
  82. quite_admin-0.4.1/docs/ru/toc.yaml +65 -0
  83. quite_admin-0.4.1/examples/__init__.py +0 -0
  84. quite_admin-0.4.1/examples/common.py +211 -0
  85. quite_admin-0.4.1/examples/fastapi_app.py +24 -0
  86. quite_admin-0.4.1/examples/litestar_app.py +23 -0
  87. quite_admin-0.4.1/examples/templates/report.html +8 -0
  88. quite_admin-0.4.1/package-lock.json +2812 -0
  89. quite_admin-0.4.1/package.json +33 -0
  90. quite_admin-0.4.1/playwright.config.mjs +26 -0
  91. quite_admin-0.4.1/pyproject.toml +103 -0
  92. quite_admin-0.4.1/scripts/build_demo.py +168 -0
  93. quite_admin-0.4.1/scripts/check-docs.mjs +54 -0
  94. quite_admin-0.4.1/scripts/check_api.py +195 -0
  95. quite_admin-0.4.1/scripts/check_distributions.py +128 -0
  96. quite_admin-0.4.1/scripts/check_release.py +60 -0
  97. quite_admin-0.4.1/scripts/diplodoc.cjs +29 -0
  98. quite_admin-0.4.1/scripts/prepare-pages.mjs +11 -0
  99. quite_admin-0.4.1/scripts/test_compatibility.py +147 -0
  100. quite_admin-0.4.1/src/quite_admin/__init__.py +45 -0
  101. quite_admin-0.4.1/src/quite_admin/adapters/__init__.py +5 -0
  102. quite_admin-0.4.1/src/quite_admin/adapters/_gino_relations.py +247 -0
  103. quite_admin-0.4.1/src/quite_admin/adapters/_peewee_relations.py +228 -0
  104. quite_admin-0.4.1/src/quite_admin/adapters/_queries.py +113 -0
  105. quite_admin-0.4.1/src/quite_admin/adapters/_sql_metadata.py +201 -0
  106. quite_admin-0.4.1/src/quite_admin/adapters/_sql_relations.py +244 -0
  107. quite_admin-0.4.1/src/quite_admin/adapters/_sqlalchemy_relations.py +305 -0
  108. quite_admin-0.4.1/src/quite_admin/adapters/_tortoise_relations.py +219 -0
  109. quite_admin-0.4.1/src/quite_admin/adapters/base.py +28 -0
  110. quite_admin-0.4.1/src/quite_admin/adapters/delegating.py +50 -0
  111. quite_admin-0.4.1/src/quite_admin/adapters/gino.py +221 -0
  112. quite_admin-0.4.1/src/quite_admin/adapters/peewee.py +200 -0
  113. quite_admin-0.4.1/src/quite_admin/adapters/sql.py +258 -0
  114. quite_admin-0.4.1/src/quite_admin/adapters/sqlalchemy.py +240 -0
  115. quite_admin-0.4.1/src/quite_admin/adapters/tortoise.py +155 -0
  116. quite_admin-0.4.1/src/quite_admin/admin.py +1769 -0
  117. quite_admin-0.4.1/src/quite_admin/auth.py +95 -0
  118. quite_admin-0.4.1/src/quite_admin/concurrency.py +135 -0
  119. quite_admin-0.4.1/src/quite_admin/config.py +226 -0
  120. quite_admin-0.4.1/src/quite_admin/diagram.py +164 -0
  121. quite_admin-0.4.1/src/quite_admin/errors.py +21 -0
  122. quite_admin-0.4.1/src/quite_admin/exports.py +126 -0
  123. quite_admin-0.4.1/src/quite_admin/filters.py +363 -0
  124. quite_admin-0.4.1/src/quite_admin/i18n.py +390 -0
  125. quite_admin-0.4.1/src/quite_admin/logging.py +69 -0
  126. quite_admin-0.4.1/src/quite_admin/operations.py +44 -0
  127. quite_admin-0.4.1/src/quite_admin/py.typed +0 -0
  128. quite_admin-0.4.1/src/quite_admin/relations.py +60 -0
  129. quite_admin-0.4.1/src/quite_admin/schema.py +358 -0
  130. quite_admin-0.4.1/src/quite_admin/static/admin.css +551 -0
  131. quite_admin-0.4.1/src/quite_admin/static/filters.js +247 -0
  132. quite_admin-0.4.1/src/quite_admin/static/forms.js +249 -0
  133. quite_admin-0.4.1/src/quite_admin/static/inline.js +107 -0
  134. quite_admin-0.4.1/src/quite_admin/static/listing.js +37 -0
  135. quite_admin-0.4.1/src/quite_admin/static/navigation.js +12 -0
  136. quite_admin-0.4.1/src/quite_admin/static/relations.js +160 -0
  137. quite_admin-0.4.1/src/quite_admin/static/schema.js +364 -0
  138. quite_admin-0.4.1/src/quite_admin/templates/quite_admin/_icons.html +3 -0
  139. quite_admin-0.4.1/src/quite_admin/templates/quite_admin/_schema_content.html +21 -0
  140. quite_admin-0.4.1/src/quite_admin/templates/quite_admin/base.html +51 -0
  141. quite_admin-0.4.1/src/quite_admin/templates/quite_admin/dashboard.html +13 -0
  142. quite_admin-0.4.1/src/quite_admin/templates/quite_admin/delete.html +8 -0
  143. quite_admin-0.4.1/src/quite_admin/templates/quite_admin/error.html +2 -0
  144. quite_admin-0.4.1/src/quite_admin/templates/quite_admin/filters.html +27 -0
  145. quite_admin-0.4.1/src/quite_admin/templates/quite_admin/form.html +72 -0
  146. quite_admin-0.4.1/src/quite_admin/templates/quite_admin/list.html +62 -0
  147. quite_admin-0.4.1/src/quite_admin/templates/quite_admin/login.html +15 -0
  148. quite_admin-0.4.1/src/quite_admin/templates/quite_admin/schema.html +2 -0
  149. quite_admin-0.4.1/src/quite_admin/theme.py +99 -0
  150. quite_admin-0.4.1/tests/__init__.py +0 -0
  151. quite_admin-0.4.1/tests/browser/listing.spec.mjs +144 -0
  152. quite_admin-0.4.1/tests/browser_app.py +114 -0
  153. quite_admin-0.4.1/tests/conftest.py +135 -0
  154. quite_admin-0.4.1/tests/databases.py +89 -0
  155. quite_admin-0.4.1/tests/demo.test.mjs +143 -0
  156. quite_admin-0.4.1/tests/filters.test.cjs +62 -0
  157. quite_admin-0.4.1/tests/forms.test.cjs +25 -0
  158. quite_admin-0.4.1/tests/gino/__init__.py +0 -0
  159. quite_admin-0.4.1/tests/gino/conftest.py +106 -0
  160. quite_admin-0.4.1/tests/gino/test_contracts.py +38 -0
  161. quite_admin-0.4.1/tests/gino/test_gino.py +254 -0
  162. quite_admin-0.4.1/tests/helpers.py +29 -0
  163. quite_admin-0.4.1/tests/schema.test.cjs +58 -0
  164. quite_admin-0.4.1/tests/sqlmodel/__init__.py +0 -0
  165. quite_admin-0.4.1/tests/sqlmodel/conftest.py +110 -0
  166. quite_admin-0.4.1/tests/sqlmodel/test_contracts.py +49 -0
  167. quite_admin-0.4.1/tests/sqlmodel/test_models.py +73 -0
  168. quite_admin-0.4.1/tests/test_adapter_safety.py +221 -0
  169. quite_admin-0.4.1/tests/test_adapters.py +190 -0
  170. quite_admin-0.4.1/tests/test_concurrency.py +95 -0
  171. quite_admin-0.4.1/tests/test_customization.py +290 -0
  172. quite_admin-0.4.1/tests/test_database_features.py +169 -0
  173. quite_admin-0.4.1/tests/test_dependency_profiles.py +34 -0
  174. quite_admin-0.4.1/tests/test_diagram.py +227 -0
  175. quite_admin-0.4.1/tests/test_examples.py +40 -0
  176. quite_admin-0.4.1/tests/test_exports.py +132 -0
  177. quite_admin-0.4.1/tests/test_extensions.py +240 -0
  178. quite_admin-0.4.1/tests/test_filters.py +286 -0
  179. quite_admin-0.4.1/tests/test_form_controls.py +139 -0
  180. quite_admin-0.4.1/tests/test_inline_edit.py +79 -0
  181. quite_admin-0.4.1/tests/test_integration.py +178 -0
  182. quite_admin-0.4.1/tests/test_listing_interface.py +65 -0
  183. quite_admin-0.4.1/tests/test_logging.py +580 -0
  184. quite_admin-0.4.1/tests/test_public_api.py +286 -0
  185. quite_admin-0.4.1/tests/test_relations.py +778 -0
  186. quite_admin-0.4.1/tests/test_release_checks.py +51 -0
  187. quite_admin-0.4.1/tests/test_schema.py +153 -0
  188. quite_admin-0.4.1/tests/test_sql_reflection.py +99 -0
  189. quite_admin-0.4.1/tests/test_web.py +294 -0
  190. quite_admin-0.4.1/uv.lock +1871 -0
@@ -0,0 +1,37 @@
1
+ name: ci
2
+ on:
3
+ push:
4
+ branches: ['**']
5
+ pull_request:
6
+ workflow_dispatch:
7
+ workflow_call:
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ tests:
13
+ uses: ./.github/workflows/tests.yml
14
+ databases:
15
+ uses: ./.github/workflows/databases.yml
16
+ compatibility:
17
+ uses: ./.github/workflows/compatibility.yml
18
+ security:
19
+ uses: ./.github/workflows/security.yml
20
+ ready:
21
+ name: CI ready
22
+ if: always()
23
+ needs: [tests, databases, compatibility, security]
24
+ runs-on: ubuntu-latest
25
+ steps:
26
+ - name: Require every validation group to succeed
27
+ env:
28
+ CI_RESULTS: ${{ toJSON(needs) }}
29
+ run: |
30
+ python - <<'PY'
31
+ import json
32
+ import os
33
+ results = json.loads(os.environ['CI_RESULTS'])
34
+ failures = [name for name, job in results.items() if job['result'] != 'success']
35
+ if failures:
36
+ raise SystemExit('Required checks did not pass: ' + ', '.join(failures))
37
+ PY
@@ -0,0 +1,80 @@
1
+ name: dependency compatibility
2
+ on: [workflow_call, workflow_dispatch]
3
+ permissions:
4
+ contents: read
5
+
6
+ jobs:
7
+ modern:
8
+ runs-on: ubuntu-latest
9
+ strategy:
10
+ fail-fast: false
11
+ matrix:
12
+ python-version: ['3.11', '3.15']
13
+ profile: [minimum, latest]
14
+ include:
15
+ - python-version: '3.12'
16
+ profile: starlette-0
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ - uses: astral-sh/setup-uv@v6
20
+ with:
21
+ version: '0.13.6'
22
+ python-version: ${{ matrix.python-version }}
23
+ enable-cache: true
24
+ - name: Resolve fresh dependency endpoints and run the full suite
25
+ run: >-
26
+ uv run --no-project --python ${{ matrix.python-version }} python scripts/test_compatibility.py
27
+ --profile ${{ matrix.profile }} --python ${{ matrix.python-version }}
28
+ --report build/compatibility/modern-${{ matrix.profile }}-${{ matrix.python-version }}.json
29
+ - name: Keep the ordinary lockfile unchanged
30
+ run: git diff --exit-code -- pyproject.toml uv.lock
31
+ - uses: actions/upload-artifact@v4
32
+ if: always()
33
+ with:
34
+ name: modern-${{ matrix.profile }}-${{ matrix.python-version }}
35
+ path: build/compatibility/
36
+ if-no-files-found: warn
37
+
38
+ gino:
39
+ runs-on: ubuntu-latest
40
+ strategy:
41
+ fail-fast: false
42
+ matrix:
43
+ python-version: ['3.11', '3.15']
44
+ profile: [minimum, latest]
45
+ services:
46
+ postgres:
47
+ image: postgres:17
48
+ env:
49
+ POSTGRES_USER: quite_admin
50
+ POSTGRES_PASSWORD: ci-test-only
51
+ POSTGRES_DB: quite_admin_gino_test
52
+ ports:
53
+ - 5432:5432
54
+ options: >-
55
+ --health-cmd "pg_isready -U quite_admin -d quite_admin_gino_test"
56
+ --health-interval 5s
57
+ --health-timeout 5s
58
+ --health-retries 30
59
+ env:
60
+ QUITE_ADMIN_GINO_TEST_DATABASE_URL: postgresql://quite_admin:ci-test-only@127.0.0.1:5432/quite_admin_gino_test
61
+ steps:
62
+ - uses: actions/checkout@v4
63
+ - uses: astral-sh/setup-uv@v6
64
+ with:
65
+ version: '0.13.6'
66
+ python-version: ${{ matrix.python-version }}
67
+ enable-cache: true
68
+ - name: Check GINO endpoints separately from SQLAlchemy 2.x
69
+ run: >-
70
+ uv run --no-project --python ${{ matrix.python-version }} python scripts/test_compatibility.py --legacy
71
+ --profile ${{ matrix.profile }} --python ${{ matrix.python-version }}
72
+ --report build/compatibility/gino-${{ matrix.profile }}-${{ matrix.python-version }}.json
73
+ - name: Keep the ordinary lockfile unchanged
74
+ run: git diff --exit-code -- pyproject.toml uv.lock
75
+ - uses: actions/upload-artifact@v4
76
+ if: always()
77
+ with:
78
+ name: gino-${{ matrix.profile }}-${{ matrix.python-version }}
79
+ path: build/compatibility/
80
+ if-no-files-found: warn
@@ -0,0 +1,81 @@
1
+ name: database contracts
2
+ on: [workflow_call, workflow_dispatch]
3
+ permissions:
4
+ contents: read
5
+
6
+ jobs:
7
+ gino-legacy:
8
+ runs-on: ubuntu-latest
9
+ strategy:
10
+ fail-fast: false
11
+ matrix:
12
+ python-version: ['3.11', '3.12', '3.13', '3.14', '3.15']
13
+ services:
14
+ postgres:
15
+ image: postgres:17
16
+ env:
17
+ POSTGRES_USER: quite_admin
18
+ POSTGRES_PASSWORD: ci-test-only
19
+ POSTGRES_DB: quite_admin_gino_test
20
+ ports:
21
+ - 5432:5432
22
+ options: >-
23
+ --health-cmd "pg_isready -U quite_admin -d quite_admin_gino_test"
24
+ --health-interval 5s
25
+ --health-timeout 5s
26
+ --health-retries 30
27
+ env:
28
+ QUITE_ADMIN_GINO_TEST_DATABASE_URL: postgresql://quite_admin:ci-test-only@127.0.0.1:5432/quite_admin_gino_test
29
+ steps:
30
+ - uses: actions/checkout@v4
31
+ - uses: astral-sh/setup-uv@v6
32
+ with:
33
+ version: '0.13.6'
34
+ python-version: ${{ matrix.python-version }}
35
+ enable-cache: true
36
+ - run: uv sync --locked --no-dev --extra gino-legacy --group gino-check
37
+ - run: uv run --no-sync pytest --confcutdir=tests/gino tests/gino -q
38
+
39
+ contracts:
40
+ runs-on: ubuntu-latest
41
+ strategy:
42
+ fail-fast: false
43
+ matrix:
44
+ include:
45
+ - database: postgresql
46
+ image: postgres:17
47
+ port: 5432
48
+ health: pg_isready -U quite_admin -d quite_admin_test
49
+ - database: mysql
50
+ image: mysql:8.4
51
+ port: 3306
52
+ health: mysqladmin ping -h 127.0.0.1 --silent
53
+ services:
54
+ database:
55
+ image: ${{ matrix.image }}
56
+ env:
57
+ POSTGRES_USER: quite_admin
58
+ POSTGRES_PASSWORD: ci-test-only
59
+ POSTGRES_DB: quite_admin_test
60
+ MYSQL_ROOT_PASSWORD: ci-root-test-only
61
+ MYSQL_USER: quite_admin
62
+ MYSQL_PASSWORD: ci-test-only
63
+ MYSQL_DATABASE: quite_admin_test
64
+ ports:
65
+ - ${{ matrix.port }}:${{ matrix.port }}
66
+ options: >-
67
+ --health-cmd "${{ matrix.health }}"
68
+ --health-interval 5s
69
+ --health-timeout 5s
70
+ --health-retries 30
71
+ env:
72
+ QUITE_ADMIN_TEST_DATABASE_URL: ${{ matrix.database }}://quite_admin:ci-test-only@127.0.0.1:${{ matrix.port }}/quite_admin_test
73
+ steps:
74
+ - uses: actions/checkout@v4
75
+ - uses: astral-sh/setup-uv@v6
76
+ with:
77
+ version: '0.13.6'
78
+ python-version: '3.12'
79
+ enable-cache: true
80
+ - run: uv sync --locked --group database-check
81
+ - run: uv run --group database-check pytest tests/test_adapters.py tests/test_adapter_safety.py tests/test_relations.py tests/test_sql_reflection.py tests/test_concurrency.py tests/test_filters.py tests/test_diagram.py tests/sqlmodel -q
@@ -0,0 +1,90 @@
1
+ name: pages
2
+
3
+ on:
4
+ workflow_run:
5
+ workflows: [ci]
6
+ types: [completed]
7
+ branches: [master]
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+ actions: read
13
+
14
+ concurrency:
15
+ group: github-pages
16
+ cancel-in-progress: false
17
+
18
+ jobs:
19
+ current:
20
+ if: >-
21
+ (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/master') ||
22
+ (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push')
23
+ runs-on: ubuntu-latest
24
+ outputs:
25
+ fresh: ${{ steps.head.outputs.fresh }}
26
+ sha: ${{ steps.head.outputs.sha }}
27
+ steps:
28
+ - uses: actions/github-script@v7
29
+ id: head
30
+ with:
31
+ script: |
32
+ const {data} = await github.rest.repos.getBranch({...context.repo, branch:'master'});
33
+ const sha = context.payload.workflow_run?.head_sha || context.sha;
34
+ const runs = await github.rest.actions.listWorkflowRuns({
35
+ ...context.repo, workflow_id:'ci.yml', head_sha:sha, per_page:100,
36
+ });
37
+ const verified = runs.data.workflow_runs.some(run =>
38
+ run.head_sha === sha && run.conclusion === 'success');
39
+ core.setOutput('fresh', String(data.commit.sha === sha && verified));
40
+ core.setOutput('sha', sha);
41
+
42
+ build:
43
+ needs: current
44
+ if: needs.current.outputs.fresh == 'true'
45
+ runs-on: ubuntu-latest
46
+ steps:
47
+ - uses: actions/checkout@v4
48
+ with:
49
+ ref: ${{ needs.current.outputs.sha }}
50
+ - uses: astral-sh/setup-uv@v6
51
+ with:
52
+ version: '0.13.6'
53
+ python-version: '3.12'
54
+ enable-cache: true
55
+ - run: uv sync --locked
56
+ - uses: actions/setup-node@v4
57
+ with:
58
+ node-version: '24'
59
+ cache: npm
60
+ - run: npm ci
61
+ - run: npm run docs:build
62
+ - run: npm run demo:test
63
+ - uses: actions/configure-pages@v5
64
+ - uses: actions/upload-pages-artifact@v4
65
+ with:
66
+ path: build/docs
67
+
68
+ deploy:
69
+ needs: [current, build]
70
+ runs-on: ubuntu-latest
71
+ permissions:
72
+ contents: read
73
+ pages: write
74
+ id-token: write
75
+ environment:
76
+ name: github-pages
77
+ url: ${{ steps.deployment.outputs.page_url }}
78
+ steps:
79
+ - uses: actions/github-script@v7
80
+ id: head
81
+ env:
82
+ TESTED_SHA: ${{ needs.current.outputs.sha }}
83
+ with:
84
+ script: |
85
+ const {data} = await github.rest.repos.getBranch({...context.repo, branch:'master'});
86
+ core.setOutput('fresh', String(data.commit.sha === process.env.TESTED_SHA));
87
+ - name: Deploy Diplodoc
88
+ if: steps.head.outputs.fresh == 'true'
89
+ id: deployment
90
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,121 @@
1
+ name: publish to PyPI
2
+ on:
3
+ workflow_run:
4
+ workflows: [release]
5
+ types: [completed]
6
+ workflow_dispatch:
7
+ inputs:
8
+ tag:
9
+ description: Published and validated version tag to upload to PyPI
10
+ required: true
11
+ type: string
12
+
13
+ permissions:
14
+ contents: read
15
+ concurrency:
16
+ group: pypi
17
+ cancel-in-progress: false
18
+ env:
19
+ SOURCE_REF: ${{ inputs.tag || github.event.workflow_run.head_sha }}
20
+ REQUESTED_TAG: ${{ inputs.tag }}
21
+
22
+ jobs:
23
+ build:
24
+ if: >-
25
+ github.event_name == 'workflow_dispatch' ||
26
+ (github.event.workflow_run.conclusion == 'success' &&
27
+ (github.event.workflow_run.event == 'push' || github.event.workflow_run.event == 'release') &&
28
+ github.event.workflow_run.head_repository.full_name == github.repository)
29
+ runs-on: ubuntu-latest
30
+ permissions:
31
+ contents: read
32
+ actions: read
33
+ outputs:
34
+ version: ${{ steps.metadata.outputs.version }}
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+ with:
38
+ ref: ${{ env.SOURCE_REF }}
39
+ persist-credentials: false
40
+ - uses: astral-sh/setup-uv@v6
41
+ with:
42
+ version: '0.13.6'
43
+ python-version: '3.12'
44
+ - name: Validate release metadata
45
+ id: metadata
46
+ run: |
47
+ version=$(uv run --no-project python -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')
48
+ tag="v$version"
49
+ if [ -n "$REQUESTED_TAG" ]; then
50
+ test "$tag" = "$REQUESTED_TAG"
51
+ fi
52
+ uv run --no-project python scripts/check_release.py --tag "$tag"
53
+ printf 'version=%s\n' "$version" >> "$GITHUB_OUTPUT"
54
+ printf 'RELEASE_TAG=%s\n' "$tag" >> "$GITHUB_ENV"
55
+ - name: Verify the published tag and validation results
56
+ env:
57
+ GH_TOKEN: ${{ github.token }}
58
+ GH_REPO: ${{ github.repository }}
59
+ SOURCE_SHA: ${{ github.event.workflow_run.head_sha }}
60
+ run: |
61
+ test "$(gh release view "$RELEASE_TAG" --json isDraft --jq '.isDraft')" = false
62
+ commit=$(git rev-parse HEAD)
63
+ test "$(gh api "repos/$GH_REPO/commits/$RELEASE_TAG" --jq '.sha')" = "$commit"
64
+ if [ "$GITHUB_EVENT_NAME" = workflow_run ]; then
65
+ test "$commit" = "$SOURCE_SHA"
66
+ else
67
+ runs=$(gh api "repos/$GH_REPO/actions/workflows/ci.yml/runs?head_sha=$commit&status=success&per_page=1" --jq '.total_count')
68
+ test "$runs" -gt 0 || { echo 'The tagged commit needs a successful full CI run.'; exit 1; }
69
+ fi
70
+ - name: Build one universal wheel and source distribution
71
+ run: uv build
72
+ - name: Check metadata and package contents before uploading
73
+ run: |
74
+ uvx --from 'twine>=6,<7' twine check --strict dist/*
75
+ uv run --no-project python scripts/check_distributions.py
76
+ - uses: actions/upload-artifact@v4
77
+ with:
78
+ name: pypi-distributions
79
+ path: |
80
+ dist/*.whl
81
+ dist/*.tar.gz
82
+ if-no-files-found: error
83
+
84
+ publish:
85
+ needs: build
86
+ runs-on: ubuntu-latest
87
+ environment:
88
+ name: pypi
89
+ url: https://pypi.org/p/quite-admin
90
+ permissions:
91
+ id-token: write
92
+ steps:
93
+ - uses: actions/download-artifact@v4
94
+ with:
95
+ name: pypi-distributions
96
+ path: dist
97
+ - name: Publish verified distributions through Trusted Publishing
98
+ uses: pypa/gh-action-pypi-publish@release/v1
99
+ with:
100
+ skip-existing: true
101
+
102
+ verify:
103
+ needs: [build, publish]
104
+ runs-on: ubuntu-latest
105
+ permissions: {}
106
+ env:
107
+ PACKAGE_VERSION: ${{ needs.build.outputs.version }}
108
+ steps:
109
+ - uses: astral-sh/setup-uv@v6
110
+ with:
111
+ version: '0.13.6'
112
+ python-version: '3.12'
113
+ - name: Install the released package from PyPI outside the checkout
114
+ run: |
115
+ for attempt in 1 2 3 4 5 6; do
116
+ if uv run --no-project --with "quite-admin==$PACKAGE_VERSION" python -I -c 'import os, quite_admin; from importlib import metadata, resources; assert quite_admin.__version__ == metadata.version("quite-admin") == os.environ["PACKAGE_VERSION"]; assert resources.files("quite_admin").joinpath("static/forms.js").is_file(); print("Installed quite-admin", quite_admin.__version__)'; then
117
+ exit 0
118
+ fi
119
+ sleep 10
120
+ done
121
+ exit 1
@@ -0,0 +1,57 @@
1
+ name: release
2
+ on:
3
+ push:
4
+ tags: ['v*']
5
+ release:
6
+ types: [published]
7
+ permissions:
8
+ contents: read
9
+ concurrency:
10
+ group: release-${{ github.ref }}
11
+ cancel-in-progress: false
12
+ env:
13
+ RELEASE_TAG: ${{ github.event.release.tag_name || github.ref_name }}
14
+
15
+ jobs:
16
+ metadata:
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+ with:
21
+ ref: ${{ env.RELEASE_TAG }}
22
+ - uses: astral-sh/setup-uv@v6
23
+ with:
24
+ version: '0.13.6'
25
+ python-version: '3.12'
26
+ - run: uv run --no-project python scripts/check_release.py --tag "$RELEASE_TAG"
27
+
28
+ checks:
29
+ needs: metadata
30
+ uses: ./.github/workflows/ci.yml
31
+
32
+ publish:
33
+ if: github.event_name == 'push'
34
+ needs: [metadata, checks]
35
+ runs-on: ubuntu-latest
36
+ permissions:
37
+ contents: write
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+ with:
41
+ ref: ${{ env.RELEASE_TAG }}
42
+ - uses: astral-sh/setup-uv@v6
43
+ with:
44
+ version: '0.13.6'
45
+ python-version: '3.12'
46
+ - run: uv run --no-project python scripts/check_release.py --tag "$RELEASE_TAG" --notes release-notes.md
47
+ - name: Publish release with changelog; GitHub supplies source archives
48
+ env:
49
+ GH_TOKEN: ${{ github.token }}
50
+ GH_REPO: ${{ github.repository }}
51
+ run: |
52
+ if gh release view "$RELEASE_TAG" > /dev/null 2>&1; then
53
+ gh release edit "$RELEASE_TAG" --title "Quite Admin $RELEASE_TAG" --notes-file release-notes.md
54
+ else
55
+ gh release create "$RELEASE_TAG" --verify-tag --draft --title "Quite Admin $RELEASE_TAG" --notes-file release-notes.md
56
+ fi
57
+ gh release edit "$RELEASE_TAG" --draft=false --latest
@@ -0,0 +1,50 @@
1
+ name: dependency security
2
+ on:
3
+ workflow_dispatch:
4
+ workflow_call:
5
+ schedule:
6
+ - cron: '17 6 * * 1'
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ python-audit:
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ include:
17
+ - adapter: modern
18
+ export-options: --extra all --all-groups
19
+ - adapter: gino-legacy
20
+ export-options: --no-dev --extra gino-legacy --group gino-check
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ - uses: astral-sh/setup-uv@v6
24
+ with:
25
+ version: '0.13.6'
26
+ python-version: '3.12'
27
+ enable-cache: true
28
+ - run: uv export --locked ${{ matrix.export-options }} --no-emit-project -o requirements-audit.txt
29
+ - run: uvx --from pip-audit==2.10.1 pip-audit -r requirements-audit.txt --require-hashes --disable-pip --strict
30
+
31
+ documentation-audit:
32
+ runs-on: ubuntu-latest
33
+ steps:
34
+ - uses: actions/checkout@v4
35
+ - uses: actions/setup-node@v4
36
+ with:
37
+ node-version: '24'
38
+ cache: npm
39
+ - run: npm ci
40
+ - run: npm audit --audit-level=high
41
+
42
+ dependency-review:
43
+ if: github.event_name == 'pull_request' && !github.event.repository.private
44
+ runs-on: ubuntu-latest
45
+ steps:
46
+ - uses: actions/checkout@v4
47
+ - uses: actions/dependency-review-action@v5
48
+ with:
49
+ fail-on-severity: moderate
50
+ fail-on-scopes: runtime, development, unknown
@@ -0,0 +1,98 @@
1
+ name: tests
2
+ on: [workflow_call, workflow_dispatch]
3
+
4
+ permissions:
5
+ contents: read
6
+
7
+ jobs:
8
+ pytest:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ fail-fast: false
12
+ matrix:
13
+ python-version: ['3.11', '3.12', '3.13', '3.14', '3.15']
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: astral-sh/setup-uv@v6
17
+ with:
18
+ version: '0.13.6'
19
+ python-version: ${{ matrix.python-version }}
20
+ enable-cache: true
21
+ - run: uv sync --locked
22
+ - run: uv run ruff check src tests examples scripts
23
+ - run: uv run ruff format --check src tests examples scripts
24
+ - run: uv run python scripts/check_release.py
25
+ - run: uv run python scripts/check_api.py --profile modern
26
+ - run: uv run pytest -q
27
+
28
+ logging-backends:
29
+ runs-on: ubuntu-latest
30
+ steps:
31
+ - uses: actions/checkout@v4
32
+ - uses: astral-sh/setup-uv@v6
33
+ with:
34
+ version: '0.13.6'
35
+ python-version: '3.12'
36
+ enable-cache: true
37
+ - run: uv sync --locked --group logging-check
38
+ - run: uv run --group logging-check python -c 'import picologging, structlog, loguru'
39
+ - run: uv run --group logging-check pytest tests/test_logging.py -q
40
+
41
+ docs:
42
+ runs-on: ubuntu-latest
43
+ steps:
44
+ - uses: actions/checkout@v4
45
+ - uses: astral-sh/setup-uv@v6
46
+ with:
47
+ version: '0.13.6'
48
+ python-version: '3.12'
49
+ enable-cache: true
50
+ - run: uv sync --locked
51
+ - uses: actions/setup-node@v4
52
+ with:
53
+ node-version: '24'
54
+ cache: npm
55
+ - run: npm ci
56
+ - run: npm run docs:build
57
+ - run: npm run demo:test
58
+ - uses: actions/upload-artifact@v4
59
+ with:
60
+ name: quite-admin-docs
61
+ path: build/docs
62
+ if-no-files-found: error
63
+
64
+ browser:
65
+ runs-on: ${{ matrix.os }}
66
+ strategy:
67
+ fail-fast: false
68
+ matrix:
69
+ include:
70
+ - browser: chromium
71
+ os: ubuntu-latest
72
+ - browser: firefox
73
+ os: ubuntu-latest
74
+ - browser: webkit
75
+ os: macos-latest
76
+ steps:
77
+ - uses: actions/checkout@v4
78
+ - uses: astral-sh/setup-uv@v6
79
+ with:
80
+ version: '0.13.6'
81
+ python-version: '3.12'
82
+ enable-cache: true
83
+ - run: uv sync --locked
84
+ - uses: actions/setup-node@v4
85
+ with:
86
+ node-version: '24'
87
+ cache: npm
88
+ - run: npm ci
89
+ - run: npx --no-install playwright install --with-deps ${{ matrix.browser }}
90
+ - run: npm run browser:test -- --project=${{ matrix.browser }}
91
+ - uses: actions/upload-artifact@v4
92
+ if: failure()
93
+ with:
94
+ name: browser-${{ matrix.browser }}
95
+ path: |
96
+ test-results/
97
+ playwright-report/
98
+ if-no-files-found: warn
@@ -0,0 +1,17 @@
1
+ .venv/
2
+ .venv-gino/
3
+ .venv-gino-legacy/
4
+ __pycache__/
5
+ *.py[cod]
6
+ .pytest_cache/
7
+ .ruff_cache/
8
+ dist/
9
+ *.egg-info/
10
+ *.db
11
+ .env
12
+ artifacts/
13
+ .idea/
14
+ node_modules/
15
+ build/
16
+ test-results/
17
+ playwright-report/
@@ -0,0 +1,25 @@
1
+ # quite-admin
2
+
3
+ - Support Python 3.11–3.15, FastAPI and Litestar. Keep the core ORM-independent; access data through adapters.
4
+ - Preserve authentication, authorization, CSRF, field restrictions and CSP. Never log passwords, tokens or record values.
5
+ - Document user-facing changes in both Diplodoc languages: `docs/en` is primary, `docs/ru` is the translation. Update both navigation files when adding pages.
6
+ - Verify changed behavior with integration tests. Do not suppress dependency warnings.
7
+ - Python checks: `uv run pytest -q`, `uv run ruff check src tests examples scripts`, `uv run ruff format --check src tests examples scripts`.
8
+ - Run `npm run docs:build` after documentation changes.
9
+
10
+ ## Versioning
11
+
12
+ - Use PEP 440-compatible `MAJOR.MINOR.PATCH` versions.
13
+ - `PATCH`: backward-compatible bug fixes, security fixes and runtime dependency fixes.
14
+ - `MINOR`: new features, options and adapters that preserve existing default behavior.
15
+ - `MAJOR`: incompatible public API or behavior changes, feature removal, or dropping Python / framework / ORM support. Before `1.0`, bump `MINOR` for these changes; moving to `1.0` requires a separate decision about API stability.
16
+ - Reset `MINOR` and `PATCH` when bumping `MAJOR`; reset `PATCH` when bumping `MINOR`.
17
+ - Documentation-only changes, tests, behavior-preserving refactoring and development tooling updates do not require a library version bump. A dependency upgrade alone does not imply `MAJOR`: assess the library's compatibility.
18
+ - Plan the version relative to the latest released version, choosing the highest applicable bump. If there is no release, use the previous recorded version. Bump once per batch of changes; the latest finalized release is `0.4.1` (2026-11-01); subsequent changes must target a higher version using the rules above. Keep the version visible in README and record changes in CHANGELOG.md.
19
+ - The source of truth is `project.version` in `pyproject.toml`. Update `src/quite_admin/__init__.py::__version__` in sync and regenerate `uv.lock` with `uv lock`; check version references in the UI and documentation.
20
+ - Every version-changing commit must update `pyproject.toml`, README, `__version__` and `uv.lock` together. Never change only the displayed README version; verify that all library version references agree before committing.
21
+ - `package.json` and `package-lock.json` belong to documentation tooling and need not match the Python package version. Update lockfiles through their package managers.
22
+ - Document breaking changes and migration steps in EN/RU. Create release tags and publish only when explicitly requested by the user.
23
+ - Preserve the public API baseline in `api/*-0.4.json`; run `python scripts/check_api.py --profile modern`. Keep required adapter methods separate from optional capabilities and preserve template API 1. See `docs/en/api-stability.md` for deprecation and migration rules.
24
+ - Run `python scripts/check_release.py` before a version/release commit; finalize the changelog date before tagging. Tagged releases use `.github/workflows/release.yml`; version updates alone never publish.
25
+ - GitHub releases retain only automatic source archives. After the complete validation gate, a version-tag push publishes the GitHub release with the matching changelog. The separate `pypi.yml` workflow builds one wheel/sdist pair, validates metadata 2.4 and clean installations, and publishes to PyPI through the `pypi` environment and Trusted Publishing. Never build packages in each Python matrix entry or store a PyPI API token in the repository.