how can i create custom field with script runner? - groovy

My epics contain the system field Rank, How can I add this field to the tasks of my epic using the script runner or other tools ?

You need com.atlassian.greenhopper.api.rank.RankService class
Try this to make rank of issue1 after issue2:
import com.atlassian.greenhopper.api.rank.RankService
import com.atlassian.jira.issue.fields.CustomField
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.customisers.JiraAgileBean
import com.atlassian.jira.component.ComponentAccessor
#WithPlugin('com.pyxis.greenhopper.jira')
#JiraAgileBean
RankService rankService
def user = ComponentAccessor.getUserManager().getUserByKey('userName')
def issue1 = ComponentAccessor.getIssueManager().getIssueByCurrentKey("KEY")
def issue2 = ComponentAccessor.getIssueManager().getIssueByCurrentKey("KEY")
def rank = ComponentAccessor.getCustomFieldManager().getCustomFieldObject(rankFieldId)
rankService.rankAfter(user, rankFieldId, issue1, issue2)

Related

How to retrieve the value of the summary system field using the postfunction of a workflow transition in scriptrunner

I am trying to retrieve the value of the Summary system field in Jira using ScriptRunner. I am using the following code in scriptrunner but the problem is that the variable cf returned by the line def cf = customFieldManager.getCustomFieldObject("Summary") is null. How can I fix this and retrieve the value of the summary field in ScriptRunner?
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import org.apache.log4j.Logger
def log = Logger.getLogger("atlassian-jira.log")
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def issueManager = ComponentAccessor.getIssueManager()
def cf = customFieldManager.getCustomFieldObject("Summary")
log.warn("MOUNA 1: "+cf)
issue.setCustomFieldValue(cf, "mouna")
log.warn("MOUNA 2: "+issue)
"Summary" field in Jira is not a custom field.
You can access the Summary field (and other system fields) directly from issue:
log.warn(issue.summary)
But for updating it in Post Function, you need to use MutableIssue class:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.event.type.EventDispatchOption
def mIssue = (MutableIssue) issue
mIssue.setSummary("New Summary")
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser() // Or you can get any user by using UserManager
ComponentAccessor.getIssueManager().updateIssue(user, mIssue, EventDispatchOption.ISSUE_UPDATED, false)
Of course, don't forget to import required classes at beginning of your code:

How to set default epic link in Jira using Groovy

I need to set epic link using groovy if a condition is true. I'm using the following script:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.Issue;
def customFieldManager = ComponentAccessor.getCustomFieldManager()
IssueManager issueManager = ComponentAccessor.getOSGiComponentInstanceOfType(IssueManager.class)
def epiclink = CustomFieldManager.getCustomFieldObject("customfield_1000")
issue.setCustomFieldValue(epiclink,"MAR-1518")
But im getting this error:
I tried this code from this question but it didn't worked for me.
You just have a typo. In line
def epiclink = CustomFieldManager.getCustomFieldObject("customfield_1000")
you are calling the CustomFieldManager class (inital is uppercase)
However, you need to call your variable customFieldManager which is from ComponentAccessor.customFieldManager
So, the above line should be:
def epiclink = customFieldManager.getCustomFieldObject("customfield_1000")

Is it possible to make a module available as an import from another module?

I'm refactoring some code and have moved around some files. But for backwards compatibility, I would like to make all of my modules keep their old import paths.
my file structure is as follows
--| calcs/
----| __init__.py
----| new_dir
------| new_file1.py
------| new_file2.py
What do I need to do ensure that I can use an import like
import calcs.newfile1.foo
# OR
from calcs.newfile1 import foo
I have tried a few methods of adding the imports to the top level __init__.py file. As is reccommended here
But while this seems to allow an import such as import calcs.newfile1, An import such as import calcs.newfile1.foo raises ModuleNotFoundError: No module named calcs.newfile1
I expect that I need python to recognize calcs.newfile1 as a **module **. At the moment it seems to just be importing it as a class or other object of some sort
The only way i know how to do it is by creating a custom import hook.
Here is the PEP for more information.
If you need some help on how to implement one, i'll suggest you to take a look at the six module,
here
and here
Basically your calcs/__init__.py will become like this:
''' calcs/__init__.py '''
from .new_dir import new_file1, new_file2
import sys
__path__ = []
__package__ = __name__
class CalcsImporter:
def __init__(self, exported_mods):
self.exported_mods = {
f'{__name__}.{key}': value for key, value in exported_mods.items()
}
def find_module(self, fullname, path=None):
if fullname in self.exported_mods:
return self
return None
def load_module(self, fullname):
try:
return sys.modules[fullname]
except KeyError:
pass
try:
mod = self.exported_mods[fullname]
except KeyError:
raise ImportError('Unable to load %r' % fullname)
mod.__loader__ = self
sys.modules[fullname] = mod
return mod
_importer = CalcsImporter({
'new_file1': new_file1,
'new_file2': new_file2,
})
sys.meta_path.append(_importer)
and you should be able to do from calcs.new_file1 import foo

REDO: Starting Flask in a thread, ca. 2020

