Bu yazıyı, projede kullanırken özellikle kaynak sıkıntısı yaşamış olduğum için, ekstra bir kaynak türetebilmek amacıyla yazmak istedim. Microsoft’un kendi yayınlamış olduğu dokumanda basit anlamda api’lerin tanımları ve parametreleri yer almakta fakat kullanım farklılıkları yaşandığı durumlardaki çözümler maalesef yer almıyor. Bu yazıda apileri kullanma biçimimden ve karşılaştığım bazı problemlere getirdiğim çözümleri anlatacağım.
Azure Devops temel olarak sürüm kontrolü, raporlama, gereksinim yönetimi, proje yönetimi, otomatik derlemeler, DevOps süreçlerini barındıran pipeline kurulumları ve release adımlarını, test durumlarını içinde barındıran bir Microsoft ürünüdür.
Bu yazı içinde proje yönetimi ile ilgili bazı işlemler yapmak amacıyla Azure Devops Rest Api’nin kullanımını anlatacağım. Azure Devops Rest Api içerisinde Post ve Get methodlarıyla farklı türlerde özellikler yaratabilmek ve bunları yönetebilmeyi hedefledik.
Azure Devops içerisinde süreçleri ve projeyi takip edebilmek için işleri gruplandırırız. Bunlar en üst kırılımdan itibaren, epic -> feature -> user story -> task ve hatalar için bug şeklindedir.
Rest apiler ile çalışabilmek için personal access token türetmek gerekmektedir. Personal access token ayarlar menüsünden aşağıdaki gibi seçilir:
Açılan ekran üzerinden New Token butonuyla yeni yaratma işlemini yapabilirsiniz. Token sürenizi kişisel olarak ayarlayabilir workflow üzerinde yapacağınız işlemlere Read, Read Write, Read Write Manage seçenekleri üzerinden bir yetkilendirme seçerek yaratabilirsiniz.
Örnek bağlantılar JavaSpring uygulaması üzerinde gösterilmektedir.
Azure Devops ile bağlantı kurabilmek için bağlantı parametrelerini aşağıdaki gibi ayarlayabilirsiniz.
String encodedPAT = Base64.getUrlEncoder().encodeToString(personalAccessToken.getBytes()); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestProperty("Authorization","Basic" + encodedPAT); conn.setDoOutput(true); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type","application/json-patch+json;charset=utf-8");
Bu işlemler sonrasında kendi oluşturacağınız request body’i connection içinde yer alan output stream objesine write etmek gereklidir.
OutputStream os = conn.getOutputStream(); os.write(requestBody.getBytes()); os.flush();
Sonrasında oluşan isteğin başarılı dönüp dönmediği kontrol edilir. Buffered Reader objesi üzerinden output alınarak object’e map edilir.
int status = conn.getResponseCode(); if(status != 200){ BufferedReader br = new BufferedReader(new InputStreamReader((conn.getErrorStream()))); String output; while((output=br.readLine())!=null){ log.debug(output); } } BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; StringBuilder content = new StringBuilder(); while((inputLine = in.readLine())!=null) { content.append(inputLine); } in.close(); String response = content.toString(); conn.disconnect();
Gönderilecek body içerisinde attachment eklenecekse bağlantı içinde output stream’ e kaydetme biçimi farklılık gösterir. attachmentData objesi bir byte array tipindedir. Bundan dolayı gönderilen objenin bir byte arraye dönüşümü kod içerisinde bağlantı öncesinde yapılmalıdır.
OutputStream os = conn.getOutputStream(); os.write(attachmentData, 0, attachmentData.length);
Attachment ekleyebilmek için çağırılan Azure Devops Apisi:
POST : https://dev.azure.com/{organization-name}/_apis/wit/attachments?api-version=6.0&fileName=attachedImage.png
Attachment eklenmiş request içindeki response aşağıdaki şekildedir. Buradaki url, work item create edilirken request body içerisinde kullanılacaktır.
{ "id":"uploadedImageId", "url":"https://dev.azure.com/{project-name}/{project-related-process-id}/_apis/wit/attachments/uploadedImageId?fileName={attachedImage.png}" }
Kullanılan apiler:
Bu api ile sizde Azure’da iş tipi yani work item’ları projeniz özelinde listeyebilirsiniz.
Buradan organization değişkeni Azure Devops’un bağlı olduğu organizasyona aittir. ProcessID add, create ve delete olmak üzere verilir. Buradan mevcut projeye ait tüm iş tipleri görülebilir.
Bir work item tipine ait şu response döner:
{ "id": "agile-board-id", "name": "agile-board-id.epic", "description": null, "url": "get-method-url", "inherits": null, "class": "system", "color": "009CCC", "icon": "icon_clipboard", "isDisabled": false }
Spesifik olarak bir work itema ait bilgileri görebilmek için de yukarıdaki bağlantı adımlarını kullanarak aşağıdaki apiyi çağırırsanız o itema ait bilgileri görebilirsiniz:
Yeni bir work item yaratabilmek için bu api çağırılır request body kod içerisinde istenilen kriterlere göre oluşturulur:
POST: https://dev.azure.com/{organization-name}/_apis//wit/workitems/$task?api-version=6.0
Yeni bir work item yaratırken numaralarla işaretli alanlar için sırasıyla request body alanları doldurulur,
1- Title -Başlık yaratmak için aşağıdaki obje doldurulur.
{ "op": "add", "path": "/fields/System.Title", "from": null, "value": "Başlık Bilgisi" }
2- Description yaratmak için:
{ "op": "add", "path": "/fields/System.Description", "from": null, "value": "Açıklama Bilgisi" }
3- State:
{ "op": "add", "path": "/fields/System.State", "from": null, "value": "New" // Burada status kendi azure devopsunuzda belirlemiş olduğunuz statelere göre değişkenlik gösterir }
4- Area Path
{ "op": "add", "path": "/fields/System.AreaPath", "from": null, "value": "proje bağımlı-takım ismi" }
5- Iteration Path — Bu değer verilmediği zaman belirlenen area path içinde default olarak backlog item yaratır.
{ "op": "add", "path": "/fields/System.IterationPath", "from": null, "value": "Iteration ismi" }
6- Priority –
{ "op": "add", "path": "/fields/System.Priority", "from": null, "value": "öncelik numarası" }
7- Relation — Burada url bilgisi, hangi work item’a related olmasını istiyorsak onun bilgisini içerir.
{ "op": "add", "path": "/relations/-", "value": { "rel": "add", "url": " https://dev.azure.com/{organization-name}/_apis/wit/workitems/{baseWorkItemId}" } }
8- Assigned To — Work item’ı oluşturduktan sonra kime atamak istiyorsak onun azure devopsa kayıtlı user bilgisi verilir. Eğer bu bilgi request bodyde yer almazsa default olarak unassigned atanır.
{ "op": "add", "path": "/fields/System.AssignedTo", "value": "AssignedPerson" }
9- Attachment eklemek için aşağıdaki obje gönderilir. Buradaki url bilgisi üst tarafta anlattığımız attachment oluşturmak için attıiğımız post methodu sonrasında elde ettiğimiz response içindeki url bilgisidir:
{ "op": "add", "path": "/relations/-", "value": { "rel": "add", "url": "https://dev.azure.com/{project-name}/{project-relate-process-id}/_apis/wit/attachments/uploadedImageId?fileName={attachedImage.png}", "attributes": { "comment": "Attachment'a ait yorum" } } }
Zorluk yaşadığım noktalardan bahsetmem gerekirse:
Azure devops work item’ı içindeki alanlar html bağımlı şekilde oluşturulmuştur. Bundan dolayı oluşturulan tanımı string olarak gönderdiğimizde boşluk, alt satıra inme karakterleri api tarafından halledilememektedir. Bundan dolayı description alanı içindeki stringi html’e dönüştürüp öyle göndermemiz gerekir.
İkinci bir konu ise karakter konusu, utf-8 formatını charset olarak request property alanı içinde vermeliyiz. Bu şekilde vermediğimizde şuradaki karakter setlerinde hata alıyoruz: 1234567890*-/+,<>£#$½{[]}\|~¨i₺€@æß´`|é!’^+%&/()=?
Keyifli okumalar,