diff --git a/app-deploy.sh b/app-deploy.sh index 5b84c7c..3a7f009 100755 --- a/app-deploy.sh +++ b/app-deploy.sh @@ -4,6 +4,7 @@ source /usr/local/bin/.app-deploy-sources/__constants.sh source /usr/local/bin/.app-deploy-sources/__help.sh if [ -z "$1" ] || [ "$1" == 'trigger' ] ; then source ./.deploy-options.sh + source ./.changelog-generator.sh source /usr/local/bin/.app-deploy-sources/__trigger_deploy.sh fi source /usr/local/bin/.app-deploy-sources/__auto_update.sh diff --git a/examples/changelog_generator/jira/.changelog-generator.py b/examples/changelog_generator/jira/.changelog-generator.py new file mode 100644 index 0000000..625cfa8 --- /dev/null +++ b/examples/changelog_generator/jira/.changelog-generator.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3.8 + +import sys +from jira import JIRA + +# Generate changelog +def generate_changelog(issues, server, jira_email, jira_token): + + if jira_email is None or jira_token is None or server is None: + #Pass -99 from python as print inside python is not visible. Calling sys.exit will just stop execution. + return "-99" + + options = { + 'server': server + } + + try: + jira = JIRA(options, basic_auth=(jira_email, jira_token)) + except: + return "-1001" + + build_changelog = "" + for issueId in issues.split(): + issueId = issueId.upper() + issue = jira.issue(issueId) + taskName = issue.fields.summary + taskUrl = server + "/browse/" + issueId + fullName = "\n* [" + issueId + " " + taskName + "](" + taskUrl + ")" + build_changelog += fullName + + return build_changelog + +# Main +if __name__ == "__main__": + + if len(sys.argv) != 5: + sys.exit(1) + + input_string = sys.argv[1] + server = sys.argv[2] + jira_email = sys.argv[3] + jira_token = sys.argv[4] + result = generate_changelog(input_string, server, jira_email, jira_token) + print(result) diff --git a/examples/changelog_generator/jira/.changelog-generator.sh b/examples/changelog_generator/jira/.changelog-generator.sh new file mode 100644 index 0000000..1f5c4c5 --- /dev/null +++ b/examples/changelog_generator/jira/.changelog-generator.sh @@ -0,0 +1,159 @@ +## This is and example of changelog generator for projects that use JIRA. +## Script calls a python script that uses JIRA package to fetch issues from JIRA API +## Generated changelog is in format +## +## * [ ]() +## * [ ]() +## ... +## +## depending on how many issue numbers are provided. +## Script can also be configured to parse the task number for the branch name. + + +## In order to use this script you'll need to follow these steps +## +## 1. Install JIRA package ("pip install jira" will do the trick) +## 2. Create a JIRA token (https://id.atlassian.com/manage-profile/security/api-tokens) +## 3. Open .zshrc (or .bash_profile) +## 4. Add these two lines: +## export JIRA_EMAIL="" +## export JIRA_TOKEN="" +## 5. Save and close .zshrc (or .bash_profile) and restart terminal (or run source ~/.zshrc or source ~/.bash_profile) +## +## Now you should be all set to use this script in your app-deploy. + + +# Regex used to find task numbers in branch name. +# Replace with prefix used in task numbers on your project. +# Set to "" if you don't want to use this feature. +BRANCH_NAME_TASK_MATCHING_REGEX="(-[0-9]+)" + +# Path to python script that will fetch issues from JIRA. +PYTHON_SCRIPT_PATH=".changelog-generator.py" + +# JIRA project URL. Used by python script to construct a url to specific issue. +# Replace with your JIRA project name. +JIRA_PROJECT_URL="https://.atlassian.net" + +function generate_changelog { + + if [[ -z "$JIRA_EMAIL" || -z "$JIRA_TOKEN" ]]; then + echo "Missing JIRA_EMAIL or JIRA_TOKEN. Please add it to your .zshrc or .bash_profile configuration file." + echo + + return + fi + + local task_numbers="" + + if [[ ! -z $BRANCH_NAME_TASK_MATCHING_REGEX ]]; then + # Task number contained in branch name + current_branch=`git rev-parse --abbrev-ref HEAD` + if [[ $current_branch =~ $BRANCH_NAME_TASK_MATCHING_REGEX ]]; then + task_numbers=$(printf "%s " "${BASH_REMATCH[@]}") + fi + fi + + # Manually enter task number + if [[ -z $task_numbers ]]; then + echo + echo "Enter task number contained in this build, separated by space (e.g., -1234 -5678)." + echo "For manual changelog entry, leave input empty and press enter." + echo + read -r -p "Tasks contained in this build (e.g. -1234 -5678): " task_numbers + fi + + # Select or edit changelog, edit tasks list and generate again + while true; do + + if [[ -z "$task_numbers" ]]; then + break + fi + + __call_python_script "$task_numbers" + + if [[ -z "$CHANGELOG" ]]; then + # reason for failure already printed so just break + break + fi + + local user_input="" + __print_generated_changelog + read -r -p "Press enter to use generated changelog or select one of options (e - edit changelog, a - change task numbers): " user_input + + # Enter + if [ -z "$user_input" ]; then + break # Enter pressed -> Exit loop + + # Edit tasks list + elif [ "$user_input" == "a" ]; then + echo + echo "Enter a new list of tasks." + echo "If an already entered task is needed, please copy it from the list, as the new list will override the existing one." + echo + echo "Entered tasks so far: $task_numbers" + echo + read -r -p "Tasks contained in this build: " task_numbers + continue + + # Edit changelog + elif [ "$user_input" == "e" ]; then + temp_file=$(mktemp) + echo "$CHANGELOG" > "$temp_file" + if [[ $EDITOR ]]; then + $EDITOR "$temp_file" + else + nano "$temp_file" + fi + CHANGELOG=$(cat "$temp_file") + rm "$temp_file" + + # Wrong input + else + echo "Oh no! Wrong input... try again!" + fi + done +} + +function __call_python_script { + + local task_numbers=$1 + local generated_changelog=$(python3 $PYTHON_SCRIPT_PATH "$task_numbers" "$JIRA_PROJECT_URL" "$JIRA_EMAIL" "$JIRA_TOKEN") + + if [[ $generated_changelog == "-99" ]]; then + echo "JIRA configuration isn't valid. Current configurations:" + echo "JIRA_PROJECT_URL: $JIRA_PROJECT_URL" + echo "JIRA_EMAIL: $JIRA_EMAIL" + echo "JIRA_TOKEN: $JIRA_TOKEN" + echo + echo "Please check your configuration and try again." + echo + + return + fi + + if [[ $generated_changelog == "-1001" ]]; then + echo "Failed to connect to JIRA. Please check your configuration and permissions and try again." + echo + + return + fi + + if [[ -z $generated_changelog ]]; then + echo "Generated changelog is empty." + echo + + return + fi + + CHANGELOG=$generated_changelog +} + +function __print_generated_changelog() { + echo + echo "Generated changelog:" + echo "---------------------------------------------------------------" + echo "$CHANGELOG" + echo "---------------------------------------------------------------" + echo +} diff --git a/sources/__init.sh b/sources/__init.sh index 4057dce..b8354f3 100644 --- a/sources/__init.sh +++ b/sources/__init.sh @@ -1,5 +1,20 @@ source /usr/local/bin/.app-deploy-sources/__constants.sh +function __init_deploy_options { + cat /usr/local/bin/.app-deploy-sources/deploy-options.sh > ./.deploy-options.sh + echo "The options file was generated successfully!" + echo "NOTE: Change default values to the project specific." + echo +} + +function __init_changelog_generator { + cat /usr/local/bin/.app-deploy-sources/changelog-generator.sh > ./.changelog-generator.sh + echo "Changelog generator file was generated successfully!" + echo "NOTE: Change default implementation to the project specific." + echo " Examples can be found https://github.com/infinum/app-deploy-script/tree/master/examples/changelog_generator." + echo +} + ################################# # INIT NEW PROJECT # ################################# @@ -13,13 +28,25 @@ function __init { echo "If you continue, stored options will be overridden!" echo read -r -p "Do you want to proceed? [y/n] " c - if ! [[ ${c} =~ ^(yes|y|Y) ]] || [ -z ${c} ]; then - exit 1 + if [[ ${c} =~ ^(yes|y|Y) ]] || [ -z ${c} ]; then + __init_deploy_options fi + else + __init_deploy_options fi - cat /usr/local/bin/.app-deploy-sources/deploy-options.sh > ./.deploy-options.sh - echo "The options file was generated successfully!" - echo "NOTE: Change default values to the project specific." - echo -} \ No newline at end of file + if [ -e "./.changelog-generator.sh" ]; then + echo "Changelog generator file already exists." + echo "If you continue, current implementation will be overridden!" + echo + read -r -p "Do you want to proceed? [y/n] " c + if [[ ${c} =~ ^(yes|y|Y) ]] || [ -z ${c} ]; then + __init_changelog_generator + fi + else + read -r -p "Add changelog generator file? [y/n] " c + if [[ ${c} =~ ^(yes|y|Y) ]] || [ -z ${c} ]; then + __init_changelog_generator + fi + fi +} diff --git a/sources/changelog-generator.sh b/sources/changelog-generator.sh new file mode 100644 index 0000000..11f9f72 --- /dev/null +++ b/sources/changelog-generator.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +######################################################### +# CHANGELOG GENERATOR # +# # +# Part of script that should be edited by the user. # +# # +# This will generate the changelog. # +######################################################### + +## Used to autmatically generate changelog. +## If CHANGELOG is empty user will be asked to enter it manually. +## +## !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +## !!! Result needs to be saved in CHANGELOG variable !!! +## !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +## +## Look at examples folder to get inspired. + +function generate_changelog { + # add logic to generate changelog + CHANGELOG="" +} diff --git a/sources/helpers/__base_tag_handling.sh b/sources/helpers/__base_tag_handling.sh index 6c01006..f174faa 100644 --- a/sources/helpers/__base_tag_handling.sh +++ b/sources/helpers/__base_tag_handling.sh @@ -43,7 +43,7 @@ function __create_app_version_and_build_number { fi if ! [[ "$appversion" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] - then + then echo "App version is in wrong format (use M.m.p format, e.g. 1.0.0). Aborting..." exit 5 fi @@ -86,27 +86,58 @@ function __create_trigger_ci_timestamp_tag { trigger_tag+="$target/" done - # Sufix timestamp + # Sufix timestamp trigger_tag+="$TRIGGER_TAG_SUFIX" # Assign to shared property tags_to_deploy=("$trigger_tag") } +function __changelog_generator_exists { + if ! declare -f generate_changelog > /dev/null; then + return 1 + fi + + return 0 +} + # Changelog function __generate_tag_and_changelog { - echo echo "###############################################################" echo "# CHANGELOG #" echo "###############################################################" echo + + # Generate changelog + + if __changelog_generator_exists; then + echo "------------------------------------------------------------" + echo "Generating changelog message..." + echo "------------------------------------------------------------" + + CHANGELOG="" + generate_changelog # Result will be saved in CHANGELOG + + if [[ ! -z "$CHANGELOG" ]]; then + for tag in "${tags_to_deploy[@]}"; do + git tag -a "$tag" -m "${CHANGELOG}" + done + return # No need to ask for changelog if one is generated + else + echo "Failed to generate changelog" + echo + fi + fi + + # Enter changelog manually + echo "------------------------------------------------------------" echo "Enter changelog message..." echo "------------------------------------------------------------" sleep 1 - tag_message_added=0 + local tag_message_added=0 for tag in "${tags_to_deploy[@]}"; do if [ ${tag_message_added} -eq 1 ]; then @@ -118,4 +149,4 @@ function __generate_tag_and_changelog { tag_message_added=1 fi done -} \ No newline at end of file +}