Skip to content

ref(preprod): Drop hash-keyed manifest fallback#113967

Merged
NicoHinderling merged 3 commits intomasterfrom
04-24-ref_preprod_remove_hash_keyed_manifest_fallback
Apr 24, 2026
Merged

ref(preprod): Drop hash-keyed manifest fallback#113967
NicoHinderling merged 3 commits intomasterfrom
04-24-ref_preprod_remove_hash_keyed_manifest_fallback

Conversation

@NicoHinderling
Copy link
Copy Markdown
Contributor

@NicoHinderling NicoHinderling commented Apr 24, 2026

Resolves the EME-977 TODO: drop the backwards-compat fallback for snapshot manifests that pre-date the content_hash field.

ImageMetadata.content_hash becomes required (str). Manifests from old SDK versions omitted it and relied on a content_hash or key fallback at every read site; all callers now assume the hash is present.

Drops the fallback and the EME-977 TODO at three sites:

  • preprod_artifact_snapshot.py — GET response construction.
  • tasks.pyhead_by_name / base_by_name for diff matching.
  • tasks.pyhead_meta_by_hash / base_meta_by_hash for rename detection.

No behavior change for any manifest uploaded by a modern client. If a legacy manifest without content_hash is still reachable, snapshot parsing will now raise a pydantic validation error instead of silently keying on the file name.

@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Apr 24, 2026
@NicoHinderling NicoHinderling marked this pull request as ready for review April 24, 2026 18:18
@NicoHinderling NicoHinderling requested a review from a team as a code owner April 24, 2026 18:18
Comment thread src/sentry/preprod/api/models/snapshots/project_preprod_snapshot_models.py Outdated
@github-actions
Copy link
Copy Markdown
Contributor

Backend Test Failures

Failures on 4db2eda in this run:

tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_all_image_file_names_must_contain_all_imageslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:287: in test_all_image_file_names_must_contain_all_images
    assert "all_image_file_names" in response.data["detail"]
E   AssertionError: assert 'all_image_file_names' in 'The images field is required and must be an object mapping image names to image metadata.'
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_all_image_file_names_requires_selectivelog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:292: in test_all_image_file_names_requires_selective
    assert "selective" in response.data["detail"]
E   AssertionError: assert 'selective' in 'The images field is required and must be an object mapping image names to image metadata.'
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_base_upload_triggers_comparison_for_waiting_headlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:365: in test_base_upload_triggers_comparison_for_waiting_head
    assert response.status_code == 200
E   assert 400 == 200
E    +  where 400 = <Response status_code=400, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_selective_with_all_image_file_names_acceptedlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:303: in test_selective_with_all_image_file_names_accepted
    assert response.status_code == 200
E   assert 400 == 200
E    +  where 400 = <Response status_code=400, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_selective_without_all_image_file_names_acceptedlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:299: in test_selective_without_all_image_file_names_accepted
    assert response.status_code == 200
E   assert 400 == 200
E    +  where 400 = <Response status_code=400, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_snapshot_upload_creates_commit_comparisonlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:87: in test_snapshot_upload_creates_commit_comparison
    assert response.status_code == 200
E   assert 400 == 200
E    +  where 400 = <Response status_code=400, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_snapshot_upload_stores_manifest_keylog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:116: in test_snapshot_upload_stores_manifest_key
    assert response.status_code == 200
E   assert 400 == 200
E    +  where 400 = <Response status_code=400, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_successful_snapshot_uploadlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:49: in test_successful_snapshot_upload
    assert response.status_code == 200
E   assert 400 == 200
E    +  where 400 = <Response status_code=400, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotGetTest::test_get_snapshot_detailslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:450: in test_get_snapshot_details
    assert response.status_code == 200
E   assert 500 == 200
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotGetTest::test_get_snapshot_details_returns_all_imageslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:507: in test_get_snapshot_details_returns_all_images
    assert response.status_code == 200
E   assert 500 == 200
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotGetTest::test_get_snapshot_details_with_vcs_infolog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:480: in test_get_snapshot_details_with_vcs_info
    assert response.status_code == 200
E   assert 500 == 200
E    +  where 500 = <Response status_code=500, "application/json">.status_code

@NicoHinderling NicoHinderling changed the title ref(preprod): Drop hash-keyed manifest fallback and require app_id ref(preprod): Drop hash-keyed manifest fallback Apr 24, 2026
@NicoHinderling NicoHinderling force-pushed the 04-24-ref_preprod_remove_hash_keyed_manifest_fallback branch from 557c30d to de8d0a4 Compare April 24, 2026 18:36
@github-actions
Copy link
Copy Markdown
Contributor

Backend Test Failures

Failures on 273eedd in this run:

tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_all_image_file_names_must_contain_all_imageslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:287: in test_all_image_file_names_must_contain_all_images
    assert "all_image_file_names" in response.data["detail"]
E   AssertionError: assert 'all_image_file_names' in 'The images field is required and must be an object mapping image names to image metadata.'
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_all_image_file_names_requires_selectivelog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:292: in test_all_image_file_names_requires_selective
    assert "selective" in response.data["detail"]
E   AssertionError: assert 'selective' in 'The images field is required and must be an object mapping image names to image metadata.'
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_base_upload_triggers_comparison_for_waiting_headlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:365: in test_base_upload_triggers_comparison_for_waiting_head
    assert response.status_code == 200
E   assert 400 == 200
E    +  where 400 = <Response status_code=400, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_selective_with_all_image_file_names_acceptedlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:303: in test_selective_with_all_image_file_names_accepted
    assert response.status_code == 200
E   assert 400 == 200
E    +  where 400 = <Response status_code=400, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_selective_without_all_image_file_names_acceptedlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:299: in test_selective_without_all_image_file_names_accepted
    assert response.status_code == 200
E   assert 400 == 200
E    +  where 400 = <Response status_code=400, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_snapshot_upload_creates_commit_comparisonlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:87: in test_snapshot_upload_creates_commit_comparison
    assert response.status_code == 200
E   assert 400 == 200
E    +  where 400 = <Response status_code=400, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_snapshot_upload_stores_manifest_keylog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:116: in test_snapshot_upload_stores_manifest_key
    assert response.status_code == 200
E   assert 400 == 200
E    +  where 400 = <Response status_code=400, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotTest::test_successful_snapshot_uploadlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:49: in test_successful_snapshot_upload
    assert response.status_code == 200
E   assert 400 == 200
E    +  where 400 = <Response status_code=400, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotGetTest::test_get_snapshot_detailslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:450: in test_get_snapshot_details
    assert response.status_code == 200
E   assert 500 == 200
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotGetTest::test_get_snapshot_details_returns_all_imageslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:507: in test_get_snapshot_details_returns_all_images
    assert response.status_code == 200
E   assert 500 == 200
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py::ProjectPreprodSnapshotGetTest::test_get_snapshot_details_with_vcs_infolog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/preprod/api/endpoints/test_preprod_artifact_snapshot.py:480: in test_get_snapshot_details_with_vcs_info
    assert response.status_code == 200
E   assert 500 == 200
E    +  where 500 = <Response status_code=500, "application/json">.status_code

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit da81756. Configure here.

Comment thread src/sentry/preprod/snapshots/manifest.py
@NicoHinderling NicoHinderling merged commit 66d5562 into master Apr 24, 2026
57 checks passed
@NicoHinderling NicoHinderling deleted the 04-24-ref_preprod_remove_hash_keyed_manifest_fallback branch April 24, 2026 19:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants