| import fs from 'fs' |
| import semver from 'semver' |
|
|
| import versionSatisfiesRange from './version-satisfies-range' |
|
|
| interface VersionDateData { |
| releaseDate: string |
| releaseCandidateDate?: string |
| generalAvailabilityDate?: string |
| deprecationDate: string |
| [key: string]: any |
| } |
|
|
| interface EnhancedVersionDateData extends VersionDateData { |
| displayCandidateDate?: string | null |
| displayReleaseDate?: string | null |
| } |
|
|
| interface RawDatesData { |
| [version: string]: VersionDateData |
| } |
|
|
| const rawDates: RawDatesData = JSON.parse( |
| fs.readFileSync('src/ghes-releases/lib/enterprise-dates.json', 'utf8'), |
| ) |
|
|
| |
| |
| |
|
|
| |
| export const next = '3.20' |
| export const nextNext = '3.21' |
|
|
| |
| export const supported = ['3.19', '3.18', '3.17', '3.16', '3.15', '3.14'] |
|
|
| |
| export const releaseCandidate = '3.19' |
|
|
| |
| |
| export const deprecatedWithFunctionalRedirects = [ |
| '3.13', |
| '3.12', |
| '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'] |
|
|
| |
| export const firstReleaseStoredInBlobStorage = '3.2' |
| export const firstVersionDeprecatedOnNewSite = '2.13' |
| export const lastVersionWithoutArchivedRedirectsFile = '2.17' |
| export const lastReleaseWithLegacyFormat = '2.18' |
| export const firstReleaseNote = '2.20' |
| export const firstRestoredAdminGuides = '2.21' |
|
|
| |
| |
| |
|
|
| |
| 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 dates: Record<string, EnhancedVersionDateData> = Object.fromEntries( |
| Object.entries(rawDates).map(([version, versionData]) => [ |
| version, |
| { |
| ...versionData, |
| displayCandidateDate: processDateForDisplay(versionData.releaseCandidateDate), |
| displayReleaseDate: processDateForDisplay(versionData.generalAvailabilityDate), |
| }, |
| ]), |
| ) as Record<string, EnhancedVersionDateData> |
|
|
| |
| export const nextDeprecationDate = dates[oldestSupported].deprecationDate |
| export const isOldestReleaseDeprecated = nextDeprecationDate |
| ? new Date() > new Date(nextDeprecationDate) |
| : false |
|
|
| |
| export const deprecatedOnNewSite = deprecated.filter((version) => |
| versionSatisfiesRange(version, '>=2.13'), |
| ) |
|
|
| 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'), |
| ) |
|
|
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| function processDateForDisplay(date: string | undefined): string | null { |
| if (!date) return null |
| const currentTimestamp = Math.floor(Date.now() / 1000) |
| const dateTimestamp = Math.floor(new Date(date).getTime() / 1000) |
| return dateTimestamp <= currentTimestamp ? date : null |
| } |
|
|
| |
| |
| |
| |
| |
| |
| function isValidNext(v1: string, v2: string): void { |
| 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`) |
| } |
|
|
| export const findReleaseNumberIndex = (releaseNum: string): number => { |
| return all.findIndex((i) => i === releaseNum) |
| } |
|
|
| export const getNextReleaseNumber = (releaseNum: string): string => { |
| return all[findReleaseNumberIndex(releaseNum) - 1] |
| } |
|
|
| export const getPreviousReleaseNumber = (releaseNum: string): string => { |
| return all[findReleaseNumberIndex(releaseNum) + 1] |
| } |
|
|
| |
| isValidNext(supported[0], next) |
| isValidNext(next, nextNext) |
|
|
| |
| |
| |
|
|
| export default { |
| next, |
| nextNext, |
| supported, |
| deprecated, |
| deprecatedWithFunctionalRedirects, |
| legacyAssetVersions, |
| all, |
| latest, |
| latestStable, |
| releaseCandidate, |
| oldestSupported, |
| nextDeprecationDate, |
| isOldestReleaseDeprecated, |
| deprecatedOnNewSite, |
| dates, |
| firstVersionDeprecatedOnNewSite, |
| lastVersionWithoutArchivedRedirectsFile, |
| lastReleaseWithLegacyFormat, |
| firstReleaseStoredInBlobStorage, |
| deprecatedReleasesWithLegacyFormat, |
| deprecatedReleasesWithNewFormat, |
| deprecatedReleasesOnDeveloperSite, |
| firstReleaseNote, |
| firstRestoredAdminGuides, |
| findReleaseNumberIndex, |
| getNextReleaseNumber, |
| getPreviousReleaseNumber, |
| } |
|
|