0

Add Attachments to Issue

by
Published Nov 2, 2023

Attach one or more files from Windmill object storage to an issue. Each file keeps the name at the end of its storage path.

Script jira Verified

The script

Submitted by hugo989 Bun
Verified 4 hours ago
1
import * as wmill from "windmill-client"
2
import { S3Object } from "windmill-client"
3

4
/**
5
 * Add Attachments to Issue
6
 * Attach one or more files from Windmill object storage to an issue. Each file keeps the name at the end of its storage path.
7
 */
8
export async function main(
9
  auth: RT.Jira,
10
  issue_id_or_key: string,
11
  files: S3Object[]
12
) {
13
  const form = new FormData()
14
  for (const file of files) {
15
    const bytes = await wmill.loadS3File(file)
16
    if (!bytes) {
17
      throw new Error(`Could not load ${file.s3} from object storage`)
18
    }
19
    form.append("file", new Blob([bytes]), file.s3.split("/").pop())
20
  }
21

22
  const url = new URL(
23
    `https://${auth.domain}.atlassian.net/rest/api/3/issue/${issue_id_or_key}/attachments`
24
  )
25
  const response = await fetch(url, {
26
    method: "POST",
27
    headers: {
28
      Authorization: `Basic ${btoa(`${auth.username}:${auth.password}`)}`,
29
      "X-Atlassian-Token": "no-check",
30
      Accept: "application/json",
31
    },
32
    body: form,
33
  })
34

35
  if (!response.ok) {
36
    throw new Error(`${response.status} ${await response.text()}`)
37
  }
38

39
  return await response.json()
40
}
41

Other submissions
  • Submitted by hugo697 Typescript (fetch-only)
    Created 525 days ago
    1
    type Jira = {
    2
      username: string;
    3
      password: string;
    4
      domain: string;
    5
    };
    6
    /**
    7
     * Add attachment
    8
     * Adds one or more attachments to an issue.
    9
     */
    10
    export async function main(
    11
      auth: Jira,
    12
      issueIdOrKey: string,
    13
      body: {
    14
        bytes?: string[];
    15
        contentType?: string;
    16
        empty?: boolean;
    17
        inputStream?: { [k: string]: unknown };
    18
        name?: string;
    19
        originalFilename?: string;
    20
        resource?: {
    21
          description?: string;
    22
          file?: string;
    23
          filename?: string;
    24
          inputStream?: { [k: string]: unknown };
    25
          open?: boolean;
    26
          readable?: boolean;
    27
          uri?: string;
    28
          url?: string;
    29
        };
    30
        size?: number;
    31
      }[]
    32
    ) {
    33
      const url = new URL(
    34
        `https://${auth.domain}.atlassian.net/rest/api/2/issue/${issueIdOrKey}/attachments`
    35
      );
    36
    
    
    37
      const formData = new FormData();
    38
      for (const [k, v] of Object.entries(body)) {
    39
        if (v !== undefined && v !== "") {
    40
          formData.append(k, String(v));
    41
        }
    42
      }
    43
      const response = await fetch(url, {
    44
        method: "POST",
    45
        headers: {
    46
          Authorization: "Basic " + btoa(`${auth.username}:${auth.password}`),
    47
        },
    48
        body: formData,
    49
      });
    50
      if (!response.ok) {
    51
        const text = await response.text();
    52
        throw new Error(`${response.status} ${text}`);
    53
      }
    54
      return await response.json();
    55
    }
    56