-
Notifications
You must be signed in to change notification settings - Fork 0
Add changelog generator #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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) |
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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
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" | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 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 | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we call |
||||||||||
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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||||||||||
if [[ $current_branch =~ $BRANCH_NAME_TASK_MATCHING_REGEX ]]; then | ||||||||||
task_numbers=$(printf "%s " "${BASH_REMATCH[@]}") | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Be careful with |
||||||||||
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 | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we have already defined |
||||||||||
fi | ||||||||||
|
||||||||||
# Select or edit changelog, edit tasks list and generate again | ||||||||||
while true; do | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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" | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Be sure that whatever is behind |
||||||||||
|
||||||||||
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 | ||||||||||
} |
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 # | ||
################################# | ||
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
} |
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="" | ||
} |
There was a problem hiding this comment.
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.