CI - Publishable crates check also checks for license file (#2681)

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
This commit is contained in:
Zeke Foppa
2025-04-29 13:20:42 -07:00
committed by GitHub
parent 020d64c1f1
commit 99d13282df
2 changed files with 40 additions and 27 deletions
View File
+40 -27
View File
@@ -3,7 +3,7 @@ import argparse
import sys
from pathlib import Path
def find_non_path_spacetimedb_deps(dev_deps):
def find_non_path_spacetimedb_deps(dev_deps, cargo_toml_path):
non_path_spacetimedb = []
for name, details in dev_deps.items():
if not name.startswith("spacetimedb"):
@@ -15,10 +15,10 @@ def find_non_path_spacetimedb_deps(dev_deps):
else:
# String dependency = version from crates.io
non_path_spacetimedb.append(name)
return non_path_spacetimedb
success = not non_path_spacetimedb
return success, non_path_spacetimedb
def check_cargo_metadata(data):
package = data.get("package", {})
def check_cargo_metadata(package, cargo_toml_path):
missing_fields = []
# Accept either license OR license-file
@@ -28,7 +28,31 @@ def check_cargo_metadata(data):
if "description" not in package:
missing_fields.append("description")
return missing_fields
missing_license_file = None
if "license-file" in package:
license_file = package["license-file"]
license_path = cargo_toml_path.parent / license_file
if not license_path.exists():
missing_license_file = license_path
success = not missing_fields and not missing_license_file
return success, missing_fields, missing_license_file
def run_checks(data, cargo_toml_path):
result = {
"success": True,
}
success, bad_deps = find_non_path_spacetimedb_deps(data.get("dev-dependencies", {}), cargo_toml_path)
result["success"] = result["success"] and success
result["bad_deps"] = bad_deps
success, missing_fields, missing_license_file = check_cargo_metadata(data.get("package", {}), cargo_toml_path)
result["missing_fields"] = missing_fields
result["missing_license_file"] = missing_license_file
result["success"] = result["success"] and success
return result
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Check Cargo.toml for metadata and dev-dependencies.")
@@ -43,29 +67,18 @@ if __name__ == "__main__":
data = toml.load(cargo_toml_path)
# Check dev-dependencies
dev_deps = data.get("dev-dependencies", {})
bad_deps = find_non_path_spacetimedb_deps(dev_deps)
# Check license/license-file and description
missing_fields = check_cargo_metadata(data)
exit_code = 0
if bad_deps:
print(f"❌ These dev-dependencies in {cargo_toml_path} must be converted to use `path` in order to not impede crate publishing:")
for dep in bad_deps:
print(f" - {dep}")
exit_code = 1
if missing_fields:
print(f"❌ Missing required fields in [package] of {cargo_toml_path}: {', '.join(missing_fields)}")
exit_code = 1
if exit_code == 0:
checks = run_checks(data, cargo_toml_path)
if checks["success"]:
print(f"{cargo_toml_path} passed all checks.")
sys.exit(exit_code)
else:
print(f"{cargo_toml_path} failed checks:")
if checks["missing_fields"]:
print(f" Missing required fields: {', '.join(checks['missing_fields'])}")
if checks["missing_license_file"]:
print(f" Specified license file does not exist: {checks['missing_license_file']}")
if checks["bad_deps"]:
print(f" These dev-dependencies must be converted to use `path` in order to not impede crate publishing: {', '.join(checks['bad_deps'])}")
sys.exit(1)
except Exception as e:
print(f"⚠️ Error: {e}")