)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"494c90ec6d0a500ca8a2fbfb828f41abda39428f","unresolved":true,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":"[1] https://review.opendev.org/c/openstack/watcher/+/955753"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Depends-On: https://review.opendev.org/c/openstack/requirements/+/959051"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Change-Id: Ice3e01c214a8ce78553fe8ebc6ca9f43ffd3f273"},{"line_number":21,"context_line":"Signed-off-by: Alfredo Moralejo \u003camoralej@redhat.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":13,"id":"c7b844eb_ec2caa04","line":18,"range":{"start_line":18,"start_character":12,"end_line":18,"end_character":72},"updated":"2025-09-02 10:54:11.000000000","message":"https://review.opendev.org/c/openstack/requirements/+/959051 is merged now.","commit_id":"1d75e29fc37baac5e6fea1ce4e896991c8a6dd77"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ca56d701388ca74db085f2efbcb838c9b0e0b780","unresolved":false,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":"[1] https://review.opendev.org/c/openstack/watcher/+/955753"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Depends-On: https://review.opendev.org/c/openstack/requirements/+/959051"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Change-Id: Ice3e01c214a8ce78553fe8ebc6ca9f43ffd3f273"},{"line_number":21,"context_line":"Signed-off-by: Alfredo Moralejo \u003camoralej@redhat.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":13,"id":"028657bb_ae5da001","line":18,"range":{"start_line":18,"start_character":12,"end_line":18,"end_character":72},"in_reply_to":"c7b844eb_ec2caa04","updated":"2025-11-26 05:46:11.000000000","message":"Done","commit_id":"1d75e29fc37baac5e6fea1ce4e896991c8a6dd77"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"72a2089ade5b16ecb858dfe4a819221f7257eeac","unresolved":true,"context_lines":[{"line_number":22,"context_line":"  when the parent action plan has SUCCEEDED"},{"line_number":23,"context_line":"- Gracefully degrade UI when older Watcher API versions are detected"},{"line_number":24,"context_line":"  (hides Actions column and skip controls for API \u003c 1.5)"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"Technical improvements:"},{"line_number":27,"context_line":"- Refactor client helper module renaming \u0027wv\u0027 to \u0027common_client\u0027 for"},{"line_number":28,"context_line":"  clarity and consistency"},{"line_number":29,"context_line":"- Add get_server_microversion_range() to get microversion"},{"line_number":30,"context_line":"- Add is_supported() helper using watcherclient\u0027s api_versioning"},{"line_number":31,"context_line":"  APIVersion for microversion capability checking"},{"line_number":32,"context_line":"- Add WatcherDashboardException typed exception in common/exceptions.py,"},{"line_number":33,"context_line":"  replacing generic ValueError in Action.update()"},{"line_number":34,"context_line":"- Catch wc_exc.MethodNotAllowed specifically in Action.update() instead"},{"line_number":35,"context_line":"  of broad except Exception for graceful degradation on HTTP 405"},{"line_number":36,"context_line":"- Replace request-object mutation pattern in action_plans DetailView"},{"line_number":37,"context_line":"  with a detail_action_plan property and explicit kwargs to"},{"line_number":38,"context_line":"  RelatedActionsTable via get_tables()"},{"line_number":39,"context_line":"- Add get_strategy_display_name() shared helper in api/watcher.py"},{"line_number":40,"context_line":"  using strategy.to_dict() to access display_name (not exposed in"},{"line_number":41,"context_line":"  watcherclient Strategy resource fields)"},{"line_number":42,"context_line":"- Add get_strategies_for_goal() AJAX endpoint in audit_templates for"},{"line_number":43,"context_line":"  dynamic strategy filtering by goal"},{"line_number":44,"context_line":"- Refactor audit template CreateForm: remove unnecessary try/except"},{"line_number":45,"context_line":"  AttributeError around self.data (never None on Django forms),"},{"line_number":46,"context_line":"  dynamically populate strategy choices on POST"},{"line_number":47,"context_line":"- Update python-watcherclient requirement to \u003e\u003d4.9.0"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"Testing:"},{"line_number":50,"context_line":"- Add unit tests for Action.update(), microversion"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":44,"id":"fa1d4177_53b6e1f9","line":47,"range":{"start_line":25,"start_character":1,"end_line":47,"end_character":52},"updated":"2026-02-26 20:02:33.000000000","message":"honestly looking at this again you have tried to do far to much in one commit\n\ni woudl expect at least 5 commite for this\n\n- the microversion fucntionlatiy shoudl be its own commeit with the watcher client version bump.\n\n- \"Refactor client helper module renaming \u0027wv\u0027 to \u0027common_client\u0027 for\n  clarity and consistency\" shoudl be its own commit\n  \n-  Add get_strategies_for_goal() AJAX endpoint in audit_templates for\n  dynamic strategy filtering by goal should be its own commit.\n  \n- Refactor audit template CreateForm: remove unnecessary try/except\n  AttributeError around self.data (never None on Django forms),\n  dynamically populate strategy choices on POST\n- and finally after those 4 enableign comits you shoudl implemnt the skip ui change.\n\ni think you shoudl proably do that breakdown because it very hard to review this as it is","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"71f3046d41eea82d04eeee796017e9477ea9bf21","unresolved":true,"context_lines":[{"line_number":22,"context_line":"  when the parent action plan has SUCCEEDED"},{"line_number":23,"context_line":"- Gracefully degrade UI when older Watcher API versions are detected"},{"line_number":24,"context_line":"  (hides Actions column and skip controls for API \u003c 1.5)"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"Technical improvements:"},{"line_number":27,"context_line":"- Refactor client helper module renaming \u0027wv\u0027 to \u0027common_client\u0027 for"},{"line_number":28,"context_line":"  clarity and consistency"},{"line_number":29,"context_line":"- Add get_server_microversion_range() to get microversion"},{"line_number":30,"context_line":"- Add is_supported() helper using watcherclient\u0027s api_versioning"},{"line_number":31,"context_line":"  APIVersion for microversion capability checking"},{"line_number":32,"context_line":"- Add WatcherDashboardException typed exception in common/exceptions.py,"},{"line_number":33,"context_line":"  replacing generic ValueError in Action.update()"},{"line_number":34,"context_line":"- Catch wc_exc.MethodNotAllowed specifically in Action.update() instead"},{"line_number":35,"context_line":"  of broad except Exception for graceful degradation on HTTP 405"},{"line_number":36,"context_line":"- Replace request-object mutation pattern in action_plans DetailView"},{"line_number":37,"context_line":"  with a detail_action_plan property and explicit kwargs to"},{"line_number":38,"context_line":"  RelatedActionsTable via get_tables()"},{"line_number":39,"context_line":"- Add get_strategy_display_name() shared helper in api/watcher.py"},{"line_number":40,"context_line":"  using strategy.to_dict() to access display_name (not exposed in"},{"line_number":41,"context_line":"  watcherclient Strategy resource fields)"},{"line_number":42,"context_line":"- Add get_strategies_for_goal() AJAX endpoint in audit_templates for"},{"line_number":43,"context_line":"  dynamic strategy filtering by goal"},{"line_number":44,"context_line":"- Refactor audit template CreateForm: remove unnecessary try/except"},{"line_number":45,"context_line":"  AttributeError around self.data (never None on Django forms),"},{"line_number":46,"context_line":"  dynamically populate strategy choices on POST"},{"line_number":47,"context_line":"- Update python-watcherclient requirement to \u003e\u003d4.9.0"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"Testing:"},{"line_number":50,"context_line":"- Add unit tests for Action.update(), microversion"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":44,"id":"e2088651_7f1cb9fa","line":47,"range":{"start_line":25,"start_character":1,"end_line":47,"end_character":52},"in_reply_to":"821f3026_f9eccb68","updated":"2026-03-03 07:34:31.000000000","message":"Added 978607: Add microversion 1.5 API support and status_message display | https://review.opendev.org/c/openstack/watcher-dashboard/+/978607 and then rebase this skip patch on top of that.","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"adabc2734fd6d4c6d6f4d13bba4777f35b0a4e21","unresolved":false,"context_lines":[{"line_number":22,"context_line":"  when the parent action plan has SUCCEEDED"},{"line_number":23,"context_line":"- Gracefully degrade UI when older Watcher API versions are detected"},{"line_number":24,"context_line":"  (hides Actions column and skip controls for API \u003c 1.5)"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"Technical improvements:"},{"line_number":27,"context_line":"- Refactor client helper module renaming \u0027wv\u0027 to \u0027common_client\u0027 for"},{"line_number":28,"context_line":"  clarity and consistency"},{"line_number":29,"context_line":"- Add get_server_microversion_range() to get microversion"},{"line_number":30,"context_line":"- Add is_supported() helper using watcherclient\u0027s api_versioning"},{"line_number":31,"context_line":"  APIVersion for microversion capability checking"},{"line_number":32,"context_line":"- Add WatcherDashboardException typed exception in common/exceptions.py,"},{"line_number":33,"context_line":"  replacing generic ValueError in Action.update()"},{"line_number":34,"context_line":"- Catch wc_exc.MethodNotAllowed specifically in Action.update() instead"},{"line_number":35,"context_line":"  of broad except Exception for graceful degradation on HTTP 405"},{"line_number":36,"context_line":"- Replace request-object mutation pattern in action_plans DetailView"},{"line_number":37,"context_line":"  with a detail_action_plan property and explicit kwargs to"},{"line_number":38,"context_line":"  RelatedActionsTable via get_tables()"},{"line_number":39,"context_line":"- Add get_strategy_display_name() shared helper in api/watcher.py"},{"line_number":40,"context_line":"  using strategy.to_dict() to access display_name (not exposed in"},{"line_number":41,"context_line":"  watcherclient Strategy resource fields)"},{"line_number":42,"context_line":"- Add get_strategies_for_goal() AJAX endpoint in audit_templates for"},{"line_number":43,"context_line":"  dynamic strategy filtering by goal"},{"line_number":44,"context_line":"- Refactor audit template CreateForm: remove unnecessary try/except"},{"line_number":45,"context_line":"  AttributeError around self.data (never None on Django forms),"},{"line_number":46,"context_line":"  dynamically populate strategy choices on POST"},{"line_number":47,"context_line":"- Update python-watcherclient requirement to \u003e\u003d4.9.0"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"Testing:"},{"line_number":50,"context_line":"- Add unit tests for Action.update(), microversion"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":44,"id":"710e1eac_8f3e07e7","line":47,"range":{"start_line":25,"start_character":1,"end_line":47,"end_character":52},"in_reply_to":"e2088651_7f1cb9fa","updated":"2026-03-03 20:10:08.000000000","message":"Done","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7d3d0986fb1dc653e515a4351eb7d7b40b816512","unresolved":true,"context_lines":[{"line_number":22,"context_line":"  when the parent action plan has SUCCEEDED"},{"line_number":23,"context_line":"- Gracefully degrade UI when older Watcher API versions are detected"},{"line_number":24,"context_line":"  (hides Actions column and skip controls for API \u003c 1.5)"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"Technical improvements:"},{"line_number":27,"context_line":"- Refactor client helper module renaming \u0027wv\u0027 to \u0027common_client\u0027 for"},{"line_number":28,"context_line":"  clarity and consistency"},{"line_number":29,"context_line":"- Add get_server_microversion_range() to get microversion"},{"line_number":30,"context_line":"- Add is_supported() helper using watcherclient\u0027s api_versioning"},{"line_number":31,"context_line":"  APIVersion for microversion capability checking"},{"line_number":32,"context_line":"- Add WatcherDashboardException typed exception in common/exceptions.py,"},{"line_number":33,"context_line":"  replacing generic ValueError in Action.update()"},{"line_number":34,"context_line":"- Catch wc_exc.MethodNotAllowed specifically in Action.update() instead"},{"line_number":35,"context_line":"  of broad except Exception for graceful degradation on HTTP 405"},{"line_number":36,"context_line":"- Replace request-object mutation pattern in action_plans DetailView"},{"line_number":37,"context_line":"  with a detail_action_plan property and explicit kwargs to"},{"line_number":38,"context_line":"  RelatedActionsTable via get_tables()"},{"line_number":39,"context_line":"- Add get_strategy_display_name() shared helper in api/watcher.py"},{"line_number":40,"context_line":"  using strategy.to_dict() to access display_name (not exposed in"},{"line_number":41,"context_line":"  watcherclient Strategy resource fields)"},{"line_number":42,"context_line":"- Add get_strategies_for_goal() AJAX endpoint in audit_templates for"},{"line_number":43,"context_line":"  dynamic strategy filtering by goal"},{"line_number":44,"context_line":"- Refactor audit template CreateForm: remove unnecessary try/except"},{"line_number":45,"context_line":"  AttributeError around self.data (never None on Django forms),"},{"line_number":46,"context_line":"  dynamically populate strategy choices on POST"},{"line_number":47,"context_line":"- Update python-watcherclient requirement to \u003e\u003d4.9.0"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"Testing:"},{"line_number":50,"context_line":"- Add unit tests for Action.update(), microversion"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":44,"id":"821f3026_f9eccb68","line":47,"range":{"start_line":25,"start_character":1,"end_line":47,"end_character":52},"in_reply_to":"fa1d4177_53b6e1f9","updated":"2026-02-27 10:59:20.000000000","message":"Yes, I totally agree. The code became too messy, addressing multiple things in same patch.\n\nThank you for suggestion on breaking it into multiple patch.\nBelow are the list of patches:\n- [Rename \u0027wv\u0027 to \u0027common_client\u0027 in client helper module](https://review.opendev.org/c/openstack/watcher-dashboard/+/978160)\n\n- [Centralize strategy display_name access into a shared helper](https://review.opendev.org/c/openstack/watcher-dashboard/+/978161) \n\n- [Simplify selected goal retrieval in Audit template CreateForm](https://review.opendev.org/c/openstack/watcher-dashboard/+/978171)\n\n- [Add microversion discovery for API calls](https://review.opendev.org/c/openstack/watcher-dashboard/+/978186) Before moving to skip feature reimplmentation, I need your feedback on this patch. I am thinking about following the same approach for Skip feature.","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"74415af2453e3909716acc70e11d570a37da563b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"5fef361b_60bf888c","updated":"2025-08-28 12:33:11.000000000","message":"Screenshot before SKIP action button and SKIP reason feature:\n- Action Plan Details View: https://i.imgur.com/YGO7NcI.png\n- Actions Details View: https://i.imgur.com/P6L7lOT.png\n\nScreenshot After SKIP action button and SKIP reason feature:\n- Action Plan Details containing skip button: https://i.imgur.com/LCw1ibf.png\n- On clicking Skip Action button, Skip Reason pop up opens: https://i.imgur.com/3x4nx6X.png\n- Action Details view showing skip reason: https://i.imgur.com/w1lu3yO.png","commit_id":"9a2b32b732466a8360f382eb33cef534f2f87595"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"9c5ff80cddbefc56227dc0ae261152458617a18b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"367528e8_e2eef571","updated":"2025-08-28 19:03:10.000000000","message":"Thanks for providing the screenshots\nI think that we just need to sync with the fix proposed in [1].\n\n[1] https://review.opendev.org/c/openstack/watcher/+/958778","commit_id":"df7a850bc63e0ee72ecf389491d7f310f0ac2b06"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"6515c4595d4bdab6215aabba50d4362a682eba0a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"b2c29aea_54ec3674","updated":"2025-08-28 12:52:25.000000000","message":"recheck","commit_id":"df7a850bc63e0ee72ecf389491d7f310f0ac2b06"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ed410f766e79f0fcacdf10dd169f32b44ab47e5c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"0a31487c_4f732eed","updated":"2025-08-29 04:20:06.000000000","message":"Thank you @viroel@gmail.com for the review. I have addressed the comments.","commit_id":"9d98d5f00088fffd136ec736801a7c758e7c5dbf"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"672f380379c3047eb18c296ca16a6b2f00389b1a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"61b7069f_94bb079c","updated":"2025-08-29 12:30:04.000000000","message":"Looks good.\nI tried in my env and it works, Skip action with/without reason. Only udpating the the \u0027reason\u0027 also works.\nOne thing that I would change is to return to the Action Plan details (dashboard/admin/action_plans/{action_id}/detail) once we Skip an action, since now it actually returns to the Action Plan index page.","commit_id":"b5a3ba47f3963edcbeeb7c4b8556d53f5995477d"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"0cae1e1aeadf5a4556bf2e10c656d59753a5358f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"8a839ac3_fb2ac1c9","updated":"2025-08-29 18:30:37.000000000","message":"Thanks for updating the patch","commit_id":"acfb5a24ee8f2e9c9f5c2f84e91091ffad09877c"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"cb0fa95b495196cf210972e7704bd4abe1aa39d5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"417fa178_4d767f1d","updated":"2025-09-01 05:19:00.000000000","message":"check-rdo","commit_id":"c91b2de6143d8157827ed2a76c86c9323d15f777"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"918bbc6815a702d5a0e897f3e28c1d685ce7586c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"135a41c0_15b60893","updated":"2025-09-02 13:38:24.000000000","message":"We are missing the requirements bump","commit_id":"dc67371c2c2ca4e5c5883dc86a5ee53b0db3acfe"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"dc6f9c768689ba7192237068bfe7628345e2fd2e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":17,"id":"ae2b01b1_4d23b657","updated":"2025-09-02 14:09:40.000000000","message":"Thanks for the updates Chandan","commit_id":"a2a8ae865bc6f110af4ac24708877ea66f1d52ba"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"5ec8e9c12a00b4a9fc988202d882e2fd92a6ca49","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":17,"id":"03a149c0_f5a97b74","updated":"2025-09-02 13:59:12.000000000","message":"thanks for the changes Chandan!","commit_id":"a2a8ae865bc6f110af4ac24708877ea66f1d52ba"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"1b5529c04686f9af568508cf272830eb4c99bb82","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":25,"id":"1b2cbd51_0af0b143","updated":"2025-09-19 09:20:15.000000000","message":"I\u0027ve successfully tested locally. The version discovery is working fine and the new functionality. I guess it will need some rebase and changes after latest changes in previous commits. Other than that:\n\n- See my comment about when the Skip button should be allowed.\n- Would it be possible to also add the Status message field to the ActionPlan overview table in the actionplan details? note that, i.e. when skipping manually an action, the status_message of the actionplan will be updated with \"one or more actions were skipped\", which is a good information to show imo\n\nOther than that, lgtm","commit_id":"e7fbc5f512273f63c5094194f5ac0111ef8d8038"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"68863a3836d63e956dba368842361530e8d43489","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":28,"id":"0ab38d37_a040b482","updated":"2025-09-30 10:03:07.000000000","message":"I\u0027ve successfully tested this locally.\n\nThe only blocker to merge it for me is that the change in the strategy details (setting max hight for the strategy spec) should be a separate review.\n\nOther than that, i think it would be good to explicitly check if the microversion for skip is available instead of just assuming it is not based on a general Exception in a couple of cases (see my comments inline)","commit_id":"5018a4bb21bf76f6742b33511591cdccba8ca101"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"747d896fa56d5a3e222e4992fcc43042981b1dd2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":29,"id":"8b2eda2b_2eb8e9df","updated":"2025-10-03 08:14:40.000000000","message":"Testing this running watcher without support for 1.5 fails. A fix for the version discovery implementation is needed, see my comments below.","commit_id":"00b0ad0ece0e7c73cb31747920bf45073d105870"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"8187d3b182dd4b6555558df211c6a799572f622f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":30,"id":"19b5946b_e5275d5e","updated":"2025-10-06 07:05:41.000000000","message":"I have tested it with older and newer cloud, both seems to be working fine now.","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":30,"id":"33d4f60a_1dc586f8","updated":"2025-10-08 15:08:16.000000000","message":"My main concern is that we could simplify the many checks that we have againt 1.5 here. I also don\u0027t think that we need to hide the Status Message column when showing details, just because the server don\u0027t support it. It will have an empty content only.\nI agree that is fine to hide (or disable) the Skip button in the end, to avoid confusion.\nI think that we can improve the code by adding properties and avoid some dynamic caching added.","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"fc888a62e65ade12ac21f27d87d09403c42fb274","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":30,"id":"145f1962_1e0fab7d","updated":"2025-10-06 11:25:51.000000000","message":"Thanks for all your fixes!","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":30,"id":"dc421b91_84598e95","in_reply_to":"33d4f60a_1dc586f8","updated":"2025-10-10 15:10:41.000000000","message":"Thank you for the comprehensive review. The main concerns were about simplifying microversion checks, reducing code complexity, and avoiding unnecessary dynamic attribute management. I\u0027ve implemented a cleaner approach that:\n\n1. Always uses the maximum supported server version\n2. Filters status_message content based on microversion support\n3. Eliminates redundant microversion checks\n4. Replaces dynamic getattr/setattr/hasattr with proper properties based sean\u0027s gist\n5. Always shows status_message fields in UI (with empty content when unsupported)","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"b054c398e3a7dbacebdd8468a4ff1a8f33f5414e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":30,"id":"6a5495f1_709f5287","in_reply_to":"dc421b91_84598e95","updated":"2025-11-04 12:08:38.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"b054c398e3a7dbacebdd8468a4ff1a8f33f5414e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":33,"id":"cf14441a_fbb0fbe8","updated":"2025-11-04 12:08:38.000000000","message":"Looks good, not sure if there are more things to fix before we proceed. Not sure about the \u0027latest\u0027 comparison.\nAlso did a quick test with current PS and it is working, but I just tested with microversion 1.6.","commit_id":"1f3a375cb983e4db9a2219247628aa16e62e05fc"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"83c15644d59d7b5edd392d771d4dda461aa9a91b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":36,"id":"6ba01f32_122e12b7","updated":"2025-11-19 10:33:51.000000000","message":"Needs manual rebase, other than that, lgtm","commit_id":"18275cdb90c24a7ec060daf2c96caa3e531b40d1"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"2b558ed8a757592936c253bc077bece7529ddc71","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":37,"id":"357f599f_0bad7dbc","updated":"2026-02-18 08:38:29.000000000","message":"Hello @smooney@redhat.com @amoralej@redhat.com @viroel@gmail.com, I have added the playwright based integration test https://review.opendev.org/c/openstack/watcher-dashboard/+/976594 to test skip workflow\n\nHere is the job result: https://zuul.opendev.org/t/openstack/build/caf3bc578b1947e3a25e67101d8969ab and generated screenshots from the test: https://4e653b44258ae0ef8e8c-431c4675dbf321a8fbd861f82b52f6e9.ssl.cf2.rackcdn.com/openstack/caf3bc578b1947e3a25e67101d8969ab/controller/logs/playwright/screenshots/watcher_dashboard.test.integration.test_playwright_skip_action_workflow.SkipActionWorkflowTests.test_skip_action_workflow/index.html\n\nPlease have a look when you get time thank you!","commit_id":"35ea4c9800470864148288cc7860b439788069ec"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"69e75a28edf020dea6cc1d980f1e51eeaa9df3e2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":37,"id":"c44d1a96_bcde4b86","in_reply_to":"357f599f_0bad7dbc","updated":"2026-02-18 14:19:30.000000000","message":"Thanks for the playwright tests, it\u0027s great to have them together with the new feature. I tested successfully and codewise my main comment is that the new \"Skip Action\" form should have buttons to close / cancel for usability. Other than that, i think it works as expected.","commit_id":"35ea4c9800470864148288cc7860b439788069ec"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cb85b8994073c52a5d99aae84c144a69325e1f26","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":40,"id":"965405fe_b216192b","updated":"2026-02-25 18:52:41.000000000","message":"https://paste.opendev.org/show/bzNpdAdbeeMeeULzfwxe/ is a more consie ai review \nof this change using sonnet.\n\nim not sure you will have time to adress all the issues htere\ncertely fixing all method in `watcher_dashboard/api/watcher.py to accpet the intened microverion is out of scope fo this change but\nyou should at elast fix the ones your adding.","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cf5770ef24939fbdc459a03a9b1bc6d75d2c0ac8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":40,"id":"2747f2d6_3afebc85","updated":"2026-02-25 18:30:48.000000000","message":"this might be functional but there area lot of python fundamental that are wrong with this code.","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"95ad43b894ddf01d938e9c5e708e3d757ec4a26c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":41,"id":"653376ea_c6395c0f","updated":"2026-02-26 13:54:56.000000000","message":"Need to address the Sean comment","commit_id":"4f6c274d0ddb00cabe7d63c83971c7ff8bdfdc5f"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ffff5a8378c3a631db8e5ff1502fcb009d4330d5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":43,"id":"d9c2ea92_6bcf4abe","updated":"2026-02-26 15:18:26.000000000","message":"Thank you for the https://paste.opendev.org/show/bzNpdAdbeeMeeULzfwxe/ and detailed suggestion on the implementation, I tried to address most of them, I might missed few, Will re-update the patch and fix it.","commit_id":"81beba98cbc0ebbb0b8d0f0bc95c38b717339c1d"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"a34cbf1cd07b2a57b758783f1eba4945f418c09e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":45,"id":"2439872d_0e06c86e","updated":"2026-03-03 07:36:49.000000000","message":"I have marked most of the comments as resolved based on breaking the changes in multiple patches.","commit_id":"37f27c514e7c513f32e0c1cc764c62d50d1e99e3"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"d1c643f1e14b68675e801398cf2c30067183044f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":45,"id":"6345327f_5a460dc6","updated":"2026-03-03 08:37:38.000000000","message":"Needs more fixes","commit_id":"37f27c514e7c513f32e0c1cc764c62d50d1e99e3"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"adabc2734fd6d4c6d6f4d13bba4777f35b0a4e21","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":47,"id":"f69daf96_631f5ffc","updated":"2026-03-03 20:10:08.000000000","message":"i have not run this loocaly\n\nbut review in the playwrigte patch latere\n\nhttps://1e1442a936d81c7126bc-fc1e7af78d7504e20bbc3359634b65b5.ssl.cf1.rackcdn.com/openstack/6eeb40834f8743d3af4cfcfbc23b96d1/controller/logs/playwright/screenshots/watcher_dashboard.test.integration.test_playwright_skip_action_workflow.SkipActionWorkflowTests.test_skip_action_workflow/\n\nspecificlly\n\n\t023_action_plan_detail_loaded.png\tTue Mar 3 11:39:39 2026\t127.7K\n[ ]\t024_skip_action_modal_open.png\tTue Mar 3 11:39:40 2026\t138.8K\n[ ]\t025_skip_reason_filled.png\tTue Mar 3 11:39:40 2026\t142.1K\n[ ]\t026_skip_action_submitted.png\tTue Mar 3 11:39:42 2026\t133.3K\n[ ]\t027_action_detail_loaded.png\n\nthis looks corerct to me.\n\ni think we can proceed with this as the final patch for this relase and then work on the rc release patches.","commit_id":"3a884013ecbca509d2379b090f2a16bb6206d2d5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"29e65cdcf2cdf61a23dc814228f0bfdfe2fcddc1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":47,"id":"3cbe296e_9d5243a0","updated":"2026-03-03 20:36:24.000000000","message":"lgtm, I also didn\u0027t test in my env this time, but based on playwrite test outputs it seems that is working properly.\nI agree with Sean that we can proceed with this patch and work with fixes if needed.\nThanks for working hard in these series.","commit_id":"3a884013ecbca509d2379b090f2a16bb6206d2d5"}],"requirements.txt":[{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"918bbc6815a702d5a0e897f3e28c1d685ce7586c","unresolved":true,"context_lines":[{"line_number":6,"context_line":"horizon\u003e\u003d18.2.0 # Apache-2.0"},{"line_number":7,"context_line":""},{"line_number":8,"context_line":"PyYAML\u003e\u003d3.12 # MIT"},{"line_number":9,"context_line":"# TODO(amoralej) bump minor version supporting action update"},{"line_number":10,"context_line":"python-watcherclient\u003e\u003d1.1.0 # Apache-2.0"}],"source_content_type":"text/plain","patch_set":15,"id":"90e6e8e0_7cc583a3","line":9,"range":{"start_line":9,"start_character":0,"end_line":9,"end_character":60},"updated":"2025-09-02 13:38:24.000000000","message":"you still need to bump here based on\nhttps://github.com/openstack/requirements/blob/7898ec56b4eeb8f67370d60d13b53a95a1a774e7/upper-constraints.txt#L120","commit_id":"dc67371c2c2ca4e5c5883dc86a5ee53b0db3acfe"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"76feef4681ace347404cd21ce982d89597883b56","unresolved":false,"context_lines":[{"line_number":6,"context_line":"horizon\u003e\u003d18.2.0 # Apache-2.0"},{"line_number":7,"context_line":""},{"line_number":8,"context_line":"PyYAML\u003e\u003d3.12 # MIT"},{"line_number":9,"context_line":"# TODO(amoralej) bump minor version supporting action update"},{"line_number":10,"context_line":"python-watcherclient\u003e\u003d1.1.0 # Apache-2.0"}],"source_content_type":"text/plain","patch_set":15,"id":"7d61c08b_9bf98b41","line":9,"range":{"start_line":9,"start_character":0,"end_line":9,"end_character":60},"in_reply_to":"90e6e8e0_7cc583a3","updated":"2025-09-02 13:41:47.000000000","message":"Done","commit_id":"dc67371c2c2ca4e5c5883dc86a5ee53b0db3acfe"}],"watcher_dashboard/api/watcher.py":[{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"9c5ff80cddbefc56227dc0ae261152458617a18b","unresolved":true,"context_lines":[{"line_number":425,"context_line":"        watcherclient(request).action.update(action_id, patch)"},{"line_number":426,"context_line":""},{"line_number":427,"context_line":"    @classmethod"},{"line_number":428,"context_line":"    def update(cls, request, action_id, state, reason\u003dNone):"},{"line_number":429,"context_line":"        \"\"\"Update an action\u0027s state and optionally status message"},{"line_number":430,"context_line":""},{"line_number":431,"context_line":"        :param request: request object"}],"source_content_type":"text/x-python","patch_set":3,"id":"f27f5200_b63d5890","line":428,"range":{"start_line":428,"start_character":40,"end_line":428,"end_character":45},"updated":"2025-08-28 19:03:10.000000000","message":"we need to support updating reason only too, and fail when both state and reason are None. Check [1]\n\n[1] https://review.opendev.org/c/openstack/watcher/+/958778","commit_id":"df7a850bc63e0ee72ecf389491d7f310f0ac2b06"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"672f380379c3047eb18c296ca16a6b2f00389b1a","unresolved":false,"context_lines":[{"line_number":425,"context_line":"        watcherclient(request).action.update(action_id, patch)"},{"line_number":426,"context_line":""},{"line_number":427,"context_line":"    @classmethod"},{"line_number":428,"context_line":"    def update(cls, request, action_id, state, reason\u003dNone):"},{"line_number":429,"context_line":"        \"\"\"Update an action\u0027s state and optionally status message"},{"line_number":430,"context_line":""},{"line_number":431,"context_line":"        :param request: request object"}],"source_content_type":"text/x-python","patch_set":3,"id":"08e638bf_a823a928","line":428,"range":{"start_line":428,"start_character":40,"end_line":428,"end_character":45},"in_reply_to":"308171ed_8dc2d27e","updated":"2025-08-29 12:30:04.000000000","message":"Done","commit_id":"df7a850bc63e0ee72ecf389491d7f310f0ac2b06"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ed410f766e79f0fcacdf10dd169f32b44ab47e5c","unresolved":true,"context_lines":[{"line_number":425,"context_line":"        watcherclient(request).action.update(action_id, patch)"},{"line_number":426,"context_line":""},{"line_number":427,"context_line":"    @classmethod"},{"line_number":428,"context_line":"    def update(cls, request, action_id, state, reason\u003dNone):"},{"line_number":429,"context_line":"        \"\"\"Update an action\u0027s state and optionally status message"},{"line_number":430,"context_line":""},{"line_number":431,"context_line":"        :param request: request object"}],"source_content_type":"text/x-python","patch_set":3,"id":"308171ed_8dc2d27e","line":428,"range":{"start_line":428,"start_character":40,"end_line":428,"end_character":45},"in_reply_to":"f27f5200_b63d5890","updated":"2025-08-29 04:20:06.000000000","message":"Done","commit_id":"df7a850bc63e0ee72ecf389491d7f310f0ac2b06"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"72762335346460df1c418685701469bef59a4759","unresolved":true,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":23,"context_line":"WATCHER_SERVICE \u003d \u0027infra-optim\u0027"},{"line_number":24,"context_line":"WATCHER_API_VERSION \u003d \"1.5\""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"def watcherclient(request, password\u003dNone):"}],"source_content_type":"text/x-python","patch_set":17,"id":"3d49aed9_dd7a17e6","line":24,"updated":"2025-09-03 16:28:11.000000000","message":"it is not valide ot use the same micorverion for all requests\n\nthis cause the following warning to be show to the user if they use the newer verion of the plugin with an older cloud\n\n\n```\nWarning: Requested API version 1.5 is not supported by the server or the requested operation is not supported by the requested version. Supported version range is 1.0 to 1.4 \n```\nhttps://imgur.com/a/6Rewlt3\n\nthat is not corect.\n\nyou shoudl only be using 1.5 if the cloud supprot it and you shoudl nto be show this as a warning in the ui.","commit_id":"a2a8ae865bc6f110af4ac24708877ea66f1d52ba"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"8d93d742d0d2a6b80ff72a3dfae2294808a4162b","unresolved":true,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":23,"context_line":"WATCHER_SERVICE \u003d \u0027infra-optim\u0027"},{"line_number":24,"context_line":"WATCHER_API_VERSION \u003d \"1.5\""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"def watcherclient(request, password\u003dNone):"}],"source_content_type":"text/x-python","patch_set":17,"id":"52fc7cf7_6119ff99","line":24,"in_reply_to":"3d49aed9_dd7a17e6","updated":"2025-09-03 16:33:57.000000000","message":"to be clear its perfectly ok to require a new verison of openstack client to use the new verion of the horizon plugin\n\nhowever it breaks upgrade rules ot require watcher to be upgrade to use the new verion of the plugin.\n\nboth shoudl be upgradable in either order and it should fail gracefully if 1.5 is not supproted \n\nthe stragy parmeter do at least show up on the audit page \n\nhttps://imgur.com/a/t9OX3EQ\n\nbut you cant actully create audit templates or audits properly so this need to be fixed before we can proceed with this patch.","commit_id":"a2a8ae865bc6f110af4ac24708877ea66f1d52ba"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7afce0951cda84e58f4632237d55a2a0d0052def","unresolved":true,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":23,"context_line":"WATCHER_SERVICE \u003d \u0027infra-optim\u0027"},{"line_number":24,"context_line":"WATCHER_API_VERSION \u003d \"1.5\""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"def watcherclient(request, password\u003dNone):"}],"source_content_type":"text/x-python","patch_set":17,"id":"a5f46d6e_860c889f","line":24,"in_reply_to":"52fc7cf7_6119ff99","updated":"2025-09-04 07:28:02.000000000","message":"Thank you @seanmooney8202@yahoo.ie, thank you for highlighting upgrade case. I have fixed it now. Now user will receive following error https://i.imgur.com/h7awlIm.png on adding reason message on older cloud.\n\nI hope it addresses the above issue.","commit_id":"a2a8ae865bc6f110af4ac24708877ea66f1d52ba"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"90edb189d881773270175181de001ad9057ba630","unresolved":true,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":23,"context_line":"WATCHER_SERVICE \u003d \u0027infra-optim\u0027"},{"line_number":24,"context_line":"WATCHER_API_VERSION \u003d \"1.5\""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"def watcherclient(request, password\u003dNone):"}],"source_content_type":"text/x-python","patch_set":17,"id":"a362e47e_4f92c668","line":24,"in_reply_to":"633b0214_a81f2d2c","updated":"2025-09-09 09:01:41.000000000","message":"Here is the updated screenshot\n- for older cloud with no skip action: https://i.imgur.com/3DrBBIm.png\n- Newer cloud with skip action: https://i.imgur.com/st7FxWl.png","commit_id":"a2a8ae865bc6f110af4ac24708877ea66f1d52ba"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ca56d701388ca74db085f2efbcb838c9b0e0b780","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":23,"context_line":"WATCHER_SERVICE \u003d \u0027infra-optim\u0027"},{"line_number":24,"context_line":"WATCHER_API_VERSION \u003d \"1.5\""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"def watcherclient(request, password\u003dNone):"}],"source_content_type":"text/x-python","patch_set":17,"id":"8416746a_51734dc4","line":24,"in_reply_to":"a362e47e_4f92c668","updated":"2025-11-26 05:46:11.000000000","message":"Done","commit_id":"a2a8ae865bc6f110af4ac24708877ea66f1d52ba"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"4d3249004d76227a2d13dc11087c1857bb4bd00b","unresolved":true,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":23,"context_line":"WATCHER_SERVICE \u003d \u0027infra-optim\u0027"},{"line_number":24,"context_line":"WATCHER_API_VERSION \u003d \"1.5\""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"def watcherclient(request, password\u003dNone):"}],"source_content_type":"text/x-python","patch_set":17,"id":"633b0214_a81f2d2c","line":24,"in_reply_to":"a5f46d6e_860c889f","updated":"2025-09-04 10:31:31.000000000","message":"you missed my point they should not receve an error at all\nthey shoudl just not have the option to skip if the clodu does nto supprot it.","commit_id":"a2a8ae865bc6f110af4ac24708877ea66f1d52ba"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"68863a3836d63e956dba368842361530e8d43489","unresolved":true,"context_lines":[{"line_number":340,"context_line":"                 the ID"},{"line_number":341,"context_line":"        :rtype:  :py:class:`~.ActionPlan`"},{"line_number":342,"context_line":"        \"\"\""},{"line_number":343,"context_line":"        # Try SKIP_ACTION microversion first to include status_message."},{"line_number":344,"context_line":"        # Fall back to default for older clouds without support."},{"line_number":345,"context_line":"        try:"},{"line_number":346,"context_line":"            client \u003d watcherclient("},{"line_number":347,"context_line":"                request, api_version\u003dcommon_client.SKIP_ACTION)"},{"line_number":348,"context_line":"            return client.action_plan.get(action_plan_id\u003daction_plan_id)"},{"line_number":349,"context_line":"        except Exception:"},{"line_number":350,"context_line":"            client \u003d watcherclient(request)"},{"line_number":351,"context_line":"            return client.action_plan.get(action_plan_id\u003daction_plan_id)"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"    @classmethod"},{"line_number":354,"context_line":"    def delete(cls, request, action_plan_id):"}],"source_content_type":"text/x-python","patch_set":28,"id":"df3463d6_009af177","line":351,"range":{"start_line":343,"start_character":0,"end_line":351,"end_character":72},"updated":"2025-09-30 10:03:07.000000000","message":"why not use the is_supported method here to find out if 1.5 is supported to define the microversion to use?. This may end up in unexpected failures in cases where an Excepthing is raised for any other issue.","commit_id":"5018a4bb21bf76f6742b33511591cdccba8ca101"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"2f54c5f4e57268fe0e879860761bb89e356702d4","unresolved":false,"context_lines":[{"line_number":340,"context_line":"                 the ID"},{"line_number":341,"context_line":"        :rtype:  :py:class:`~.ActionPlan`"},{"line_number":342,"context_line":"        \"\"\""},{"line_number":343,"context_line":"        # Try SKIP_ACTION microversion first to include status_message."},{"line_number":344,"context_line":"        # Fall back to default for older clouds without support."},{"line_number":345,"context_line":"        try:"},{"line_number":346,"context_line":"            client \u003d watcherclient("},{"line_number":347,"context_line":"                request, api_version\u003dcommon_client.SKIP_ACTION)"},{"line_number":348,"context_line":"            return client.action_plan.get(action_plan_id\u003daction_plan_id)"},{"line_number":349,"context_line":"        except Exception:"},{"line_number":350,"context_line":"            client \u003d watcherclient(request)"},{"line_number":351,"context_line":"            return client.action_plan.get(action_plan_id\u003daction_plan_id)"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"    @classmethod"},{"line_number":354,"context_line":"    def delete(cls, request, action_plan_id):"}],"source_content_type":"text/x-python","patch_set":28,"id":"8c273d69_47a04296","line":351,"range":{"start_line":343,"start_character":0,"end_line":351,"end_character":72},"in_reply_to":"df3463d6_009af177","updated":"2025-10-03 04:00:29.000000000","message":"Done","commit_id":"5018a4bb21bf76f6742b33511591cdccba8ca101"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"68863a3836d63e956dba368842361530e8d43489","unresolved":true,"context_lines":[{"line_number":421,"context_line":"        :rtype:  :py:class:`~.Action`"},{"line_number":422,"context_line":"        \"\"\""},{"line_number":423,"context_line":"        # Try SKIP_ACTION microversion first to include status_message"},{"line_number":424,"context_line":"        try:"},{"line_number":425,"context_line":"            client \u003d watcherclient("},{"line_number":426,"context_line":"                request, api_version\u003dcommon_client.SKIP_ACTION)"},{"line_number":427,"context_line":"            return client.action.get(action_id\u003daction_id)"},{"line_number":428,"context_line":"        except Exception:"},{"line_number":429,"context_line":"            # Fall back to default microversion for older clouds"},{"line_number":430,"context_line":"            # Silently handle older clouds without logging exceptions"},{"line_number":431,"context_line":"            client \u003d watcherclient(request)"},{"line_number":432,"context_line":"            return client.action.get(action_id\u003daction_id)"},{"line_number":433,"context_line":""},{"line_number":434,"context_line":"    @classmethod"},{"line_number":435,"context_line":"    def delete(cls, request, action_id):"}],"source_content_type":"text/x-python","patch_set":28,"id":"0ce2a988_831c61b5","line":432,"range":{"start_line":424,"start_character":0,"end_line":432,"end_character":57},"updated":"2025-09-30 10:03:07.000000000","message":"ditto","commit_id":"5018a4bb21bf76f6742b33511591cdccba8ca101"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"2f54c5f4e57268fe0e879860761bb89e356702d4","unresolved":false,"context_lines":[{"line_number":421,"context_line":"        :rtype:  :py:class:`~.Action`"},{"line_number":422,"context_line":"        \"\"\""},{"line_number":423,"context_line":"        # Try SKIP_ACTION microversion first to include status_message"},{"line_number":424,"context_line":"        try:"},{"line_number":425,"context_line":"            client \u003d watcherclient("},{"line_number":426,"context_line":"                request, api_version\u003dcommon_client.SKIP_ACTION)"},{"line_number":427,"context_line":"            return client.action.get(action_id\u003daction_id)"},{"line_number":428,"context_line":"        except Exception:"},{"line_number":429,"context_line":"            # Fall back to default microversion for older clouds"},{"line_number":430,"context_line":"            # Silently handle older clouds without logging exceptions"},{"line_number":431,"context_line":"            client \u003d watcherclient(request)"},{"line_number":432,"context_line":"            return client.action.get(action_id\u003daction_id)"},{"line_number":433,"context_line":""},{"line_number":434,"context_line":"    @classmethod"},{"line_number":435,"context_line":"    def delete(cls, request, action_id):"}],"source_content_type":"text/x-python","patch_set":28,"id":"0509ef88_b377fb4d","line":432,"range":{"start_line":424,"start_character":0,"end_line":432,"end_character":57},"in_reply_to":"0ce2a988_831c61b5","updated":"2025-10-03 04:00:29.000000000","message":"Done","commit_id":"5018a4bb21bf76f6742b33511591cdccba8ca101"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"68863a3836d63e956dba368842361530e8d43489","unresolved":true,"context_lines":[{"line_number":445,"context_line":"            action_id\u003daction_id)"},{"line_number":446,"context_line":""},{"line_number":447,"context_line":"    @classmethod"},{"line_number":448,"context_line":"    def start(cls, request, action_id):"},{"line_number":449,"context_line":"        \"\"\"Start an Action Plan"},{"line_number":450,"context_line":""},{"line_number":451,"context_line":"        :param request: request object"},{"line_number":452,"context_line":"        :type  request: django.http.HttpRequest"},{"line_number":453,"context_line":""},{"line_number":454,"context_line":"        :param action_id: action_plan id"},{"line_number":455,"context_line":"        :type  action_id: int"},{"line_number":456,"context_line":"        \"\"\""},{"line_number":457,"context_line":"        patch \u003d []"},{"line_number":458,"context_line":"        patch.append({\u0027op\u0027: \u0027replace\u0027, \u0027path\u0027: \u0027/state\u0027, \u0027value\u0027: \u0027PENDING\u0027})"},{"line_number":459,"context_line":"        # Use default microversion for action start"},{"line_number":460,"context_line":"        action_mgr \u003d watcherclient(request, api_version\u003dNone).action"},{"line_number":461,"context_line":"        if hasattr(action_mgr, \u0027update\u0027):"},{"line_number":462,"context_line":"            action_mgr.update(action_id, patch)"},{"line_number":463,"context_line":"        else:"},{"line_number":464,"context_line":"            # Fallback for older client versions"},{"line_number":465,"context_line":"            action_mgr._update(action_mgr._path(action_id), patch)"},{"line_number":466,"context_line":""},{"line_number":467,"context_line":"    @classmethod"},{"line_number":468,"context_line":"    def update(cls, request, action_id, state\u003dNone, reason\u003dNone):"}],"source_content_type":"text/x-python","patch_set":28,"id":"339cd1c5_138c55a3","line":465,"range":{"start_line":448,"start_character":3,"end_line":465,"end_character":66},"updated":"2025-09-30 10:03:07.000000000","message":"For follow-up, this is wrong and never used, we should remove it in a follow-up patch.","commit_id":"5018a4bb21bf76f6742b33511591cdccba8ca101"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"31410901559bfc20dad77564010b16b43b4e8f31","unresolved":true,"context_lines":[{"line_number":445,"context_line":"            action_id\u003daction_id)"},{"line_number":446,"context_line":""},{"line_number":447,"context_line":"    @classmethod"},{"line_number":448,"context_line":"    def start(cls, request, action_id):"},{"line_number":449,"context_line":"        \"\"\"Start an Action Plan"},{"line_number":450,"context_line":""},{"line_number":451,"context_line":"        :param request: request object"},{"line_number":452,"context_line":"        :type  request: django.http.HttpRequest"},{"line_number":453,"context_line":""},{"line_number":454,"context_line":"        :param action_id: action_plan id"},{"line_number":455,"context_line":"        :type  action_id: int"},{"line_number":456,"context_line":"        \"\"\""},{"line_number":457,"context_line":"        patch \u003d []"},{"line_number":458,"context_line":"        patch.append({\u0027op\u0027: \u0027replace\u0027, \u0027path\u0027: \u0027/state\u0027, \u0027value\u0027: \u0027PENDING\u0027})"},{"line_number":459,"context_line":"        # Use default microversion for action start"},{"line_number":460,"context_line":"        action_mgr \u003d watcherclient(request, api_version\u003dNone).action"},{"line_number":461,"context_line":"        if hasattr(action_mgr, \u0027update\u0027):"},{"line_number":462,"context_line":"            action_mgr.update(action_id, patch)"},{"line_number":463,"context_line":"        else:"},{"line_number":464,"context_line":"            # Fallback for older client versions"},{"line_number":465,"context_line":"            action_mgr._update(action_mgr._path(action_id), patch)"},{"line_number":466,"context_line":""},{"line_number":467,"context_line":"    @classmethod"},{"line_number":468,"context_line":"    def update(cls, request, action_id, state\u003dNone, reason\u003dNone):"}],"source_content_type":"text/x-python","patch_set":28,"id":"4326a1a1_d2bea0c1","line":465,"range":{"start_line":448,"start_character":3,"end_line":465,"end_character":66},"in_reply_to":"339cd1c5_138c55a3","updated":"2025-10-03 03:52:57.000000000","message":"Dropped in https://review.opendev.org/c/openstack/watcher-dashboard/+/962898","commit_id":"5018a4bb21bf76f6742b33511591cdccba8ca101"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"b6488e35e0e73ffb0f1cd36e5e705843412b0b5d","unresolved":false,"context_lines":[{"line_number":445,"context_line":"            action_id\u003daction_id)"},{"line_number":446,"context_line":""},{"line_number":447,"context_line":"    @classmethod"},{"line_number":448,"context_line":"    def start(cls, request, action_id):"},{"line_number":449,"context_line":"        \"\"\"Start an Action Plan"},{"line_number":450,"context_line":""},{"line_number":451,"context_line":"        :param request: request object"},{"line_number":452,"context_line":"        :type  request: django.http.HttpRequest"},{"line_number":453,"context_line":""},{"line_number":454,"context_line":"        :param action_id: action_plan id"},{"line_number":455,"context_line":"        :type  action_id: int"},{"line_number":456,"context_line":"        \"\"\""},{"line_number":457,"context_line":"        patch \u003d []"},{"line_number":458,"context_line":"        patch.append({\u0027op\u0027: \u0027replace\u0027, \u0027path\u0027: \u0027/state\u0027, \u0027value\u0027: \u0027PENDING\u0027})"},{"line_number":459,"context_line":"        # Use default microversion for action start"},{"line_number":460,"context_line":"        action_mgr \u003d watcherclient(request, api_version\u003dNone).action"},{"line_number":461,"context_line":"        if hasattr(action_mgr, \u0027update\u0027):"},{"line_number":462,"context_line":"            action_mgr.update(action_id, patch)"},{"line_number":463,"context_line":"        else:"},{"line_number":464,"context_line":"            # Fallback for older client versions"},{"line_number":465,"context_line":"            action_mgr._update(action_mgr._path(action_id), patch)"},{"line_number":466,"context_line":""},{"line_number":467,"context_line":"    @classmethod"},{"line_number":468,"context_line":"    def update(cls, request, action_id, state\u003dNone, reason\u003dNone):"}],"source_content_type":"text/x-python","patch_set":28,"id":"8791f35d_16c918f1","line":465,"range":{"start_line":448,"start_character":3,"end_line":465,"end_character":66},"in_reply_to":"4326a1a1_d2bea0c1","updated":"2025-10-07 08:06:21.000000000","message":"Done","commit_id":"5018a4bb21bf76f6742b33511591cdccba8ca101"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":342,"context_line":"        \"\"\""},{"line_number":343,"context_line":"        # Use SKIP_ACTION microversion if supported to include status_message."},{"line_number":344,"context_line":"        # Fall back to default for older clouds without support."},{"line_number":345,"context_line":"        mv_supported \u003d common_client.is_supported("},{"line_number":346,"context_line":"            common_client.get_server_microversion_range(request),"},{"line_number":347,"context_line":"            common_client.SKIP_ACTION)"},{"line_number":348,"context_line":"        api_version \u003d common_client.SKIP_ACTION if mv_supported else None"},{"line_number":349,"context_line":"        client \u003d watcherclient(request, api_version\u003dapi_version)"},{"line_number":350,"context_line":"        return client.action_plan.get(action_plan_id\u003daction_plan_id)"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    @classmethod"},{"line_number":353,"context_line":"    def delete(cls, request, action_plan_id):"},{"line_number":354,"context_line":"        \"\"\"Delete an action plan"}],"source_content_type":"text/x-python","patch_set":30,"id":"e568ccd1_852c280e","line":351,"range":{"start_line":345,"start_character":0,"end_line":351,"end_character":0},"updated":"2025-10-08 15:08:16.000000000","message":"this is confusing to me, why not always use max supported version instead? we would need to rewrite this method for every new microversion addded in watcher. I think that checking if SKIP_ACTION is supported is valid when you need to decide to display or not an info, or to enable or not the action button...","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":false,"context_lines":[{"line_number":342,"context_line":"        \"\"\""},{"line_number":343,"context_line":"        # Use SKIP_ACTION microversion if supported to include status_message."},{"line_number":344,"context_line":"        # Fall back to default for older clouds without support."},{"line_number":345,"context_line":"        mv_supported \u003d common_client.is_supported("},{"line_number":346,"context_line":"            common_client.get_server_microversion_range(request),"},{"line_number":347,"context_line":"            common_client.SKIP_ACTION)"},{"line_number":348,"context_line":"        api_version \u003d common_client.SKIP_ACTION if mv_supported else None"},{"line_number":349,"context_line":"        client \u003d watcherclient(request, api_version\u003dapi_version)"},{"line_number":350,"context_line":"        return client.action_plan.get(action_plan_id\u003daction_plan_id)"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    @classmethod"},{"line_number":353,"context_line":"    def delete(cls, request, action_plan_id):"},{"line_number":354,"context_line":"        \"\"\"Delete an action plan"}],"source_content_type":"text/x-python","patch_set":30,"id":"8880c979_cd207d59","line":351,"range":{"start_line":345,"start_character":0,"end_line":351,"end_character":0},"in_reply_to":"e568ccd1_852c280e","updated":"2025-10-10 15:10:41.000000000","message":"Done. It Now always uses max supported version (`max_version or \"999\"`) and filters status_message content afterward if the server doesn\u0027t support microversion 1.5. This approach will work for all future microversions without code changes.","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":419,"context_line":"                 the ID"},{"line_number":420,"context_line":"        :rtype:  :py:class:`~.Action`"},{"line_number":421,"context_line":"        \"\"\""},{"line_number":422,"context_line":"        # Use SKIP_ACTION microversion if supported to include status_message."},{"line_number":423,"context_line":"        # Fall back to default for older clouds without support."},{"line_number":424,"context_line":"        mv_supported \u003d common_client.is_supported("},{"line_number":425,"context_line":"            common_client.get_server_microversion_range(request),"},{"line_number":426,"context_line":"            common_client.SKIP_ACTION)"},{"line_number":427,"context_line":"        api_version \u003d common_client.SKIP_ACTION if mv_supported else None"},{"line_number":428,"context_line":"        client \u003d watcherclient(request, api_version\u003dapi_version)"},{"line_number":429,"context_line":"        return client.action.get(action_id\u003daction_id)"},{"line_number":430,"context_line":""},{"line_number":431,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":30,"id":"b47e3f23_c947414c","line":428,"range":{"start_line":422,"start_character":0,"end_line":428,"end_character":64},"updated":"2025-10-08 15:08:16.000000000","message":"same question from ActionPlan get method","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":false,"context_lines":[{"line_number":419,"context_line":"                 the ID"},{"line_number":420,"context_line":"        :rtype:  :py:class:`~.Action`"},{"line_number":421,"context_line":"        \"\"\""},{"line_number":422,"context_line":"        # Use SKIP_ACTION microversion if supported to include status_message."},{"line_number":423,"context_line":"        # Fall back to default for older clouds without support."},{"line_number":424,"context_line":"        mv_supported \u003d common_client.is_supported("},{"line_number":425,"context_line":"            common_client.get_server_microversion_range(request),"},{"line_number":426,"context_line":"            common_client.SKIP_ACTION)"},{"line_number":427,"context_line":"        api_version \u003d common_client.SKIP_ACTION if mv_supported else None"},{"line_number":428,"context_line":"        client \u003d watcherclient(request, api_version\u003dapi_version)"},{"line_number":429,"context_line":"        return client.action.get(action_id\u003daction_id)"},{"line_number":430,"context_line":""},{"line_number":431,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":30,"id":"524c2eab_313129f8","line":428,"range":{"start_line":422,"start_character":0,"end_line":428,"end_character":64},"in_reply_to":"b47e3f23_c947414c","updated":"2025-10-10 15:10:41.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":426,"context_line":"            common_client.SKIP_ACTION)"},{"line_number":427,"context_line":"        api_version \u003d common_client.SKIP_ACTION if mv_supported else None"},{"line_number":428,"context_line":"        client \u003d watcherclient(request, api_version\u003dapi_version)"},{"line_number":429,"context_line":"        return client.action.get(action_id\u003daction_id)"},{"line_number":430,"context_line":""},{"line_number":431,"context_line":"    @classmethod"},{"line_number":432,"context_line":"    def delete(cls, request, action_id):"}],"source_content_type":"text/x-python","patch_set":30,"id":"6712692b_1f09d67a","line":429,"range":{"start_line":429,"start_character":0,"end_line":429,"end_character":53},"updated":"2025-10-08 15:08:16.000000000","message":"So I am back here after looking at other files:\nI think that there is many places that we check if 1.5 is supported, just to show/hide information about status_message.\nI think that we can just:\n1. get server microversion range\n2. call action.get with max supported version\n3. if supported version is \u003c 1.5, you can just set `status_message` to None.\nThis will continue to work for future microversions.\nYou can do the same process in the future for new attributes.","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":true,"context_lines":[{"line_number":426,"context_line":"            common_client.SKIP_ACTION)"},{"line_number":427,"context_line":"        api_version \u003d common_client.SKIP_ACTION if mv_supported else None"},{"line_number":428,"context_line":"        client \u003d watcherclient(request, api_version\u003dapi_version)"},{"line_number":429,"context_line":"        return client.action.get(action_id\u003daction_id)"},{"line_number":430,"context_line":""},{"line_number":431,"context_line":"    @classmethod"},{"line_number":432,"context_line":"    def delete(cls, request, action_id):"}],"source_content_type":"text/x-python","patch_set":30,"id":"854bdbd5_07ac7dbe","line":429,"range":{"start_line":429,"start_character":0,"end_line":429,"end_character":53},"in_reply_to":"6712692b_1f09d67a","updated":"2025-10-10 15:10:41.000000000","message":"Added Both ActionPlan.get() and Action.get() now follow this exact pattern.","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"b054c398e3a7dbacebdd8468a4ff1a8f33f5414e","unresolved":false,"context_lines":[{"line_number":426,"context_line":"            common_client.SKIP_ACTION)"},{"line_number":427,"context_line":"        api_version \u003d common_client.SKIP_ACTION if mv_supported else None"},{"line_number":428,"context_line":"        client \u003d watcherclient(request, api_version\u003dapi_version)"},{"line_number":429,"context_line":"        return client.action.get(action_id\u003daction_id)"},{"line_number":430,"context_line":""},{"line_number":431,"context_line":"    @classmethod"},{"line_number":432,"context_line":"    def delete(cls, request, action_id):"}],"source_content_type":"text/x-python","patch_set":30,"id":"b035015c_8dbe9850","line":429,"range":{"start_line":429,"start_character":0,"end_line":429,"end_character":53},"in_reply_to":"854bdbd5_07ac7dbe","updated":"2025-11-04 12:08:38.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":455,"context_line":"        patch.append({\u0027op\u0027: \u0027replace\u0027, \u0027path\u0027: \u0027/state\u0027, \u0027value\u0027: \u0027PENDING\u0027})"},{"line_number":456,"context_line":"        # Use default microversion for action start"},{"line_number":457,"context_line":"        action_mgr \u003d watcherclient(request, api_version\u003dNone).action"},{"line_number":458,"context_line":"        if hasattr(action_mgr, \u0027update\u0027):"},{"line_number":459,"context_line":"            action_mgr.update(action_id, patch)"},{"line_number":460,"context_line":"        else:"},{"line_number":461,"context_line":"            # Fallback for older client versions"},{"line_number":462,"context_line":"            action_mgr._update(action_mgr._path(action_id), patch)"},{"line_number":463,"context_line":""},{"line_number":464,"context_line":"    @classmethod"},{"line_number":465,"context_line":"    def update(cls, request, action_id, state\u003dNone, reason\u003dNone):"}],"source_content_type":"text/x-python","patch_set":30,"id":"bdb80bc0_a77e56f9","line":462,"range":{"start_line":458,"start_character":0,"end_line":462,"end_character":65},"updated":"2025-10-08 15:08:16.000000000","message":"I don\u0027t think that this is needed, since the requirement makes mandatory client \u003e\u003d4.9\nhttps://review.opendev.org/c/openstack/watcher-dashboard/+/958209/30/requirements.txt#9\nhttps://github.com/openstack/python-watcherclient/blob/4.9.0/watcherclient/v1/action.py#L87","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"b054c398e3a7dbacebdd8468a4ff1a8f33f5414e","unresolved":false,"context_lines":[{"line_number":455,"context_line":"        patch.append({\u0027op\u0027: \u0027replace\u0027, \u0027path\u0027: \u0027/state\u0027, \u0027value\u0027: \u0027PENDING\u0027})"},{"line_number":456,"context_line":"        # Use default microversion for action start"},{"line_number":457,"context_line":"        action_mgr \u003d watcherclient(request, api_version\u003dNone).action"},{"line_number":458,"context_line":"        if hasattr(action_mgr, \u0027update\u0027):"},{"line_number":459,"context_line":"            action_mgr.update(action_id, patch)"},{"line_number":460,"context_line":"        else:"},{"line_number":461,"context_line":"            # Fallback for older client versions"},{"line_number":462,"context_line":"            action_mgr._update(action_mgr._path(action_id), patch)"},{"line_number":463,"context_line":""},{"line_number":464,"context_line":"    @classmethod"},{"line_number":465,"context_line":"    def update(cls, request, action_id, state\u003dNone, reason\u003dNone):"}],"source_content_type":"text/x-python","patch_set":30,"id":"121df559_3db5a9c5","line":462,"range":{"start_line":458,"start_character":0,"end_line":462,"end_character":65},"in_reply_to":"bdb80bc0_a77e56f9","updated":"2025-11-04 12:08:38.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":482,"context_line":"        patch \u003d []"},{"line_number":483,"context_line":"        if state is not None:"},{"line_number":484,"context_line":"            patch.append({\u0027op\u0027: \u0027replace\u0027, \u0027path\u0027: \u0027/state\u0027, \u0027value\u0027: state})"},{"line_number":485,"context_line":"        if reason:"},{"line_number":486,"context_line":"            patch.append({\u0027op\u0027: \u0027replace\u0027, \u0027path\u0027: \u0027/status_message\u0027,"},{"line_number":487,"context_line":"                          \u0027value\u0027: reason})"},{"line_number":488,"context_line":"        # Use SKIP_ACTION when supported; otherwise default. Gracefully no-op"}],"source_content_type":"text/x-python","patch_set":30,"id":"b3574730_2dcf4f84","line":485,"range":{"start_line":485,"start_character":11,"end_line":485,"end_character":17},"updated":"2025-10-08 15:08:16.000000000","message":"Do we support empty string in reason? If yes, we need to fix here","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":false,"context_lines":[{"line_number":482,"context_line":"        patch \u003d []"},{"line_number":483,"context_line":"        if state is not None:"},{"line_number":484,"context_line":"            patch.append({\u0027op\u0027: \u0027replace\u0027, \u0027path\u0027: \u0027/state\u0027, \u0027value\u0027: state})"},{"line_number":485,"context_line":"        if reason:"},{"line_number":486,"context_line":"            patch.append({\u0027op\u0027: \u0027replace\u0027, \u0027path\u0027: \u0027/status_message\u0027,"},{"line_number":487,"context_line":"                          \u0027value\u0027: reason})"},{"line_number":488,"context_line":"        # Use SKIP_ACTION when supported; otherwise default. Gracefully no-op"}],"source_content_type":"text/x-python","patch_set":30,"id":"bc23d1a2_7624b907","line":485,"range":{"start_line":485,"start_character":11,"end_line":485,"end_character":17},"in_reply_to":"b3574730_2dcf4f84","updated":"2025-10-10 15:10:41.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":499,"context_line":"            return None"},{"line_number":500,"context_line":"        mv \u003d common_client.SKIP_ACTION if mv_supported else None"},{"line_number":501,"context_line":"        try:"},{"line_number":502,"context_line":"            action_mgr \u003d watcherclient(request, api_version\u003dmv).action"},{"line_number":503,"context_line":"            if hasattr(action_mgr, \u0027update\u0027):"},{"line_number":504,"context_line":"                return action_mgr.update(action_id, patch)"},{"line_number":505,"context_line":"            return action_mgr._update(action_mgr._path(action_id), patch)"}],"source_content_type":"text/x-python","patch_set":30,"id":"33cb4f54_575d78b6","line":502,"range":{"start_line":502,"start_character":12,"end_line":502,"end_character":70},"updated":"2025-10-08 15:08:16.000000000","message":"I think that we are creating a more complex code that is actually needed. I think that we need to validate if SKIP_ACTION is supported or not to just to accept/deny \u0027reason\u0027 attribute.\nWe could default this update call to always the server\u0027s max supported api version.","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":false,"context_lines":[{"line_number":499,"context_line":"            return None"},{"line_number":500,"context_line":"        mv \u003d common_client.SKIP_ACTION if mv_supported else None"},{"line_number":501,"context_line":"        try:"},{"line_number":502,"context_line":"            action_mgr \u003d watcherclient(request, api_version\u003dmv).action"},{"line_number":503,"context_line":"            if hasattr(action_mgr, \u0027update\u0027):"},{"line_number":504,"context_line":"                return action_mgr.update(action_id, patch)"},{"line_number":505,"context_line":"            return action_mgr._update(action_mgr._path(action_id), patch)"}],"source_content_type":"text/x-python","patch_set":30,"id":"bba902c9_40f9802b","line":502,"range":{"start_line":502,"start_character":12,"end_line":502,"end_character":70},"in_reply_to":"33cb4f54_575d78b6","updated":"2025-10-10 15:10:41.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"ff3e1932fb664ac55704c0274b88791fa87b8f63","unresolved":true,"context_lines":[{"line_number":479,"context_line":"            action_id\u003daction_id)"},{"line_number":480,"context_line":""},{"line_number":481,"context_line":"    @classmethod"},{"line_number":482,"context_line":"    def start(cls, request, action_id):"},{"line_number":483,"context_line":"        \"\"\"Start an Action Plan"},{"line_number":484,"context_line":""},{"line_number":485,"context_line":"        :param request: request object"}],"source_content_type":"text/x-python","patch_set":37,"id":"01eea6e7_2f379c5b","line":482,"updated":"2026-02-18 14:06:01.000000000","message":"Actions can not be started and action status can not be set to PENDING. I think this method can be removed.","commit_id":"35ea4c9800470864148288cc7860b439788069ec"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"8a12529de0fc36b4ef1bab742369e4f0d8cf9c15","unresolved":false,"context_lines":[{"line_number":479,"context_line":"            action_id\u003daction_id)"},{"line_number":480,"context_line":""},{"line_number":481,"context_line":"    @classmethod"},{"line_number":482,"context_line":"    def start(cls, request, action_id):"},{"line_number":483,"context_line":"        \"\"\"Start an Action Plan"},{"line_number":484,"context_line":""},{"line_number":485,"context_line":"        :param request: request object"}],"source_content_type":"text/x-python","patch_set":37,"id":"b04894a4_4af69242","line":482,"in_reply_to":"01eea6e7_2f379c5b","updated":"2026-02-22 07:42:53.000000000","message":"Done","commit_id":"35ea4c9800470864148288cc7860b439788069ec"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cf5770ef24939fbdc459a03a9b1bc6d75d2c0ac8","unresolved":true,"context_lines":[{"line_number":367,"context_line":"                with suppress(TypeError):"},{"line_number":368,"context_line":"                    action_plan[\u0027status_message\u0027] \u003d None"},{"line_number":369,"context_line":""},{"line_number":370,"context_line":"        return action_plan"},{"line_number":371,"context_line":""},{"line_number":372,"context_line":"    @classmethod"},{"line_number":373,"context_line":"    def delete(cls, request, action_plan_id):"}],"source_content_type":"text/x-python","patch_set":40,"id":"6b41ebcc_b5a0f0c3","line":370,"updated":"2026-02-25 18:30:48.000000000","message":"i have given this feedback before\n\nhttps://review.opendev.org/c/openstack/watcher-dashboard/+/957232/comment/0b4c2ae2_c693a41d/\nall the methods in this module should take the micoversion as a pramter\n\ncalulating the newest avialbel like this is not correct.\n\nit might work but it will brak if we remove status metod or similar in a new one.","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ffff5a8378c3a631db8e5ff1502fcb009d4330d5","unresolved":true,"context_lines":[{"line_number":367,"context_line":"                with suppress(TypeError):"},{"line_number":368,"context_line":"                    action_plan[\u0027status_message\u0027] \u003d None"},{"line_number":369,"context_line":""},{"line_number":370,"context_line":"        return action_plan"},{"line_number":371,"context_line":""},{"line_number":372,"context_line":"    @classmethod"},{"line_number":373,"context_line":"    def delete(cls, request, action_plan_id):"}],"source_content_type":"text/x-python","patch_set":40,"id":"c6a3b0d3_e632adc4","line":370,"in_reply_to":"6b41ebcc_b5a0f0c3","updated":"2026-02-26 15:18:26.000000000","message":"I might have missed it during addressing multiple comments, Fixed it now.","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cf5770ef24939fbdc459a03a9b1bc6d75d2c0ac8","unresolved":true,"context_lines":[{"line_number":495,"context_line":"        :rtype:  :py:class:`~.Action` or None"},{"line_number":496,"context_line":"        \"\"\""},{"line_number":497,"context_line":"        if state is None and reason is None:"},{"line_number":498,"context_line":"            raise ValueError(\"Either \u0027state\u0027 or \u0027reason\u0027 must be provided\")"},{"line_number":499,"context_line":""},{"line_number":500,"context_line":"        patch \u003d []"},{"line_number":501,"context_line":"        if state is not None:"}],"source_content_type":"text/x-python","patch_set":40,"id":"557ec5af_02152bca","line":498,"range":{"start_line":498,"start_character":18,"end_line":498,"end_character":28},"updated":"2026-02-25 18:30:48.000000000","message":"this is not really ideal. we shoudl genrally avodi raising generic errors like value error and prefer having our own typed expctions.","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ffff5a8378c3a631db8e5ff1502fcb009d4330d5","unresolved":true,"context_lines":[{"line_number":495,"context_line":"        :rtype:  :py:class:`~.Action` or None"},{"line_number":496,"context_line":"        \"\"\""},{"line_number":497,"context_line":"        if state is None and reason is None:"},{"line_number":498,"context_line":"            raise ValueError(\"Either \u0027state\u0027 or \u0027reason\u0027 must be provided\")"},{"line_number":499,"context_line":""},{"line_number":500,"context_line":"        patch \u003d []"},{"line_number":501,"context_line":"        if state is not None:"}],"source_content_type":"text/x-python","patch_set":40,"id":"8a3cdf13_32e66bdd","line":498,"range":{"start_line":498,"start_character":18,"end_line":498,"end_character":28},"in_reply_to":"557ec5af_02152bca","updated":"2026-02-26 15:18:26.000000000","message":"There is some still left, I will address that.","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cf5770ef24939fbdc459a03a9b1bc6d75d2c0ac8","unresolved":true,"context_lines":[{"line_number":523,"context_line":"                request, api_version\u003dmax_version or common_client.MIN_DEFAULT"},{"line_number":524,"context_line":"            ).action"},{"line_number":525,"context_line":"            return action_mgr.update(action_id, patch)"},{"line_number":526,"context_line":"        except Exception as e:"},{"line_number":527,"context_line":"            error_msg \u003d str(e).lower()"},{"line_number":528,"context_line":"            if \"method not allowed\" in error_msg or \"405\" in error_msg:"},{"line_number":529,"context_line":"                LOG.info("}],"source_content_type":"text/x-python","patch_set":40,"id":"7be1af6b_37e33dca","line":526,"range":{"start_line":526,"start_character":15,"end_line":526,"end_character":24},"updated":"2026-02-25 18:30:48.000000000","message":"you shoudl also genreally avoid cachtion excption like this.","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"72a2089ade5b16ecb858dfe4a819221f7257eeac","unresolved":true,"context_lines":[{"line_number":439,"context_line":""},{"line_number":440,"context_line":"    @classmethod"},{"line_number":441,"context_line":"    def update(cls, request, action_id, state\u003dNone, reason\u003dNone,"},{"line_number":442,"context_line":"               api_version\u003dcommon_client.SKIP_ACTION):"},{"line_number":443,"context_line":"        \"\"\"Update an action\u0027s state and/or status message."},{"line_number":444,"context_line":""},{"line_number":445,"context_line":"        :param request: request object"}],"source_content_type":"text/x-python","patch_set":44,"id":"3336e3e6_1a900927","line":442,"range":{"start_line":442,"start_character":27,"end_line":442,"end_character":52},"updated":"2026-02-26 20:02:33.000000000","message":"you shoudl not be encodeing the default in the funtio ndefintions\nyou should be passing them in teh function call sites.\n\napi version here and above should be  api_version\u003dNone","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"a34cbf1cd07b2a57b758783f1eba4945f418c09e","unresolved":false,"context_lines":[{"line_number":439,"context_line":""},{"line_number":440,"context_line":"    @classmethod"},{"line_number":441,"context_line":"    def update(cls, request, action_id, state\u003dNone, reason\u003dNone,"},{"line_number":442,"context_line":"               api_version\u003dcommon_client.SKIP_ACTION):"},{"line_number":443,"context_line":"        \"\"\"Update an action\u0027s state and/or status message."},{"line_number":444,"context_line":""},{"line_number":445,"context_line":"        :param request: request object"}],"source_content_type":"text/x-python","patch_set":44,"id":"d984690f_bbd9bf15","line":442,"range":{"start_line":442,"start_character":27,"end_line":442,"end_character":52},"in_reply_to":"3336e3e6_1a900927","updated":"2026-03-03 07:36:49.000000000","message":"Done","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"}],"watcher_dashboard/common/client.py":[{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"747d896fa56d5a3e222e4992fcc43042981b1dd2","unresolved":true,"context_lines":[{"line_number":95,"context_line":""},{"line_number":96,"context_line":"        verify \u003d False if insecure else (ca_file or True)"},{"line_number":97,"context_line":"        timeout \u003d getattr(settings, \u0027WATCHER_API_TIMEOUT\u0027, 5)"},{"line_number":98,"context_line":"        resp \u003d requests.get("},{"line_number":99,"context_line":"            endpoint, headers\u003dheaders, verify\u003dverify, timeout\u003dtimeout)"},{"line_number":100,"context_line":"        if 200 \u003c\u003d resp.status_code \u003c 300:"},{"line_number":101,"context_line":"            result \u003d ("},{"line_number":102,"context_line":"                resp.headers.get(\u0027OpenStack-API-Minimum-Version\u0027),"},{"line_number":103,"context_line":"                resp.headers.get(\u0027OpenStack-API-Maximum-Version\u0027),"},{"line_number":104,"context_line":"            )"},{"line_number":105,"context_line":"        else:"},{"line_number":106,"context_line":"            # Treat auth/not-found and other non-2xx as unknown"},{"line_number":107,"context_line":"            LOG.debug("}],"source_content_type":"text/x-python","patch_set":29,"id":"09861bd9_e5ac6d50","line":104,"range":{"start_line":98,"start_character":0,"end_line":104,"end_character":13},"updated":"2025-10-03 08:14:40.000000000","message":"This is actually not working properly. The call to the bare endpoint is not returning headers in the headers. The headers response to a call to `https://watcher-public-openstack.apps-crc.testing` i.e. returns:\n\n```\n{\u0027date\u0027: \u0027Fri, 03 Oct 2025 07:42:04 GMT\u0027, \n \u0027server\u0027: \u0027Apache\u0027,\n \u0027content-length\u0027: \u0027536\u0027,\n \u0027content-type\u0027: \u0027application/json\u0027,\n \u0027set-cookie\u0027: \u00270a98f3d612a3c8fda809da40f2e41782\u003dc2326a1b4eba8a80614bd0860215fbc7; path\u003d/; HttpOnly; Secure; SameSite\u003dNone\u0027}\n```\n\nWhile a call to https://watcher-public-openstack.apps-crc.testing/v1/, i.e. returns the expected api versions in the headers:\n\n```\n{\u0027date\u0027: \u0027Fri, 03 Oct 2025 07:50:29 GMT\u0027,\n \u0027server\u0027: \u0027Apache\u0027,\n \u0027content-length\u0027: \u00276634\u0027,\n \u0027vary\u0027: \u0027OpenStack-API-Version\u0027,\n \u0027openstack-api-minimum-version\u0027: \u00271.0\u0027,\n \u0027openstack-api-maximum-version\u0027: \u00271.4\u0027,\n \u0027openstack-api-version\u0027: \u0027infra-optim 1.0\u0027,\n \u0027content-type\u0027: \u0027application/json\u0027,\n \u0027set-cookie\u0027: \u00270a98f3d612a3c8fda809da40f2e41782\u003dc2326a1b4eba8a80614bd0860215fbc7; path\u003d/; HttpOnly; Secure; SameSite\u003dNone\u0027}\n```\n\nI see two options:\n\n1.- doing the call to /v1 url and keep using headers to get min and max versions\n2.- keep using the same url for the get but get min and max versions from the body instead of the headers. See the result of a get on it:\n\n```\n$ curl -g -i -X GET https://watcher-public-openstack.apps-crc.testing/ -H \"Accept: application/json\" -H \"Content-Type: application/json\" -H \"OpenStack-API-Version: infra-optim 1.4\" -H \"User-Agent: python-watcherclient\" -H \"X-Auth-Token: gAAAAABo33-TmRLUqI3tEBvgh7Kmkv-GYcHVaRju879tpq7QLo9_rM5EQ5kYFwTyJXnMuBvH_TILgSPdnsQcvykNcwAa9QE2wgjTZi-RsKAoregFf3QTLI6WBx7dO9m3454GRZYQo4rSrQof2tzCtQd13xlx0FUT9KlNohDrtlGShtGFsCfXPmk\"\nHTTP/1.1 200 OK\ndate: Fri, 03 Oct 2025 07:59:41 GMT\nserver: Apache\ncontent-length: 536\ncontent-type: application/json\nset-cookie: 0a98f3d612a3c8fda809da40f2e41782\u003dc2326a1b4eba8a80614bd0860215fbc7; path\u003d/; HttpOnly; Secure; SameSite\u003dNone\n\n{\"name\": \"OpenStack Watcher API\", \"description\": \"Watcher is an OpenStack project which aims to improve physical resources usage through better VM placement.\", \"versions\": [{\"id\": \"v1\", \"status\": \"CURRENT\", \"max_version\": \"1.4\", \"min_version\": \"1.0\", \"links\": [{\"href\": \"https://watcher-public-openstack.apps-crc.testing/v1/\", \"rel\": \"self\"}]}], \"default_version\": {\"id\": \"v1\", \"status\": \"CURRENT\", \"max_version\": \"1.4\", \"min_version\": \"1.0\", \"links\": [{\"href\": \"https://watcher-public-openstack.apps-crc.testing/v1/\", \"rel\": \"self\"}]}}\n```\n\nnote `\"versions\": [{\"id\": \"v1\", \"status\": \"CURRENT\", \"max_version\": \"1.4\", \"min_version\": \"1.0\",`\n\n\nNote this works when having 1.5 because when versions are not found, is_supported returns True (that\u0027s a separate issue):\n\n```\n\u003e\u003e\u003e is_supported((None, None), \u00271.5\u0027)\nTrue\n```","commit_id":"00b0ad0ece0e7c73cb31747920bf45073d105870"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"8187d3b182dd4b6555558df211c6a799572f622f","unresolved":true,"context_lines":[{"line_number":95,"context_line":""},{"line_number":96,"context_line":"        verify \u003d False if insecure else (ca_file or True)"},{"line_number":97,"context_line":"        timeout \u003d getattr(settings, \u0027WATCHER_API_TIMEOUT\u0027, 5)"},{"line_number":98,"context_line":"        resp \u003d requests.get("},{"line_number":99,"context_line":"            endpoint, headers\u003dheaders, verify\u003dverify, timeout\u003dtimeout)"},{"line_number":100,"context_line":"        if 200 \u003c\u003d resp.status_code \u003c 300:"},{"line_number":101,"context_line":"            result \u003d ("},{"line_number":102,"context_line":"                resp.headers.get(\u0027OpenStack-API-Minimum-Version\u0027),"},{"line_number":103,"context_line":"                resp.headers.get(\u0027OpenStack-API-Maximum-Version\u0027),"},{"line_number":104,"context_line":"            )"},{"line_number":105,"context_line":"        else:"},{"line_number":106,"context_line":"            # Treat auth/not-found and other non-2xx as unknown"},{"line_number":107,"context_line":"            LOG.debug("}],"source_content_type":"text/x-python","patch_set":29,"id":"9c13757d_cd22cdb5","line":104,"range":{"start_line":98,"start_character":0,"end_line":104,"end_character":13},"in_reply_to":"09861bd9_e5ac6d50","updated":"2025-10-06 07:05:41.000000000","message":"Thank you for sharing the options here and examples. Went with option 2.","commit_id":"00b0ad0ece0e7c73cb31747920bf45073d105870"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"b6488e35e0e73ffb0f1cd36e5e705843412b0b5d","unresolved":false,"context_lines":[{"line_number":95,"context_line":""},{"line_number":96,"context_line":"        verify \u003d False if insecure else (ca_file or True)"},{"line_number":97,"context_line":"        timeout \u003d getattr(settings, \u0027WATCHER_API_TIMEOUT\u0027, 5)"},{"line_number":98,"context_line":"        resp \u003d requests.get("},{"line_number":99,"context_line":"            endpoint, headers\u003dheaders, verify\u003dverify, timeout\u003dtimeout)"},{"line_number":100,"context_line":"        if 200 \u003c\u003d resp.status_code \u003c 300:"},{"line_number":101,"context_line":"            result \u003d ("},{"line_number":102,"context_line":"                resp.headers.get(\u0027OpenStack-API-Minimum-Version\u0027),"},{"line_number":103,"context_line":"                resp.headers.get(\u0027OpenStack-API-Maximum-Version\u0027),"},{"line_number":104,"context_line":"            )"},{"line_number":105,"context_line":"        else:"},{"line_number":106,"context_line":"            # Treat auth/not-found and other non-2xx as unknown"},{"line_number":107,"context_line":"            LOG.debug("}],"source_content_type":"text/x-python","patch_set":29,"id":"c3fcd7ae_7b3e9f18","line":104,"range":{"start_line":98,"start_character":0,"end_line":104,"end_character":13},"in_reply_to":"9c13757d_cd22cdb5","updated":"2025-10-07 08:06:21.000000000","message":"Acknowledged","commit_id":"00b0ad0ece0e7c73cb31747920bf45073d105870"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"747d896fa56d5a3e222e4992fcc43042981b1dd2","unresolved":true,"context_lines":[{"line_number":127,"context_line":"        return True"},{"line_number":128,"context_line":"    min_ver, max_ver \u003d mv_range"},{"line_number":129,"context_line":"    if max_ver is None:"},{"line_number":130,"context_line":"        return True"},{"line_number":131,"context_line":"    req_t \u003d _to_version_tuple(required)"},{"line_number":132,"context_line":"    min_t \u003d ("},{"line_number":133,"context_line":"        _to_version_tuple(min_ver)"}],"source_content_type":"text/x-python","patch_set":29,"id":"64a87e0f_75b2739e","line":130,"range":{"start_line":130,"start_character":0,"end_line":130,"end_character":2},"updated":"2025-10-03 08:14:40.000000000","message":"I\u0027m not sure if defaulting to true is good, is this to cover the case where max is set to `latest`?, see what i mentioned before, in case versions are not properly found this makes is_supported to return true:\n\n```\n\u003e\u003e\u003e is_supported((None, None), \u00271.7\u0027)\nTrue\n```\n\nMaybe we should treat latest specifically and defalut to false.","commit_id":"00b0ad0ece0e7c73cb31747920bf45073d105870"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"b6488e35e0e73ffb0f1cd36e5e705843412b0b5d","unresolved":false,"context_lines":[{"line_number":127,"context_line":"        return True"},{"line_number":128,"context_line":"    min_ver, max_ver \u003d mv_range"},{"line_number":129,"context_line":"    if max_ver is None:"},{"line_number":130,"context_line":"        return True"},{"line_number":131,"context_line":"    req_t \u003d _to_version_tuple(required)"},{"line_number":132,"context_line":"    min_t \u003d ("},{"line_number":133,"context_line":"        _to_version_tuple(min_ver)"}],"source_content_type":"text/x-python","patch_set":29,"id":"28c0114c_11e5227b","line":130,"range":{"start_line":130,"start_character":0,"end_line":130,"end_character":2},"in_reply_to":"01ab14c6_417a02df","updated":"2025-10-07 08:06:21.000000000","message":"Acknowledged","commit_id":"00b0ad0ece0e7c73cb31747920bf45073d105870"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"8187d3b182dd4b6555558df211c6a799572f622f","unresolved":true,"context_lines":[{"line_number":127,"context_line":"        return True"},{"line_number":128,"context_line":"    min_ver, max_ver \u003d mv_range"},{"line_number":129,"context_line":"    if max_ver is None:"},{"line_number":130,"context_line":"        return True"},{"line_number":131,"context_line":"    req_t \u003d _to_version_tuple(required)"},{"line_number":132,"context_line":"    min_t \u003d ("},{"line_number":133,"context_line":"        _to_version_tuple(min_ver)"}],"source_content_type":"text/x-python","patch_set":29,"id":"01ab14c6_417a02df","line":130,"range":{"start_line":130,"start_character":0,"end_line":130,"end_character":2},"in_reply_to":"64a87e0f_75b2739e","updated":"2025-10-06 07:05:41.000000000","message":"Fixed now.","commit_id":"00b0ad0ece0e7c73cb31747920bf45073d105870"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":61,"context_line":"        return (1, 0)"},{"line_number":62,"context_line":"    try:"},{"line_number":63,"context_line":"        major, minor \u003d value.split(\u0027.\u0027)"},{"line_number":64,"context_line":"        return (int(major), int(minor) if minor !\u003d \u0027latest\u0027 else 10**9)"},{"line_number":65,"context_line":"    except Exception:"},{"line_number":66,"context_line":"        return (1, 0)"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"fe92f32c_0ba24ac8","line":64,"range":{"start_line":64,"start_character":65,"end_line":64,"end_character":70},"updated":"2025-10-08 15:08:16.000000000","message":"I think that \"999\" is the value usually used for latest.","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"b054c398e3a7dbacebdd8468a4ff1a8f33f5414e","unresolved":true,"context_lines":[{"line_number":61,"context_line":"        return (1, 0)"},{"line_number":62,"context_line":"    try:"},{"line_number":63,"context_line":"        major, minor \u003d value.split(\u0027.\u0027)"},{"line_number":64,"context_line":"        return (int(major), int(minor) if minor !\u003d \u0027latest\u0027 else 10**9)"},{"line_number":65,"context_line":"    except Exception:"},{"line_number":66,"context_line":"        return (1, 0)"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"eb76699f_7fe0637c","line":64,"range":{"start_line":64,"start_character":65,"end_line":64,"end_character":70},"in_reply_to":"cd789001_0b014403","updated":"2025-11-04 12:08:38.000000000","message":"I think that i wasn\u0027t clear enough in previous comment. If minor \u003d\u003d \u0027latest\u0027 you can use 999 instead of 10**9. But you may want to  still compare with \"latest\" string. Not sure if this is being used in the dashboard in the end","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7e8de1f232fef1b8641dee1a78bc3f273a5658db","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        return (1, 0)"},{"line_number":62,"context_line":"    try:"},{"line_number":63,"context_line":"        major, minor \u003d value.split(\u0027.\u0027)"},{"line_number":64,"context_line":"        return (int(major), int(minor) if minor !\u003d \u0027latest\u0027 else 10**9)"},{"line_number":65,"context_line":"    except Exception:"},{"line_number":66,"context_line":"        return (1, 0)"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"47431592_77a6868a","line":64,"range":{"start_line":64,"start_character":65,"end_line":64,"end_character":70},"in_reply_to":"eb76699f_7fe0637c","updated":"2025-11-06 05:15:53.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":true,"context_lines":[{"line_number":61,"context_line":"        return (1, 0)"},{"line_number":62,"context_line":"    try:"},{"line_number":63,"context_line":"        major, minor \u003d value.split(\u0027.\u0027)"},{"line_number":64,"context_line":"        return (int(major), int(minor) if minor !\u003d \u0027latest\u0027 else 10**9)"},{"line_number":65,"context_line":"    except Exception:"},{"line_number":66,"context_line":"        return (1, 0)"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"cd789001_0b014403","line":64,"range":{"start_line":64,"start_character":65,"end_line":64,"end_character":70},"in_reply_to":"fe92f32c_0ba24ac8","updated":"2025-10-10 15:10:41.000000000","message":"Now using 999 for latest check","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":70,"context_line":"    \"\"\"Discover server (min, max) microversions with per-request caching."},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    Caches on request as `_watcher_microversion_range` (preferred) and reads"},{"line_number":73,"context_line":"    legacy `_watcher_mv_range` for backward compatibility."},{"line_number":74,"context_line":"    \"\"\""},{"line_number":75,"context_line":"    cached \u003d getattr(request, \u0027_watcher_microversion_range\u0027, None)"},{"line_number":76,"context_line":"    if cached is None:"}],"source_content_type":"text/x-python","patch_set":30,"id":"89b5132a_c124a160","line":73,"range":{"start_line":73,"start_character":0,"end_line":73,"end_character":58},"updated":"2025-10-08 15:08:16.000000000","message":"IIUC you can just ignore _watcher_mv_range, if it will only trigger another version request. By reading/writing both, we will never get rid of one of them?","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    \"\"\"Discover server (min, max) microversions with per-request caching."},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    Caches on request as `_watcher_microversion_range` (preferred) and reads"},{"line_number":73,"context_line":"    legacy `_watcher_mv_range` for backward compatibility."},{"line_number":74,"context_line":"    \"\"\""},{"line_number":75,"context_line":"    cached \u003d getattr(request, \u0027_watcher_microversion_range\u0027, None)"},{"line_number":76,"context_line":"    if cached is None:"}],"source_content_type":"text/x-python","patch_set":30,"id":"f82a697d_1359fbfc","line":73,"range":{"start_line":73,"start_character":0,"end_line":73,"end_character":58},"in_reply_to":"89b5132a_c124a160","updated":"2025-10-10 15:10:41.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"        insecure \u003d getattr(settings, \u0027OPENSTACK_SSL_NO_VERIFY\u0027, False)"},{"line_number":87,"context_line":"        ca_file \u003d getattr(settings, \u0027OPENSTACK_SSL_CACERT\u0027, None)"},{"line_number":88,"context_line":"        token \u003d getattr(getattr(request, \u0027user\u0027, None), \u0027token\u0027, None)"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"        headers \u003d {}"},{"line_number":91,"context_line":"        if token and getattr(token, \u0027id\u0027, None):"},{"line_number":92,"context_line":"            headers[\u0027X-Auth-Token\u0027] \u003d token.id"},{"line_number":93,"context_line":"        # Hint API to respond with version range headers"},{"line_number":94,"context_line":"        headers.setdefault(\u0027OpenStack-API-Version\u0027, f\u0027{_HEADER_SERVICE} 1.0\u0027)"}],"source_content_type":"text/x-python","patch_set":30,"id":"2860dbc3_50bc79f9","line":91,"range":{"start_line":88,"start_character":5,"end_line":91,"end_character":48},"updated":"2025-10-08 15:08:16.000000000","message":"request.user.token.id is directly accessed in other places in the code, do we need these multiple getattr?","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":false,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"        insecure \u003d getattr(settings, \u0027OPENSTACK_SSL_NO_VERIFY\u0027, False)"},{"line_number":87,"context_line":"        ca_file \u003d getattr(settings, \u0027OPENSTACK_SSL_CACERT\u0027, None)"},{"line_number":88,"context_line":"        token \u003d getattr(getattr(request, \u0027user\u0027, None), \u0027token\u0027, None)"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"        headers \u003d {}"},{"line_number":91,"context_line":"        if token and getattr(token, \u0027id\u0027, None):"},{"line_number":92,"context_line":"            headers[\u0027X-Auth-Token\u0027] \u003d token.id"},{"line_number":93,"context_line":"        # Hint API to respond with version range headers"},{"line_number":94,"context_line":"        headers.setdefault(\u0027OpenStack-API-Version\u0027, f\u0027{_HEADER_SERVICE} 1.0\u0027)"}],"source_content_type":"text/x-python","patch_set":30,"id":"bb6ff6b5_2564f287","line":91,"range":{"start_line":88,"start_character":5,"end_line":91,"end_character":48},"in_reply_to":"2860dbc3_50bc79f9","updated":"2025-10-10 15:10:41.000000000","message":"my bad, fixed it now.","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":123,"context_line":"    except Exception as exc:"},{"line_number":124,"context_line":"        LOG.debug(\u0027Microversion discovery failed: %s\u0027, exc)"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"    setattr(request, \u0027_watcher_microversion_range\u0027, result)"},{"line_number":127,"context_line":"    # Also set legacy name for any other code paths in this request"},{"line_number":128,"context_line":"    setattr(request, \u0027_watcher_mv_range\u0027, result)"},{"line_number":129,"context_line":"    return result"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"a6cab8ee_68e9d1c2","line":128,"range":{"start_line":126,"start_character":0,"end_line":128,"end_character":49},"updated":"2025-10-08 15:08:16.000000000","message":"we may need to find a better way to do this instead of setattr, with a guarantee that this always exist and defaults to None?","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"b054c398e3a7dbacebdd8468a4ff1a8f33f5414e","unresolved":false,"context_lines":[{"line_number":123,"context_line":"    except Exception as exc:"},{"line_number":124,"context_line":"        LOG.debug(\u0027Microversion discovery failed: %s\u0027, exc)"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"    setattr(request, \u0027_watcher_microversion_range\u0027, result)"},{"line_number":127,"context_line":"    # Also set legacy name for any other code paths in this request"},{"line_number":128,"context_line":"    setattr(request, \u0027_watcher_mv_range\u0027, result)"},{"line_number":129,"context_line":"    return result"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"3d76f684_c7202262","line":128,"range":{"start_line":126,"start_character":0,"end_line":128,"end_character":49},"in_reply_to":"8c247f5c_8b213450","updated":"2025-11-04 12:08:38.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":true,"context_lines":[{"line_number":123,"context_line":"    except Exception as exc:"},{"line_number":124,"context_line":"        LOG.debug(\u0027Microversion discovery failed: %s\u0027, exc)"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"    setattr(request, \u0027_watcher_microversion_range\u0027, result)"},{"line_number":127,"context_line":"    # Also set legacy name for any other code paths in this request"},{"line_number":128,"context_line":"    setattr(request, \u0027_watcher_mv_range\u0027, result)"},{"line_number":129,"context_line":"    return result"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"8c247f5c_8b213450","line":128,"range":{"start_line":126,"start_character":0,"end_line":128,"end_character":49},"in_reply_to":"a6cab8ee_68e9d1c2","updated":"2025-10-10 15:10:41.000000000","message":"Replaced setattr with direct attribute assignment (`request._watcher_microversion_range \u003d result`)","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":137,"context_line":"    avoid masking discovery failures."},{"line_number":138,"context_line":"    \"\"\""},{"line_number":139,"context_line":"    # Handle \u0027latest\u0027 as a special case - always supported"},{"line_number":140,"context_line":"    if required \u003d\u003d \u0027latest\u0027:"},{"line_number":141,"context_line":"        return True"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"    # If version discovery failed, default to False"},{"line_number":144,"context_line":"    if not mv_range:"}],"source_content_type":"text/x-python","patch_set":30,"id":"c581c7fd_5ae16502","line":141,"range":{"start_line":140,"start_character":0,"end_line":141,"end_character":19},"updated":"2025-10-08 15:08:16.000000000","message":"not sure if this makes sense. if a server supports latest microversion? not sure which part of the code will ask if \u0027latest\u0027 is supported. You usually want to know if a specific api_version is supported by the server, like \u00271.5\u0027","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"b054c398e3a7dbacebdd8468a4ff1a8f33f5414e","unresolved":false,"context_lines":[{"line_number":137,"context_line":"    avoid masking discovery failures."},{"line_number":138,"context_line":"    \"\"\""},{"line_number":139,"context_line":"    # Handle \u0027latest\u0027 as a special case - always supported"},{"line_number":140,"context_line":"    if required \u003d\u003d \u0027latest\u0027:"},{"line_number":141,"context_line":"        return True"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"    # If version discovery failed, default to False"},{"line_number":144,"context_line":"    if not mv_range:"}],"source_content_type":"text/x-python","patch_set":30,"id":"4a4981b5_65cd5a30","line":141,"range":{"start_line":140,"start_character":0,"end_line":141,"end_character":19},"in_reply_to":"42f7f542_ac312b81","updated":"2025-11-04 12:08:38.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":true,"context_lines":[{"line_number":137,"context_line":"    avoid masking discovery failures."},{"line_number":138,"context_line":"    \"\"\""},{"line_number":139,"context_line":"    # Handle \u0027latest\u0027 as a special case - always supported"},{"line_number":140,"context_line":"    if required \u003d\u003d \u0027latest\u0027:"},{"line_number":141,"context_line":"        return True"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"    # If version discovery failed, default to False"},{"line_number":144,"context_line":"    if not mv_range:"}],"source_content_type":"text/x-python","patch_set":30,"id":"42f7f542_ac312b81","line":141,"range":{"start_line":140,"start_character":0,"end_line":141,"end_character":19},"in_reply_to":"c581c7fd_5ae16502","updated":"2025-10-10 15:10:41.000000000","message":"dropped the special case for latest","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"b054c398e3a7dbacebdd8468a4ff1a8f33f5414e","unresolved":true,"context_lines":[{"line_number":114,"context_line":"                if min_hdr or max_hdr:"},{"line_number":115,"context_line":"                    result \u003d (min_hdr, max_hdr)"},{"line_number":116,"context_line":"        else:"},{"line_number":117,"context_line":"            LOG.debug(\u0027MV discovery status\u003d%s for %s\u0027,"},{"line_number":118,"context_line":"                      resp.status_code, endpoint)"},{"line_number":119,"context_line":"    except Exception as exc:"},{"line_number":120,"context_line":"        LOG.debug(\u0027Microversion discovery failed: %s\u0027, exc)"}],"source_content_type":"text/x-python","patch_set":33,"id":"33198ba3_5854d594","line":117,"range":{"start_line":117,"start_character":23,"end_line":117,"end_character":25},"updated":"2025-11-04 12:08:38.000000000","message":"\u0027microversion\u0027 is better than \u0027MV\u0027","commit_id":"1f3a375cb983e4db9a2219247628aa16e62e05fc"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7e8de1f232fef1b8641dee1a78bc3f273a5658db","unresolved":false,"context_lines":[{"line_number":114,"context_line":"                if min_hdr or max_hdr:"},{"line_number":115,"context_line":"                    result \u003d (min_hdr, max_hdr)"},{"line_number":116,"context_line":"        else:"},{"line_number":117,"context_line":"            LOG.debug(\u0027MV discovery status\u003d%s for %s\u0027,"},{"line_number":118,"context_line":"                      resp.status_code, endpoint)"},{"line_number":119,"context_line":"    except Exception as exc:"},{"line_number":120,"context_line":"        LOG.debug(\u0027Microversion discovery failed: %s\u0027, exc)"}],"source_content_type":"text/x-python","patch_set":33,"id":"07b1a501_4811d51f","line":117,"range":{"start_line":117,"start_character":23,"end_line":117,"end_character":25},"in_reply_to":"33198ba3_5854d594","updated":"2025-11-06 05:15:53.000000000","message":"Done","commit_id":"1f3a375cb983e4db9a2219247628aa16e62e05fc"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cf5770ef24939fbdc459a03a9b1bc6d75d2c0ac8","unresolved":true,"context_lines":[{"line_number":58,"context_line":"    )"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"def _to_version_tuple(value):"},{"line_number":62,"context_line":"    \"\"\"Convert \u0027X.Y\u0027 into comparable (X, Y). Unknown -\u003e (1, 0).\"\"\""},{"line_number":63,"context_line":"    if not value:"},{"line_number":64,"context_line":"        return (1, 0)"}],"source_content_type":"text/x-python","patch_set":40,"id":"69d51ccd_41a327e3","line":61,"updated":"2026-02-25 18:30:48.000000000","message":"normally i would say we shoudl use micoversion-parse for this\nits not currently a runtime depency so this is somewhat ok","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ffff5a8378c3a631db8e5ff1502fcb009d4330d5","unresolved":false,"context_lines":[{"line_number":58,"context_line":"    )"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"def _to_version_tuple(value):"},{"line_number":62,"context_line":"    \"\"\"Convert \u0027X.Y\u0027 into comparable (X, Y). Unknown -\u003e (1, 0).\"\"\""},{"line_number":63,"context_line":"    if not value:"},{"line_number":64,"context_line":"        return (1, 0)"}],"source_content_type":"text/x-python","patch_set":40,"id":"7f722214_8e77d792","line":61,"in_reply_to":"69d51ccd_41a327e3","updated":"2026-02-26 15:18:26.000000000","message":"Acknowledged","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cf5770ef24939fbdc459a03a9b1bc6d75d2c0ac8","unresolved":true,"context_lines":[{"line_number":64,"context_line":"        return (1, 0)"},{"line_number":65,"context_line":"    try:"},{"line_number":66,"context_line":"        major, minor \u003d value.split(\u0027.\u0027)"},{"line_number":67,"context_line":"        return (int(major), int(minor) if minor !\u003d \u0027latest\u0027 else 999)"},{"line_number":68,"context_line":"    except ValueError:"},{"line_number":69,"context_line":"        return (1, 0)"},{"line_number":70,"context_line":""}],"source_content_type":"text/x-python","patch_set":40,"id":"05f83260_1d1663ac","line":67,"range":{"start_line":67,"start_character":39,"end_line":67,"end_character":69},"updated":"2026-02-25 18:30:48.000000000","message":"this is kind of a hack however\n\nthe bigger issue is we already have code in the watcher client for this which you should b eusedin instead\n\nhttps://github.com/openstack/python-watcherclient/blob/master/watcherclient/common/api_versioning.py","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ffff5a8378c3a631db8e5ff1502fcb009d4330d5","unresolved":true,"context_lines":[{"line_number":64,"context_line":"        return (1, 0)"},{"line_number":65,"context_line":"    try:"},{"line_number":66,"context_line":"        major, minor \u003d value.split(\u0027.\u0027)"},{"line_number":67,"context_line":"        return (int(major), int(minor) if minor !\u003d \u0027latest\u0027 else 999)"},{"line_number":68,"context_line":"    except ValueError:"},{"line_number":69,"context_line":"        return (1, 0)"},{"line_number":70,"context_line":""}],"source_content_type":"text/x-python","patch_set":40,"id":"47dfb1c4_18b6a254","line":67,"range":{"start_line":67,"start_character":39,"end_line":67,"end_character":69},"in_reply_to":"05f83260_1d1663ac","updated":"2026-02-26 15:18:26.000000000","message":"+1, Fixed it now.","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cf5770ef24939fbdc459a03a9b1bc6d75d2c0ac8","unresolved":true,"context_lines":[{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    Caches on request as `_watcher_microversion_range`."},{"line_number":76,"context_line":"    \"\"\""},{"line_number":77,"context_line":"    try:"},{"line_number":78,"context_line":"        return request._watcher_microversion_range"},{"line_number":79,"context_line":"    except AttributeError:"},{"line_number":80,"context_line":"        pass"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    result \u003d (None, None)"},{"line_number":83,"context_line":"    try:"},{"line_number":84,"context_line":"        endpoint \u003d base.url_for(request, WATCHER_SERVICE)"}],"source_content_type":"text/x-python","patch_set":40,"id":"d15c7f22_030ce7a1","line":81,"range":{"start_line":77,"start_character":2,"end_line":81,"end_character":1},"updated":"2026-02-25 18:30:48.000000000","message":"this to mean telem me tehre is a bug in the way you have impeltne dthis as we shoudl not get an atribute error like this.\n\nall supproted version fo watcher willl support this and this is not the correct way to do the early return pattern either this would be one of the few time hasattr woudl be correct to use.\n\nthe real rpoblem is you shoudl be caching at  different level or not caching at all.","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cf5770ef24939fbdc459a03a9b1bc6d75d2c0ac8","unresolved":true,"context_lines":[{"line_number":92,"context_line":"        verify \u003d False if insecure else (ca_file or True)"},{"line_number":93,"context_line":"        timeout \u003d WATCHER_API_TIMEOUT"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"        resp \u003d requests.get("},{"line_number":96,"context_line":"            endpoint, headers\u003dheaders, verify\u003dverify, timeout\u003dtimeout)"},{"line_number":97,"context_line":"        if 200 \u003c\u003d resp.status_code \u003c 300:"},{"line_number":98,"context_line":"            # Prefer body (most reliable across deployments)"}],"source_content_type":"text/x-python","patch_set":40,"id":"f5f8447d_db3cf438","line":95,"updated":"2026-02-25 18:30:48.000000000","message":"you should not be using the request lib directly","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ffff5a8378c3a631db8e5ff1502fcb009d4330d5","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        verify \u003d False if insecure else (ca_file or True)"},{"line_number":93,"context_line":"        timeout \u003d WATCHER_API_TIMEOUT"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"        resp \u003d requests.get("},{"line_number":96,"context_line":"            endpoint, headers\u003dheaders, verify\u003dverify, timeout\u003dtimeout)"},{"line_number":97,"context_line":"        if 200 \u003c\u003d resp.status_code \u003c 300:"},{"line_number":98,"context_line":"            # Prefer body (most reliable across deployments)"}],"source_content_type":"text/x-python","patch_set":40,"id":"78b56281_b4bc005d","line":95,"in_reply_to":"f5f8447d_db3cf438","updated":"2026-02-26 15:18:26.000000000","message":"replaced it with get_client method from client.py.","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cf5770ef24939fbdc459a03a9b1bc6d75d2c0ac8","unresolved":true,"context_lines":[{"line_number":123,"context_line":"    return result"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"def is_supported(mv_range, required):"},{"line_number":127,"context_line":"    \"\"\"Return True if server supports the required microversion."},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    Accepts mv_range as a tuple (min_version, max_version). Unknown"}],"source_content_type":"text/x-python","patch_set":40,"id":"d90151b5_c21d917f","line":126,"updated":"2026-02-25 18:30:48.000000000","message":"this should be comparing the api version object form watcher client.","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"72a2089ade5b16ecb858dfe4a819221f7257eeac","unresolved":true,"context_lines":[{"line_number":52,"context_line":"    )"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"def get_server_microversion_range(request):"},{"line_number":56,"context_line":"    \"\"\"Discover server (min, max) microversions."},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    Queries the Watcher API root endpoint to retrieve the supported"}],"source_content_type":"text/x-python","patch_set":44,"id":"ecd56ab1_143a9cac","line":55,"updated":"2026-02-26 20:02:33.000000000","message":"you do not need to check the range just the max verion\n\n\nwhile its techincily possibel to reaise the min veriosn watcher has never done that and its not somethign that is configurable.\nso the min verison is alwasy 1.0\nall we need to check is fi the server version is \u003e\u003d the reqiured version for a given feature.","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"a34cbf1cd07b2a57b758783f1eba4945f418c09e","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    )"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"def get_server_microversion_range(request):"},{"line_number":56,"context_line":"    \"\"\"Discover server (min, max) microversions."},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    Queries the Watcher API root endpoint to retrieve the supported"}],"source_content_type":"text/x-python","patch_set":44,"id":"2bc82c11_a7edd2b6","line":55,"in_reply_to":"ecd56ab1_143a9cac","updated":"2026-03-03 07:36:49.000000000","message":"Done","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"72a2089ade5b16ecb858dfe4a819221f7257eeac","unresolved":true,"context_lines":[{"line_number":90,"context_line":"    except Exception:"},{"line_number":91,"context_line":"        LOG.debug(\u0027Microversion discovery failed\u0027, exc_info\u003dTrue)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"    request._watcher_microversion_range \u003d result"},{"line_number":94,"context_line":"    return result"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"962644f3_38a5bac8","line":93,"updated":"2026-02-26 20:02:33.000000000","message":"-1 for this pattern.\nwe shoudl not proceed with this patch until you are nolonger extendign the qeust object dynmaicly like this.","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"a34cbf1cd07b2a57b758783f1eba4945f418c09e","unresolved":false,"context_lines":[{"line_number":90,"context_line":"    except Exception:"},{"line_number":91,"context_line":"        LOG.debug(\u0027Microversion discovery failed\u0027, exc_info\u003dTrue)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"    request._watcher_microversion_range \u003d result"},{"line_number":94,"context_line":"    return result"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"7dccb0eb_5deb8e11","line":93,"in_reply_to":"962644f3_38a5bac8","updated":"2026-03-03 07:36:49.000000000","message":"Done","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"}],"watcher_dashboard/content/action_plans/views.py":[{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    def get_context_data(self, **kwargs):"},{"line_number":140,"context_line":"        context \u003d super(DetailView, self).get_context_data(**kwargs)"},{"line_number":141,"context_line":"        action_plan \u003d getattr(self, \u0027_detail_action_plan\u0027, None) or \\"},{"line_number":142,"context_line":"            self._get_data()"},{"line_number":143,"context_line":"        context[\"action_plan\"] \u003d action_plan"},{"line_number":144,"context_line":"        # No direct table mutation here; flags are passed at construct time"},{"line_number":145,"context_line":"        # Show Related Actions only when SKIP_ACTION microversion is supported."}],"source_content_type":"text/x-python","patch_set":30,"id":"f95d9c81_c9d5e109","line":142,"range":{"start_line":141,"start_character":0,"end_line":142,"end_character":28},"updated":"2025-10-08 15:08:16.000000000","message":"if you plan to cache this info in \u0027_detail_action_plan\u0027, always initialize it with None, so you don\u0027t need to add getattr in all places.\nYou can create a property that retrieve the content at the time that you first access it.","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":false,"context_lines":[{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    def get_context_data(self, **kwargs):"},{"line_number":140,"context_line":"        context \u003d super(DetailView, self).get_context_data(**kwargs)"},{"line_number":141,"context_line":"        action_plan \u003d getattr(self, \u0027_detail_action_plan\u0027, None) or \\"},{"line_number":142,"context_line":"            self._get_data()"},{"line_number":143,"context_line":"        context[\"action_plan\"] \u003d action_plan"},{"line_number":144,"context_line":"        # No direct table mutation here; flags are passed at construct time"},{"line_number":145,"context_line":"        # Show Related Actions only when SKIP_ACTION microversion is supported."}],"source_content_type":"text/x-python","patch_set":30,"id":"5e4dc6a2_3763264e","line":142,"range":{"start_line":141,"start_character":0,"end_line":142,"end_character":28},"in_reply_to":"f95d9c81_c9d5e109","updated":"2025-10-10 15:10:41.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":144,"context_line":"        # No direct table mutation here; flags are passed at construct time"},{"line_number":145,"context_line":"        # Show Related Actions only when SKIP_ACTION microversion is supported."},{"line_number":146,"context_line":"        # Treat unknown discovery as unsupported for this UI section."},{"line_number":147,"context_line":"        try:"},{"line_number":148,"context_line":"            mv_range \u003d common_client.get_server_microversion_range("},{"line_number":149,"context_line":"                self.request)"},{"line_number":150,"context_line":"            min_mv, max_mv \u003d mv_range"},{"line_number":151,"context_line":"            if max_mv is None:"},{"line_number":152,"context_line":"                context[\"show_related_actions\"] \u003d False"},{"line_number":153,"context_line":"            else:"},{"line_number":154,"context_line":"                context[\"show_related_actions\"] \u003d common_client.is_supported("},{"line_number":155,"context_line":"                    mv_range, common_client.SKIP_ACTION)"},{"line_number":156,"context_line":"        except Exception:"},{"line_number":157,"context_line":"            context[\"show_related_actions\"] \u003d False"},{"line_number":158,"context_line":"        LOG.info(\u0027*********************************\u0027)"},{"line_number":159,"context_line":"        LOG.info(action_plan)"},{"line_number":160,"context_line":"        LOG.info(\u0027*********************************\u0027)"}],"source_content_type":"text/x-python","patch_set":30,"id":"7c8df573_527d57a8","line":157,"range":{"start_line":147,"start_character":0,"end_line":157,"end_character":51},"updated":"2025-10-08 15:08:16.000000000","message":"I think you can make it simple, since `is_supported` already returns False if microversion is None","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":false,"context_lines":[{"line_number":144,"context_line":"        # No direct table mutation here; flags are passed at construct time"},{"line_number":145,"context_line":"        # Show Related Actions only when SKIP_ACTION microversion is supported."},{"line_number":146,"context_line":"        # Treat unknown discovery as unsupported for this UI section."},{"line_number":147,"context_line":"        try:"},{"line_number":148,"context_line":"            mv_range \u003d common_client.get_server_microversion_range("},{"line_number":149,"context_line":"                self.request)"},{"line_number":150,"context_line":"            min_mv, max_mv \u003d mv_range"},{"line_number":151,"context_line":"            if max_mv is None:"},{"line_number":152,"context_line":"                context[\"show_related_actions\"] \u003d False"},{"line_number":153,"context_line":"            else:"},{"line_number":154,"context_line":"                context[\"show_related_actions\"] \u003d common_client.is_supported("},{"line_number":155,"context_line":"                    mv_range, common_client.SKIP_ACTION)"},{"line_number":156,"context_line":"        except Exception:"},{"line_number":157,"context_line":"            context[\"show_related_actions\"] \u003d False"},{"line_number":158,"context_line":"        LOG.info(\u0027*********************************\u0027)"},{"line_number":159,"context_line":"        LOG.info(action_plan)"},{"line_number":160,"context_line":"        LOG.info(\u0027*********************************\u0027)"}],"source_content_type":"text/x-python","patch_set":30,"id":"8f52a86e_480a17cb","line":157,"range":{"start_line":147,"start_character":0,"end_line":157,"end_character":51},"in_reply_to":"7c8df573_527d57a8","updated":"2025-10-10 15:10:41.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":161,"context_line":"        return context"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"    def get_tabs(self, request, *args, **kwargs):"},{"line_number":164,"context_line":"        action_plan \u003d getattr(self, \u0027_detail_action_plan\u0027, None) or \\"},{"line_number":165,"context_line":"            self._get_data()"},{"line_number":166,"context_line":"        return self.tab_group_class("},{"line_number":167,"context_line":"            request, action_plan\u003daction_plan, **kwargs)"}],"source_content_type":"text/x-python","patch_set":30,"id":"6f0ca6bd_8a7373a3","line":164,"range":{"start_line":164,"start_character":67,"end_line":164,"end_character":69},"updated":"2025-10-08 15:08:16.000000000","message":"parenthesis instead of backslash\nhttps://docs.openstack.org/hacking/latest/user/hacking.html#general","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":false,"context_lines":[{"line_number":161,"context_line":"        return context"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"    def get_tabs(self, request, *args, **kwargs):"},{"line_number":164,"context_line":"        action_plan \u003d getattr(self, \u0027_detail_action_plan\u0027, None) or \\"},{"line_number":165,"context_line":"            self._get_data()"},{"line_number":166,"context_line":"        return self.tab_group_class("},{"line_number":167,"context_line":"            request, action_plan\u003daction_plan, **kwargs)"}],"source_content_type":"text/x-python","patch_set":30,"id":"c4fca83b_fab4208e","line":164,"range":{"start_line":164,"start_character":67,"end_line":164,"end_character":69},"in_reply_to":"6f0ca6bd_8a7373a3","updated":"2025-10-10 15:10:41.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":169,"context_line":"    def get_tables(self):"},{"line_number":170,"context_line":"        tables \u003d super(DetailView, self).get_tables()"},{"line_number":171,"context_line":"        try:"},{"line_number":172,"context_line":"            action_plan \u003d getattr(self, \u0027_detail_action_plan\u0027, None) or \\"},{"line_number":173,"context_line":"                self._get_data()"},{"line_number":174,"context_line":"            parent_succeeded \u003d ("},{"line_number":175,"context_line":"                getattr(action_plan, \u0027state\u0027, None) \u003d\u003d \u0027SUCCEEDED\u0027"}],"source_content_type":"text/x-python","patch_set":30,"id":"f0e1e494_e1b77c1c","line":172,"range":{"start_line":172,"start_character":41,"end_line":172,"end_character":60},"updated":"2025-10-08 15:08:16.000000000","message":"_detail_action_plan to a property?","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":169,"context_line":"    def get_tables(self):"},{"line_number":170,"context_line":"        tables \u003d super(DetailView, self).get_tables()"},{"line_number":171,"context_line":"        try:"},{"line_number":172,"context_line":"            action_plan \u003d getattr(self, \u0027_detail_action_plan\u0027, None) or \\"},{"line_number":173,"context_line":"                self._get_data()"},{"line_number":174,"context_line":"            parent_succeeded \u003d ("},{"line_number":175,"context_line":"                getattr(action_plan, \u0027state\u0027, None) \u003d\u003d \u0027SUCCEEDED\u0027"}],"source_content_type":"text/x-python","patch_set":30,"id":"5ec950a3_b296a501","line":172,"range":{"start_line":172,"start_character":72,"end_line":172,"end_character":73},"updated":"2025-10-08 15:08:16.000000000","message":"ditto.","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":false,"context_lines":[{"line_number":169,"context_line":"    def get_tables(self):"},{"line_number":170,"context_line":"        tables \u003d super(DetailView, self).get_tables()"},{"line_number":171,"context_line":"        try:"},{"line_number":172,"context_line":"            action_plan \u003d getattr(self, \u0027_detail_action_plan\u0027, None) or \\"},{"line_number":173,"context_line":"                self._get_data()"},{"line_number":174,"context_line":"            parent_succeeded \u003d ("},{"line_number":175,"context_line":"                getattr(action_plan, \u0027state\u0027, None) \u003d\u003d \u0027SUCCEEDED\u0027"}],"source_content_type":"text/x-python","patch_set":30,"id":"d2dc2066_ecf3a2f3","line":172,"range":{"start_line":172,"start_character":72,"end_line":172,"end_character":73},"in_reply_to":"5ec950a3_b296a501","updated":"2025-10-10 15:10:41.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":false,"context_lines":[{"line_number":169,"context_line":"    def get_tables(self):"},{"line_number":170,"context_line":"        tables \u003d super(DetailView, self).get_tables()"},{"line_number":171,"context_line":"        try:"},{"line_number":172,"context_line":"            action_plan \u003d getattr(self, \u0027_detail_action_plan\u0027, None) or \\"},{"line_number":173,"context_line":"                self._get_data()"},{"line_number":174,"context_line":"            parent_succeeded \u003d ("},{"line_number":175,"context_line":"                getattr(action_plan, \u0027state\u0027, None) \u003d\u003d \u0027SUCCEEDED\u0027"}],"source_content_type":"text/x-python","patch_set":30,"id":"528de80b_3226534c","line":172,"range":{"start_line":172,"start_character":41,"end_line":172,"end_character":60},"in_reply_to":"f0e1e494_e1b77c1c","updated":"2025-10-10 15:10:41.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":172,"context_line":"            action_plan \u003d getattr(self, \u0027_detail_action_plan\u0027, None) or \\"},{"line_number":173,"context_line":"                self._get_data()"},{"line_number":174,"context_line":"            parent_succeeded \u003d ("},{"line_number":175,"context_line":"                getattr(action_plan, \u0027state\u0027, None) \u003d\u003d \u0027SUCCEEDED\u0027"},{"line_number":176,"context_line":"            )"},{"line_number":177,"context_line":"        except Exception:"},{"line_number":178,"context_line":"            parent_succeeded \u003d False"}],"source_content_type":"text/x-python","patch_set":30,"id":"ac31e5b4_0a915916","line":175,"range":{"start_line":175,"start_character":24,"end_line":175,"end_character":35},"updated":"2025-10-08 15:08:16.000000000","message":"action_plan always have a state, right?","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":false,"context_lines":[{"line_number":172,"context_line":"            action_plan \u003d getattr(self, \u0027_detail_action_plan\u0027, None) or \\"},{"line_number":173,"context_line":"                self._get_data()"},{"line_number":174,"context_line":"            parent_succeeded \u003d ("},{"line_number":175,"context_line":"                getattr(action_plan, \u0027state\u0027, None) \u003d\u003d \u0027SUCCEEDED\u0027"},{"line_number":176,"context_line":"            )"},{"line_number":177,"context_line":"        except Exception:"},{"line_number":178,"context_line":"            parent_succeeded \u003d False"}],"source_content_type":"text/x-python","patch_set":30,"id":"926738a9_4b34a891","line":175,"range":{"start_line":175,"start_character":24,"end_line":175,"end_character":35},"in_reply_to":"ac31e5b4_0a915916","updated":"2025-10-10 15:10:41.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cf5770ef24939fbdc459a03a9b1bc6d75d2c0ac8","unresolved":true,"context_lines":[{"line_number":167,"context_line":"        # Store parent state and skip support on request for the table"},{"line_number":168,"context_line":"        try:"},{"line_number":169,"context_line":"            # Set request-scoped hints for tables"},{"line_number":170,"context_line":"            self.request._watcher_current_action_plan_state \u003d ("},{"line_number":171,"context_line":"                action_plan.state if action_plan else None)"},{"line_number":172,"context_line":"            self.request._watcher_supports_skip \u003d ("},{"line_number":173,"context_line":"                context[\"show_related_actions\"])"}],"source_content_type":"text/x-python","patch_set":40,"id":"65597102_39d5cc9a","line":170,"in_reply_to":"54571310_9cbc3a35","updated":"2026-02-25 18:30:48.000000000","message":"ya that is not a good patther to use and when you use it you should never access it directly out side fo the class that is using it.\n\nassing aroudn extra data on the request liek this is not something we should allow.\n\n\nthere are limited case where this is accpatble but i dont belive this i sone of them\n\nwe should just pass the context object to the Calles that need this or similar.","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"adabc2734fd6d4c6d6f4d13bba4777f35b0a4e21","unresolved":false,"context_lines":[{"line_number":167,"context_line":"        # Store parent state and skip support on request for the table"},{"line_number":168,"context_line":"        try:"},{"line_number":169,"context_line":"            # Set request-scoped hints for tables"},{"line_number":170,"context_line":"            self.request._watcher_current_action_plan_state \u003d ("},{"line_number":171,"context_line":"                action_plan.state if action_plan else None)"},{"line_number":172,"context_line":"            self.request._watcher_supports_skip \u003d ("},{"line_number":173,"context_line":"                context[\"show_related_actions\"])"}],"source_content_type":"text/x-python","patch_set":40,"id":"e73a4c7c_c8dad98c","line":170,"in_reply_to":"65597102_39d5cc9a","updated":"2026-03-03 20:10:08.000000000","message":"Acknowledged","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"adabc2734fd6d4c6d6f4d13bba4777f35b0a4e21","unresolved":true,"context_lines":[{"line_number":152,"context_line":"        from construct_tables() which loads data into each table, then"},{"line_number":153,"context_line":"        again from get_context_data() to build the template context."},{"line_number":154,"context_line":"        We must update the existing table instance rather than replace"},{"line_number":155,"context_line":"        it, otherwise the data loaded by construct_tables() is lost."},{"line_number":156,"context_line":"        \"\"\""},{"line_number":157,"context_line":"        table_dict \u003d super().get_tables()"},{"line_number":158,"context_line":"        action_plan \u003d self._get_data()"}],"source_content_type":"text/x-python","patch_set":47,"id":"ec865714_ff249fd0","line":155,"updated":"2026-03-03 20:10:08.000000000","message":"ew, but thanks for documenting this","commit_id":"3a884013ecbca509d2379b090f2a16bb6206d2d5"}],"watcher_dashboard/content/actions/forms.py":[{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"9c5ff80cddbefc56227dc0ae261152458617a18b","unresolved":true,"context_lines":[{"line_number":79,"context_line":"            watcher.Action.update(request, action_id, state\u003d\"SKIPPED\","},{"line_number":80,"context_line":"                                  reason\u003dreason)"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"            success_message \u003d _(\"Action %(action_id)s has been skipped.\")"},{"line_number":83,"context_line":"            if reason:"},{"line_number":84,"context_line":"                success_message +\u003d _(\" Reason: %(reason)s\")"},{"line_number":85,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"b2c729f3_31c8f095","line":82,"range":{"start_line":82,"start_character":0,"end_line":82,"end_character":73},"updated":"2025-08-28 19:03:10.000000000","message":"If previous state is already SKIPPED, we can provide a different Success message, like, saying that skip reason was updated.","commit_id":"df7a850bc63e0ee72ecf389491d7f310f0ac2b06"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ed410f766e79f0fcacdf10dd169f32b44ab47e5c","unresolved":false,"context_lines":[{"line_number":79,"context_line":"            watcher.Action.update(request, action_id, state\u003d\"SKIPPED\","},{"line_number":80,"context_line":"                                  reason\u003dreason)"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"            success_message \u003d _(\"Action %(action_id)s has been skipped.\")"},{"line_number":83,"context_line":"            if reason:"},{"line_number":84,"context_line":"                success_message +\u003d _(\" Reason: %(reason)s\")"},{"line_number":85,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"57ca4dfc_5ef110f5","line":82,"range":{"start_line":82,"start_character":0,"end_line":82,"end_character":73},"in_reply_to":"b2c729f3_31c8f095","updated":"2025-08-29 04:20:06.000000000","message":"Done","commit_id":"df7a850bc63e0ee72ecf389491d7f310f0ac2b06"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"6cce8acceb9642efa1f29ab9e251768140dd52c8","unresolved":true,"context_lines":[{"line_number":34,"context_line":"    reason \u003d forms.CharField("},{"line_number":35,"context_line":"        label\u003d_(\"Reason for skipping\"),"},{"line_number":36,"context_line":"        widget\u003dforms.Textarea(attrs\u003d{\u0027rows\u0027: 3}),"},{"line_number":37,"context_line":"        max_length\u003d255,"},{"line_number":38,"context_line":"        required\u003dFalse,"},{"line_number":39,"context_line":"        help_text\u003d_(\"Optional reason for skipping this action. \""},{"line_number":40,"context_line":"                    \"This will be stored as the status message.\"))"}],"source_content_type":"text/x-python","patch_set":13,"id":"a82b41f8_c5a0fe1f","line":37,"updated":"2025-09-02 10:44:18.000000000","message":"we should restrict this length further. The column in the database is configured to hold up to 255 chars, but watcher inserts the string `Action skipped by user. Reson:` before the reason passed in the form https://github.com/openstack/watcher/blob/e5b18afa017750fa5d02858eea5322d67ca2155a/watcher/api/controllers/v1/action.py#L455, so if the text input is longer than 223 chars, when trying to skip the action we\u0027ll get an error when trying to insert to the database. To be safe in case the text changes in the future I would set the max length to something like 200 characters","commit_id":"1d75e29fc37baac5e6fea1ce4e896991c8a6dd77"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"d617856184843211a22e53f9c8ea7ad338f9042c","unresolved":false,"context_lines":[{"line_number":34,"context_line":"    reason \u003d forms.CharField("},{"line_number":35,"context_line":"        label\u003d_(\"Reason for skipping\"),"},{"line_number":36,"context_line":"        widget\u003dforms.Textarea(attrs\u003d{\u0027rows\u0027: 3}),"},{"line_number":37,"context_line":"        max_length\u003d255,"},{"line_number":38,"context_line":"        required\u003dFalse,"},{"line_number":39,"context_line":"        help_text\u003d_(\"Optional reason for skipping this action. \""},{"line_number":40,"context_line":"                    \"This will be stored as the status message.\"))"}],"source_content_type":"text/x-python","patch_set":13,"id":"febd4a5b_a2c976aa","line":37,"in_reply_to":"a82b41f8_c5a0fe1f","updated":"2025-09-02 13:13:00.000000000","message":"Done","commit_id":"1d75e29fc37baac5e6fea1ce4e896991c8a6dd77"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"adabc2734fd6d4c6d6f4d13bba4777f35b0a4e21","unresolved":true,"context_lines":[{"line_number":66,"context_line":"        reason \u003d data.get(\u0027reason\u0027, \u0027\u0027).strip() or None"},{"line_number":67,"context_line":"        action \u003d data[\u0027_action\u0027]"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"        state \u003d None if action.state \u003d\u003d \u0027SKIPPED\u0027 else \u0027SKIPPED\u0027"},{"line_number":70,"context_line":"        try:"},{"line_number":71,"context_line":"            result \u003d watcher.Action.update("},{"line_number":72,"context_line":"                request, action_id, state\u003dstate, reason\u003dreason,"}],"source_content_type":"text/x-python","patch_set":47,"id":"b3450650_efdc512a","line":69,"range":{"start_line":69,"start_character":7,"end_line":69,"end_character":64},"updated":"2026-03-03 20:10:08.000000000","message":"```suggestion\n        state \u003d action.state or \u0027SKIPPED\u0027\n```\n\ni think that ^ would be logically equivalent.","commit_id":"3a884013ecbca509d2379b090f2a16bb6206d2d5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"29e65cdcf2cdf61a23dc814228f0bfdfe2fcddc1","unresolved":true,"context_lines":[{"line_number":66,"context_line":"        reason \u003d data.get(\u0027reason\u0027, \u0027\u0027).strip() or None"},{"line_number":67,"context_line":"        action \u003d data[\u0027_action\u0027]"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"        state \u003d None if action.state \u003d\u003d \u0027SKIPPED\u0027 else \u0027SKIPPED\u0027"},{"line_number":70,"context_line":"        try:"},{"line_number":71,"context_line":"            result \u003d watcher.Action.update("},{"line_number":72,"context_line":"                request, action_id, state\u003dstate, reason\u003dreason,"}],"source_content_type":"text/x-python","patch_set":47,"id":"7e8eb32b_c5cf7e1a","line":69,"range":{"start_line":69,"start_character":7,"end_line":69,"end_character":64},"in_reply_to":"b3450650_efdc512a","updated":"2026-03-03 20:36:24.000000000","message":"iiuc, action.state holds the current action state, which can be PENDING or SKIPPED, and state would be the new state. So we only need to update if action.state is not yet SKIPPED (which means that user can update the message only)","commit_id":"3a884013ecbca509d2379b090f2a16bb6206d2d5"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"adabc2734fd6d4c6d6f4d13bba4777f35b0a4e21","unresolved":true,"context_lines":[{"line_number":76,"context_line":"            messages.error(request, str(exc))"},{"line_number":77,"context_line":"            return False"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        if result is None:"},{"line_number":80,"context_line":"            messages.warning("},{"line_number":81,"context_line":"                request,"},{"line_number":82,"context_line":"                _(\u0027Skip is not supported by this server.\u0027))"},{"line_number":83,"context_line":"            return False"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"        if state is None:"},{"line_number":86,"context_line":"            msg \u003d _(\u0027Skip reason was successfully updated.\u0027)"}],"source_content_type":"text/x-python","patch_set":47,"id":"8ec68356_4ffd523c","line":83,"range":{"start_line":79,"start_character":7,"end_line":83,"end_character":24},"updated":"2026-03-03 20:10:08.000000000","message":"so this shoudl never happen because we shoudl not display the ablity to skip if the server does not supprot it.\n\nso this woudl only happne if someon driectly called the form endpoint with curl or similar.","commit_id":"3a884013ecbca509d2379b090f2a16bb6206d2d5"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"29e65cdcf2cdf61a23dc814228f0bfdfe2fcddc1","unresolved":true,"context_lines":[{"line_number":76,"context_line":"            messages.error(request, str(exc))"},{"line_number":77,"context_line":"            return False"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        if result is None:"},{"line_number":80,"context_line":"            messages.warning("},{"line_number":81,"context_line":"                request,"},{"line_number":82,"context_line":"                _(\u0027Skip is not supported by this server.\u0027))"},{"line_number":83,"context_line":"            return False"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"        if state is None:"},{"line_number":86,"context_line":"            msg \u003d _(\u0027Skip reason was successfully updated.\u0027)"}],"source_content_type":"text/x-python","patch_set":47,"id":"134afcf1_9745c548","line":83,"range":{"start_line":79,"start_character":7,"end_line":83,"end_character":24},"in_reply_to":"8ec68356_4ffd523c","updated":"2026-03-03 20:36:24.000000000","message":"yeah, that\u0027s my understanding too, the skip button wouldn\u0027t be available if not supported by the server.","commit_id":"3a884013ecbca509d2379b090f2a16bb6206d2d5"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"adabc2734fd6d4c6d6f4d13bba4777f35b0a4e21","unresolved":true,"context_lines":[{"line_number":81,"context_line":"                request,"},{"line_number":82,"context_line":"                _(\u0027Skip is not supported by this server.\u0027))"},{"line_number":83,"context_line":"            return False"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"        if state is None:"},{"line_number":86,"context_line":"            msg \u003d _(\u0027Skip reason was successfully updated.\u0027)"},{"line_number":87,"context_line":"        else:"},{"line_number":88,"context_line":"            msg \u003d _(\u0027Action was successfully skipped.\u0027)"},{"line_number":89,"context_line":"        messages.success(request, msg)"},{"line_number":90,"context_line":"        return True"}],"source_content_type":"text/x-python","patch_set":47,"id":"6fde943b_7dafc372","line":88,"range":{"start_line":84,"start_character":1,"end_line":88,"end_character":55},"updated":"2026-03-03 20:10:08.000000000","message":"oh i see your using state to determine which action was taken\n\ni woudl move thie up to where its set above to make that clearer","commit_id":"3a884013ecbca509d2379b090f2a16bb6206d2d5"}],"watcher_dashboard/content/actions/tables.py":[{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"9c5ff80cddbefc56227dc0ae261152458617a18b","unresolved":true,"context_lines":[{"line_number":71,"context_line":"    policy_rules \u003d ((\"infra-optim\", \"action:update\"),)"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def allowed(self, request, action):"},{"line_number":74,"context_line":"        return action and action.state \u003d\u003d \"PENDING\""},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"    @staticmethod"},{"line_number":77,"context_line":"    def action_present(count):"}],"source_content_type":"text/x-python","patch_set":3,"id":"0412d88c_e2d4d5fb","line":74,"range":{"start_line":74,"start_character":0,"end_line":74,"end_character":51},"updated":"2025-08-28 19:03:10.000000000","message":"since we can update the reason message, SKIPPED states should also be allowed.","commit_id":"df7a850bc63e0ee72ecf389491d7f310f0ac2b06"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"672f380379c3047eb18c296ca16a6b2f00389b1a","unresolved":false,"context_lines":[{"line_number":71,"context_line":"    policy_rules \u003d ((\"infra-optim\", \"action:update\"),)"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def allowed(self, request, action):"},{"line_number":74,"context_line":"        return action and action.state \u003d\u003d \"PENDING\""},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"    @staticmethod"},{"line_number":77,"context_line":"    def action_present(count):"}],"source_content_type":"text/x-python","patch_set":3,"id":"146e035e_26e0a69d","line":74,"range":{"start_line":74,"start_character":0,"end_line":74,"end_character":51},"in_reply_to":"0412d88c_e2d4d5fb","updated":"2025-08-29 12:30:04.000000000","message":"Done","commit_id":"df7a850bc63e0ee72ecf389491d7f310f0ac2b06"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"6cce8acceb9642efa1f29ab9e251768140dd52c8","unresolved":true,"context_lines":[{"line_number":38,"context_line":"    (\"FAILED\", pgettext_lazy(\"Power state of an Instance\", u\"Failed\")),"},{"line_number":39,"context_line":"    (\"DELETED\", pgettext_lazy(\"Power state of an Instance\", u\"Deleted\")),"},{"line_number":40,"context_line":"    (\"PENDING\", pgettext_lazy(\"Power state of an Instance\", u\"Pending\")),"},{"line_number":41,"context_line":"    (\"SKIPPED\", pgettext_lazy(\"Power state of an Instance\", u\"Skipped\")),"},{"line_number":42,"context_line":")"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"564bb87f_1bd64216","line":41,"updated":"2025-09-02 10:44:18.000000000","message":"I realize that this text was added before this patch, but it does not seem correct, why is it talking about the power state of an instance? Also, is this displayed anywhere? I can\u0027t seem to find it in my environment","commit_id":"1d75e29fc37baac5e6fea1ce4e896991c8a6dd77"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"e645c9f574d51ae8602b168470164373c3fb1645","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    (\"FAILED\", pgettext_lazy(\"Power state of an Instance\", u\"Failed\")),"},{"line_number":39,"context_line":"    (\"DELETED\", pgettext_lazy(\"Power state of an Instance\", u\"Deleted\")),"},{"line_number":40,"context_line":"    (\"PENDING\", pgettext_lazy(\"Power state of an Instance\", u\"Pending\")),"},{"line_number":41,"context_line":"    (\"SKIPPED\", pgettext_lazy(\"Power state of an Instance\", u\"Skipped\")),"},{"line_number":42,"context_line":")"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"ded77f01_b63d20a5","line":41,"in_reply_to":"2ed82dcb_a6782f97","updated":"2025-09-04 10:40:20.000000000","message":"Done","commit_id":"1d75e29fc37baac5e6fea1ce4e896991c8a6dd77"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"4d4395aa0995134755cbb74f0e64a54669e3358f","unresolved":true,"context_lines":[{"line_number":38,"context_line":"    (\"FAILED\", pgettext_lazy(\"Power state of an Instance\", u\"Failed\")),"},{"line_number":39,"context_line":"    (\"DELETED\", pgettext_lazy(\"Power state of an Instance\", u\"Deleted\")),"},{"line_number":40,"context_line":"    (\"PENDING\", pgettext_lazy(\"Power state of an Instance\", u\"Pending\")),"},{"line_number":41,"context_line":"    (\"SKIPPED\", pgettext_lazy(\"Power state of an Instance\", u\"Skipped\")),"},{"line_number":42,"context_line":")"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"bbd73d89_5fae852f","line":41,"in_reply_to":"564bb87f_1bd64216","updated":"2025-09-02 12:57:16.000000000","message":"I think it got copied from here https://opendev.org/openstack/horizon/src/branch/master/openstack_dashboard/dashboards/project/instances/tables.py#L1204\n\nIt is translation text. It provides a contextual hint to translators for words that have multiple meanings.\n\nIt needs to be corrected. Can we fix it as a follow up?","commit_id":"1d75e29fc37baac5e6fea1ce4e896991c8a6dd77"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"f32aee100c890dc0fef8216cf731df7a586e63c1","unresolved":true,"context_lines":[{"line_number":38,"context_line":"    (\"FAILED\", pgettext_lazy(\"Power state of an Instance\", u\"Failed\")),"},{"line_number":39,"context_line":"    (\"DELETED\", pgettext_lazy(\"Power state of an Instance\", u\"Deleted\")),"},{"line_number":40,"context_line":"    (\"PENDING\", pgettext_lazy(\"Power state of an Instance\", u\"Pending\")),"},{"line_number":41,"context_line":"    (\"SKIPPED\", pgettext_lazy(\"Power state of an Instance\", u\"Skipped\")),"},{"line_number":42,"context_line":")"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"2ed82dcb_a6782f97","line":41,"in_reply_to":"5e2bba2f_72068b87","updated":"2025-09-02 14:29:23.000000000","message":"Addressed it here https://review.opendev.org/c/openstack/watcher-dashboard/+/959189","commit_id":"1d75e29fc37baac5e6fea1ce4e896991c8a6dd77"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"aab06dba6f8f4a123dbe2bd31784548ba339bc4f","unresolved":true,"context_lines":[{"line_number":38,"context_line":"    (\"FAILED\", pgettext_lazy(\"Power state of an Instance\", u\"Failed\")),"},{"line_number":39,"context_line":"    (\"DELETED\", pgettext_lazy(\"Power state of an Instance\", u\"Deleted\")),"},{"line_number":40,"context_line":"    (\"PENDING\", pgettext_lazy(\"Power state of an Instance\", u\"Pending\")),"},{"line_number":41,"context_line":"    (\"SKIPPED\", pgettext_lazy(\"Power state of an Instance\", u\"Skipped\")),"},{"line_number":42,"context_line":")"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"5e2bba2f_72068b87","line":41,"in_reply_to":"bbd73d89_5fae852f","updated":"2025-09-02 12:59:25.000000000","message":"thanks for the context, I think we can fix this in a follow up since it was already present before this patch","commit_id":"1d75e29fc37baac5e6fea1ce4e896991c8a6dd77"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"e645c9f574d51ae8602b168470164373c3fb1645","unresolved":true,"context_lines":[{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        # Check if action updates are supported by trying to get the client"},{"line_number":79,"context_line":"        try:"},{"line_number":80,"context_line":"            from watcher_dashboard.api import watcher"},{"line_number":81,"context_line":"            client \u003d watcher.watcherclient(request)"},{"line_number":82,"context_line":"            # If the action manager doesn\u0027t have update method, hide button"},{"line_number":83,"context_line":"            return (hasattr(client.action, \u0027update\u0027) or"}],"source_content_type":"text/x-python","patch_set":20,"id":"81f65e39_8f4da1fc","line":80,"updated":"2025-09-04 10:40:20.000000000","message":"this import is already done in line 28","commit_id":"e807aeb1cf9fa6d145c56a5bacd72fa276645a4c"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"90edb189d881773270175181de001ad9057ba630","unresolved":false,"context_lines":[{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        # Check if action updates are supported by trying to get the client"},{"line_number":79,"context_line":"        try:"},{"line_number":80,"context_line":"            from watcher_dashboard.api import watcher"},{"line_number":81,"context_line":"            client \u003d watcher.watcherclient(request)"},{"line_number":82,"context_line":"            # If the action manager doesn\u0027t have update method, hide button"},{"line_number":83,"context_line":"            return (hasattr(client.action, \u0027update\u0027) or"}],"source_content_type":"text/x-python","patch_set":20,"id":"9fb0f90f_095ace5e","line":80,"in_reply_to":"81f65e39_8f4da1fc","updated":"2025-09-09 09:01:41.000000000","message":"Done","commit_id":"e807aeb1cf9fa6d145c56a5bacd72fa276645a4c"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"1b5529c04686f9af568508cf272830eb4c99bb82","unresolved":true,"context_lines":[{"line_number":105,"context_line":"    policy_rules \u003d ((\"infra-optim\", \"action:update\"),)"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"    def allowed(self, request, action):"},{"line_number":108,"context_line":"        # Allow skipping when PENDING and allow updating reason when SKIPPED"},{"line_number":109,"context_line":"        if not (action and action.state in (\"PENDING\", \"SKIPPED\")):"},{"line_number":110,"context_line":"            return False"},{"line_number":111,"context_line":"        # Only show when the minimum microversion for skip is supported"},{"line_number":112,"context_line":"        return _supports_skip_api(request)"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    @staticmethod"},{"line_number":115,"context_line":"    def action_present(count):"}],"source_content_type":"text/x-python","patch_set":25,"id":"8bd66db6_46e6e3cd","line":112,"range":{"start_line":108,"start_character":0,"end_line":112,"end_character":42},"updated":"2025-09-19 09:20:15.000000000","message":"ideally, we should also check the state of the parent actionplan. Changing the state is only supported when the actionplan is in recommended or pending, see https://github.com/openstack/watcher/blob/master/watcher/api/controllers/v1/action.py#L432-L435\n\nIn case someone tries to skip a pending action in an ongoing action, it would receive an error from the API, but it\u0027d be good to add the check here imo.","commit_id":"e7fbc5f512273f63c5094194f5ac0111ef8d8038"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"de0b2d6c898e58ae62f6fbed45c614961dcc6536","unresolved":false,"context_lines":[{"line_number":105,"context_line":"    policy_rules \u003d ((\"infra-optim\", \"action:update\"),)"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"    def allowed(self, request, action):"},{"line_number":108,"context_line":"        # Allow skipping when PENDING and allow updating reason when SKIPPED"},{"line_number":109,"context_line":"        if not (action and action.state in (\"PENDING\", \"SKIPPED\")):"},{"line_number":110,"context_line":"            return False"},{"line_number":111,"context_line":"        # Only show when the minimum microversion for skip is supported"},{"line_number":112,"context_line":"        return _supports_skip_api(request)"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    @staticmethod"},{"line_number":115,"context_line":"    def action_present(count):"}],"source_content_type":"text/x-python","patch_set":25,"id":"5154f1df_7000e392","line":112,"range":{"start_line":108,"start_character":0,"end_line":112,"end_character":42},"in_reply_to":"8bd66db6_46e6e3cd","updated":"2025-09-29 04:59:16.000000000","message":"Done","commit_id":"e7fbc5f512273f63c5094194f5ac0111ef8d8038"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":63,"context_line":"        # Silently handle older clouds without logging exceptions"},{"line_number":64,"context_line":"        supported \u003d False"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    setattr(request, \u0027_watcher_supports_skip_api\u0027, supported)"},{"line_number":67,"context_line":"    return supported"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"43c94757_ccf4fee1","line":66,"range":{"start_line":66,"start_character":4,"end_line":66,"end_character":61},"updated":"2025-10-08 15:08:16.000000000","message":"so here you are adding another dynamic attribute. Why not stay only with the cached \u0027_watcher_microversion_range\u0027 and just check if ```supported \u003d common_client.is_supported(mv_range, common_client.SKIP_ACTION)```? the cached microversion is already validated in \u0027get_server_microversion_range\u0027","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":true,"context_lines":[{"line_number":63,"context_line":"        # Silently handle older clouds without logging exceptions"},{"line_number":64,"context_line":"        supported \u003d False"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    setattr(request, \u0027_watcher_supports_skip_api\u0027, supported)"},{"line_number":67,"context_line":"    return supported"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"4a6e3aae_c5560a33","line":66,"range":{"start_line":66,"start_character":4,"end_line":66,"end_character":61},"in_reply_to":"43c94757_ccf4fee1","updated":"2025-10-10 15:10:41.000000000","message":"yup","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ca56d701388ca74db085f2efbcb838c9b0e0b780","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        # Silently handle older clouds without logging exceptions"},{"line_number":64,"context_line":"        supported \u003d False"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    setattr(request, \u0027_watcher_supports_skip_api\u0027, supported)"},{"line_number":67,"context_line":"    return supported"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"be6f3854_af458306","line":66,"range":{"start_line":66,"start_character":4,"end_line":66,"end_character":61},"in_reply_to":"4a6e3aae_c5560a33","updated":"2025-11-26 05:46:11.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":113,"context_line":"            return False"},{"line_number":114,"context_line":"        # Only allow when the parent Action Plan is in RECOMMENDED or PENDING"},{"line_number":115,"context_line":"        try:"},{"line_number":116,"context_line":"            action_plan_uuid \u003d getattr(action, \u0027action_plan_uuid\u0027, None)"},{"line_number":117,"context_line":"            if not action_plan_uuid:"},{"line_number":118,"context_line":"                return False"},{"line_number":119,"context_line":"            action_plan \u003d watcher.ActionPlan.get(request, action_plan_uuid)"},{"line_number":120,"context_line":"            parent_state \u003d getattr(action_plan, \u0027state\u0027, None)"},{"line_number":121,"context_line":"            if parent_state not in (\"RECOMMENDED\", \"PENDING\"):"},{"line_number":122,"context_line":"                return False"},{"line_number":123,"context_line":"        except Exception:"}],"source_content_type":"text/x-python","patch_set":30,"id":"f4f78544_190603d5","line":120,"range":{"start_line":116,"start_character":0,"end_line":120,"end_character":62},"updated":"2025-10-08 15:08:16.000000000","message":"action_plan_uuid and state should always exist i think, so we might be able to remove these getattr","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":false,"context_lines":[{"line_number":113,"context_line":"            return False"},{"line_number":114,"context_line":"        # Only allow when the parent Action Plan is in RECOMMENDED or PENDING"},{"line_number":115,"context_line":"        try:"},{"line_number":116,"context_line":"            action_plan_uuid \u003d getattr(action, \u0027action_plan_uuid\u0027, None)"},{"line_number":117,"context_line":"            if not action_plan_uuid:"},{"line_number":118,"context_line":"                return False"},{"line_number":119,"context_line":"            action_plan \u003d watcher.ActionPlan.get(request, action_plan_uuid)"},{"line_number":120,"context_line":"            parent_state \u003d getattr(action_plan, \u0027state\u0027, None)"},{"line_number":121,"context_line":"            if parent_state not in (\"RECOMMENDED\", \"PENDING\"):"},{"line_number":122,"context_line":"                return False"},{"line_number":123,"context_line":"        except Exception:"}],"source_content_type":"text/x-python","patch_set":30,"id":"9f7b1fd4_c7cf124e","line":120,"range":{"start_line":116,"start_character":0,"end_line":120,"end_character":62},"in_reply_to":"f4f78544_190603d5","updated":"2025-10-10 15:10:41.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cf5770ef24939fbdc459a03a9b1bc6d75d2c0ac8","unresolved":true,"context_lines":[{"line_number":177,"context_line":"        return datum.uuid"},{"line_number":178,"context_line":""},{"line_number":179,"context_line":"    def __init__(self, request, data\u003dNone, needs_form_wrapper\u003dNone, **kwargs):"},{"line_number":180,"context_line":"        # Prefer explicit kwarg from the view; fallback to request-scoped hint"},{"line_number":181,"context_line":"        parent_succeeded \u003d kwargs.pop(\u0027parent_succeeded\u0027, None)"},{"line_number":182,"context_line":"        supports_skip \u003d kwargs.pop(\u0027supports_skip\u0027, None)"},{"line_number":183,"context_line":"        if parent_succeeded is None:"},{"line_number":184,"context_line":"            # Dynamic attribute needed - request used as temporary data store"},{"line_number":185,"context_line":"            # for passing action plan state between components"},{"line_number":186,"context_line":"            try:"},{"line_number":187,"context_line":"                req_state \u003d request._watcher_current_action_plan_state"},{"line_number":188,"context_line":"            except AttributeError:"},{"line_number":189,"context_line":"                req_state \u003d None"},{"line_number":190,"context_line":"            parent_succeeded \u003d req_state \u003d\u003d \u0027SUCCEEDED\u0027"},{"line_number":191,"context_line":"        self._parent_succeeded \u003d bool(parent_succeeded)"},{"line_number":192,"context_line":""},{"line_number":193,"context_line":"        # Use caller-provided support flag when available; otherwise, discover"},{"line_number":194,"context_line":"        self._supports_api_1_5 \u003d ("},{"line_number":195,"context_line":"            bool(supports_skip)"},{"line_number":196,"context_line":"            if supports_skip is not None"},{"line_number":197,"context_line":"            else _supports_skip_api(request)"},{"line_number":198,"context_line":"        )"},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"        # If parent succeeded, drop row actions entirely to hide the column"},{"line_number":201,"context_line":"        if self._parent_succeeded:"},{"line_number":202,"context_line":"            self._meta.row_actions \u003d ()"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":"        super().__init__("},{"line_number":205,"context_line":"            request,"},{"line_number":206,"context_line":"            data\u003ddata,"},{"line_number":207,"context_line":"            needs_form_wrapper\u003dneeds_form_wrapper,"},{"line_number":208,"context_line":"            **kwargs"},{"line_number":209,"context_line":"        )"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"    def get_row_actions(self, datum):"},{"line_number":212,"context_line":"        \"\"\"Return row actions only if allowed by MV and plan state.\"\"\""},{"line_number":213,"context_line":"        if not self._supports_api_1_5:"}],"source_content_type":"text/x-python","patch_set":40,"id":"7c5c420c_141bef67","line":210,"range":{"start_line":180,"start_character":0,"end_line":210,"end_character":1},"updated":"2026-02-25 18:30:48.000000000","message":"this is all exceptionally messy code.\n\nwe shoudl not have to handel the caller optionally passing supports_skip like this.\n\nwe shoudl also not be calling  bool(supports_skip) it should already be a boolean if we are passing it as an augment.\n\nwe are deifnine this as \n\nsupports_skip \u003d kwargs.pop(\u0027supports_skip\u0027, None)\n\nso we only ever take teh fi side  of \n\n       self._supports_api_1_5 \u003d (\n            bool(supports_skip)\n            if supports_skip is not None\n            else _supports_skip_api(request)\n        )\nwhen its not noen so that means we passed it and we shoudl not be passing a string in that case.","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"adabc2734fd6d4c6d6f4d13bba4777f35b0a4e21","unresolved":false,"context_lines":[{"line_number":177,"context_line":"        return datum.uuid"},{"line_number":178,"context_line":""},{"line_number":179,"context_line":"    def __init__(self, request, data\u003dNone, needs_form_wrapper\u003dNone, **kwargs):"},{"line_number":180,"context_line":"        # Prefer explicit kwarg from the view; fallback to request-scoped hint"},{"line_number":181,"context_line":"        parent_succeeded \u003d kwargs.pop(\u0027parent_succeeded\u0027, None)"},{"line_number":182,"context_line":"        supports_skip \u003d kwargs.pop(\u0027supports_skip\u0027, None)"},{"line_number":183,"context_line":"        if parent_succeeded is None:"},{"line_number":184,"context_line":"            # Dynamic attribute needed - request used as temporary data store"},{"line_number":185,"context_line":"            # for passing action plan state between components"},{"line_number":186,"context_line":"            try:"},{"line_number":187,"context_line":"                req_state \u003d request._watcher_current_action_plan_state"},{"line_number":188,"context_line":"            except AttributeError:"},{"line_number":189,"context_line":"                req_state \u003d None"},{"line_number":190,"context_line":"            parent_succeeded \u003d req_state \u003d\u003d \u0027SUCCEEDED\u0027"},{"line_number":191,"context_line":"        self._parent_succeeded \u003d bool(parent_succeeded)"},{"line_number":192,"context_line":""},{"line_number":193,"context_line":"        # Use caller-provided support flag when available; otherwise, discover"},{"line_number":194,"context_line":"        self._supports_api_1_5 \u003d ("},{"line_number":195,"context_line":"            bool(supports_skip)"},{"line_number":196,"context_line":"            if supports_skip is not None"},{"line_number":197,"context_line":"            else _supports_skip_api(request)"},{"line_number":198,"context_line":"        )"},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"        # If parent succeeded, drop row actions entirely to hide the column"},{"line_number":201,"context_line":"        if self._parent_succeeded:"},{"line_number":202,"context_line":"            self._meta.row_actions \u003d ()"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":"        super().__init__("},{"line_number":205,"context_line":"            request,"},{"line_number":206,"context_line":"            data\u003ddata,"},{"line_number":207,"context_line":"            needs_form_wrapper\u003dneeds_form_wrapper,"},{"line_number":208,"context_line":"            **kwargs"},{"line_number":209,"context_line":"        )"},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"    def get_row_actions(self, datum):"},{"line_number":212,"context_line":"        \"\"\"Return row actions only if allowed by MV and plan state.\"\"\""},{"line_number":213,"context_line":"        if not self._supports_api_1_5:"}],"source_content_type":"text/x-python","patch_set":40,"id":"1183882e_8f0b782d","line":210,"range":{"start_line":180,"start_character":0,"end_line":210,"end_character":1},"in_reply_to":"7c5c420c_141bef67","updated":"2026-03-03 20:10:08.000000000","message":"Acknowledged","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cf5770ef24939fbdc459a03a9b1bc6d75d2c0ac8","unresolved":true,"context_lines":[{"line_number":238,"context_line":"        if req_state \u003d\u003d \u0027SUCCEEDED\u0027:"},{"line_number":239,"context_line":"            return False"},{"line_number":240,"context_line":"        # Default behavior: show if there are row actions defined"},{"line_number":241,"context_line":"        return bool(self._meta.row_actions)"},{"line_number":242,"context_line":""},{"line_number":243,"context_line":"    class Meta:"},{"line_number":244,"context_line":"        name \u003d \"related_wactions\""}],"source_content_type":"text/x-python","patch_set":40,"id":"9336ee34_7ab46a8a","line":241,"range":{"start_line":241,"start_character":15,"end_line":241,"end_character":43},"updated":"2026-02-25 18:30:48.000000000","message":"using bool like thsi is also a bit of  a code smell\n\nthe correct thign to do would likely be \n\n```suggestion\n        return len(self._meta.row_actions) \u003e0\n```\n\nthere is an implict convertion of non empty list to True\nbut that isnt as clare as expressing your intet.","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ffff5a8378c3a631db8e5ff1502fcb009d4330d5","unresolved":false,"context_lines":[{"line_number":238,"context_line":"        if req_state \u003d\u003d \u0027SUCCEEDED\u0027:"},{"line_number":239,"context_line":"            return False"},{"line_number":240,"context_line":"        # Default behavior: show if there are row actions defined"},{"line_number":241,"context_line":"        return bool(self._meta.row_actions)"},{"line_number":242,"context_line":""},{"line_number":243,"context_line":"    class Meta:"},{"line_number":244,"context_line":"        name \u003d \"related_wactions\""}],"source_content_type":"text/x-python","patch_set":40,"id":"c67df246_9c29cf02","line":241,"range":{"start_line":241,"start_character":15,"end_line":241,"end_character":43},"in_reply_to":"9336ee34_7ab46a8a","updated":"2026-02-26 15:18:26.000000000","message":"Done","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"72a2089ade5b16ecb858dfe4a819221f7257eeac","unresolved":true,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from django.template.defaultfilters import title  # noqa"},{"line_number":19,"context_line":"from django import urls"},{"line_number":20,"context_line":"from django.utils.translation import gettext_lazy as _"},{"line_number":21,"context_line":"from django.utils.translation import ngettext_lazy"},{"line_number":22,"context_line":"from django.utils.translation import pgettext_lazy"},{"line_number":23,"context_line":"import horizon.exceptions"},{"line_number":24,"context_line":"import horizon.messages"},{"line_number":25,"context_line":"import horizon.tables"}],"source_content_type":"text/x-python","patch_set":44,"id":"9a15a656_9b8a88dd","line":22,"range":{"start_line":20,"start_character":0,"end_line":22,"end_character":50},"updated":"2026-02-26 20:02:33.000000000","message":"this really should be \n\n```suggestion\nfrom django.utils import translation\n```\n\nand later do\n_ \u003d translation.gettext_lazy\n\nyou shoudl use translation.ngettext_lazy below as needed\n\nhttps://github.com/openstack/hacking/blob/master/HACKING.rst?plain\u003d1#L58\n\ni guess we can fix this later all of this will have to be cleaned up shortly when i apply ruff to the repo after we tag RC1","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"adabc2734fd6d4c6d6f4d13bba4777f35b0a4e21","unresolved":false,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from django.template.defaultfilters import title  # noqa"},{"line_number":19,"context_line":"from django import urls"},{"line_number":20,"context_line":"from django.utils.translation import gettext_lazy as _"},{"line_number":21,"context_line":"from django.utils.translation import ngettext_lazy"},{"line_number":22,"context_line":"from django.utils.translation import pgettext_lazy"},{"line_number":23,"context_line":"import horizon.exceptions"},{"line_number":24,"context_line":"import horizon.messages"},{"line_number":25,"context_line":"import horizon.tables"}],"source_content_type":"text/x-python","patch_set":44,"id":"72a23c31_57380d80","line":22,"range":{"start_line":20,"start_character":0,"end_line":22,"end_character":50},"in_reply_to":"9a15a656_9b8a88dd","updated":"2026-03-03 20:10:08.000000000","message":"Acknowledged","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"72a2089ade5b16ecb858dfe4a819221f7257eeac","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    classes \u003d (\"ajax-modal\", \"btn-danger\")"},{"line_number":71,"context_line":"    policy_rules \u003d ((\"infra-optim\", \"action:update\"),)"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def allowed(self, request, action):"},{"line_number":74,"context_line":"        if not (action and action.state in (\"PENDING\", \"SKIPPED\")):"},{"line_number":75,"context_line":"            return False"},{"line_number":76,"context_line":"        return True"}],"source_content_type":"text/x-python","patch_set":44,"id":"600faab9_71a316db","line":73,"in_reply_to":"fdaa4d94_7f5f2cf6","updated":"2026-02-26 20:02:33.000000000","message":"i think the api woudl block this (its a bug if it didnt) but we should not preset the option to skip in the ui if the the action plan is running or completed since it shoudl not be possibel to retoactivly change it.\n\ni think we can ignore this for now.\n\nthis woudl be checked elsewhere","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"72a2089ade5b16ecb858dfe4a819221f7257eeac","unresolved":true,"context_lines":[{"line_number":75,"context_line":"            return False"},{"line_number":76,"context_line":"        return True"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    @staticmethod"},{"line_number":79,"context_line":"    def action_present(count):"},{"line_number":80,"context_line":"        return ngettext_lazy("},{"line_number":81,"context_line":"            \"Skip Action\","},{"line_number":82,"context_line":"            \"Skip Actions\","},{"line_number":83,"context_line":"            count"},{"line_number":84,"context_line":"        )"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    @staticmethod"},{"line_number":87,"context_line":"    def action_past(count):"},{"line_number":88,"context_line":"        return ngettext_lazy("},{"line_number":89,"context_line":"            \"Skipped Action\","},{"line_number":90,"context_line":"            \"Skipped Actions\","},{"line_number":91,"context_line":"            count"},{"line_number":92,"context_line":"        )"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"def get_action_plan_link(datum):"},{"line_number":96,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":44,"id":"4947167b_33ef1546","line":93,"range":{"start_line":78,"start_character":3,"end_line":93,"end_character":1},"updated":"2026-02-26 20:02:33.000000000","message":"im not sure we need the plural form or pasted tence do we?\n\nwehre is this printing in the ui?","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"a34cbf1cd07b2a57b758783f1eba4945f418c09e","unresolved":false,"context_lines":[{"line_number":75,"context_line":"            return False"},{"line_number":76,"context_line":"        return True"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    @staticmethod"},{"line_number":79,"context_line":"    def action_present(count):"},{"line_number":80,"context_line":"        return ngettext_lazy("},{"line_number":81,"context_line":"            \"Skip Action\","},{"line_number":82,"context_line":"            \"Skip Actions\","},{"line_number":83,"context_line":"            count"},{"line_number":84,"context_line":"        )"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    @staticmethod"},{"line_number":87,"context_line":"    def action_past(count):"},{"line_number":88,"context_line":"        return ngettext_lazy("},{"line_number":89,"context_line":"            \"Skipped Action\","},{"line_number":90,"context_line":"            \"Skipped Actions\","},{"line_number":91,"context_line":"            count"},{"line_number":92,"context_line":"        )"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"def get_action_plan_link(datum):"},{"line_number":96,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":44,"id":"9ff34bcd_081196f7","line":93,"range":{"start_line":78,"start_character":3,"end_line":93,"end_character":1},"in_reply_to":"23cfc6b6_a683f0c3","updated":"2026-03-03 07:36:49.000000000","message":"Done","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7d3d0986fb1dc653e515a4351eb7d7b40b816512","unresolved":true,"context_lines":[{"line_number":75,"context_line":"            return False"},{"line_number":76,"context_line":"        return True"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    @staticmethod"},{"line_number":79,"context_line":"    def action_present(count):"},{"line_number":80,"context_line":"        return ngettext_lazy("},{"line_number":81,"context_line":"            \"Skip Action\","},{"line_number":82,"context_line":"            \"Skip Actions\","},{"line_number":83,"context_line":"            count"},{"line_number":84,"context_line":"        )"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    @staticmethod"},{"line_number":87,"context_line":"    def action_past(count):"},{"line_number":88,"context_line":"        return ngettext_lazy("},{"line_number":89,"context_line":"            \"Skipped Action\","},{"line_number":90,"context_line":"            \"Skipped Actions\","},{"line_number":91,"context_line":"            count"},{"line_number":92,"context_line":"        )"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"def get_action_plan_link(datum):"},{"line_number":96,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":44,"id":"23cfc6b6_a683f0c3","line":93,"range":{"start_line":78,"start_character":3,"end_line":93,"end_character":1},"in_reply_to":"4947167b_33ef1546","updated":"2026-02-27 10:59:20.000000000","message":"Nope, we donot need. We donot display plurals in UI. It got carry forward from initial patchset. https://review.opendev.org/c/openstack/watcher-dashboard/+/958209/1/watcher_dashboard/content/actions/tables.py. I will drop once I respin this patch.","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"}],"watcher_dashboard/content/actions/views.py":[{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"0cae1e1aeadf5a4556bf2e10c656d59753a5358f","unresolved":true,"context_lines":[{"line_number":119,"context_line":"    page_title \u003d _(\"Skip Action\")"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def get_success_url(self):"},{"line_number":122,"context_line":"        return reverse(\"horizon:admin:action_plans:index\")"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    def get_context_data(self, **kwargs):"},{"line_number":125,"context_line":"        context \u003d super(SkipActionView, self).get_context_data(**kwargs)"}],"source_content_type":"text/x-python","patch_set":9,"id":"4977a255_2186273a","line":122,"range":{"start_line":122,"start_character":0,"end_line":122,"end_character":58},"updated":"2025-08-29 18:30:37.000000000","message":"instead of getting back to the index, I think that we should go back to the horizon:admin:action_plans:detail instead. But you would need to get the action_plan_uuid from the Action I think","commit_id":"acfb5a24ee8f2e9c9f5c2f84e91091ffad09877c"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"d1c00181e923c8e6fd15ff19564d03818b693606","unresolved":true,"context_lines":[{"line_number":119,"context_line":"    page_title \u003d _(\"Skip Action\")"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def get_success_url(self):"},{"line_number":122,"context_line":"        return reverse(\"horizon:admin:action_plans:index\")"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    def get_context_data(self, **kwargs):"},{"line_number":125,"context_line":"        context \u003d super(SkipActionView, self).get_context_data(**kwargs)"}],"source_content_type":"text/x-python","patch_set":9,"id":"e163b678_6bdabe04","line":122,"range":{"start_line":122,"start_character":0,"end_line":122,"end_character":58},"in_reply_to":"4977a255_2186273a","updated":"2025-09-01 05:01:03.000000000","message":"Thanks for the pointer, can you check now?","commit_id":"acfb5a24ee8f2e9c9f5c2f84e91091ffad09877c"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ca56d701388ca74db085f2efbcb838c9b0e0b780","unresolved":false,"context_lines":[{"line_number":119,"context_line":"    page_title \u003d _(\"Skip Action\")"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def get_success_url(self):"},{"line_number":122,"context_line":"        return reverse(\"horizon:admin:action_plans:index\")"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    def get_context_data(self, **kwargs):"},{"line_number":125,"context_line":"        context \u003d super(SkipActionView, self).get_context_data(**kwargs)"}],"source_content_type":"text/x-python","patch_set":9,"id":"da95f56a_de5ed4e6","line":122,"range":{"start_line":122,"start_character":0,"end_line":122,"end_character":58},"in_reply_to":"e163b678_6bdabe04","updated":"2025-11-26 05:46:11.000000000","message":"Done","commit_id":"acfb5a24ee8f2e9c9f5c2f84e91091ffad09877c"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":103,"context_line":"        action \u003d self._get_data()"},{"line_number":104,"context_line":"        context[\"action\"] \u003d action"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        # Show status_message only when API 1.5 is supported or action has it"},{"line_number":107,"context_line":"        context[\"show_status_message\"] \u003d ("},{"line_number":108,"context_line":"            self._should_show_status_message(action))"},{"line_number":109,"context_line":"        return context"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def _should_show_status_message(self, action):"}],"source_content_type":"text/x-python","patch_set":30,"id":"bec5ec53_867b4797","line":108,"range":{"start_line":106,"start_character":0,"end_line":108,"end_character":53},"updated":"2025-10-08 15:08:16.000000000","message":"I don\u0027t think this is needed here. You can always display the Status Message field in the UI, what would change is that we can keep or drop the content from Action.status_message, based on the supported microversion.","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ffff5a8378c3a631db8e5ff1502fcb009d4330d5","unresolved":false,"context_lines":[{"line_number":103,"context_line":"        action \u003d self._get_data()"},{"line_number":104,"context_line":"        context[\"action\"] \u003d action"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        # Show status_message only when API 1.5 is supported or action has it"},{"line_number":107,"context_line":"        context[\"show_status_message\"] \u003d ("},{"line_number":108,"context_line":"            self._should_show_status_message(action))"},{"line_number":109,"context_line":"        return context"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def _should_show_status_message(self, action):"}],"source_content_type":"text/x-python","patch_set":30,"id":"1da43445_e8dbb9db","line":108,"range":{"start_line":106,"start_character":0,"end_line":108,"end_character":53},"in_reply_to":"94df4597_30e8127c","updated":"2026-02-26 15:18:26.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":true,"context_lines":[{"line_number":103,"context_line":"        action \u003d self._get_data()"},{"line_number":104,"context_line":"        context[\"action\"] \u003d action"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        # Show status_message only when API 1.5 is supported or action has it"},{"line_number":107,"context_line":"        context[\"show_status_message\"] \u003d ("},{"line_number":108,"context_line":"            self._should_show_status_message(action))"},{"line_number":109,"context_line":"        return context"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def _should_show_status_message(self, action):"}],"source_content_type":"text/x-python","patch_set":30,"id":"94df4597_30e8127c","line":108,"range":{"start_line":106,"start_character":0,"end_line":108,"end_character":53},"in_reply_to":"bec5ec53_867b4797","updated":"2025-10-10 15:10:41.000000000","message":"yes","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":108,"context_line":"            self._should_show_status_message(action))"},{"line_number":109,"context_line":"        return context"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def _should_show_status_message(self, action):"},{"line_number":112,"context_line":"        \"\"\"Determine if status message should be shown."},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"        Returns True if:"}],"source_content_type":"text/x-python","patch_set":30,"id":"b82655d5_d4940acc","line":111,"range":{"start_line":111,"start_character":0,"end_line":111,"end_character":50},"updated":"2025-10-08 15:08:16.000000000","message":"we have more than one place that is doing the similar things at this point, e.g:\n1. here\n2. https://review.opendev.org/c/openstack/watcher-dashboard/+/958209/30/watcher_dashboard/content/actions/tables.py#35","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ca56d701388ca74db085f2efbcb838c9b0e0b780","unresolved":false,"context_lines":[{"line_number":108,"context_line":"            self._should_show_status_message(action))"},{"line_number":109,"context_line":"        return context"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def _should_show_status_message(self, action):"},{"line_number":112,"context_line":"        \"\"\"Determine if status message should be shown."},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"        Returns True if:"}],"source_content_type":"text/x-python","patch_set":30,"id":"6e82e7f4_e14301c5","line":111,"range":{"start_line":111,"start_character":0,"end_line":111,"end_character":50},"in_reply_to":"7847c5bf_cb37780a","updated":"2025-11-26 05:46:11.000000000","message":"Done","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":true,"context_lines":[{"line_number":108,"context_line":"            self._should_show_status_message(action))"},{"line_number":109,"context_line":"        return context"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def _should_show_status_message(self, action):"},{"line_number":112,"context_line":"        \"\"\"Determine if status message should be shown."},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"        Returns True if:"}],"source_content_type":"text/x-python","patch_set":30,"id":"7847c5bf_cb37780a","line":111,"range":{"start_line":111,"start_character":0,"end_line":111,"end_character":50},"in_reply_to":"b82655d5_d4940acc","updated":"2025-10-10 15:10:41.000000000","message":"yes good catch","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"72a2089ade5b16ecb858dfe4a819221f7257eeac","unresolved":true,"context_lines":[{"line_number":89,"context_line":"        parameter_cls \u003d collections.namedtuple("},{"line_number":90,"context_line":"            \u0027Parameter\u0027, field_names\u003d[\u0027name\u0027, \u0027value\u0027])"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"        return [parameter_cls(name\u003dname, value\u003dvalue)"},{"line_number":93,"context_line":"                for name, value in action.input_parameters.items()]"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    def get_context_data(self, **kwargs):"},{"line_number":96,"context_line":"        context \u003d super().get_context_data(**kwargs)"}],"source_content_type":"text/x-python","patch_set":44,"id":"76995bd7_f20c1e6b","side":"PARENT","line":93,"range":{"start_line":92,"start_character":7,"end_line":93,"end_character":67},"updated":"2026-02-26 20:02:33.000000000","message":"the previous code assuemed that action.input_parameters.items() is alwasy safe to call \nbut the updated code assumes that action may not even have input_parmaeter\n``` \n   try:\n            params \u003d action.input_parameters\n        except AttributeError:\n            # Handle mapping-like action (e.g., dict in tests) via EAFP\n            try:\n                params \u003d action.get(\u0027input_parameters\u0027)\n            except AttributeError:\n                params \u003d None\n        if not isinstance(params, dict):\n            return []\n```\n why? this seam like a massive regression.","commit_id":"3e1db2ba6d3ffd8b79fe0a4bc8f2650ff2f68cf9"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"a34cbf1cd07b2a57b758783f1eba4945f418c09e","unresolved":true,"context_lines":[{"line_number":89,"context_line":"        parameter_cls \u003d collections.namedtuple("},{"line_number":90,"context_line":"            \u0027Parameter\u0027, field_names\u003d[\u0027name\u0027, \u0027value\u0027])"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"        return [parameter_cls(name\u003dname, value\u003dvalue)"},{"line_number":93,"context_line":"                for name, value in action.input_parameters.items()]"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    def get_context_data(self, **kwargs):"},{"line_number":96,"context_line":"        context \u003d super().get_context_data(**kwargs)"}],"source_content_type":"text/x-python","patch_set":44,"id":"d305acae_303246c4","side":"PARENT","line":93,"range":{"start_line":92,"start_character":7,"end_line":93,"end_character":67},"in_reply_to":"76995bd7_f20c1e6b","updated":"2026-03-03 07:36:49.000000000","message":"My mistake, dropped it from current changes.","commit_id":"3e1db2ba6d3ffd8b79fe0a4bc8f2650ff2f68cf9"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"adabc2734fd6d4c6d6f4d13bba4777f35b0a4e21","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        parameter_cls \u003d collections.namedtuple("},{"line_number":90,"context_line":"            \u0027Parameter\u0027, field_names\u003d[\u0027name\u0027, \u0027value\u0027])"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"        return [parameter_cls(name\u003dname, value\u003dvalue)"},{"line_number":93,"context_line":"                for name, value in action.input_parameters.items()]"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    def get_context_data(self, **kwargs):"},{"line_number":96,"context_line":"        context \u003d super().get_context_data(**kwargs)"}],"source_content_type":"text/x-python","patch_set":44,"id":"5fd5a0c8_d66093a1","side":"PARENT","line":93,"range":{"start_line":92,"start_character":7,"end_line":93,"end_character":67},"in_reply_to":"d305acae_303246c4","updated":"2026-03-03 20:10:08.000000000","message":"Done","commit_id":"3e1db2ba6d3ffd8b79fe0a4bc8f2650ff2f68cf9"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"29e65cdcf2cdf61a23dc814228f0bfdfe2fcddc1","unresolved":false,"context_lines":[{"line_number":141,"context_line":"        self._action_plan_uuid \u003d action.action_plan_uuid"},{"line_number":142,"context_line":"        return super().form_valid(form)"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"    def get_success_url(self):"},{"line_number":145,"context_line":"        \"\"\"Redirect to parent action plan detail after skip.\"\"\""},{"line_number":146,"context_line":"        if self._action_plan_uuid:"},{"line_number":147,"context_line":"            return reverse("}],"source_content_type":"text/x-python","patch_set":47,"id":"b79989e2_52454c0a","line":144,"range":{"start_line":144,"start_character":0,"end_line":144,"end_character":30},"updated":"2026-03-03 20:36:24.000000000","message":"this is great, I see that in playwrite change[1] it is redirecting properly, it was an issue in previous version of this patch (or similar) patch.\n\n[1] https://review.opendev.org/c/openstack/watcher-dashboard/+/958209/47","commit_id":"3a884013ecbca509d2379b090f2a16bb6206d2d5"}],"watcher_dashboard/content/audit_templates/forms.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cf5770ef24939fbdc459a03a9b1bc6d75d2c0ac8","unresolved":true,"context_lines":[{"line_number":77,"context_line":"        # If this is a POST, populate strategies for the selected goal so that"},{"line_number":78,"context_line":"        # server-side validation accepts the submitted value (mirrors the AJAX"},{"line_number":79,"context_line":"        # behavior in the template for client-side population)."},{"line_number":80,"context_line":"        try:"},{"line_number":81,"context_line":"            selected_goal \u003d self.data.get(\u0027goal\u0027)"},{"line_number":82,"context_line":"        except AttributeError:"},{"line_number":83,"context_line":"            selected_goal \u003d None"},{"line_number":84,"context_line":"        if selected_goal and \u0027strategy\u0027 in self.fields:"},{"line_number":85,"context_line":"            filtered_strategies \u003d self._get_strategy_list_for_goal("},{"line_number":86,"context_line":"                request, selected_goal)"}],"source_content_type":"text/x-python","patch_set":40,"id":"a7160237_edd63222","line":83,"range":{"start_line":80,"start_character":8,"end_line":83,"end_character":32},"updated":"2026-02-25 18:30:48.000000000","message":"```suggestion\n        selected_goal \u003d self.data.get(\u0027goal\u0027, None)\n```\n\ndata is never None\n\nhttps://github.com/django/django/blob/stable/6.0.x/django/forms/forms.py#L89\nhttps://github.com/django/django/blob/stable/5.2.x/django/forms/forms.py#L89\nhttps://github.com/django/django/blob/stable/4.2.x/django/forms/forms.py#L90\n\nso self.data will never raise Atibute error\n\nwe use get becuase on a key error it will return None because that is the default but nice to be explcity \n\n```\nselected_goal \u003d self.data.get(\u0027goal\u0027)\n```\n\ntechnialy ^ is enough.\n\nwe inherit form SelfHandlingForm\nwhich is just a standard django form with the request saved in self.request\n\nhttps://github.com/openstack/horizon/blob/master/horizon/forms/base.py#L32","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ffff5a8378c3a631db8e5ff1502fcb009d4330d5","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        # If this is a POST, populate strategies for the selected goal so that"},{"line_number":78,"context_line":"        # server-side validation accepts the submitted value (mirrors the AJAX"},{"line_number":79,"context_line":"        # behavior in the template for client-side population)."},{"line_number":80,"context_line":"        try:"},{"line_number":81,"context_line":"            selected_goal \u003d self.data.get(\u0027goal\u0027)"},{"line_number":82,"context_line":"        except AttributeError:"},{"line_number":83,"context_line":"            selected_goal \u003d None"},{"line_number":84,"context_line":"        if selected_goal and \u0027strategy\u0027 in self.fields:"},{"line_number":85,"context_line":"            filtered_strategies \u003d self._get_strategy_list_for_goal("},{"line_number":86,"context_line":"                request, selected_goal)"}],"source_content_type":"text/x-python","patch_set":40,"id":"f42e0146_6112c0e8","line":83,"range":{"start_line":80,"start_character":8,"end_line":83,"end_character":32},"in_reply_to":"a7160237_edd63222","updated":"2026-02-26 15:18:26.000000000","message":"Done","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cf5770ef24939fbdc459a03a9b1bc6d75d2c0ac8","unresolved":true,"context_lines":[{"line_number":140,"context_line":"            messages.warning(request, exc)"},{"line_number":141,"context_line":"            strategies \u003d []"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"        choices \u003d []"},{"line_number":144,"context_line":"        for strategy in strategies:"},{"line_number":145,"context_line":"            # Dynamic access needed across API versions; prefer EAFP"},{"line_number":146,"context_line":"            try:"},{"line_number":147,"context_line":"                display_name \u003d strategy.display_name"},{"line_number":148,"context_line":"            except AttributeError:"},{"line_number":149,"context_line":"                try:"},{"line_number":150,"context_line":"                    display_name \u003d strategy.name"},{"line_number":151,"context_line":"                except AttributeError:"},{"line_number":152,"context_line":"                    display_name \u003d \u0027\u0027"},{"line_number":153,"context_line":"            choices.append((strategy.uuid, display_name))"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"        if choices:"},{"line_number":156,"context_line":"            choices.insert(0, (\"\", _(\"Select Strategy\")))"},{"line_number":157,"context_line":"        return choices"}],"source_content_type":"text/x-python","patch_set":40,"id":"1d3ef9bc_646c2d99","line":154,"range":{"start_line":143,"start_character":2,"end_line":154,"end_character":1},"updated":"2026-02-25 18:30:48.000000000","message":"this is also not really any better then what w edid before\n\n\n\n```suggestion\n        choices \u003d []\n        for strategy in strategies:\n           data \u003d strategy.to_dict()\n           display_name \u003d data.get(\u0027display_name\u0027)\n           if display_name is None:\n             display_name \u003d data.get(\u0027name\u0027,\u0027\u0027)\n           choices.append((strategy.uuid, display_name))\n\n```","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ffff5a8378c3a631db8e5ff1502fcb009d4330d5","unresolved":true,"context_lines":[{"line_number":140,"context_line":"            messages.warning(request, exc)"},{"line_number":141,"context_line":"            strategies \u003d []"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"        choices \u003d []"},{"line_number":144,"context_line":"        for strategy in strategies:"},{"line_number":145,"context_line":"            # Dynamic access needed across API versions; prefer EAFP"},{"line_number":146,"context_line":"            try:"},{"line_number":147,"context_line":"                display_name \u003d strategy.display_name"},{"line_number":148,"context_line":"            except AttributeError:"},{"line_number":149,"context_line":"                try:"},{"line_number":150,"context_line":"                    display_name \u003d strategy.name"},{"line_number":151,"context_line":"                except AttributeError:"},{"line_number":152,"context_line":"                    display_name \u003d \u0027\u0027"},{"line_number":153,"context_line":"            choices.append((strategy.uuid, display_name))"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"        if choices:"},{"line_number":156,"context_line":"            choices.insert(0, (\"\", _(\"Select Strategy\")))"},{"line_number":157,"context_line":"        return choices"}],"source_content_type":"text/x-python","patch_set":40,"id":"eb63c5bc_14ca6f4d","line":154,"range":{"start_line":143,"start_character":2,"end_line":154,"end_character":1},"in_reply_to":"1d3ef9bc_646c2d99","updated":"2026-02-26 15:18:26.000000000","message":"Fixed it with wrapper method get_strategy_display_name","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"}],"watcher_dashboard/content/audit_templates/views.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cf5770ef24939fbdc459a03a9b1bc6d75d2c0ac8","unresolved":true,"context_lines":[{"line_number":158,"context_line":"                    display_name \u003d strategy.name"},{"line_number":159,"context_line":"                except AttributeError:"},{"line_number":160,"context_line":"                    display_name \u003d \u0027\u0027"},{"line_number":161,"context_line":"            data.append({\u0027uuid\u0027: strategy.uuid, \u0027display_name\u0027: display_name})"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"        return JsonResponse({\u0027strategies\u0027: data})"},{"line_number":164,"context_line":"    except Exception as exc:"}],"source_content_type":"text/x-python","patch_set":40,"id":"e0418022_187a10a9","line":161,"updated":"2026-02-25 18:30:48.000000000","message":"same comment here althogu ureally we shoudl update hte watcher client to have this as a properly on the return object here\n\nhttps://github.com/openstack/python-watcherclient/blob/master/watcherclient/v1/strategy.py#L22-L25\n\nfor now you shoudl provide a hleper function for this in the api module.\nlike this\n\nhttps://github.com/openstack/watcher-dashboard/blob/master/watcher_dashboard/api/watcher.py#L525-L527\n\nalthogh for that to work proeprly instead of retunign the wraw client object we would have to convertion it in get an list.\n\nthat a common bug in everyton one of those classses...\n\n```\nreturn watcherclient(request).strategy.get(strategy)\n```\n\nshoudl be\n \n```\nreturn cls(watcherclient(request).strategy.get(strategy))\n```\n\nyou can still add a static metod however that will do the conversion for you so you do not need to do this in muliple places.","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ffff5a8378c3a631db8e5ff1502fcb009d4330d5","unresolved":false,"context_lines":[{"line_number":158,"context_line":"                    display_name \u003d strategy.name"},{"line_number":159,"context_line":"                except AttributeError:"},{"line_number":160,"context_line":"                    display_name \u003d \u0027\u0027"},{"line_number":161,"context_line":"            data.append({\u0027uuid\u0027: strategy.uuid, \u0027display_name\u0027: display_name})"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"        return JsonResponse({\u0027strategies\u0027: data})"},{"line_number":164,"context_line":"    except Exception as exc:"}],"source_content_type":"text/x-python","patch_set":40,"id":"6dd60452_cbe67a88","line":161,"in_reply_to":"e0418022_187a10a9","updated":"2026-02-26 15:18:26.000000000","message":"Done","commit_id":"167b2ada6ee7338bbc35d4cc1341007f29a36094"}],"watcher_dashboard/templates/infra_optim/action_plans/details.html":[{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"68863a3836d63e956dba368842361530e8d43489","unresolved":true,"context_lines":[{"line_number":13,"context_line":"        display: none;"},{"line_number":14,"context_line":"      }"},{"line_number":15,"context_line":"    \u003c/style\u003e"},{"line_number":16,"context_line":"    {% elif show_related_actions and action_plan.state \u003d\u003d \u0027SUCCEEDED\u0027 %}"},{"line_number":17,"context_line":"    \u003cstyle\u003e"},{"line_number":18,"context_line":"      /* Hide Actions column header when action plan succeeded */"},{"line_number":19,"context_line":"      #related_wactions th:last-child {"}],"source_content_type":"text/html","patch_set":28,"id":"807c050a_52b7ed40","line":16,"range":{"start_line":16,"start_character":0,"end_line":16,"end_character":2},"updated":"2025-09-30 10:03:07.000000000","message":"+1 i like this","commit_id":"5018a4bb21bf76f6742b33511591cdccba8ca101"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"ca56d701388ca74db085f2efbcb838c9b0e0b780","unresolved":false,"context_lines":[{"line_number":13,"context_line":"        display: none;"},{"line_number":14,"context_line":"      }"},{"line_number":15,"context_line":"    \u003c/style\u003e"},{"line_number":16,"context_line":"    {% elif show_related_actions and action_plan.state \u003d\u003d \u0027SUCCEEDED\u0027 %}"},{"line_number":17,"context_line":"    \u003cstyle\u003e"},{"line_number":18,"context_line":"      /* Hide Actions column header when action plan succeeded */"},{"line_number":19,"context_line":"      #related_wactions th:last-child {"}],"source_content_type":"text/html","patch_set":28,"id":"2bc3b1dd_6b54edac","line":16,"range":{"start_line":16,"start_character":0,"end_line":16,"end_character":2},"in_reply_to":"807c050a_52b7ed40","updated":"2025-11-26 05:46:11.000000000","message":"Acknowledged","commit_id":"5018a4bb21bf76f6742b33511591cdccba8ca101"}],"watcher_dashboard/templates/infra_optim/actions/_skip.html":[{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"9c5ff80cddbefc56227dc0ae261152458617a18b","unresolved":true,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"{% block modal-body-right %}"},{"line_number":10,"context_line":"  \u003ch3\u003e{% trans \"Description\" %}\u003c/h3\u003e"},{"line_number":11,"context_line":"  \u003cp\u003e{% trans \"This action will mark the selected action as SKIPPED. You can optionally provide a reason that will be stored as the status message.\" %}\u003c/p\u003e"},{"line_number":12,"context_line":"  \u003cp\u003e{% trans \"Skipped actions will not be executed and cannot be restarted.\" %}\u003c/p\u003e"},{"line_number":13,"context_line":"{% endblock %} "}],"source_content_type":"text/html","patch_set":3,"id":"ecdeda4d_3e8c838f","line":11,"range":{"start_line":11,"start_character":15,"end_line":11,"end_character":147},"updated":"2025-08-28 19:03:10.000000000","message":"You can also update reason messages for Actions in SKIPPED state.","commit_id":"df7a850bc63e0ee72ecf389491d7f310f0ac2b06"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"672f380379c3047eb18c296ca16a6b2f00389b1a","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"{% block modal-body-right %}"},{"line_number":10,"context_line":"  \u003ch3\u003e{% trans \"Description\" %}\u003c/h3\u003e"},{"line_number":11,"context_line":"  \u003cp\u003e{% trans \"This action will mark the selected action as SKIPPED. You can optionally provide a reason that will be stored as the status message.\" %}\u003c/p\u003e"},{"line_number":12,"context_line":"  \u003cp\u003e{% trans \"Skipped actions will not be executed and cannot be restarted.\" %}\u003c/p\u003e"},{"line_number":13,"context_line":"{% endblock %} "}],"source_content_type":"text/html","patch_set":3,"id":"19752f44_481b4bf1","line":11,"range":{"start_line":11,"start_character":15,"end_line":11,"end_character":147},"in_reply_to":"ecdeda4d_3e8c838f","updated":"2025-08-29 12:30:04.000000000","message":"Done","commit_id":"df7a850bc63e0ee72ecf389491d7f310f0ac2b06"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"6cce8acceb9642efa1f29ab9e251768140dd52c8","unresolved":true,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"{% block modal-body-right %}"},{"line_number":10,"context_line":"  \u003ch3\u003e{% trans \"Description\" %}\u003c/h3\u003e"},{"line_number":11,"context_line":"  \u003cp\u003e{% trans \"This action will mark the selected action as SKIPPED. You can optionally provide a reason that will be stored as the status message. You can also update reason messages for Actions in SKIPPED state.\" %}\u003c/p\u003e"},{"line_number":12,"context_line":"  \u003cp\u003e{% trans \"Skipped actions will not be executed and cannot be restarted.\" %}\u003c/p\u003e"},{"line_number":13,"context_line":"{% endblock %}"}],"source_content_type":"text/html","patch_set":13,"id":"4eeee07c_6fb0686d","line":11,"updated":"2025-09-02 10:44:18.000000000","message":"is this the text that is displayed to the user? If so, should we mention here the length limit for the reason?","commit_id":"1d75e29fc37baac5e6fea1ce4e896991c8a6dd77"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"d617856184843211a22e53f9c8ea7ad338f9042c","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"{% block modal-body-right %}"},{"line_number":10,"context_line":"  \u003ch3\u003e{% trans \"Description\" %}\u003c/h3\u003e"},{"line_number":11,"context_line":"  \u003cp\u003e{% trans \"This action will mark the selected action as SKIPPED. You can optionally provide a reason that will be stored as the status message. You can also update reason messages for Actions in SKIPPED state.\" %}\u003c/p\u003e"},{"line_number":12,"context_line":"  \u003cp\u003e{% trans \"Skipped actions will not be executed and cannot be restarted.\" %}\u003c/p\u003e"},{"line_number":13,"context_line":"{% endblock %}"}],"source_content_type":"text/html","patch_set":13,"id":"37a5c3ac_2d4211cd","line":11,"in_reply_to":"4eeee07c_6fb0686d","updated":"2025-09-02 13:13:00.000000000","message":"Done","commit_id":"1d75e29fc37baac5e6fea1ce4e896991c8a6dd77"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"ff3e1932fb664ac55704c0274b88791fa87b8f63","unresolved":true,"context_lines":[{"line_number":1,"context_line":"{% extends \"horizon/common/_modal_form.html\" %}"},{"line_number":2,"context_line":"{% load i18n %}"},{"line_number":3,"context_line":"{% block form_id %}skip_action_form{% endblock %}"},{"line_number":4,"context_line":"{% block form_action %}{{ submit_url }}{% endblock %}"}],"source_content_type":"text/html","patch_set":37,"id":"b5997306_050f89a9","line":1,"updated":"2026-02-18 14:06:01.000000000","message":"This template is missing Cancel button in the header and close button (X) in the header. May we use the infra_optim/_modal_form_xl.html template which includes those (As the Create Audit one i.e.) or maybe add those buttons here?","commit_id":"35ea4c9800470864148288cc7860b439788069ec"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"642af6aff6d2c89de4b47bb149fe704d3e290e94","unresolved":true,"context_lines":[{"line_number":1,"context_line":"{% extends \"horizon/common/_modal_form.html\" %}"},{"line_number":2,"context_line":"{% load i18n %}"},{"line_number":3,"context_line":"{% block form_id %}skip_action_form{% endblock %}"},{"line_number":4,"context_line":"{% block form_action %}{{ submit_url }}{% endblock %}"}],"source_content_type":"text/html","patch_set":37,"id":"ceba5631_552fd773","line":1,"in_reply_to":"b5997306_050f89a9","updated":"2026-02-18 14:06:40.000000000","message":"I meant Cancel button in the footer and close button(X) in the header.","commit_id":"35ea4c9800470864148288cc7860b439788069ec"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"8a12529de0fc36b4ef1bab742369e4f0d8cf9c15","unresolved":false,"context_lines":[{"line_number":1,"context_line":"{% extends \"horizon/common/_modal_form.html\" %}"},{"line_number":2,"context_line":"{% load i18n %}"},{"line_number":3,"context_line":"{% block form_id %}skip_action_form{% endblock %}"},{"line_number":4,"context_line":"{% block form_action %}{{ submit_url }}{% endblock %}"}],"source_content_type":"text/html","patch_set":37,"id":"5a889d1b_3c64c7a6","line":1,"in_reply_to":"ceba5631_552fd773","updated":"2026-02-22 07:42:53.000000000","message":"Done\n\nBased on my testing with playwright test https://review.opendev.org/c/openstack/watcher-dashboard/+/976594 Here is the sckip action form https://06c425c005622414e7bc-fc8dbe66ba43ee6d3126c4b00a900b20.ssl.cf2.rackcdn.com/openstack/8b36c6c1a6754018af3e2c88d7611a9f/controller/logs/playwright/screenshots/watcher_dashboard.test.integration.test_playwright_skip_action_workflow.SkipActionWorkflowTests.test_skip_action_workflow/025_skip_reason_filled.png with close button.","commit_id":"35ea4c9800470864148288cc7860b439788069ec"}],"watcher_dashboard/templates/infra_optim/actions/details.html":[{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"4c4d560680313ed43ee02ee34cc364feb2261a90","unresolved":true,"context_lines":[{"line_number":22,"context_line":"        \u003c/a\u003e\u003c/dd\u003e"},{"line_number":23,"context_line":"        \u003cdt\u003e{% trans \"State\" %}\u003c/dt\u003e"},{"line_number":24,"context_line":"        \u003cdd\u003e{{ action.state|default:_(\"-\") }}\u003c/dd\u003e"},{"line_number":25,"context_line":"        {% if show_status_message and action.status_message %}"},{"line_number":26,"context_line":"        {% if action.state \u003d\u003d \u0027SKIPPED\u0027 %}"},{"line_number":27,"context_line":"        \u003cdt\u003e{% trans \"Skip Reason\" %}\u003c/dt\u003e"},{"line_number":28,"context_line":"        \u003cdd\u003e{{ action.status_message }}\u003c/dd\u003e"}],"source_content_type":"text/html","patch_set":30,"id":"9d58cacc_7c1b6b3d","line":25,"range":{"start_line":25,"start_character":14,"end_line":25,"end_character":33},"updated":"2025-10-08 15:08:16.000000000","message":"I think that we can always display the status_message header/column. What we would do is to drop the message itself from the action, when microversion is not supported. Because in the end, this ui client supported status_message, but the server don\u0027t.","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"7809b5389bf66349108172fd95231e4f14d3bf0a","unresolved":false,"context_lines":[{"line_number":22,"context_line":"        \u003c/a\u003e\u003c/dd\u003e"},{"line_number":23,"context_line":"        \u003cdt\u003e{% trans \"State\" %}\u003c/dt\u003e"},{"line_number":24,"context_line":"        \u003cdd\u003e{{ action.state|default:_(\"-\") }}\u003c/dd\u003e"},{"line_number":25,"context_line":"        {% if show_status_message and action.status_message %}"},{"line_number":26,"context_line":"        {% if action.state \u003d\u003d \u0027SKIPPED\u0027 %}"},{"line_number":27,"context_line":"        \u003cdt\u003e{% trans \"Skip Reason\" %}\u003c/dt\u003e"},{"line_number":28,"context_line":"        \u003cdd\u003e{{ action.status_message }}\u003c/dd\u003e"}],"source_content_type":"text/html","patch_set":30,"id":"bce76b61_38d5d5dd","line":25,"range":{"start_line":25,"start_character":14,"end_line":25,"end_character":33},"in_reply_to":"9d58cacc_7c1b6b3d","updated":"2025-10-10 15:10:41.000000000","message":"Acknowledged","commit_id":"cde10961fe1aeb4a6e2161673f396e1200d7c720"}],"watcher_dashboard/templates/infra_optim/actions/skip.html":[{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"815d4eceabe995e091173355e3f9bf6918aa677e","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":44,"id":"5b4e92d6_7fa8e504","line":8,"updated":"2026-02-26 15:22:45.000000000","message":"Added this to fix Confirmed Missing Template — `TemplateDoesNotExist` Bug discovered in AI review 8 from https://paste.opendev.org/show/bzNpdAdbeeMeeULzfwxe/","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"},{"author":{"_account_id":12393,"name":"chandan kumar","display_name":"Chandan Kumar","email":"chkumar@redhat.com","username":"chkumar246"},"change_message_id":"948517ddc4512267e989cfc42c0ef95723e41f9c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":44,"id":"b810e430_24aa47e9","line":8,"in_reply_to":"5b4e92d6_7fa8e504","updated":"2026-03-03 10:04:43.000000000","message":"Done","commit_id":"721c36b0758c292498e0f6dc96fea9442d40c3f4"}],"watcher_dashboard/templates/infra_optim/strategies/details.html":[{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"68863a3836d63e956dba368842361530e8d43489","unresolved":true,"context_lines":[{"line_number":23,"context_line":"        \u003cdt\u003e{% trans \"Update At\" %}\u003c/dt\u003e"},{"line_number":24,"context_line":"        \u003cdd\u003e{{ strategy.updated_at|parse_isotime|default:_(\"-\") }}\u003c/dd\u003e"},{"line_number":25,"context_line":"        \u003cdt\u003e{% trans \"Parameters Spec\" %}\u003c/dt\u003e"},{"line_number":26,"context_line":"        \u003cdd style\u003d\"height: auto; max-height: 500px; overflow: auto\"\u003e"},{"line_number":27,"context_line":"          {% if strategy_parameters_spec_pretty %}"},{"line_number":28,"context_line":"            {{ strategy_parameters_spec_pretty|safe }}"},{"line_number":29,"context_line":"          {% else %}"}],"source_content_type":"text/html","patch_set":28,"id":"2a18ed2c_310b9ea3","line":26,"range":{"start_line":26,"start_character":0,"end_line":26,"end_character":2},"updated":"2025-09-30 10:03:07.000000000","message":"this should go to its own independent review (we may want to cherry-pick it).","commit_id":"5018a4bb21bf76f6742b33511591cdccba8ca101"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"b6488e35e0e73ffb0f1cd36e5e705843412b0b5d","unresolved":false,"context_lines":[{"line_number":23,"context_line":"        \u003cdt\u003e{% trans \"Update At\" %}\u003c/dt\u003e"},{"line_number":24,"context_line":"        \u003cdd\u003e{{ strategy.updated_at|parse_isotime|default:_(\"-\") }}\u003c/dd\u003e"},{"line_number":25,"context_line":"        \u003cdt\u003e{% trans \"Parameters Spec\" %}\u003c/dt\u003e"},{"line_number":26,"context_line":"        \u003cdd style\u003d\"height: auto; max-height: 500px; overflow: auto\"\u003e"},{"line_number":27,"context_line":"          {% if strategy_parameters_spec_pretty %}"},{"line_number":28,"context_line":"            {{ strategy_parameters_spec_pretty|safe }}"},{"line_number":29,"context_line":"          {% else %}"}],"source_content_type":"text/html","patch_set":28,"id":"ac9677c6_e98903d1","line":26,"range":{"start_line":26,"start_character":0,"end_line":26,"end_character":2},"in_reply_to":"2a18ed2c_310b9ea3","updated":"2025-10-07 08:06:21.000000000","message":"Done","commit_id":"5018a4bb21bf76f6742b33511591cdccba8ca101"}]}
