Version History and Release Notes ================================= Releases of [SaaS Pegasus: The Django SaaS Boilerplate](https://www.saaspegasus.com/) are documented here. ## Version 2025.6.2 This hotfix release addresses two minor issues in the 2025.6 release: - Remove breaking reference to `.babelrc` in `Dockerfile.web` on Vite builds. This was causing deployments to fail on some Docker-based platforms. - Always add `gevent` dependency to production requirements if using celery. This fixes an issue running celery in production on certain deployment platforms. Thanks Justin and Eugene for the bug reports! *June 25, 2025* ## Version 2025.6.1 This is a hotfix release which addresses two minor issues: - Fix `make npm-install` and `make npm-uninstall` commands when using vite as a bundler. Thanks Matt for reporting! - Fix broken dark mode behavior on Tailwind when attempting to disable it. Thanks Wik for the report and fix! *June 23, 2025* ## Version 2025.6 This release hardens the production Celery set up, expands AI-development tooling, improves production support for the standalone React front end, and extends the ecommerce application. Read on for details! ### Celery improvements - Celery periodic tasks can now be configured via `settings.SCHEDULED_TASKS` and synchronized with a new management command (`./manage.py bootstrap_celery_tasks`). The previous migration files that created celery periodic tasks have been removed. - The Celery gunicorn worker pool changed from the default of 'prefork' to 'gevent' in production, and the concurrency was increased. This should be a more scalable setup for most projects, though may need to be changed for projects that are heavily CPU-bound. - Because of the above change, a separate worker for Celery Beat has been added to all production deploy environments (because beat can't be run with the gevent pool). - Updated the [Celery documentation](./celery.md) to reflect these changes. ### AI-Coding improvements - **Added an optional Claude Code Github workflow**. When enabled, you can mention @claude on a Github pull request or issue to trigger a Claude Code update. Learn more [in the docs here](./ai/development.md#the-github-workflow-file). - **Added optional support for JetBrains / PyCharm Junie AI rules files.** [Docs](./ai/development.md#working-with-junie) - Edited and expanded the AI rules files based on various user feedback (thanks to many who have contributed to this). ### Standalone front end improvements These updates affect the [standalone React front end](./experimental/react-front-end.md). - Updated the front end CSS to build the files directly in the front end (and import relevant files from the Django app in `index.css`), rather than including the built Django CSS files directly. - Some required Tailwind CSS files in the `assets` directory will be included if you use the standalone front end even if you build for a different framework. - Added tailwindcss, the typography plugin, and daisyui as explicit dependencies (and plugins) to the front end to enable the above change. - Upgraded all JavaScript dependencies in the front end. - Removed unnecessary default styles from `index.css`. - Updated front end to use aliases for the "assets" directory. Also updated `tsconfig.json` to handle this. - Updated `vite.config.ts` to fix various build issues if the parent `node_modules` isn't available. - Fixed the default values of `FRONTEND_ADDRESS` and related values in `settings.py` and `.env` files to point to "http://localhost:5174" (instead of port 5173). - Added `CSRF_COOKIE_DOMAIN`, `CORS_ALLOWED_ORIGINS`, and `SESSION_COOKIE_DOMAIN` to `settings.py` using environment variables. These must be customized when deploying the standalone front end. - Updated Kamal's `deploy.yml` to include default values for the above settings. - **Added initial documentation on [deploying the standalone front end to production](./experimental/react-front-end.md#deployment).** ### Other updates - **Added a digital download example to the ecommerce application.** You can now associate a file with ecommerce products and only people who have purchased the product will be able to access it. - Also added tests for this workflow. - Added a private storage backend, for storing private files on S3-compatible storage backends (used by the above). - Upgraded most Python dependencies to their latest versions. - Fix `target-version` in `pyproject.toml` to match the currently recommended Python 3.12. Thanks Finbar for reporting! - Fixed a bug where group chat avatars were incorrectly styled on Tailwind builds. Added a new `pg-avatar` CSS class to handle this. - Made some updates Digital Ocean deployments: - Switched Redis to Valkey, and upgraded it to version 8. - Upgraded Postgres to version 17. - Updated the [Digital Ocean deployment docs](./deployment/digital-ocean.md) to reflect the latest changes. - Fixed email verification emails when `ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED = True`. Thanks Justin for reporting and helping with the fix! - Removed default font-weight styling from `email_template_base.html`. - Api keys associated with inactive users will no longer pass API permission checks. Thanks Brennan for the suggestion! - Removed unused `.babelrc` file if not building with Webpack. - Automatically confirm user emails when they create accounts through the invitation acceptance workflow, since they can only get the invitation URL from the email link. ### Upgrading If your project has existing migration files that create celery tasks (e.g. `/apps/subscriptions/migrations/0001_celery_tasks.py`), you should leave them in your repository to prevent issues running future migrations. The tasks themselves are unaffected, since they live in the database. *June 10, 2025* ## Version 2025.5.1 This is a minor bugfix release on top of 2025.5. - Removed bad reference to Modals in `site.js`. Thanks Jacob for reporting! - Fixed Python Celery setup in `build_celery.sh` when using `uv` (Render deployments only). Thanks Jacob for reporting! - Fixed issue with the shadcn dashboard caused by a missing `{% vite_react_refresh %}` tag. Thanks Shoaib for reporting! *May 16, 2025* ## Version 2025.5 This release has a few big updates: ### Use Vite instead of Webpack for building the front end This release adds the option to use [Vite](https://vite.dev/) as a bundler instead of Webpack. Vite is a modern build tool that adds a few key benefits over the Webpack build system: 1. It is much faster than Webpack. 2. Hot Module Replacement (HMR)---a development feature that lets code changes in your front end files automatically update without a full-page reload. 3. Code splitting---a production feature that breaks your front end files into individual bundles that encapsulate code dependencies. This leads to less redundant JavaScript and faster page loads. You can watch the video below for a walkthrough of these benefits and how they work in the new setup.
You can also see the overhauled [front end documentation](/front-end/overview.md) and [Vite-specific guidance](/front-end/vite.md) for more details. ### Gitlab CI support You can now run CI on Gitlab in addition to Github. Gitlab's CI will run your tests, linting, and build / type-check your front end files. Thanks to Paolo and Simon for contributing to this feature! ### Retiring the Bootstrap Material Theme **The material theme for Bootstrap has been deprecated.** This means that the theme will be in maintenance-only mode, and support will eventually be dropped (probably in 6-12 months). Existing projects can continue using the theme, but new projects should not, and new Pegasus features will eventually not be developed and tested on the theme. Dropping support for this theme was a difficult decision. The main reason it was made is that several Pegasus customers have complained about the lack of documentation and support for this theme from its maintainer, Creative Tim. Additionally, their process around updating the theme has involved releasing large, poorly-documented updates which have been difficult to incorporate back into Pegasus. If you would like help migrating off this theme, you can reach out via standard support channels. ### Complete changelog **Changes related to Vite support** - **Added Vite as an option for your front end build system. See [the front end](/front-end/overview.md) and [vite-specific docs](/front-end/vite.md) for details.** - **`window.SiteJS` is now populated explicitly in JavaScript files (in addition to webpack's library support, which does not work with Vite builds).** - Affected files include: `app.js` (`window.SiteJS.app`), `pegasus.js` (`window.SiteJS.pegasus`) - Imports in those files were also renamed to avoid namespace confilcts. - Updated all JavaScript files using JSX to have a `.jsx` extension. - Removed legacy Vue2 code and imports from the Vue example. - Removed unused imports shadcn components. - Removed leading tilde ("~" character) from CSS imports in various places. - Changed CSS imports in JavaScript files from `require` to `import`. - Fixed a few small React warnings/issues in the AI chat app. - Removed no longer needed `vue-template-compiler` dependency. - **Updated the standalone front end to run on port 5174 to not conflict with the default vite port.** **Other Changes** - **Added "Gitlab" as an option for CI.** (Thanks Paolo and Simon!) - **Deprecated the Material Bootstrap theme.** - **Upgraded all Python packages to the latest versions, including Django 5.2.** - **Upgraded all npm packages to the latest versions.** - **Updated all `blocktranslate` tags to use the `trimmed` option for easier translation.** - Added explicit width and height to some svgs to slightly improve styling when CSS is not present. - Made minor updates to AI rules files. - Use the new `ACCOUNT_SIGNUP_FIELDS` setting to configure sign up fields and removed usages of deprecated allauth fields. - **Removed `project_settings` from the `project_meta` context processor.** This was previously only used to pass the now-deprecated `ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE` setting to sign up templates. The sign up templates now render the second password field based on the form value. ### Upgrading For help switching from Webpack to Vite, see [the Webpack to Vite migration guide](/front-end/migrating.md). *May 15, 2025* ## Version 2025.4.4 This is another minor release: - Stop dynamically setting user/group ID in the `Makefile` and just default to `1000`. The dynamic ID assignment was continuing to cause issues on certain MacOS environments. - Add `make build-api-client` target even when not using Docker. - Added additional guidance on Pegasus's Django model conventions to the Python AI rules. *May 5, 2025* ## Version 2025.4.3 This is another bugfix release: - Make the user/group creation more resilient in development Docker containers, which fixes a permissions issue on MacOS in certain environments. Thanks Chris for reporting! - Add `architecture.md` to cursor rules directory. *May 1, 2025* ## Version 2025.4.2 This is a bugfix release that addresses a few problems in the most recent build: - Moved the new `CustomHeadlessAdapter` to `users/adapters.py` to fix an issue with it not being available if you built without teams enabled. Thanks Alex for reporting! - Remove source maps for JavaScript bundles in production. This results in substantially smaller production bundle sizes. Thanks Jan for reporting! - Automatically do a best effort to set the user/group ID used by the development docker container in the `Makefile`. Thanks Jacob for suggesting! For the source map fix, you can change the "devtool" setting in `webpack.config.js` to this: ```javascript devtool: process.env.NODE_ENV === 'production' ? false : "eval-cheap-source-map", ``` *Apr 29, 2025* ## Version 2025.4.1 This is a big release with a few major updates. ### Team invitation workflow changes The workflow around new users joining teams and accepting invitations has been streamlined based on user feedback. For a summary of the changes you can watch [this walkthrough](https://youtu.be/qxr_WdQEL2g) or read below. Key user-facing changes: - **When a user signs up with a pending invitation they will be redirected to view it before creating their first team.** - **Accepting an invitation requires having a verified email address for the email it was sent to.** - Users can view pending invitations for any of their email addresses from the team selector dropdown. - Inviting an email address of someone who's already in a team will show an error message that they are already part of the team. In addition, the following fixes and code updates were made: - Added an API and serializer for accessing the logged-in user's invitations, used by the React view. - React: renamed `getInviteUrl` helper JS function to `getResendInviteUrl`. *Thanks to EJ, Geoff, Valics, Simon, Arno, and possibly others who contributed ideas and feedback on the design of these changes.* ### API authentication and Standalone front end updates The [Standalone React Front end](./experimental/react-front-end.md) underwent a major overhaul. Importantly, it now uses [allauth headless](https://docs.allauth.org/en/dev/headless/index.html) instead of a custom `dj-rest-auth` and custom authentication APIs. On top of this, support for many new authentication workflows was added to the standalone front end, including email confirmation, password reset, and social authentication. The standalone front end---which is still in experimental mode---is now close-to-parity with the Django authentication system. Details: - **Enabled and configured [allauth headless](https://docs.allauth.org/en/dev/headless/index.html)** (if authentication APIs are enabled or using the standalone front end). - **Removed `dj-rest-auth` and `djangorestframework-simplejwt` and associated setup code. Auth now uses allauth headless and sessions by default.** - **Removed the `apps/authentication` app and associated api client code.** - **Updated the standalone front end to use an authentication system against allauth headless and added support for email confirmation, social authentication and password reset.** These changes borrow heavily from the [allauth example](https://github.com/pennersr/django-allauth/tree/main/examples/react-spa) project, and involve a large number of code-level changes which are not fully outlined here, though some of the larger ones are listed below: - Added a `CustomHeadlessAdapter` class to add the user's profile picture to the API. - Removed translation markup from JavaScript code that is shared with the standalone front end. Translations are not supported, currently. - Upgraded eslint-related libraries. - Updated `.eslintrc.cjs` to `eslint.config.mjs` and tweaked the configuration settings. - Show more/better validation errors on login, signup, etc. - Changed `ProtectedRoute` to `AuthenticatedRoute`. - Added templates and components for various new authentication workflows (email confirmation, password reset, etc.). - Added an `ACCOUNT_USER_DISPLAY` setting. - Updated [the standalone front end docs](./experimental/react-front-end.md) to reflect the latest setup. ### Djstripe upgrade and webhook updates This release upgrades `dj-stripe` to version 2.9 and migrates to dj-stripe's database-backed webhooks. This lets you set up multiple webhook endpoints/secrets, if desired. See the upgrade section below for details on updating. Details: - **Upgraded dj-stripe to version 2.9** - **Webhook endpoints now need to be configured in the database instead of having a single global endpoint.** See [the updated subscription webhooks documentation](/subscriptions.md#webhooks) for more details. - Updated webhook handling for subscriptions and ecommerce purchases to be compatible with the above model. - Added a `bootstrap_dev_webhooks` management command to help set up `djstripe` webhooks for development. - Added `apps.utils` to `settings.INSTALLED_APPS` so that management commands inside it are picked up. - Removed the no-longer used `DJSTRIPE_WEBHOOK_SECRET` setting and environment variable. - Upgraded `stripe` to version `11.6` (there is [a bug with djstripe and the latest `12.0` release](https://github.com/dj-stripe/dj-stripe/issues/2153)) - Updated the [subscription docs](/subscriptions.md#webhooks) to reflect the latest changes for setting up webhooks in dev and production. ### Ruff linting updates The ruff linting rules were expanded and code has been modified to pass the revised ruleset. This leads to cleaner, more consistent code across the project and should make future Pegasus merges/upgrades smoother. Details: - **Updated the default ruff rules to enable all of the [E (error) Rules](https://docs.astral.sh/ruff/rules/#error-e), as well as the [UP (pyupgrade) Rules](https://docs.astral.sh/ruff/rules/#pyupgrade-up), [B (flake8-bugbear) Rules](https://docs.astral.sh/ruff/rules/#flake8-bugbear-b), and [SIM (flake8-simplify) rules](https://docs.astral.sh/ruff/rules/#flake8-simplify-sim), in addition to the already-enabled [F (Pyflakes) Rules](https://docs.astral.sh/ruff/rules/#pyflakes-f), and [I (isort) Rules](https://docs.astral.sh/ruff/rules/#isort-i).** - These lead to some minor code changes, including: - Use `contextlib.suppress` in a few places instead of the previous exception handling - Use `raise ... from` in several places for more explicit exception handling. - Combined some nested if statements into single lines. - Use `super()` instead of `super(C, self)` - Use f-strings instead of percent style format strings when possible. - Use `Type | OtherType` instead of `Union[Type, OtherType]` in type hints - Use core types for `list`, `dict` etc. instead of the type classes. - Define classes without the object base class. - Increased strictness around line lengths. - Changed rule definition from `extend-select` to `select` based on [ruff's recommendations](https://docs.astral.sh/ruff/linter/#rule-selection). ### Other updates - **Change: Upgraded npm to the latest version (11.3) in Docker containers and docs.** - **Change: Added a honeypot field to the sign up form to help reduce bot/spam sign ups.** (Thanks Chris and Stian for suggesting!) - Change: Added an "@" alias for the `assets/javascript` folder and started using it in imports. - Change: Updated development Docker setup to run as the logged-in user (under a `django` user account) instead of root. This should help with file ownership permissions being assigned to root after running the project with Docker. Thanks Finbar and Jacob for the suggestion and help with this! - Change: Removed the "app-card" styling from the loading widget to make it more versatile. - Change: Tweaked whitespace in a few templates to be more consistent across the project. - Change: Use `blocktranslate trimmed` instead of `blocktranslate` in some Django templates. - Change: Updated the output of `bootstrap_subscriptions` to communicate that only subscription products should be added to `ACTIVE_PRODUCTS`. - **Fix: Changed reference of `stripe.Invoice.upcoming` to `stripe.Invoice.create_preview` since Stripe [deprecated the upcoming invoice API](https://docs.stripe.com/changelog/basil/2025-03-31/invoice-preview-api-deprecations).** - This fixes an issue with loading the "manage subscription" page when using the latest Stripe API version. - Fix: Added `DEBUG=false` to `heroku.yml` setup section, which helps enforce that debug is disabled when running `collectstatic`. This helps avoid "No module named 'daphne'" errors in async deployments. Thanks Abhishek for reporting! - Fix: The `dark_mode_selector.html` component is no longer included if you have disabled dark mode. - Fix: Improved chat height styling on mobile screens to avoid extra scrolling. - Fix: Updated the migration that creates the default Site object to also update the table sequence ID. Thanks Julian and Geoff for the suggestion and help with this! - Fix: Fixed a test case in `test_member_management` that wasn't getting properly exercised. - Fix: Deleted the unused `_create_api_keys_if_necessary` function in `bootstrap_subscriptions.py` - Fix: Fixed the hover text color of the `.pg-button-danger` CSS class styles on tailwind builds. ### Upgrading There are several changes in this release that may require additional steps during the upgrade process. To help with this, I recorded a video walkthrough of myself upgrading one of my own projects, which you can watch below:
#### Authentication APIs If you were using Pegasus's [standalone React front end](./experimental/react-front-end.md) then your setup should work out of the box after upgrading. If you were using the `dj-rest-auth` app and previous authentication APIs in a different way, then you will need to either: 1. Update the client code to work with allauth headless. This can be done by referring to the example front end and [allauth documentation](https://docs.allauth.org/en/dev/headless/index.html). 2. Restore the previous implementation of the authentication APIs. This can be achieved by *rejecting* the proposed changes to remove the `apps.authentication` app and library dependencies/setup during the upgrade process. #### Djstripe and Webhooks There are a few issues you might run into with the dj-stripe upgrade. **Database Migrations** If you get an `InconsistentMigrationHistory` running `manage.py migrate` on your database, look for any diffs in your existing migration files that change the `djstripe` dependency from `0012_2_8` to `0014_2_9a`, and then revert these changes back to `0012_2_8`. **Webhooks** The most recent dj-stripe has disabled the global webhook support in favor of database-backed webhooks. These are more versatile, secure, and easier to set up, but require a migration from the previous set up. To migrate your webhooks, follow the instructions to set up a new webhook endpoint from the [subscriptions docs](./subscriptions.md#webhooks-in-production) and then delete your previous webhook endpoint. There is a complete walkthrough of this process in the video above. **If you fail to do this your webhooks will stop working in production.** #### Formatting and linting All Pegasus code should be updated to pass the new ruff linting configuration, but the configuration changes might cause build failures on code that has been added/modified. Many fixes can be automated by running: ``` (uv run) ruff check --fix --unsafe-fixes ``` On the upgraded codebase and reviewing the changes made. However, some errors will likely require manual fixing, which can be done by reading the output and making the suggested change (or even giving the task to an LLM). You can see how I did this process with Claude code in the above video. Alternatively, you can modify the `[tool.ruff.lint]` section of `pyproject.toml` to remove any categories of fixes you don't want to turn on for your project. *April 24, 2025* ## Version 2025.4 The main feature of this release is improved support for AI tools and coding assistants. This release adds a suite of rules files that can be used with Cursor, Claude Code, or other AI-enabled IDEs. It also adds an MCP configuration for interfacing with your development database and controlling a web browser. These options are configurable via new project settings. Watch a demo below, or check out the new [AI tool docs](/ai/development.md).
### Added - **Optional rules files and MCP configuration for Cursor or Claude.** - These files will continue to be modified and iterated on as more developers use them and provide feedback.settings ### Changed - Improved default file input styles. - Add front end install / build to `make init`. (Thanks Jacob for reporting!) - Bumped `vite` used by the standalone front end to the latest version. - Upgraded several Python packages to their latest versions. - Removed unused `postcss.config.js` file from the front end. (Thanks Jacob for reporting!) ### Fixed - **Fixed a potential XSS vulnerability issue with `markdown_tags` not properly escaping vulnerable tags.** This issue existed if you were using the AI chat UI, or built other functionality on top of that library. All markdown is now sanitized with `nh3`. (Thanks Mitja for reporting!) - Also added tests for this functionality. ### Translation Creator updates A number of new features were added to [Translation Creator](https://www.saaspegasus.com/store/product/translation-creator/) this month. Big thanks to community member Valics who contributed the first draft of most of these updates. - **Upgraded to the latest Pegasus, including Tailwind 4 and DaisyUI 5.** - **Translations will now retain comments.** - **Added pagination, sort, and filtering to the translations view.** - Added the ability to delete projects and clear translations. - Updated the DB constraint to use a hash of the input text instead of the text itself, which improves performance and fixes a bug with long translations. - Added / updated test cases. *April 4, 2025* ## Version 2025.3 This release upgrades TailwindCSS to version 4 (and DaisyUI to Version 5). It also has several minor updates and fixes. ### Tailwind 4 Update Pegasus now runs on Tailwind V4! This comes with [a huge number of improvements](https://tailwindcss.com/blog/tailwindcss-v4), including much faster build times, simplified tooling, automatic content detection, and more. Tailwind and DaisyUI were upgraded using the associated guides ([Tailwind](https://tailwindcss.com/docs/upgrade-guide), [DaisyUI](https://daisyui.com/docs/upgrade/)). There is also an [upgrade guide for Pegasus apps](./css/tailwind.md#upgrading-from-tailwind-3-to-4). Here's a detailed breakdown of the changes: - **Upgraded to Tailwind 4 and DaisyUI 5.** - **Changed how tailwind is imported and customized in `site-tailwind.css` to match the V4 guidance.** - **Removed `content` section of `tailwind.config.js`. Tailwind 4 automatically finds all content for the project.** - **Updated `postcss.config.js` to match the Tailwind 4 recommendation (using `@tailwindcss/postcss`).** - __Converted tailwind-specific CSS to V4 syntax, using `npx @tailwindcss/upgrade`. *These changes were automated.*__ - Removed `@layer` declarations - Converted some helper classes to use `@utility` - Changed some double quotes to single quotes and cleaned up whitespace in css files. - Updated various classes in templates/JavaScript files according to the migration guide, e.g. `outline-none` --> `outline-hidden`, `flex-grow` --> `grow`, `max-w-screen-xl` --> `max-w-(--breakpoint-xl)` etc. - DaisyUI updates: - **DaisyUI is now initialized as a plugin in `site-tailwind.css` instead of `tailwind.config.js`.** - **Themes are also now handled in this section. The docs have been updated to reflect this.** - Updated Pegasus CSS color variables to use the DaisyUI 5 versions. - Cleaned up Tailwind form rendering tags, removed unnecessary markup, and upgraded markup to be compatible DaisyUI 5, e.g. removing `-bordered` classes. - Checkboxes will now appear on the left instead of the right of labels. - Updated active tabs to use the latest DaisyUI markup (`menu-active` instead of `active`). - Shadcn updates: - **Moved shadcn components from `assets/javascript/components/ui` to `assets/javascript/shadcn/components/ui`.** - **New shadcn components can now be added via the CLI and will end up in the right place with no additional steps.** - Updated `tsconfig.json` and `webpack.config.js` to be consistent with new shadcn setup. - Regenerated shadcn components from the latest version of the library. - Changed shadcn themeing to use `@theme` declaration. - Removed all shadcn customizations from `tailwind.config.js` as they are superceded by the theme system. - Upgraded various shadcn dependencies to their latest versions. - Flowbite updates: - **Upgraded Flowbite to version 3.1.** - **Flowbite is now initialized as a plugin in `site-tailwind.css`.** - Explicitly import flowbite styles when building with flowbite enabled. This fixes out-of-the-box styling of some plugins. (Thanks Eeshan for reporting and fixing!) - Extracted dark mode selector to its own component and upgraded it to work with DaisyUI 5. - Other fixes / changes - Cleaned up various bits of CSS to use nested selectors. - Improved the contrast of the `pg-text-muted` class on dark mode. - Cleaned up commented out code in CSS files. - Removed unused "app" CSS class styles. - Standalone front end updates: - **Removed tailwind entirely from the standalone front end CSS.** The standalone front end currently gets its css from the same built file as the Django app. - Updated the [Tailwind Documentation](/css/tailwind.md) to reflect the V4 changes. ### Other Updates - Fixed an issue running `./manage.py` commands in production docker containers when using `uv`. Thanks Richard, Bryan, and Ken for reporting! - Fixed active tab highlighting on Flowbite demo. - Removed `--no-emit-package setuptools` from the `make pip-compile` command. Some configurations require setuptools and this was causing issues on some pip-tools builds. Thanks Jim for reporting and fixing! - Changed ruff `exclude` to `extend-exclude` in `pyproject.toml` to keep ruff's defaults. Thanks Justin for the suggestion! - Added help text to a few `make` targets that were missing it. Thanks Steve for the suggestion! - Removed unused `pg-is-loading` CSS class. - Fix syntax of commented out `EMAIL_BACKEND` variable in `deploy.yml`. - Removed language codes from the language selector dropdown. ### Upgrading See the [Tailwind upgrade guide](./css/tailwind.md#upgrading-from-tailwind-3-to-4) for details on upgrading existing Tailwind projects. *Mar 26, 2025* ## Version 2025.2.2 This is a hotfix release that fixes a bug in the styling of the avatar in the navbar on Bootstrap using certain browsers. Thanks Luc for reporting! - Restored `navbar.css` on bootstrap builds and moved it out of the bulma-specific folder. - Updated imports in `base.css` accordingly. *Mar 13 2025* ## Version 2025.2.1 This is a hotfix release that fixes a missing newline between `REDIS_URL` and `GOOGLE_ANALYTICS_ID` in `.env` / `secrets` files. Thanks Peter for the bug report! *Mar 7 2025* ## Version 2025.2 This is a maintenance release with a number of upgrades and fixes. ### Added - **You can now configure the Github integration to push your Pegasus code to a subdirectory of the repository.** [More details in the updated Github docs here](./github.md#pushing-pegasus-code-to-a-subdirectory-in-your-repository). Thanks to Simon for helping with this, and Aaron, Bernard, Danil, and Arno for suggesting it! - Added a `429.html` error template. ### Changed - **Migrated the majority of shared style files from sass to css, and removed sass from Tailwind builds.** This makes the setup more consistent with a typical Tailwind project. - Removed "sass" and "sass-loader" packages from Tailwind builds. - Updated `webpack.config.js` on bootstrap and bulma builds to also now handle `.css` files. - Related, ported the `navbar.sass` file to css, moved it to the `bulma` folder, and removed it from non-Bulma builds. - **Set [Django's cache framework](https://docs.djangoproject.com/en/latest/topics/cache/) to use Redis in production by default.** - The Redis cache will be enabled when `settings.DEBUG` is `False`. - Also explicitly list `redis` as a first-class requirement, which fixes a bug where tests could fail if you disabled celery. - Added `.venv` and `venv` to the `.gitignore` file. (Thanks Peter for suggesting!) - Use the project id in the default `AWS_STORAGE_BUCKET_NAME` in deploy.yml. (Kamal deployments, thanks Peter for suggesting!) - Updated the version of `ruff` used by pre-commit to the one that's installed in the project, and upgraded ruff to the latest (0.9.7). (Thanks Peter for reporting!) - Added a timeout and error handling to turnstile requests, to prevent hanging if Cloudflare was for some reason down. (Thanks Peter for suggesting!) - Removed `ENABLE_DEBUG_TOOLBAR=True` from production environment/secrets files. - Consistently use double quotes instead of single quotes in environment and deployment files. (Thanks Peter for suggesting!) - Removed duplicate and unused variable declarations across Kamal's `deploy.yml` and `secrets` files. Public variables are now listed in `deploy.yml` and private ones are listed in `secrets`. (Thanks Peter for suggesting!) ### Fixed - **Improved edge-case handling the Stripe checkout integration.** - Users should now see helpful error messages instead of getting 500 errors or ending up in an invalid state if they hit certain invalid URLs. - This also fixes a vulnerability where an attacker could potentially simulate e-commerce purchases through manual inspection and manipulation of requests. - Fixed a bug where `setuptools` was accidentally not present in production requirements files when using pip-tools. This caused production deployments to fail in certain cases. (Thanks Eeshan and Jim for reporting!) - Fixed an issue deploying to Heroku with Docker when using uv by removing Docker caching, which Heroku does not support. (thanks Toul for reporting!) - Fixed the active tab highlighting styles in the examples navigation on Bulma builds. - Removed unnecessary `
` elements from `top_nav.html` on Bootstrap builds. - Don't include Docker translation instructions in README if not using Docker. (Thanks Peter for reporting!) - Updated the Pegasus CLI to [version 0.8](https://github.com/saaspegasus/pegasus-cli/releases/tag/v0.8), which fixes a bad html closing tag in the generated templates. (Thanks Julian for the bugfix!) - Removed celery sections from `deploy.yml` in kamal builds if celery isn't enabled. ### Removed - Removed `django_otp` dependency and configuration, which was only there to facilitate the transition to `allauth.mfa`. See the release notes for [Version 2024.5](#version-20245) for more information on this change. - Also removed the associated `migrate_allauth_2fa` management command. - Removed the default user-facing messages on login/logout. You can add them back or customize them by editing the files in `/templates/account/messages/`. ### Documentation - Added [a community guide on using Digital Ocean Spaces](./community/digital-ocean-spaces.md) (alongside Amazon SES). Thanks Neil and Finbar for the contribution! ### Upgrading Tailwind projects that have added their own `.sass` files will need to either restore sass support or port these files to `.css` (llms are good at this!). You can "restore" sass support by rejecting the proposed changes in `package.json` and `webpack.config.js` during upgrade. If you have removed Redis from your project you will need to update the default cache config in `settings.py`. *Feb 28, 2025* ## Version 2025.1.1 This is a hotfix release that fixes an issue with installing Node 22 in the development Docker container. Thanks Oscar and Emiliano for reporting! If you'd rather manually apply the patch, you can just apply the following patch to your `Dockerfile.dev` file: ```diff RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=locked \ --mount=target=/var/cache/apt,type=cache,sharing=locked \ rm -f /etc/apt/apt.conf.d/docker-clean && \ - echo "deb https://deb.nodesource.com/node_22.x bookworm main" > /etc/apt/sources.list.d/nodesource.list && \ - wget -qO- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \ + curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \ apt-get update && \ apt-get install -yqq nodejs \ ``` *Jan 28, 2025* ## Version 2025.1 This release includes mostly backend infrastructure changes to some Pegasus features to pave the way for a (future) plugin ecosystem. This should make it easier to maintain Pegasus apps as well as possible (in the future) for other people to develop apps that can seamlessly integrate into Pegasus. ### New "async" build flag Previously when you enabled async / websockets, you also got the group chat example application. Now you can enable async features without this additional example app, and turn it on separately with a new configuration option. This lets you use async but not have to manually delete the example application. ### Added a flag to remove Celery (if possible) Added a configuration option that will remove celery and all dependencies + configuration ***if no other parts of your application need it***. Celery will also be removed from production deployment configurations. Celery is still required (and will be automatically enabled) if you are using any of: 1. The Pegasus examples 2. Subscriptions with per-unit billing enabled 3. Any AI chat features If you're not using these features and want to disable Celery you can do that from your project settings page. ### Organizational changes to apps for more consistency The following changes don't have any new features or functionality, but change small things about how the code is organized for affected apps (AI chat, AI images, and async group chat). It is hoped that these changes will make maintenance, upgrades, and future extensions to Pegasus easier. Changes affecting the AI Chat, AI Images, and Group Chat apps: - Moved app declarations for these apps to the end of `PROJECT_APPS` in `settings.py` - Moved url declarations for these apps to the end of `urls.py`. - Moved settings and environment variables for these apps to be located together. - Settings for these apps are now prefixed with `AI_CHAT_` or `AI_IMAGES_`, respectively. - **This also means that shared settings like `OPENAI_API_KEY` are now declared multiple times and need to be updated in multiple places.** See the "upgrading" section below on how to get around this duplication. - Moved chat JavaScript setup to the end of `module.exports` in `webpack.config.js`. - Depending on your configuration, the order of navigation tabs in the UI may change. - Made minor tweaks to how channels urls are set up. - Image logos used by the AI chat and images apps were moved to `/static/images/ai_images/` and `/static/images/ai_images/`, respectively. - The declaration for these apps has moved to a new "plugins" section of `pegasus-config.yml`. ### Other Changes Other changes included in this release are below. **Changed** - **Upgraded default Python to Python 3.12.** - Bumped the Python version to 3.12 in CI, and dev/production Docker containers. - Also added [a `.python-version` file](https://docs.astral.sh/uv/concepts/python-versions/#python-version-files) for uv builds (set to 3.12) - **Upgraded default Node to 22.** - Bumped the Node version to 22 in CI, and dev/production Docker containers. - **Upgraded nearly all Python packages to their latest versions.** - Added a pin to `dj-stripe<2.9` because 2.9 is not yet supported. - **Upgraded nearly all JavaScript packages to their latest versions.** - Tailwind v4 was not upgraded as it was just released and is not yet supported. - **Ruff and pre-commit will now sort imports by default.** (See upgrade notes below) - **This also updates import sorting in a number of files.** - **Pre-commit now runs ruff with `--fix` enabled, which will automatically apply (but not stage) fixable errors.** - Dependencies are now sorted in `pyproject.toml` (uv builds) and `requirements.in` (pip-tools builds) - Added email address to admin search for team memberships and invitations. Thanks EJ for the suggestion! - Made the "timezone" field editable in the user admin. Thanks Peter for the suggestion! - Changed active tab variable for ai image app from "ai_images" to "ai-images" to match convention of other apps. - Added a link from the user profile to manage email addresses if the user has more than one email registered. (Thanks Simon for the suggestion!) - Make it so that `./manage.py` commands default to `uv run` if you build with uv enabled. - The `chat_tags` template tag library was moved to the `web` app and renamed to `markdown_tags`, making it easier to use outside the chat application. **Fixed** - **Fixed an issue that caused Render deployments to fail when using uv.** (Thanks Jacob for reporting and helping fix!) - Add `psycopg2-binary` to production requirements if using sqlite, since it still required for production deployments. (Thanks Randall for reporting!) - Updated invitations to always store email addresses in lowercase to be consistent with account emails. Also fixed comparisons between invitations and sign up emails to be case-insensitive. (Thanks EJ for reporting and the fix!) - Renamed `tailwind.config.js` to `tailwind.config.cjs` which prevents build failures on Node 22. **Removed** - Removed no-longer-used `payments.js` and `stripe.sass` files. - Stopped including `pip-tools` in `dev-requirements` when using `uv`, as it is no longer needed. ### Upgrading **Python / Node updates** You may need to manually modify your dev/production environment to upgrade to Python 3.12 and Node 22. If you're using Docker, this should happen automatically by following the [upgrade process](./upgrading.md). Pegasus apps should still run on Python 3.11 / Node 20, but will no longer be extensively tested on those versions moving forwards. **Settings Changes** Some settings around AI API keys have been renamed and will need to be updated in your `settings.py` and `.env` files. If you are using AI chat and AI images with OpenAI, the easiest way to use a shared API key is to add the following to your `.env` / environment variables: ``` OPENAI_API_KEY="sk-***" ``` And then modify your settings variables to read from that value: ```python # add an OPENAI_API_KEY setting, in case it was referenced elsewhere in your code OPENAI_API_KEY = env("OPENAI_API_KEY", default="") # modify the image/chat settings to use the same openai key instead of reading from new environment variables AI_IMAGES_OPENAI_API_KEY = OPENAI_API_KEY AI_CHAT_OPENAI_API_KEY = OPENAI_API_KEY ``` **Import Sorting Changes** If you have auto-formatting enabled you will likely get CI errors after upgrading due to the stricter import sorting. You can fix these by running a manual ruff check locally and then committing the result: ``` ruff check --fix # or with uv uv run ruff check --fix ``` *Jan 27, 2025* ## Version 2024.12.1 This is a minor hotfix release for 2024.12 - **Fixed a bug where the delete workflow was broken for apps created by the Pegasus CLI on non-Tailwind builds.** This happened becasue the "css_framework" cli option was accidentally missing from `pegasus-config.yml`. Thanks Robert for reporting! - Updated the README instructions for setting up pre-commit hooks when using uv. *Jan 13, 2025* ## Version 2024.12 content/ This release adds first-class support for using uv as a complete replacement for development and production workflows (see below), and has a handful of fixes/changes. ### UV support! This release adds full support for [uv](https://docs.astral.sh/uv/) as a replacement package manager for your project. You can use uv by selecting the new "uv" as your "Python package manager" on your project settings page. When you select uv the following changes will be made: - All requirements.in / requirements.txt files are removed. - Your project requirements will now be listed in your `pyproject.toml` file. - Development and production dependencies will be listed under separate dependency-groups. - Your pinned project requirements will be listed in a new `uv.lock` file. - Docker containers (in development and production) will use `uv` to set up and manage the Python environment. - A `make uv` target will be added to Docker builds to run `uv` commands in your container. The main benefits of using uv are: - Speed. It is just way, way faster to anything related to package management. - Easier to setup and install Python. - Lock files (pinned versions) are consistent across any platform. - More tooling. - Speed. (It's so fast we put it twice.) There will be a longer write up about uv released very soon, but in the meantime you can review the updated [python documentation](./python/setup.md) and new [uv documentation](./python/uv.md). The rest of the docs have been updated to accommodate uv, though it's possible there are some places that were missed. If you spot any issues in the docs, get in touch! ### Other fixes - **Upgraded the pegasus cli to fix an issue where the generated list views were not properly scoped to the appropriate team / user.** If you used the CLI to generate any apps it's highly recommended that you check that you are not exposing objects that should not be viewable. ### Other updates - **Changed the default set up of social logins to use settings-based configuration instead of `SocialApps` in the database.** See the upgrade notes if you are using social logins to prevent issues. Thanks Alex for the suggestion and for helping with the updated documentation! - Updated the default flowbite setup to disable the forms plugin. This was causing styling conflicts with the default DaisyUI styles on certain form elements, including checkboxes. - Re-formatted the default form input template for readability. ### Upgrading To migrate an existing project to `uv` see [this guide](./cookbooks.md#migrating-from-pip-tools-to-uv). If your application was already using social logins defined in the database, the new settings-based declaration will conflict and cause errors on social login. To fix this you can either delete the `APPS` section of the relevant service in `settings.SOCIALACCOUNT_PROVIDERS`, or you can move the credentials into your project environment (e.g. `.env`) and delete relevant the `SocialApp` from the Django admin. *November 29, 2024* ## Version 2024.11.3 This is a minor maintenance release with a few changes in preparation for adding `uv` support (coming soon!). ### Changed - Pinned the version of `uv` used in CI and Dockerfiles. - Added `venv` and `.venv` directories to the `.dockerignore` file and `make translations` target. - The `make requirements` command now restarts containers in the background, making it easier to combine with other make targets. - Added a catch-all to the `Makefile` to prevent error messages when running `make npm-install ` and similar commands. - Updated README commands to consistently use `python manage.py` instead of just `./manage.py`. - Made some minor formatting changes to `pyproject.toml`. - Fixed the link to the multi-stage dockerfile docs in `Dockerfile.web` - Upgraded a number of Python packages. - Updated the `default_stages` of the `.pre-commit-config.yaml` file to the latest expected format (`pre-commit`). *Nov 21, 2024* ## Version 2024.11.2 This release adds the ability to disable dark mode on Tailwind, upgrades front end libraries, bumps the API client version, and has a handful of other small changes and fixes. ## Added - **Added a new build option to disable dark mode for Tailwind builds.** (Thanks Arno for suggesting!) - Added basic user-facing error messages to the standalone front end sign up and login workflows. ## Changed - **Upgraded all JavaScript dependencies.** - **Updated the API client to use the latest version 7.9.0, and updated the standalone front end to work with the latest changes.** - Updated template-partials installation to be manually loaded, to allow for easier integration with other templating systems like django-cotton. - Moved active tab highlighting to the base view in the example object demo. - Made a few very minor edits to comments and whitespace in a few places. ## Fixed - Fixed a bug where your migrations and tests would fail if your project name was > 50 characters (thanks Bernard for reporting!). - Fixed a bug in the group chat demo where submitting an empty room name would take you to a 404 page. - The `docker_startup.sh` file is no longer included if you are not using a docker-based deploy platform. - Updated the `config/README` file which had outdated information that predated the migration to Kamal 2. (Thanks Arno for reporting!) - Improved comments in the kamal `secrets` file and `.env` files. (Thanks Arno for suggesting!) ## Removed - The `.env` file is no longer included in zip downloads. This file was already removed from Github builds so this just makes the two consistent. Projects should create `.env` file from the `.env.example` file. - Removed the `migrate_customers_to_teams` management command. This was added for an upgrade two years ago, and is assumed to be no longer needed. *Nov 14 2024* ## Version 2024.11.1 This is a minor hotfix release. ### Fixed - Fixed an issue where the team selector was accidentally transparent in Tailwind builds. - Removed shadcn template that was accidentally included even if shadcn was disabled. ### Updated - Removed extra whitespace from `form_tags.py`. (Thanks Brennon for reporting!) - Updated `make help` to allow for commands defined in `custom.mk` with digits to also show up. (Thanks Arno for suggesting!) *Nov 4 2024* ## Version 2024.11 This is a feature release with an emphasis on improving the Tailwind CSS experience with Pegasus. Watch the video below for a demo, or read on for the highlights.
### Dark mode improvements A dark mode selector was added to the navigation, allowing users to easily toggle between light, dark, and "system default" mode. The user's selection is preserved server-side in the session object, which also helps to prevent flickering across page loads. ### Better Theme Support It's now easier than ever to change your project's theme. Each project now supports a default light and dark theme which will be used throughout the site. The default themes need only be changed in `tailwind.config.js`, and `settings.py` and everything else is taken care of. See the updated [tailwind theme documentation](./css/tailwind.md#changing-your-themes) for more details. ### New shadcn integration and demo dashboard A new build setting allows you to build your project with [shadcn/ui](https://ui.shadcn.com/) installed. Shadcn is a great and versatile component library for React and Tailwind, but it is difficult to integrate it into a Django project without building a separate front end. Now Pegasus takes care of that integration for you, and provides a reference dashboard implementation of how to work with the library. The reference dashboard is a hybrid single-page React app served by Django. It uses the same colors as the DaisyUI theme, and will update when you change your theme, and has many interactive components. However, it is not connected to any backend data—it is just a UI example. Read more in the [shadcn docs here](./css/tailwind.md#shadcn). ### New flowbite integration and demo component page Another new build setting allows you to build your project with [flowbite](https://flowbite.com/) installed. Flowbite is another great component library for Tailwind and does *not* use React---making it a great fit for htmx projects. If you enable this setting, flowbite will automatically be installed and you can drop flowbite components into any Django template. The reference page has an example of a few of these components. Read more in the [flowbite docs here](./css/tailwind.md#flowbite). ### Other updates - **Upgraded all Python packages to their latest versions.** - **[uv](https://docs.astral.sh/uv/) is now used to install Python packages in Docker files and Github actions.** - Also updated `make pip-compile` target to use `uv`. - This resulted in minor changes to all `requirements.txt` files. - **Team invitation pages now prompt a user to log in instead of sign up if the email is associated with a known account.** (Thanks Daniel for suggesting!) - Your configured Github username, if available, will be used in a few places instead of a default value. (Thanks Richard for suggesting!) - Added `bg-base-100` to the `` tag of the base template and removed it from other components where it was now redundant. This improves theming support when themes heavily modify the base color. (Tailwind builds only) - Added equals signs to `ENV` declarations in production Docker files, for consistency. (Thanks Denis for suggesting!) - Slightly improved the styling of the e-commerce app. - Overhauled the [Tailwind CSS documentation](./css/tailwind.md). **Updates to the CLI ([release notes](https://github.com/saaspegasus/pegasus-cli/releases))** - Fixed a bug on certain environments where the `pegasus` command conflicted with a local `pegasus` folder, causing import errors running the CLI. - Apps created with `startapp` now use a `POST` for deletion instead of a `GET`. - Deletion now includes a modal confirmation (Tailwind and Bulma builds only). ### Upgrading If you're using Docker the `make upgrade` command won't work out-of-the-box due to the change in how requirements files are managed. You will first have to rebuild your containers with: ``` make build ``` or ``` docker compose build ``` After that, you should be able to run `make upgrade` as normal. *Nov 1, 2024* ## Version 2024.10 This release upgrades Kamal deployment to Kamal 2 and dramatically simplifies the Kamal deployment process. ### Kamal 2 deployment and related changes In the upgrade to Kamal 2, the following changes were made: - Updated Kamal to run from the root project directory instead of the `deploy` subdirectory. - Also moved the config file was also moved from `deploy/config/deploy.yml` to `config/deploy.yml` - Moved environment secrets from `deploy/.env` to `.kamal/secrets` to match Kamal 2's recommendation. - Kamal can now be installed and run with Docker without any additional workarounds [as described here](https://kamal-deploy.org/docs/installation/) The custom docker set up instructions have been removed. - Kamal is now run as root by default, which dramatically simplifies the server setup process. There is now no need to run any manual steps to set up your server. - Kamal now creates and manages its own docker network. - Traefik has been dropped in favor of `kamal-proxy` for the proxy server, as per the new Kamal defaults. - The `.gitignore` and `.dockerignore` files were updated to reflect the new structure. - Added `apps.web.middleware.healthchecks.HealthCheckMiddleware` to workaround Kamal health checks and Django security features, [as outlined here](https://github.com/basecamp/kamal/issues/992#issuecomment-2381122195). - Removed unnecessary media directory set up from `Dockerfile.web`. It is recommended to use an external storage service for media files and not the Docker container. In addition, there were a few changes that affect projects that aren't using Kamal: - `apps.web.locale_middleware` was moved to `apps.web.middleware.locale` - `docker_startup.sh` was moved from the `deploy` folder to the project root. The [Kamal documentation](./deployment/kamal.md) has been updated to reflect these changes. ### Other fixes - **Subscriptions in a "past due" state are now treated as "active" for the purposes of feature gating and accessing the billing portal.** This is more consistent with [how Stripe treats subscriptions in this state](https://docs.stripe.com/api/subscriptions/object#subscription_object-status). (Thanks Luc for suggesting!) - Fixed a bug where several `make` targets mistakenly included a `--no-deps` flag which would fail if your database container was not running. (Thanks Gary for reporting!) - Fixed an issue where Stripe subscription webhooks weren't properly handled if you were using the embedded Stripe pricing table. (Thanks Andrew for reporting!) - Fixed an issue introduced in 2024.9 where Stripe ecommerce webhooks weren't always processed correctly. - Added a migration file to automatically work around [this dj-stripe issue](https://github.com/dj-stripe/dj-stripe/issues/2038) so that it wasn't a manual process. *Oct 15, 2024* ## Version 2024.9.3 This release is mainly [an update to the CLI](https://github.com/saaspegasus/pegasus-cli/releases/tag/v0.3): ### CLI updates - **You can now generate apps that work seamlessly with Pegasus teams** (will use `BaseTeamModel` and add the team slug and permissions checks to all urls and views). - The CLI now generates a default `admin.py` config for each data model. - User foreign keys now use `settings.AUTH_USER_MODEL` instead of being hardcoded to `apps.users.models.CustomUser`. ### Other changes - Fixed an issue where HTMX links without href tags weren't showing a pointer cursor on some CSS frameworks. - Add default region to Redis and Postgres configurations in `render.yaml` to make it easier to find/replace them when changing your project's region. (Thanks Jacob for suggesting!) *Sep 26, 2024* ## Version 2024.9.2 This release fixes a bug that prevented the CLI from running on Windows machines. Thanks Jonathan for reporting! If you don't want to upgrade you can just `pip install pegasus-cli==0.2.1` to apply the fix. *Sep 20, 2024* ## Version 2024.9.1 This release fixes a few things in the 2024.9 release. - Updated the `bootstrap_ecommerce` management command to create `ProductConfiguration` objects for all active Products in Stripe. - Fixed an issue on the ecommerce homepage where a closing `
` tag was misplaced if a product didn't have a default price set. *Sep 18, 2024* ## Version 2024.9 There are two big updates in this release: 1. The Pegasus CLI, which allows you to instantly spin up new apps. 2. E-Commerce/Payments improvements. ### The Pegasus CLI The [Pegasus CLI](https://github.com/saaspegasus/pegasus-cli/) is a standalone command-line tool that allows you to instantly spin up new Django apps. You can specify as many data models as you want and it will generate a starting CRUD interface for each of them. Here's a quick demo:
**At the moment the CLI only supports HTMX build of Pegasus.** A React-based implementation is planned for a future date. Huge thanks to Peter for his excellent [Pegasus example apps](https://github.com/pcherna/pegasus-example-apps-v2) project which served as a reference for implementing the CRUD application and pagination. ### E-Commerce / Payments demo improvements This is a series of updates designed to make it easier to build a functional end-to-end application on top of the e-commerce demo. - Added a `ProductConfiguration` model to attach additional metadata to products. - E-Commerce product URLs and views now use the `ProductConfiguration` `slug` field instead of the Stripe Product IDs. - Added a `@product_required` decorator that can be used to restrict access to views based on whether the user has purchased a product. - Added a demo "access product" page that shows how to use the `@product_required` decorator. - Added `user_owns_product` and `get_valid_user_purchase` helper functions. - Improved the navigation and use of breadcrumbs in the demo UI. - **See upgrade notes for information about migrating previous data to the new set up.** See also: the updated [Payments docs](./payments.md). ### Other Changes #### Added - **Added `django-htmx` and `django-template-partials` as first-class dependencies to HTMX builds.** These libraries are used by the CLI and will be used for more HTMX-based functionality moving forwards. - Added `make manage` command to run arbitrary `manage.py` commands in a docker environment. E.g. `make manage ARGS='createsuperuser'`. - Added the ability to pass arguments to `make test` in docker. E.g. `make tests ARGS='apps.teams --keepdb'`. (Thanks David for the suggestion!) #### Changed - Changed links on the tailwind signup page to use `pg-link` class instead of explict tailwind classes. (Thanks Peter for the suggestion!) - Silenced extraneous djstripe warnings when running tests. (Thanks Chris for the suggestion!) - Added `.vscode` and vs workspace files to the project `.gitignore`. - Switched from `assert` statements to `raise ValueError` in the e-commerce Stripe checkout confirmation view. - Moved some of the currency helper functions out of the `subscriptions` app into `utils.billing` so they can be used in ecommerce workflows even if subscriptions are disabled. - Set `PYTHONUNBUFFERED` and `PYTHONDONTWRITEBYTECODE` in docker compose file for python containers. (Thanks Richard for the suggestion!) - Upgraded Django to 5.1.1. #### Fixed - Fixed a typo in the help text for the `bootstrap_ecommerce` command. - Fixed a bug where `user_teams` context processor could cause a crash if auth middeware didn't run (for example, on a 500 error page in production). ### Upgrade Notes If you have existing `Purchase` data in your application you will need to migrate it to the new `ProductConfiguration` structure. This is a three-step process: First you will need to apply the database updates, but allow `Purchase.product_configuration` to be null. Instead of running `./manage.py migrate` you will have to run the following command: ```bash ./manage.py migrate ecommerce 0002 ``` After running this, you can run the following command to migrate the existing data: ```bash ./manage.py migrate_ecommerce ``` The `migrate_ecommerce` management command will: 1. Create `ProductConfiguration` objects for all products in `settings.ACTIVE_ECOMMERCE_PRODUCT_IDS` 2. Create `ProductConfiguration` objects for all products referenced in existing `Purchase` models. 3. Set `purchase.product_configuration` to the new `ProductConfiguration` object for each `Purchase`. Finally, you can make the `Purchase.product_configuration` field non-null, by running: ```bash ./manage.py migrate ecommerce 0003 ``` **New projects, or projects without any existing purchase data can skip these steps and run `./manage.py migrate` directly.** However, you may still want to run `./manage.py migrate_ecommerce` to populate `ProductConfiguration` objects for your active products. *Sep 17, 2024* ## Version 2024.8.2 This is a maintenance release that includes a number of mostly small fixes and updates, and updates Django to version 5.1. ### Fixed - **Fixed a few styling issues on Bulma builds**: - Disabled dark mode. The styling for Dark mode was not fully supported by Bulma and led to strange-looking layouts. - Fixed an issue where the active tab wasn't properly highlighted in certain cases on Bulma builds. - Fixed an issue with sqlite builds where the default `DATABASE_URL` would cause the DB to switch to Postgres. (Thanks Harry and Richard for reporting!) - Switched allauth from [Twitter](https://docs.allauth.org/en/latest/socialaccount/providers/twitter.html) (which seems no longer supported) to [Twitter Oauth2](https://docs.allauth.org/en/latest/socialaccount/providers/twitter_oauth2.html), which still works. (Thanks Bandi for reporting!) - Fixed an issue introduced in version 2024.8 which caused Heroku Docker deploys to fail. Heroku [does not support caching](https://stackoverflow.com/a/78901250/8207), so it has been removed from Heroku Docker builds. (Thanks Richard for reporting!) - Fixed a bug where the `team_nav_items.html` and `team_selector.html` templates could be accidentally included even if you built without teams. - Changed the (unused) `text-muted` css class to `pg-text-muted` in a handful of places on Tailwind builds. (Thanks Peter for reporting!) - Removed unused `AWS_S3_CUSTOM_DOMAIN` variable from `.env` files. ### Changed - **Upgraded Django to version 5.1.** - Upgraded all Python packages to their latest versions. - Updated Pegasus color CSS variables to use the DaisyUI variables, so that they change when you change DaisyUI themes. (Thanks Peter for the suggestion!) - Removed `custom.mk` if your project was not generated with a `Makefile`. (Thanks Finbar for reporting!) - Removed "Containers started" message from `make start` command that never executed. (Thanks Richard for reporting!) - Better style inputs of type `time` and `datetime-local` in forms on all CSS frameworks. (Thanks Peter for reporting and fixing!) - Simplified Bulma navbar to use bulma native classes instead of custom CSS. (See upgrade note below.) - Updated default Github repo in `app-spec.yml` to use raw project slug instead of the hyphenated version. (Digital Ocean deployments, only, thanks Richard for suggesting) - Moved `SERVER_EMAIL` and `DEFAULT_FROM_EMAIL` from `settings_production.py` to main `settings.py` file, and made it possible to set them via the environment/`.env` file. - Added many more common settings and secrets to the Kamal `deploy.yml` file. ### Documentation - Improved the documentation on [customizing the Material Bootstrap theme](./css/material.md). - Added documentation for [deploying multiple apps to the same VPS with Kamal](./deployment/kamal.md#cookbooks). ### Upgrading - Bulma builds may need to add the `is-tab` class to `navbar-items` in the top nav to mimic the updated navbar styling. *August 23, 2024* ## Version 2024.8.1 This is a maintenance release which upgrades HTMX to version 2.0 and fixes a handful of minor bugs. ### Changed - **Upgraded HTMX to [version 2.0](https://htmx.org/posts/2024-06-17-htmx-2-0-0-is-released/).** See upgrade note below. ### Fixed - Fixed a bug on some environments where `make build-api-client` would wrong relative to the wrong directory. (Thanks Ben for finding and fixing!) - Downgraded Postgres from 16 to 14 on Digital Ocean deployments, due to [an issue with permissions on version 16](https://www.digitalocean.com/community/questions/how-can-i-create-a-postgres-16-user-that-has-permission-to-create-tables-on-an-app-platform-dev-database) that was causing new Digital Ocean deployments to fail. (Thanks Panagiotis for reporting!) - Switched the default celery pool to [solo](https://docs.celeryq.dev/en/stable/internals/reference/celery.concurrency.solo.html) in development, to fix issues running on Windows. See [updated docs](./celery.md). - Updated in-app help hint to recommend running `./manage.py bootstrap_ecommerce` instead of `./manage.py djstripe_sync_models price`. ### Upgrading Htmx 2.0 requires loading new extensions. If you were loading HTMX extensions in your own templates, you will have to upgrade the location of those to the 2.0 versions. Before: ``` ``` After: ``` ``` *August 13, 2024* ## Version 2024.8 This is a maintenance release with many small updates and fixes. ### Added - **Added test cases for subscription decorators, feature gating, and views.** These can be extended/adapted to test custom subscription logic. Also added utility functions to create test products, subscriptions and mock requests. - Added a test that will fail if your project is missing any database migrations. [More on this concept here](https://adamj.eu/tech/2024/06/23/django-test-pending-migrations/). - **Added an example landing page to Tailwind builds, based largely on [Scriv's landing page](https://scriv.ai/).** - Added `TURNSTILE_KEY` and `TURNSTILE_SECRET` to Kamal's default secrets. - Added a section on configuring static files to the [production checklist](./deployment/production-checklist.md#check-your-static-file-setup). ### Changed - **Code is now automatically formatted for all projects.** The "Autoformat code" check box has been renamed to "Enable linting and formatting" and now only controls whether `ruff` and the pre-commit hooks are included in the project download. Projects that had already enabled auto-formatting are unaffected by this change. (See upgrade notes below.) - **The example landing pages are now used as the project's landing page instead of being listed in the examples**. (Bulma and Tailwind builds only.) - **Team invitation emails are now better styled, matching the same format as account emails.** (Thanks EJ for the suggestion!) - The `EMAIL_BACKEND` setting is now configurable via an environment variable. Also, added a commented-out example of how to set email settings for a production email provider (Mailgun). - Apt and pip packages are now cached across Docker builds, which should result in faster build times after the first build. (Thanks Tobias for the suggestion!) - Improved the display format of "role" in the team invitation list. (thanks Andy for the suggestion!) - Change `user/` to `YOUR_GITHUB_USERNAME/` in the Digital Ocean `app-spec.yml` file to make it more obvious that it should be edited. (Thanks Stephen for suggesting!) - Changed the UI of social logins on the "sign in" page to match that of the "sign up" page on the Material Bootstrap theme. This makes the implementation more extensible and more consistent with other CSS frameworks. - **Upgraded all Python packages to the latest versions.** ### Fixed - Fixed a bug where the formatting `make` targets were still calling `black` and `isort` instead of `ruff`. `make black` is now `make ruff-format` and `make isort` is now `make ruff-lint`. - Fixed a bug where the sign up view tests would fail in your environment if `settings.TURNSTILE_SECRET` was set. (Thanks Finbar for reporting!) - Fixed translations on the user profile form field names. - Removed `svg` as an option for profile picture uploads, to prevent the possibility of using it as an XSS attack vector. ([More info on this threat here](https://medium.com/@rdillon73/hacktrick-stored-xss-via-a-svg-image-3def20968d9)). - Disable debug toolbar in tests, which fixes test failures under certain conditions. - Bumped the Postgres version used by Digital Ocean deployments from 12 to 16. Digital Ocean has deprecated support for version 12. (Thanks Stephen for reporting!) - Simplified how the list of social login buttons is rendered, and make social login buttons work when configuring social applications in settings (previously buttons only showed up if you configured apps in the database). See upgrade note below. ### Removed - Deleted the "sticky header" html and CSS code that was only used on the example landing pages. ### Upgrade Notes - If you had **not** been using auto-formatting until now, you should first follow the instructions for [migrating to auto-formatted code](./cookbooks.md#migrating-to-auto-formatted-code) prior to upgrading to this release. Otherwise you will likely get a lot of formatting-related merge conflicts when trying to upgrade. - If you already enabled auto-formatting (most projects), you don't need to do anything. - If you had previously configured allauth social applications in the database *and* in your settings file, you may see a duplicate "Login with XXX" button on the sign up and login pages. To fix this, remove the social application from either your settings or the database. *August, 7, 2024* ## Version 2024.6.1 This is hotfix release that addresses a few issues from yesterday's update: - Fix app styles accidentally being purged during the Docker build process. This caused styling on Docker-based deployments for tailwind builds. (Thanks Steve for reporting!) - Moved channels url import to after Django initialization. This fixes an `AppRegistryNotReady` error when deploying asynchronous apps with the AI chat app enabled. (Thanks Roman for reporting!) - Don't create the periodic task to sync subscriptions unless per-unit billing is enabled. *June 6, 2024* ## Version 2024.6 This is a feature release with a few big updates and a lot of smaller ones. ### AI model changes The library used for non-OpenAI LLMs has been changed from [`llm`](https://github.com/simonw/llm) to [`litellm`](https://docs.litellm.ai/docs/). Reasons for this change include: - It has far fewer additional dependencies. - It supports async APIs out of the box (for most models). - The `llm` library is more targeted for the command line use-case, whereas `litellm` offers similar functionality as a native Python library with a cleaner API. Litellm can still be used with all common AI models, including OpenAI, Anthropic/Claude, and local models (via ollama). For details on getting started with `litellm` see the updated [AI documentation](./ai.md). ### Formatting and linting now use Ruff Black and isort have been replaced with [ruff](https://github.com/astral-sh/ruff)---a Python linter/formatter that offers the same functionality as those tools but is much faster. Additionally, Pegasus will now remove unused imports from your files automatically, both when building your project and if you have set up `pre-commit`. This change should be a relatively seamless drop-in replacement, though you may see some new lint errors in your projects which you can choose to address. ### Spam prevention updates There has been a dramatic increase in spam-bots over the last month. Many of these bots target seemingly-innocuous functionality like sign up and password reset forms. This version includes a few updates to help combat these bots. First, you can now easily add [Cloudflare turnstile](https://www.cloudflare.com/products/turnstile/) to your sign up forms, which will present the user with a captcha and should help reduce bot sign-ups. See [the turnstile documentation](./configuration.md#turnstile) for information on setting this up. Additionally, the `ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS` setting has been set to `False` by default. This prevents "forgot password" and "magic link" emails from being sent out to unknown accounts. It should also help reduce unnecessary email sending. Finally, the [admin dashboard](#admin-dashboard) no longer shows users with unconfirmed email addresses if you have set `ACCOUNT_EMAIL_VERIFICATION = 'mandatory'`. This helps filter out likely bots from the report to provide clearer visibilty of people actually signing up for your app. ### Complete changelog Below is the complete set of changes in this release. #### Added - **Added configurable captcha support on sign up pages, using [Cloudflare turnstile](https://www.cloudflare.com/products/turnstile/).** See [the turnstile documentation](./configuration.md#turnstile) for more information on setting this up. (Thanks Troy, Jacob, Robert and others for suggesting.) - Added API views for two-factor authentication, and to change the logged-in user's password. (Thanks Finbar for suggesting!) - Add UI to tell users they need a verified email address prior to setting up two-factor auth. - Also added a `has_verified_email` helper class to the `CustomUser` model. - Added tests for the delete team view for both team admins and members. (HTMX builds only) - Added test for team member removal permissions. - Add display and sort on the number of active members in the teams admin. #### Fixed - Fixed a bug where team names longer than 50 characters could cause a crash during sign up. - Fixed a bug where multi-factor authentication QR codes had a dark background when dark mode was enabled (Tailwind builds only). (Thanks Artem for reporting!) - Fixed a bug where it was possible to bypass two-factor-authentication when using the API authentication views. (Thanks Finbar for reporting and helping with the fix!) - Fixed a bug where deleting the user's only team while impersonating them resulted in a temporary crash. (Thanks EJ for reporting!) - Fixed a bug where creating an API key crashed if your user's first + last name combined to more than 40 characters. (Thanks Luc for reporting!) - Improved the UI feedback when LLMs fail (e.g. if your API key is wrong or ollama is not running). - Removed the `static/css` and `static/js` directories from the `.dockerignore` file so that other project files can be included in these directories. Also updated the production Docker build process so that any existing files are overwritten by the built versions. (Thanks Raul for reporting!) - Made some performance improvements to the production Dockerfile build (don't rebuild the front end if there are no changes in the dependent files). - Better support trialing subscriptions with no payment methods. The subscription UI will now show the date the trial ends and won't log errors about missing invoices. (Thanks Jarrett for reporting!) #### Changed - **Upgraded all Python packages to the latest versions.** - **Upgraded all JavaScript packages to the latest versions.** - **Non-OpenAI builds now use `litellm` instead of `llm`.** See above. (Thanks Sarthak for the suggestion!) - **Changed the formatter/linter from `black` and `isort` to [ruff](https://github.com/astral-sh/ruff).** See above. - Also addressed a handful of minor linting errors that came up as a result of this change. - Codebase linting is now substantially faster. - Unused imports are now automatically removed when building your projects. - **Celerybeat now uses the `django-celery-beat` library to store tasks in the database instead of on the filesystem.** This improves support for celerybeat on Docker-based platforms. (Thanks Peter and Artem for the suggestion!) - Also added a migration to save the default scheduled tasks in the database. - The login API response has changed, to allow for two-factor auth prompts, and more machine-readable status fields. - Removed the no-longer-used `use_json_field=True` argument from wagtail `StreamField`s. - The admin dashboard no longer shows users with unconfirmed email addresses if you have set `ACCOUNT_EMAIL_VERIFICATION = 'mandatory'`. - The admin dashboard now includes sign ups from the current date, by default. - Changed behavior when team role checks fail from raising a `TeamPermissionError` to returning a 403 response, and updated affected tests. One side effect of this is that the stack traces are removed from successful test runs. - Secret keys should no longer change every time you build your Pegasus project. They are also now clearly prefixed with `django-insecure-` to indicate that they should be changed in production. - Updated the default OpenAI chat model to gpt-4o. - Upgraded the openapi client generator to version 7.5.0 and also pinned the version used by `make build-api-client` to the same one. - Team IDs are now optional on the create team page (HTMX builds only). - Add clearer error message when charts are broken due to api config issue. (Thanks Yngve for reporting!) - Added `assume_scheme="https"` to form `URLField`s to be compatible with Django 6 behavior. - Added `FORMS_URLFIELD_ASSUME_HTTPS = True` to be compatible with Django 6 behavior. - Set `ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False` by default, so that "forgot password" emails do not get sent to unknown accounts. This can help prevent spam bots. #### Removed - Removed `black` and `isort` from dev-requirements, since they have been replaced by `ruff`. - Removed `llm` library and associated code, since it has been replaced by `litellm`. - Removed no longer used `TeamPermissionError` class. #### Standalone front end The following changes affect the experimental [standalone front end](./experimental/react-front-end.md): - **The standalone React front end now supports two-factor-authentication.** - Improve the UI when you have login issues in the standalone React front end. *June 5, 2024* ## Version 2024.5.3 This is a hotfix release that fixes a bug where the landing and dashboard page image was accidentally removed if you built without the examples enabled. *May 21, 2024* ## Version 2024.5.2 This is a hotfix release that fixes a bug that prevented the team management page from loading in certain browsers if you built with a React front end and with translations enabled. Thanks Finbar for reporting! - Added `defer` keyword to various bundle scripts so they are loaded after the JavaScript translation catalog. - Updated references to `SiteJS` to run on the `DOMContentLoaded` event to allow for usage of the `defer` tag. *May 16, 2024* ## Version 2024.5.1 This is a hotfix release that fixes issues running the [experimental React frontend](./experimental/react-front-end.md) in Docker. Thanks Mohamed for reporting this! - Fix `api-client` path in the frontend docker container and add to `optimizeDeps` in vite config. - Mount `node_modules` as an anonymous volume in the frontend docker container, so it is not overwritten. - Automatically create `./frontend/.env` when running `make init` if it doesn't exist. *May 14, 2024* ## Version 2024.5 This is a major release with several big updates. Here are a few highlights: ### New AI models In addition to using OpenAI chat models, you can now build the Pegasus AI chat applicaiton with the [`llm` library](https://github.com/simonw/llm). This lets you run the chat application against any supported model---including the Anthropic family (Claude 3), and local models like Llama 3. Additionally, the image generation demo now supports Dall-E-3 and Stable Diffusion 3. For complete details, see the new [AI documentation](./ai.md). ### Health Checks A new setting allows you to turn on health checks for your application, powered by [django-health-check](https://django-health-check.readthedocs.io/en/latest/). This will create an endpoint (at `/health` by default) that pings your database, Redis instance, and Celery workers and returns a non-200 response code if there are any identified issues. These endpoints can be connected to a monitoring tool like [StatusCake](https://www.statuscake.com/) or [Uptime Robot](https://uptimerobot.com/) so that you can be alerted whenever your site is having issues. See the section on [monitoring](./deployment/production-checklist.md#set-up-monitoring) in the production checklist for more information. ### Allauth updates The [django-allauth](https://docs.allauth.org/en/latest/) library was updated to the latest version, which enabled several useful changes. The first is a "sign in by email code" option which can be used in addition to the standard username/password and social option. Users can request a code be sent to their registered email and can then use that to login. See [the magic code documentation](./configuration.md#enabling-sign-in-by-email-code) to enable/disable this. The second is using the recent [multi-factor authentication](https://docs.allauth.org/en/latest/mfa/index.html) support added to allauth in favor of the third-party `django-allauth-2fa` library. This reduces dependencies and puts all of authentication functionality on a standard path moving forwards. The complete release notes are below: ### Added - **Added an optional health check endpoint at /health/.** (see above for details) - **Added an option to connect the chatbot to other LLMs**. (see above for details) - **The AI image generation now supports Dall-E 3 and Stability AI.** - **All generated projects now include a `LICENSE.md` file.** The goal of the license file is not to change how Pegasus can be used in any way, but rather to document those terms in the codebase itself (previously they were only documented on the [terms page](https://www.saaspegasus.com/terms/)). For more information you can see the new [license page](https://www.saaspegasus.com/license/). - **Added support for "magic-code login", where a user can login to the site by requesting a code to their email address.** [Documentation.](./configuration.md#enabling-sign-in-by-email-code) - **Google cloud run builds now support Redis.** For details, see the [updated documentation](./deployment/google-cloud.md). (Thanks Forrest for suggesting!) - Added a `custom.mk` file where you can add additional `make` targets without worrying about future Pegasus upgrades. (Thanks John for proposing this!) ### Changed - Upgraded allauth to the latest version (0.62.1). - **Migrated two-factor authentication from the third-party `django-allauth-2fa` to the `django-allauth` built-in implementation.** See upgrade notes below for migrating existing projects. - Refactored how many allauth views work to be compatible with their new template override system. - **Bootstrap and Bulma builds: Move sidebar navigation into the mobile menu instead of having it take up the top of the screen on mobile screens**, similar to how things already worked on Tailwind and Material. (Thanks Luc for the nudge!) - This includes splitting out the menu items into their own sub-template files so they can be included in both menus. - Inline buttons are now spaced using the `gap` CSS property instead of the `pg-ml` class on individual buttons. - `Alpine.start()` is now called on `DOMContentLoaded` loaded event instead of using `window.load`. This makes Alpine-powered UIs more responsive, especially when used on pages with lots of images. - **Updated external JavaScript imports to use [the `defer` keyword](https://www.w3schools.com/tags/att_script_defer.asp) for slightly better page load performance.** (See upgrade note.) - Also updated inline JavaScript code in a handful of places to be compatible with deferred scripts. - Added a Github logo to connected Github accounts on profile page. - **The AI image demo and code has been moved to a first-class Pegasus application / tab.** - Update the docker container registry used by Google Cloud to reflect the latest version in Google. Also push more Google Cloud configuration variables out of the Makefile and into the environment variables. (Thanks Erwin for reporting!) - Added additional `.env` files to `.dockerignore` for Google Cloud builds. - Bumped django to the latest `5.0.6` release. ### Fixed - **SQLite build now properly parse `DATABASE_URL` if it is set. This fixes issues deploying to certain platforms when building with SQLite.** (Thanks Manasvini for reporting!) - Updated allauth documentation links in the README to point to the new [allauth docs site](https://docs.allauth.org/). (Thanks Shantu for reporting!) ### Removed - Removed several no-longer-needed allauth template files. - Removed deprecated "version" field from the dev `docker-compose.yml` file. (Thanks Moyi for reporting!) - Removed no-longer-used `pg-ml` css spacing class. - Removed redundant type="text/javascript" declarations from a few `