I have an old question looking for a fresh answer. I've tried the recipes presented in the similar but somewhat aged question "Start a flask application in a seperate thread", and some other similar solutions found in other posts.
The long and short of it is, I need to start a flask application in a 'background' thread, such that a wxPython GUI can run in the foreground. The solutions presented here seem to no longer have the desired effect. The flask app starts and the GUI never runs.
My suspicion is, the existing answers are out of date. That said, I'm open to the possibility that I've mangled something else that's hosing it up, please have a peek and advise accordingly.
Thanks for your eyeballs and brain cycles :)
My code follows.
#!/usr/bin/env python
"""
integrator.py (the app)
"""
import wx
from pubsub import pub
from flask import Flask
from flask_graphql import GraphQLView
from models import db_session
from schema import schema
from models import engine, db_session, Base, Idiom
flaskapp = Flask(__name__)
flaskapp.debug = True
flaskapp.add_url_rule(
'/graphql',
view_func=GraphQLView.as_view(
'graphql',
schema=schema,
graphiql=True
)
)
flaskapp.run(threaded=True,use_reloader=False)
#flaskapp.teardown_appcontext
def shutdown_session(exception=None):
db_session.remove()
class IntegratorTarget(wx.TextDropTarget):
def __init__(self, object):
wx.DropTarget.__init__(self)
self.object = object
def OnDropText(self, x, y, data):
print(f"<publish>{data}</publish>")
pub.sendMessage('default', arg1=data)
return True
class IntegratorFrame(wx.Frame):
def __init__(self, parent, title):
super(IntegratorFrame, self).__init__(parent, title = title,size = wx.DisplaySize())
self.panel = wx.Panel(self)
box = wx.BoxSizer(wx.HORIZONTAL)
dropTarget = IntegratorTarget(self.panel)
self.panel.SetDropTarget(dropTarget)
pub.subscribe(self.catcher, 'default')
self.panel.SetSizer(box)
self.panel.Fit()
self.Centre()
self.Show(True)
def catcher(self,arg1):
data = arg1
print(f"<subscribed>{data}</subscribed>\n\n")
return
ex = wx.App()
Base.metadata.create_all(bind=engine)
IntegratorFrame(None,'Praxis:Integrator')
ex.MainLoop()
-- eof --
""" models.py """
from sqlalchemy import *
from sqlalchemy.orm import (scoped_session, sessionmaker, relationship, backref)
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:///.praxis/lexicon/unbound.db3', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
Base = declarative_base()
# We will need this for querying
Base.query = db_session.query_property()
class Idiom(Base):
__tablename__ = "idiomae"
id = Column(Integer, primary_key=True)
src = Column(String) # the text of the drag/paste operation
taxonomy = Column(String) # the type of resource referenced in the drag/paste operation
localblob = Column(String) # local path to media referenced in 'src'
timestamp = Column(DateTime) # date and time of capture
-- eof --
""" schema.py """
import graphene
from graphene import relay
from graphene_sqlalchemy import SQLAlchemyObjectType, SQLAlchemyConnectionField
from models import db_session, Idiom as IdiomaticModel
class Idiom(SQLAlchemyObjectType):
class Meta:
model = IdiomaticModel
interfaces = (relay.Node, )
class Query(graphene.ObjectType):
node = relay.Node.Field()
# Allows sorting over multiple columns, by default over the primary key
all_idioms = SQLAlchemyConnectionField(Idiom.connection)
# Disable sorting over this field
# all_departments = SQLAlchemyConnectionField(Department.connection, sort=None)
schema = graphene.Schema(query=Query)
I see where you tell Flask to be multi-threaded, but I don't see where you're starting up the Flask app in a thread. I expected to see something like
app = Flask(__name__)
# any extra configuration
def webserver():
app.run(use_reloader=False)
web_thread = threading.Thread(target=webserver)
web_thread.start()
... continue on with the main thread
I have a working example you can crib from here. Note the need to use appropriate locking of any data structures shared between the primary thread and the threads running Flask.

How to set extra_vars while running ansilbe-playbook programmatically in python3.5?(Ansible version - 2.8)

import os
import json
from collections import namedtuple
from ansible import context
from ansible.module_utils.common.collections import ImmutableDict
from ansible.utils.vars import load_extra_vars
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import InventoryManager
from ansible.playbook.play import Play
from ansible.executor.playbook_executor import PlaybookExecutor
def execute_ansible_playbook(CLOUD_TO_USE=None, PLAYBOOK=None):
playbook_path = PLAYBOOK
#inventory_path = "hosts"
#Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'diff', 'listhosts', 'listtasks', 'listtags', 'syntax'])
loader = DataLoader()
passwords = dict(vault_pass='secret')
inventory = InventoryManager(loader=loader, sources='inventory/' + CLOUD_TO_USE)
#inventory = InventoryManager(loader=loader, sources='localhost')
variable_manager = VariableManager(loader=loader, inventory=inventory)
executor = PlaybookExecutor(
playbooks=[playbook_path],
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
passwords=passwords
)
results = executor.run()
print (results)
I got this code from Run Ansible playbook programmatically?
This is running properly for other ansible-playbooks. But now I want to pass extra_vars to an ansible-playbook. I couldn't find a proper answer.
How can I do that?
FWIW. Use ansible-runner. The documentation is not complete. All parameters are described in the source.

Resources