bugsink 2.2.0__tar.gz → 2.2.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 (592) hide show
  1. {bugsink-2.2.0 → bugsink-2.2.1}/.github/workflows/ci.yml +15 -11
  2. {bugsink-2.2.0 → bugsink-2.2.1}/.github/workflows/copilot-setup-steps.yml +2 -2
  3. {bugsink-2.2.0 → bugsink-2.2.1}/CHANGELOG.md +20 -1
  4. {bugsink-2.2.0 → bugsink-2.2.1}/PKG-INFO +1 -1
  5. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/prestart.py +11 -2
  6. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/_version.py +3 -3
  7. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/gunicorn.docker.conf.py +1 -0
  8. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/settings/default.py +4 -1
  9. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/settings/development.py +6 -5
  10. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/urls.py +2 -1
  11. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink.egg-info/PKG-INFO +1 -1
  12. {bugsink-2.2.0 → bugsink-2.2.1}/events/api_views.py +33 -11
  13. {bugsink-2.2.0 → bugsink-2.2.1}/files/views.py +1 -0
  14. bugsink-2.2.1/issues/api_views.py +296 -0
  15. {bugsink-2.2.0 → bugsink-2.2.1}/issues/models.py +163 -1
  16. bugsink-2.2.1/issues/serializers.py +90 -0
  17. bugsink-2.2.1/issues/templates/issues/event_details.html +233 -0
  18. bugsink-2.2.1/issues/test_api.py +366 -0
  19. {bugsink-2.2.0 → bugsink-2.2.1}/issues/views.py +7 -152
  20. {bugsink-2.2.0 → bugsink-2.2.1}/projects/api_views.py +38 -8
  21. {bugsink-2.2.0 → bugsink-2.2.1}/releases/api_views.py +33 -6
  22. {bugsink-2.2.0 → bugsink-2.2.1}/teams/api_views.py +35 -8
  23. bugsink-2.2.1/theme/static/css/dist/styles.css +2 -0
  24. bugsink-2.2.0/issues/api_views.py +0 -134
  25. bugsink-2.2.0/issues/serializers.py +0 -41
  26. bugsink-2.2.0/issues/templates/issues/event_details.html +0 -233
  27. bugsink-2.2.0/issues/test_api.py +0 -168
  28. bugsink-2.2.0/theme/static/css/dist/styles.css +0 -2
  29. {bugsink-2.2.0 → bugsink-2.2.1}/.bandit +0 -0
  30. {bugsink-2.2.0 → bugsink-2.2.1}/.coveragerc +0 -0
  31. {bugsink-2.2.0 → bugsink-2.2.1}/.github/dependabot.yml +0 -0
  32. {bugsink-2.2.0 → bugsink-2.2.1}/.gitignore +0 -0
  33. {bugsink-2.2.0 → bugsink-2.2.1}/AGENTS.md +0 -0
  34. {bugsink-2.2.0 → bugsink-2.2.1}/CLA.md +0 -0
  35. {bugsink-2.2.0 → bugsink-2.2.1}/CONTRIBUTING.md +0 -0
  36. {bugsink-2.2.0 → bugsink-2.2.1}/Dockerfile +0 -0
  37. {bugsink-2.2.0 → bugsink-2.2.1}/Dockerfile.fromwheel +0 -0
  38. {bugsink-2.2.0 → bugsink-2.2.1}/LICENSE +0 -0
  39. {bugsink-2.2.0 → bugsink-2.2.1}/README.md +0 -0
  40. {bugsink-2.2.0 → bugsink-2.2.1}/SECURITY.md +0 -0
  41. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/__init__.py +0 -0
  42. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/admin.py +0 -0
  43. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/apps.py +0 -0
  44. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/forms.py +0 -0
  45. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/migrations/0001_initial.py +0 -0
  46. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/migrations/0002_alter_messagingserviceconfig_project.py +0 -0
  47. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/migrations/0003_messagingserviceconfig_last_failure_error_message_and_more.py +0 -0
  48. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/migrations/0004_alter_messagingserviceconfig_kind.py +0 -0
  49. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/migrations/__init__.py +0 -0
  50. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/models.py +0 -0
  51. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/service_backends/__init__.py +0 -0
  52. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/service_backends/base.py +0 -0
  53. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/service_backends/discord.py +0 -0
  54. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/service_backends/mattermost.py +0 -0
  55. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/service_backends/slack.py +0 -0
  56. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/service_backends/webhook_security.py +0 -0
  57. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/tasks.py +0 -0
  58. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/templates/mails/issue_alert.html +0 -0
  59. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/templates/mails/issue_alert.txt +0 -0
  60. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/tests.py +0 -0
  61. {bugsink-2.2.0 → bugsink-2.2.1}/alerts/views.py +0 -0
  62. {bugsink-2.2.0 → bugsink-2.2.1}/api/LICENSE +0 -0
  63. {bugsink-2.2.0 → bugsink-2.2.1}/api/README.md +0 -0
  64. {bugsink-2.2.0 → bugsink-2.2.1}/api/event.schema.altered.json +0 -0
  65. {bugsink-2.2.0 → bugsink-2.2.1}/api/event.schema.json +0 -0
  66. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/__init__.py +0 -0
  67. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/admin.py +0 -0
  68. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/apps.py +0 -0
  69. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/future_python.py +0 -0
  70. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/__init__.py +0 -0
  71. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/__init__.py +0 -0
  72. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/check_migrations.py +0 -0
  73. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/cleanup_objectstorage.py +0 -0
  74. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/convert_mariadb_uuids.py +0 -0
  75. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/create_auth_token.py +0 -0
  76. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/fetch_event_schema_json.py +0 -0
  77. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/makemigrations.py +0 -0
  78. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/migrate.py +0 -0
  79. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/migrate_to_current_objectstorage.py +0 -0
  80. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/modelcounts.py +0 -0
  81. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/munin.py +0 -0
  82. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/raise_exception.py +0 -0
  83. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/send_bomb.py +0 -0
  84. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/send_json.py +0 -0
  85. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/showstat.py +0 -0
  86. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/stress_test.py +0 -0
  87. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/commands/vacuum.py +0 -0
  88. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/management/utils.py +0 -0
  89. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/migrations/0001_initial.py +0 -0
  90. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/migrations/0002_cachedmodelcount.py +0 -0
  91. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/migrations/0003_add_description_to_authtoken.py +0 -0
  92. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/migrations/__init__.py +0 -0
  93. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/models.py +0 -0
  94. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/tasks.py +0 -0
  95. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/templates/bsmain/auth_token_list.html +0 -0
  96. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/test_vacuum.py +0 -0
  97. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/tests.py +0 -0
  98. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/urls.py +0 -0
  99. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/utils.py +0 -0
  100. {bugsink-2.2.0 → bugsink-2.2.1}/bsmain/views.py +0 -0
  101. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/__init__.py +0 -0
  102. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/api_fields.py +0 -0
  103. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/api_mixins.py +0 -0
  104. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/api_pagination.py +0 -0
  105. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/api_serializers.py +0 -0
  106. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/app_settings.py +0 -0
  107. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/authentication.py +0 -0
  108. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/conf_templates/docker.py.template +0 -0
  109. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/conf_templates/local.py.template +0 -0
  110. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/conf_templates/singleserver.py.template +0 -0
  111. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/conf_utils.py +0 -0
  112. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/context_processors.py +0 -0
  113. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/debug_views.py +0 -0
  114. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/decorators.py +0 -0
  115. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/email_backends.py +0 -0
  116. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/event_schema.py +0 -0
  117. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/exceptions.py +0 -0
  118. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/middleware.py +0 -0
  119. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/moreiterutils.py +0 -0
  120. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/period_utils.py +0 -0
  121. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/permissions.py +0 -0
  122. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/pygments_extensions.py +0 -0
  123. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/scripts/__init__.py +0 -0
  124. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/scripts/create_conf.py +0 -0
  125. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/scripts/manage.py +0 -0
  126. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/scripts/runsnappea.py +0 -0
  127. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/scripts/show_version.py +0 -0
  128. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/scripts/util.py +0 -0
  129. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/settings/__init__.py +0 -0
  130. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/streams.py +0 -0
  131. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/test_api.py +0 -0
  132. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/test_utils.py +0 -0
  133. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/tests.py +0 -0
  134. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/timed_sqlite_backend/__init__.py +0 -0
  135. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/timed_sqlite_backend/base.py +0 -0
  136. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/tooling.py +0 -0
  137. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/transaction.py +0 -0
  138. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/utils.py +0 -0
  139. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/version.py +0 -0
  140. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/views.py +0 -0
  141. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/volume_based_condition.py +0 -0
  142. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink/wsgi.py +0 -0
  143. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink.egg-info/SOURCES.txt +0 -0
  144. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink.egg-info/dependency_links.txt +0 -0
  145. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink.egg-info/entry_points.txt +0 -0
  146. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink.egg-info/requires.txt +0 -0
  147. {bugsink-2.2.0 → bugsink-2.2.1}/bugsink.egg-info/top_level.txt +0 -0
  148. {bugsink-2.2.0 → bugsink-2.2.1}/builddocker.bash +0 -0
  149. {bugsink-2.2.0 → bugsink-2.2.1}/buildxdocker.bash +0 -0
  150. {bugsink-2.2.0 → bugsink-2.2.1}/compat/__init__.py +0 -0
  151. {bugsink-2.2.0 → bugsink-2.2.1}/compat/auth.py +0 -0
  152. {bugsink-2.2.0 → bugsink-2.2.1}/compat/dsn.py +0 -0
  153. {bugsink-2.2.0 → bugsink-2.2.1}/compat/tests.py +0 -0
  154. {bugsink-2.2.0 → bugsink-2.2.1}/compat/timestamp.py +0 -0
  155. {bugsink-2.2.0 → bugsink-2.2.1}/compat/vars.py +0 -0
  156. {bugsink-2.2.0 → bugsink-2.2.1}/docker-compose-sample.yaml +0 -0
  157. {bugsink-2.2.0 → bugsink-2.2.1}/ee/LICENSE +0 -0
  158. {bugsink-2.2.0 → bugsink-2.2.1}/ee/__init__.py +0 -0
  159. {bugsink-2.2.0 → bugsink-2.2.1}/ee/tenants/__init__.py +0 -0
  160. {bugsink-2.2.0 → bugsink-2.2.1}/ee/tenants/base.py +0 -0
  161. {bugsink-2.2.0 → bugsink-2.2.1}/ee/tenants/database_backend/__init__.py +0 -0
  162. {bugsink-2.2.0 → bugsink-2.2.1}/ee/tenants/database_backend/base.py +0 -0
  163. {bugsink-2.2.0 → bugsink-2.2.1}/ee/tenants/middleware.py +0 -0
  164. {bugsink-2.2.0 → bugsink-2.2.1}/ee/tenants/utils.py +0 -0
  165. {bugsink-2.2.0 → bugsink-2.2.1}/events/__init__.py +0 -0
  166. {bugsink-2.2.0 → bugsink-2.2.1}/events/admin.py +0 -0
  167. {bugsink-2.2.0 → bugsink-2.2.1}/events/apps.py +0 -0
  168. {bugsink-2.2.0 → bugsink-2.2.1}/events/factories.py +0 -0
  169. {bugsink-2.2.0 → bugsink-2.2.1}/events/management/__init__.py +0 -0
  170. {bugsink-2.2.0 → bugsink-2.2.1}/events/management/commands/__init__.py +0 -0
  171. {bugsink-2.2.0 → bugsink-2.2.1}/events/management/commands/cleanup_eventstorage.py +0 -0
  172. {bugsink-2.2.0 → bugsink-2.2.1}/events/management/commands/delete_by_age_until_under_retention_max.py +0 -0
  173. {bugsink-2.2.0 → bugsink-2.2.1}/events/management/commands/delete_old_events.py +0 -0
  174. {bugsink-2.2.0 → bugsink-2.2.1}/events/management/commands/fix_project_digest_order.py +0 -0
  175. {bugsink-2.2.0 → bugsink-2.2.1}/events/management/commands/make_consistent.py +0 -0
  176. {bugsink-2.2.0 → bugsink-2.2.1}/events/management/commands/migrate_to_current_eventstorage.py +0 -0
  177. {bugsink-2.2.0 → bugsink-2.2.1}/events/management/commands/nuke_events.py +0 -0
  178. {bugsink-2.2.0 → bugsink-2.2.1}/events/markdown_stacktrace.py +0 -0
  179. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0001_initial.py +0 -0
  180. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0002_initial.py +0 -0
  181. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0003_initial.py +0 -0
  182. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0004_b_squashed.py +0 -0
  183. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0004_event_irrelevance_for_retention.py +0 -0
  184. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0005_event_events_even_project_abe572_idx.py +0 -0
  185. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0006_event_never_evict.py +0 -0
  186. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0007_set_never_evict.py +0 -0
  187. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0008_remove_event_events_even_project_abe572_idx_and_more.py +0 -0
  188. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0009_event_events_even_issue_i_90497b_idx.py +0 -0
  189. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0010_rename_ingest_order_event_digest_order_and_more.py +0 -0
  190. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0011_remove_event_events_even_project_adcdee_idx_and_more.py +0 -0
  191. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0012_event_ingested_at.py +0 -0
  192. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0013_harmonize_foogested_at.py +0 -0
  193. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0014_event_grouping.py +0 -0
  194. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0015_set_event_grouping.py +0 -0
  195. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0016_truncate_exception_type_128.py +0 -0
  196. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0017_alter_event_calculated_type_and_more.py +0 -0
  197. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0018_remove_event_has_exception_remove_event_has_logentry.py +0 -0
  198. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0019_event_storage_backend.py +0 -0
  199. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0020_remove_events_with_null_issue_or_grouping.py +0 -0
  200. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0021_alter_do_nothing.py +0 -0
  201. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0022_alter_event_project.py +0 -0
  202. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0023_event_remote_addr.py +0 -0
  203. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0024_remove_event_debug_info.py +0 -0
  204. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0025_fix_never_evict.py +0 -0
  205. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0026_event_events_even_project_625413_idx.py +0 -0
  206. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0027_event_project_digest_order.py +0 -0
  207. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/0028_event_events_even_digeste_bf21dd_idx.py +0 -0
  208. {bugsink-2.2.0 → bugsink-2.2.1}/events/migrations/__init__.py +0 -0
  209. {bugsink-2.2.0 → bugsink-2.2.1}/events/models.py +0 -0
  210. {bugsink-2.2.0 → bugsink-2.2.1}/events/renderers.py +0 -0
  211. {bugsink-2.2.0 → bugsink-2.2.1}/events/retention.py +0 -0
  212. {bugsink-2.2.0 → bugsink-2.2.1}/events/serializers.py +0 -0
  213. {bugsink-2.2.0 → bugsink-2.2.1}/events/storage.py +0 -0
  214. {bugsink-2.2.0 → bugsink-2.2.1}/events/storage_registry.py +0 -0
  215. {bugsink-2.2.0 → bugsink-2.2.1}/events/tasks.py +0 -0
  216. {bugsink-2.2.0 → bugsink-2.2.1}/events/templates/events/event_stacktrace.txt +0 -0
  217. {bugsink-2.2.0 → bugsink-2.2.1}/events/test_api.py +0 -0
  218. {bugsink-2.2.0 → bugsink-2.2.1}/events/tests.py +0 -0
  219. {bugsink-2.2.0 → bugsink-2.2.1}/events/ua_stuff.py +0 -0
  220. {bugsink-2.2.0 → bugsink-2.2.1}/events/urls.py +0 -0
  221. {bugsink-2.2.0 → bugsink-2.2.1}/events/utils.py +0 -0
  222. {bugsink-2.2.0 → bugsink-2.2.1}/events/views.py +0 -0
  223. {bugsink-2.2.0 → bugsink-2.2.1}/files/__init__.py +0 -0
  224. {bugsink-2.2.0 → bugsink-2.2.1}/files/admin.py +0 -0
  225. {bugsink-2.2.0 → bugsink-2.2.1}/files/apps.py +0 -0
  226. {bugsink-2.2.0 → bugsink-2.2.1}/files/management/__init__.py +0 -0
  227. {bugsink-2.2.0 → bugsink-2.2.1}/files/management/commands/__init__.py +0 -0
  228. {bugsink-2.2.0 → bugsink-2.2.1}/files/management/commands/delete_legacy_sourcemaps.py +0 -0
  229. {bugsink-2.2.0 → bugsink-2.2.1}/files/management/commands/vacuum_files.py +0 -0
  230. {bugsink-2.2.0 → bugsink-2.2.1}/files/migrations/0001_initial.py +0 -0
  231. {bugsink-2.2.0 → bugsink-2.2.1}/files/migrations/0002_chunk_created_at_file_accessed_at_file_created_at_and_more.py +0 -0
  232. {bugsink-2.2.0 → bugsink-2.2.1}/files/migrations/0003_file_storage_backend.py +0 -0
  233. {bugsink-2.2.0 → bugsink-2.2.1}/files/migrations/0004_alter_filemetadata_unique_together_and_more.py +0 -0
  234. {bugsink-2.2.0 → bugsink-2.2.1}/files/migrations/__init__.py +0 -0
  235. {bugsink-2.2.0 → bugsink-2.2.1}/files/minidump.py +0 -0
  236. {bugsink-2.2.0 → bugsink-2.2.1}/files/models.py +0 -0
  237. {bugsink-2.2.0 → bugsink-2.2.1}/files/object_kinds.py +0 -0
  238. {bugsink-2.2.0 → bugsink-2.2.1}/files/storage.py +0 -0
  239. {bugsink-2.2.0 → bugsink-2.2.1}/files/storage_registry.py +0 -0
  240. {bugsink-2.2.0 → bugsink-2.2.1}/files/tasks.py +0 -0
  241. {bugsink-2.2.0 → bugsink-2.2.1}/files/test_vacuum.py +0 -0
  242. {bugsink-2.2.0 → bugsink-2.2.1}/files/tests.py +0 -0
  243. {bugsink-2.2.0 → bugsink-2.2.1}/files/urls.py +0 -0
  244. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/__init__.py +0 -0
  245. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/admin.py +0 -0
  246. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/apps.py +0 -0
  247. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/event_counter.py +0 -0
  248. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/exceptions.py +0 -0
  249. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/filestore.py +0 -0
  250. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/header_validators.py +0 -0
  251. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/management/__init__.py +0 -0
  252. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/management/commands/__init__.py +0 -0
  253. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/management/commands/vacuum_ingest_dir.py +0 -0
  254. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/migrations/0001_set_sqlite_wal.py +0 -0
  255. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/migrations/0002_initial.py +0 -0
  256. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/migrations/__init__.py +0 -0
  257. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/models.py +0 -0
  258. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/parsers.py +0 -0
  259. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/tasks.py +0 -0
  260. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/tests.py +0 -0
  261. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/urls.py +0 -0
  262. {bugsink-2.2.0 → bugsink-2.2.1}/ingest/views.py +0 -0
  263. {bugsink-2.2.0 → bugsink-2.2.1}/issues/__init__.py +0 -0
  264. {bugsink-2.2.0 → bugsink-2.2.1}/issues/admin.py +0 -0
  265. {bugsink-2.2.0 → bugsink-2.2.1}/issues/apps.py +0 -0
  266. {bugsink-2.2.0 → bugsink-2.2.1}/issues/factories.py +0 -0
  267. {bugsink-2.2.0 → bugsink-2.2.1}/issues/forms.py +0 -0
  268. {bugsink-2.2.0 → bugsink-2.2.1}/issues/markdown_issue.py +0 -0
  269. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0001_initial.py +0 -0
  270. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0002_initial.py +0 -0
  271. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0003_alter_turningpoint_triggering_event.py +0 -0
  272. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0004_b_squashed.py +0 -0
  273. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0004_rename_event_count_issue_digested_event_count.py +0 -0
  274. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0005_rename_ingest_order_issue_digest_order_and_more.py +0 -0
  275. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0006_issue_next_unmute_check.py +0 -0
  276. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0007_alter_turningpoint_options.py +0 -0
  277. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0008_issue_stored_event_count.py +0 -0
  278. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0009_fill_stored_event_count.py +0 -0
  279. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0010_issue_list_indexes.py +0 -0
  280. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0011_truncate_exception_type_128.py +0 -0
  281. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0012_alter_issue_calculated_type_and_more.py +0 -0
  282. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0013_fix_issue_stored_event_counts.py +0 -0
  283. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0014_grouping_grouping_key_hash.py +0 -0
  284. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0015_set_grouping_hash.py +0 -0
  285. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0016_alter_grouping_unique_together.py +0 -0
  286. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0017_issue_list_indexes_must_start_with_project.py +0 -0
  287. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0018_issue_is_deleted.py +0 -0
  288. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0019_alter_grouping_grouping_key_hash.py +0 -0
  289. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0020_remove_objects_with_null_issue.py +0 -0
  290. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0021_alter_do_nothing.py +0 -0
  291. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0022_turningpoint_project.py +0 -0
  292. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0023_turningpoint_set_project.py +0 -0
  293. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0024_turningpoint_project_alter_not_null.py +0 -0
  294. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/0025_alter_grouping_project_alter_issue_project.py +0 -0
  295. {bugsink-2.2.0 → bugsink-2.2.1}/issues/migrations/__init__.py +0 -0
  296. {bugsink-2.2.0 → bugsink-2.2.1}/issues/regressions.py +0 -0
  297. {bugsink-2.2.0 → bugsink-2.2.1}/issues/tasks.py +0 -0
  298. {bugsink-2.2.0 → bugsink-2.2.1}/issues/templates/issues/_event_nav.html +0 -0
  299. {bugsink-2.2.0 → bugsink-2.2.1}/issues/templates/issues/base.html +0 -0
  300. {bugsink-2.2.0 → bugsink-2.2.1}/issues/templates/issues/breadcrumbs.html +0 -0
  301. {bugsink-2.2.0 → bugsink-2.2.1}/issues/templates/issues/event_404.html +0 -0
  302. {bugsink-2.2.0 → bugsink-2.2.1}/issues/templates/issues/event_list.html +0 -0
  303. {bugsink-2.2.0 → bugsink-2.2.1}/issues/templates/issues/grouping.html +0 -0
  304. {bugsink-2.2.0 → bugsink-2.2.1}/issues/templates/issues/history.html +0 -0
  305. {bugsink-2.2.0 → bugsink-2.2.1}/issues/templates/issues/issue_list.html +0 -0
  306. {bugsink-2.2.0 → bugsink-2.2.1}/issues/templates/issues/stacktrace.html +0 -0
  307. {bugsink-2.2.0 → bugsink-2.2.1}/issues/templates/issues/tags.html +0 -0
  308. {bugsink-2.2.0 → bugsink-2.2.1}/issues/tests.py +0 -0
  309. {bugsink-2.2.0 → bugsink-2.2.1}/issues/urls.py +0 -0
  310. {bugsink-2.2.0 → bugsink-2.2.1}/issues/utils.py +0 -0
  311. {bugsink-2.2.0 → bugsink-2.2.1}/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  312. {bugsink-2.2.0 → bugsink-2.2.1}/locale/zh_Hans/LC_MESSAGES/django.po +0 -0
  313. {bugsink-2.2.0 → bugsink-2.2.1}/manage.py +0 -0
  314. {bugsink-2.2.0 → bugsink-2.2.1}/performance/__init__.py +0 -0
  315. {bugsink-2.2.0 → bugsink-2.2.1}/performance/bursty_data.py +0 -0
  316. {bugsink-2.2.0 → bugsink-2.2.1}/performance/context_managers.py +0 -0
  317. {bugsink-2.2.0 → bugsink-2.2.1}/performance/management/__init__.py +0 -0
  318. {bugsink-2.2.0 → bugsink-2.2.1}/performance/management/commands/__init__.py +0 -0
  319. {bugsink-2.2.0 → bugsink-2.2.1}/performance/management/commands/pftest_search.py +0 -0
  320. {bugsink-2.2.0 → bugsink-2.2.1}/performance/stress-with-eviction/README.md +0 -0
  321. {bugsink-2.2.0 → bugsink-2.2.1}/performance/stress-with-eviction/df-day.png +0 -0
  322. {bugsink-2.2.0 → bugsink-2.2.1}/performance/stress-with-eviction/event_ingest_count-day.png +0 -0
  323. {bugsink-2.2.0 → bugsink-2.2.1}/performance/stress-with-eviction/response_time_api_avg-day.png +0 -0
  324. {bugsink-2.2.0 → bugsink-2.2.1}/performance/stress-with-eviction/response_time_api_max-day.png +0 -0
  325. {bugsink-2.2.0 → bugsink-2.2.1}/performance/stress-with-eviction/snappea_queue_size-day.png +0 -0
  326. {bugsink-2.2.0 → bugsink-2.2.1}/performance/stress-with-eviction/total_requests-day.png +0 -0
  327. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/__init__.py +0 -0
  328. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/admin.py +0 -0
  329. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/apps.py +0 -0
  330. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/management/__init__.py +0 -0
  331. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/management/commands/__init__.py +0 -0
  332. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/management/commands/print_phonehome.py +0 -0
  333. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/migrations/0001_b_squashed_initial.py +0 -0
  334. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/migrations/0001_initial.py +0 -0
  335. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/migrations/0002_create_installation_id.py +0 -0
  336. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/migrations/0002_installation_email_quota_usage.py +0 -0
  337. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/migrations/0003_installation_ingest_quotas.py +0 -0
  338. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/migrations/0003_outboundmessage.py +0 -0
  339. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/migrations/0004_installation_created_at.py +0 -0
  340. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/migrations/0004_installation_quota_exceeded_reason.py +0 -0
  341. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/migrations/0005_installation_silence_email_system_warning.py +0 -0
  342. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/migrations/0005_reset_quota_exceeded_until.py +0 -0
  343. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/migrations/0006_recalculate_installation_next_quota_check.py +0 -0
  344. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/migrations/__init__.py +0 -0
  345. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/models.py +0 -0
  346. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/tasks.py +0 -0
  347. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/tests.py +0 -0
  348. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/utils.py +0 -0
  349. {bugsink-2.2.0 → bugsink-2.2.1}/phonehome/views.py +0 -0
  350. {bugsink-2.2.0 → bugsink-2.2.1}/pre-commit +0 -0
  351. {bugsink-2.2.0 → bugsink-2.2.1}/projects/__init__.py +0 -0
  352. {bugsink-2.2.0 → bugsink-2.2.1}/projects/admin.py +0 -0
  353. {bugsink-2.2.0 → bugsink-2.2.1}/projects/apps.py +0 -0
  354. {bugsink-2.2.0 → bugsink-2.2.1}/projects/context_processors.py +0 -0
  355. {bugsink-2.2.0 → bugsink-2.2.1}/projects/forms.py +0 -0
  356. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0001_initial.py +0 -0
  357. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0002_b_squashed_initial.py +0 -0
  358. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0002_initial.py +0 -0
  359. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0003_project_projects_pr_name_11d782_idx.py +0 -0
  360. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0003_project_retention_max_event_count.py +0 -0
  361. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0004_project_quota_exceeded_until.py +0 -0
  362. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0005_project_ingested_event_count.py +0 -0
  363. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0006_initial_ingested_count_value.py +0 -0
  364. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0007_rename_ingested_event_count_project_digested_event_count.py +0 -0
  365. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0008_project_next_quota_check.py +0 -0
  366. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0009_alter_project_visibility.py +0 -0
  367. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0010_project_stored_event_count.py +0 -0
  368. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0011_fill_stored_event_count.py +0 -0
  369. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0012_project_is_deleted.py +0 -0
  370. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0013_delete_objects_pointing_to_null_project.py +0 -0
  371. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0014_alter_projectmembership_project.py +0 -0
  372. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0015_project_quota_exceeded_reason.py +0 -0
  373. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0016_reset_quota_exceeded_until.py +0 -0
  374. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/0017_project_issue_count.py +0 -0
  375. {bugsink-2.2.0 → bugsink-2.2.1}/projects/migrations/__init__.py +0 -0
  376. {bugsink-2.2.0 → bugsink-2.2.1}/projects/models.py +0 -0
  377. {bugsink-2.2.0 → bugsink-2.2.1}/projects/serializers.py +0 -0
  378. {bugsink-2.2.0 → bugsink-2.2.1}/projects/tasks.py +0 -0
  379. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/mails/project_membership_invite.html +0 -0
  380. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/mails/project_membership_invite.txt +0 -0
  381. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/mails/project_membership_invite_new_user.html +0 -0
  382. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/mails/project_membership_invite_new_user.txt +0 -0
  383. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/projects/project_alerts_setup.html +0 -0
  384. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/projects/project_edit.html +0 -0
  385. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/projects/project_list.html +0 -0
  386. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/projects/project_member_settings.html +0 -0
  387. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/projects/project_members.html +0 -0
  388. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/projects/project_members_accept.html +0 -0
  389. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/projects/project_members_invite.html +0 -0
  390. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/projects/project_messaging_service_edit.html +0 -0
  391. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/projects/project_messaging_service_new.html +0 -0
  392. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/projects/project_new.html +0 -0
  393. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/projects/project_sdk_setup.html +0 -0
  394. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/projects/project_sdk_setup_javascript.html +0 -0
  395. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/projects/project_sdk_setup_php.html +0 -0
  396. {bugsink-2.2.0 → bugsink-2.2.1}/projects/templates/projects/project_sdk_setup_python.html +0 -0
  397. {bugsink-2.2.0 → bugsink-2.2.1}/projects/test_api.py +0 -0
  398. {bugsink-2.2.0 → bugsink-2.2.1}/projects/tests.py +0 -0
  399. {bugsink-2.2.0 → bugsink-2.2.1}/projects/urls.py +0 -0
  400. {bugsink-2.2.0 → bugsink-2.2.1}/projects/views.py +0 -0
  401. {bugsink-2.2.0 → bugsink-2.2.1}/pyproject.toml +0 -0
  402. {bugsink-2.2.0 → bugsink-2.2.1}/releases/__init__.py +0 -0
  403. {bugsink-2.2.0 → bugsink-2.2.1}/releases/admin.py +0 -0
  404. {bugsink-2.2.0 → bugsink-2.2.1}/releases/apps.py +0 -0
  405. {bugsink-2.2.0 → bugsink-2.2.1}/releases/migrations/0001_initial.py +0 -0
  406. {bugsink-2.2.0 → bugsink-2.2.1}/releases/migrations/0002_release_releases_re_sort_ep_5c07c8_idx.py +0 -0
  407. {bugsink-2.2.0 → bugsink-2.2.1}/releases/migrations/0003_alter_release_project.py +0 -0
  408. {bugsink-2.2.0 → bugsink-2.2.1}/releases/migrations/0004_fix_indexes.py +0 -0
  409. {bugsink-2.2.0 → bugsink-2.2.1}/releases/migrations/__init__.py +0 -0
  410. {bugsink-2.2.0 → bugsink-2.2.1}/releases/models.py +0 -0
  411. {bugsink-2.2.0 → bugsink-2.2.1}/releases/serializers.py +0 -0
  412. {bugsink-2.2.0 → bugsink-2.2.1}/releases/test_api.py +0 -0
  413. {bugsink-2.2.0 → bugsink-2.2.1}/releases/tests.py +0 -0
  414. {bugsink-2.2.0 → bugsink-2.2.1}/releases/views.py +0 -0
  415. {bugsink-2.2.0 → bugsink-2.2.1}/requirements.development.txt +0 -0
  416. {bugsink-2.2.0 → bugsink-2.2.1}/requirements.txt +0 -0
  417. {bugsink-2.2.0 → bugsink-2.2.1}/sentry/LICENSE +0 -0
  418. {bugsink-2.2.0 → bugsink-2.2.1}/sentry/__init__.py +0 -0
  419. {bugsink-2.2.0 → bugsink-2.2.1}/sentry/assemble.py +0 -0
  420. {bugsink-2.2.0 → bugsink-2.2.1}/sentry/minidump.py +0 -0
  421. {bugsink-2.2.0 → bugsink-2.2.1}/sentry/stacktraces/functions.py +0 -0
  422. {bugsink-2.2.0 → bugsink-2.2.1}/sentry/stacktraces/platform.py +0 -0
  423. {bugsink-2.2.0 → bugsink-2.2.1}/sentry/stacktraces/processing.py +0 -0
  424. {bugsink-2.2.0 → bugsink-2.2.1}/sentry/utils/safe.py +0 -0
  425. {bugsink-2.2.0 → bugsink-2.2.1}/sentry/utils/strings.py +0 -0
  426. {bugsink-2.2.0 → bugsink-2.2.1}/sentry_sdk_extensions/__init__.py +0 -0
  427. {bugsink-2.2.0 → bugsink-2.2.1}/sentry_sdk_extensions/tests.py +0 -0
  428. {bugsink-2.2.0 → bugsink-2.2.1}/sentry_sdk_extensions/transport.py +0 -0
  429. {bugsink-2.2.0 → bugsink-2.2.1}/setup.cfg +0 -0
  430. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/__init__.py +0 -0
  431. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/admin.py +0 -0
  432. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/apps.py +0 -0
  433. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/datastructures.py +0 -0
  434. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/dbrouters.py +0 -0
  435. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/decorators.py +0 -0
  436. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/example_tasks.py +0 -0
  437. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/foreman.py +0 -0
  438. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/management/__init__.py +0 -0
  439. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/management/commands/__init__.py +0 -0
  440. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/management/commands/checksnappea.py +0 -0
  441. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/management/commands/runsnappea.py +0 -0
  442. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/migrations/0001_initial.py +0 -0
  443. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/migrations/0002_create_models.py +0 -0
  444. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/migrations/0003_task_created_at.py +0 -0
  445. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/migrations/0004_task_snappea_tas_created_eb0824_idx.py +0 -0
  446. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/migrations/0005_stat.py +0 -0
  447. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/migrations/__init__.py +0 -0
  448. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/models.py +0 -0
  449. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/settings.py +0 -0
  450. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/stats.py +0 -0
  451. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/tests.py +0 -0
  452. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/utils.py +0 -0
  453. {bugsink-2.2.0 → bugsink-2.2.1}/snappea/views.py +0 -0
  454. {bugsink-2.2.0 → bugsink-2.2.1}/static/favicon.png +0 -0
  455. {bugsink-2.2.0 → bugsink-2.2.1}/static/fonts/ibm-plex-mono-v19-cyrillic_cyrillic-ext_latin_latin-ext_vietnamese-700.woff2 +0 -0
  456. {bugsink-2.2.0 → bugsink-2.2.1}/static/fonts/ibm-plex-mono-v19-cyrillic_cyrillic-ext_latin_latin-ext_vietnamese-700italic.woff2 +0 -0
  457. {bugsink-2.2.0 → bugsink-2.2.1}/static/fonts/ibm-plex-mono-v19-cyrillic_cyrillic-ext_latin_latin-ext_vietnamese-italic.woff2 +0 -0
  458. {bugsink-2.2.0 → bugsink-2.2.1}/static/fonts/ibm-plex-mono-v19-cyrillic_cyrillic-ext_latin_latin-ext_vietnamese-regular.woff2 +0 -0
  459. {bugsink-2.2.0 → bugsink-2.2.1}/static/fonts/ibm-plex-sans-v19-cyrillic_cyrillic-ext_greek_latin_latin-ext_vietnamese-700.woff2 +0 -0
  460. {bugsink-2.2.0 → bugsink-2.2.1}/static/fonts/ibm-plex-sans-v19-cyrillic_cyrillic-ext_greek_latin_latin-ext_vietnamese-700italic.woff2 +0 -0
  461. {bugsink-2.2.0 → bugsink-2.2.1}/static/fonts/ibm-plex-sans-v19-cyrillic_cyrillic-ext_greek_latin_latin-ext_vietnamese-italic.woff2 +0 -0
  462. {bugsink-2.2.0 → bugsink-2.2.1}/static/fonts/ibm-plex-sans-v19-cyrillic_cyrillic-ext_greek_latin_latin-ext_vietnamese-regular.woff2 +0 -0
  463. {bugsink-2.2.0 → bugsink-2.2.1}/static/images/bugsink-logo-dark.png +0 -0
  464. {bugsink-2.2.0 → bugsink-2.2.1}/static/images/bugsink-logo.png +0 -0
  465. {bugsink-2.2.0 → bugsink-2.2.1}/static/images/lang-javascript.png +0 -0
  466. {bugsink-2.2.0 → bugsink-2.2.1}/static/images/lang-php.png +0 -0
  467. {bugsink-2.2.0 → bugsink-2.2.1}/static/images/lang-python.png +0 -0
  468. {bugsink-2.2.0 → bugsink-2.2.1}/static/js/entity_edit.js +0 -0
  469. {bugsink-2.2.0 → bugsink-2.2.1}/static/js/issue_history.js +0 -0
  470. {bugsink-2.2.0 → bugsink-2.2.1}/static/js/issue_list.js +0 -0
  471. {bugsink-2.2.0 → bugsink-2.2.1}/static/js/issue_stacktrace.js +0 -0
  472. {bugsink-2.2.0 → bugsink-2.2.1}/static/js/project_list.js +0 -0
  473. {bugsink-2.2.0 → bugsink-2.2.1}/static/js/team_list.js +0 -0
  474. {bugsink-2.2.0 → bugsink-2.2.1}/static/js/user_list.js +0 -0
  475. {bugsink-2.2.0 → bugsink-2.2.1}/tags/__init__.py +0 -0
  476. {bugsink-2.2.0 → bugsink-2.2.1}/tags/admin.py +0 -0
  477. {bugsink-2.2.0 → bugsink-2.2.1}/tags/apps.py +0 -0
  478. {bugsink-2.2.0 → bugsink-2.2.1}/tags/management/__init__.py +0 -0
  479. {bugsink-2.2.0 → bugsink-2.2.1}/tags/management/commands/__init__.py +0 -0
  480. {bugsink-2.2.0 → bugsink-2.2.1}/tags/management/commands/init_tags.py +0 -0
  481. {bugsink-2.2.0 → bugsink-2.2.1}/tags/management/commands/vacuum_eventless_issuetags.py +0 -0
  482. {bugsink-2.2.0 → bugsink-2.2.1}/tags/management/commands/vacuum_tags.py +0 -0
  483. {bugsink-2.2.0 → bugsink-2.2.1}/tags/migrations/0001_initial.py +0 -0
  484. {bugsink-2.2.0 → bugsink-2.2.1}/tags/migrations/0002_no_cascade.py +0 -0
  485. {bugsink-2.2.0 → bugsink-2.2.1}/tags/migrations/0003_remove_objects_with_null_issue.py +0 -0
  486. {bugsink-2.2.0 → bugsink-2.2.1}/tags/migrations/0004_alter_do_nothing.py +0 -0
  487. {bugsink-2.2.0 → bugsink-2.2.1}/tags/migrations/0005_alter_eventtag_project_alter_issuetag_project_and_more.py +0 -0
  488. {bugsink-2.2.0 → bugsink-2.2.1}/tags/migrations/__init__.py +0 -0
  489. {bugsink-2.2.0 → bugsink-2.2.1}/tags/models.py +0 -0
  490. {bugsink-2.2.0 → bugsink-2.2.1}/tags/search.py +0 -0
  491. {bugsink-2.2.0 → bugsink-2.2.1}/tags/tasks.py +0 -0
  492. {bugsink-2.2.0 → bugsink-2.2.1}/tags/tests.py +0 -0
  493. {bugsink-2.2.0 → bugsink-2.2.1}/tags/utils.py +0 -0
  494. {bugsink-2.2.0 → bugsink-2.2.1}/teams/__init__.py +0 -0
  495. {bugsink-2.2.0 → bugsink-2.2.1}/teams/admin.py +0 -0
  496. {bugsink-2.2.0 → bugsink-2.2.1}/teams/apps.py +0 -0
  497. {bugsink-2.2.0 → bugsink-2.2.1}/teams/forms.py +0 -0
  498. {bugsink-2.2.0 → bugsink-2.2.1}/teams/migrations/0001_b_squashed_initial.py +0 -0
  499. {bugsink-2.2.0 → bugsink-2.2.1}/teams/migrations/0001_initial.py +0 -0
  500. {bugsink-2.2.0 → bugsink-2.2.1}/teams/migrations/0002_initial.py +0 -0
  501. {bugsink-2.2.0 → bugsink-2.2.1}/teams/migrations/0002_team_teams_team_name_43e047_idx.py +0 -0
  502. {bugsink-2.2.0 → bugsink-2.2.1}/teams/migrations/0003_alter_team_visibility.py +0 -0
  503. {bugsink-2.2.0 → bugsink-2.2.1}/teams/migrations/0004_remove_team_slug.py +0 -0
  504. {bugsink-2.2.0 → bugsink-2.2.1}/teams/migrations/__init__.py +0 -0
  505. {bugsink-2.2.0 → bugsink-2.2.1}/teams/models.py +0 -0
  506. {bugsink-2.2.0 → bugsink-2.2.1}/teams/serializers.py +0 -0
  507. {bugsink-2.2.0 → bugsink-2.2.1}/teams/tasks.py +0 -0
  508. {bugsink-2.2.0 → bugsink-2.2.1}/teams/templates/mails/team_membership_invite.html +0 -0
  509. {bugsink-2.2.0 → bugsink-2.2.1}/teams/templates/mails/team_membership_invite.txt +0 -0
  510. {bugsink-2.2.0 → bugsink-2.2.1}/teams/templates/mails/team_membership_invite_new_user.html +0 -0
  511. {bugsink-2.2.0 → bugsink-2.2.1}/teams/templates/mails/team_membership_invite_new_user.txt +0 -0
  512. {bugsink-2.2.0 → bugsink-2.2.1}/teams/templates/teams/team_edit.html +0 -0
  513. {bugsink-2.2.0 → bugsink-2.2.1}/teams/templates/teams/team_list.html +0 -0
  514. {bugsink-2.2.0 → bugsink-2.2.1}/teams/templates/teams/team_member_settings.html +0 -0
  515. {bugsink-2.2.0 → bugsink-2.2.1}/teams/templates/teams/team_members.html +0 -0
  516. {bugsink-2.2.0 → bugsink-2.2.1}/teams/templates/teams/team_members_accept.html +0 -0
  517. {bugsink-2.2.0 → bugsink-2.2.1}/teams/templates/teams/team_members_invite.html +0 -0
  518. {bugsink-2.2.0 → bugsink-2.2.1}/teams/templates/teams/team_new.html +0 -0
  519. {bugsink-2.2.0 → bugsink-2.2.1}/teams/test_api.py +0 -0
  520. {bugsink-2.2.0 → bugsink-2.2.1}/teams/tests.py +0 -0
  521. {bugsink-2.2.0 → bugsink-2.2.1}/teams/urls.py +0 -0
  522. {bugsink-2.2.0 → bugsink-2.2.1}/teams/views.py +0 -0
  523. {bugsink-2.2.0 → bugsink-2.2.1}/templates/400.html +0 -0
  524. {bugsink-2.2.0 → bugsink-2.2.1}/templates/403.html +0 -0
  525. {bugsink-2.2.0 → bugsink-2.2.1}/templates/403_csrf.html +0 -0
  526. {bugsink-2.2.0 → bugsink-2.2.1}/templates/404.html +0 -0
  527. {bugsink-2.2.0 → bugsink-2.2.1}/templates/4xx_5xx_api.txt +0 -0
  528. {bugsink-2.2.0 → bugsink-2.2.1}/templates/500.html +0 -0
  529. {bugsink-2.2.0 → bugsink-2.2.1}/templates/503.html +0 -0
  530. {bugsink-2.2.0 → bugsink-2.2.1}/templates/admin/change_form_object_tools.html +0 -0
  531. {bugsink-2.2.0 → bugsink-2.2.1}/templates/bugsink/counts.html +0 -0
  532. {bugsink-2.2.0 → bugsink-2.2.1}/templates/bugsink/csrf_debug.html +0 -0
  533. {bugsink-2.2.0 → bugsink-2.2.1}/templates/bugsink/login.html +0 -0
  534. {bugsink-2.2.0 → bugsink-2.2.1}/templates/bugsink/settings.html +0 -0
  535. {bugsink-2.2.0 → bugsink-2.2.1}/templates/robots.txt +0 -0
  536. {bugsink-2.2.0 → bugsink-2.2.1}/templates/signup.html +0 -0
  537. {bugsink-2.2.0 → bugsink-2.2.1}/theme/__init__.py +0 -0
  538. {bugsink-2.2.0 → bugsink-2.2.1}/theme/apps.py +0 -0
  539. {bugsink-2.2.0 → bugsink-2.2.1}/theme/static_src/.gitignore +0 -0
  540. {bugsink-2.2.0 → bugsink-2.2.1}/theme/static_src/package-lock.json +0 -0
  541. {bugsink-2.2.0 → bugsink-2.2.1}/theme/static_src/package.json +0 -0
  542. {bugsink-2.2.0 → bugsink-2.2.1}/theme/static_src/postcss.config.js +0 -0
  543. {bugsink-2.2.0 → bugsink-2.2.1}/theme/static_src/src/styles.css +0 -0
  544. {bugsink-2.2.0 → bugsink-2.2.1}/theme/static_src/tailwind.config.js +0 -0
  545. {bugsink-2.2.0 → bugsink-2.2.1}/theme/templates/bare_base.html +0 -0
  546. {bugsink-2.2.0 → bugsink-2.2.1}/theme/templates/barest_base.html +0 -0
  547. {bugsink-2.2.0 → bugsink-2.2.1}/theme/templates/base.html +0 -0
  548. {bugsink-2.2.0 → bugsink-2.2.1}/theme/templates/tailwind_forms/formfield.html +0 -0
  549. {bugsink-2.2.0 → bugsink-2.2.1}/theme/templatetags/__init__.py +0 -0
  550. {bugsink-2.2.0 → bugsink-2.2.1}/theme/templatetags/add_to_qs.py +0 -0
  551. {bugsink-2.2.0 → bugsink-2.2.1}/theme/templatetags/code.py +0 -0
  552. {bugsink-2.2.0 → bugsink-2.2.1}/theme/templatetags/issues.py +0 -0
  553. {bugsink-2.2.0 → bugsink-2.2.1}/theme/templatetags/stricter_templates.py +0 -0
  554. {bugsink-2.2.0 → bugsink-2.2.1}/theme/templatetags/tailwind_forms.py +0 -0
  555. {bugsink-2.2.0 → bugsink-2.2.1}/theme/templatetags/user.py +0 -0
  556. {bugsink-2.2.0 → bugsink-2.2.1}/theme/templatetags/version.py +0 -0
  557. {bugsink-2.2.0 → bugsink-2.2.1}/theme/tests.py +0 -0
  558. {bugsink-2.2.0 → bugsink-2.2.1}/tools/is_tracked_by_tailwind.py +0 -0
  559. {bugsink-2.2.0 → bugsink-2.2.1}/tools/strip-trailing-whitespace.sh +0 -0
  560. {bugsink-2.2.0 → bugsink-2.2.1}/users/__init__.py +0 -0
  561. {bugsink-2.2.0 → bugsink-2.2.1}/users/admin.py +0 -0
  562. {bugsink-2.2.0 → bugsink-2.2.1}/users/apps.py +0 -0
  563. {bugsink-2.2.0 → bugsink-2.2.1}/users/forms.py +0 -0
  564. {bugsink-2.2.0 → bugsink-2.2.1}/users/management/__init__.py +0 -0
  565. {bugsink-2.2.0 → bugsink-2.2.1}/users/management/commands/__init__.py +0 -0
  566. {bugsink-2.2.0 → bugsink-2.2.1}/users/management/commands/send_welcome_email.py +0 -0
  567. {bugsink-2.2.0 → bugsink-2.2.1}/users/migrations/0001_initial.py +0 -0
  568. {bugsink-2.2.0 → bugsink-2.2.1}/users/migrations/0002_user_theme_preference.py +0 -0
  569. {bugsink-2.2.0 → bugsink-2.2.1}/users/migrations/0003_user_language.py +0 -0
  570. {bugsink-2.2.0 → bugsink-2.2.1}/users/migrations/0004_alter_user_language.py +0 -0
  571. {bugsink-2.2.0 → bugsink-2.2.1}/users/migrations/__init__.py +0 -0
  572. {bugsink-2.2.0 → bugsink-2.2.1}/users/models.py +0 -0
  573. {bugsink-2.2.0 → bugsink-2.2.1}/users/tasks.py +0 -0
  574. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/mails/confirm_email.html +0 -0
  575. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/mails/confirm_email.txt +0 -0
  576. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/mails/reset_password_email.html +0 -0
  577. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/mails/reset_password_email.txt +0 -0
  578. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/mails/welcome_email.html +0 -0
  579. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/mails/welcome_email.txt +0 -0
  580. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/users/confirm_email.html +0 -0
  581. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/users/confirm_email_sent.html +0 -0
  582. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/users/logged_out.html +0 -0
  583. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/users/preferences.html +0 -0
  584. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/users/request_reset_password.html +0 -0
  585. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/users/resend_confirmation.html +0 -0
  586. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/users/reset_password.html +0 -0
  587. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/users/reset_password_email_sent.html +0 -0
  588. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/users/user_edit.html +0 -0
  589. {bugsink-2.2.0 → bugsink-2.2.1}/users/templates/users/user_list.html +0 -0
  590. {bugsink-2.2.0 → bugsink-2.2.1}/users/tests.py +0 -0
  591. {bugsink-2.2.0 → bugsink-2.2.1}/users/urls.py +0 -0
  592. {bugsink-2.2.0 → bugsink-2.2.1}/users/views.py +0 -0
