添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Jira里面自定义字段的选择需要在admin页面配置

Administration panel > Custom fields > configure > Edit options

有没有可以自动添加的接口什么的,经过查找,找到如下资源,先行mark,待有空来验证。

2020-03-13 更新,发现插件可以实现,看第3节

2. 信息

原文地址 https://community.atlassian.com/t5/Answers-Developer-Questions/How-do-I-update-Jira-custom-field-via-REST-api/qaq-p/498231

摘抄一下,以免信息丢失。

Followed this tutorial: https://developer.atlassian.com/server/framework/atlassian-sdk/developing-a-rest-service-plugin/
Added following method to the Rest Resource class (MyRestResrouce.java in the tutorial).

* This method is to be used whenever a new option is to be added to a custom field. It will add it to the top of the list. * @param fieldId - custom field id, e.g,. customfield_10000 * @param optionVal - option value, e.g,. 4.1r1.24.67643_70 * @return @AnonymousAllowed @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Path("/addOptionsToCustomField") public Response addOptionToCustomField(@QueryParam("fieldId") String fieldId, @QueryParam("optionVal") String optionVal) CustomFieldManager customFldMgr = ComponentAccessor.getCustomFieldManager(); OptionsManager optionsManager = ComponentAccessor.getComponentOfType(OptionsManager.class); if (fieldId == null || fieldId.trim().equals("")) { return Response.ok(new ZRestResourceModel("default","Missing custom field id")).build(); //error checking code snipped CustomField customField = customFldMgr.getCustomFieldObject(fieldId); //error checking code snipped List<FieldConfigScheme> schemes = customField.getConfigurationSchemes(); if (schemes != null && !schemes.isEmpty()) { FieldConfigScheme sc = schemes.get(0); MultiMap configs = sc.getConfigsByConfig(); if (configs != null && !configs.isEmpty()) { FieldConfig config = (FieldConfig) configs.keySet().iterator().next(); Options ops = optionsManager.getOptions(config); if(ops != null && ops.getOptionForValue(optionVal, null) != null) return Response.ok(... snipped Option op = optionsManager.createOption(config, null, new Long(1), optionVal); ops = optionsManager.getOptions(config); ops.moveToStartSequence(op); return Response.ok(new ZRestResourceModel("default","SUCCESS")).build();

3. 插件可以实现接口

发现了这个插件,可以通过接口实现对单选选项的设置

custom filed plugin
https://codeclou.io/customfield-editor-for-jira/1.3.0/rest-api/

请求头带账号密码:
13500 为custom field ID
POST http://10.10.11.18:8080/rest/jiracustomfieldeditorplugin/1/user/customfields/13500/contexts/default/options HTTP/1.1
content-type: application/json
Authorization: Basic administrator 1231231232
{ "optionvalue": "BBB品牌" }
失败信息:
HTTP/1.1 400
  "message": "validation errors",
  "statusCode": 400,
  "subCode": 400000,
  "errors": [
      "name": "optionvalue",
      "message": "This option value does already exist. Option values need to be unique."
成功信息:
HTTP/1.1 200
  "optionvalue": "BBB品牌",
  "id": 15718,
  "sequence": 264,
  "disabled": false

4. python 脚本

依照上面的插件,我写了一个python脚本可以实现对自定义字段的操作

# _*_ coding:utf-8 _*_
@version: python3.x
@author: Max.Bai
@contact: 
@software: VS Code
@file: jira_tools.py
@time: 2020/06/02 16:05
import base64
import json
import logging
import requests
from src.utils.dms_error import DmsException
class JiraCustomFieldOptionEditor(object):
    """jira custom field option editor
    Jira 自定义字段的选项编辑器
    支持查询,新增,修改
    1. Jira安装第三方插件:Customfield Editor for Jira
        官网: https://codeclou.io/customfield-editor-for-jira/2.3.0/rest-api/cors-setup/
    2. Jira中设置权限给当前用户,可以设置自定义字段, 
        操作用户可以在此页面http://1.2.3.4/secure/CustomFieldEditorPlugin-UserListCustomField.jspa,
        看到可以操作的自定义的字段,没有就需要权限设置页面添加权限
        权限操作页面 http://1.2.3.4/secure/CustomFieldEditorPlugin-AdminListCustomField.jspa
    Args:
        object ([type]): [description]
    REST_API_BASE_URL = "/rest/jiracustomfieldeditorplugin/1"
    REST_API_CUSTOM_URL = "/user/customfields"
    REST_API_OPTIONS_URL = "/user/customfields/{customFieldId}/contexts/default/options/"
    session = requests.session()
    def __init__(self, jira_root, jira_auth):
        """init
        Args:
            jira_root (str): http://1.2.3.4:8080
            user_name (str): jira username
            user_pwd (str): jira pwd
        self.jira_root = jira_root
        self.jira_auth = jira_auth
        # set header
        self.req_headers = {
            "content-type": "application/json",
            "authorization": "Basic {jira_auth}".format(jira_auth=jira_auth)
        self.full_option_url = self.jira_root + self.REST_API_BASE_URL + self.REST_API_OPTIONS_URL
    def get_avalid_custom_fields(self):
        """获取有权限操作的自定义字段
        Args:
        Returns:
            list: 字段list, 失败报错
        options = []
        req_url = self.jira_root + self.REST_API_BASE_URL + self.REST_API_CUSTOM_URL
            resp = self.session.get(req_url, headers=self.req_headers)
            if resp.status_code == 200:
                options = resp.json()
            else:
                self._raise_error_message(resp, "Get Avalid Custom Field")
            return options
        except Exception as e:
            raise DmsException("Request jira failed! ERROR:{}".format(str(e))) 
    def get_custom_field_options(self, customfield_id:int):
        """获取自定义字段的选项
        Args:
            customfield_id (int): 自定义字段ID
        Returns:
            list: 选项list, 失败报错
        options = []
        req_url = self.full_option_url.format(customFieldId=customfield_id)
            resp = self.session.get(req_url, headers=self.req_headers)
            if resp.status_code == 200:
                options = resp.json()
            else:
                self._raise_error_message(resp, "Get Custom Field[{}] Option".format(customfield_id))
            return options
        except Exception as e:
            raise DmsException("Request jira failed! ERROR:{}".format(str(e)))
    def add_custom_option(self, customfield_id:int, option_value:str):
        """添加自定义字段的选项, 选项不能重复,重复添加失败
            "optionvalue": "string",
            "id": 0,
            "sequence": 0,
            "disabled": false
        Args:
            customfield_id (int): 自定义字段ID
            option_value (str): 选项值
        Returns:
            dict: 选项 信息,失败报错
        logging.debug("Add cf {} {}".format(customfield_id, option_value))
        option = {}
        req_url = self.full_option_url.format(customFieldId=customfield_id)
        payload = {
            "optionvalue": option_value.strip()
            resp = self.session.post(req_url, data=json.dumps(payload), headers=self.req_headers)
            if resp.status_code == 200:
                option = resp.json()
            else:
                self._raise_error_message(
                    resp, 
                    "Add Custom Field[{}] Option[{}]".format(customfield_id, option_value)
            return option
        except Exception as e:
            raise DmsException("Request jira failed! ERROR:{}".format(str(e)))
    def update_custom_option(
        self, 
        customfield_id:int, 
        option_id:int, 
        option_value:str=None, 
        disabled:bool=None
        """修改自定义字段的选项值,是否禁用
            "optionvalue": "string",
            "id": 0,
            "sequence": 0,
            "disabled": false
        Args:
            customfield_id (int): 自定义字段ID
            option_id (int): 选项ID
            option_value (str): 选项值
            disabled (bool): 是否禁用,默认否
        Returns:
            dict: 选项 信息,失败报错
        option = {}
        req_url = (self.full_option_url + str(option_id)).format(customFieldId=customfield_id)
        payload = {
        if option_value:
            payload["optionvalue"] = option_value
        if disabled != None:
            payload["disabled"] = True if disabled else False
        if not payload:
            return None
            resp = self.session.put(req_url, data=json.dumps(payload), headers=self.req_headers)
            if resp.status_code == 200:
                option = resp.json()
            else:
                self._raise_error_message(
                    resp, 
                    "Update Custom Field[{}] Option[{}]".format(customfield_id, option_id)
            return option
        except Exception as e:
            raise DmsException("Request jira failed! ERROR:{}".format(str(e)))
    def _raise_error_message(self, resp, func_name):
        code = resp.status_code
        if code == 400:
            msg = "参数错误!" 
            msg += json.dumps(resp.json().get("errors"))
        elif code == 401:
            msg = "账号错误!"
        elif code == 403:
            msg = "账号权限错误!"
        elif code == 500:
            msg = "未知错误!" 
        elif code == 412:
            msg = "在请求的URL下不可用(最小版本)!" 
        else:
            msg = "未知code错误!" 
            msg += resp.json.get("message", "")
        except Exception as e:
        raise Exception('{} failed! Code:{} Message:{}'.format(func_name, code, msg))
if __name__ == "__main__":
    import time
    jira_root = "http://10.60.35.62:8080"
    jira_user = "administrator"
    jira_pwd = "123123."
    jira_cf_editor = JiraCustomFieldOptionEditor(jira_root, jira_user, jira_pwd)
    # get avalid cfs
    cfs = jira_cf_editor.get_avalid_custom_fields()
    print("Avalid CustomField List:", cfs)
    customfield_id = 10200   # 自定义字段ID
    # get options
    options = jira_cf_editor.get_custom_field_options(customfield_id)
    print("Opions List")
    for op in options:
        print(op)
    # add new option
        new_option = jira_cf_editor.add_custom_option(customfield_id, options[0]["optionvalue"])
        print("Add exists option failed success:", new_option)
    except Exception as e:
        print("Add exists option failed failed.")
        print(str(e))
    # add new option
    new_option = jira_cf_editor.add_custom_option(customfield_id, "option_{}".format(time.time()))
    new_option_id = new_option.get('id', 0)
    print("Add option success:", new_option)
    # update set option disable and option value
    updated_option = jira_cf_editor.update_custom_option(
                        customfield_id, new_option_id, 
                        option_value="option_test_{}".format(time.time()),
                        disabled=True
    print("Update option success:", updated_option)
    # update set option disable failed
        updated_option = jira_cf_editor.update_custom_option(
                        customfield_id, 1231232, 
                        option_value="option_test_{}".format(time.time()),
                        disabled=True
        print("Update option failed Failed:", updated_option)
    except Exception as e:
        print("Update option failed success:")
        print(str(e))
    # get options
    options = jira_cf_editor.get_custom_field_options(customfield_id)
    print("Opions List")
    for op in options:
        print(op)
                    Jira - 单选自定义字段 通过接口添加选项Max.Bai2019-101. 背景Jira里面自定义字段的选择需要在admin页面配置Administration panel > Custom fields > configure > Edit options有没有可以自动添加的接口什么的,经过查找,找到如下资源,先行mark,待有空来验证。2...
万一某些功能无法正常运行。
添加说明后,请仅指定以下属性:
 标签: invalid ,[ cloud jirajira 7 , jira 8 ] –指定在哪个JIRA版本中再现问题。
 项目: jira-helper
添加有关错误/问题的描述
添加说明后,请仅指定以下属性:
 标签: bug ,[ cloud jirajira 7 , jira 8 ] –指定在哪个JIRA版本中再现问题。
 项目: jira-helper
最常用标签列表
feature
invalid
 功能无法正常工作
 问题/错误,请确保指定JIRA版本标签,以便在其中复制
jira 7
 可在JIRA 7.xx中重现
jira 8
 可在JIRA 8.xx中重
				
JIRA是一款非常灵活的研发项目管理工具,本身可支持issue类型、字段、工作流、界面的自定义,但对于JIRA的系统字段以及部分工作流的自定义还是有所局限,有一款插件叫做JSU是可以很好地帮助我们优化这一点。 插件截图: 针对指定的操作进行校验,必须满足某种条件才能进行操作。 举例:经办人和史诗链接不能为空,必须有值的时候才能创建issue成功。那我们应该如何进行配置呢? (1)选择工作流中 create 的转换,选择添加验证器。 test_jira = JIRA('http://jira.test.cn', basic_auth=("username", "password")) 二、获取jira项目列表 my_projects = test_jira.projects() 三、获取jira缺陷数据 1、遍历所有的项目 for project in my_projects: project_name = project.name 2、按照项目获取上一天的所有缺陷 (1)获取当天日期
JIRA是个很cool的平台。    我们常常会把现实中的工作流程抽象出来,放到JIRA上。以达到所谓的规范化流程管理,而不是整天盯着邮件或者其他低效的方式。    随之未来的问题就是:大家不知道怎么填写JIRA表单。特别是一旦用户数量达到一定程度后,开培训讲座也不太现实。    所以JIR 2. 选择“系统”菜单下的“字段选项。 3. 在“字段”页面中,选择要编辑的字段并单击“编辑”按钮。 4. 在编辑页面中,可以更改字段名称、描述和其他属性。如果需要,可以将该字段移动到另一个问题类型或屏幕上。 5. 更改完成后,单击“更新”按钮以保存更改。 如果您需要将问题字段从一个Jira实例迁移到另一个Jira实例,则可以使用Jira导入/导出功能。为此,您可以执行以下步骤: 1. 在源Jira实例中,使用Jira导出功能导出问题数据。 2. 在目标Jira实例中,使用Jira导入功能导入问题数据。 3. 确保导入过程中将源Jira实例中的字段映射到目标Jira实例中的相应字段。 请注意,进行Jira字段迁移时应谨慎操作,并在进行任何更改之前备份现有数据。 不知道是不是flask版本的问题, if __name__ != "__main__": gunicorn_logger = logging.getLogger("gunicorn.error") # logger对象,gunicorn.error记录器 app.logger.handlers = gunicorn_logger.handlers # 将Flask应用程序记录器的处理程序设置为Gunicorn记录器 app.logger.setLevel(gunicorn_logger.level) # 将-log-level传递给gunicorn,成为其适当处理程序的日志级别 如下写法才能正常运行.flask 2.3.2 Python - AES SHA1PRNG 加密解密总结 无水先生: keygen.init(256)是表情包 python3 - AES 加密实现java中SHA1PRNG 算法 薄年阿豪: 有没有python2对应的代码,这套代码对于python2来说加密的密文和python3对应的密文不一样 Python - Requests 模拟 DWR框架的请求 zkkkkkkkkkkkkk: 请问如果不获取scriptSessionId,也就是每次请求scriptSessionId都置空,会不会对接口的返回造成影响。 Python - AES SHA1PRNG 加密解密总结 qiyuetiancheng: 问下keygen.init(256)这种该如何处理