fix: handle 409 DUPLICATE_ARTIFACT as success in release tagging#117
fix: handle 409 DUPLICATE_ARTIFACT as success in release tagging#117vpetersson merged 5 commits intomasterfrom
Conversation
When tagging an SBOM with a release, the API may return 409 Conflict with DUPLICATE_ARTIFACT if the SBOM is already tagged. This can happen when: - Server auto-tags SBOM with "latest release" on upload - Another CI job tagged the same SBOM concurrently - User tagged via UI while CI was running Treat this as idempotent success since the desired state (SBOM tagged with release) is already achieved. Companion to server-side fix that returns 409 instead of 403 for duplicate artifacts.
There was a problem hiding this comment.
Pull request overview
This PR modifies the SBOM release tagging functionality to treat HTTP 409 Conflict responses with DUPLICATE_ARTIFACT error codes as idempotent successes rather than failures. This handles scenarios where an SBOM has already been tagged with a release through server auto-tagging, concurrent CI jobs, or manual UI operations.
Changes:
- Modified
tag_sbom_with_releaseto check for 409 status withDUPLICATE_ARTIFACTerror code and return successfully - Added test coverage for the new idempotent behavior with duplicate artifacts
- Added test to verify other 409 errors still raise exceptions appropriately
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| sbomify_action/_processors/releases_api.py | Added logic to detect and handle 409 DUPLICATE_ARTIFACT responses as successful operations |
| tests/test_releases.py | Added two test cases covering the idempotent success case and ensuring other 409 errors still fail |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Replace (ValueError, KeyError) with (ValueError, TypeError, AttributeError) throughout releases_api.py: - ValueError: response.json() parsing failure - TypeError: 'in' operator on None/non-container types - AttributeError: .get() called on non-dict objects KeyError was never actually raised because: - .get() returns None instead of raising KeyError - [] indexing is always guarded by 'if key in dict' checks Addresses PR #117 feedback from Copilot code review.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Replace broad exception handling with a _safe_json_dict() helper that: - Catches only ValueError for JSON parsing failures - Uses isinstance(data, dict) to verify response type - Returns None for invalid responses, enabling clean conditionals This is more explicit and won't accidentally hide programming bugs, while still gracefully handling malformed API responses. Addresses all PR #117 feedback from Copilot code review.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Use early returns in _fetch_releases for cleaner control flow - Remove unnecessary intermediate variable in response.text handling
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Add note to _safe_json_dict docstring explaining ValueError catches JSONDecodeError - Rename test to 'succeeds' instead of 'returns_success' for accuracy
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
When tagging an SBOM with a release, the API may return 409 Conflict with DUPLICATE_ARTIFACT if the SBOM is already tagged. This can happen when:
Treat this as idempotent success since the desired state (SBOM tagged with release) is already achieved.
Companion to server-side fix that returns 409 instead of 403 for duplicate artifacts.