@@ -25,9 +25,9 @@ jobs:
25
25
  ruff:
26
26
  runs-on: ubuntu-latest
27
27
  steps:
28
- - uses: actions/checkout@v4
28
+ - uses: actions/checkout@v6
29
29
  - name: "Set up Python 3.12"
30
- uses: actions/setup-python@v5
30
+ uses: actions/setup-python@v6
31
31
  with:
32
32
  python-version: "3.12"
33
33
  - name: Install Ruff
@@ -40,10 +40,10 @@ jobs:
40
40
  bandit:
41
41
  runs-on: ubuntu-latest
42
42
  steps:
43
- - uses: actions/checkout@v4
43
+ - uses: actions/checkout@v6
44
44
 
45
45
  - name: Set up Python
46
- uses: actions/setup-python@v5
46
+ uses: actions/setup-python@v6
47
47
  with:
48
48
  python-version: 3.12
49
49
 
@@ -106,9 +106,9 @@ jobs:
106
106
  DB_USER: ${{ matrix.db_user }}
107
107
  DB_PASSWORD: ${{ matrix.db_password }}
108
108
  steps:
109
- - uses: actions/checkout@v4
109
+ - uses: actions/checkout@v6
110
110
  - name: Set up Python ${{ matrix.python-version }}
111
- uses: actions/setup-python@v5
111
+ uses: actions/setup-python@v6
112
112
  with:
