diff --git a/README.md b/README.md index f4142e3..92b1c87 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,8 @@ Once a Github release is complete, bot will upload this release to PyPI. Note that you have to setup your login details (see [Requirements](#requirements)). ## Try it locally + +### Install ``` $ pip install release-bot ``` @@ -43,7 +45,25 @@ Other possible installations are through First interaction with release bot may be automated releases on Github. Let's do it. -#### 1. Create upstream repository or use existing one +### Configure the release bot +Release bot can be configured in two ways, using `release-bot init` or manually + +#### Configuration using `release-bot init` +Clone the upstream repository where new releases will be published +and from the root dir of the repository run the following command: +```shell +release-bot init +``` +Enter the required details when asked by the bot. All of the default choices provided by the init should be enough for the current trial. You will also need to generate a [Github personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/). +Recommended permissions for access token are: `repo`, `delete_repo`, `user`. + +You can later on modify all the config files. For possible advanced setup check [the documentation for an upstream repository](#upstream-repository) and [gitchanelog](#GitChangeLog). + +After the init is completed **commit all of the changes and push it** to the upstream repo. + +#### Manual Configuration + +##### 1. Create upstream repository or use existing one This is meant to be upstream repository where new releases will be published. Within upstream repository create `release-conf.yaml` file which contains info on how to release the specific project. @@ -54,9 +74,11 @@ At the end of `release-conf.yaml` add this line of code: # whether to allow bot to make PRs based on issues trigger_on_issue: true ``` -For possible advanced setup check [the documentation for an upstream repository](#upstream-repository). +Then copy [.gitchangelog.rc](/gitchangelog/.gitchangelog.rc) and [markdown.tpl](/gitchangelog/.gitchangelog.rc) (which are the config files for the [gitchangelog](https://github.com/vaab/gitchangelog.git)) +to the root dir of the upstream repository. +For possible advanced setup check [the documentation for an upstream repository](#upstream-repository) and [gitchanelog](#GitChangeLog). -#### 2. Create `conf.yaml` +##### 2. Create `conf.yaml` Create configuration file `conf.yaml`. You can use [one](conf.yaml) from this repository. You will need to generate a [Github personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/). Recommended permissions for access token are: `repo`, `delete_repo`, `user`. @@ -66,20 +88,21 @@ At the end of `conf.yaml` add this line of code: # Name of the account that the github_token belongs to # Only needed for triggering the bot on an issue. github_username: +gitchangelog: true ``` **Note**: This file **should not** be stored in upstream repository as it contains sensitive data. For possible advanced setup check [the documentation for a private repository](#private-repository). Also, see [requirements](#requirements) in case you want include PyPi releases. -#### 3. Run release-bot -At this point, release-bot is installed. At least two configuration files are set `release-conf.yaml` and `conf.yaml` (optionally `.pypirc`). +### Run the release-bot +At this point, release-bot is installed. At least four configuration files are set `release-conf.yaml`, `conf.yaml`, `.gitchangelog.rc`, `markdown.tpl` (optionally `.pypirc`). Launch bot by a command: ```$ release-bot -c --debug``` You can scroll down and see debug information of running bot. -#### 4. Make a new release +### Make a new release - Create an issue having `0.0.1 release` as a title in your upstream repository. You can select your own version numbers. - Wait for the bot to make a new PR based on this issue (refresh interval is set in `conf.yaml`). - Once the PR is merged bot will make a new release. @@ -94,6 +117,9 @@ There are two yaml configuration files: 1. `conf.yaml` -- a config for the bot itself with some sensitive data (recommended to store in private repo) 2. `release-conf.yaml` -- stored in upstream repository and contains info on how to release the specific project. +There are two more files required if you use `gitchangelog` to genereate change logs: + 1. `.gitchangelog.rc` -- a config file used by the gitchangelog to specify the regex for converting commits and the output engine + 2. `markdown.tpl` -- a template file used by pystache to genereate markdown ## Private repository You need to setup a git repository, where you'll store the `conf.yaml` and `.pypirc` files. @@ -113,6 +139,7 @@ Here are the `conf.yaml` configuration options: | `github_app_id` | ID (a number) of the Github app. | No | | `github_app_cert_path` | Path to a certificate which Github provides as an auth mechanism for Github apps. | No | | `refresh_interval` | Time in seconds between checks on repository. Default is 180 | No | +| `use_gitchangelog` | Whether to use gitchanelog to generate change logs. False by default | No | Sample config named [conf.yaml](conf.yaml) can be found in this repository. @@ -140,6 +167,13 @@ Here are possible options: Sample config named [release-conf-example.yaml](release-conf-example.yaml) can be found in this repository. +## GitChangeLog + +For using the [gitchangelog](https://github.com/vaab/gitchangelog) you must add the line `gitchanelog: true` to the conf.yaml, and add the files `.gitchangelog.rc` and `markdown.tpl` in the root of your upstream project repository. Sample config files: [.gitchangelog.rc](/gitchangelog/.gitchangelog.rc) and [template.tpl](/gitchangelog/template.tpl). + +`.gitchangelog.rc` sample is heavily commented and should be enough to make modification but for specific details you can refer to the original [repository](https://github.com/vaab/gitchangelog). +The default template `markdown.tpl` is configured to create Markdown divided into sections (New, Changes, Fix, Others) based on the commits. The data sent to the output engine [pystache](https://github.com/defunkt/pystache) by the gitchangelog is in the following [format](https://github.com/vaab/gitchangelog/edit/master/README.rst#L331-L356). You can use it to create a custom template, please refer [mustache](http://mustache.github.io/). + ## Requirements Are specified in `requirements.txt`. You have to setup your PyPI login details in `$HOME/.pypirc` as described in diff --git a/release_bot/cli.py b/release_bot/cli.py index cedfdca..e18e32c 100644 --- a/release_bot/cli.py +++ b/release_bot/cli.py @@ -18,6 +18,7 @@ from pathlib import Path from release_bot.configuration import configuration +from release_bot.exceptions import ReleaseException class CLI: @@ -39,10 +40,8 @@ def run_bot(args): if args.configuration: args.configuration = Path(args.configuration).resolve() if not args.configuration.is_file(): - configuration.logger.error( + raise ReleaseException( f"Supplied configuration file is not found: {args.configuration}") - exit(1) - if args.debug: configuration.logger.setLevel(logging.DEBUG) for key, value in vars(args).items(): @@ -58,7 +57,8 @@ def run_bot(args): parser.set_defaults(func=run_bot) subparsers = parser.add_subparsers() - parser_init = subparsers.add_parser('init') + parser_init = subparsers.add_parser('init', + help='Initializes the repository for the release-bot') parser_init.set_defaults(func=run_init) args = parser.parse_args() diff --git a/release_bot/configuration.py b/release_bot/configuration.py index 4ba04df..5e13e60 100644 --- a/release_bot/configuration.py +++ b/release_bot/configuration.py @@ -37,12 +37,13 @@ def __init__(self): self.debug = False self.configuration = '' self.logger = None + self.init = False + self.gitchangelog = False self.set_logging() # configuration when bot is deployed as github app self.github_app_installation_id = '' self.github_app_id = '' self.github_app_cert_path = '' - self.init = False def set_logging(self, logger_name="release-bot", diff --git a/release_bot/git.py b/release_bot/git.py index f3082f5..93e25d3 100644 --- a/release_bot/git.py +++ b/release_bot/git.py @@ -54,7 +54,10 @@ def get_log_since_last_release(self, latest_version): :param latest_version: previous version :return: changelog or placeholder """ - cmd = f'gitchangelog ^{latest_version} HEAD' + if self.conf.gitchangelog: + cmd = f'gitchangelog ^{latest_version} HEAD' + else: + cmd = f'git log {latest_version}... --no-merges --format=\'* %s\'' success, changelog = run_command_get_output(self.repo_path, cmd) return changelog if success and changelog else 'No changelog provided' diff --git a/release_bot/init_repo.py b/release_bot/init_repo.py index ccdfb70..373abff 100644 --- a/release_bot/init_repo.py +++ b/release_bot/init_repo.py @@ -51,50 +51,61 @@ class Init: Creates all of the required configuration script required for the ReleaseBot """ def __init__(self): + self.conf = {} + self.release_conf = {} + + def run(self): + """ + Performs all the init tasks + """ self.create_conf() self.append_to_gitignore() - self.create_template() - self.create_gitchangelog_rc() - conclude = ("""Successfully initialized the repository + if self.conf['gitchangelog']: + self.create_template() + self.create_gitchangelog_rc() + conclude = """Successfully initialized the repository Please commit all of the changes made to the repo and -from shell run 'release-bot -c conf.yaml'""") - print(conclude) +from shell run 'release-bot -c conf.yaml'""" + print(conclude) + def create_conf(self): """ Create the release-conf.yaml and conf.yaml """ - conf = {} - conf['repository_name'] = input('Please enter the repository name:') - conf['repository_owner'] = input('Please enter the repository owner:') - print("""for details on how to get github token checkou + self.conf['repository_name'] = input('Please enter the repository name:') + self.conf['repository_owner'] = input('Please enter the repository owner:') + print("""for details on how to get github token checkout 'https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/'""") - conf['github_token'] = input('Please enter your valid github token:') + self.conf['github_token'] = input('Please enter your valid github token:') refresh_interval = input("""In how many seconds would you like the bot to check for updates (Default 180):""") if refresh_interval: - conf['refresh_interval'] = int(refresh_interval) + self.conf['refresh_interval'] = int(refresh_interval) else: - conf['refresh_interval'] = 180 + self.conf['refresh_interval'] = 180 is_owner_user = input('Are you the owner of the repo? (Y/n):') if is_owner_user.lower() == 'y' or is_owner_user == '': - conf['github_username'] = conf['repository_owner'] + self.conf['github_username'] = self.conf['repository_owner'] else: - conf['github_username'] = input('Please enter your github usename:') + self.conf['github_username'] = input('Please enter your github usename:') + gitchangelog = input( + 'would you like to use gitchangelog to generate next-gen changelogs? (Y/n):' + ) + self.conf['gitchangelog'] = bool( + gitchangelog.lower() == 'y' or gitchangelog == '' + ) - release_conf = {} cwd = os.getcwd() - release_conf['author_email'] = run_command_get_output(cwd, f'git config user.email')[1] - release_conf['author_email'] = release_conf['author_email'] - release_conf['author_name'] = run_command_get_output(cwd, f'git config user.name')[1] - release_conf['author_name'] = release_conf['author_name'] - release_conf['labels'] = [] + self.release_conf['author_email'] = run_command_get_output(cwd, f'git config user.email')[1] + self.release_conf['author_name'] = run_command_get_output(cwd, f'git config user.name')[1] + self.release_conf['labels'] = [] trigger_on_issue = input('Would you like to trigger release from issue? (Y/n):') - release_conf['trigger_on_issue'] = bool( + self.release_conf['trigger_on_issue'] = bool( trigger_on_issue.lower() == 'y' or trigger_on_issue == '' ) - self.create_yaml(conf, 'conf.yaml') - self.create_yaml(release_conf, 'release-conf.yaml') + self.create_yaml(self.conf, 'conf.yaml') + self.create_yaml(self.release_conf, 'release-conf.yaml') @staticmethod def append_to_gitignore(): diff --git a/release_bot/releasebot.py b/release_bot/releasebot.py index 7fc6160..7a00999 100644 --- a/release_bot/releasebot.py +++ b/release_bot/releasebot.py @@ -278,7 +278,8 @@ def run(self): def main(): CLI.parse_arguments() if configuration.init: - Init() + init_repo = Init() + init_repo.run() else: configuration.load_configuration()