diff --git a/cookiecutter.json b/cookiecutter.json index 7ba7ba43..bd813156 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -39,6 +39,6 @@ "aws_domain_name": "api.{{ cookiecutter.aws_base_domain_name }}", "aws_staging_domain_name": "staging.{{ cookiecutter.aws_domain_name }}", "aws_ec2_ssh_key": "", - "use_slack_notifications": "y", - "slack_channel": "{% if cookiecutter.use_slack_notification == 'y' %}#develop{% else %}''{% endif %}" + "use_slack_notification": "y", + "slack_channel": "{% if cookiecutter.use_slack_notification == 'y' %}#develop{% else %}{% endif %}" } diff --git a/{{cookiecutter.repostory_name}}/.github/workflows/cd.yml b/{{cookiecutter.repostory_name}}/.github/workflows/cd.yml index 7a84a985..8a6e627d 100644 --- a/{{cookiecutter.repostory_name}}/.github/workflows/cd.yml +++ b/{{cookiecutter.repostory_name}}/.github/workflows/cd.yml @@ -24,5 +24,5 @@ jobs: git tag $TAG git push origin $TAG env: - commit_msg : {% raw %} ${{ github.event.head_commit.message }} {% endraw %} sender : {% raw %} ${{ github.event.sender.login }} {% endraw %} + before : {% raw %} ${{ github.event.before }} {% endraw %} diff --git a/{{cookiecutter.repostory_name}}/bin/notify.py b/{{cookiecutter.repostory_name}}/bin/notify.py index 4cbf3a7a..eceb8669 100755 --- a/{{cookiecutter.repostory_name}}/bin/notify.py +++ b/{{cookiecutter.repostory_name}}/bin/notify.py @@ -1,49 +1,63 @@ import argparse +import logging import os from datetime import datetime +import itertools import requests -msg_template = "*{timestamp}*\n{author}\n{changelog}" +logger = logging.getLogger(__name__) +MSG_TEMPLATE = "*{timestamp}*\n{author}\n{changelog}" +# In case deploy is done manually we don't know what was the version of last deployment +# so printing fixed amount of commit messages +COMMITS_TO_TAKE = 5 class SlackNotifier: - url = "https://slack.com/api/chat.postMessage" + URL = "https://slack.com/api/chat.postMessage" - def __init__(self, token, channel): + def __init__(self, token: str, channel: str): if not channel or not token: - raise Exception("Missing token or channel") + raise Exception("Missing token or channel. Make sure your .env file is fine") self.token = token self.channel = channel def notify(self, text): - print(f"Sending message to channel {self.channel}") - r = requests.post( - self.url, + logger.info(f"Sending message to channel {self.channel}") + response = requests.post( + self.URL, data={ "text": text, "channel": self.channel, "token": self.token, }, ) - r.raise_for_status() + response.raise_for_status() def get_deployment_author(): return os.environ.get("sender") or "Deployed manually" -def get_deployment_changelog(): - # for now it's just message of last commit when deployed with github action - return os.environ.get("commit_msg") or "" +def get_deployment_changelog(changelog, parse=True): + if not parse: + return changelog + before_sha = os.environ.get("before") + all_commits = [c.split(",") for c in changelog.split("\n")] + if before_sha: + commits = itertools.takewhile(lambda c: c[1] == before_sha, all_commits) + else: + commits = all_commits[:COMMITS_TO_TAKE] + return "\n".join(c[1] for c in commits) -def get_message(): - return msg_template.format( + +def get_message(changelog): + return MSG_TEMPLATE.format( timestamp=datetime.now().replace(microsecond=0), author=get_deployment_author(), - changelog=get_deployment_changelog(), + changelog=changelog, ) @@ -60,16 +74,23 @@ def parse_arguments(): "-m", "--message", action="store", - default=get_message(), dest="message", + required=True, help="Message to send", ) + parser.add_argument( + "-p", + "--parse", + action=argparse.BooleanOptionalAction, + help="Parse message first. It's used during the deploy to parse `git log` output", + ) return parser.parse_args() if __name__ == "__main__": parser_result = parse_arguments() - token = os.environ.get("SLACK_TOKEN") - channel = parser_result.channel or os.environ.get("SLACK_CHANNEL") + token = os.environ.get("SLACK_TOKEN") or "" + channel = parser_result.channel or os.environ.get("SLACK_CHANNEL") or "" slack_notifier = SlackNotifier(token, channel) - slack_notifier.notify(parser_result.message) + changelog = get_deployment_changelog(parser_result.message, parser_result.parse) + slack_notifier.notify(get_message(changelog)) diff --git a/{{cookiecutter.repostory_name}}/deploy.sh b/{{cookiecutter.repostory_name}}/deploy.sh index ac851dd5..7141745a 100755 --- a/{{cookiecutter.repostory_name}}/deploy.sh +++ b/{{cookiecutter.repostory_name}}/deploy.sh @@ -29,7 +29,8 @@ docker-compose up -d {% if cookiecutter.use_slack_notification %} # Send slack notification about deploy -docker-compose run --rm app sh -c "python bin/notify.py" +output=`git log --format=format:%H,%s` +docker-compose run --rm app sh -c "python /root/src/bin/notify.py --parse -m \"$output\"" {% endif %} # Clean all dangling images diff --git a/{{cookiecutter.repostory_name}}/devops/scripts/deploy-backend.sh b/{{cookiecutter.repostory_name}}/devops/scripts/deploy-backend.sh index 24389482..fd0d3f99 100755 --- a/{{cookiecutter.repostory_name}}/devops/scripts/deploy-backend.sh +++ b/{{cookiecutter.repostory_name}}/devops/scripts/deploy-backend.sh @@ -8,4 +8,8 @@ cd "$PROJECT_DIR"/app echo "Deploying Backend: ${APP_NAME}" docker push ${APP_OWNER}.dkr.ecr.${APP_REGION}.amazonaws.com/${APP_NAME}:latest -aws autoscaling start-instance-refresh --region ${APP_REGION} --auto-scaling-group-name ${APP_NAME} \ No newline at end of file +echo "Sending slack notification" +output=`git log --format=format:%H,%s` +docker run --rm ${APP_NAME} sh -c "python bin/notify.py --parse -m \"$output\"" + +aws autoscaling start-instance-refresh --region ${APP_REGION} --auto-scaling-group-name ${APP_NAME} diff --git a/{{cookiecutter.repostory_name}}/envs/dev/.env.template b/{{cookiecutter.repostory_name}}/envs/dev/.env.template index 29a3be1a..de29480d 100644 --- a/{{cookiecutter.repostory_name}}/envs/dev/.env.template +++ b/{{cookiecutter.repostory_name}}/envs/dev/.env.template @@ -66,6 +66,6 @@ BACKUP_B2_KEY_SECRET= BACKUP_LOCAL_ROTATE_KEEP_LAST= {% if cookiecutter.use_slack_notification == "y" %} -SLACK_TOKEN="token" +SLACK_TOKEN= SLACK_CHANNEL="{{cookiecutter.slack_channel}}" {% endif %} diff --git a/{{cookiecutter.repostory_name}}/envs/prod/.env.template b/{{cookiecutter.repostory_name}}/envs/prod/.env.template index d2188648..7cf9315e 100644 --- a/{{cookiecutter.repostory_name}}/envs/prod/.env.template +++ b/{{cookiecutter.repostory_name}}/envs/prod/.env.template @@ -66,6 +66,6 @@ BACKUP_B2_KEY_SECRET= BACKUP_LOCAL_ROTATE_KEEP_LAST= {% if cookiecutter.use_slack_notification == "y" %} -SLACK_TOKEN="token" +SLACK_TOKEN= SLACK_CHANNEL="{{cookiecutter.slack_channel}}" {% endif %}