|
39 | 39 | - name: Checkout code |
40 | 40 | uses: actions/checkout@v4 |
41 | 41 |
|
| 42 | + - name: Get tag name |
| 43 | + id: tag |
| 44 | + shell: bash |
| 45 | + run: | |
| 46 | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then |
| 47 | + TAG="${{ github.event.inputs.tag }}" |
| 48 | + else |
| 49 | + TAG="${GITHUB_REF#refs/tags/}" |
| 50 | + fi |
| 51 | + # Remove 'v' prefix if present |
| 52 | + VERSION="${TAG#v}" |
| 53 | + echo "tag=$TAG" >> $GITHUB_OUTPUT |
| 54 | + echo "version=$VERSION" >> $GITHUB_OUTPUT |
| 55 | + echo "Tag: $TAG" |
| 56 | + echo "Version: $VERSION" |
| 57 | +
|
| 58 | + - name: Update version in Cargo.toml |
| 59 | + shell: bash |
| 60 | + env: |
| 61 | + VERSION: ${{ steps.tag.outputs.version }} |
| 62 | + run: | |
| 63 | + if [ -z "$VERSION" ]; then |
| 64 | + echo "Error: Version is empty" |
| 65 | + exit 1 |
| 66 | + fi |
| 67 | + |
| 68 | + # Use Python for cross-platform compatibility |
| 69 | + python3 << 'PYTHON_SCRIPT' |
| 70 | + import re |
| 71 | + import os |
| 72 | + |
| 73 | + version = os.environ['VERSION'] |
| 74 | + |
| 75 | + with open('Cargo.toml', 'r') as f: |
| 76 | + content = f.read() |
| 77 | + |
| 78 | + # Replace version line |
| 79 | + content = re.sub( |
| 80 | + r'^version = ".*"', |
| 81 | + f'version = "{version}"', |
| 82 | + content, |
| 83 | + flags=re.MULTILINE |
| 84 | + ) |
| 85 | + |
| 86 | + with open('Cargo.toml', 'w') as f: |
| 87 | + f.write(content) |
| 88 | + |
| 89 | + print(f"Updated Cargo.toml version to {version}") |
| 90 | + PYTHON_SCRIPT |
| 91 | + |
| 92 | + # Verify the change |
| 93 | + grep "^version = " Cargo.toml |
| 94 | +
|
42 | 95 | - name: Install Rust |
43 | 96 | uses: dtolnay/rust-toolchain@stable |
44 | 97 | with: |
@@ -258,6 +311,145 @@ jobs: |
258 | 311 | path: ${{ env.ARTIFACT_PATH }} |
259 | 312 | retention-days: 30 |
260 | 313 |
|
| 314 | + publish-crates: |
| 315 | + name: Publish to crates.io |
| 316 | + needs: build-and-release |
| 317 | + runs-on: ubuntu-latest |
| 318 | + permissions: |
| 319 | + contents: read |
| 320 | + |
| 321 | + steps: |
| 322 | + - name: Checkout code |
| 323 | + uses: actions/checkout@v4 |
| 324 | + |
| 325 | + - name: Check for CARGO_REGISTRY_TOKEN |
| 326 | + id: check_token |
| 327 | + shell: bash |
| 328 | + run: | |
| 329 | + if [ -n "${{ secrets.CARGO_REGISTRY_TOKEN }}" ]; then |
| 330 | + echo "token_exists=true" >> $GITHUB_OUTPUT |
| 331 | + else |
| 332 | + echo "token_exists=false" >> $GITHUB_OUTPUT |
| 333 | + echo "CARGO_REGISTRY_TOKEN is not set, skipping publish" |
| 334 | + fi |
| 335 | +
|
| 336 | + - name: Get tag name |
| 337 | + if: steps.check_token.outputs.token_exists == 'true' |
| 338 | + id: tag |
| 339 | + shell: bash |
| 340 | + run: | |
| 341 | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then |
| 342 | + TAG="${{ github.event.inputs.tag }}" |
| 343 | + else |
| 344 | + TAG="${GITHUB_REF#refs/tags/}" |
| 345 | + fi |
| 346 | + # Remove 'v' prefix if present |
| 347 | + VERSION="${TAG#v}" |
| 348 | + echo "tag=$TAG" >> $GITHUB_OUTPUT |
| 349 | + echo "version=$VERSION" >> $GITHUB_OUTPUT |
| 350 | + echo "Tag: $TAG" |
| 351 | + echo "Version: $VERSION" |
| 352 | +
|
| 353 | + - name: Update version in Cargo.toml |
| 354 | + if: steps.check_token.outputs.token_exists == 'true' |
| 355 | + shell: bash |
| 356 | + env: |
| 357 | + VERSION: ${{ steps.tag.outputs.version }} |
| 358 | + run: | |
| 359 | + if [ -z "$VERSION" ]; then |
| 360 | + echo "Error: Version is empty" |
| 361 | + exit 1 |
| 362 | + fi |
| 363 | + |
| 364 | + # Use Python for cross-platform compatibility |
| 365 | + python3 << 'PYTHON_SCRIPT' |
| 366 | + import re |
| 367 | + import os |
| 368 | + |
| 369 | + version = os.environ['VERSION'] |
| 370 | + |
| 371 | + with open('Cargo.toml', 'r') as f: |
| 372 | + content = f.read() |
| 373 | + |
| 374 | + # Replace version line |
| 375 | + content = re.sub( |
| 376 | + r'^version = ".*"', |
| 377 | + f'version = "{version}"', |
| 378 | + content, |
| 379 | + flags=re.MULTILINE |
| 380 | + ) |
| 381 | + |
| 382 | + with open('Cargo.toml', 'w') as f: |
| 383 | + f.write(content) |
| 384 | + |
| 385 | + print(f"Updated Cargo.toml version to {version}") |
| 386 | + PYTHON_SCRIPT |
| 387 | + |
| 388 | + # Verify the change |
| 389 | + grep "^version = " Cargo.toml |
| 390 | +
|
| 391 | + - name: Install Rust |
| 392 | + if: steps.check_token.outputs.token_exists == 'true' |
| 393 | + uses: dtolnay/rust-toolchain@stable |
| 394 | + |
| 395 | + - name: Configure Cargo registry token |
| 396 | + if: steps.check_token.outputs.token_exists == 'true' |
| 397 | + run: | |
| 398 | + echo "CARGO_REGISTRY_TOKEN=${{ secrets.CARGO_REGISTRY_TOKEN }}" >> $GITHUB_ENV |
| 399 | + env: |
| 400 | + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} |
| 401 | + |
| 402 | + - name: Publish to crates.io |
| 403 | + if: steps.check_token.outputs.token_exists == 'true' |
| 404 | + env: |
| 405 | + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} |
| 406 | + run: | |
| 407 | + set -e |
| 408 | + |
| 409 | + # Function to publish a crate, handling already-published versions gracefully |
| 410 | + publish_crate() { |
| 411 | + local crate=$1 |
| 412 | + echo "Publishing $crate..." |
| 413 | + if cargo publish -p "$crate" --token "$CARGO_REGISTRY_TOKEN" --no-verify 2>&1 | tee /tmp/publish_output.log; then |
| 414 | + echo "✓ Successfully published $crate" |
| 415 | + else |
| 416 | + # Check if the error is due to version already existing |
| 417 | + if grep -q "already uploaded" /tmp/publish_output.log || grep -q "already exists" /tmp/publish_output.log; then |
| 418 | + echo "⚠ $crate version already exists on crates.io, skipping" |
| 419 | + else |
| 420 | + echo "✗ Failed to publish $crate" |
| 421 | + exit 1 |
| 422 | + fi |
| 423 | + fi |
| 424 | + # Small delay to avoid rate limiting |
| 425 | + sleep 2 |
| 426 | + } |
| 427 | + |
| 428 | + # Publish crates in dependency order |
| 429 | + # Base crates first |
| 430 | + publish_crate rohas-parser |
| 431 | + publish_crate rohas-runtime |
| 432 | + publish_crate rohas-telemetry |
| 433 | + |
| 434 | + # Adapters (can be published in parallel, but do sequentially to avoid rate limits) |
| 435 | + publish_crate adapter-memory |
| 436 | + publish_crate adapter-nats |
| 437 | + publish_crate adapter-kafka |
| 438 | + publish_crate adapter-rabbitmq |
| 439 | + publish_crate adapter-aws |
| 440 | + publish_crate adapter-rocksdb |
| 441 | + |
| 442 | + # Codegen and engine (depend on parser/runtime) |
| 443 | + publish_crate rohas-codegen |
| 444 | + publish_crate rohas-engine |
| 445 | + publish_crate rohas-cron |
| 446 | + |
| 447 | + # CLI and dev-server (depend on everything) |
| 448 | + publish_crate rohas-dev-server |
| 449 | + publish_crate rohas-cli |
| 450 | + |
| 451 | + echo "✓ All crates published successfully!" |
| 452 | +
|
261 | 453 | create-release: |
262 | 454 | name: Create Release |
263 | 455 | needs: build-and-release |
|
0 commit comments