feat: Add CI/CD workflows for testing and publishing SAL crates
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Test Publishing Setup / Test Publishing Setup (pull_request) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Test Publishing Setup / Test Publishing Setup (pull_request) Has been cancelled
				
			- Add a workflow for testing the publishing setup - Add a workflow for publishing SAL crates to crates.io - Improve crate metadata and version management - Add optional dependencies for modularity - Improve documentation for publishing and usage
This commit is contained in:
		
							
								
								
									
										227
									
								
								.github/workflows/publish.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								.github/workflows/publish.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,227 @@ | ||||
| name: Publish SAL Crates | ||||
|  | ||||
| on: | ||||
|   release: | ||||
|     types: [published] | ||||
|   workflow_dispatch: | ||||
|     inputs: | ||||
|       version: | ||||
|         description: 'Version to publish (e.g., 0.1.0)' | ||||
|         required: true | ||||
|         type: string | ||||
|       dry_run: | ||||
|         description: 'Dry run (do not actually publish)' | ||||
|         required: false | ||||
|         type: boolean | ||||
|         default: false | ||||
|  | ||||
| env: | ||||
|   CARGO_TERM_COLOR: always | ||||
|  | ||||
| jobs: | ||||
|   publish: | ||||
|     name: Publish to crates.io | ||||
|     runs-on: ubuntu-latest | ||||
|      | ||||
|     steps: | ||||
|     - name: Checkout repository | ||||
|       uses: actions/checkout@v4 | ||||
|       with: | ||||
|         fetch-depth: 0 | ||||
|      | ||||
|     - name: Install Rust toolchain | ||||
|       uses: dtolnay/rust-toolchain@stable | ||||
|       with: | ||||
|         toolchain: stable | ||||
|      | ||||
|     - name: Cache Cargo dependencies | ||||
|       uses: actions/cache@v4 | ||||
|       with: | ||||
|         path: | | ||||
|           ~/.cargo/bin/ | ||||
|           ~/.cargo/registry/index/ | ||||
|           ~/.cargo/registry/cache/ | ||||
|           ~/.cargo/git/db/ | ||||
|           target/ | ||||
|         key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | ||||
|         restore-keys: | | ||||
|           ${{ runner.os }}-cargo- | ||||
|      | ||||
|     - name: Install cargo-edit for version management | ||||
|       run: cargo install cargo-edit | ||||
|      | ||||
|     - name: Set version from release tag | ||||
|       if: github.event_name == 'release' | ||||
|       run: | | ||||
|         VERSION=${GITHUB_REF#refs/tags/v} | ||||
|         echo "PUBLISH_VERSION=$VERSION" >> $GITHUB_ENV | ||||
|         echo "Publishing version: $VERSION" | ||||
|      | ||||
|     - name: Set version from workflow input | ||||
|       if: github.event_name == 'workflow_dispatch' | ||||
|       run: | | ||||
|         echo "PUBLISH_VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV | ||||
|         echo "Publishing version: ${{ github.event.inputs.version }}" | ||||
|      | ||||
|     - name: Update version in all crates | ||||
|       run: | | ||||
|         echo "Updating version to $PUBLISH_VERSION" | ||||
|          | ||||
|         # Update root Cargo.toml | ||||
|         cargo set-version $PUBLISH_VERSION | ||||
|          | ||||
|         # Update each crate | ||||
|         CRATES=(os process text net git vault kubernetes virt redisclient postgresclient zinit_client mycelium rhai) | ||||
|         for crate in "${CRATES[@]}"; do | ||||
|           if [ -d "$crate" ]; then | ||||
|             cd "$crate" | ||||
|             cargo set-version $PUBLISH_VERSION | ||||
|             cd .. | ||||
|             echo "Updated $crate to version $PUBLISH_VERSION" | ||||
|           fi | ||||
|         done | ||||
|      | ||||
|     - name: Run tests | ||||
|       run: cargo test --workspace --verbose | ||||
|      | ||||
|     - name: Check formatting | ||||
|       run: cargo fmt --all -- --check | ||||
|      | ||||
|     - name: Run clippy | ||||
|       run: cargo clippy --workspace --all-targets --all-features -- -D warnings | ||||
|      | ||||
|     - name: Dry run publish (check packages) | ||||
|       run: | | ||||
|         echo "Checking all packages can be published..." | ||||
|          | ||||
|         CRATES=(os process text net git vault kubernetes virt redisclient postgresclient zinit_client mycelium rhai) | ||||
|         for crate in "${CRATES[@]}"; do | ||||
|           if [ -d "$crate" ]; then | ||||
|             echo "Checking $crate..." | ||||
|             cd "$crate" | ||||
|             cargo publish --dry-run | ||||
|             cd .. | ||||
|           fi | ||||
|         done | ||||
|          | ||||
|         echo "Checking main crate..." | ||||
|         cargo publish --dry-run | ||||
|      | ||||
|     - name: Publish crates (dry run) | ||||
|       if: github.event.inputs.dry_run == 'true' | ||||
|       run: | | ||||
|         echo "🔍 DRY RUN MODE - Would publish the following crates:" | ||||
|         echo "Individual crates: sal-os, sal-process, sal-text, sal-net, sal-git, sal-vault, sal-kubernetes, sal-virt, sal-redisclient, sal-postgresclient, sal-zinit-client, sal-mycelium, sal-rhai" | ||||
|         echo "Meta-crate: sal" | ||||
|         echo "Version: $PUBLISH_VERSION" | ||||
|      | ||||
|     - name: Publish individual crates | ||||
|       if: github.event.inputs.dry_run != 'true' | ||||
|       env: | ||||
|         CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | ||||
|       run: | | ||||
|         echo "Publishing individual crates..." | ||||
|          | ||||
|         # Crates in dependency order | ||||
|         CRATES=(os process text net git vault kubernetes virt redisclient postgresclient zinit_client mycelium rhai) | ||||
|          | ||||
|         for crate in "${CRATES[@]}"; do | ||||
|           if [ -d "$crate" ]; then | ||||
|             echo "Publishing sal-$crate..." | ||||
|             cd "$crate" | ||||
|              | ||||
|             # Retry logic for transient failures | ||||
|             for attempt in 1 2 3; do | ||||
|               if cargo publish --token $CARGO_REGISTRY_TOKEN; then | ||||
|                 echo "✅ sal-$crate published successfully" | ||||
|                 break | ||||
|               else | ||||
|                 if [ $attempt -eq 3 ]; then | ||||
|                   echo "❌ Failed to publish sal-$crate after 3 attempts" | ||||
|                   exit 1 | ||||
|                 else | ||||
|                   echo "⚠️ Attempt $attempt failed, retrying in 30 seconds..." | ||||
|                   sleep 30 | ||||
|                 fi | ||||
|               fi | ||||
|             done | ||||
|              | ||||
|             cd .. | ||||
|              | ||||
|             # Wait for crates.io to process | ||||
|             if [ "$crate" != "rhai" ]; then | ||||
|               echo "⏳ Waiting 30 seconds for crates.io to process..." | ||||
|               sleep 30 | ||||
|             fi | ||||
|           fi | ||||
|         done | ||||
|      | ||||
|     - name: Publish main crate | ||||
|       if: github.event.inputs.dry_run != 'true' | ||||
|       env: | ||||
|         CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | ||||
|       run: | | ||||
|         echo "Publishing main sal crate..." | ||||
|          | ||||
|         # Wait a bit longer before publishing the meta-crate | ||||
|         echo "⏳ Waiting 60 seconds for all individual crates to be available..." | ||||
|         sleep 60 | ||||
|          | ||||
|         # Retry logic for the main crate | ||||
|         for attempt in 1 2 3; do | ||||
|           if cargo publish --token $CARGO_REGISTRY_TOKEN; then | ||||
|             echo "✅ Main sal crate published successfully" | ||||
|             break | ||||
|           else | ||||
|             if [ $attempt -eq 3 ]; then | ||||
|               echo "❌ Failed to publish main sal crate after 3 attempts" | ||||
|               exit 1 | ||||
|             else | ||||
|               echo "⚠️ Attempt $attempt failed, retrying in 60 seconds..." | ||||
|               sleep 60 | ||||
|             fi | ||||
|           fi | ||||
|         done | ||||
|      | ||||
|     - name: Create summary | ||||
|       if: always() | ||||
|       run: | | ||||
|         echo "## 📦 SAL Publishing Summary" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "**Version:** $PUBLISH_VERSION" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "**Trigger:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY | ||||
|          | ||||
|         if [ "${{ github.event.inputs.dry_run }}" == "true" ]; then | ||||
|           echo "**Mode:** Dry Run" >> $GITHUB_STEP_SUMMARY | ||||
|         else | ||||
|           echo "**Mode:** Live Publishing" >> $GITHUB_STEP_SUMMARY | ||||
|         fi | ||||
|          | ||||
|         echo "" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "### Published Crates" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- sal-os" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- sal-process" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- sal-text" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- sal-net" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- sal-git" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- sal-vault" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- sal-kubernetes" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- sal-virt" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- sal-redisclient" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- sal-postgresclient" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- sal-zinit-client" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- sal-mycelium" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- sal-rhai" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- sal (meta-crate)" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "### Usage" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "" >> $GITHUB_STEP_SUMMARY | ||||
|         echo '```bash' >> $GITHUB_STEP_SUMMARY | ||||
|         echo "# Individual crates" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "cargo add sal-os sal-process sal-text" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "# Meta-crate with features" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "cargo add sal --features core" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "cargo add sal --features all" >> $GITHUB_STEP_SUMMARY | ||||
|         echo '```' >> $GITHUB_STEP_SUMMARY | ||||
							
								
								
									
										233
									
								
								.github/workflows/test-publish.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										233
									
								
								.github/workflows/test-publish.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,233 @@ | ||||
| name: Test Publishing Setup | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|     branches: [ main, master ] | ||||
|     paths: | ||||
|       - '**/Cargo.toml' | ||||
|       - 'scripts/publish-all.sh' | ||||
|       - '.github/workflows/publish.yml' | ||||
|   pull_request: | ||||
|     branches: [ main, master ] | ||||
|     paths: | ||||
|       - '**/Cargo.toml' | ||||
|       - 'scripts/publish-all.sh' | ||||
|       - '.github/workflows/publish.yml' | ||||
|   workflow_dispatch: | ||||
|  | ||||
| env: | ||||
|   CARGO_TERM_COLOR: always | ||||
|  | ||||
| jobs: | ||||
|   test-publish-setup: | ||||
|     name: Test Publishing Setup | ||||
|     runs-on: ubuntu-latest | ||||
|      | ||||
|     steps: | ||||
|     - name: Checkout repository | ||||
|       uses: actions/checkout@v4 | ||||
|      | ||||
|     - name: Install Rust toolchain | ||||
|       uses: dtolnay/rust-toolchain@stable | ||||
|       with: | ||||
|         toolchain: stable | ||||
|      | ||||
|     - name: Cache Cargo dependencies | ||||
|       uses: actions/cache@v4 | ||||
|       with: | ||||
|         path: | | ||||
|           ~/.cargo/bin/ | ||||
|           ~/.cargo/registry/index/ | ||||
|           ~/.cargo/registry/cache/ | ||||
|           ~/.cargo/git/db/ | ||||
|           target/ | ||||
|         key: ${{ runner.os }}-cargo-publish-test-${{ hashFiles('**/Cargo.lock') }} | ||||
|         restore-keys: | | ||||
|           ${{ runner.os }}-cargo-publish-test- | ||||
|           ${{ runner.os }}-cargo- | ||||
|      | ||||
|     - name: Install cargo-edit | ||||
|       run: cargo install cargo-edit | ||||
|      | ||||
|     - name: Test workspace structure | ||||
|       run: | | ||||
|         echo "Testing workspace structure..." | ||||
|          | ||||
|         # Check that all expected crates exist | ||||
|         EXPECTED_CRATES=(os process text net git vault kubernetes virt redisclient postgresclient zinit_client mycelium rhai herodo) | ||||
|          | ||||
|         for crate in "${EXPECTED_CRATES[@]}"; do | ||||
|           if [ -d "$crate" ] && [ -f "$crate/Cargo.toml" ]; then | ||||
|             echo "✅ $crate exists" | ||||
|           else | ||||
|             echo "❌ $crate missing or invalid" | ||||
|             exit 1 | ||||
|           fi | ||||
|         done | ||||
|      | ||||
|     - name: Test feature configuration | ||||
|       run: | | ||||
|         echo "Testing feature configuration..." | ||||
|          | ||||
|         # Test that features work correctly | ||||
|         cargo check --features os | ||||
|         cargo check --features process | ||||
|         cargo check --features text | ||||
|         cargo check --features net | ||||
|         cargo check --features git | ||||
|         cargo check --features vault | ||||
|         cargo check --features kubernetes | ||||
|         cargo check --features virt | ||||
|         cargo check --features redisclient | ||||
|         cargo check --features postgresclient | ||||
|         cargo check --features zinit_client | ||||
|         cargo check --features mycelium | ||||
|         cargo check --features rhai | ||||
|          | ||||
|         echo "✅ All individual features work" | ||||
|          | ||||
|         # Test feature groups | ||||
|         cargo check --features core | ||||
|         cargo check --features clients | ||||
|         cargo check --features infrastructure | ||||
|         cargo check --features scripting | ||||
|          | ||||
|         echo "✅ All feature groups work" | ||||
|          | ||||
|         # Test all features | ||||
|         cargo check --features all | ||||
|          | ||||
|         echo "✅ All features together work" | ||||
|      | ||||
|     - name: Test dry-run publishing | ||||
|       run: | | ||||
|         echo "Testing dry-run publishing..." | ||||
|          | ||||
|         # Test each individual crate can be packaged | ||||
|         CRATES=(os process text net git vault kubernetes virt redisclient postgresclient zinit_client mycelium rhai) | ||||
|          | ||||
|         for crate in "${CRATES[@]}"; do | ||||
|           echo "Testing sal-$crate..." | ||||
|           cd "$crate" | ||||
|           cargo publish --dry-run | ||||
|           cd .. | ||||
|           echo "✅ sal-$crate can be published" | ||||
|         done | ||||
|          | ||||
|         # Test main crate | ||||
|         echo "Testing main sal crate..." | ||||
|         cargo publish --dry-run | ||||
|         echo "✅ Main sal crate can be published" | ||||
|      | ||||
|     - name: Test publishing script | ||||
|       run: | | ||||
|         echo "Testing publishing script..." | ||||
|          | ||||
|         # Make script executable | ||||
|         chmod +x scripts/publish-all.sh | ||||
|          | ||||
|         # Test dry run | ||||
|         ./scripts/publish-all.sh --dry-run --version 0.1.0-test | ||||
|          | ||||
|         echo "✅ Publishing script works" | ||||
|      | ||||
|     - name: Test version consistency | ||||
|       run: | | ||||
|         echo "Testing version consistency..." | ||||
|          | ||||
|         # Get version from root Cargo.toml | ||||
|         ROOT_VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/') | ||||
|         echo "Root version: $ROOT_VERSION" | ||||
|          | ||||
|         # Check all crates have the same version | ||||
|         CRATES=(os process text net git vault kubernetes virt redisclient postgresclient zinit_client mycelium rhai herodo) | ||||
|          | ||||
|         for crate in "${CRATES[@]}"; do | ||||
|           if [ -f "$crate/Cargo.toml" ]; then | ||||
|             CRATE_VERSION=$(grep '^version = ' "$crate/Cargo.toml" | head -1 | sed 's/version = "\(.*\)"/\1/') | ||||
|             if [ "$CRATE_VERSION" = "$ROOT_VERSION" ]; then | ||||
|               echo "✅ $crate version matches: $CRATE_VERSION" | ||||
|             else | ||||
|               echo "❌ $crate version mismatch: $CRATE_VERSION (expected $ROOT_VERSION)" | ||||
|               exit 1 | ||||
|             fi | ||||
|           fi | ||||
|         done | ||||
|      | ||||
|     - name: Test metadata completeness | ||||
|       run: | | ||||
|         echo "Testing metadata completeness..." | ||||
|          | ||||
|         # Check that all crates have required metadata | ||||
|         CRATES=(os process text net git vault kubernetes virt redisclient postgresclient zinit_client mycelium rhai) | ||||
|          | ||||
|         for crate in "${CRATES[@]}"; do | ||||
|           echo "Checking sal-$crate metadata..." | ||||
|           cd "$crate" | ||||
|            | ||||
|           # Check required fields exist | ||||
|           if ! grep -q '^name = "sal-' Cargo.toml; then | ||||
|             echo "❌ $crate missing or incorrect name" | ||||
|             exit 1 | ||||
|           fi | ||||
|            | ||||
|           if ! grep -q '^description = ' Cargo.toml; then | ||||
|             echo "❌ $crate missing description" | ||||
|             exit 1 | ||||
|           fi | ||||
|            | ||||
|           if ! grep -q '^repository = ' Cargo.toml; then | ||||
|             echo "❌ $crate missing repository" | ||||
|             exit 1 | ||||
|           fi | ||||
|            | ||||
|           if ! grep -q '^license = ' Cargo.toml; then | ||||
|             echo "❌ $crate missing license" | ||||
|             exit 1 | ||||
|           fi | ||||
|            | ||||
|           echo "✅ sal-$crate metadata complete" | ||||
|           cd .. | ||||
|         done | ||||
|      | ||||
|     - name: Test dependency resolution | ||||
|       run: | | ||||
|         echo "Testing dependency resolution..." | ||||
|          | ||||
|         # Test that all workspace dependencies resolve correctly | ||||
|         cargo tree --workspace > /dev/null | ||||
|         echo "✅ All dependencies resolve correctly" | ||||
|          | ||||
|         # Test that there are no dependency conflicts | ||||
|         cargo check --workspace | ||||
|         echo "✅ No dependency conflicts" | ||||
|      | ||||
|     - name: Generate publishing report | ||||
|       if: always() | ||||
|       run: | | ||||
|         echo "## 🧪 Publishing Setup Test Report" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "### ✅ Tests Passed" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- Workspace structure validation" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- Feature configuration testing" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- Dry-run publishing simulation" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- Publishing script validation" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- Version consistency check" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- Metadata completeness verification" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "- Dependency resolution testing" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "### 📦 Ready for Publishing" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "All SAL crates are ready for publishing to crates.io!" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "**Individual Crates:** 13 modules" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "**Meta-crate:** sal with optional features" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "**Binary:** herodo script executor" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "### 🚀 Next Steps" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "1. Create a release tag (e.g., v0.1.0)" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "2. The publish workflow will automatically trigger" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "3. All crates will be published to crates.io" >> $GITHUB_STEP_SUMMARY | ||||
|         echo "4. Users can install with: \`cargo add sal-os\` or \`cargo add sal --features all\`" >> $GITHUB_STEP_SUMMARY | ||||
		Reference in New Issue
	
	Block a user