Some checks failed
Build and Test / Validate Setup (push) Has been cancelled
Build and Test / Build (darwin-amd64) (push) Has been cancelled
Build and Test / Build (darwin-arm64) (push) Has been cancelled
Build and Test / Build (linux-amd64) (push) Has been cancelled
Build and Test / Build (windows-amd64) (push) Has been cancelled
Build and Test / Build (linux-arm64) (push) Has been cancelled
Build and Test / Security Audit (push) Has been cancelled
Build and Test / Package Results (push) Has been cancelled
Build and Test / Quality Gate (push) Has been cancelled
595 lines
20 KiB
Plaintext
Executable File
595 lines
20 KiB
Plaintext
Executable File
#!/usr/bin/env nu
|
|
|
|
# Create Full Distribution - Complete Packaging Workflow
|
|
# Creates both full distributions (nushell + plugins) and bin archives (plugins only)
|
|
#
|
|
# Usage:
|
|
# create_full_distribution.nu # Current platform
|
|
# create_full_distribution.nu --all-platforms # All platforms
|
|
# create_full_distribution.nu --bin-only # Only create bin archives
|
|
|
|
use lib/common_lib.nu *
|
|
|
|
# Main entry point
|
|
def main [
|
|
--all-platforms # Create packages for all platforms
|
|
--bin-only # Only create bin archives
|
|
--checksums # Generate SHA256 checksums
|
|
--verify # Verify packages after creation
|
|
] {
|
|
# CRITICAL: Ensure we're in the repository root directory
|
|
let current_dir = $env.PWD
|
|
|
|
# Check if we're already in the right directory
|
|
let is_repo_root = (
|
|
("nu_plugin_auth" | path exists) and
|
|
("nushell" | path exists) and
|
|
("scripts" | path exists)
|
|
)
|
|
|
|
if not $is_repo_root {
|
|
# Try to find the repository root by looking for the marker files
|
|
let script_parent = $current_dir
|
|
let potential_root = ($script_parent | path dirname)
|
|
|
|
if not (($potential_root | path join "nu_plugin_auth" | path exists) and
|
|
($potential_root | path join "nushell" | path exists)) {
|
|
log_error $"❌ Cannot find repository root from current directory: ($current_dir)"
|
|
log_error "Expected to find: nu_plugin_* directories and nushell/ directory"
|
|
exit 1
|
|
}
|
|
|
|
try {
|
|
cd $potential_root
|
|
log_info $"✅ Changed directory to repository root: ($potential_root)"
|
|
} catch {
|
|
log_error $"Failed to change to repository root: ($potential_root)"
|
|
exit 1
|
|
}
|
|
} else {
|
|
log_info $"✅ Already in repository root: ($current_dir)"
|
|
}
|
|
|
|
print_banner
|
|
|
|
if not $bin_only {
|
|
# Phase 1: Collect binaries
|
|
print "╔══════════════════════════════════════════════════════════╗"
|
|
print "║ Phase 1: Collect Binaries ║"
|
|
print "╚══════════════════════════════════════════════════════════╝"
|
|
|
|
collect_binaries $all_platforms
|
|
}
|
|
|
|
# Phase 2: Create full distribution packages
|
|
if not $bin_only {
|
|
print ""
|
|
print "╔══════════════════════════════════════════════════════════╗"
|
|
print "║ Phase 2: Create Full Distribution Packages ║"
|
|
print "╚══════════════════════════════════════════════════════════╝"
|
|
|
|
create_distribution_packages $all_platforms $checksums
|
|
}
|
|
|
|
# Phase 3: Create bin archives
|
|
print ""
|
|
print "╔══════════════════════════════════════════════════════════╗"
|
|
print "║ Phase 3: Create Bin Archives ║"
|
|
print "╚══════════════════════════════════════════════════════════╝"
|
|
|
|
create_bin_archives
|
|
|
|
# Phase 4: Verification
|
|
if $verify {
|
|
print ""
|
|
print "╔══════════════════════════════════════════════════════════╗"
|
|
print "║ Phase 4: Verify Packages ║"
|
|
print "╚══════════════════════════════════════════════════════════╝"
|
|
|
|
verify_packages
|
|
}
|
|
|
|
# Final summary
|
|
generate_distribution_summary $all_platforms $bin_only
|
|
}
|
|
|
|
# Print banner
|
|
def print_banner [] {
|
|
print $"
|
|
(ansi blue)╔════════════════════════════════════════════════════════════╗
|
|
║ ║
|
|
║ 📦 Complete Distribution Creator 📦 ║
|
|
║ ║
|
|
║ Creates: ║
|
|
║ • Full distribution packages \(nu + plugins\) ║
|
|
║ • Bin archives \(plugins only\) ║
|
|
║ • Checksums and manifests ║
|
|
║ ║
|
|
╚════════════════════════════════════════════════════════════╝(ansi reset)
|
|
"
|
|
}
|
|
|
|
# Collect binaries for distribution
|
|
def collect_binaries [all_platforms: bool] {
|
|
log_info "📥 Collecting binaries..."
|
|
|
|
if ("./scripts/collect_full_binaries.nu" | path exists) {
|
|
# Use built nu binary, not system nu (which may be broken)
|
|
let built_nu = "./nushell/target/release/nu"
|
|
let nu_bin = if ($built_nu | path exists) { $built_nu } else { "nu" }
|
|
|
|
let result = (do {
|
|
if $all_platforms {
|
|
^$nu_bin ./scripts/collect_full_binaries.nu --all-platforms --force
|
|
} else {
|
|
^$nu_bin ./scripts/collect_full_binaries.nu --force
|
|
}
|
|
} | complete)
|
|
|
|
print $result.stdout
|
|
|
|
if ($result.stderr | is-not-empty) {
|
|
print $result.stderr
|
|
}
|
|
|
|
if $result.exit_code == 0 {
|
|
log_success "Binaries collected successfully"
|
|
} else {
|
|
log_error $"Failed to collect binaries \(exit code: ($result.exit_code)\)"
|
|
if ($result.stderr | is-not-empty) {
|
|
log_error $result.stderr
|
|
}
|
|
exit 1
|
|
}
|
|
} else {
|
|
log_warn "collect_full_binaries.nu not found, using fallback..."
|
|
collect_binaries_fallback
|
|
}
|
|
}
|
|
|
|
# Fallback binary collection
|
|
def collect_binaries_fallback [] {
|
|
let platform = detect_platform
|
|
|
|
log_info $"Collecting for platform: ($platform)"
|
|
|
|
# Create distribution directory
|
|
let dist_dir = $"./distribution/($platform)"
|
|
ensure_dir $dist_dir
|
|
|
|
# Copy nushell binary
|
|
if ("./nushell/target/release/nu" | path exists) {
|
|
cp ./nushell/target/release/nu $dist_dir
|
|
log_success "Copied nushell binary"
|
|
} else {
|
|
log_error "Nushell binary not found. Build it first with: just build-nushell"
|
|
exit 1
|
|
}
|
|
|
|
# Copy system plugins
|
|
let system_plugins = (try { ls ./nushell/target/release/nu_plugin_* } catch { [] } | where type == file)
|
|
for plugin in $system_plugins {
|
|
cp $plugin.name $dist_dir
|
|
}
|
|
|
|
if ($system_plugins | length) > 0 {
|
|
log_success $"Copied ($system_plugins | length) system plugins"
|
|
}
|
|
|
|
# Copy custom plugins
|
|
let custom_plugins = (try { ls nu_plugin_*/target/release/nu_plugin_* } catch { [] } | where type == file)
|
|
for plugin in $custom_plugins {
|
|
cp $plugin.name $dist_dir
|
|
}
|
|
|
|
if ($custom_plugins | length) > 0 {
|
|
log_success $"Copied ($custom_plugins | length) custom plugins"
|
|
}
|
|
|
|
let total = 1 + ($system_plugins | length) + ($custom_plugins | length)
|
|
log_success $"Total binaries collected: ($total)"
|
|
}
|
|
|
|
# Create distribution packages
|
|
def create_distribution_packages [
|
|
all_platforms: bool
|
|
checksums: bool
|
|
] {
|
|
log_info "📦 Creating distribution packages..."
|
|
|
|
if ("./scripts/create_distribution_packages.nu" | path exists) {
|
|
# Use project binary for consistency
|
|
let built_nu = "./nushell/target/release/nu"
|
|
let nu_bin = if ($built_nu | path exists) { $built_nu } else { "nu" }
|
|
|
|
let result = (do {
|
|
if $all_platforms and $checksums {
|
|
^$nu_bin ./scripts/create_distribution_packages.nu --all-platforms --checksums
|
|
} else if $all_platforms {
|
|
^$nu_bin ./scripts/create_distribution_packages.nu --all-platforms
|
|
} else if $checksums {
|
|
^$nu_bin ./scripts/create_distribution_packages.nu --checksums
|
|
} else {
|
|
^$nu_bin ./scripts/create_distribution_packages.nu
|
|
}
|
|
} | complete)
|
|
|
|
print $result.stdout
|
|
|
|
if $result.exit_code == 0 {
|
|
log_success "Distribution packages created"
|
|
}
|
|
} else {
|
|
log_warn "create_distribution_packages.nu not found, using justfile..."
|
|
|
|
let pack_result = (do {
|
|
if $all_platforms {
|
|
just pack-full-all
|
|
} else {
|
|
just pack-full
|
|
}
|
|
} | complete)
|
|
|
|
if $pack_result.exit_code == 0 {
|
|
log_success "Packages created via justfile"
|
|
}
|
|
}
|
|
}
|
|
|
|
# Create bin archives (plugin-only) - directly from built plugins
|
|
def create_bin_archives [] {
|
|
log_info "📦 Creating bin archives (plugin-only)..."
|
|
|
|
# Create output directory
|
|
if not ("./bin_archives" | path exists) {
|
|
mkdir ./bin_archives
|
|
}
|
|
|
|
# Get version for naming
|
|
let version = try {
|
|
open ./nushell/Cargo.toml | get package.version
|
|
} catch {
|
|
"unknown"
|
|
}
|
|
|
|
# Get actually built platforms from distribution directory
|
|
let built_platforms = try {
|
|
ls ./distribution/*/nu | each {|p| $p.name | path dirname | path basename}
|
|
} catch {
|
|
[]
|
|
}
|
|
|
|
# If no platforms found, skip Phase 3
|
|
if ($built_platforms | length) == 0 {
|
|
log_warn "No platforms found in distribution directory - skipping plugin archive creation"
|
|
return
|
|
}
|
|
|
|
# Create archive for each built platform
|
|
for platform in $built_platforms {
|
|
let archive_name = $"plugins-only-($version)-($platform).tar.gz"
|
|
let archive_path = (pwd | append "bin_archives" | path join | append $archive_name | path join)
|
|
|
|
# Create temporary directory for archive contents
|
|
let temp_dir = (pwd | append "bin_archives" | path join | append $"plugins-temp-($version)-($platform)" | path join)
|
|
mkdir $temp_dir
|
|
|
|
# Collect all built plugin binaries (both custom and workspace plugins)
|
|
log_info $"📦 Collecting plugins for ($platform)..."
|
|
|
|
# Get custom plugin binaries from nu_plugin_*/target/release/
|
|
let custom_plugins = (
|
|
try {
|
|
ls nu_plugin_*/target/release/nu_plugin_*
|
|
| where type == "file"
|
|
| where ($it.name | str ends-with ".d") == false # Exclude .d dependency files
|
|
} catch {
|
|
[]
|
|
}
|
|
)
|
|
|
|
# Get workspace plugin binaries from nushell/target/release/
|
|
let workspace_plugins = (
|
|
try {
|
|
ls nushell/target/release/nu_plugin_*
|
|
| where type == "file"
|
|
| where ($it.name | str ends-with ".d") == false # Exclude .d dependency files
|
|
} catch {
|
|
[]
|
|
}
|
|
)
|
|
|
|
# Combine both lists
|
|
let plugins_to_copy = ($custom_plugins | append $workspace_plugins)
|
|
|
|
let plugin_count = ($plugins_to_copy | length)
|
|
|
|
if $plugin_count > 0 {
|
|
log_success $"Collected ($plugin_count) plugins"
|
|
|
|
# Copy plugins to temp directory
|
|
try {
|
|
$plugins_to_copy | each {|p|
|
|
cp $p.name $temp_dir
|
|
}
|
|
} catch {
|
|
log_error "Failed to copy plugins to temp directory"
|
|
}
|
|
|
|
# Create archive using absolute path (tar -C changes directory safely)
|
|
log_info "Creating archive..."
|
|
let tar_result = (do {
|
|
tar -C $temp_dir -czf $archive_path .
|
|
} | complete)
|
|
|
|
if $tar_result.exit_code == 0 {
|
|
if ($archive_path | path exists) {
|
|
let size = (ls $archive_path | get 0.size) / 1024 / 1024
|
|
log_success $"Archive created: ($archive_name) - (($size | into int))MB"
|
|
} else {
|
|
log_error $"Archive file exists but cannot be accessed: ($archive_path)"
|
|
}
|
|
} else {
|
|
log_error $"Failed to create archive. Exit code: ($tar_result.exit_code)"
|
|
if ($tar_result.stderr | is-not-empty) {
|
|
log_error $"Tar error: ($tar_result.stderr)"
|
|
}
|
|
}
|
|
} else {
|
|
log_warn $"No plugins found to package for ($platform)"
|
|
}
|
|
|
|
# Clean up temp directory
|
|
if ($temp_dir | path exists) {
|
|
try {
|
|
rm -r $temp_dir
|
|
} catch {
|
|
log_warn "Could not clean up temporary directory"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Verify packages
|
|
def verify_packages [] {
|
|
log_info "✅ Verifying packages..."
|
|
|
|
# Check distribution packages
|
|
if ("./distribution/packages" | path exists) {
|
|
let packages = (try { ls ./distribution/packages/*.tar.gz ./distribution/packages/*.zip } catch { [] })
|
|
|
|
if ($packages | length) > 0 {
|
|
log_success $"Found ($packages | length) distribution packages"
|
|
|
|
for pkg in $packages {
|
|
let name = $pkg.name | path basename
|
|
let size = $pkg.size / 1024 / 1024
|
|
|
|
if $size < 1 {
|
|
log_error $" ✗ ($name): Too small (($size | into int)MB)"
|
|
} else if $size > 500 {
|
|
log_warn $" ⚠ ($name): Very large (($size | into int)MB)"
|
|
} else {
|
|
log_success $" ✓ ($name): (($size | into int)MB)"
|
|
}
|
|
}
|
|
} else {
|
|
log_warn "No distribution packages found"
|
|
}
|
|
}
|
|
|
|
# Check bin archives
|
|
if ("./bin_archives" | path exists) {
|
|
let archives = (try { ls ./bin_archives/*.tar.gz } catch { [] })
|
|
|
|
if ($archives | length) > 0 {
|
|
log_success $"Found ($archives | length) bin archives"
|
|
} else {
|
|
log_warn "No bin archives found"
|
|
}
|
|
}
|
|
|
|
# Verify checksums if present
|
|
if ("./distribution/packages/checksums.txt" | path exists) {
|
|
log_info "Verifying checksums..."
|
|
|
|
let check_result = (do {
|
|
cd distribution/packages
|
|
shasum -c checksums.txt
|
|
} | complete)
|
|
|
|
if $check_result.exit_code == 0 {
|
|
log_success "All checksums verified"
|
|
} else {
|
|
log_error "Checksum verification failed"
|
|
}
|
|
}
|
|
}
|
|
|
|
# Generate distribution summary
|
|
def generate_distribution_summary [
|
|
all_platforms: bool
|
|
bin_only: bool
|
|
] {
|
|
log_info "\n📊 Distribution Summary\n"
|
|
|
|
# Get nushell version
|
|
let version = if ("./nushell/Cargo.toml" | path exists) {
|
|
open ./nushell/Cargo.toml | get package.version
|
|
} else {
|
|
"unknown"
|
|
}
|
|
|
|
log_success $"Nushell version: ($version)"
|
|
|
|
# Count distribution packages
|
|
if not $bin_only and ("./distribution/packages" | path exists) {
|
|
let packages = (try { ls ./distribution/packages/*.tar.gz ./distribution/packages/*.zip } catch { [] })
|
|
|
|
if ($packages | length) > 0 {
|
|
log_success $"Distribution packages: ($packages | length)"
|
|
|
|
let total_size = ($packages | get size | math sum) / 1024 / 1024
|
|
log_info $"Total size: (($total_size | into int))MB"
|
|
}
|
|
}
|
|
|
|
# Count bin archives
|
|
if ("./bin_archives" | path exists) {
|
|
let archives = (try { ls ./bin_archives/*.tar.gz } catch { [] })
|
|
|
|
if ($archives | length) > 0 {
|
|
log_success $"Bin archives: ($archives | length)"
|
|
|
|
let total_size = ($archives | get size | math sum) / 1024 / 1024
|
|
log_info $"Total size: (($total_size | into int))MB"
|
|
}
|
|
}
|
|
|
|
# List platforms
|
|
if not $bin_only and ("./distribution" | path exists) {
|
|
let platforms = (try { ls ./distribution/*/nu } catch { [] } | each {|p| $p.name | path dirname | path basename})
|
|
|
|
if ($platforms | length) > 0 {
|
|
log_info $"\nPlatforms built: ($platforms | str join ', ')"
|
|
|
|
# Next steps - use actual built platforms
|
|
log_info "\n📝 Next Steps:"
|
|
log_info " 1. Register plugins:"
|
|
# Show example for first built platform
|
|
let first_platform = $platforms | first 1 | get 0
|
|
log_info $" cd distribution/($first_platform) && nu register-plugins.nu"
|
|
}
|
|
} else {
|
|
# If bin_only, no next steps for distribution
|
|
log_info "\n📝 Next Steps:"
|
|
}
|
|
|
|
if not $bin_only {
|
|
# Continue with other next steps
|
|
}
|
|
|
|
log_info " 2. Upload to release:"
|
|
log_info " gh release create v($version) distribution/packages/*"
|
|
|
|
log_info " 3. Update documentation:"
|
|
log_info " Update README.md with new version"
|
|
}
|
|
|
|
# Detect current platform
|
|
def detect_platform []: nothing -> string {
|
|
let host_info = sys host
|
|
let os = $host_info.name
|
|
let arch = (sys cpu | get 0.name)
|
|
|
|
if $os == "Darwin" {
|
|
if $arch == "aarch64" {
|
|
"darwin-arm64"
|
|
} else {
|
|
"darwin-x86_64"
|
|
}
|
|
} else if $os == "Linux" {
|
|
if $arch == "aarch64" {
|
|
"linux-arm64"
|
|
} else {
|
|
"linux-x86_64"
|
|
}
|
|
} else if $os == "Windows" {
|
|
"windows-x86_64"
|
|
} else {
|
|
$"($os | str downcase)-($arch)"
|
|
}
|
|
}
|
|
|
|
# Ensure directory exists
|
|
def ensure_dir [dir: string] {
|
|
if not ($dir | path exists) {
|
|
mkdir $dir
|
|
}
|
|
}
|
|
|
|
# Quick command to rebuild and redistribute
|
|
def "main rebuild" [] {
|
|
log_info "🔄 Rebuild and redistribute workflow\n"
|
|
|
|
# Build nushell
|
|
log_info "Building nushell..."
|
|
let build_result = (do {
|
|
just build-nushell
|
|
} | complete)
|
|
|
|
if $build_result.exit_code != 0 {
|
|
log_error "Nushell build failed"
|
|
exit 1
|
|
}
|
|
|
|
# Build plugins
|
|
log_info "Building plugins..."
|
|
let plugins_result = (do {
|
|
just build
|
|
} | complete)
|
|
|
|
if $plugins_result.exit_code != 0 {
|
|
log_warn "Some plugins failed to build"
|
|
}
|
|
|
|
# Create distributions
|
|
main --checksums
|
|
}
|
|
|
|
# Show distribution status
|
|
def "main status" [] {
|
|
log_info "📊 Distribution Status\n"
|
|
|
|
# Check if nushell is built
|
|
if ("./nushell/target/release/nu" | path exists) {
|
|
let version_result = (do {
|
|
./nushell/target/release/nu -c "version | get version"
|
|
} | complete)
|
|
|
|
log_success $"Nushell binary: (str trim $version_result.stdout)"
|
|
} else {
|
|
log_warn "Nushell binary: Not built"
|
|
}
|
|
|
|
# Check distribution directory
|
|
if ("./distribution" | path exists) {
|
|
let platforms = (try { ls ./distribution/*/nu } catch { [] })
|
|
|
|
if ($platforms | length) > 0 {
|
|
log_success $"Distribution platforms: ($platforms | length)"
|
|
|
|
for p in $platforms {
|
|
let platform = $p.name | path dirname | path basename
|
|
print $" • ($platform)"
|
|
}
|
|
} else {
|
|
log_warn "Distribution: No binaries collected"
|
|
}
|
|
} else {
|
|
log_warn "Distribution: Not created"
|
|
}
|
|
|
|
# Check packages
|
|
if ("./distribution/packages" | path exists) {
|
|
let packages = (try { ls ./distribution/packages/*.tar.gz ./distribution/packages/*.zip } catch { [] })
|
|
|
|
if ($packages | length) > 0 {
|
|
log_success $"Packages: ($packages | length) created"
|
|
} else {
|
|
log_warn "Packages: None created"
|
|
}
|
|
}
|
|
|
|
# Check bin archives
|
|
if ("./bin_archives" | path exists) {
|
|
let archives = (try { ls ./bin_archives/*.tar.gz } catch { [] })
|
|
|
|
if ($archives | length) > 0 {
|
|
log_success $"Bin archives: ($archives | length) created"
|
|
} else {
|
|
log_warn "Bin archives: None created"
|
|
}
|
|
}
|
|
}
|