This is an automated email from the ASF dual-hosted git repository.

zhouky pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-celeborn.git


The following commit(s) were added to refs/heads/main by this push:
     new df8b56a7c [CELEBORN-930][INFRA] Eagerly check if the token is valid to 
align with the behavior of username/password auth
df8b56a7c is described below

commit df8b56a7c7848dbb573cda8876b861f03e4b76ec
Author: Kent Yao <[email protected]>
AuthorDate: Tue Aug 29 21:33:11 2023 +0800

    [CELEBORN-930][INFRA] Eagerly check if the token is valid to align with the 
behavior of username/password auth
    
    ### What changes were proposed in this pull request?
    
    Previously, we allowed for token authentication when resolving Jira issues 
in pull request merging. However, the token auth is kinda lazy during the 
initial handshake, maintainers might get confused someday.
    
    This pull request promptly calls the current_user() function to initiate 
authentication and provides clear instructions for token expiration.
    
    see also 
https://github.com/apache/spark/commit/8523ee5d90f854cdeb96c70cb16db7cd32f5429e
    
    ### Why are the changes needed?
    
    make it easy for maintainers to update their expired Jira tokens.
    
    ### Does this PR introduce _any_ user-facing change?
    
    no
    
    ### How was this patch tested?
    
    a maintainer can test this with invalid tokens
    
    Closes #1857 from yaooqinn/CELEBORN-930.
    
    Authored-by: Kent Yao <[email protected]>
    Signed-off-by: zky.zhoukeyong <[email protected]>
---
 dev/merge_pr.py | 82 +++++++++++++++++++++++++++++++++------------------------
 1 file changed, 48 insertions(+), 34 deletions(-)

diff --git a/dev/merge_pr.py b/dev/merge_pr.py
index 5ac9cc876..7ecb7d969 100755
--- a/dev/merge_pr.py
+++ b/dev/merge_pr.py
@@ -243,13 +243,6 @@ def cherry_pick(pr_num, merge_hash, default_branch):
 
 
 def resolve_jira_issue(merge_branches, comment, default_jira_id=""):
-    jira_server = {"server": JIRA_API_BASE}
-
-    if JIRA_ACCESS_TOKEN is not None:
-        asf_jira = jira.client.JIRA(jira_server, token_auth=JIRA_ACCESS_TOKEN)
-    else:
-        asf_jira = jira.client.JIRA(jira_server, basic_auth=(JIRA_USERNAME, 
JIRA_PASSWORD))
-
     jira_id = input("Enter a JIRA id [%s]: " % default_jira_id)
     if jira_id == "":
         jira_id = default_jira_id
@@ -263,7 +256,7 @@ def resolve_jira_issue(merge_branches, comment, 
default_jira_id=""):
     cur_summary = issue.fields.summary
     cur_assignee = issue.fields.assignee
     if cur_assignee is None:
-        cur_assignee = choose_jira_assignee(issue, asf_jira)
+        cur_assignee = choose_jira_assignee(issue)
     # Check again, we might not have chosen an assignee
     if cur_assignee is None:
         cur_assignee = "NOT ASSIGNED!!!"
@@ -361,7 +354,7 @@ def resolve_jira_issue(merge_branches, comment, 
default_jira_id=""):
     print("Successfully resolved %s with fixVersions=%s!" % (jira_id, 
fix_versions))
 
 
-def choose_jira_assignee(issue, asf_jira):
+def choose_jira_assignee(issue):
     """
     Prompt the user to choose who to assign the issue to in jira, given a list 
of candidates,
     including the original reporter and all commentors
@@ -394,7 +387,7 @@ def choose_jira_assignee(issue, asf_jira):
                     # assume it's a user id, and try to assign (might fail, we 
just prompt again)
                     assignee = asf_jira.user(raw_assignee)
                 try:
-                    assign_issue(asf_jira, issue.key, assignee.name)
+                    assign_issue(issue.key, assignee.name)
                 except Exception as e:
                     if (
                         e.__class__.__name__ == "JIRAError"
@@ -405,8 +398,8 @@ def choose_jira_assignee(issue, asf_jira):
                             "User '%s' cannot be assigned, add to contributors 
role and try again?"
                             % assignee.name
                         )
-                        grant_contributor_role(assignee.name, asf_jira)
-                        assign_issue(asf_jira, issue.key, assignee.name)
+                        grant_contributor_role(assignee.name)
+                        assign_issue(issue.key, assignee.name)
                     else:
                         raise e
                 return assignee
@@ -416,21 +409,21 @@ def choose_jira_assignee(issue, asf_jira):
             traceback.print_exc()
             print("Error assigning JIRA, try again (or leave blank and fix 
manually)")
 
-def grant_contributor_role(user: str, asf_jira):
+def grant_contributor_role(user: str):
     role = asf_jira.project_role("CELEBORN", 10010)
     role.add_user(user)
     print("Successfully added user '%s' to contributors role" % user)
 
-def assign_issue(client, issue: int, assignee: str) -> bool:
+def assign_issue(issue: int, assignee: str) -> bool:
     """
     Assign an issue to a user, which is a shorthand for 
