{ "info": { "author": "Marcel Steffen", "author_email": "marcel@talentsconnect.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Console", "Intended Audience :: Developers", "Topic :: Software Development :: Version Control :: Git", "Topic :: Utilities" ], "description": "[![PyPI](https://img.shields.io/pypi/v/Braumeister.svg)](https://pypi.python.org/pypi/Braumeister/)\n[![Build Status](https://travis-ci.org/talentsconnect/braumeister.svg?branch=master)](https://travis-ci.org/talentsconnect/braumeister)\n\n```none\n ,---. ,---. .--. .-. .-. ,---. ,-. .---. _______ ,---. ,---. \n | .-.\\ | .-.\\ / /\\ \\ | | | ||\\ /| | .-' |(| ( .-._)|__ __|| .-' | .-.\\ \n | |-' \\ | `-'/ / /__\\ \\| | | ||(\\ / | | `-. (_) (_) \\ )| | | `-. | `-'/ \n | |--. \\| ( | __ || | | |(_)\\/ | | .-' | | _ \\ \\ (_) | | .-' | ( \n | |`-' /| |\\ \\ | | |)|| `-')|| \\ / | | `--.| |( `-' ) | | | `--.| |\\ \\ \n /( `--' |_| \\)\\|_| (_)`---(_)| |\\/| | /( __.'`-' `----' `-' /( __.'|_| \\)\\ \n(__) (__) '-' '-'(__) (__) (__) \n```\n\n`braumeister` is a release-candidate preparation tool for git and JIRA users. \nGiven a fix-version, it gathers git branches mentioned in JIRA issues targetting this fix-version and merges them in a release-candidate branch.\n\n# Installation\n**The `braumeister` requires at least Python `3.5`**\n\nInstall with:\n```sh\npip3 install braumeister\n```\n\n# Configuration\nYou can initialize the `braumeister` inside the root directory of a git repository like this:\n```sh\nbraumeister init\n```\n\nThe `braumeister` will create a `.braumeister` configuration file in the current directory. The configuration may look like this:\n\n```ini\n[general]\nverbose = false\n\n[jira]\nurl = https://jira.dev\nusername = my-user\npassword = secret\ndestination_transition = Merged\nbranch_custom_field_id = customfield_5711\n```\n\n|Section|key|default value|description|\n|-------|---|-----|---|\n|general|verbose|false|Verbose output|\n|jira|url|None|JIRA Base URL|\n|jira|username|None|A JIRA User|\n|jira|password|None|The password for the user|\n|jira|destination_transition|None|Workflow Transition name for the ticket after merging, if executed with `-u`|\n|jira|branch_custom_field_id|None|The JIRA Custom Field where we should read the branch from|\n\nWe'll be looking for a configuration file at the following places\n```\n[CURRENT-DIRECTORY]/.braumeister\n~/.braumeister\n```\n\n**It's recommended to add the following files to your `.gitignore`**\n```gitignore\n.braumeister\nrelease_state.json\n```\n\n## JIRA Configuration\n### Custom Field f\u00fcr Branch anlegen\nIn JIRA, press `gg` (or `.`) to open the \"Quick Actions\" > Type `Custom Fields` > `Add custom field` > `Text field (single line)` > `Next`\n```\nName: Branch\nDescription: git Branch\n```\nIn the next screen, you need to assign the created field to one or more screens.\nThe `branch_custom_field_id` is `customfield_[ID]` whereas the `ID` is the number in the URL behind the `customFieldId=`.\ne.g.:\n```none\nhttps://jira.dev/secure/admin/ConfigureCustomField!default.jspa?customFieldId=57111\n```\nHere, the JIRA Custom Field Id is `5711`, so the `braumeister` configuration for `branch_custom_field_id` would be `customfield_5711`.\n\n# Description\nThe `braumeister` requests all issues from JIRA with the given release name as `Fix Version`.\nIn theses tickets, we'll search for the configured custom field (eg Branch) containing the git branch.\nThe release branch will be created like this:\n```\nrelease/[cleaned_release_name]_RC_[LATEST_RC + 1]\n```\nIf the `braumeister` discovered a branch with the same name, we'll increase the `RC` part with 1 (with leading zeros). The first release branch will have the RC `001`.\n\nFor each of theses branches, the following commands will be executed:\n```sh\n$ git checkout $branch\n$ git pull\n$ git merge origin/master\n$ git push origin $branch\n$ git checkout $release_branch\n$ git merge origin/$branch\n$ git branch -D $branch\n```\n\nAfter merging all branches to the release branch, the branch will be pushed to `origin`.\n\n## Conflicts\nIf there are any conflicts during the merge of a branch, the `braumeister` will stop and write the current state to a `release_state.json` file. The output may looks like this:\n```sh\n$ braumeister -n \"Barking Dog\" candidate\n[*] Requesting all issues with fixVersion: Barking Dog\n[+] Requesting issue: https://jira.dev/rest/api/2/issue/5711\n[+] Requesting issue: https://jira.dev/rest/api/2/issue/5712\n[+] Requesting issue: https://jira.dev/rest/api/2/issue/5713\n[+] The last branch for RC Barking Dog is: release/Barking_Dog_RC_002\n[+] Creating new branch 'release/Barking_Dog_RC_003' from master\n\nBranch 'release/Barking_Dog_RC_003' set up to track remote branch 'master' from 'origin'.\nSwitched to a new branch 'release/Barking_Dog_RC_003'\n\n[\ud83c\udf7b ] Merging feature-2...\n[\ud83c\udf7b ] Branch 'feature-2' merged\n\n[\ud83c\udf7b ] Merging feature-1...\n\nWriting state json!\n\nA merge error occured while merging feature into release/Barking_Dog_RC_003\n\nPlease do the following steps:\n\t* Resolve the conflicts\n\t* Commit the changes\n\t* Call the script again with the option -r\n```\n\nThe `braumeister` will stay in the current release branch to let you resolve the conflict. After the conflict has been resolved, you can rerun the `braumeister` with `-r` to resume where we stopped.\n\n```sh\n$ braumeister -n \"Barking Dog\" -r candidate\nReading state json!\nResuming with feature-1\n[\ud83c\udf7b ] Merging feature-1...\n[\ud83c\udf7b ] Branch 'feature-1' merged\n\n[\ud83c\udf7b ] Merging affe...\n[\ud83c\udf7b ] Branch 'affe' merged\n\nDeleting state json!\n\n[\ud83c\udf7b ] All done. Grab a \ud83c\udf7a\n```\n\n## Examples\n\n### Release Candidate\n\n#### New release candidate\n```sh\n$ braumeister -n \"Barking Dog\" candidate\n[*] Requesting all issues with fixVersion: Barking Dog\n[+] Requesting issue: https://jira.dev/rest/api/2/issue/5711\n[+] Creating new branch 'release/Barking_Dog_RC_001' from master\n\nBranch 'release/Barking_Dog_RC_001' set up to track remote branch 'master' from 'origin'.\nSwitched to a new branch 'release/Barking_Dog_RC_001'\n\n[\ud83c\udf7b ] Merging affe...\n[\ud83c\udf7b ] Branch 'affe' merged\n\n\n[\ud83c\udf7b ] All done. Grab a \ud83c\udf7a\n```\n\n#### Existing release candidate\nWhen you execute the `braumeister` with the same release name again, a new release candidate will be created (increasing the `RC` part with 1).\n\n```sh\n$ braumeister -n \"Barking Dog\" candidate\n[*] Requesting all issues with fixVersion: Barking Dog\n[+] Requesting issue: https://jira.dev/rest/api/2/issue/5711\n[+] The last branch for RC Barking Dog is: release/Barking_Dog_RC_001\n[+] Creating new branch 'release/Barking_Dog_RC_002' from master\n\nBranch 'release/Barking_Dog_RC_002' set up to track remote branch 'master' from 'origin'.\nSwitched to a new branch 'release/Barking_Dog_RC_002'\n\n[\ud83c\udf7b ] Merging affe...\n[\ud83c\udf7b ] Branch 'affe' merged\n\n\n[\ud83c\udf7b ] All done. Grab a \ud83c\udf7a\n```\n\n#### Update JIRA issue\nExecuting the `braumeister` with `-u` will also execute the configured transition on all related issues.\n\n```sh\n$ braumeister -n \"Barking Dog\" -u candidate\n[*] Requesting all issues with fixVersion: Barking Dog\n[+] Requesting issue: https://jira.dev/rest/api/2/issue/31300\n[+] Requesting issue: https://jira.dev/rest/api/2/issue/30209\n[+] The last branch for RC Barking Dog is: release/Barking_Dog_RC_004\n[+] Creating new branch 'release/Barking_Dog_RC_005' from master\n\nBranch 'release/Barking_Dog_RC_005' set up to track remote branch 'master' from 'origin'.\nSwitched to a new branch 'release/Barking_Dog_RC_005'\n\n[\ud83c\udf7b ] Merging feature-1...\n[\ud83c\udf7b ] Branch 'feature-1' merged\n\n[\ud83c\udf7b ] Merging affe...\n[\ud83c\udf7b ] Branch 'affe' merged\n\nDeleting state json!\n------------------------------------\n[+] Update status to Merged on all related jira issues!\n------------------------------------\nRequesting all transitions for: DEV-1\nUpdating jira status on DEV-1 to Staging Needed\n------------------------------------\nRequesting all transitions for: DEV-2\nUpdating jira status on DEV-2 to Staging Needed\n\n[\ud83c\udf7b ] All done. Grab a \ud83c\udf7a\n```\n\n### Release\n\n#### New release\n```sh\n$ braumeister -n \"Barking Dog\" release\n[*] Requesting all issues with fixVersion: Barking Dog\n[+] Requesting issue: https://jira.dev/rest/api/2/issue/5711\n[+] Creating new branch 'release/Barking_Dog_GA' from master\n\nBranch 'release/Barking_Dog_GA' set up to track remote branch 'master' from 'origin'.\nSwitched to a new branch 'release/Barking_Dog_GA'\n\n[\ud83c\udf7b ] Merging affe...\n[\ud83c\udf7b ] Branch 'affe' merged\n\n[\ud83c\udf7b ] All done. Grab a \ud83c\udf7a\n```\n\n#### Finalize a release\nWhen you execute the `braumeister` with the `finalize` action it will merge the given branch back to `origin/master`. \n\nTHIS CHANGES YOUR REMOTE REPOSITORY, HANDLE WITH CARE!\n\n```sh\n$ braumeister -n \"Barking Dog\" finalize\n[+] Merging branch 'release/Barking_Dog_GA' to origin/master\n\n[\ud83c\udf7b ] Merging release/Barking_Dog_GA...\n[\ud83c\udf7b ] Branch 'release/Barking_Dog_GA' merged\n\n[\ud83c\udf7b ] All done. Grab a \ud83c\udf7a\n```\n\n#### Cleanup after a release\nWhen you execute the `braumeister` with the `cleanup` action it will delete all branches associated with tickets in your `fixVersion`.\n\nTHIS CHANGES YOUR REMOTE REPOSITORY, HANDLE WITH CARE!\n\n```sh\n$ braumeister -n \"Barking Dog\" cleanup\n[+] Cleaning up after release of Barking Dog\n\n[\ud83c\udf7b ] Deleting origin/feature-nifty...\n[\ud83c\udf7b ] Deleting origin/feature-seven...\n[\ud83c\udf7b ] Deleting origin/feature-eleven...\n\n[\ud83c\udf7b ] Brewhouse all clean again. Grab a \ud83c\udf7a\n```\n\n# Development\nRunning tests\n```sh\nmake test\n```\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://www.talentsconnect.com", "keywords": "git jira release", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "Braumeister", "package_url": "https://pypi.org/project/Braumeister/", "platform": "", "project_url": "https://pypi.org/project/Braumeister/", "project_urls": { "Homepage": "https://www.talentsconnect.com" }, "release_url": "https://pypi.org/project/Braumeister/0.3.4/", "requires_dist": [ "requests", "colorama" ], "requires_python": "!=2.7, !=3.4, >=3.5", "summary": "Easy release bulding, combining JIRA and git", "version": "0.3.4" }, "last_serial": 4431170, "releases": { "0.0.5": [ { "comment_text": "", "digests": { "md5": "48c48275271594a5d9a99fe3410ec1f0", "sha256": "70c7a7222861c52d5b643e3f9396d6b1de50fed553249800a188238cf36abd9d" }, "downloads": -1, "filename": "Braumeister-0.0.5.tar.gz", "has_sig": false, "md5_digest": "48c48275271594a5d9a99fe3410ec1f0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8163, "upload_time": "2018-02-09T15:10:14", "url": "https://files.pythonhosted.org/packages/38/a8/e091218cc4a00cc15128e37b1ec30fac251c86852f8cd9558cf39e52652a/Braumeister-0.0.5.tar.gz" } ], "0.1.0": [ { "comment_text": "", "digests": { "md5": "3a74ed1022a295bac196e8c02a8dee74", "sha256": "5f47eae68313f46ac5aa66f1e9c4335728a5de72462c7d78b4b89bdba47572ed" }, "downloads": -1, "filename": "Braumeister-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "3a74ed1022a295bac196e8c02a8dee74", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 15975, "upload_time": "2018-02-13T07:34:19", "url": "https://files.pythonhosted.org/packages/0b/a4/e7eaaf75e38deeb8598e733036bf9d41051073fde90079ab9148745f1629/Braumeister-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "70a9e405242a58130f1f5a9b11f93b35", "sha256": "06de7ede2203d34857290a203c73634549d51c6a07d6249abe3049945dc2d0fd" }, "downloads": -1, "filename": "Braumeister-0.1.0.tar.gz", "has_sig": false, "md5_digest": "70a9e405242a58130f1f5a9b11f93b35", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12247, "upload_time": "2018-02-13T07:34:02", "url": "https://files.pythonhosted.org/packages/a8/b0/e0227cf9b8991c5011f541efaaa67c7e784846277298431033d3c3c1bd6e/Braumeister-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "893c64a1aff2194730cb7cd7fc9ba813", "sha256": "3a8e7526c04ee111d0b6b6cb0d9734389061cc51af351ca28a2a5c4bc70c1831" }, "downloads": -1, "filename": "braumeister-0.2.0.tar.gz", "has_sig": false, "md5_digest": "893c64a1aff2194730cb7cd7fc9ba813", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13717, "upload_time": "2018-03-16T07:22:07", "url": "https://files.pythonhosted.org/packages/25/ad/d334781284322efa8610b523746eb3a1220c00f9f6a27db1362ba949f1cd/braumeister-0.2.0.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "73a448fe42c9f0bb510b07b8bfead56b", "sha256": "fcde564f1215331e34bc1a55660f5d76447224648da40a0abf77f4e4c682c48b" }, "downloads": -1, "filename": "braumeister-0.2.2-py2-none-any.whl", "has_sig": false, "md5_digest": "73a448fe42c9f0bb510b07b8bfead56b", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 21187, "upload_time": "2018-03-26T11:06:04", "url": "https://files.pythonhosted.org/packages/54/42/79f5af3d4264ffda9f47402953fd22f37c5ee42019e0d0d8ef84e7d5c14a/braumeister-0.2.2-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ee4f86c254d7f17c12b5d5685d94f620", "sha256": "8a4509ff2eef646cf42704e4db73499df857436e546d116b24543c50d387a90b" }, "downloads": -1, "filename": "braumeister-0.2.2-py3-none-any.whl", "has_sig": false, "md5_digest": "ee4f86c254d7f17c12b5d5685d94f620", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 16242, "upload_time": "2018-03-26T11:11:45", "url": "https://files.pythonhosted.org/packages/37/2b/865bd569d3bc838c7fcbebe7afbbe8ad2a9a0626b5d53d96236101b5838e/braumeister-0.2.2-py3-none-any.whl" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "b87a8a3a586fb81cdd9960b95e3d1ee3", "sha256": "ebdeec3df324bf6eea96a209fa84c5262b22b53b97f55f36e3ba6eac19d56c61" }, "downloads": -1, "filename": "braumeister-0.2.3-py3-none-any.whl", "has_sig": false, "md5_digest": "b87a8a3a586fb81cdd9960b95e3d1ee3", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 20161, "upload_time": "2018-03-26T11:17:34", "url": "https://files.pythonhosted.org/packages/8b/50/a8e533ba4919e1cb462b0a5bde94dbffd583995dd43c6724b2b8d35c2e7d/braumeister-0.2.3-py3-none-any.whl" } ], "0.3.3": [ { "comment_text": "", "digests": { "md5": "83987aacce35dd7c774d785e30fc05ef", "sha256": "cf741e96897b4cb9780e84cbb82ddd4ad8b90ec37965023a9b0810bf54b958ea" }, "downloads": -1, "filename": "braumeister-0.3.3-py3-none-any.whl", "has_sig": false, "md5_digest": "83987aacce35dd7c774d785e30fc05ef", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": "!=2.7, !=3.4, >=3.5", "size": 18947, "upload_time": "2018-10-30T10:31:43", "url": "https://files.pythonhosted.org/packages/c0/90/55a497f80482ab9bcf7b2521ad60361feeca69c8c1c8f02fa0b283cd4894/braumeister-0.3.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "aaebd81ccd9752800b2c2481f72564b0", "sha256": "bca129aa3e61c846978444b3cb10d14c3368ed5eb5b24dcf7b1dde86bcf02784" }, "downloads": -1, "filename": "braumeister-0.3.3.tar.gz", "has_sig": false, "md5_digest": "aaebd81ccd9752800b2c2481f72564b0", "packagetype": "sdist", "python_version": "source", "requires_python": "!=2.7, !=3.4, >=3.5", "size": 14538, "upload_time": "2018-10-30T10:31:44", "url": "https://files.pythonhosted.org/packages/74/82/e433da5c40f061652a87458c4a9789e9a0654867e2a6e46c10b0da725930/braumeister-0.3.3.tar.gz" } ], "0.3.4": [ { "comment_text": "", "digests": { "md5": "662f8e87ca54bc8ccdcb579e272a9fb3", "sha256": "4d579199307bef2d5d508cc038ed2b7e2b3e8586330f75a281fa1bf56e118a9e" }, "downloads": -1, "filename": "braumeister-0.3.4-py3-none-any.whl", "has_sig": false, "md5_digest": "662f8e87ca54bc8ccdcb579e272a9fb3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": "!=2.7, !=3.4, >=3.5", "size": 19005, "upload_time": "2018-10-30T11:18:13", "url": "https://files.pythonhosted.org/packages/29/ca/41c34a7e49d42991989536bc6b934180b26bfd183fe63fe74e547e8749fd/braumeister-0.3.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "612a02468c747e41f38bb4b81caac367", "sha256": "ca5d967c462ad1b0ae819713355a44381d83b3352dfab723716169b21d9b215f" }, "downloads": -1, "filename": "braumeister-0.3.4.tar.gz", "has_sig": false, "md5_digest": "612a02468c747e41f38bb4b81caac367", "packagetype": "sdist", "python_version": "source", "requires_python": "!=2.7, !=3.4, >=3.5", "size": 14597, "upload_time": "2018-10-30T11:18:15", "url": "https://files.pythonhosted.org/packages/10/14/c529faed3b361583551e8f353e5664e9752d6ebab725efc8046a3b912f19/braumeister-0.3.4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "662f8e87ca54bc8ccdcb579e272a9fb3", "sha256": "4d579199307bef2d5d508cc038ed2b7e2b3e8586330f75a281fa1bf56e118a9e" }, "downloads": -1, "filename": "braumeister-0.3.4-py3-none-any.whl", "has_sig": false, "md5_digest": "662f8e87ca54bc8ccdcb579e272a9fb3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": "!=2.7, !=3.4, >=3.5", "size": 19005, "upload_time": "2018-10-30T11:18:13", "url": "https://files.pythonhosted.org/packages/29/ca/41c34a7e49d42991989536bc6b934180b26bfd183fe63fe74e547e8749fd/braumeister-0.3.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "612a02468c747e41f38bb4b81caac367", "sha256": "ca5d967c462ad1b0ae819713355a44381d83b3352dfab723716169b21d9b215f" }, "downloads": -1, "filename": "braumeister-0.3.4.tar.gz", "has_sig": false, "md5_digest": "612a02468c747e41f38bb4b81caac367", "packagetype": "sdist", "python_version": "source", "requires_python": "!=2.7, !=3.4, >=3.5", "size": 14597, "upload_time": "2018-10-30T11:18:15", "url": "https://files.pythonhosted.org/packages/10/14/c529faed3b361583551e8f353e5664e9752d6ebab725efc8046a3b912f19/braumeister-0.3.4.tar.gz" } ] }