Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app-deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
44 changes: 44 additions & 0 deletions examples/changelog_generator/jira/.changelog-generator.py
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know using Python would ease the implementation; however, I would consider using pure bash as much as possible, as with this one, we have now introduced a new dependency and requirement that the user needs to have Python 3.8.

Original file line number Diff line number Diff line change
@@ -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)
159 changes: 159 additions & 0 deletions examples/changelog_generator/jira/.changelog-generator.sh
Original file line number Diff line number Diff line change
@@ -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
##
## * [<issue number> <issue title>](<link to issue>)
## * [<issue number> <issue title>](<link to issue>)
## ...
##
## 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="<your email on jira>"
## export JIRA_TOKEN="<your 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 <project> 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="(<project>-[0-9]+)"
Comment on lines +28 to +29
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Set to "" if you don't want to use this feature.
BRANCH_NAME_TASK_MATCHING_REGEX="(<project>-[0-9]+)"
# Set to BRANCH_NAME_TASK_MATCHING_REGEX to "" if you don't want to use this feature.
BRANCH_NAME_TASK_MATCHING_REGEX="(<project>-[0-9]+)"

It should be self-explanatory, but on first reading, I thought that I had to set to ""


# 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 <project> with your JIRA project name.
JIRA_PROJECT_URL="https://<project>.atlassian.net"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's create a few additional variables at the top of the file where the user will have to write a value for this <project>, and BRANCH_NAME_TASK_MATCHING_REGEX's <project>.

It's always better to write those bash scripts in a way that you have some "global" config variables that the user needs to define/fill (even better, some yaml file, but let's not complicate for now), instead of the user needing to read through the file and search for all templates they have to fill/change.


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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we call exit or return some non 0 code so that program stops with the execution?

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`
Comment on lines +50 to +51
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the main script already has this info. Please check and use that global var instead of rereading it with git command.

if [[ $current_branch =~ $BRANCH_NAME_TASK_MATCHING_REGEX ]]; then
task_numbers=$(printf "%s " "${BASH_REMATCH[@]}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be careful with printf. Not all bash versions support it. I think I had issues with it, so I tried to avoid using it.

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., <project>-1234 <project>-5678)."
echo "For manual changelog entry, leave input empty and press enter."
echo
read -r -p "Tasks contained in this build (e.g. <project>-1234 <project>-5678): " task_numbers
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have already defined <project> within a global variable for this script, is it necessary for the user to retype it?
Can we maybe ask the user only for the task number (i.e., 1234, 5678) and then construct tasks using <project> from various + entered values?

fi

# Select or edit changelog, edit tasks list and generate again
while true; do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 not sure I would use this approach as this could easily introduce an infinite loop...

execution will be paused when we call for a text editor. Maybe we can just leverage that? E.g., check how creating a regular tag opens the text editor, and while the editor is open, the script waits for input.


if [[ -z "$task_numbers" ]]; then
break
fi

__call_python_script "$task_numbers"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be sure that whatever is behind __call_python_script, is supported on all Bash versions. Check which version came with macOS (at least 2-3 versions in the past).


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
}
41 changes: 34 additions & 7 deletions sources/__init.sh
Original file line number Diff line number Diff line change
@@ -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 #
#################################
Expand All @@ -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
Comment on lines +31 to 33
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the user enters N or just hits enter, what would happen if this logic is removed? Will execution stop?

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
}
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
}
23 changes: 23 additions & 0 deletions sources/changelog-generator.sh
Original file line number Diff line number Diff line change
@@ -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=""
}
41 changes: 36 additions & 5 deletions sources/helpers/__base_tag_handling.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -118,4 +149,4 @@ function __generate_tag_and_changelog {
tag_message_added=1
fi
done
}
}