floxide 3.2.2

A directed graph workflow system in Rust
Documentation
name: Release (Cargo Workspaces)
on:
  workflow_dispatch:
    inputs:
      release_type:
        description: "Semver bump level for the release."
        required: true
        type: choice
        options: [patch, minor, major]
      dry_run:
        description: "Set to true to simulate the release (no push or actual publish)."
        required: false
        default: false
        type: boolean
      skip_commit:
        description: "If true, skip version bump commit (assume versions already updated)."
        required: false
        default: false
        type: boolean

permissions:
  contents: write
  packages: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      # 1. Check out the repository
      - name: Checkout code
        uses: actions/checkout@v4
        # Use the default GITHUB_TOKEN for authentication (set by Actions)
        # This token will be used later for pushing commits and tags.

      # 2. Configure git author (required for committing via Actions)
      - name: Configure Git user
        run: |
          git config user.name "GitHub Actions"
          git config user.email "actions@github.com"

      # 3. Set up Rust toolchain (uses Rust stable by default)
      - name: Setup Rust
        uses: dtolnay/rust-toolchain@stable
        # uses: actions/setup-rust@v1
        # with:
        #   rust-version: stable

      # 3.5. Configure SSL certificates and cargo credentials
      - name: Configure SSL and cargo credentials
        run: |
          # Ensure SSL certificates are properly set up
          echo "Setting up SSL certificates..."
          sudo update-ca-certificates --fresh || true

          # Set up cargo credentials
          echo "Setting up cargo credentials..."
          mkdir -p ~/.cargo
          echo "[registry]" > ~/.cargo/credentials.toml
          echo "token = \"${{ secrets.CRATES_IO_TOKEN }}\"" >> ~/.cargo/credentials.toml
          chmod 600 ~/.cargo/credentials.toml

      # 4. Cache Rust build artifacts for faster builds (optional optimization)
      - name: Cache cargo build
        uses: Swatinem/rust-cache@v2

      # 5. Install cargo-workspaces CLI tool
      - name: Install cargo-workspaces
        uses: taiki-e/install-action@v2
        with:
          tool: cargo-workspaces

      # 6. Version bump, commit, and tag (without pushing yet) using cargo-workspaces
      - name: Bump version and tag commit
        if: ${{ inputs.skip_commit != 'true' }}
        run: |
          # Run version bump with exact version pins for dependencies
          cargo workspaces version ${{ inputs.release_type }} \
            --yes --allow-branch main \
            --exact \
            --no-git-push \
            ${{ inputs.dry_run == 'true' && '--dry-run' || '' }}
        env:
          CARGO_NET_EMPTY_VERSION_REPLACE: "true"
          # ^ (Optional environment fix: ensures cargo publishes use new versions if a crate had 0.0.0 version placeholders)
          # Fix SSL certificate issues
          NODE_EXTRA_CA_CERTS: /etc/ssl/certs/ca-certificates.crt
          # Use token for authentication
          CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}

      # 7. *Skip-commit mode:* If versions are already bumped manually, just create tag for current commit
      - name: Tag existing commit (skip version bump)
        if: ${{ inputs.skip_commit == 'true' }}
        run: |
          # Determine version for tagging (assuming a workspace with unified version)
          VERSION=$(cargo metadata --no-deps --format-version=1 | jq -r '.packages[0].version')
          git tag -a "v${VERSION}" -m "Release v${VERSION}"
          echo "Tagged current commit with v${VERSION}"

      # 8. Push commit and tags to remote (handle existing tags by force-pushing if needed)
      - name: Push changes to GitHub
        if: ${{ inputs.dry_run != 'true' }}
        env:
          # Use provided GITHUB_TOKEN (from checkout) for authentication (already configured by checkout action)
          TAG_REF: "refs/tags/$(git tag --sort=-creatordate -l | head -n1)"
        run: |
          echo "Pushing new commit to origin..."
          git push origin HEAD:${{ github.ref_name }}  # Push the new commit to the current branch
          echo "Pushing tags to origin..."
          git push origin --tags || { 
            echo "Tag push failed (tag may already exist). Forcing tag update..."; 
            git push origin --tags --force;  # Force-push tags if a conflict (existing tag) is detected
          }

      # 9. Publish crates to crates.io in dependency order
      - name: Publish to crates.io
        if: ${{ inputs.dry_run != 'true' }}
        env:
          CARGO_REGISTRIES_CRATES_IO_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}
          # Direct token for cargo login
          CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}
          # Fix SSL certificate issues
          NODE_EXTRA_CA_CERTS: /etc/ssl/certs/ca-certificates.crt
        run: |
          # Use --from-git to publish based on existing tags (skip versioning step)
          # With publish = false set for subcrates, only the main crate will be published.
          cargo workspaces publish \
            --from-git \
            --yes \
            --allow-branch main \
            --token "${{ secrets.CRATES_IO_TOKEN }}" \
            --no-verify \
            ${{ inputs.dry_run == 'true' && '--dry-run' || '' }}