Commit 22facfb
committed
fix(gitlab): preserve user-added labels in publish_labels and get_pr_labels
PRReviewer.set_review_labels and similar callers do a read-modify-write
cycle on MR labels (read existing via get_pr_labels(update=True), filter
out our managed labels, add review-effort/security labels, write back via
publish_labels) specifically to preserve user-added labels. On the GitLab
provider both halves of that cycle were buggy, so any label a user added
after the webhook fired would be wiped on every /review.
Issue 1: GitLabProvider.get_pr_labels(update=False) ignored the update
flag and returned self.mr.labels from the snapshot cached at provider
construction. Callers requesting a fresh read silently got stale data,
so user-added labels were missing from current_labels and excluded from
the write.
Issue 2: GitLabProvider.publish_labels did:
self.mr.labels = list(set(pr_types))
self.mr.save()
which issues a full PUT on the labels array against that same stale
snapshot. Any concurrent addition during the read-modify-write window
is silently dropped.
This change fixes both halves:
- get_pr_labels(update=True) now actually refreshes via
self._get_merge_request() before reading. update=False keeps the
cached read so the hot path is unchanged. Refresh failure propagates
to the caller so a stale snapshot cannot corrupt the
read-modify-write cycle (see PRDescription change below).
- publish_labels refreshes the MR immediately before computing the
delta, then uses python-gitlab's add_labels / remove_labels
attributes (forwarded by python-gitlab to identically-named API
parameters on PUT /projects/:id/merge_requests/:merge_request_iid)
on save(). The server now applies an incremental set-diff, so
concurrent additions outside the diff are preserved.
- save() is wrapped in try/finally; both add_labels and remove_labels
are delattr'd in the finally block so a later self.mr.save() on the
same provider instance (e.g. publish_description) cannot resend the
prior label diff. Cleanup runs on save() failure too.
- publish_labels aborts on refresh failure (logs and returns without
calling save()) so we never publish from a stale snapshot.
- The refresh-failure warning logs only the exception type, not the
raw exception object. HTTP/SDK client errors can carry credentialed
URLs or headers in their message; logs are a security boundary.
PRDescription.run now isolates label-update failures: the label
refresh/publish block is wrapped in an inline try/except so that a
transient GitLab API error during get_pr_labels(update=True) (or a
publish_labels failure) does not abort the surrounding description
publish. Without this wrapper, the outer try/except in run() is wide
enough that a label-step exception would skip the description publish
too. PRReviewer.set_review_labels already wraps its
get_pr_labels(update=True) call in a try/except, so no change is
needed there. Other providers' get_pr_labels methods swallow
exceptions and return [], which is why callers were not previously
structured to expect exceptions here.
Tests:
New tests in tests/unittest/test_gitlab_provider.py cover:
- publish_labels: noop when sets are equal, add-only diff, remove-only
diff, user labels outside the diff are not touched, abort on refresh
failure (and the warning log redacts the exception body), diff-attr
cleanup on save() failure.
- get_pr_labels: no-update returns cached, update refreshes, update
propagates refresh failure.
New tests in tests/unittest/test_pr_description.py cover the
description publish flow remaining intact when:
- get_pr_labels(update=True) raises.
- publish_labels raises.
PYTHONPATH=. ./.venv/bin/pytest tests/unittest -q
1052 passed
Signed-off-by: Allen Shearin <allen.p.shearin@gmail.com>1 parent bd09b6c commit 22facfb
4 files changed
Lines changed: 408 additions & 12 deletions
File tree
- pr_agent
- git_providers
- tools
- tests/unittest
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
886 | 886 | | |
887 | 887 | | |
888 | 888 | | |
889 | | - | |
890 | | - | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
| 892 | + | |
| 893 | + | |
| 894 | + | |
| 895 | + | |
| 896 | + | |
| 897 | + | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
| 913 | + | |
| 914 | + | |
| 915 | + | |
| 916 | + | |
| 917 | + | |
| 918 | + | |
| 919 | + | |
| 920 | + | |
| 921 | + | |
| 922 | + | |
| 923 | + | |
| 924 | + | |
| 925 | + | |
| 926 | + | |
| 927 | + | |
| 928 | + | |
| 929 | + | |
| 930 | + | |
| 931 | + | |
| 932 | + | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
| 936 | + | |
| 937 | + | |
| 938 | + | |
| 939 | + | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
| 945 | + | |
| 946 | + | |
891 | 947 | | |
892 | 948 | | |
893 | 949 | | |
894 | 950 | | |
895 | 951 | | |
896 | 952 | | |
897 | 953 | | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
| 960 | + | |
| 961 | + | |
| 962 | + | |
| 963 | + | |
| 964 | + | |
| 965 | + | |
| 966 | + | |
| 967 | + | |
| 968 | + | |
898 | 969 | | |
899 | 970 | | |
900 | 971 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
157 | 157 | | |
158 | 158 | | |
159 | 159 | | |
160 | | - | |
161 | | - | |
162 | | - | |
163 | | - | |
164 | | - | |
165 | | - | |
166 | | - | |
167 | | - | |
168 | | - | |
169 | | - | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
170 | 183 | | |
171 | 184 | | |
172 | 185 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
255 | 255 | | |
256 | 256 | | |
257 | 257 | | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
0 commit comments