EDIT:
Below only worked if an attachment was actually uploaded but failed if no upload was made.
To fix this, we add a condition based on length on the actual form output that we are using and put the "Parse JSON" and "For Each Attachment" within that "If yes".
The condition should be " "0" is not equal to "length(body('Get_response_details')?['the_form_question'])" "

Hi @ersanbil @Ratheeshvenu @shsharma14 @KelvinRHC
Recently I managed to get this working and since I do not see this "solution" elsewhere in the community I thought of posting it.
This solution adds ALL attachments for me.
I am no Power Automate veteran so have that in mind, and sorry in advance for the mix of Swedish and English in the samples below.



Explanation:
1. "Parse the JSON" with the question including the upload attachment from the MS Forms "Get Response Details"
Scheme:
{
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"link": {
"type": "string"
},
"id": {
"type": "string"
},
"type": {},
"size": {
"type": "integer"
},
"referenceId": {
"type": "string"
},
"driveId": {
"type": "string"
},
"status": {
"type": "integer"
},
"uploadSessionUrl": {}
},
"required": [
"name",
"link",
"id",
"type",
"size",
"referenceId",
"driveId",
"status",
"uploadSessionUrl"
]
}
}
2. "For Each" I then:
3. "OneDrive for Business - Get File Content by Path" where the content is the path such as apps/Microsoft Forms/{form name}/{question}/@{items('For_Each_Attachment')['name']} - This to get the content of all files as Base64, Name is from the first Parse JSON
4. "Compose" with the expression below - This is to retrieve only the Base64 content from the Get File Content which contains other information as well.
outputs('Get_File_Content_by_Path')?['body/$content']
5. "Send a HTTP request to Azure DevOps - Send Attachment to DevOps" with:
POST
URL = {project}/_apis/wit/attachments?filename=@{items('For_Each_Attachment')['name']}&api-version=7.1
Content-Type = application/octet-stream
Body = Output of "Compose"
Set body as Base64
This is to send the attachment into DevOps, this does not link it to any workitem. Name is from the first Parse JSON.
6. "Parse JSON" with the output from "Send Attachment to DevOps" as content and the following scheme:
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"url": {
"type": "string"
}
}
}
This is so we can know what the URL is of the attachment we want to attach later on.
7. "Send a HTTP request to Azure DevOps - Add attachment" with:
PATCH
URL = {project}/_apis/wit/workitems/@{outputs('Create_change_request')?['body/id']}/?api-version=7.2-preview
@{outputs('Create_change_request')?['body/id']} is the ID of your workitem which is created before in the flow
Content-Type = application/json-patch+json
Body = ( url = "url" from lst Parse JSON ) ( name = name from first Parse JSON )
[
{
"op": "add",
"path": "/relations/-",
"value":
{
"rel": "AttachedFile",
"url": "@{body('Parsa_JSON_2')?['url']}",
"attributes":
{
"comment": "Automatic attachment upload",
"name":"@{items('For_Each_Attachment')['name']}"
}
}
}
]