jira.client.JIRA.assign_issue.
     The original one has an issue that it will search users again and only 
choose the assignee
     from 20 candidates. If it's unmatched, it picks the head blindly. In our 
case, the assignee
     is already resolved.
     """
-    url = getattr(client, "_get_latest_url")(f"issue/{issue}/assignee")
+    url = getattr(asf_jira, "_get_latest_url")(f"issue/{issue}/assignee")
     payload = {"name": assignee}
-    getattr(client, "_session").put(url, data=json.dumps(payload))
+    getattr(asf_jira, "_session").put(url, data=json.dumps(payload))
     return True
 
 
@@ -495,17 +488,43 @@ def get_current_ref():
         return ref
 
 
+def initialize_jira():
+    global asf_jira
+    jira_server = {"server": JIRA_API_BASE}
+
+    if not JIRA_IMPORTED:
+        print("ERROR finding jira library. Run 'pip3 install jira' to 
install.")
+        continue_maybe("Continue without jira?")
+    elif JIRA_ACCESS_TOKEN:
+        client = jira.client.JIRA(jira_server, token_auth=JIRA_ACCESS_TOKEN)
+        try:
+            # Eagerly check if the token is valid to align with the behavior 
of username/password
+            # authn
+            client.current_user()
+            asf_jira = client
+        except Exception as e:
+            if e.__class__.__name__ == "JIRAError" and getattr(e, 
"status_code", None) == 401:
+                msg = (
+                        "ASF JIRA could not authenticate with the invalid or 
expired token '%s'"
+                        % JIRA_ACCESS_TOKEN
+                )
+                fail(msg)
+            else:
+                raise e
+    elif JIRA_USERNAME and JIRA_PASSWORD:
+        asf_jira = jira.client.JIRA(jira_server, basic_auth=(JIRA_USERNAME, 
JIRA_PASSWORD))
+    else:
+        print("Neither JIRA_ACCESS_TOKEN nor JIRA_USERNAME/JIRA_PASSWORD are 
set.")
+        continue_maybe("Continue without jira?")
+
+
 def main():
+    initialize_jira()
     global original_head
 
     os.chdir(PROJECT_HOME)
     original_head = get_current_ref()
 
-    # Check this up front to avoid failing the JIRA update at the very end
-    if not JIRA_ACCESS_TOKEN and (not ASF_USERNAME or not ASF_PASSWORD):
-        msg = "The env-vars JIRA_ACCESS_TOKEN or ASF_USERNAME/ASF_PASSWORD are 
not set. Continue?"
-        continue_maybe(msg)
-
     branches = get_json("%s/branches" % GITHUB_API_BASE)
     branch_names = list(filter(lambda x: x.startswith("branch-"), [x["name"] 
for x in branches]))
     # Assumes branch names can be sorted lexicographically
@@ -603,20 +622,15 @@ def main():
     while input("\n%s (y/n): " % pick_prompt).lower() == "y":
         merged_refs = merged_refs + [cherry_pick(pr_num, merge_hash, 
latest_branch)]
 
-    if JIRA_IMPORTED:
-        if JIRA_ACCESS_TOKEN or (ASF_USERNAME and ASF_PASSWORD):
-            continue_maybe("Would you like to update an associated JIRA?")
-            jira_comment = "Issue resolved by pull request %s\n[%s/%s]" % (
-                pr_num,
-                GITHUB_BASE,
-                pr_num,
-            )
-            resolve_jira_issues(title, merged_refs, jira_comment)
-        else:
-            print("Neither JIRA_ACCESS_TOKEN nor ASF_USERNAME/ASF_PASSWORD are 
set.")
-            print("Exiting without trying to close the associated JIRA.")
+    if asf_jira is not None:
+        continue_maybe("Would you like to update an associated JIRA?")
+        jira_comment = "Issue resolved by pull request %s\n[%s/%s]" % (
+            pr_num,
+            GITHUB_BASE,
+            pr_num,
+        )
+        resolve_jira_issues(title, merged_refs, jira_comment)
     else:
-        print("Could not find jira-python library. Run 'sudo pip3 install 
jira' to install.")
         print("Exiting without trying to close the associated JIRA.")
 
 

Reply via email to