Refactor CI pipeline scripts and documentation

- Consolidated CI pipeline steps into PowerShell and Bash scripts for improved usability and consistency.
- Updated documentation in `ci.md` to clarify the execution process and options for skipping the rbx-dom section.
- Enhanced error handling and reporting in the scripts to provide clearer feedback on CI step results.
- Streamlined formatting and linting processes for both Rojo and rbx-dom, ensuring a more efficient CI workflow.
This commit is contained in:
Joe 2026-02-10 16:46:26 -06:00
parent 9688224cb4
commit f496bee347
8 changed files with 473 additions and 193 deletions

View file

@ -109,11 +109,20 @@ pub fn syncback_csv<'sync>(
if !meta.is_empty() {
let parent = snapshot.path.parent_err()?;
let instance_name = &new_inst.name;
let meta_name = if name_needs_slugify(instance_name) {
slugify_name(instance_name)
let meta_name = snapshot
.path
.file_stem()
.and_then(|s| s.to_str())
.unwrap_or("");
let meta_name = if meta_name.is_empty() {
let instance_name = &new_inst.name;
if name_needs_slugify(instance_name) {
slugify_name(instance_name)
} else {
instance_name.clone()
}
} else {
instance_name.clone()
meta_name.to_string()
};
fs_snapshot.add_file(
parent.join(format!("{}.meta.json5", meta_name)),

View file

@ -186,19 +186,22 @@ pub fn syncback_dir_no_meta<'sync>(
old_child_map.insert(inst.name(), inst);
}
// Pre-seed taken_names from old children's slugified instance names.
// This ensures new-only children that happen to slugify to the same
// bare slug as an existing sibling will be deduplicated (e.g., new
// "A/B" → slug "A_B" won't collide with existing "A_B").
// Matches the approach used in api.rs (lines 902-920).
for (_, inst) in &old_child_map {
let name = inst.name();
let slug = if name_needs_slugify(name) {
slugify_name(name).to_lowercase()
} else {
name.to_lowercase()
};
taken_names.insert(slug);
// Pre-seed taken_names from old children's slugified instance names
// so that new-only children correctly dedup against existing siblings
// (e.g., new "A/B" → slug "A_B" won't collide with existing "A_B").
// Only in incremental mode: in clean mode, old_ref is forced to None
// for all children, so every child is treated as new and pre-seeding
// would cause false collisions (spurious ~1 suffixes).
if snapshot.data.is_incremental() {
for inst in old_child_map.values() {
let name = inst.name();
let slug = if name_needs_slugify(name) {
slugify_name(name).to_lowercase()
} else {
name.to_lowercase()
};
taken_names.insert(slug);
}
}
for new_child_ref in new_inst.children() {

View file

@ -20,7 +20,10 @@ use crate::{
PathIgnoreRule, SyncRule,
},
snapshot_middleware::Middleware,
syncback::{filter_properties, inst_path, FsSnapshot, SyncbackReturn, SyncbackSnapshot},
syncback::{
filter_properties, inst_path, name_needs_slugify, slugify_name, FsSnapshot, SyncbackReturn,
SyncbackSnapshot,
},
variant_eq::variant_eq,
RojoRef,
};
@ -655,6 +658,27 @@ pub fn syncback_project<'sync>(
std::collections::HashSet<String>,
> = std::collections::HashMap::new();
// Pre-seed taken_names from old children's slugified instance names
// so that new-only children correctly dedup against existing siblings
// (e.g., new "utils" won't collide with existing "Utils.luau").
// Only in incremental mode: in clean mode, old_ref is forced to None
// for all children, so every child is treated as new and pre-seeding
// would cause false collisions (spurious ~1 suffixes).
if snapshot.data.is_incremental() {
if let Some(parent_path) = ref_to_path_map.get(&new_inst.referent()) {
let taken = taken_names_per_dir.entry(parent_path.clone()).or_default();
for old_child in old_child_map.values() {
let name = old_child.name();
let slug = if name_needs_slugify(name) {
slugify_name(name).to_lowercase()
} else {
name.to_lowercase()
};
taken.insert(slug);
}
}
}
for (name, new_child) in new_child_map.drain() {
// Skip instances of ignored classes
if snapshot.should_ignore_class(&new_child.class) {

View file

@ -58,11 +58,20 @@ pub fn syncback_txt<'sync>(
if !meta.is_empty() {
let parent = snapshot.path.parent_err()?;
let instance_name = &new_inst.name;
let meta_name = if name_needs_slugify(instance_name) {
slugify_name(instance_name)
let meta_name = snapshot
.path
.file_stem()
.and_then(|s| s.to_str())
.unwrap_or("");
let meta_name = if meta_name.is_empty() {
let instance_name = &new_inst.name;
if name_needs_slugify(instance_name) {
slugify_name(instance_name)
} else {
instance_name.clone()
}
} else {
instance_name.clone()
meta_name.to_string()
};
fs_snapshot.add_file(
parent.join(format!("{}.meta.json5", meta_name)),