-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgit-release
executable file
·128 lines (109 loc) · 4.4 KB
/
git-release
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/bin/bash
# Tags a new release with the given version. Optionally creates a Gitlab release and/or MR.
# The Gitlab API endpoint is inferred from the remote named "origin". Change `git_remote_name` below to rely on another
# remote.
#
# Usage:
# git release <version> [--gitlab-release] [--gitlab-mr]
#
# Example:
# git release 4.2.0 --gitlab-release --gitlab-mr
#
# @todo:
# - Use official glab cli.
# - Open up vim allow to edit the changelog before creating the release or MR.
# - Figure out the version based on commit semver markers for patch, minor & major.
for cmd in git git-changelog curl sed jq; do
if ! command -v $cmd &> /dev/null; then
echo "❗️ERROR: $cmd is not installed."
exit 1
fi
done
if [ "$#" -lt 1 ] || [[ "$1" =~ ^-- ]]; then
echo "Usage: git release <version> [--gitlab-release] [--gitlab-mr]"
exit 1
fi
gitlab_release=false
gitlab_mr=false
for arg in "$@"; do
if [ "$arg" = "--gitlab-release" ]; then
gitlab_release=true
fi
if [ "$arg" = "--gitlab-mr" ]; then
gitlab_mr=true
fi
done
version=$1
changelog=$(git changelog)
git_remote_name=origin
git_tag_name="$version"
git_tag_annotation="Release $version\n\n$changelog"
git_tag_annotation=$(printf %b "${git_tag_annotation}")
git_tag_annotation_markdown="### Release $version \n\n#### $changelog"
git_tag_annotation_markdown=$(printf %b "${git_tag_annotation_markdown}")
git tag -s -a "$git_tag_name" -m "$git_tag_annotation"
echo "New tag was successfully created 🕺"
# See: https://docs.gitlab.com/ee/api/releases/#create-a-release
if [ "$gitlab_release" = true ]; then
release_name="$version"
release_desc="$git_tag_annotation_markdown"
rollback () {
printf "\n❗️ERROR\n%s\n\nℹ️ INFO\nThe tag we just created is going to be deleted now. Good luck next time!\n" "$1"
git tag -d "$version"
echo "Evaluate if the tag needs to be deleted from the remote as well. If so, please do it manually:"
echo "git push origin --no-verify -d $version"
exit 1
}
if [ -z "$GITLAB_RELEASE_ACCESS_TOKEN" ]; then
rollback "To make a Gitlab release, make sure the \"GITLAB_RELEASE_ACCESS_TOKEN\" env var is available."
fi
git push "$git_remote_name" "$version" --no-verify
project_url=$(git remote get-url $git_remote_name)
repo_path=${project_url##*:} # Extract the part after the colon.
repo_path=${repo_path%.git} # Remove the ".git" suffix.
project_id=$(echo "$repo_path" | sed -E 's|/|%2F|g')
domain=${project_url%%:*} # Extract the domain before the colon.
domain=${domain//git@/} # Remove git@ if it exists in the domain.
domain=${domain//https:\/\//} # Remove https:// if it exists in the domain.
domain=${domain//.clu01/} # Remove .clu01 if it exists in the domain. Sorry!
# See: https://stackoverflow.com/a/73907425/65732
gitlab_api_url="https://$domain/api/v4/projects/$project_id/releases"
gitlab_release_payload=$(jq \
'{"name":$release_name,"description":$release_desc,"tag_name":$version}' \
--arg release_name "$release_name" \
--arg release_desc "$release_desc" \
--arg version "$version" \
--null-input --compact-output --raw-output --monochrome-output
)
response=$(curl -s \
--location "$gitlab_api_url" \
--write-out "%{http_code}\n" \
--header 'Content-Type: application/json' \
--header "PRIVATE-TOKEN: $GITLAB_RELEASE_ACCESS_TOKEN" \
--data "$gitlab_release_payload"
)
response_body="${response:0:${#response}-3}"
response_code="${response: -3}"
if [[ "$response_code" -eq 201 ]]; then
release_url="https://$domain/$repo_path/-/releases/$release_name"
echo "A new Gitlab release was created 💃🎉"
echo "$release_url"
else
rollback "Failed to create the Gitlab release: ($response_code) $(echo $response_body | jq .message)"
fi
fi
if [ "$gitlab_mr" = true ]; then
for cmd in lab; do
if ! command -v $cmd &> /dev/null; then
echo "❗️ERROR: $cmd is not installed."
exit 1
fi
done
mr_file_content="$git_tag_annotation"
if [ "$gitlab_release" = true ]; then
mr_file_content=$(printf %b "${mr_file_content}\n\n${release_url}")
fi
mr_file=$(mktemp)
echo "$mr_file_content" > "$mr_file"
lab mr create origin master -l "state::awaiting release" -a sep -F "$mr_file"
fi