aboutsummaryrefslogtreecommitdiff
path: root/maintainers/release-notes
blob: 51864cbc2a67d31942bf7f409a71d34dcdeb978c (plain)
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/env nix-shell
#!nix-shell -i bash ../shell.nix -I nixpkgs=channel:nixos-unstable-small
#                                   ^^^^^^^
#                Only used for bash. shell.nix goes to the flake.

# --- CONFIGURATION ---

# This does double duty for
# - including rl-next
# - marking where to insert new links (right after)
SUMMARY_MARKER_LINE='release-notes/rl-next.md'

# --- LIB ---

log() {
  echo 1>&2 "release-notes:" "$@"
}
logcmd() {
  local cmd="$1"
  shift
  logcmd2 "$cmd" "${*@Q}" "$cmd" "$@"
}
logcmd2() {
  local fakecmd="$1"
  local fakeargs="$2"
  shift
  shift
  printf 1>&2 "release-notes: \033[34;1m$fakecmd\033[0m "
  echo "$fakeargs" 1>&2
  "$@"
}
die() {
  # ANSI red
  printf 1>&2 "release-notes: \033[31;1merror:\033[0m"
  echo 1>&2 "" "$@"
  exit 1
}
confirm() {
  local answer
  echo 1>&2 "$@" "[y/n]"
  read -r answer
  case "$answer" in
    y|Y|yes|Yes|YES)
      return 0
      ;;
    n|N|no|No|NO)
      return 1
      ;;
    *)
      echo 1>&2 "please answer y or n"
      confirm "$@"
      ;;
  esac
}
report_done() {
  logcmd2 "git" "show" git -c pager.show=false show
  printf 1>&2 "release-notes: \033[32;1mdone\033[0m\n"
}

# --- PARSE ARGS ---

if [[ $# -gt 0 ]]; then
  die "Release notes takes no arguments, but make sure to set VERSION."
fi

# --- CHECKS ---

if [[ ! -e flake.nix ]] || [[ ! -e .git ]]; then
  die "must run in repo root"
  exit 1
fi

# repo must be clean
if ! git diff --quiet; then
  die "repo is dirty, please commit or stash changes"
fi

if ! git diff --quiet --cached; then
  die "repo has staged changes, please commit or stash them"
fi

if ! grep -F "$SUMMARY_MARKER_LINE" doc/manual/src/SUMMARY.md >/dev/null; then
  # would have been nice to catch this early, but won't be worth the extra infra
  die "SUMMARY.md is missing the marker line '$SUMMARY_MARKER_LINE', which would be used for inserting a new release notes page. Please fix the script."
fi

if [[ ! -n "${VERSION:-}" ]]; then
  die "please set the VERSION environment variable before invoking this script"
  exit 1
fi

# version_major_minor:      MAJOR.MINOR
# version_full:             MAJOR.MINOR.PATCH
# IS_PATCH:                 true if this is a patch release; append instead of create
if grep -E '^[0-9]+\.[0-9]+$' <<< "$VERSION" >/dev/null; then
  log 'is minor'
  IS_PATCH=false
  version_full="$VERSION.0"
  version_major_minor="$VERSION"
elif grep -E '^[0-9]+\.[0-9]+\.0$' <<< "$VERSION" >/dev/null; then
  log 'is minor (.0)'
  IS_PATCH=false
  version_full="$VERSION"
  version_major_minor="$(echo "$VERSION" | sed -e 's/\.0$//')"
elif grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' <<< "$VERSION" >/dev/null; then
  log 'is patch'
  IS_PATCH=true
  version_full="$VERSION"
  version_major_minor="$(echo "$VERSION" | sed -e 's/\.[0-9]*$//')"
else
  die "VERSION must be MAJOR.MINOR[.PATCH], where each is a number, e.g. 2.20 or 2.20.1 (VERSION was set to $VERSION)"
fi

unset VERSION

log "version_major_minor=$version_major_minor"
log "version_full=$version_full"
log "IS_PATCH=$IS_PATCH"

basename=rl-${version_major_minor}.md
file=doc/manual/src/release-notes/$basename

if ! $IS_PATCH; then
  if [[ -e $file ]]; then
    die "release notes file $file already exists. If you'd like to make a minor release, pass a patch version, e.g. 2.20.1"
  fi
fi

# --- DEFAULTS ---

if [[ ! -n "${DATE:-}" ]]; then
  DATE="$(date +%Y-%m-%d)"
  log "DATE not set, using $DATE"
fi

case "$DATE" in
  [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])
    ;;
  *)
    die "DATE must be YYYY-MM-DD, e.g. 2021-12-31 (DATE was set to $DATE)"
    ;;
esac

# --- DO THE WORK ---

# menu
title="Release $version_major_minor ($DATE)"
# section on page
section_title="Release $version_full ($DATE)"

(
  # TODO add minor number, and append?
  echo "# $section_title"
  echo
  build-release-notes --change-authors doc/manual/change-authors.yml doc/manual/rl-next
) | tee -a $file

log "Wrote $file"

if ! $IS_PATCH; then
  NEW_SUMMARY_LINE="  - [$title](release-notes/$basename)"

  # find the marker line, insert new link after it
  escaped_marker="$(echo "$SUMMARY_MARKER_LINE" | sed -e 's/\//\\\//g' -e 's/ /\\ /g')"
  escaped_line="$(echo "$NEW_SUMMARY_LINE" | sed -e 's/\//\\\//g' -e 's/ /\\ /g')"
  logcmd sed -i -e "/$escaped_marker/a $escaped_line" doc/manual/src/SUMMARY.md
fi

for f in doc/manual/rl-next/*.md; do
  if [[ config != "$(basename $f)" ]]; then
    logcmd git rm $f
  fi
done

logcmd git add $file doc/manual/src/SUMMARY.md
logcmd git status
logcmd git commit -m "release notes: $version_full"

report_done