diff --git a/content/learn/migration-guides/0.10-to-0.11.md b/content/learn/migration-guides/0.10-to-0.11.md index 8d90ade691..59ee0cf065 100644 --- a/content/learn/migration-guides/0.10-to-0.11.md +++ b/content/learn/migration-guides/0.10-to-0.11.md @@ -9,7 +9,7 @@ weight = 6 Bevy relies heavily on improvements in the Rust language and compiler. As a result, the Minimum Supported Rust Version (MSRV) is "the latest stable release" of Rust. -
+
### [Schedule-First: the new and improved add_systems](https://github.com/bevyengine/bevy/pull/8079) diff --git a/content/learn/migration-guides/0.11-to-0.12.md b/content/learn/migration-guides/0.11-to-0.12.md index be9e50592a..7f16155acc 100644 --- a/content/learn/migration-guides/0.11-to-0.12.md +++ b/content/learn/migration-guides/0.11-to-0.12.md @@ -9,7 +9,7 @@ weight = 7 Bevy relies heavily on improvements in the Rust language and compiler. As a result, the Minimum Supported Rust Version (MSRV) is "the latest stable release" of Rust. -
+
### [API updates to the AnimationPlayer](https://github.com/bevyengine/bevy/pull/9002) diff --git a/content/learn/migration-guides/0.12-to-0.13.md b/content/learn/migration-guides/0.12-to-0.13.md index a581642a8f..498592e584 100644 --- a/content/learn/migration-guides/0.12-to-0.13.md +++ b/content/learn/migration-guides/0.12-to-0.13.md @@ -8,7 +8,7 @@ long_title = "Migration Guide: 0.12 to 0.13" Bevy relies heavily on improvements in the Rust language and compiler. As a result, the Minimum Supported Rust Version (MSRV) is "the latest stable release" of Rust. -
+
### [Support all types of animation interpolation from gltf](https://github.com/bevyengine/bevy/pull/10755) diff --git a/content/learn/migration-guides/0.9-to-0.10.md b/content/learn/migration-guides/0.9-to-0.10.md index f496eca915..47c73f1cb3 100644 --- a/content/learn/migration-guides/0.9-to-0.10.md +++ b/content/learn/migration-guides/0.9-to-0.10.md @@ -9,7 +9,7 @@ weight = 5 Bevy relies heavily on improvements in the Rust language and compiler. As a result, the Minimum Supported Rust Version (MSRV) is "the latest stable release" of Rust. -
+
### [Migrate engine to Schedule v3 (stageless)](https://github.com/bevyengine/bevy/pull/7267) diff --git a/generate-release/src/migration_guides.rs b/generate-release/src/migration_guides.rs index a1771ac09a..13181dacd9 100644 --- a/generate-release/src/migration_guides.rs +++ b/generate-release/src/migration_guides.rs @@ -7,7 +7,7 @@ use crate::{ markdown::write_markdown_section, }; use std::{ - collections::BTreeMap, + collections::{BTreeMap, BTreeSet}, fs::{self, OpenOptions}, io::Write as IoWrite, path::PathBuf, @@ -25,7 +25,7 @@ struct MigrationGuides { struct MigrationGuide { title: String, prs: Vec, - areas: Vec, + areas: BTreeSet, file_name: String, } @@ -42,61 +42,48 @@ pub fn generate_migration_guides( // Create the directory that will contain all the migration guides std::fs::create_dir_all(&path).context(format!("Failed to create {path:?}"))?; - // We'll write the file once at the end when all the metdaata is generated - let mut guides_metadata = Vec::new(); - - // If there is metadata that already exists, - // and would contain info such as which PR already - // has an entry, then get it and use it for that. - let preexisting_metadata_file = fs::read_to_string(path.join("_guides.toml")).ok(); - // Deserializes the file inside the option into the `MigrationGuides` struct, - // and then transposes / swaps the internal result of that operation to external, - // and returns the error of that result if there is one, - // else we have our preexisting metadata, ready to use. - let preexisting_metadata: Option = preexisting_metadata_file - .as_deref() - .map(toml::from_str) - .transpose()?; - - eprintln!("metadata exists? {}", preexisting_metadata.is_some()); - - let mut new_prs = false; + let mut guides_metadata = if overwrite_existing { + vec![] + } else { + // If there is metadata that already exists, + // and would contain info such as which PR already + // has an entry, then get it and use it for that. + let preexisting_metadata_file = fs::read_to_string(path.join("_guides.toml")).ok(); + // Deserializes the file inside the option into the `MigrationGuides` struct, + // and then transposes / swaps the internal result of that operation to external, + // and returns the error of that result if there is one, + // else we have our preexisting metadata, ready to use. + let preexisting_metadata: Option = preexisting_metadata_file + .as_deref() + .map(toml::from_str) + .transpose()?; + + eprintln!("metadata exists? {}", preexisting_metadata.is_some()); + // Populate the metadata to be written with the + // preexisting metadata so that it is not lost, + // or overwritten. + preexisting_metadata + .map(|metadata| metadata.guides) + .unwrap_or_default() + }; // Write all the separate migration guide files for (area, prs) in areas { - let mut prs = prs; - // The PRs inside each area are sorted by close date - // This doesn't really matter for the final output, - // but it's useful to keep the metadata file in the same order between runs - prs.sort_by_key(|k| k.1.closed_at); - for (title, pr) in prs { // If a PR is already included in the migration guides, // then do not generate anything for this PR. - // - // If overwrite_existing is true, then ignore - // if the PRs may have already been generated. - if preexisting_metadata.is_some() && !overwrite_existing { - let preexisting_metadata = preexisting_metadata.clone().expect( - "that preexisting metadata exists at the _guides.toml for this release version", - ); - let mut pr_already_generated = false; - - for migration_guide in preexisting_metadata.guides { - if migration_guide.prs.contains(&pr.number) { - pr_already_generated = true; - } - } + let mut pr_already_generated = false; - if pr_already_generated { - eprintln!("PR #{} already exists", pr.number); - continue; + for migration_guide in guides_metadata.iter() { + if migration_guide.prs.contains(&pr.number) { + pr_already_generated = true; } } - // If the code has reached this point then that means - // there is new PRs to be recorded. - new_prs = true; + if pr_already_generated { + eprintln!("PR #{} already exists", pr.number); + continue; + } // Slugify the title let title_slug = title @@ -112,45 +99,71 @@ pub fn generate_migration_guides( // 64 is completely arbitrary but felt long enough and is a nice power of 2 file_name.truncate(64); - // Generate the metadata block for this migration - // We always re-generate it because we need to keep the ordering if a new migration is added - let metadata_block = generate_metadata_block(&title, &file_name, &area, pr.number); + // Add the markdown extension + file_name = format!("{file_name}.md"); - let file_path = path.join(format!("{file_name}.md")); + let file_path = path.join(&file_name); if write_migration_file( &file_path, pr.body.as_ref().context("PR has no body")?, pr.number, )? { - guides_metadata.push(metadata_block); + guides_metadata.push(MigrationGuide { + title, + prs: vec![pr.number], + areas: area.clone().into_iter().collect(), + file_name, + }); } } } - if !new_prs { - return Ok(()); - } + // Sort by: Area in ascending order (empty areas at the end), and Title in ascending order + guides_metadata.sort_by(|a, b| { + let areas_cmp = match (a.areas.is_empty(), b.areas.is_empty()) { + (false, false) => { + let a_areas = a.areas.clone().into_iter().collect::>().join(" "); + let b_areas = b.areas.clone().into_iter().collect::>().join(" "); + + a_areas.cmp(&b_areas) + } + (false, true) => std::cmp::Ordering::Less, + (true, false) => std::cmp::Ordering::Greater, + (true, true) => std::cmp::Ordering::Equal, + }; + + areas_cmp.then_with(|| a.title.cmp(&b.title)) + }); + + // Create the metadata file, and overwrite it if it already exists. + // + // Note: + // The file, while overwritten, + // may still contain the same underlying data gotten from + // the preexisting metadata earlier, if overwrite_existing is false, + // thus preserving the data even if the file itself is overwritten. + let mut guides_toml = OpenOptions::new() + .write(true) + .truncate(true) + .create(true) + .open(path.join("_guides.toml")) + .context("Failed to create _guides.toml")?; - let mut guides_toml = if overwrite_existing { - // Replace and overwrite file. - OpenOptions::new() - .write(true) - .truncate(true) - .create(true) - .open(path.join("_guides.toml")) - .context("Failed to create _guides.toml")? - } else { - // Append to the metadata file, - // creating it if necessary. - OpenOptions::new() - .append(true) - .create(true) - .open(path.join("_guides.toml")) - .context("Failed to create _guides.toml")? - }; for metadata in guides_metadata { - writeln!(&mut guides_toml, "{metadata}")?; + // Generate the metadata block for this migration. + // + // We always freshly generate and write this data to the file, + // rather than appending to the end-of-file, + // so that we can maintain proper ordering of the entries. + let metadata_block = generate_metadata_block( + &metadata.title, + &metadata.file_name, + &metadata.areas.into_iter().collect::>(), + &metadata.prs, + ); + + writeln!(&mut guides_toml, "{metadata_block}")?; } Ok(()) @@ -201,15 +214,20 @@ fn generate_metadata_block( title: &str, file_name: &String, areas: &[String], - pr_number: u64, + pr_number: &[u64], ) -> String { format!( r#"[[guides]] title = "{title}" -prs = [{pr_number}] +prs = [{pr_numbers}] areas = [{areas}] -file_name = "{file_name}.md" +file_name = "{file_name}" "#, + pr_numbers = pr_number + .iter() + .map(|pr| pr.to_string()) + .collect::>() + .join(", "), areas = areas .iter() .map(|area| format!("\"{area}\"")) diff --git a/release-content/0.14/migration-guides/_guides.toml b/release-content/0.14/migration-guides/_guides.toml index b95734f8f4..764edbaccc 100644 --- a/release-content/0.14/migration-guides/_guides.toml +++ b/release-content/0.14/migration-guides/_guides.toml @@ -1,45 +1,3 @@ -[[guides]] -title = "Overhaul `Color`" -prs = ["12163"] -areas = ["Color", "Gizmos", "Rendering", "Text", "UI"] -file_name = "12163_Migrate_from_LegacyColor_to_bevy_colorColor.md" - -[[guides]] -title = "Make default behavior for `BackgroundColor` and `BorderColor` more intuitive" -prs = ["14017"] -areas = ["Rendering", "UI"] -file_name = "14017_Make_default_behavior_for_BackgroundColor_and_BorderColor_.md" - -[[guides]] -title = "Register missing types manually" -prs = ["12314"] -areas = ["Reflection"] -file_name = "12314_Clean_up_type_registrations.md" - -[[guides]] -title = "`OnEnter` state schedules now run before Startup schedules" -prs = ["11426"] -areas = ["App", "ECS"] -file_name = "11426_on_enter_startup_states.md" - -[[guides]] -title = "Fix `Node2d` typo" -prs = ["12038"] -areas = [] -file_name = "12038_fix_some_typos.md" - -[[guides]] -title = "Update to `fixedbitset` 0.5" -prs = ["12512"] -areas = [] -file_name = "12512_Update_to_fixedbitset_05.md" - -[[guides]] -title = "Move WASM panic handler from `LogPlugin` to `PanicHandlerPlugin`" -prs = ["12557"] -areas = [] -file_name = "12557_refactor_separate_out_PanicHandlerPlugin.md" - [[guides]] title = "`AnimationClip` now uses UUIDs and `NoOpTypeIdHash` is now `NoOpHash`" prs = ["11707"] @@ -58,6 +16,12 @@ prs = ["12575"] areas = ["Animation", "Color", "Math", "Rendering"] file_name = "12575_Color_maths_4.md" +[[guides]] +title = "`OnEnter` state schedules now run before Startup schedules" +prs = ["11426"] +areas = ["App", "ECS"] +file_name = "11426_on_enter_startup_states.md" + [[guides]] title = "Separate `SubApp` from `App`" prs = ["9202"] @@ -148,6 +112,12 @@ prs = ["12407"] areas = ["Audio"] file_name = "12407_Fix_leftover_references_to_children_when_despawning_audio_.md" +[[guides]] +title = "Overhaul `Color`" +prs = ["12163"] +areas = ["Color", "Gizmos", "Rendering", "Text", "UI"] +file_name = "12163_Migrate_from_LegacyColor_to_bevy_colorColor.md" + [[guides]] title = "Move WGSL math constants and color operations from `bevy_pbr` to `bevy_render`" prs = ["13209"] @@ -340,6 +310,12 @@ prs = ["13261"] areas = ["Gizmos"] file_name = "13261_More_gizmos_builders.md" +[[guides]] +title = "Contextually clearing gizmos" +prs = ["10973"] +areas = ["Gizmos"] +file_name = "10973_Contextually_clearing_gizmos.md" + [[guides]] title = "Rename touchpad input to gesture" prs = ["13660"] @@ -358,6 +334,12 @@ prs = ["13678"] areas = ["Input", "Windowing"] file_name = "13678_flush_key_input_cache_when_Bevy_loses_focus_Adopted.md" +[[guides]] +title = "Separating Finite and Infinite 3d Planes" +prs = ["12426"] +areas = ["Math", "Rendering"] +file_name = "12426_separating_finite_and_infinite_3d_planes.md" + [[guides]] title = "Move direction types out of `bevy::math::primitives`" prs = ["12018"] @@ -442,6 +424,12 @@ prs = ["12732"] areas = ["Math", "Utils"] file_name = "12732_Move_FloatOrd_into_bevy_math.md" +[[guides]] +title = "Register missing types manually" +prs = ["12314"] +areas = ["Reflection"] +file_name = "12314_Clean_up_type_registrations.md" + [[guides]] title = "Change `ReflectSerialize` trait bounds" prs = ["12024"] @@ -472,6 +460,12 @@ prs = ["12715"] areas = ["Reflection", "Scenes"] file_name = "12715_Fix_TypeRegistry_use_in_dynamic_scene.md" +[[guides]] +title = "Make default behavior for `BackgroundColor` and `BorderColor` more intuitive" +prs = ["14017"] +areas = ["Rendering", "UI"] +file_name = "14017_Make_default_behavior_for_BackgroundColor_and_BorderColor_.md" + [[guides]] title = "Rename `Camera3dBundle::dither` to `deband_dither`" prs = ["11939"] @@ -767,13 +761,19 @@ areas = ["Windowing"] file_name = "13366_fix_upgrade_to_winit_v030.md" [[guides]] -title = "Separating Finite and Infinite 3d Planes" -prs = ["12426"] -areas = ["Math", "Rendering"] -file_name = "12426_separating_finite_and_infinite_3d_planes.md" +title = "Fix `Node2d` typo" +prs = ["12038"] +areas = [] +file_name = "12038_fix_some_typos.md" [[guides]] -title = "Contextually clearing gizmos" -prs = ["10973"] -areas = ["Gizmos"] -file_name = "10973_Contextually_clearing_gizmos.md" +title = "Update to `fixedbitset` 0.5" +prs = ["12512"] +areas = [] +file_name = "12512_Update_to_fixedbitset_05.md" + +[[guides]] +title = "Move WASM panic handler from `LogPlugin` to `PanicHandlerPlugin`" +prs = ["12557"] +areas = [] +file_name = "12557_refactor_separate_out_PanicHandlerPlugin.md" diff --git a/sass/pages/_content.scss b/sass/pages/_content.scss index d49b8044be..4c13e61a4e 100644 --- a/sass/pages/_content.scss +++ b/sass/pages/_content.scss @@ -5,7 +5,7 @@ $content-font-size: 1.22rem; font-size: $content-font-size; font-weight: 400; line-height: 1.43; - color: #d2d2d2; + color: #bbb; font-style: normal; text-decoration: none; word-break: break-word; diff --git a/sass/pages/_migration_guide.scss b/sass/pages/_migration_guide.scss index 1aef0c362c..a42cef3f13 100644 --- a/sass/pages/_migration_guide.scss +++ b/sass/pages/_migration_guide.scss @@ -1,4 +1,53 @@ .migration-guide { + h1, h2, h3 { + color: #eee; + } + + h2 { + margin-block: 5rem 1rem; + + &:first-child { + margin-top: 3rem; + } + } + + h2 + h3 { + margin-top: 0; + padding-top: 0; + border-top: 0; + text-wrap: pretty; + } + + h3 { + margin-block: 2rem .5rem; + padding-top: 2rem; + border-top: solid rgba(#fff, 0.05) 1px; + } +} + +.migration-guide-meta { + display: flex; + align-items: center; + gap: 8px; + list-style: none; + padding: 0px !important; + margin: 0px 0px 1rem !important; + + li { + font-size: 0.9rem; + } + + &__area { + padding: 0.2rem 0.3rem; + line-height: 1; + border-radius: 0.2rem; + border-style: solid; + border-width: 1px; + color: #888; + } +} + +.migration-guide-legacy { h3 { margin-top: 2rem; padding-top: 2rem; @@ -6,6 +55,33 @@ border-top: solid darken($color-white, 60%) 1px; } + .migration-guide-area-tags { + display: flex; + flex-wrap: wrap; + gap: 0.2rem; + color: gray; + } + + .migration-guide-area-tag { + display: block; + font-size: 0.8rem; + padding-left: 0.2rem; + padding-right: 0.2rem; + padding-top: 0.2rem; + padding-bottom: 0.2rem; + margin-top: 0.3rem; + margin-bottom: 0.3rem; + line-height: 1; + border-radius: 0.3rem; + border-style: solid; + border-width: 1px; + } + + ul.migration-guide-pr-list { + list-style: none; + padding: 0px; + } + p, ul, li, @@ -13,31 +89,3 @@ font-size: 1rem; } } - -.migration-guide-area-tags { - display: flex; - flex-wrap: wrap; - gap: 0.2rem; - color: gray; -} - -.migration-guide-area-tag { - display: block; - font-size: 0.8rem; - padding-left: 0.2rem; - padding-right: 0.2rem; - padding-top: 0.2rem; - padding-bottom: 0.2rem; - margin-top: 0.3rem; - margin-bottom: 0.3rem; - line-height: 1; - border-radius: 0.3rem; - border-style: solid; - border-width: 1px; -} - -ul.migration-guide-pr-list { - list-style: none; - padding: 0px; -} - diff --git a/templates/shortcodes/migration_guides.md b/templates/shortcodes/migration_guides.md index adf1d12fd1..a26d6659aa 100644 --- a/templates/shortcodes/migration_guides.md +++ b/templates/shortcodes/migration_guides.md @@ -2,6 +2,7 @@ {% set base_path = macros::release_path(version=version, path="/migration-guides/") %} {% set guides_data = load_data(path=macros::path_join(path_a=base_path, path_b="/_guides.toml")) %} +{% set previous_area = "" %}