admin管理员组

文章数量:1394202

I want to find the work items that were reopened (were closed before and now are opened again)

I have used this api to get all the revisions of work items : Reporting Work Item Revisions - Read Reporting Revisions Get

/{anization}/{project}/_apis/wit/reporting/workitemrevisions?api-version=7.1

Now, from these revisions, I want to find the instances when the state was changed, specifically when the state was set to closed. Then, I will check the next revisions to see if there has been a state change if yes then it indicated it was reopened

I want to find the work items that were reopened (were closed before and now are opened again)

I have used this api to get all the revisions of work items : Reporting Work Item Revisions - Read Reporting Revisions Get

https://dev.azure/{anization}/{project}/_apis/wit/reporting/workitemrevisions?api-version=7.1

Now, from these revisions, I want to find the instances when the state was changed, specifically when the state was set to closed. Then, I will check the next revisions to see if there has been a state change if yes then it indicated it was reopened

Share Improve this question asked Mar 12 at 11:41 A-73-Sakshee B AgarwalA-73-Sakshee B Agarwal 1 7
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Bot Commented Mar 12 at 12:19
  • the api fetches all the revisions of all work items, its like this id123{ rev:1 state:proposed} id123{ rev:2, state: closed} – A-73-Sakshee B Agarwal Commented Mar 12 at 12:22
  • Fetch Work Item Revisions using the Reporting Work Item Revisions API with required fields (System.Id, System.Rev, System.State). Process Each Work Item to track state changes over revisions. Detect Reopened Work Items by finding items that changed from "Closed" to any other state in later revisions. Output Results with work item ID, reopened revision, and state transition details Total Reopened Work Items: 3 Work Item 123 reopened at Rev 5 from Closed to Active Work Item 456 reopened at Rev 8 from Closed to New Work Item 789 reopened at Rev 12 from Closed to Proposed – A-73-Sakshee B Agarwal Commented Mar 12 at 12:34
  • So, you’re already receiving API responses that contain field values from each revision of individual work items. The key question now is how to use Python to process these revision elements and generate an expect report like excel table? – Alvin Zhao Commented Mar 13 at 2:53
  • Hi @A-73-SaksheeBAgarwal, Good day and welcome to SO. May I know if you have got a chance to test the Python script in my answer below to fetch the reopened wit details? Hope it may resolve your query in this post. Look forward to your reply and wish you lovely weekend. – Alvin Zhao Commented Mar 14 at 9:19
 |  Show 2 more comments

1 Answer 1

Reset to default 0

The key to answering this question is understanding how Azure DevOps tracks work item state changes. When a work item transitions from Closed to any other state, it generates a new revision where:

  1. The System.State field reflects the updated state.
  2. The System.Reason field is always set to Reactivated.

To retrieve and process such data, you can use the following Python script, which:

  1. Calls the Azure DevOps API with fields=System.State,System.Reason to fetch state transition details.
  2. Continuously follows the nextLink in the response until isLastBatch is true, ensuring all revisions are retrieved.
  3. Extracts and logs work item revisions where System.Reason is Reactivated.
import base64
import json
import requests
import csv

# Define your Azure DevOps anization, project, and personal access token
anization = "YourADOOrgName"
project = "YourProjectName"
personal_access_token = 'xxxxxx'

# Define the file paths to help check output values
all_values_path = r"C:\Users\Alvin\Desktop\reporting_values.json"
reactivated_values_path = r"C:\Users\Alvin\Desktop\reactivated_wit.json"
reactivated_csv_path = r"C:\Users\Alvin\Desktop\reactivated_wit.csv"

# Azure DevOps API [Reporting Work Item Revisions - Read Reporting Revisions Get]
# GET https://dev.azure/{anization}/{project}/_apis/wit/reporting/workitemrevisions?api-version=7.2-preview.2
reporting_url = f"https://dev.azure/{anization}/{project}/_apis/wit/reporting/workitemrevisions?fields=System.State,System.Reason&api-version=7.2-preview.2"
headers = {
    "Authorization": f"Bearer {personal_access_token}",
    "Content-Type": "application/json"
}

# Lists to store all values and reactivated work items
all_values = []
reactivated_items = []
batch_count = 0  # Counter for batches

while reporting_url:
    batch_count += 1
    print(f"Fetching batch {batch_count} from: {reporting_url}")

    # Make the API request
    response = requests.get(reporting_url, headers=headers)

    # Parse the response JSON
    response_json = response.json()

    # Extract and append the 'values' node
    values = response_json.get("values", [])
    all_values.extend(values)
   
    # Extract work items where "System.Reason" is "Reactivated"
    for item in values:
        fields = item.get("fields", {})
        if fields.get("System.Reason") == "Reactivated":
            reactivated_items.append(item)

    print(f"Batch {batch_count} retrieved {len(values)} records, {len(reactivated_items)} reactivated items found so far.")

    # Check if there is a nextLink for more data
    if response_json.get("isLastBatch", True):
        print("Finished retrieving all data. 'isLastBatch' is True.")
        break  # Stop if this is the last batch

    # Update the reporting_url with nextLink for the next batch
    reporting_url = response_json.get("nextLink")
    print("Continuing to next batch...\n")

# Save the extracted 'values' data to a JSON file
with open(all_values_path, "w", encoding="utf-8") as json_file:
    json.dump(all_values, json_file, indent=4, ensure_ascii=False)

# Save the 'reactivated' work items separately
with open(reactivated_values_path, "w", encoding="utf-8") as json_file:
    json.dump(reactivated_items, json_file, indent=4, ensure_ascii=False)

# Create a summary of reactivated work items
csv_data = []
print(f"\nTotal Reopened Work Items: {len(reactivated_items)}\n")

for item in reactivated_items:
    work_item_id = item["id"]
    rev = item["rev"]
    current_state = item.get("fields", {}).get("System.State", "Unknown")
   
    transition_description = f"from Closed to {current_state}"
    print(f"Work Item {work_item_id} reopened at Rev {rev} {transition_description}")
   
    csv_data.append([work_item_id, rev, transition_description])

# Write CSV report
with open(reactivated_csv_path, "w", newline="", encoding="utf-8") as csvfile:
    csv_writer = csv.writer(csvfile)
    csv_writer.writerow(["Work Item ID", "Revision Number", "Reopened Description"])  # Header

    for row in csv_data:
        csv_writer.writerow(row)

print(f"\nExtracted all 'values' data has been saved to {all_values_path}")
print(f"Extracted 'Reactivated' work items have been saved to {reactivated_values_path}")
print(f"Reactivated work item summary saved to {reactivated_csv_path}")

本文标签: pythonfiltering reopened workitems in azure devopsusing reporting revisions apiStack Overflow