Intro
Template engine for (currently) Jira and Email. Uses yaml and jinja2. It helps you create multiple (possibly cross-linked) jira issues and emails from a template.
Table of Contents
Installation
Windows
- Download Workflow_Templater_${version}.exe from the latest release on Releases page.
- Install it.
- Now
workflow-templater
executable should be available from Windows Command Prompt (cmd.exe
) and from Powershell. - (Optional, recommended) Install Windows Terminal and use it instead of default console.
macOS
- Install python ≥ 3.10.
- Using official Python installer:
- Install python ≥ 3.10 from https://python.org/ ("macOS 64-bit installer")
- Install CA certificates for python, execute in Terminal:
/Applications/Python\ 3.7/Install\ Certificates.command
Alternatively, you can double-click on Install Certificates.command
in Finder
- Or using Homebrew:
brew install python
-
pip3 install workflow-templater
Anything else (GNU/Linux, Cygwin, *nix, etc)
Using pip
- Make sure that python ≥ 3.10 is installed
-
pip3 install workflow-templater
Using pipx
-
pipx run workflow-templater
From source
- Clone this repo
- Install dependencies if required
pip3 install -r requirements.txt
- You can execute the script directly:
cd workflow_templater
./workflow_templater/__init__.py --help
Or install/build/whatever it with
python3 setup.py
Usage
See
workflow-templater --help
Configuration
To avoid typing same command line arguments each time, it is possible to specify them in configuration file. Configuration file location is OS-specific, to find out correct location for your os, execute workflow-templater --help
, you'll see message "--config CONFIG overwrite config file path, default is ${location}" where ${location} is the location of configuration file on your OS. You can create this file and specify values of command-line arguments omitting --
and replacing -
with _
, for example, --jira-user j_wayne
becomes jira_user: j_wayne
, --dry-run
becomes dry_run: true
and so on. You can also use jinja2 in configuration file which evaluates using variables from itself.
Example ~/.config/workflow-templater/config.yaml
:
dry_run: true
verbose: true
user: j_wayne
jira: https://jira.example.com/
jira_user: '{{ user }}'
email_user: '{{ user }}'
email_from: '{{ user }}@example.com'
email_smtp: 'smtp.example.com:587'
jira_keyring_service_name: 'MyCorp LDAP'
email_keyring_service_name: 'MyCorp LDAP'
Template description
Overview
-
Whole workflow template is a directory.
-
There should be one file with variables named 0_common.yaml
, 00_common.yaml
or common.yaml
. Alternatively, you can name this file as you wish and specify its name with --vars
argument.
-
There may be any amount of "issue" files:
- ending with ".jira.yaml" for jira issue
- All fields in each jira.issue file are send as is to Jira via API in
fields
fileld with the exception of following fields:
watchers
: it's impossible to add watchers during create so it handled separately via this API method.update
: its content is sent in update
via API- global special fields (see below)
- ending with ".email.yaml" for email.
-
There may be optional file named mutate.py
with function mutate
which accepts variables, modifies them and returns the result wich can be used in templates.
Basic example:
def mutate(variables):
variables['new_variable'] = f'{variables["old_var1"]} and {variables["old_var2"]}'
return variables
Security note: if you concerned that this feature introduces an ability to execute arbitrary code from the templates, that's correct. However, this is also possible with bare jinja templates (see https://github.com/pallets/jinja/issues/549), so you should make sure that your templates come from trusted sources anyway.
-
Each "issue" file is yaml file where each string value is rendered with Jinja2 using variables from *common.yaml
file.
-
Special variables available for use in jinja:
issuekey_self
: Jira issue key or Message-ID of current issue or email.issuekey_<name>
: Jira issue key or Message-ID of issue or email named <name>
. For example, for issue in filename something.jira.yaml
this variable name would be issuekey_something
and it can be used in all templates.
-
Global special fields:
foreach
: list, create one issue per item in this list. List items should be strings or dicts (in case of dicts you must specify foreach_namevar
too, see below). In case of strings, issuekey_ variable would be named issuekey_<name>_<list_value>
Example:
foreach:
- Android
- iOS
summary: 'Release application for {{ item }}'
...
would finally evaluate to following issues:
summary: 'Release application for Android'
...
summary: 'Release application for iOS'
...
foreach_fromvar
: if content for foreach
variable is shared between several templates, it's better to specify it in *common.yaml
file and specify here the name of the variable in this file. Example:
common.yaml
:
OSes:
- Android
- iOS
...
build.jira.yaml
:
foreach_fromvar: OSes
summary: 'Build clients for {{ item }}'
...
release.jira.yaml
:
foreach_fromvar: OSes
summary: 'Release application for {{ item }}'
...
foreach_key
: if you don't like default variable name (item
) for each item in foreach
list, you may specify it here. Example
foreach:
- Android
- iOS
foreach_key: os
summary: 'Release application for {{ os }}'
...
would finally evaluate to following issues:
summary: 'Release application for Android'
...
summary: 'Release application for iOS'
...
foreach_namevar
: when foreach is in use, workflow-templater would generate issuekey_ variable name as follows: issuekey_<name>_<list_value>
. If you use dicts as foreach values, you need to specify key name in this dicts which will be appended to the end of this variable name. Example
release.jira.yaml
file:
foreach:
- name: Android
date: !!timestamp 2019-10-24 06:30:00.0
- name: iOS
date: !!timestamp 2019-10-24 10:50:00.0
foreach_namevar: name
summary: 'Release application for {{ item.name }}'
...
Now in any other (or the same) issue you can link to this issues as follows:
summary: 'Notify community'
description: |
Android release task: {{ issuekey_release_Android }}
iOS release task: {{ issuekey_release_iOS }}
if
: if this variable value evaluates to empty string (''
), false
or no
, this template will be completely ignored. Note: value for this variable is calculated for each item separately when foreach
or foreach_fromvar
is in use.
Example:
foreach:
- Android
- iOS
foreach_key: os
if: '{{ os in ["Android", "GNU/Linux"] }}'
summary: 'Release application for {{ os }}'
...
would finally evaluate to following issue (only one, obviously):
summary: 'Release application for Android'
...
Examples
See basic release example for basic example.