diff --git a/.gitignore b/.gitignore index 5e99da5..9096800 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,4 @@ jspm_packages *.html *.png *.svg +!release-schedule-proposal/*.svg diff --git a/bin/lts.js b/bin/lts.js index 3752e8c..e5fca0c 100644 --- a/bin/lts.js +++ b/bin/lts.js @@ -4,9 +4,9 @@ const Path = require('path'); const Bossy = require('bossy'); const Lib = require('../lib'); const now = new Date(); -const oneYearFromNow = new Date(); +const oneYearFromNow = new Date('2035-01-01'); -oneYearFromNow.setFullYear(now.getFullYear() + 1); +// oneYearFromNow.setFullYear(now.getFullYear() + 1); const cliArgs = { 'd': { @@ -103,7 +103,7 @@ const options = { queryStart: new Date(args.start), queryEnd: new Date(args.end), html: args.html ? Path.resolve(args.html) : null, - svg: args.svg ? Path.resolve(args.svg) : null, + svg: args.svg ? Path.resolve(args.svg) : Path.join(__dirname, '..', 'release-schedule-proposal', 'rolling.svg'), png: args.png ? Path.resolve(args.png) : null, animate: args.animate, excludeMain: args.excludeMain, @@ -112,3 +112,10 @@ const options = { }; Lib.create(options); + +Lib.create({ + ...options, + queryStart: new Date('2029-09-01'), + queryEnd: new Date('2031-05-01'), + svg: options.svg.replace('.svg', '2030.svg'), +}); diff --git a/lib/index.js b/lib/index.js index ff99db3..6996c54 100644 --- a/lib/index.js +++ b/lib/index.js @@ -2,8 +2,12 @@ const Fs = require('fs'); const D3 = require('d3'); const D3Node = require('d3-node'); +const { Temporal } = require("@js-temporal/polyfill"); const styles = ` +.beta { + fill:rgb(240, 240, 75); +} .current { fill: #5fa04e; } @@ -13,7 +17,7 @@ const styles = ` .maintenance { fill: #b1bcc2; } -.unstable { +.unstable,.alpha { fill: #e99c40; } .bar-join { @@ -29,20 +33,80 @@ const styles = ` .axis--y .tick text { text-anchor: end; } -.label { +.label,.label-beta { fill: #fff; font: 20px sans-serif; font-weight: 100; text-anchor: start; dominant-baseline: middle; text-transform: uppercase; +} +.label-beta{ + fill: #000; }`; +const schedule = { + title: 'Rolling semver-major', + currentDuration: { weeks: 6 }, + maintenanceDuration: { weeks: 8 }, + activeDuration: false, +}; + +console.log(`\n## ${schedule.title}`); +{ + const ___ = duration_s => Array.isArray(duration_s) ? + `\n - for even-numbered releases:${___(duration_s[0])}\n - for odd-numbered releases:${___(duration_s[1])}` : + ` ${duration_s ? Temporal.Duration.from(duration_s).weeks : 0} weeks`; + console.log(Object.entries(schedule).map(([key, duration], i) => key === 'title' ? '' : + ` ${i}. ${key.replace('D', ' d')}:${___(duration)}` + ).join('\n')); +} +{ + const durations = Object.entries(schedule).filter(c => c[0] !== 'title' && c[0] !== 'alphaDuration' && c[1]).map(c => c[1]); + const hasArray = durations.some(Array.isArray); + const __ = arr => arr.reduce((acc, dur) => acc+Temporal.Duration.from(dur).weeks, 0) + const ___ = () => hasArray ? + `\n - for even-numbered releases: ${__(durations.map(c => (Array.isArray(c) ? c[0] : c) || 'P0M'))} weeks\n - for odd-numbered releases: ${__(durations.map(c => (Array.isArray(c) ? c[1] : c) || 'P0M'))} weeks` : + ` ${__(durations)} weeks`; + console.log(`\n Total life span (from start of beta until end of maintenance):${___(schedule)}`) +} + +const __ = (duration_s, i) => Array.isArray(duration_s) ? duration_s[i % duration_s.length] : duration_s; + +function createDataEntry(start, i) { + const ret = {}; + + const isLTS = (start.month === 10 && start.year !== 2026) || (start.month === 9 && start.day > 17); + + const alphaDuration = __(schedule.alphaDuration, i); + const betaDuration = __(schedule.betaDuration, i); + const currentDuration = __(schedule.currentDuration, i); + const activeDuration = __(isLTS ? { months: 12} : schedule.activeDuration, i); + const maintenanceDuration = __(isLTS ? {months: 18} : schedule.maintenanceDuration, i); + + if (alphaDuration) { + ret.alpha = start.toString(); + start = start.add(alphaDuration); + } + if (betaDuration) { + ret.beta = start.toString(); + start = start.add(betaDuration); + } + ret.start = start.toString(); + start = start.add(currentDuration); + if (activeDuration) { + ret.lts = start.toString(); + start = start.add(activeDuration); + } + ret.maintenance = start.toString(); + ret.end = start.add(maintenanceDuration).toString(); + return ret; +} + function parseInput (data, queryStart, queryEnd, excludeMain, projectName) { const output = []; - Object.keys(data).forEach((v) => { - const version = data[v]; + const addData = (v, version) => { const name = `${projectName} ${v.replace('v', '')}`; const current = version.start ? new Date(version.start) : null; const active = version.lts ? new Date(version.lts) : null; @@ -76,7 +140,20 @@ function parseInput (data, queryStart, queryEnd, excludeMain, projectName) { if (current < queryEnd && end > queryStart) { output.push({ name, type: 'current', start: current, end }); } - }); + if (version.beta) { + const start = new Date(version.beta); + output.push(({ name, type: 'beta', start, end: current })); + output.push(({ name, type: 'alpha', start: new Date(version.alpha), end: start })); + } + } + Object.entries(data).forEach(v => addData(...v, false)); + const queryEndPlainDate = Temporal.PlainDate.from(queryEnd.toISOString().slice(0, 10)); + for (let start = Temporal.PlainDate.from(data.v26.lts), i = 27; Temporal.PlainDate.compare(queryEndPlainDate, start) === 1; i++) { + const dataEntry = createDataEntry(start, i); + addData(`v${i}`, dataEntry); + const nextStart = Temporal.PlainDate.from(dataEntry.lts || dataEntry.maintenance); + start = nextStart; + } if (!excludeMain) { output.unshift({ @@ -92,7 +169,7 @@ function parseInput (data, queryStart, queryEnd, excludeMain, projectName) { function create (options) { - const { queryStart, queryEnd, html, svg: svgFile, png, animate, excludeMain, projectName, margin: marginInput, currentDateMarker } = options; + const { queryStart, queryEnd, html, svg: svgFile, png, animate, excludeMain, projectName, margin: marginInput } = options; const data = parseInput(options.data, queryStart, queryEnd, excludeMain, projectName); const d3n = new D3Node({ svgStyles: styles, d3Module: D3 }); const margin = marginInput || { top: 30, right: 30, bottom: 30, left: 110 }; @@ -108,7 +185,7 @@ function create (options) { .padding(0.3); const xAxis = D3.axisBottom(xScale) .tickSize(height) - .tickFormat(D3.timeFormat('%b %Y')); + .tickFormat(D3.timeFormat('%b%y')); const yAxis = D3.axisRight(yScale).tickSize(width); const svg = d3n.createSVG() .attr('width', width + margin.left + margin.right) @@ -148,21 +225,6 @@ function create (options) { .attr('stroke', '#89a19d'); } - if (currentDateMarker) { - const currentDate = new Date(); - - // Add a vertical red line for the current date - const currentX = xScale(currentDate); - svg.append('line') - .attr('x1', currentX) - .attr('x2', currentX) - .attr('stroke-width', 2) - .attr('y1', 0) - .attr('y2', height) - .attr('stroke', currentDateMarker) - .attr('opacity', 1); - } - svg.append('g') .attr('class', 'axis axis--x') .call(customXAxis); @@ -196,7 +258,7 @@ function create (options) { .attr('height', calculateHeight) .style('opacity', (data) => { // Hack to hide on current and unstable - if ((data.type === 'unstable' || data.type === 'current') || + if ((data.type === 'unstable' || data.type === 'current' || data.type === 'alpha') || xScale(data.start) <= 0) { return 0; } @@ -205,7 +267,7 @@ function create (options) { }); bar.append('text') - .attr('class', 'label') + .attr('class', data => data.type=== 'beta' ? 'label-beta' : 'label') .attr('x', (data) => { return xScale(data.start) + 15; }) @@ -226,6 +288,8 @@ function create (options) { if (typeof svgFile === 'string') { Fs.writeFileSync(svgFile, d3n.svgString()); + + console.log(`\n ![Release schedule proposal preview](.${svgFile.slice(svgFile.lastIndexOf('/'))})`) } if (typeof png === 'string') { diff --git a/lts.json b/lts.json index 69a967b..f59db08 100644 --- a/lts.json +++ b/lts.json @@ -1,53 +1,21 @@ { - "v0.10": { - "start": "2013-03-11", - "end": "2016-10-31" - }, - "v0.12": { - "start": "2015-02-06", - "end": "2016-12-31" - }, - "v4": { - "start": "2015-09-08", - "lts": "2015-10-12", - "maintenance": "2017-04-01", - "end": "2018-04-01", - "codename": "Argon" - }, - "v5": { - "start": "2015-10-29", - "maintenance": "2016-04-30", - "end": "2016-06-30" - }, - "v6": { - "start": "2016-04-26", - "lts": "2016-10-18", - "maintenance": "2018-04-01", - "end": "2019-04-01", - "codename": "Boron" - }, - "v7": { - "start": "2016-10-25", - "maintenance": "2017-04-30", - "end": "2017-06-30" - }, - "v8": { - "start": "2017-04-30", - "lts": "2017-10-31", - "maintenance": "2019-04-01", - "end": "2019-12-31", + "v24": { + "start": "2025-05-06", + "lts": "2025-10-28", + "maintenance": "2026-10-20", + "end": "2028-04-30", "codename": "" }, - "v9": { - "start": "2017-10-01", - "maintenance": "2018-04-01", - "end": "2018-06-30" + "v25": { + "start": "2025-10-15", + "maintenance": "2026-04-01", + "end": "2026-06-01" }, - "v10": { - "start": "2018-04-30", - "lts": "2018-10-01", - "maintenance": "2020-04-01", - "end": "2021-04-01", + "v26": { + "start": "2026-04-22", + "lts": "2026-10-20", + "maintenance": "2028-04-20", + "end": "2029-04-30", "codename": "" } } diff --git a/package.json b/package.json index 7829b90..6facaf3 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "node": ">=4.0.0" }, "dependencies": { + "@js-temporal/polyfill": "0.4.4", "bossy": "3.0.4", "d3": "4.7.4", "d3-node": "1.0.1", diff --git a/release-schedule-proposal/README.md b/release-schedule-proposal/README.md new file mode 100644 index 0000000..811d9b1 --- /dev/null +++ b/release-schedule-proposal/README.md @@ -0,0 +1,200 @@ +# Release schedule proposals + +To add a new proposal to this list, update the `schedule` variable in `lib/index.js`, +the SVG name in `bin/lts.js`, and use the following command: + +```sh +node ./bin/lts.js >> release-schedule-proposal/README.md +``` + +## Enterprise Feedback + +* Current releases are generally ignored (including the even-numbered releases). +* Prefer to keep (i.e. do not shorten) 30 month LTS support window (from start of Active LTS through to End-of-Life). +* Several teams asked if the LTS support window could be extended (5 years was quoted for other software (e.g. OpenSSL) LTS). +* Want predictable cadence for forward planning. +* Want LTS support window overlap to aid migration from one LTS release line to another. + +## Dependency lifecycles + +(Non-exhaustive list) + +| Dependency | LTS policy | Notes | +|-|-|-| +| c-ares | Unknown | - | +| ICU4C | Unknown | Releases historically appear to be April and October. We have generally updated within release lines as ICU does not consider changes to localized output to be breaking, but we have had issues raised against Node.js when output changes | +| libuv | None | Has historically accommodated Node.js due to overlap of collaborators/maintainers | +| npm | None | https://github.com/npm/cli/wiki/Integrating-with-node | +| OpenSSL | [Policy](https://openssl-library.org/policies/releasestrat/index.html). New LTS every 2 years. Each LTS supported minimum of 5 years. | "In essence that means an LTS will be released every April in odd-numbered years." so may just miss new LTS versions for Node.js semver-majors if we keep to April releases | +| Undici | Unknown | Overlap of collaborators/maintainers with Node.js | +| V8 | None. Does not follow semver. | V8 updates are generally considered semver-major as the V8 ABI is part of Node.js' | +| zlib | Unknown | Node.js is using Chromium's fork of zlib | + +Here are the release schedule proposals: + +## Status quo + +1. Current duration: 6 months +2. Active duration: + - For even-numbered releases: 12 months + - For odd-numbered releases: 0 months +3. Maintenance duration: + - For even-numbered releases: 18 months + - For odd-numbered releases: 3 months + +Total life span (from start of beta until end of maintenance): + +- For even-numbered releases: 36 months +- For odd-numbered releases: 9 months + +![Release schedule proposal preview](./status-quo.svg) + +![Release schedule proposal preview](./status-quo2030.svg) + +### Maintainers Feedback + +* Current release cadence (2 majors/year) is seen as burdensome — too many active branches and backports. +* Reducing to one major per year would **lower the number of active release lines**, easing backporting release management. +* **Security releases** would be simpler to coordinate, with fewer simultaneous branches to patch and less overlap between LTS lines. +* Shorter maintenance windows would **limit the volume of non-security backports**, allowing focus on critical fixes only. +* Concerns remain about ecosystem adaptation, but the **reduction in workload is broadly seen as a clear benefit**. +* Using current releases to field test changes for regressions not caught by tests before landing on LTS. + +## Proposal 1: LTS every year + +1. Alpha duration: 5 months +2. Beta duration: 1 months +3. Current duration: 6 months +4. Active duration: 12 months +5. Maintenance duration: 18 months + +Total life span (from start of beta until end of maintenance): 37 months + +![Release schedule proposal preview](./lts-every-year.svg) + +![Release schedule proposal preview](./lts-every-year2030.svg) + +### Alpha and Beta definition + +#### Stability expectations + +Alpha releases may contain semver-major changes (assuming such change does not "break the ecosystem"), +but no ABI-breaking changes (so native addons can be tested on those versions). + +Once the release has reached the beta period, semver-major changes will no +longer be included, except: + +- security fixes +- V8 update +- one-time exception granted by the TSC + +Once the beta period is ended, only security fixes and one-time exception +granted by the TSC may contain semver-major changes. + +Updating V8 during the Beta period is considered the optimal tradeoff, despite +the ABI and API potential breakage, as otherwise the included V8 version would +be 1 year old by the time the release line transitions to LTS. + +#### Release frequency + +Version | Tentative Date | Type of changes +--------|--------------| ------------- +v27.0.0-alpha.0 | 2026-10-20 | Branch-off +v27.0.0-alpha.1 | 2026-11-03 | most changes[^1] +v27.0.0-alpha.2 | 2026-11-17 | most changes[^1] +v27.0.0-alpha.3 | 2026-12-01 | most changes[^1] +v27.0.0-alpha.4 | 2026-12-15 | most changes[^1] +v27.0.0-alpha.5 | 2026-12-29 | most changes[^1] +v27.0.0-alpha.6 | 2027-01-12 | most changes[^1] +v27.0.0-alpha.7 | 2027-01-26 | most changes[^1] +v27.0.0-alpha.8 | 2027-02-09 | most changes[^1] +v27.0.0-alpha.9 | 2027-02-23 | most changes[^1] +v27.0.0-alpha.10 | 2027-03-09 | most changes[^1] +v27.0.0-beta.0 | 2027-03-23 | most changes[^1] + V8 update +v27.0.0-beta.1 | 2027-04-06 | semver-minor only + V8 update +v27.0.0 | 2027-04-20 | semver-minor only +v27.x.x | 2027-05-04 | … +v27.x.x | 2027-10-05 | … +v27.x.x (LTS transition) | 2027-10-20 | no changes +(Maintenance transition) | 2028-10-20 | _No release_ +(End-of-Life) | 2030-10-20 | _No release_ + +[^1]: Most changes from `main`, except those marked as `dont-land-on-v27.x` because e.g. they contain ABI-breaking changes, or are considered too breaking for the ecosystem, or are moving a deprecation to EOL if 27.x already contains the change moving it to Runtime. + +#### Security support + +TL;DR: TBD + +It has not been decided whether security fixes would +trigger a security release, or if those would simply be included in the next +regular release (potentially ahead of schedule). The difference on a maintenance +perspective is that a security release requires locking the CI until all the +queued security releases are ready. + +## Proposal 2: Longer life cycle + +1. current duration: + - for even-numbered releases: 6 months + - for odd-numbered releases: 12 months +2. active duration: + - for even-numbered releases: 18 months + - for odd-numbered releases: 0 months +3. maintenance duration: + - for even-numbered releases: 24 months + - for odd-numbered releases: 2 months + +Total life span (from start of beta until end of maintenance): +- for even-numbered releases: 48 months +- for odd-numbered releases: 14 months + +![Release schedule proposal preview](./longer-life-cycle.svg) + +![Release schedule proposal preview](./longer-life-cycle2030.svg) + +## Proposal 3: Less frequent LTS + +1. current duration: 6 months +2. active duration: + - for modulo-4-numbered releases: 24 months + - for other releases: 0 months +3. maintenance duration: + - for modulo-4-numbered releases: 18 months + - for other releases: 2 months + +Total life span (from start of beta until end of maintenance): +- for module-4-numbered releases: 48 months +- for releases: 8 months + +![Release schedule proposal preview](./less-frequent-lts.svg) + +![Release schedule proposal preview](./less-frequent-lts2030.svg) + +## Proposal 4: No Active LTS anymore + +1. current duration: 12 months +2. active duration: 0 months +3. maintenance duration: 24 months + +Total life span (from start of beta until end of maintenance): 36 months + +![Release schedule proposal preview](./no-active-lts.svg) + +![Release schedule proposal preview](./no-active-lts2030.svg) + +## Proposal 5: Rolling semver-major + +1. current duration: 6 weeks +2. active duration: + - 0 weeks + - or 12 months for the October release +3. maintenance duration: + - 8 weeks + - or 18 months for the October release + +Total life span (from start of beta until end of maintenance): +- 14 weeks +- or 31 months for the October release + +![Release schedule proposal preview](./rolling.svg) + +![Release schedule proposal preview](./rolling2030.svg) diff --git a/release-schedule-proposal/less-frequent-lts.svg b/release-schedule-proposal/less-frequent-lts.svg new file mode 100644 index 0000000..fffdc9f --- /dev/null +++ b/release-schedule-proposal/less-frequent-lts.svg @@ -0,0 +1,40 @@ +Jan26Jan27Jan28Jan29Jan30Jan31Jan32Jan33Jan34Jan35MainNode.js 24Node.js 25Node.js 26Node.js 27Node.js 28Node.js 29Node.js 30Node.js 31Node.js 32Node.js 33Node.js 34Node.js 35Node.js 36Node.js 37Node.js 38Node.js 39Node.js 40Node.js 41Node.js 42Node.js 43unstablemaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentactivecurrentmaintenancecurrentmaintenancecurrentcurrent \ No newline at end of file diff --git a/release-schedule-proposal/less-frequent-lts2030.svg b/release-schedule-proposal/less-frequent-lts2030.svg new file mode 100644 index 0000000..e1664b7 --- /dev/null +++ b/release-schedule-proposal/less-frequent-lts2030.svg @@ -0,0 +1,40 @@ +Oct29Jan30Apr30Jul30Oct30Jan31Apr31MainNode.js 28Node.js 32Node.js 33Node.js 34Node.js 35Node.js 36unstablemaintenanceactiveactivecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentcurrent \ No newline at end of file diff --git a/release-schedule-proposal/longer-life-cycle.svg b/release-schedule-proposal/longer-life-cycle.svg new file mode 100644 index 0000000..a98ed11 --- /dev/null +++ b/release-schedule-proposal/longer-life-cycle.svg @@ -0,0 +1,40 @@ +Jan26Jan27Jan28Jan29Jan30Jan31Jan32Jan33Jan34Jan35MainNode.js 24Node.js 25Node.js 26Node.js 27Node.js 28Node.js 29Node.js 30Node.js 31Node.js 32Node.js 33Node.js 34Node.js 35Node.js 36Node.js 37unstablemaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentactivecurrentcurrent \ No newline at end of file diff --git a/release-schedule-proposal/longer-life-cycle2030.svg b/release-schedule-proposal/longer-life-cycle2030.svg new file mode 100644 index 0000000..73622ef --- /dev/null +++ b/release-schedule-proposal/longer-life-cycle2030.svg @@ -0,0 +1,40 @@ +Oct29Jan30Apr30Jul30Oct30Jan31Apr31MainNode.js 28Node.js 30Node.js 31Node.js 32Node.js 33unstablemaintenanceactivemaintenanceactivecurrentmaintenancecurrentactivecurrentcurrent \ No newline at end of file diff --git a/release-schedule-proposal/lts-every-year.svg b/release-schedule-proposal/lts-every-year.svg new file mode 100644 index 0000000..cf4c553 --- /dev/null +++ b/release-schedule-proposal/lts-every-year.svg @@ -0,0 +1,40 @@ +Jan26Jan27Jan28Jan29Jan30Jan31Jan32Jan33Jan34Jan35MainNode.js 24Node.js 25Node.js 26Node.js 27Node.js 28Node.js 29Node.js 30Node.js 31Node.js 32Node.js 33Node.js 34Node.js 35unstablemaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenanceactivecurrentbetaalphamaintenanceactivecurrentbetaalphamaintenanceactivecurrentbetaalphamaintenanceactivecurrentbetaalphamaintenanceactivecurrentbetaalphamaintenanceactivecurrentbetaalphamaintenanceactivecurrentbetaalphaactivecurrentbetaalphabetaalpha \ No newline at end of file diff --git a/release-schedule-proposal/lts-every-year2030.svg b/release-schedule-proposal/lts-every-year2030.svg new file mode 100644 index 0000000..fe84cae --- /dev/null +++ b/release-schedule-proposal/lts-every-year2030.svg @@ -0,0 +1,40 @@ +Oct29Jan30Apr30Jul30Oct30Jan31Apr31MainNode.js 27Node.js 28Node.js 29Node.js 30Node.js 31unstablemaintenancebetaalphamaintenanceactivebetaalphamaintenanceactivecurrentbetaalphaactivecurrentbetaalphacurrentbetaalpha \ No newline at end of file diff --git a/release-schedule-proposal/no-active-lts.svg b/release-schedule-proposal/no-active-lts.svg new file mode 100644 index 0000000..4594175 --- /dev/null +++ b/release-schedule-proposal/no-active-lts.svg @@ -0,0 +1,40 @@ +Jan26Jan27Jan28Jan29Jan30Jan31Jan32Jan33Jan34Jan35MainNode.js 24Node.js 25Node.js 26Node.js 27Node.js 28Node.js 29Node.js 30Node.js 31Node.js 32Node.js 33Node.js 34Node.js 35unstablemaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentcurrent \ No newline at end of file diff --git a/release-schedule-proposal/no-active-lts2030.svg b/release-schedule-proposal/no-active-lts2030.svg new file mode 100644 index 0000000..f7ce0ca --- /dev/null +++ b/release-schedule-proposal/no-active-lts2030.svg @@ -0,0 +1,40 @@ +Oct29Jan30Apr30Jul30Oct30Jan31Apr31MainNode.js 27Node.js 28Node.js 29Node.js 30Node.js 31unstablemaintenancemaintenancemaintenancecurrentmaintenancecurrentcurrent \ No newline at end of file diff --git a/release-schedule-proposal/rolling.svg b/release-schedule-proposal/rolling.svg new file mode 100644 index 0000000..28d8c7f --- /dev/null +++ b/release-schedule-proposal/rolling.svg @@ -0,0 +1,40 @@ +Jan26Jan27Jan28Jan29Jan30Jan31Jan32Jan33Jan34Jan35MainNode.js 24Node.js 25Node.js 26Node.js 27Node.js 28Node.js 29Node.js 30Node.js 31Node.js 32Node.js 33Node.js 34Node.js 35Node.js 36Node.js 37Node.js 38Node.js 39Node.js 40Node.js 41Node.js 42Node.js 43Node.js 44Node.js 45Node.js 46Node.js 47Node.js 48Node.js 49Node.js 50Node.js 51Node.js 52Node.js 53Node.js 54Node.js 55Node.js 56Node.js 57Node.js 58Node.js 59Node.js 60Node.js 61Node.js 62Node.js 63Node.js 64Node.js 65Node.js 66Node.js 67Node.js 68Node.js 69Node.js 70Node.js 71Node.js 72Node.js 73Node.js 74Node.js 75Node.js 76Node.js 77Node.js 78Node.js 79Node.js 80Node.js 81Node.js 82Node.js 83Node.js 84Node.js 85Node.js 86Node.js 87Node.js 88Node.js 89Node.js 90Node.js 91Node.js 92Node.js 93Node.js 94Node.js 95Node.js 96Node.js 97Node.js 98unstablemaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentactivecurrentmaintenancecurrentcurrent \ No newline at end of file diff --git a/release-schedule-proposal/rolling2030.svg b/release-schedule-proposal/rolling2030.svg new file mode 100644 index 0000000..8e32392 --- /dev/null +++ b/release-schedule-proposal/rolling2030.svg @@ -0,0 +1,40 @@ +Oct29Jan30Apr30Jul30Oct30Jan31Apr31MainNode.js 35Node.js 44Node.js 50Node.js 51Node.js 52Node.js 53Node.js 54Node.js 55Node.js 56Node.js 57Node.js 58Node.js 59Node.js 60Node.js 61Node.js 62Node.js 63Node.js 64Node.js 65Node.js 66unstablemaintenancemaintenanceactivemaintenancemaintenancecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentactivecurrentmaintenancecurrentmaintenancecurrentmaintenancecurrentcurrent \ No newline at end of file diff --git a/release-schedule-proposal/status-quo.svg b/release-schedule-proposal/status-quo.svg new file mode 100644 index 0000000..8270d09 --- /dev/null +++ b/release-schedule-proposal/status-quo.svg @@ -0,0 +1,40 @@ +Jan26Jan27Jan28Jan29Jan30Jan31Jan32Jan33Jan34Jan35MainNode.js 24Node.js 25Node.js 26Node.js 27Node.js 28Node.js 29Node.js 30Node.js 31Node.js 32Node.js 33Node.js 34Node.js 35Node.js 36Node.js 37Node.js 38Node.js 39Node.js 40Node.js 41Node.js 42Node.js 43unstablemaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentmaintenanceactivecurrentmaintenancecurrentactivecurrentcurrent \ No newline at end of file diff --git a/release-schedule-proposal/status-quo2030.svg b/release-schedule-proposal/status-quo2030.svg new file mode 100644 index 0000000..6a93dbd --- /dev/null +++ b/release-schedule-proposal/status-quo2030.svg @@ -0,0 +1,40 @@ +Oct29Jan30Apr30Jul30Oct30Jan31Apr31MainNode.js 28Node.js 30Node.js 32Node.js 33Node.js 34Node.js 35Node.js 36unstablemaintenancemaintenanceactivemaintenanceactivecurrentmaintenancecurrentactivecurrentmaintenancecurrentcurrent \ No newline at end of file