113
113
  python-version: ${{ matrix.python-version }}
114
114
  - name: Start MySQL If Needed
@@ -134,7 +134,7 @@ jobs:
134
134
  pip install -r requirements.development.txt
135
135
  pip install mysqlclient psycopg2
136
136
  - name: Check out event-samples
137
- uses: actions/checkout@master
137
+ uses: actions/checkout@v6
138
138
  with:
139
139
  repository: bugsink/event-samples
140
140
  path: "event-samples"
@@ -169,17 +169,17 @@ jobs:
169
169
  # Build the Docker image, start it, wait for readiness, log in at /accounts/login/,
170
170
  # and verify that / redirects to /teams/.
171
171
  steps:
172
- - uses: actions/checkout@v4
172
+ - uses: actions/checkout@v6
173
173
 
174
174
  - name: Build Docker image
175
175
  run: docker build -t bugsink-ci .
176
176
 
177
- - name: Run container (admin:admin)
177
+ - name: Run container (no-reply@bugsink.com:admin)
178
178
  run: |
179
179
  docker rm -f bugsink-ci || true
180
180
  docker run -d --name bugsink-ci \
181
181
  -e SECRET_KEY=UtdHATKzQKLkz3izFFpxCKamhEdspeHmCQFvLx1DAwskqEuyKL \
