Coverage for scripts / approve_request.py: 43%

61 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2025-12-25 18:08 -0500

1#!/usr/bin/env python3 

2""" 

3Approve an approval request for a JSM request. 

4 

5This script approves pending approval requests in JSM workflows, 

6typically used for change management and approval processes. 

7""" 

8 

9import sys 

10import argparse 

11from pathlib import Path 

12from datetime import datetime 

13 

14# Add shared lib to path 

15sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent / 'shared' / 'scripts' / 'lib')) 

16 

17from config_manager import get_jira_client 

18from error_handler import handle_errors 

19 

20 

21def get_jira_client(profile=None): 

22 """Get JIRA client (overridable for testing).""" 

23 from config_manager import get_jira_client as _get_client 

24 return _get_client(profile) 

25 

26 

27@handle_errors 

28def main(args=None): 

29 """Main function.""" 

30 parser = argparse.ArgumentParser( 

31 description='Approve JSM approval request', 

32 formatter_class=argparse.RawDescriptionHelpFormatter, 

33 epilog=""" 

34Examples: 

35 # Approve single approval 

36 %(prog)s REQ-123 --approval-id 10050 

37 

38 # Skip confirmation 

39 %(prog)s REQ-123 --approval-id 10050 --yes 

40 

41 # Dry run (show what would be approved) 

42 %(prog)s REQ-123 --approval-id 10050 --dry-run 

43 """ 

44 ) 

45 

46 parser.add_argument('issue_key', 

47 help='Request key (e.g., REQ-123)') 

48 parser.add_argument('--approval-id', required=True, action='append', 

49 help='Approval ID to approve (can specify multiple times)') 

50 parser.add_argument('--yes', '-y', action='store_true', 

51 help='Skip confirmation prompt') 

52 parser.add_argument('--dry-run', action='store_true', 

53 help='Show what would be approved without making changes') 

54 parser.add_argument('--profile', 

55 help='JIRA profile to use') 

56 

57 parsed_args = parser.parse_args(args) 

58 

59 # Get JIRA client 

60 jira = get_jira_client(parsed_args.profile) 

61 

62 # Process each approval ID 

63 for approval_id in parsed_args.approval_id: 

64 # Get approval details for confirmation 

65 try: 

66 approval = jira.get_request_approval(parsed_args.issue_key, approval_id) 

67 except: 

68 print(f"\nError: Could not get approval {approval_id}") 

69 continue 

70 

71 approval_name = approval.get('name', 'Unknown') 

72 approvers = approval.get('approvers', []) 

73 approvers_str = ', '.join([a.get('displayName', 'Unknown') for a in approvers]) 

74 created = approval.get('createdDate', '') 

75 

76 # Format created date 

77 try: 

78 created_dt = datetime.fromisoformat(created.replace('Z', '+00:00')) 

79 created_str = created_dt.strftime('%Y-%m-%d %H:%M') 

80 except: 

81 created_str = created[:16] if created else 'Unknown' 

82 

83 # Show approval details 

84 print(f"\nApprove approval for {parsed_args.issue_key}?") 

85 print(f"\nApproval ID: {approval_id}") 

86 print(f"Name: {approval_name}") 

87 print(f"Approvers: {approvers_str}") 

88 print(f"Created: {created_str}") 

89 

90 if parsed_args.dry_run: 

91 print(f"\n[DRY RUN] Would approve approval {approval_id} for {parsed_args.issue_key}") 

92 continue 

93 

94 # Confirm unless --yes 

95 if not parsed_args.yes: 

96 confirm = input("\nType 'yes' to confirm: ") 

97 if confirm.lower() != 'yes': 

98 print("Cancelled.") 

99 continue 

100 

101 # Approve the approval 

102 result = jira.answer_approval(parsed_args.issue_key, approval_id, 'approve') 

103 

104 completed = result.get('completedDate', '') 

105 try: 

106 completed_dt = datetime.fromisoformat(completed.replace('Z', '+00:00')) 

107 completed_str = completed_dt.strftime('%Y-%m-%d %H:%M') 

108 except: 

109 completed_str = completed[:16] if completed else 'Just now' 

110 

111 print(f"\nApproval {approval_id} APPROVED for {parsed_args.issue_key}.") 

112 print(f"\nStatus: approve") 

113 print(f"Completed: {completed_str}") 

114 

115 return 0 

116 

117 

118if __name__ == '__main__': 

119 sys.exit(main())