-
Notifications
You must be signed in to change notification settings - Fork 61.6k
/
Copy pathenterprise-server-releases.js
155 lines (142 loc) · 4.66 KB
/
enterprise-server-releases.js
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
import fs from 'fs/promises'
import semver from 'semver'
import versionSatisfiesRange from './version-satisfies-range.js'
export const dates = JSON.parse(await fs.readFile('src/ghes-releases/lib/enterprise-dates.json'))
// GHES Release Lifecycle Dates:
// enterprise-releases/docs/supported-versions.md#release-lifecycle-dates
// Some frontmatter may contain the upcoming GHES release number
export const next = '3.17'
export const nextNext = '3.18'
export const supported = ['3.16', '3.15', '3.14', '3.13', '3.12']
// Edit this to `null` when it's no longer the release candidate
export const releaseCandidate = null
// Ensure that:
// "next" is ahead of "latest" by one minor or major release.
// "nextNext" is ahead of "next" by one minor or major release.
isValidNext(supported[0], next)
isValidNext(next, nextNext)
function isValidNext(v1, v2) {
const semverV1 = semver.coerce(v1).raw
const semverV2 = semver.coerce(v2).raw
const isValid =
semverV2 === semver.inc(semverV1, 'minor') || semverV2 === semver.inc(semverV1, 'major')
if (!isValid)
throw new Error(`The version "${v2}" is not one version ahead of "${v1}" as expected`)
}
// This indicates the point where we started treating redirect lookups
// to be a *function* rather than a big *lookup object*.
// This is important distinguish because we need to leverage that
// when dealing with redirects specifically in these archived
// enterprise versions.
// When you're archiving a version, add the new archived number to this
// array and you should never need to touch the `deprecated` array
// on the line just below.
export const deprecatedWithFunctionalRedirects = [
'3.11',
'3.10',
'3.9',
'3.8',
'3.7',
'3.6',
'3.5',
'3.4',
'3.3',
'3.2',
'3.1',
'3.0',
]
export const deprecated = [
...deprecatedWithFunctionalRedirects,
'2.22',
'2.21',
'2.20',
'2.19',
'2.18',
'2.17',
'2.16',
'2.15',
'2.14',
'2.13',
'2.12',
'2.11',
'2.10',
'2.9',
'2.8',
'2.7',
'2.6',
'2.5',
'2.4',
'2.3',
'2.2',
'2.1',
'2.0',
'11.10.340',
]
export const legacyAssetVersions = ['3.0', '2.22', '2.21']
// As of GHES 3.2, we started storing the scraped assets and html
// in Azure blob storage. All enterprise deprecated veresions are
// now stored in individual docs-ghes-<release number> repos. This
// release number now indicates a change in the way the archived html
// references assets.
export const firstReleaseStoredInBlobStorage = '3.2'
export const all = supported.concat(deprecated)
export const latest = supported[0]
export const latestStable = releaseCandidate ? supported[1] : latest
export const oldestSupported = supported[supported.length - 1]
export const nextDeprecationDate = dates[oldestSupported].deprecationDate
export const isOldestReleaseDeprecated = new Date() > new Date(nextDeprecationDate)
export const deprecatedOnNewSite = deprecated.filter((version) =>
versionSatisfiesRange(version, '>=2.13'),
)
export const firstVersionDeprecatedOnNewSite = '2.13'
// starting from 2.18, we updated the archival script to create a redirects.json top-level file in the archived repo
export const lastVersionWithoutArchivedRedirectsFile = '2.17'
// last version using paths like /enterprise/<release>/<user>/<product>/<category>/<article>
// instead of /enterprise-server@<release>/<product>/<category>/<article>
export const lastReleaseWithLegacyFormat = '2.18'
export const deprecatedReleasesWithLegacyFormat = deprecated.filter((version) =>
versionSatisfiesRange(version, '<=2.18'),
)
export const deprecatedReleasesWithNewFormat = deprecated.filter((version) =>
versionSatisfiesRange(version, '>2.18'),
)
export const deprecatedReleasesOnDeveloperSite = deprecated.filter((version) =>
versionSatisfiesRange(version, '<=2.16'),
)
export const firstReleaseNote = '2.20'
export const firstRestoredAdminGuides = '2.21'
export const findReleaseNumberIndex = (releaseNum) => {
return all.findIndex((i) => i === releaseNum)
}
export const getNextReleaseNumber = (releaseNum) => {
return all[findReleaseNumberIndex(releaseNum) - 1]
}
export const getPreviousReleaseNumber = (releaseNum) => {
return all[findReleaseNumberIndex(releaseNum) + 1]
}
export default {
next,
nextNext,
supported,
deprecated,
legacyAssetVersions,
all,
latest,
latestStable,
releaseCandidate,
oldestSupported,
nextDeprecationDate,
isOldestReleaseDeprecated,
deprecatedOnNewSite,
dates,
firstVersionDeprecatedOnNewSite,
lastVersionWithoutArchivedRedirectsFile,
lastReleaseWithLegacyFormat,
deprecatedReleasesWithLegacyFormat,
deprecatedReleasesWithNewFormat,
deprecatedReleasesOnDeveloperSite,
firstReleaseNote,
firstRestoredAdminGuides,
getNextReleaseNumber,
getPreviousReleaseNumber,
}