The idea
I am currently developing a 'release notes' application using NodeJS that calls various Azure DevOps REST API endpoints to obtain work items based on a specific tag.
What I have right now
What I have at the moment works like this;
- Some work items on Azure DevOps are (custom) tagged with
v1.1. - The JS functions I wrote, fetch all work items that match the given
v1.1tag. - A wiki entry is created using generated markdown, showing a breakdown of each work item (format not important to the question).
/**
* Function used to fetch initial work items from Azure DevOps that match the provided release number
* @param {String} releaseNumber - the given release number
* @returns {Array} workItems - the initial work items fetched from Azure DevOps
*/
async function fetchWorkItems(releaseNumber) {
console.log('\nFetching work items for given release number...');
let response;
try {
response = await axios.post('https://dev.azure.com/myTestOrg/myTestProject/_apis/wit/wiql?api-version=6', {
query: `SELECT [State], [Title] FROM WorkItems WHERE [Tags] CONTAINS '${releaseNumber}'`
}, {
headers: {
Authorization: getAuthToken()
}
});
console.log(`Found ${response.data.workItems.length} work item(s).`);
} catch (e) {
console.error('\nUnable to fetch work items. See below error message');
console.error(e.message);
process.exit(1);
}
return response.data.workItems;
}
/**
* Function used to fetch the details for a given array of work items
* @param {Array} givenWorkItems - given array of work items to fetch the details for
* @returns {Array} details - the initial work items fetched from Azure DevOps
*/
async function fetchWorkItemDetails(givenWorkItems) {
console.log('\nFetching further details for the given work item(s)...');
const returnData = [];
let response;
for (const item of givenWorkItems) {
try {
// eslint-disable-next-line no-await-in-loop
response = await axios.get(item.url, {
headers: {
Authorization: getAuthToken()
}
});
} catch (e) {
console.error('\nUnable to fetch details for given work items. See below error message');
console.error(e.message);
process.exit(1);
} finally {
returnData.push({
type: response.data.fields['System.WorkItemType'],
title: response.data.fields['System.Title'],
url: response.data._links.html.href
});
}
}
console.log(`Found details for ${returnData.length} work item(s).`);
return returnData;
}
...
/**
* Function used to create the wiki entry based on a given markup string
* @param {String} releaseNumber - the given release number
* @param {String} givenMarkdown - given array of work items to fetch the details for
* @returns {undefined} nothing
*/
async function createWiki(releaseNumber, givenMarkdown) {
console.log('\nCreating wiki entry...');
try {
await axios.put(`https://dev.azure.com/myTestOrg/myTestProject/_apis/wiki/wikis/myTestProject.wiki/pages?path=/Releases/Release%20${releaseNumber}&api-version=6.0`, {
content: givenMarkdown
}, {
headers: {
Authorization: getAuthToken()
}
});
} catch (e) {
console.error('\nUnable to create wiki entry for given markdown. See below error message');
console.error(e.message);
process.exit(1);
} finally {
console.log('Successfully created wiki entry.');
}
}
...
const workItems = await fetchWorkItems(releaseNumber);
const workItemDetails = await fetchWorkItemDetails(workItems);
const formattedDetails = formatWorkItemDetails(workItemDetails);
const generatedMarkup = generateMarkdown(formattedDetails);
await createWiki(releaseNumber, generatedMarkup);
...
// creates the wiki based on the given `releaseNumber` variable
// (which is the workitem tag of `v1.1` in our case)
Why what I have right now is not good enough
This application works fine if I remember to tag the work item with the correct v1.1 tag - but in case I do not, this program will not pick up the fact that a specific ticket (and associated branch/ code) has been merged in and has been/ is awaiting release - I hope this makes sense?
The question
Is there a way for me to fetch all work items (regardless of tag) that have been merged into a branch (or a git tag) via the REST api?
I noticed there is also a azure-devops-node-api npm package which may be suitable but I have no idea if what I'm trying to achieve is possible.
Why can't I use XYZ
I saw this project https://marketplace.visualstudio.com/items?itemName=richardfennellBM.BM-VSTS-XplatGenerateReleaseNotes which when I tried it, seemed to work fine but won't suit my needs as;
- I do not use the dedicated
releasesection in DevOps, I just have several application pipelines which contain gated steps used to deploy various apps to QA/ Staging/ Production environments - I share the same release number across several Azure DevOps pipelines (and the above solution (I found) works best for a single pipeline)
- I don't want to combine several application pipelines into a single master one unless I really need to.