# 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
<!-- generated with `md_toc -p README.md github` -->
<!--TOC-->
- [Intro](#intro)
- [Table of Contents](#table-of-contents)
- [Installation](#installation)
- [Windows](#windows)
- [macOS](#macos)
- [Anything else (GNU/Linux, Cygwin, *nix, etc)](#anything-else-gnulinux-cygwin-nix-etc)
- [Using pip](#using-pip)
- [Using pipx](#using-pipx)
- [From source](#from-source)
- [Usage](#usage)
- [Configuration](#configuration)
- [Template description](#template-description)
- [Overview](#overview)
- [Examples](#examples)
<!--TOC-->
# Installation
## Windows
1. Download Workflow_Templater_${version}.exe from the latest release on [Releases page](https://github.com/m-khvoinitsky/workflow-templater/releases).
2. Install it.
3. Now `workflow-templater` executable should be available from Windows Command Prompt (`cmd.exe`) and from Powershell.
4. (Optional, recommended) Install [Windows Terminal](https://github.com/Microsoft/Terminal) and use it instead of default console.
## macOS
1. Install python ≥ 3.10.
* Using official Python installer:
1. Install python ≥ 3.10 from <https://python.org/> ("macOS 64-bit installer")
2. 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](https://brew.sh/):
```sh
brew install python
```
2. ```sh
pip3 install workflow-templater
```
## Anything else (GNU/Linux, Cygwin, *nix, etc)
### Using pip
1. Make sure that python ≥ 3.10 is installed
2.
```sh
pip3 install workflow-templater
```
### Using pipx
1.
```sh
pipx run workflow-templater
```
### From source
1. Clone this repo
2. Install dependencies if required
```sh
pip3 install -r requirements.txt
```
3. 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
```sh
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`:
```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'
# avoid typing in the same password for jira and email
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](https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-createIssue) 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](https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-addWatcher).
* `update`: its content is sent in `update` via [API](https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-createIssue)
* 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:
```python
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](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](http://jinja.pocoo.org/docs/templates/) 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:
```yaml
foreach:
- Android
- iOS
summary: 'Release application for {{ item }}'
...
```
would finally evaluate to following issues:
```yaml
summary: 'Release application for Android'
...
```
```yaml
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`:
```yaml
OSes:
- Android
- iOS
...
```
`build.jira.yaml`:
```yaml
foreach_fromvar: OSes
summary: 'Build clients for {{ item }}'
...
```
`release.jira.yaml`:
```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
```yaml
foreach:
- Android
- iOS
foreach_key: os
summary: 'Release application for {{ os }}'
...
```
would finally evaluate to following issues:
```yaml
summary: 'Release application for Android'
...
```
```yaml
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:
```yaml
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:
```yaml
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:
```yaml
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):
```yaml
summary: 'Release application for Android'
...
```
## Examples
See [basic release example](https://github.com/m-khvoinitsky/workflow-templater/tree/master/examples/basic_release_example) for basic example.
Raw data
{
"_id": null,
"home_page": "https://github.com/m-khvoinitsky/workflow-templater",
"name": "workflow-templater",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "jira email template workflow release",
"author": "Mikhail Khvoinitsky",
"author_email": "me@khvoinitsky.org",
"download_url": "https://files.pythonhosted.org/packages/5b/f0/f5a46a62139f38b9e170bacc1e2d39014376045d57597aeec6008a9fec7d/workflow_templater-0.2.15.tar.gz",
"platform": null,
"description": "# Intro\nTemplate 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.\n\n# Table of Contents\n<!-- generated with `md_toc -p README.md github` -->\n<!--TOC-->\n\n- [Intro](#intro)\n- [Table of Contents](#table-of-contents)\n- [Installation](#installation)\n - [Windows](#windows)\n - [macOS](#macos)\n - [Anything else (GNU/Linux, Cygwin, *nix, etc)](#anything-else-gnulinux-cygwin-nix-etc)\n - [Using pip](#using-pip)\n - [Using pipx](#using-pipx)\n - [From source](#from-source)\n- [Usage](#usage)\n- [Configuration](#configuration)\n- [Template description](#template-description)\n - [Overview](#overview)\n - [Examples](#examples)\n\n<!--TOC-->\n\n# Installation\n\n## Windows\n1. Download Workflow_Templater_${version}.exe from the latest release on [Releases page](https://github.com/m-khvoinitsky/workflow-templater/releases).\n2. Install it.\n3. Now `workflow-templater` executable should be available from Windows Command Prompt (`cmd.exe`) and from Powershell.\n4. (Optional, recommended) Install [Windows Terminal](https://github.com/Microsoft/Terminal) and use it instead of default console.\n\n## macOS\n1. Install python \u2265 3.10.\n * Using official Python installer:\n 1. Install python \u2265 3.10 from <https://python.org/> (\"macOS 64-bit installer\")\n 2. Install CA certificates for python, execute in Terminal:\n ```\n /Applications/Python\\ 3.7/Install\\ Certificates.command\n ```\n Alternatively, you can double-click on `Install Certificates.command` in Finder\n * Or using [Homebrew](https://brew.sh/):\n ```sh\n brew install python\n ```\n2. ```sh\n pip3 install workflow-templater\n ```\n## Anything else (GNU/Linux, Cygwin, *nix, etc)\n### Using pip\n1. Make sure that python \u2265 3.10 is installed\n2.\n ```sh\n pip3 install workflow-templater\n ```\n### Using pipx\n1.\n ```sh\n pipx run workflow-templater\n ```\n### From source\n1. Clone this repo\n2. Install dependencies if required\n ```sh\n pip3 install -r requirements.txt\n ```\n3. You can execute the script directly:\n ```\n cd workflow_templater\n ./workflow_templater/__init__.py --help\n ```\n Or install/build/whatever it with\n ```\n python3 setup.py\n ```\n\n# Usage\nSee\n```sh\nworkflow-templater --help\n```\n# Configuration\nTo 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.\n\nExample `~/.config/workflow-templater/config.yaml`:\n```yaml\ndry_run: true\nverbose: true\nuser: j_wayne\njira: https://jira.example.com/\njira_user: '{{ user }}'\nemail_user: '{{ user }}'\nemail_from: '{{ user }}@example.com'\nemail_smtp: 'smtp.example.com:587'\n# avoid typing in the same password for jira and email\njira_keyring_service_name: 'MyCorp LDAP'\nemail_keyring_service_name: 'MyCorp LDAP'\n\n```\n\n# Template description\n## Overview\n* Whole workflow template is a directory.\n* 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.\n* There may be any amount of \"issue\" files:\n * ending with \".jira.yaml\" for jira issue\n * All fields in each jira.issue file are send as is to Jira via [API](https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-createIssue) in `fields` fileld with the exception of following fields:\n * `watchers`: it's impossible to add watchers during create so it handled separately via [this API method](https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-addWatcher).\n * `update`: its content is sent in `update` via [API](https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-createIssue)\n * global special fields (see below)\n * ending with \".email.yaml\" for email.\n* 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.\n\n Basic example:\n ```python\n def mutate(variables):\n variables['new_variable'] = f'{variables[\"old_var1\"]} and {variables[\"old_var2\"]}'\n return variables\n ```\n\n 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](https://github.com/pallets/jinja/issues/549)), so you should make sure that your templates come from trusted sources anyway.\n\n* Each \"issue\" file is yaml file where each string value is rendered with [Jinja2](http://jinja.pocoo.org/docs/templates/) using variables from `*common.yaml` file.\n* Special variables available for use in jinja:\n * `issuekey_self`: Jira issue key or Message-ID of current issue or email.\n * `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.\n* Global special fields:\n * `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>`\n Example:\n ```yaml\n foreach:\n - Android\n - iOS\n summary: 'Release application for {{ item }}'\n ...\n ```\n would finally evaluate to following issues:\n ```yaml\n summary: 'Release application for Android'\n ...\n ```\n ```yaml\n summary: 'Release application for iOS'\n ...\n ```\n * `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:\n `common.yaml`:\n ```yaml\n OSes:\n - Android\n - iOS\n ...\n ```\n `build.jira.yaml`:\n ```yaml\n foreach_fromvar: OSes\n summary: 'Build clients for {{ item }}'\n ...\n ```\n `release.jira.yaml`:\n ```yaml\n foreach_fromvar: OSes\n summary: 'Release application for {{ item }}'\n ...\n ```\n * `foreach_key`: if you don't like default variable name (`item`) for each item in `foreach` list, you may specify it here. Example\n ```yaml\n foreach:\n - Android\n - iOS\n foreach_key: os\n summary: 'Release application for {{ os }}'\n ...\n ```\n would finally evaluate to following issues:\n ```yaml\n summary: 'Release application for Android'\n ...\n ```\n ```yaml\n summary: 'Release application for iOS'\n ...\n ```\n * `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\n `release.jira.yaml` file:\n ```yaml\n foreach:\n - name: Android\n date: !!timestamp 2019-10-24 06:30:00.0\n - name: iOS\n date: !!timestamp 2019-10-24 10:50:00.0\n foreach_namevar: name\n summary: 'Release application for {{ item.name }}'\n ...\n ```\n Now in any other (or the same) issue you can link to this issues as follows:\n ```yaml\n summary: 'Notify community'\n description: |\n Android release task: {{ issuekey_release_Android }}\n iOS release task: {{ issuekey_release_iOS }}\n ```\n * `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.\n Example:\n ```yaml\n foreach:\n - Android\n - iOS\n foreach_key: os\n if: '{{ os in [\"Android\", \"GNU/Linux\"] }}'\n summary: 'Release application for {{ os }}'\n ...\n ```\n would finally evaluate to following issue (only one, obviously):\n ```yaml\n summary: 'Release application for Android'\n ...\n ```\n\n## Examples\nSee [basic release example](https://github.com/m-khvoinitsky/workflow-templater/tree/master/examples/basic_release_example) for basic example.\n",
"bugtrack_url": null,
"license": "",
"summary": "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.",
"version": "0.2.15",
"project_urls": {
"Homepage": "https://github.com/m-khvoinitsky/workflow-templater"
},
"split_keywords": [
"jira",
"email",
"template",
"workflow",
"release"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "86813cea2f1d28a0d150709d3b28b5c583441e68d688eaab4c3b6145d7e3072b",
"md5": "88e64a71fe009fdc3d10d54608c0b590",
"sha256": "4666f8660b3a4303cab92ee85409c84606cc31c71ebcb7fd7c8528a5be755030"
},
"downloads": -1,
"filename": "workflow_templater-0.2.15-py3-none-any.whl",
"has_sig": false,
"md5_digest": "88e64a71fe009fdc3d10d54608c0b590",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 15969,
"upload_time": "2023-06-25T13:05:10",
"upload_time_iso_8601": "2023-06-25T13:05:10.296577Z",
"url": "https://files.pythonhosted.org/packages/86/81/3cea2f1d28a0d150709d3b28b5c583441e68d688eaab4c3b6145d7e3072b/workflow_templater-0.2.15-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "5bf0f5a46a62139f38b9e170bacc1e2d39014376045d57597aeec6008a9fec7d",
"md5": "8f0493452d01b74c7927b8f538740227",
"sha256": "2e0c22471de2282d7a90aa4eb71d653b4725fdc94ada8f7fe6bc70dace3be10f"
},
"downloads": -1,
"filename": "workflow_templater-0.2.15.tar.gz",
"has_sig": false,
"md5_digest": "8f0493452d01b74c7927b8f538740227",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 17118,
"upload_time": "2023-06-25T13:05:11",
"upload_time_iso_8601": "2023-06-25T13:05:11.672051Z",
"url": "https://files.pythonhosted.org/packages/5b/f0/f5a46a62139f38b9e170bacc1e2d39014376045d57597aeec6008a9fec7d/workflow_templater-0.2.15.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-06-25 13:05:11",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "m-khvoinitsky",
"github_project": "workflow-templater",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "workflow-templater"
}