1
+ #! /bin/bash
2
+
3
+ set -euo pipefail
4
+
5
+ # This script automatically updates the release calendar in docs/install/releases/index.md
6
+ # It calculates the releases based on the first Tuesday of each month rule
7
+ # and updates the status of each release (Not Supported, Security Support, Stable, Mainline, Not Released)
8
+
9
+ DOCS_FILE=" docs/install/releases/index.md"
10
+
11
+ # Define unique markdown comments as anchors
12
+ CALENDAR_START_MARKER=" <!-- RELEASE_CALENDAR_START -->"
13
+ CALENDAR_END_MARKER=" <!-- RELEASE_CALENDAR_END -->"
14
+
15
+ # Get current date
16
+ current_date=$( date +" %Y-%m-%d" )
17
+ current_month=$( date +" %m" )
18
+ current_year=$( date +" %Y" )
19
+
20
+ # Function to get the first Tuesday of a given month and year
21
+ get_first_tuesday () {
22
+ local year=$1
23
+ local month=$2
24
+
25
+ # Find the first day of the month
26
+ local first_day=$( date -d " $year -$month -01" +" %u" )
27
+
28
+ # Calculate days until first Tuesday (if day 1 is Tuesday, first_day=2)
29
+ local days_until_tuesday=$(( first_day == 2 ? 0 : (9 - first_day) % 7 ))
30
+
31
+ # Get the date of the first Tuesday
32
+ local first_tuesday=$( date -d " $year -$month -01 +$days_until_tuesday days" +" %Y-%m-%d" )
33
+
34
+ echo " $first_tuesday "
35
+ }
36
+
37
+ # Function to format date as "Month DD, YYYY"
38
+ format_date () {
39
+ date -d " $1 " +" %B %d, %Y"
40
+ }
41
+
42
+ # Function to get the latest patch version for a minor release
43
+ get_latest_patch () {
44
+ local version_major=$1
45
+ local version_minor=$2
46
+
47
+ # Get all tags for this minor version
48
+ local tags=$( cd " $( git rev-parse --show-toplevel) " && git tag | grep " ^v$version_major \\ .$version_minor \\ ." | sort -V)
49
+
50
+ # Get the latest one
51
+ local latest=$( echo " $tags " | tail -1)
52
+
53
+ if [ -z " $latest " ]; then
54
+ # If no tags found, return empty
55
+ echo " "
56
+ else
57
+ # Return without the v prefix
58
+ echo " ${latest# v} "
59
+ fi
60
+ }
61
+
62
+ # Generate releases table showing:
63
+ # - 3 previous unsupported releases
64
+ # - 1 security support release (n-2)
65
+ # - 1 stable release (n-1)
66
+ # - 1 mainline release (n)
67
+ # - 1 next release (n+1)
68
+ generate_release_calendar () {
69
+ local result=" "
70
+ local version_major=2
71
+
72
+ # Find the current minor version by looking at the last mainline release tag
73
+ local latest_version=$( cd " $( git rev-parse --show-toplevel) " && git tag | grep ' ^v[0-9]*\.[0-9]*\.[0-9]*$' | sort -V | tail -1)
74
+ local version_minor=$( echo " $latest_version " | cut -d. -f2)
75
+
76
+ # Start with 3 unsupported releases back
77
+ local start_minor=$(( version_minor - 5 ))
78
+
79
+ # Initialize the calendar table with an additional column for latest release
80
+ result=" | Release name | Release Date | Status | Latest Release |\n"
81
+ result+=" |-------------|-------------------|------------------|----------------|\n"
82
+
83
+ # Generate rows for each release (7 total: 3 unsupported, 1 security, 1 stable, 1 mainline, 1 next)
84
+ for i in {0..6}; do
85
+ # Calculate release minor version
86
+ local rel_minor=$(( start_minor + i))
87
+ # Format release name without the .x
88
+ local version_name=" $version_major .$rel_minor "
89
+
90
+ # Calculate release month and year based on release pattern
91
+ # This is a simplified calculation assuming monthly releases
92
+ local rel_month=$(( (current_month - (5 - i) + 12 ) % 12 ))
93
+ [[ $rel_month -eq 0 ]] && rel_month=12
94
+ local rel_year=$current_year
95
+ if [[ $rel_month -gt $current_month ]]; then
96
+ rel_year=$(( rel_year - 1 ))
97
+ fi
98
+ if [[ $rel_month -lt $current_month && $i -gt 5 ]]; then
99
+ rel_year=$(( rel_year + 1 ))
100
+ fi
101
+
102
+ # Skip January releases starting from 2025
103
+ if [[ $rel_month -eq 1 && $rel_year -ge 2025 ]]; then
104
+ rel_month=2
105
+ rel_year=$rel_year
106
+ fi
107
+
108
+ # Get release date (first Tuesday of the month)
109
+ local release_date=$( get_first_tuesday $rel_year $( printf " %02d" $rel_month ) )
110
+ local formatted_date=$( format_date " $release_date " )
111
+
112
+ # Get latest patch version
113
+ local latest_patch=$( get_latest_patch $version_major $rel_minor )
114
+ local patch_link=" "
115
+ if [ -n " $latest_patch " ]; then
116
+ patch_link=" [v${latest_patch} ](https://github.com/coder/coder/releases/tag/v${latest_patch} )"
117
+ else
118
+ patch_link=" N/A"
119
+ fi
120
+
121
+ # Determine status
122
+ local status
123
+ if [[ " $release_date " > " $current_date " ]]; then
124
+ status=" Not Released"
125
+ elif [[ $i -eq 6 ]]; then
126
+ status=" Not Released"
127
+ elif [[ $i -eq 5 ]]; then
128
+ status=" Mainline"
129
+ elif [[ $i -eq 4 ]]; then
130
+ status=" Stable"
131
+ elif [[ $i -eq 3 ]]; then
132
+ status=" Security Support"
133
+ else
134
+ status=" Not Supported"
135
+ fi
136
+
137
+ # Format version name and patch link based on release status
138
+ # No links for unreleased versions
139
+ local formatted_version_name
140
+ if [[ " $status " == " Not Released" ]]; then
141
+ formatted_version_name=" $version_name "
142
+ patch_link=" N/A"
143
+ else
144
+ formatted_version_name=" [$version_name ](https://coder.com/changelog/coder-$version_major -$rel_minor )"
145
+ fi
146
+
147
+ # Add row to table
148
+ result+=" | $formatted_version_name | $formatted_date | $status | $patch_link |\n"
149
+ done
150
+
151
+ echo -e " $result "
152
+ }
153
+
154
+ # Check if the markdown comments exist in the file
155
+ if ! grep -q " $CALENDAR_START_MARKER " " $DOCS_FILE " || ! grep -q " $CALENDAR_END_MARKER " " $DOCS_FILE " ; then
156
+ echo " Error: Markdown comment anchors not found in $DOCS_FILE "
157
+ echo " Please add the following anchors around the release calendar table:"
158
+ echo " $CALENDAR_START_MARKER "
159
+ echo " $CALENDAR_END_MARKER "
160
+ exit 1
161
+ fi
162
+
163
+ # Generate the new calendar table content
164
+ NEW_CALENDAR=$( generate_release_calendar)
165
+
166
+ # Update the file while preserving the rest of the content
167
+ awk -v start_marker=" $CALENDAR_START_MARKER " \
168
+ -v end_marker=" $CALENDAR_END_MARKER " \
169
+ -v new_calendar=" $NEW_CALENDAR " \
170
+ '
171
+ BEGIN { found_start = 0; found_end = 0; print_line = 1; }
172
+ $0 ~ start_marker {
173
+ print;
174
+ print new_calendar;
175
+ found_start = 1;
176
+ print_line = 0;
177
+ next;
178
+ }
179
+ $0 ~ end_marker {
180
+ found_end = 1;
181
+ print_line = 1;
182
+ print;
183
+ next;
184
+ }
185
+ print_line || !found_start || found_end { print }
186
+ ' " $DOCS_FILE " > " ${DOCS_FILE} .new"
187
+
188
+ # Replace the original file with the updated version
189
+ mv " ${DOCS_FILE} .new" " $DOCS_FILE "
190
+
191
+ echo " Successfully updated release calendar in $DOCS_FILE "
0 commit comments