• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kobotoolbox / kpi / 24841258195
82%
master: 76%

Build:
Build:
LAST BUILD BRANCH: main
DEFAULT BRANCH: master
Ran 23 Apr 2026 02:45PM UTC
Jobs 10
Files 912
Run time 3min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

23 Apr 2026 02:35PM UTC coverage: 81.17% (-1.0%) from 82.12%
24841258195

push

github

web-flow
fix(user_reports): drop and recreate materialized view around djstripe migrations DEV-2015 (#6960)

### 👷 Description for instance maintainers
This PR resolves a migration failure caused by the
`user_reports_userreportsmv` materialized view, which depends on columns
altered by djstripe 2.9 migrations (notably `djstripe_price.type` and
`djstripe_product.type` in `djstripe.0013_2_9`).

Without this fix, `djstripe.0013_2_9` fails with:
`cannot alter type of a column used by a view or rule`


### Notes 

**Race-condition safeguards during DROP**
The Celery task `refresh_user_report_snapshots` periodically runs
`REFRESH MATERIALIZED VIEW CONCURRENTLY`, which would block the `DROP`.
The migration now:

1. Acquires the Redis lock `billing_and_usage_snapshot:run_lock`
(blocking, 5s timeout) to prevent new task runs.
2. If the lock is already held, calls `pg_terminate_backend()` on any
backend refreshing the MV or holding a lock on it. The terminated Celery
task then releases the Redis lock through its own `finally` block. The
MV is about to be dropped, so losing an in-flight refresh is harmless.
3. Sets a PostgreSQL `lock_timeout = '30s'` as a belt-and-braces safety
net before issuing the `DROP`.

### 👀 Preview steps

1. â„šī¸ Have Stripe enabled and an account with a paid subscription plan.
2. Verify `/api/v2/user_reports/` lists users with their Stripe plans.
3. Roll djstripe back: `./manage.py migrate djstripe 0012_2_8`.
4. 🔴 [on `release/2.026.12`] Re-running migrations fails on
`djstripe.0013_2_9` with the materialized view dependency error.
5. Check out this PR branch and run `./manage.py migrate` 🎉.
6. đŸŸĸ The `user_reports` migration drops the MV before djstripe runs, and
djstripe migrations complete successfully.
7. The LRM runner (Celery Beat task `execute_long_running_migrations`)
runs every 15 minutes on the quarter hour and will recreate the MV in
the background. To force it immediately, call
`kobo.apps.long_running_migrations.tasks.execute_long_runni... (continued)

7643 of 11973 branches covered (63.84%)

0 of 9 new or added lines in 1 file covered. (0.0%)

1718 existing lines in 82 files now uncovered.

29248 of 36033 relevant lines covered (81.17%)

5.78 hits per line

Uncovered Changes

Lines Coverage ∆ File
9
0.0
-100.0% kobo/conftest.py

Coverage Regressions

Lines Coverage ∆ File
209
31.18
-58.71% kpi/serializers/v2/asset_permission_assignment.py
167
46.79
-27.51% kpi/deployment_backends/openrosa_backend.py
133
70.66
-23.09% kpi/serializers/v2/asset.py
85
59.93
-28.62% kpi/views/v2/data.py
66
31.62
-56.41% kpi/serializers/v2/export_task.py
66
26.85
-61.11% kpi/serializers/v2/paired_data.py
65
69.75
-18.21% kpi/views/v2/asset.py
63
34.55
-57.27% kpi/views/v2/paired_data.py
46
70.97
-11.41% kpi/deployment_backends/base_backend.py
46
50.7
-21.4% kpi/renderers.py
43
41.18
-50.59% kpi/views/environment.py
40
55.49
-23.12% kpi/serializers/current_user.py
33
66.4
-26.4% kpi/models/paired_data.py
32
50.75
-47.76% kpi/views/v2/asset_export_settings.py
29
63.16
-30.53% kpi/views/v2/asset_permission_assignment.py
27
45.16
-43.55% kpi/views/v2/attachment.py
26
27.5
-65.0% kpi/serializers/v2/attachment_delete.py
26
55.56
-19.26% kpi/views/v2/asset_snapshot.py
25
31.11
-55.56% kpi/serializers/v2/data.py
25
74.76
-24.27% kpi/utils/usage_calculator.py
24
71.43
-28.57% kpi/serializers/v2/service_usage.py
23
62.82
-29.49% kpi/authentication.py
23
81.18
-3.87% kpi/models/import_export_task.py
23
40.48
-54.76% kpi/serializers/v2/deployment.py
21
38.33
-35.0% kpi/serializers/v2/asset_export_settings.py
20
85.25
-9.22% kpi/utils/xml.py
19
57.36
-14.73% kobo/apps/trash_bin/utils/trash.py
19
38.24
-55.88% kpi/parsers.py
19
33.33
-63.33% kpi/utils/paired_data.py
19
51.06
-40.43% kpi/views/v2/import_task.py
18
87.79
-8.45% kpi/permissions.py
18
66.04
-33.96% kpi/views/v2/export_task.py
17
42.5
-42.5% kpi/views/__init__.py
13
40.0
-43.33% kpi/serializers/v2/asset_counts.py
11
70.18
-19.3% kpi/utils/mailer.py
10
44.0
-40.0% kobo/apps/stripe/signals.py
10
33.33
-37.04% kpi/mixins/audio_transcoding.py
9
47.73
-20.45% kobo/apps/trash_bin/models/attachment.py
9
77.07
-4.39% kpi/utils/mongo_helper.py
8
58.51
-8.51% kobo/apps/stripe/utils/billing_dates.py
7
75.0
-25.0% kobo/apps/subsequences/utils/supplement_data.py
7
87.14
-10.0% kpi/utils/cache.py
7
74.07
-25.93% kpi/views/v2/attachment_delete.py
7
75.86
-24.14% kpi/views/v2/tag.py
6
0.0
-100.0% kobo/conftest.py
6
80.0
-20.0% kpi/serializers/v2/tag.py
6
76.47
-17.65% kpi/utils/rename_xls_sheet.py
6
64.29
-14.29% kpi/utils/urls.py
5
76.47
-4.2% kobo/apps/stripe/utils/subscription_limits.py
5
76.0
-20.0% kpi/views/v2/asset_counts.py
5
61.54
-38.46% kpi/views/v2/logout.py
4
80.95
-19.05% kobo/apps/trash_bin/utils/signals.py
4
95.1
-3.92% kpi/models/asset_file.py
4
92.35
-0.73% kpi/models/asset.py
4
85.34
-3.45% kpi/models/asset_snapshot.py
4
87.62
-3.81% kpi/utils/object_permission.py
4
20.0
-80.0% kpi/utils/placeholders.py
3
78.57
-10.71% kpi/utils/submission.py
3
30.67
-4.0% kpi/utils/two_database_configuration_checker.py
3
86.67
-10.0% kpi/views/v2/asset_version.py
3
75.0
-25.0% kpi/views/v2/open_rosa.py
2
82.14
-7.14% kobo/urls.py
2
85.71
-9.52% kpi/fields/writable_json.py
2
80.0
-20.0% kpi/mixins/mfa.py
2
94.43
-0.56% kpi/mixins/object_permission.py
2
96.3
-3.7% kpi/mixins/xls_exportable.py
2
80.17
-1.72% kpi/paginators.py
2
92.73
-3.64% kpi/signals.py
2
42.17
-2.41% kpi/utils/storage.py
2
88.24
-11.76% kpi/views/v2/service_usage.py
1
93.02
-2.33% kpi/backends.py
1
96.67
-3.33% kpi/fields/kpi_uid.py
1
82.61
-4.35% kpi/fields/relative_prefix_hyperlinked_related.py
1
75.0
-8.33% kpi/mixins/validation_password_permission.py
1
62.5
-12.5% kpi/utils/datetime.py
1
93.94
-1.01% kpi/utils/django_orm_helper.py
1
81.25
-6.25% kpi/utils/drf_exceptions.py
1
50.0
-50.0% kpi/utils/export_task.py
1
78.57
-0.89% kpi/utils/models.py
1
92.31
-7.69% kpi/versioning.py
1
90.0
-2.5% kpi/views/v1/import_task.py
1
93.33
-6.67% kpi/views/v2/asset_usage.py
Jobs
ID Job ID Ran Files Coverage
1 24841258195.1 23 Apr 2026 02:45PM UTC 908
52.72
2 24841258195.2 23 Apr 2026 02:46PM UTC 908
54.25
3 24841258195.3 23 Apr 2026 02:46PM UTC 910
53.94
4 24841258195.4 23 Apr 2026 02:47PM UTC 908
52.96
5 24841258195.5 23 Apr 2026 02:47PM UTC 910
55.5
6 24841258195.6 23 Apr 2026 02:47PM UTC 910
65.96
7 24841258195.7 23 Apr 2026 02:47PM UTC 908
60.26
8 24841258195.8 23 Apr 2026 02:49PM UTC 910
61.38
9 24841258195.9 23 Apr 2026 02:49PM UTC 910
54.3
10 24841258195.10 23 Apr 2026 02:50PM UTC 912
68.19
Source Files on build 24841258195
  • Tree
  • List 912
  • Changed 22
  • Source Changed 0
  • Coverage Changed 22
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • d87feb8f on github
  • Prev Build on release/2.026.12 (#24837117774)
  • Next Build on release/2.026.12 (#24983934715)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc