forked from PinSpace-Org/GistPin
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerate-changelog.sh
More file actions
executable file
路118 lines (100 loc) 路 3.36 KB
/
Copy pathgenerate-changelog.sh
File metadata and controls
executable file
路118 lines (100 loc) 路 3.36 KB
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
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
CONFIG_PATH="${REPO_ROOT}/infrastructure/ci/changelog-config.json"
CHANGELOG_PATH="${REPO_ROOT}/CHANGELOG.md"
if ! command -v jq >/dev/null 2>&1; then
echo "jq is required to generate changelog."
exit 1
fi
if [[ ! -f "${CONFIG_PATH}" ]]; then
echo "Config not found at ${CONFIG_PATH}"
exit 1
fi
MAX_COMMITS="$(jq -r '.maxCommits // 300' "${CONFIG_PATH}")"
FALLBACK_SECTION="$(jq -r '.fallbackSection // "Other Changes"' "${CONFIG_PATH}")"
INCLUDE_COMPARE_LINK="$(jq -r '.includeCompareLink // true' "${CONFIG_PATH}")"
REPO_URL="$(jq -r '.repoUrl // ""' "${CONFIG_PATH}")"
TODAY="$(date +%Y-%m-%d)"
TMP_FILE="$(mktemp)"
SECTIONS_DIR="$(mktemp -d)"
TYPE_ORDER_FILE="$(mktemp)"
cleanup() {
rm -rf "${SECTIONS_DIR}" "${TYPE_ORDER_FILE}"
}
trap cleanup EXIT
while IFS= read -r row; do
type="$(jq -r '.type' <<<"${row}")"
title="$(jq -r '.title' <<<"${row}")"
printf '%s|%s\n' "${type}" "${title}" >> "${TYPE_ORDER_FILE}"
: > "${SECTIONS_DIR}/${type}.md"
done < <(jq -c '.types[]' "${CONFIG_PATH}")
: > "${SECTIONS_DIR}/_fallback.md"
extract_issue_refs() {
local text="$1"
local refs
refs="$(grep -Eo '#[0-9]+' <<<"${text}" | tr '\n' ' ' | sed 's/[[:space:]]\+/ /g' | sed 's/[[:space:]]$//')"
if [[ -n "${refs}" ]]; then
printf ' (%s)' "${refs}"
fi
}
extract_pr_ref() {
local text="$1"
local pr
pr="$(grep -Eo '\(#[0-9]+\)$' <<<"${text}" | tail -n1 || true)"
if [[ -n "${pr}" ]]; then
printf ' %s' "${pr}"
fi
}
normalize_summary() {
local subject="$1"
subject="$(sed -E 's/^[a-zA-Z]+(\([^)]+\))?!?:[[:space:]]*//' <<<"${subject}")"
subject="$(sed -E 's/[[:space:]]+\(#[0-9]+\)$//' <<<"${subject}")"
printf '%s' "${subject}"
}
while IFS= read -r line; do
[[ -z "${line}" ]] && continue
sha="${line%%|*}"
subject="${line#*|}"
commit_type="$(sed -nE 's/^([a-zA-Z]+)(\([^)]+\))?!?:.*/\1/p' <<<"${subject}" | tr '[:upper:]' '[:lower:]')"
summary="$(normalize_summary "${subject}")"
issue_refs="$(extract_issue_refs "${subject}")"
pr_ref="$(extract_pr_ref "${subject}")"
short_sha="$(git rev-parse --short "${sha}")"
entry="- ${summary}${issue_refs}${pr_ref} ([${short_sha}](../../commit/${sha}))"
if [[ -n "${commit_type:-}" && -f "${SECTIONS_DIR}/${commit_type}.md" ]]; then
printf '%s\n' "${entry}" >> "${SECTIONS_DIR}/${commit_type}.md"
else
printf '%s\n' "${entry}" >> "${SECTIONS_DIR}/_fallback.md"
fi
done < <(git log -n "${MAX_COMMITS}" --pretty=format:'%H|%s')
{
echo "# Changelog"
echo
echo "## ${TODAY}"
echo
while IFS='|' read -r type title; do
if [[ -s "${SECTIONS_DIR}/${type}.md" ]]; then
echo "### ${title}"
echo
cat "${SECTIONS_DIR}/${type}.md"
echo
fi
done < "${TYPE_ORDER_FILE}"
if [[ -s "${SECTIONS_DIR}/_fallback.md" ]]; then
echo "### ${FALLBACK_SECTION}"
echo
cat "${SECTIONS_DIR}/_fallback.md"
echo
fi
if [[ "${INCLUDE_COMPARE_LINK}" == "true" && -n "${REPO_URL}" ]]; then
latest_tag="$(git describe --tags --abbrev=0 2>/dev/null || true)"
if [[ -n "${latest_tag}" ]]; then
head_sha="$(git rev-parse HEAD)"
echo "[Full Changelog](${REPO_URL}/compare/${latest_tag}...${head_sha})"
fi
fi
} > "${TMP_FILE}"
mv "${TMP_FILE}" "${CHANGELOG_PATH}"
echo "Generated changelog at ${CHANGELOG_PATH}"