Skip to content

Instantly share code, notes, and snippets.

@mirontoli
Last active September 30, 2025 02:49
Show Gist options
  • Save mirontoli/a1dd36cd4956efa38119111b01c7516d to your computer and use it in GitHub Desktop.
Save mirontoli/a1dd36cd4956efa38119111b01c7516d to your computer and use it in GitHub Desktop.
trigger: none
schedules:
- cron: "0 12 * * 5"
displayName: Weekly Friday Report
branches:
include:
- main
always: "true"
pool:
vmImage: ubuntu-latest
stages:
- stage: RunReport
jobs:
- job: RunReportJob
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.x'
addToPath: true
displayName: 'Set up Python'
- script: |
pip install -r requirements.txt
displayName: 'Install dependencies'
- script: |
python report-time.py
displayName: 'Run report.py'
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)

Prompt 1:

get token for Azure DevOps. Call the api to get the tasks that are children of the user story 2454. get the task that has "anatoly" in its name. Call the api and update the field "Completed" with 10 hours.

Prompt 2:

now I would like check even for week number (and the anatoly check), i want to get a task where anatoly is present but also the current week in format "v39" where 39 is the current week number in Sweden.

Prompt 3:

create a copy of headers and replace Content-Type to application/json-patch+json

Prompt 4:

Create an azure-pipelines.yaml file that runs every friday 12 o'clock utc and executes a python script called report.py

import os
import requests
import json
import datetime
token = os.getenv("SYSTEM_ACCESSTOKEN")
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
print(f'token {token[:10]}...')
# Azure DevOps configuration
organization = "tolle" # Replace with your organization name
project = "project1" # Replace with your project name
userstory_id = 1456 # User story ID to query
me = "anatoly"
hours_to_add = 10
# Get work items that are children of user story 124686
base_url = f"https://dev.azure.com/{organization}/{project}/_apis/wit"
query_url = f"{base_url}/wiql?api-version=7.0"
wiql_query = {
"query": f"SELECT [System.Id], [System.Title], [System.WorkItemType] FROM WorkItemLinks WHERE ([Source].[System.Id] = {userstory_id}) AND ([System.Links.LinkType] = 'System.LinkTypes.Hierarchy-Forward') MODE (Recursive)"
}
# Execute the query
query_response = requests.post(query_url, headers=headers, json=wiql_query)
query_result = query_response.json()
print(json.dumps(query_result, indent=2))
# Extract work item IDs from the query result
work_item_ids = []
if 'workItemRelations' in query_result:
for relation in query_result['workItemRelations']:
if relation.get('target'):
work_item_ids.append(relation['target']['id'])
print(f"Found {len(work_item_ids)} child work items")
# Get detailed information for each work item
if work_item_ids:
ids_string = ",".join(map(str, work_item_ids))
details_url = f"{base_url}/workitems?ids={ids_string}&api-version=7.0"
details_response = requests.get(details_url, headers=headers)
work_items = details_response.json()['value']
# Find the task with "anatoly" in its name
anatoly_task = None
for item in work_items:
# Get current week number in Sweden (ISO week)
current_week = datetime.date.today().isocalendar()[1]
week_format = f"v{current_week}"
title = item['fields'].get('System.Title', '').lower()
if 'anatoly' in title and week_format in title and item['fields'].get('System.WorkItemType') == 'Task':
anatoly_task = item
break
else:
print(f"No child work items found for user story {userstory_id}")
if anatoly_task:
print(json.dumps(anatoly_task, indent=2))
print(anatoly_task['fields']['System.Title'])
# Create a copy of headers with updated Content-Type for patch operations
patch_headers = headers.copy()
patch_headers['Content-Type'] = 'application/json-patch+json'
if anatoly_task:
task_id = anatoly_task['id']
print(f"Found Anatoly's task: {anatoly_task['fields']['System.Title']} (ID: {task_id})")
# Update the "Completed" field with 10 hours
update_url = f"{base_url}/workitems/{task_id}?api-version=7.0"
update_data = [
{
"op": "add",
"path": "/fields/Microsoft.VSTS.Scheduling.CompletedWork",
"value": hours_to_add
}
]
update_response = requests.patch(update_url, headers=patch_headers, json=update_data)
if update_response.status_code == 200:
print(f"Successfully updated Completed Work to {hours_to_add} hours")
updated_task = update_response.json()
print(f"Updated task: {updated_task['fields']['System.Title']}")
print(f"Completed Work: {updated_task['fields'].get('Microsoft.VSTS.Scheduling.CompletedWork', 'Not set')}")
else:
print(f"Failed to update task. Status code: {update_response.status_code}")
print(f"Error: {update_response.text}")
else:
print(f"No task with 'anatoly' in the name found among the children of user story {userstory_id}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment