diff --git a/.github/workflows/generate-erd.yaml b/.github/workflows/generate-erd.yaml new file mode 100644 index 000000000..e6c2419f3 --- /dev/null +++ b/.github/workflows/generate-erd.yaml @@ -0,0 +1,61 @@ +name: Generate Graph Models + +on: + push: + paths: + - "backend/apps/*/models/*.py" + workflow_dispatch: + +jobs: + generate-graph: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Install Poetry + run: pipx install poetry + + - name: Install Graphviz + run: sudo apt-get install -y graphviz + + - name: Set up Python + uses: actions/setup-python@v5 + with: + cache: "poetry" + cache-dependency-path: backend/poetry.lock + python-version: "3.13" + + - name: Install Dependencies + working-directory: backend + run: poetry install --no-root + + - name: Prepare Secrets + run: | + echo "DJANGO_SENTRY_DSN=None" >> $GITHUB_ENV + echo "DJANGO_ALGOLIA_APPLICATION_ID=None" >> $GITHUB_ENV + echo "DJANGO_ALGOLIA_WRITE_API_KEY=None" >> $GITHUB_ENV + echo "DJANGO_DB_PASSWORD=None" >> $GITHUB_ENV + echo "DJANGO_OPEN_AI_SECRET_KEY=None" >> $GITHUB_ENV + echo "DJANGO_SECRET_KEY=None" >> $GITHUB_ENV + echo "DJANGO_SLACK_BOT_TOKEN=None" >> $GITHUB_ENV + echo "DJANGO_SLACK_SIGNING_SECRET=None" >> $GITHUB_ENV + + - name: Generate Graph Model Image + working-directory: backend + run: | + poetry run python manage.py graph_models -a -o ../docs/models_relations.png + + - name: Upload Graph Image as Artifact + uses: actions/upload-artifact@v4 + with: + name: models-relations + path: docs/models_relations.png + + - name: Commit and Push Updated Image + run: | + git config --global user.name "GitHub Actions" + git config --global user.email "actions@github.com" + git add docs/models_relations.png + git diff --staged --quiet || (git commit -m "Update models relations graph" && git push) diff --git a/backend/poetry.lock b/backend/poetry.lock index 66f2c6ea5..7d7a77e5a 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" @@ -773,6 +773,21 @@ files = [ asgiref = ">=3.6" django = ">=4.2" +[[package]] +name = "django-extensions" +version = "3.2.3" +description = "Extensions for Django" +optional = false +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "django-extensions-3.2.3.tar.gz", hash = "sha256:44d27919d04e23b3f40231c4ab7af4e61ce832ef46d610cc650d53e68328410a"}, + {file = "django_extensions-3.2.3-py3-none-any.whl", hash = "sha256:9600b7562f79a92cbf1fde6403c04fee314608fefbb595502e34383ae8203401"}, +] + +[package.dependencies] +Django = ">=3.2" + [[package]] name = "django-filter" version = "25.1" @@ -2257,6 +2272,20 @@ files = [ [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" +[[package]] +name = "pydotplus" +version = "2.0.2" +description = "Python interface to Graphviz's Dot language" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "pydotplus-2.0.2.tar.gz", hash = "sha256:91e85e9ee9b85d2391ead7d635e3d9c7f5f44fd60a60e59b13e2403fa66505c4"}, +] + +[package.dependencies] +pyparsing = ">=2.0.1" + [[package]] name = "pygithub" version = "2.6.1" @@ -2325,6 +2354,21 @@ cffi = ">=1.4.1" docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] +[[package]] +name = "pyparsing" +version = "3.2.3" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf"}, + {file = "pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + [[package]] name = "pytest" version = "8.3.5" @@ -3157,4 +3201,4 @@ propcache = ">=0.2.1" [metadata] lock-version = "2.1" python-versions = "^3.13" -content-hash = "8dc9e85a835bc82849fe37e2adf4fa037d1be36fcbbc2208cc105386aa4b249e" +content-hash = "99c2ee82d2a3a763131b0006fb31451b0ca9a41b2a79a6e4c2a16273ae9c007a" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index cd0e91f1e..6eed6cef0 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -48,6 +48,8 @@ pyyaml = "^6.0.2" requests = "^2.32.3" sentry-sdk = { extras = ["django"], version = "^2.20.0" } slack-bolt = "^1.22.0" +django-extensions = "^3.2.3" +pydotplus = "^2.0.2" [tool.poetry.group.dev.dependencies] djlint = "^1.36.4" diff --git a/backend/settings/local.py b/backend/settings/local.py index 054d17159..63a005e17 100644 --- a/backend/settings/local.py +++ b/backend/settings/local.py @@ -22,3 +22,5 @@ class Local(Base): PUBLIC_IP_ADDRESS = values.Value() SLACK_COMMANDS_ENABLED = True SLACK_EVENTS_ENABLED = True + + INSTALLED_APPS = (*Base.INSTALLED_APPS, "django_extensions") # type: ignore[assignment] diff --git a/docs/models_relations.png b/docs/models_relations.png new file mode 100644 index 000000000..d18086c4f Binary files /dev/null and b/docs/models_relations.png differ