mirror of
https://github.com/Nostalgica-Reverie/Content-Monorepo.git
synced 2026-05-09 00:24:15 +00:00
157 lines
5.9 KiB
Rust
157 lines
5.9 KiB
Rust
use serde_json::Value;
|
|
use std::env;
|
|
use std::fs::{self, OpenOptions};
|
|
use std::io::Write;
|
|
use std::path::{Path, PathBuf};
|
|
use std::process::{Command, ExitStatus};
|
|
|
|
fn main() {
|
|
let diff_output = Command::new("git")
|
|
.args(["diff-tree", "--no-commit-id", "--name-only", "-r", "HEAD"])
|
|
.output()
|
|
.expect("failed to run git diff");
|
|
|
|
let diff_str = String::from_utf8_lossy(&diff_output.stdout);
|
|
let manifest_path_str = diff_str.lines().find(|l| l.ends_with("manifest.json"));
|
|
|
|
let manifest_path_str = match manifest_path_str {
|
|
Some(p) => p,
|
|
None => {
|
|
println!("no manifest.json found in recent commit. skipping.");
|
|
std::process::exit(0);
|
|
}
|
|
};
|
|
|
|
let manifest_path = Path::new(manifest_path_str);
|
|
let p_dir = manifest_path.parent().expect("Could not find parent dir");
|
|
|
|
let manifest_content = fs::read_to_string(manifest_path).expect("Failed to read manifest");
|
|
let manifest: Value = serde_json::from_str(&manifest_content).expect("Failed to parse manifest JSON");
|
|
|
|
let raw_name = manifest["name"].as_str().unwrap();
|
|
let p_name = raw_name.replace(" ", "-");
|
|
let p_ver = manifest["version"].as_str().unwrap();
|
|
let mc_ver = manifest["mc_version"].as_str().unwrap();
|
|
let p_type = manifest["type"].as_str().unwrap();
|
|
let mr_id = manifest["modrinth_id"].as_str().unwrap_or("");
|
|
let cf_id = manifest["curseforge_id"].as_str().unwrap_or("");
|
|
let filename_base = format!("{}-{}-fabric-{}", p_name, mc_ver, p_ver);
|
|
|
|
let changelog_file = p_dir.join("changelog.md");
|
|
let mut notes = if changelog_file.exists() {
|
|
fs::read_to_string(&changelog_file).unwrap()
|
|
} else {
|
|
format!("update for {}", raw_name)
|
|
};
|
|
|
|
let prev_bump = Command::new("git")
|
|
.args(["log", "-n", "2", "--format=%H", "--", manifest_path_str])
|
|
.output()
|
|
.expect("Failed to get git log for manifest");
|
|
|
|
let prev_hashes = String::from_utf8_lossy(&prev_bump.stdout);
|
|
let prev_hash = prev_hashes.lines().nth(1).unwrap_or("HEAD~1");
|
|
|
|
let logs = Command::new("git")
|
|
.args(["log", &format!("{}..HEAD", prev_hash), "--format=%h %s - %an", "--", p_dir.to_str().unwrap()])
|
|
.output()
|
|
.expect("Failed to get commit logs");
|
|
|
|
let commit_lines: Vec<&str> = std::str::from_utf8(&logs.stdout)
|
|
.unwrap()
|
|
.lines()
|
|
.filter(|l| l.contains(": "))
|
|
.collect();
|
|
|
|
if !commit_lines.is_empty() {
|
|
if !notes.contains("# :purple_circle: Meta-changes") {
|
|
notes.push_str("\n\n# :purple_circle: Meta-changes\n");
|
|
}
|
|
notes.push_str("\n### Automated Commit Log\n");
|
|
for line in commit_lines {
|
|
notes.push_str(&format!("{}\n", line));
|
|
}
|
|
}
|
|
|
|
let workspace = env::var("GITHUB_WORKSPACE").unwrap_or_else(|_| ".".to_string());
|
|
let artifacts_dir = Path::new(&workspace).join(p_dir).join("artifacts");
|
|
|
|
if artifacts_dir.exists() {
|
|
fs::remove_dir_all(&artifacts_dir).unwrap();
|
|
}
|
|
fs::create_dir_all(&artifacts_dir).unwrap();
|
|
|
|
println!("::group::Building Artifacts");
|
|
if p_type == "modpack" {
|
|
for platform in &["mr", "cf"] {
|
|
let target_folder = format!("{}-{}", mc_ver, platform);
|
|
let target_path = p_dir.join(&target_folder);
|
|
|
|
if target_path.exists() {
|
|
// Refresh packwiz
|
|
run_cmd("packwiz", &["refresh"], &target_path);
|
|
|
|
let (export_cmd, ext) = if *platform == "mr" { ("modrinth", "mrpack") } else { ("curseforge", "zip") };
|
|
let out_file = artifacts_dir.join(format!("{}-{}.{}", filename_base, platform, ext));
|
|
|
|
// Export packwiz
|
|
run_cmd("packwiz", &[export_cmd, "export", "--output", out_file.to_str().unwrap()], &target_path);
|
|
} else {
|
|
println!("Skipping {}: folder {} not found", platform, target_path.display());
|
|
}
|
|
}
|
|
} else if p_type == "resourcepack" || p_type == "datapack" {
|
|
let out_file = artifacts_dir.join(format!("{}-{}.zip", manifest["id"].as_str().unwrap(), p_ver));
|
|
let content_dir = p_dir.join("content");
|
|
|
|
if content_dir.exists() {
|
|
run_cmd("zip", &["-r", out_file.to_str().unwrap(), "."], &content_dir);
|
|
} else {
|
|
println!("Error: content directory not found at {}", content_dir.display());
|
|
}
|
|
}
|
|
println!("::endgroup::");
|
|
|
|
if let Ok(out_path) = env::var("GITHUB_OUTPUT") {
|
|
let mut out_file = OpenOptions::new()
|
|
.append(true)
|
|
.create(true)
|
|
.open(out_path)
|
|
.expect("Could not open GITHUB_OUTPUT");
|
|
|
|
writeln!(out_file, "mr_id={}", mr_id).unwrap();
|
|
writeln!(out_file, "cf_id={}", cf_id).unwrap();
|
|
writeln!(out_file, "name={} {}", raw_name, p_ver).unwrap();
|
|
writeln!(out_file, "ver={}", p_ver).unwrap();
|
|
writeln!(out_file, "mc={}", mc_ver).unwrap();
|
|
writeln!(out_file, "type={}", p_type).unwrap();
|
|
writeln!(out_file, "path={}", p_dir.to_str().unwrap()).unwrap();
|
|
|
|
let delimiter = "EOF_NOTES_DELIMITER";
|
|
writeln!(out_file, "notes<<{}\n{}\n{}", delimiter, notes.trim(), delimiter).unwrap();
|
|
}
|
|
}
|
|
|
|
fn run_cmd(cmd: &str, args: &[&str], dir: &PathBuf) {
|
|
let status = Command::new(cmd)
|
|
.args(args)
|
|
.current_dir(dir)
|
|
.status();
|
|
|
|
match status {
|
|
Ok(s) if s.success() => (),
|
|
Ok(s) => {
|
|
eprintln!("Command '{} {:?}' failed with exit code: {}", cmd, args, s);
|
|
std::process::exit(1);
|
|
}
|
|
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
|
|
eprintln!("CRITICAL: Binary '{}' not found in PATH.", cmd);
|
|
eprintln!("Ensure it is installed and added to GITHUB_PATH.");
|
|
std::process::exit(1);
|
|
}
|
|
Err(e) => {
|
|
eprintln!("Failed to execute '{}': {}", cmd, e);
|
|
std::process::exit(1);
|
|
}
|
|
}
|
|
} |