0

Update Issue

by
Published Nov 2, 2023

Edit an issue's fields. Only what you pass changes: `summary` and `description` (plain text, converted to Atlassian Document Format) are shortcuts, `fields` sets any field by ID, and `update` takes add/remove/set operations (e.g. `{ "labels": [{ "add": "triaged" }] }`). Status changes go through Transition Issue. Skipping notifications needs the Administer Jira or Administer Projects permission.

Script jira Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 4 hours ago
1
//native
2

3
// Wraps plain text in Atlassian Document Format, one paragraph per line.
4
function adf(text: string) {
5
  return {
6
    type: "doc",
7
    version: 1,
8
    content: text.split("\n").map((line) => ({
9
      type: "paragraph",
10
      content: line ? [{ type: "text", text: line }] : [],
11
    })),
12
  }
13
}
14

15
/**
16
 * Update Issue
17
 * Edit an issue's fields. Only what you pass changes: `summary` and `description` (plain text, converted to Atlassian Document Format) are shortcuts, `fields` sets any field by ID, and `update` takes add/remove/set operations (e.g. `{ "labels": [{ "add": "triaged" }] }`). Status changes go through Transition Issue. Skipping notifications needs the Administer Jira or Administer Projects permission.
18
 */
19
export async function main(
20
  auth: RT.Jira,
21
  issue_id_or_key: string,
22
  summary: string | undefined,
23
  description: string | undefined,
24
  fields: { [key: string]: any } | undefined,
25
  update: { [key: string]: any } | undefined,
26
  skip_notifications: boolean | undefined,
27
  return_issue: boolean | undefined
28
) {
29
  const url = new URL(
30
    `https://${auth.domain}.atlassian.net/rest/api/3/issue/${issue_id_or_key}`
31
  )
32

33
  if (skip_notifications) {
34
    url.searchParams.append("notifyUsers", "false")
35
  }
36
  if (return_issue) {
37
    url.searchParams.append("returnIssue", "true")
38
  }
39

40
  const body: { [key: string]: any } = { fields: { ...fields } }
41
  if (summary != null && summary !== "") {
42
    body.fields.summary = summary
43
  }
44
  if (description != null && description !== "") {
45
    body.fields.description = adf(description)
46
  }
47
  if (update && Object.keys(update).length) {
48
    body.update = update
49
  }
50

51
  const response = await fetch(url, {
52
    method: "PUT",
53
    headers: {
54
      Authorization: `Basic ${btoa(`${auth.username}:${auth.password}`)}`,
55
      "Content-Type": "application/json",
56
      Accept: "application/json",
57
    },
58
    body: JSON.stringify(body),
59
  })
60

61
  if (!response.ok) {
62
    throw new Error(`${response.status} ${await response.text()}`)
63
  }
64

65
  if (response.status === 204) return { success: true }
66
  return await response.json()
67
}
68

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
     * Edit issue
    8
     * Edits an issue.
    9
     */
    10
    export async function main(
    11
      auth: Jira,
    12
      issueIdOrKey: string,
    13
      notifyUsers: string | undefined,
    14
      overrideScreenSecurity: string | undefined,
    15
      overrideEditableFlag: string | undefined,
    16
      returnIssue: string | undefined,
    17
      expand: string | undefined,
    18
      body: {
    19
        fields?: { [k: string]: unknown };
    20
        historyMetadata?: {
    21
          activityDescription?: string;
    22
          activityDescriptionKey?: string;
    23
          actor?: {
    24
            avatarUrl?: string;
    25
            displayName?: string;
    26
            displayNameKey?: string;
    27
            id?: string;
    28
            type?: string;
    29
            url?: string;
    30
            [k: string]: unknown;
    31
          };
    32
          cause?: {
    33
            avatarUrl?: string;
    34
            displayName?: string;
    35
            displayNameKey?: string;
    36
            id?: string;
    37
            type?: string;
    38
            url?: string;
    39
            [k: string]: unknown;
    40
          };
    41
          description?: string;
    42
          descriptionKey?: string;
    43
          emailDescription?: string;
    44
          emailDescriptionKey?: string;
    45
          extraData?: { [k: string]: string };
    46
          generator?: {
    47
            avatarUrl?: string;
    48
            displayName?: string;
    49
            displayNameKey?: string;
    50
            id?: string;
    51
            type?: string;
    52
            url?: string;
    53
            [k: string]: unknown;
    54
          };
    55
          type?: string;
    56
          [k: string]: unknown;
    57
        };
    58
        properties?: { key?: string; value?: { [k: string]: unknown } }[];
    59
        transition?: {
    60
          expand?: string;
    61
          fields?: {
    62
            [k: string]: {
    63
              allowedValues?: { [k: string]: unknown }[];
    64
              autoCompleteUrl?: string;
    65
              configuration?: { [k: string]: { [k: string]: unknown } };
    66
              defaultValue?: { [k: string]: unknown };
    67
              hasDefaultValue?: boolean;
    68
              key: string;
    69
              name: string;
    70
              operations: string[];
    71
              required: boolean;
    72
              schema: {
    73
                configuration?: { [k: string]: { [k: string]: unknown } };
    74
                custom?: string;
    75
                customId?: number;
    76
                items?: string;
    77
                system?: string;
    78
                type: string;
    79
              };
    80
            };
    81
          };
    82
          hasScreen?: boolean;
    83
          id?: string;
    84
          isAvailable?: boolean;
    85
          isConditional?: boolean;
    86
          isGlobal?: boolean;
    87
          isInitial?: boolean;
    88
          looped?: boolean;
    89
          name?: string;
    90
          to?: {
    91
            description?: string;
    92
            iconUrl?: string;
    93
            id?: string;
    94
            name?: string;
    95
            scope?: {
    96
              project?: {
    97
                avatarUrls?: {
    98
                  "16x16"?: string;
    99
                  "24x24"?: string;
    100
                  "32x32"?: string;
    101
                  "48x48"?: string;
    102
                };
    103
                id?: string;
    104
                key?: string;
    105
                name?: string;
    106
                projectCategory?: {
    107
                  description?: string;
    108
                  id?: string;
    109
                  name?: string;
    110
                  self?: string;
    111
                };
    112
                projectTypeKey?: "software" | "service_desk" | "business";
    113
                self?: string;
    114
                simplified?: boolean;
    115
              };
    116
              type?: "PROJECT" | "TEMPLATE";
    117
              [k: string]: unknown;
    118
            };
    119
            self?: string;
    120
            statusCategory?: {
    121
              colorName?: string;
    122
              id?: number;
    123
              key?: string;
    124
              name?: string;
    125
              self?: string;
    126
              [k: string]: unknown;
    127
            };
    128
            [k: string]: unknown;
    129
          };
    130
          [k: string]: unknown;
    131
        };
    132
        update?: {
    133
          [k: string]: {
    134
            add?: { [k: string]: unknown };
    135
            copy?: { [k: string]: unknown };
    136
            edit?: { [k: string]: unknown };
    137
            remove?: { [k: string]: unknown };
    138
            set?: { [k: string]: unknown };
    139
          }[];
    140
        };
    141
        [k: string]: unknown;
    142
      }
    143
    ) {
    144
      const url = new URL(
    145
        `https://${auth.domain}.atlassian.net/rest/api/2/issue/${issueIdOrKey}`
    146
      );
    147
      for (const [k, v] of [
    148
        ["notifyUsers", notifyUsers],
    149
        ["overrideScreenSecurity", overrideScreenSecurity],
    150
        ["overrideEditableFlag", overrideEditableFlag],
    151
        ["returnIssue", returnIssue],
    152
        ["expand", expand],
    153
      ]) {
    154
        if (v !== undefined && v !== "") {
    155
          url.searchParams.append(k, v);
    156
        }
    157
      }
    158
      const response = await fetch(url, {
    159
        method: "PUT",
    160
        headers: {
    161
          "Content-Type": "application/json",
    162
          Authorization: "Basic " + btoa(`${auth.username}:${auth.password}`),
    163
        },
    164
        body: JSON.stringify(body),
    165
      });
    166
      if (!response.ok) {
    167
        const text = await response.text();
    168
        throw new Error(`${response.status} ${text}`);
    169
      }
    170
      return await response.json();
    171
    }
    172