182
- -e CREATE_SUPERUSER=admin:admin \
182
+ -e CREATE_SUPERUSER=no-reply@bugsink.com:admin \
183
183
  -e PORT=8000 \
184
184
  -p 8000:8000 \
185
185
  bugsink-ci
@@ -214,7 +214,7 @@ jobs:
214
214
  CODE=$(curl -sS -b cookies.txt -c cookies.txt \
215
215
  -H "Content-Type: application/x-www-form-urlencoded" \
216
216
  -H "Referer: http://localhost:8000/accounts/login/" \
217
- -d "username=admin&password=admin&csrfmiddlewaretoken=${CSRF}&next=/" \
217
+ -d "username=no-reply@bugsink.com&password=admin&csrfmiddlewaretoken=${CSRF}&next=/" \
218
218
  -o /dev/null -w "%{http_code}" \
219
219
  http://localhost:8000/accounts/login/)
220
220
 
@@ -236,3 +236,7 @@ jobs:
236
236
  fi
237
237
 
238
238
  echo "Login OK and / redirects to /teams/"
239
+
240
+ - name: Show Docker logs
241
+ if: always()
242
+ run: docker logs bugsink-ci || true
@@ -19,14 +19,14 @@ jobs:
19
19
  SAMPLES_DIR: ${{ github.workspace }}/event-samples
20
20
  steps:
21
21
  - name: Check out code
22
- uses: actions/checkout@v4
22
+ uses: actions/checkout@v6
23
23
 
24
24
  - name: Install project `pre-commit` hook
25
25
  run: |
26
26
  cp pre-commit .git/hooks/pre-commit
27
27
 
28
28
  - name: Set up Python 3.12
29
- uses: actions/setup-python@v5
29
+ uses: actions/setup-python@v6
30
30
  with:
31
31
  python-version: "3.12"
32
32
 
@@ -1,6 +1,24 @@
1
1
  # Changes
2
2
 
3
- ## 2.2.0 (19 May 2026)
3
+ ## 2.2.1 (22 May 2026)
4
+
5
+ ### API
6
+
7
+ * Add issue actions to the canonical API, see #214 and #401.
8
+ * Add canonical API issue comment creation, see #352 and #401.
9
+ * Accept issue friendly IDs in the canonical API, see #389 and #401.
10
+ * Improve OpenAPI endpoint docs, see #390 and #401.
11
+ * Use Bugsink's version as the OpenAPI spec version, see #307.
12
+
13
+ ### Smaller fixes
14
+
15
+ * Fix long module names overlapping version values on event detail pages, see #377 and #382.
16
+ * Validate `CREATE_SUPERUSER` email addresses and use the email as username in Docker server-start setup, see #394.
17
+ * Development server: do not send email by default, see d6d5190441b3.
18
+ * Docker: disable Gunicorn's unused control socket, see #405.
19
+ * Sourcemap uploads without a project slug now log server-side context before returning `400`, see #404 and #408.
20
+
21
+ ## 2.2.0 (21 May 2026)
4
22
 
5
23
  ### Security
6
24
 
@@ -26,6 +44,7 @@ https://github.com/bugsink/bugsink/security/advisories/GHSA-5389-f7vh-wxj8
26
44
 
27
45
  ### Smaller fixes
28
46
 
47
+ * Fix health-check `ALLOWED_HOSTS`-ignore, see #140, #397
29
48
  * Generate an `event_id` on `/store/` when the SDK does not send one, see #383.
30
49
  * Refresh issue title fields on every event digest, see #378.
31
50
  * Include ingest-dir cleanup in the `vacuum` command and warn about stale ingest-dir files, see 772fb1a9bff6 and
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bugsink
3
- Version: 2.2.0
3
+ Version: 2.2.1
4
4
  Summary: Self-hosted Error Tracking
5
5
  Author-email: "Bugsink B.V." <info@bugsink.com>
6
6
  Project-URL: homepage, https://www.bugsink.com/
@@ -2,6 +2,8 @@ import os
2
2
 
3
3
  from django.core.management.base import BaseCommand
4
4
  from django.contrib.auth import get_user_model
5
+ from django.core.exceptions import ValidationError
6
+ from django.core.validators import validate_email
5
7
 
6
8
  from phonehome.tasks import send_if_due
7
9
 
@@ -17,7 +19,7 @@ class Command(BaseCommand):
17
19
  return
18
20
 
19
21
  if ":" not in os.getenv("CREATE_SUPERUSER"):
20
- raise ValueError("CREATE_SUPERUSER should be in the format 'username:password'")
22
+ raise ValueError("CREATE_SUPERUSER should be in the format 'email:password'")
21
23
 
22
24
  username, password = os.getenv("CREATE_SUPERUSER").split(":", 1)
23
25
 
@@ -28,7 +30,14 @@ class Command(BaseCommand):
28
30
 
29
31
  return
30
32
 
31
- User.objects.create_superuser(username=username, password=password)
33
+ # Validate only when we're actually creating the user, so existing installations with a stale
34
+ # CREATE_SUPERUSER value keep starting normally.
35
+ try:
36
+ validate_email(username)
37
+ except ValidationError as e:
38
+ raise ValueError("CREATE_SUPERUSER email should be a valid email address") from e
39
+
40
+ User.objects.create_superuser(username=username, email=username, password=password)
32
41
  print(f"Superuser created: {username}")
33
42
 
34
43
  def handle(self, *args, **options):
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '2.2.0'
22
- __version_tuple__ = version_tuple = (2, 2, 0)
21
+ __version__ = version = '2.2.1'
22
+ __version_tuple__ = version_tuple = (2, 2, 1)
23
23
 
24
- __commit_id__ = commit_id = 'gdac28a708'
24
+ __commit_id__ = commit_id = 'gea814dc8e'
@@ -1,4 +1,5 @@
1
1
  # gunicorn config file for Docker deployments
2
2
  import multiprocessing
3
3
 
4
+ control_socket_disable = True
4
5
  workers = min(multiprocessing.cpu_count(), 4)
@@ -6,6 +6,9 @@ from pathlib import Path
6
6
 
7
7
  from django.utils.log import DEFAULT_LOGGING
8
8
 
9
+ from ..version import version as __version__
10
+
11
+
9
12
  # We have a single file for our default settings, and expect (if they use the singleserver setup) the end-users to
10
13
  # configure their setup using a single bugsink_conf.py also. To be able to have (slightly) different settings for e.g.
11
14
  # logging for various commands, we expose a variable I_AM_RUNNING that can be used to determine what command is being
@@ -90,7 +93,7 @@ REST_FRAMEWORK = {
90
93
  SPECTACULAR_SETTINGS = {
91
94
  'TITLE': 'Bugsink',
92
95
  'DESCRIPTION': 'Bugsink API Documentation',
93
- 'VERSION': '1.0.0',
96
+ 'VERSION': __version__,
94
97
  'SERVE_INCLUDE_SCHEMA': False, # keep the docs clean and not document the docs endpoint itself.
95
98
 
96
99
  "SECURITY": [
@@ -73,11 +73,12 @@ SNAPPEA = {
73
73
  "PID_FILE": "/tmp/bugsink/snappea.pid", # nosec B108
74
74
  }
75
75
 
76
- EMAIL_HOST = os.getenv("EMAIL_HOST")
77
- EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER")
78
- EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD")
79
- EMAIL_PORT = 587
80
- EMAIL_USE_TLS = True
76
+ EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
77
+ # EMAIL_HOST = os.getenv("EMAIL_HOST")
78
+ # EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER")
79
+ # EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD")
80
+ # EMAIL_PORT = 587
81
+ # EMAIL_USE_TLS = True
81
82
 
82
83
  SERVER_EMAIL = DEFAULT_FROM_EMAIL = 'Bugsink Development Server <bugsink@example.org>'
83
84
 
@@ -18,7 +18,7 @@ from files.views import chunk_upload, artifact_bundle_assemble, difs_assemble, a
18
18
  from bugsink.decorators import login_exempt
19
19
 
20
20
  from events.api_views import EventViewSet
21
- from issues.api_views import IssueViewSet
21
+ from issues.api_views import IssueCommentViewSet, IssueViewSet
22
22
  from projects.api_views import ProjectViewSet
23
23
  from releases.api_views import ReleaseViewSet
24
24
  from teams.api_views import TeamViewSet
@@ -34,6 +34,7 @@ admin.site.index_title = "Admin" # everyone calls this the "admin" anyway. Let'
34
34
 
35
35
  api_router = routers.DefaultRouter()
36
36
  api_router.register(r'events', EventViewSet)
37
+ api_router.register(r'issue-comments', IssueCommentViewSet, basename='issue-comment')
37
38
  api_router.register(r'issues', IssueViewSet)
38
39
  api_router.register(r'projects', ProjectViewSet)
39
40
  api_router.register(r'releases', ReleaseViewSet)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bugsink
3
- Version: 2.2.0
3
+ Version: 2.2.1
4
4
  Summary: Self-hosted Error Tracking
5
5
  Author-email: "Bugsink B.V." <info@bugsink.com>
6
6
  Project-URL: homepage, https://www.bugsink.com/
@@ -3,12 +3,13 @@ from rest_framework import viewsets
3
3
  from rest_framework.exceptions import ValidationError
4
4
  from rest_framework.decorators import action
5
5
  from rest_framework.response import Response
6
- from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiTypes, OpenApiResponse
6
+ from drf_spectacular.utils import extend_schema, OpenApiExample, OpenApiParameter, OpenApiTypes, OpenApiResponse
7
7
 
8
8
 
9
9
  from bugsink.utils import assert_
10
10
  from bugsink.api_pagination import AscDescCursorPagination
11
11
  from bugsink.api_mixins import AtomicRequestMixin
12
+ from issues.models import issue_lookup_kwargs
12
13
 
13
14
  from .models import Event
14
15
  from .serializers import EventListSerializer, EventDetailSerializer
@@ -26,12 +27,6 @@ class EventPagination(AscDescCursorPagination):
26
27
 
27
28
 
28
29
  class EventViewSet(AtomicRequestMixin, viewsets.ReadOnlyModelViewSet):
29
- """
30
- LIST requires: ?issue=<uuid>
31
- Optional: ?order=asc|desc (default: desc)
32
- LIST omits `data`, ordered by digest_order
33
- RETRIEVE includes `data` (pure PK lookup; no filters/order applied)
34
- """
35
30
  queryset = Event.objects.all() # router requirement for basename inference
36
31
  serializer_class = EventListSerializer
37
32
  pagination_class = EventPagination
@@ -42,16 +37,19 @@ class EventViewSet(AtomicRequestMixin, viewsets.ReadOnlyModelViewSet):
42
37
  if "issue" not in query_params:
43
38
  raise ValidationError({"issue": ["This field is required."]})
44
39
 
45
- return queryset.filter(issue=query_params["issue"])
40
+ lookup_kwargs = {"issue__" + k: v for k, v in issue_lookup_kwargs(query_params["issue"]).items()}
41
+ return queryset.filter(issue__is_deleted=False, **lookup_kwargs)
46
42
 
47
43
  @extend_schema(
44
+ summary="List events",
45
+ description="List events for an issue. The list response omits the full event `data` payload.",
48
46
  parameters=[
49
47
  OpenApiParameter(
50
48
  name="issue",
51
- type=OpenApiTypes.UUID,
49
+ type=OpenApiTypes.STR,
52
50
  location=OpenApiParameter.QUERY,
53
51
  required=True,
54
- description="Filter events by issue UUID (required).",
52
+ description="Filter events by issue UUID or friendly ID (required).",
55
53
  ),
56
54
  OpenApiParameter(
57
55
  name="order",
@@ -66,6 +64,17 @@ class EventViewSet(AtomicRequestMixin, viewsets.ReadOnlyModelViewSet):
66
64
  def list(self, request, *args, **kwargs):
67
65
  return super().list(request, *args, **kwargs)
68
66
 
67
+ @extend_schema(
68
+ summary="Retrieve an event",
69
+ description=(
70
+ "Retrieve an event by internal Bugsink event UUID. "
71
+ "The detail response includes the full `data` payload."
72
+ ),
73
+ responses=EventDetailSerializer,
74
+ )
75
+ def retrieve(self, request, *args, **kwargs):
76
+ return super().retrieve(request, *args, **kwargs)
77
+
69
78
  def get_object(self):
70
79
  """
71
80
  DRF's get_object(), but we intentionally bypass filter_queryset for detail routes to keep PK lookups
@@ -94,8 +103,21 @@ class EventViewSet(AtomicRequestMixin, viewsets.ReadOnlyModelViewSet):
94
103
  return EventDetailSerializer if self.action == "retrieve" else EventListSerializer
95
104
 
96
105
  @extend_schema(
106
+ summary="Render an event stacktrace",
97
107
  description="Render the event's stacktrace (frames, source, locals) as Markdown-like text.",
98
- responses={200: OpenApiResponse(response=str, description="Stacktrace as Markdown")},
108
+ responses={
109
+ 200: OpenApiResponse(
110
+ response=str,
111
+ description="Stacktrace as Markdown",
112
+ examples=[
113
+ OpenApiExample(
114
+ "Stacktrace",
115
+ value="Traceback (most rece...",
116
+ response_only=True,
117
+ ),
118
+ ],
119
+ )
120
+ },
99
121
  )
100
122
  @action(
101
123
  detail=True,
@@ -238,6 +238,7 @@ def artifact_bundle_assemble(request, organization_slug):
238
238
  chunk_checksums = data["chunks"]
239
239
  projects, error = get_artifact_bundle_projects(data)
240
240
  if error is not None:
241
+ logger.warning("Rejected artifact bundle: project slug is missing or does not match an existing project.")
241
242
  return JsonResponse({"error": error}, status=400)
242
243
 
243
244
  # sentry-cli >= 3.x calls this endpoint before uploading chunks (to learn which ones are missing), then uploads
@@ -0,0 +1,296 @@
1
+ from django.shortcuts import get_object_or_404
2
+ from rest_framework import mixins, status, viewsets
3
+ from rest_framework.decorators import action
4
+ from rest_framework.pagination import CursorPagination
5
+ from rest_framework.exceptions import ValidationError
6
+ from rest_framework.response import Response
7
+ from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiTypes
8
+
9
+ from bugsink.api_mixins import AtomicRequestMixin
10
+ from bugsink.utils import assert_
11
+
12
+ from .models import Issue, IssueStateManager, TurningPoint, apply_issue_action, issue_lookup_kwargs
13
+ from .serializers import (
14
+ IssueCommentSerializer,
15
+ IssueMuteForSerializer,
16
+ IssueMuteUntilSerializer,
17
+ IssueSerializer,
18
+ )
19
+
20
+
21
+ class IssuesCursorPagination(CursorPagination):
22
+ """
23
+ Cursor paginator for /issues supporting ?sort=… and ?order=asc|desc.
24
+
25
+ Sort modes are named after the *primary* column:
26
+ - sort=digest_order → unique per project → no tie-breakers needed
27
+ - sort=last_seen → timestamp → tie-breaker on id
28
+
29
+ Direction applies to primary *and beyond* (i.e. all fields in the list).
30
+ The view MUST filter by project; ordering is handled here.
31
+ """
32
+ # Cursor pagination requires an indexed, mostly-stable ordering. Stable mode: sort=digest_order (default). We
33
+ # require ?project=<uuid> and have a composite (project_id, digest_order) index, so ORDER BY digest_order after
34
+ # filtering by project is fast and cursor-stable.
35
+
36
+ # We also offer a "recent" mode: sort=last_seen. This is not stable, as new events can come in mid-cursor, and
37
+ # reshuffle things causing misses or duplicates. However, this is the desired UX for a "recent activity" view.
38
+ # i.e. the typical usage would in fact just be to get the "first page" of recent activity.
39
+ page_size = 250
40
+ default_direction = "asc"
41
+ default_sort = "digest_order"
42
+
43
+ VALID_SORTS = ("digest_order", "last_seen")
44
+ VALID_ORDERS = ("asc", "desc")
45
+
46
+ def get_ordering(self, request, queryset, view):
47
+ sort = request.query_params.get("sort", self.default_sort)
48
+ if sort not in self.VALID_SORTS:
49
+ raise ValidationError({"sort": ["Must be 'digest_order' or 'last_seen'."]})
50
+
51
+ order = request.query_params.get("order", self.default_direction)
52
+ if order not in self.VALID_ORDERS:
53
+ raise ValidationError({"order": ["Must be 'asc' or 'desc'."]})
54
+
55
+ desc = (order == "desc")
56
+
57
+ if sort == "digest_order":
58
+ # Unique per project; stable cursor once filtered by project.
59
+ return ["-digest_order" if desc else "digest_order"]
60
+
61
+ # sort == "last_seen": timestamp needs a deterministic tie-breaker.
62
+ if desc:
63
+ return ["-last_seen", "-id"]
64
+ return ["last_seen", "id"]
65
+
66
+
67
+ class IssueViewSet(AtomicRequestMixin, viewsets.ReadOnlyModelViewSet):
68
+ queryset = Issue.objects.filter(is_deleted=False).select_related("project") # hide soft-deleted; router basename
69
+ serializer_class = IssueSerializer
70
+ pagination_class = IssuesCursorPagination
71
+ http_method_names = ["get", "post", "delete", "head", "options"]
72
+
73
+ def get_queryset(self):
74
+ return self.queryset
75
+
76
+ @extend_schema(
77
+ summary="List issues",
78
+ description="List issues for a project.",
79
+ parameters=[
80
+ OpenApiParameter(
81
+ name="project",
82
+ type=OpenApiTypes.INT,
83
+ location=OpenApiParameter.QUERY,
84
+ required=True,
85
+ description="Filter issues by project id (required).",
86
+ ),
87
+ OpenApiParameter(
88
+ name="sort",
89
+ type=OpenApiTypes.STR,
90
+ location=OpenApiParameter.QUERY,
91
+ required=False,
92
+ enum=["digest_order", "last_seen"],
93
+ description="Sort mode (default: digest_order).",
94
+ ),
95
+ OpenApiParameter(
96
+ name="order",
97
+ type=OpenApiTypes.STR,
98
+ location=OpenApiParameter.QUERY,
99
+ required=False,
100
+ enum=["asc", "desc"],
101
+ description="Sort order (default: asc).",
102
+ ),
103
+ ]
104
+ )
105
+ def list(self, request, *args, **kwargs):
106
+ return super().list(request, *args, **kwargs)
107
+
108
+ @extend_schema(
109
+ summary="Retrieve an issue",
110
+ description="Retrieve an issue by issue UUID or friendly ID.",
111
+ responses=IssueSerializer,
112
+ )
113
+ def retrieve(self, request, *args, **kwargs):
114
+ return super().retrieve(request, *args, **kwargs)
115
+
116
+ @extend_schema(
117
+ summary="Delete an issue",
118
+ description="Delete an issue.",
119
+ )
120
+ def destroy(self, request, *args, **kwargs):
121
+ issue = self.get_object()
122
+ issue.delete_deferred()
123
+ return Response(status=status.HTTP_204_NO_CONTENT)
124
+
125
+ def filter_queryset(self, queryset):
126
+ queryset = super().filter_queryset(queryset)
127
+ if self.action != "list":
128
+ return queryset
129
+
130
+ project = self.request.query_params.get("project")
131
+ if not project:
132
+ # the below at least until we have a UI for cross-project Issue listing, i.e. #190
133
+ raise ValidationError({"project": ["This field is required."]})
134
+
135
+ return queryset.filter(project=project)
136
+
137
+ def get_object(self):
138
+ """
139
+ DRF's get_object(), but bypass filter_queryset for detail.
140
+ """
141
+ # NOTE: alternatively, we just complain hard when a filter is applied to a detail view.
142
+ # TODO: copy/paste from events/api_views.py
143
+ queryset = self.get_queryset()
144
+
145
+ lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
146
+ assert_(
147
+ lookup_url_kwarg in self.kwargs,
148
+ 'Expected view %s to be called with a URL keyword argument named "%s".'
149
+ % (self.__class__.__name__, lookup_url_kwarg)
150
+ )
151
+
152
+ obj = get_object_or_404(queryset, **issue_lookup_kwargs(self.kwargs[lookup_url_kwarg]))
153
+ self.check_object_permissions(self.request, obj)
154
+ return obj
155
+
156
+ def _action_response(self, issue):
157
+ issue.save()
158
+ return Response(self.get_serializer(issue).data)
159
+
160
+ def _assert_unresolved(self, issue):
161
+ if issue.is_resolved:
162
+ raise ValidationError({"detail": "Issue is already resolved."})
163
+
164
+ def _assert_unmuted(self, issue):
165
+ if issue.is_muted:
166
+ raise ValidationError({"detail": "Issue is already muted."})
167
+
168
+ def _apply_issue_action(self, issue, action):
169
+ # Bearer-token API auth currently represents a global token, not a user.
170
+ apply_issue_action(IssueStateManager, issue, action, user=None)
171
+ return self._action_response(issue)
172
+
173
+ @extend_schema(
174
+ summary="Resolve an issue",
175
+ description="Mark this issue as resolved.",
176
+ request=OpenApiTypes.NONE,
177
+ responses=IssueSerializer,
178
+ )
179
+ @action(detail=True, methods=["post"])
180
+ def resolve(self, request, pk=None):
181
+ issue = self.get_object()
182
+ self._assert_unresolved(issue)
183
+ return self._apply_issue_action(issue, "resolve")
184
+
185
+ @extend_schema(
186
+ summary="Resolve an issue in the next release",
187
+ description="Mark this issue as resolved by the next release.",
188
+ request=OpenApiTypes.NONE,
189
+ responses=IssueSerializer,
190
+ )
191
+ @action(detail=True, methods=["post"], url_path="resolve-next")
192
+ def resolve_next(self, request, pk=None):
193
+ issue = self.get_object()
194
+ self._assert_unresolved(issue)
195
+ return self._apply_issue_action(issue, "resolved_next")
196
+
197
+ @extend_schema(
198
+ summary="Resolve an issue in the latest release",
199
+ description="Mark this issue as resolved in the latest release.",
200
+ request=OpenApiTypes.NONE,
201
+ responses=IssueSerializer,
202
+ )
203
+ @action(detail=True, methods=["post"], url_path="resolve-latest")
204
+ def resolve_latest(self, request, pk=None):
205
+ issue = self.get_object()
206
+ self._assert_unresolved(issue)
207
+ if not issue.project.has_releases:
208
+ raise ValidationError({"detail": "Project has no releases."})
209
+
210
+ latest_release = issue.project.get_latest_release()
211
+ if latest_release.version + "\n" in issue.events_at:
212
+ raise ValidationError({"detail": "Issue has already occurred in the latest release."})
213
+
214
+ return self._apply_issue_action(issue, "resolved_release:" + latest_release.version)
215
+
216
+ @extend_schema(
217
+ summary="Mute an issue",
218
+ description="Mute this issue.",
219
+ request=OpenApiTypes.NONE,
220
+ responses=IssueSerializer,
221
+ )
222
+ @action(detail=True, methods=["post"])
223
+ def mute(self, request, pk=None):
224
+ issue = self.get_object()
225
+ self._assert_unresolved(issue)
226
+ self._assert_unmuted(issue)
227
+ return self._apply_issue_action(issue, "mute")
228
+
229
+ @extend_schema(
230
+ summary="Mute an issue for a period",
231
+ description="Mute this issue for a relative period, e.g. for 3 days.",
232
+ request=IssueMuteForSerializer,
233
+ responses=IssueSerializer,
234
+ )
235
+ @action(detail=True, methods=["post"], url_path="mute-for")
236
+ def mute_for(self, request, pk=None):
237
+ serializer = IssueMuteForSerializer(data=request.data)
238
+ serializer.is_valid(raise_exception=True)
239
+ period_name = serializer.validated_data["period_name"]
240
+ nr_of_periods = serializer.validated_data["nr_of_periods"]
241
+
242
+ issue = self.get_object()
243
+ self._assert_unresolved(issue)
244
+ self._assert_unmuted(issue)
245
+ return self._apply_issue_action(issue, f"mute_for:{period_name},{nr_of_periods},")
246
+
247
+ @extend_schema(
248
+ summary="Mute an issue until a threshold is reached",
249
+ description="Mute this issue until a threshold is reached, e.g. more than 10 events in 1 hour.",
250
+ request=IssueMuteUntilSerializer,
251
+ responses=IssueSerializer,
252
+ )
253
+ @action(detail=True, methods=["post"], url_path="mute-until")
254
+ def mute_until(self, request, pk=None):
255
+ serializer = IssueMuteUntilSerializer(data=request.data)
256
+ serializer.is_valid(raise_exception=True)
257
+ period_name = serializer.validated_data["period_name"]
258
+ nr_of_periods = serializer.validated_data["nr_of_periods"]
259
+ gte_threshold = serializer.validated_data["gte_threshold"]
260
+
261
+ issue = self.get_object()
262
+ self._assert_unresolved(issue)
263
+ self._assert_unmuted(issue)
264
+ return self._apply_issue_action(issue, f"mute_until:{period_name},{nr_of_periods},{gte_threshold}")
265
+
266
+ @extend_schema(
267
+ summary="Unmute an issue",
268
+ description="Unmute this issue.",
269
+ request=OpenApiTypes.NONE,
270
+ responses=IssueSerializer,
271
+ )
272
+ @action(detail=True, methods=["post"])
273
+ def unmute(self, request, pk=None):
274
+ issue = self.get_object()
275
+ self._assert_unresolved(issue)
276
+ if not issue.is_muted:
277
+ raise ValidationError({"detail": "Issue is not muted."})
278
+
279
+ return self._apply_issue_action(issue, "unmute")
280
+
281
+ # NOTE: No 'unresolve' action: reopen is intentionally not exposed in the UI either. See apply_issue_action.
282
+
283
+
284
+ class IssueCommentViewSet(AtomicRequestMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):
285
+ queryset = TurningPoint.objects.none() # router basename only
286
+ serializer_class = IssueCommentSerializer
287
+ http_method_names = ["post", "head", "options"]
288
+
289
+ @extend_schema(
290
+ summary="Create an issue comment",
291
+ description="Add a comment to an issue. `issue` accepts an issue UUID or friendly ID.",
292
+ request=IssueCommentSerializer,
293
+ responses=IssueCommentSerializer,
294
+ )
295
+ def create(self, request, *args, **kwargs):
296
+ return super().create(request, *args, **kwargs)