feat: restore MiniMax M2.5 free default model #100
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Rust CI/CD Pipeline | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - 'rust/**' | |
| - 'scripts/**' | |
| - '.github/workflows/rust.yml' | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| paths: | |
| - 'rust/**' | |
| - 'scripts/**' | |
| - '.github/workflows/rust.yml' | |
| workflow_dispatch: | |
| inputs: | |
| bump_type: | |
| description: 'Version bump type' | |
| required: true | |
| type: choice | |
| options: | |
| - patch | |
| - minor | |
| - major | |
| description: | |
| description: 'Release description (optional)' | |
| required: false | |
| type: string | |
| concurrency: | |
| group: rust-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| CARGO_TERM_COLOR: always | |
| # Note: -Dwarnings is disabled while Rust implementation is WIP | |
| # Enable later with: RUSTFLAGS: -Dwarnings | |
| jobs: | |
| # Changelog fragment check - only runs on PRs | |
| changelog-check: | |
| name: Changelog Fragment Check | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Check for changelog fragments | |
| run: | | |
| # Get list of fragment files (excluding README) | |
| FRAGMENTS=$(find rust/changelog.d -name "*.md" ! -name "README.md" 2>/dev/null | wc -l) | |
| # Get changed files in PR | |
| CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD) | |
| # Check if any Rust source files changed | |
| SOURCE_CHANGED=$(echo "$CHANGED_FILES" | grep -E "^rust/(src/|tests/|Cargo\.toml)" | wc -l) | |
| if [ "$SOURCE_CHANGED" -gt 0 ] && [ "$FRAGMENTS" -eq 0 ]; then | |
| echo "::warning::No changelog fragment found. Please add a changelog entry in rust/changelog.d/" | |
| echo "" | |
| echo "To create a changelog fragment:" | |
| echo " touch rust/changelog.d/\$(date +%Y%m%d_%H%M%S)_description.md" | |
| echo "" | |
| echo "See rust/changelog.d/README.md for more information." | |
| # Note: This is a warning, not a failure, to allow flexibility | |
| exit 0 | |
| fi | |
| echo "Changelog check passed" | |
| # Lint and format check | |
| lint: | |
| name: Lint and Format Check | |
| runs-on: ubuntu-latest | |
| needs: [changelog-check] | |
| if: always() && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || needs.changelog-check.result == 'success' || needs.changelog-check.result == 'skipped') | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt, clippy | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '24.x' | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| rust/target | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('rust/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo- | |
| - name: Check formatting | |
| run: cargo fmt --all -- --check | |
| working-directory: rust | |
| - name: Run Clippy | |
| run: cargo clippy --all-targets --all-features | |
| working-directory: rust | |
| - name: Check file size limit | |
| run: node scripts/check-file-size.mjs | |
| # Test on multiple platforms | |
| test: | |
| name: Test (${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| needs: [changelog-check] | |
| if: always() && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || needs.changelog-check.result == 'success' || needs.changelog-check.result == 'skipped') | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # Note: Windows skipped while bash tool tests use Unix-specific commands | |
| os: [ubuntu-latest, macos-latest] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| rust/target | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('rust/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo- | |
| - name: Run tests | |
| run: cargo test --all-features --verbose | |
| working-directory: rust | |
| # Note: Doc tests skipped - this is a binary crate without lib target | |
| # Build package - only runs if lint and test pass | |
| build: | |
| name: Build Package | |
| runs-on: ubuntu-latest | |
| needs: [lint, test] | |
| if: always() && needs.lint.result == 'success' && needs.test.result == 'success' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| rust/target | |
| key: ${{ runner.os }}-cargo-build-${{ hashFiles('rust/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-build- | |
| - name: Check package | |
| run: cargo package --list | |
| working-directory: rust | |
| - name: Build release | |
| run: cargo build --release --verbose | |
| working-directory: rust | |
| # Automatic release on push to main using changelog fragments | |
| auto-release: | |
| name: Auto Release | |
| needs: [lint, test, build] | |
| # Use always() to ensure this job runs even when changelog-check was skipped (on push events) | |
| # Without always(), GitHub Actions skips jobs when any transitive dependency was skipped | |
| if: always() && github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.lint.result == 'success' && needs.test.result == 'success' && needs.build.result == 'success' | |
| runs-on: ubuntu-latest | |
| concurrency: | |
| group: release-main | |
| cancel-in-progress: false | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '24.x' | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Recover missing GitHub release for current version | |
| id: recover | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| CURRENT_VERSION=$(grep -Po '(?<=^version = ")[^"]*' rust/Cargo.toml) | |
| TAG_EXISTS=false | |
| RELEASE_EXISTS=false | |
| if git rev-parse "rust-v$CURRENT_VERSION" >/dev/null 2>&1; then | |
| TAG_EXISTS=true | |
| fi | |
| if gh api "repos/${{ github.repository }}/releases/tags/rust-v$CURRENT_VERSION" --silent 2>/dev/null; then | |
| RELEASE_EXISTS=true | |
| fi | |
| if [ "$TAG_EXISTS" = "true" ] && [ "$RELEASE_EXISTS" = "false" ]; then | |
| echo "Recovering: tag rust-v$CURRENT_VERSION exists but GitHub release is missing" | |
| node scripts/create-github-release.mjs \ | |
| --release-version "$CURRENT_VERSION" \ | |
| --repository "${{ github.repository }}" \ | |
| --prefix "rust-" | |
| node scripts/format-github-release.mjs \ | |
| --release-version "$CURRENT_VERSION" \ | |
| --repository "${{ github.repository }}" \ | |
| --commit-sha "$(git rev-list -1 rust-v$CURRENT_VERSION)" \ | |
| --prefix "rust-" | |
| echo "recovered=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "No recovery needed (tag=$TAG_EXISTS, release=$RELEASE_EXISTS)" | |
| echo "recovered=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Determine bump type from changelog fragments | |
| id: bump_type | |
| run: node scripts/rust-get-bump-type.mjs | |
| - name: Check if version already released or no fragments | |
| id: check | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| CURRENT_VERSION=$(grep -Po '(?<=^version = ")[^"]*' rust/Cargo.toml) | |
| # Check if version is published on crates.io (source of truth for publish status) | |
| CRATE_NAME=$(grep -Po '(?<=^name = ")[^"]*' rust/Cargo.toml) | |
| HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://crates.io/api/v1/crates/$CRATE_NAME/$CURRENT_VERSION") | |
| CRATES_PUBLISHED=false | |
| if [ "$HTTP_STATUS" = "200" ]; then | |
| CRATES_PUBLISHED=true | |
| fi | |
| TAG_EXISTS=false | |
| if git rev-parse "rust-v$CURRENT_VERSION" >/dev/null 2>&1; then | |
| TAG_EXISTS=true | |
| fi | |
| RELEASE_EXISTS=false | |
| if gh api "repos/${{ github.repository }}/releases/tags/rust-v$CURRENT_VERSION" --silent 2>/dev/null; then | |
| RELEASE_EXISTS=true | |
| fi | |
| echo "Tag exists: $TAG_EXISTS, Release exists: $RELEASE_EXISTS, Crates.io published: $CRATES_PUBLISHED" | |
| if [ "${{ steps.bump_type.outputs.has_fragments }}" = "true" ]; then | |
| echo "Found changelog fragments, proceeding with release" | |
| echo "should_release=true" >> $GITHUB_OUTPUT | |
| echo "skip_bump=false" >> $GITHUB_OUTPUT | |
| elif [ "$TAG_EXISTS" = "true" ] && [ "$RELEASE_EXISTS" = "true" ] && [ "$CRATES_PUBLISHED" = "true" ]; then | |
| echo "No changelog fragments and rust-v$CURRENT_VERSION fully released (tag + GitHub release + crates.io)" | |
| echo "should_release=false" >> $GITHUB_OUTPUT | |
| elif [ "$TAG_EXISTS" = "true" ] && [ "$RELEASE_EXISTS" = "false" ]; then | |
| echo "Tag exists but GitHub release missing for rust-v$CURRENT_VERSION — recovering" | |
| echo "should_release=true" >> $GITHUB_OUTPUT | |
| echo "skip_bump=true" >> $GITHUB_OUTPUT | |
| elif [ "$TAG_EXISTS" = "false" ]; then | |
| echo "No changelog fragments but rust-v$CURRENT_VERSION not yet tagged" | |
| echo "should_release=true" >> $GITHUB_OUTPUT | |
| echo "skip_bump=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "Version rust-v$CURRENT_VERSION appears fully released" | |
| echo "should_release=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Collect changelog and bump version | |
| id: version | |
| if: steps.check.outputs.should_release == 'true' && steps.check.outputs.skip_bump != 'true' | |
| run: | | |
| node scripts/rust-version-and-commit.mjs \ | |
| --bump-type "${{ steps.bump_type.outputs.bump_type }}" | |
| - name: Get current version | |
| id: current_version | |
| if: steps.check.outputs.should_release == 'true' | |
| run: | | |
| CURRENT_VERSION=$(grep -Po '(?<=^version = ")[^"]*' rust/Cargo.toml) | |
| echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT | |
| - name: Build release | |
| if: steps.check.outputs.should_release == 'true' | |
| run: cargo build --release | |
| working-directory: rust | |
| - name: Publish to crates.io | |
| id: publish | |
| if: steps.check.outputs.should_release == 'true' | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN || secrets.CARGO_TOKEN }} | |
| run: node scripts/publish-to-crates.mjs --should-pull | |
| - name: Create GitHub Release | |
| if: steps.check.outputs.should_release == 'true' && (steps.publish.outputs.published == 'true' || steps.publish.outcome == 'success') | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| node scripts/create-github-release.mjs \ | |
| --release-version "${{ steps.current_version.outputs.version }}" \ | |
| --repository "${{ github.repository }}" \ | |
| --prefix "rust-" | |
| - name: Format GitHub release notes | |
| if: steps.check.outputs.should_release == 'true' && (steps.publish.outputs.published == 'true' || steps.publish.outcome == 'success') | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: node scripts/format-github-release.mjs --release-version "${{ steps.current_version.outputs.version }}" --repository "${{ github.repository }}" --commit-sha "${{ github.sha }}" --prefix "rust-" | |
| # Manual release via workflow_dispatch | |
| manual-release: | |
| name: Manual Release | |
| needs: [lint, test, build] | |
| # Use always() to ensure this job runs even when changelog-check was skipped | |
| if: always() && github.event_name == 'workflow_dispatch' && needs.lint.result == 'success' && needs.test.result == 'success' && needs.build.result == 'success' | |
| runs-on: ubuntu-latest | |
| concurrency: | |
| group: release-main | |
| cancel-in-progress: false | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '24.x' | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Collect changelog fragments | |
| run: | | |
| # Check if there are any fragments to collect | |
| FRAGMENTS=$(find rust/changelog.d -name "*.md" ! -name "README.md" 2>/dev/null | wc -l) | |
| if [ "$FRAGMENTS" -gt 0 ]; then | |
| echo "Found $FRAGMENTS changelog fragment(s), collecting..." | |
| node scripts/rust-collect-changelog.mjs | |
| else | |
| echo "No changelog fragments found, skipping collection" | |
| fi | |
| - name: Version and commit | |
| id: version | |
| run: | | |
| node scripts/rust-version-and-commit.mjs \ | |
| --bump-type "${{ github.event.inputs.bump_type }}" \ | |
| --description "${{ github.event.inputs.description }}" | |
| - name: Build release | |
| if: steps.version.outputs.version_committed == 'true' || steps.version.outputs.already_released == 'true' | |
| run: cargo build --release | |
| working-directory: rust | |
| - name: Publish to crates.io | |
| id: publish | |
| if: steps.version.outputs.version_committed == 'true' || steps.version.outputs.already_released == 'true' | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN || secrets.CARGO_TOKEN }} | |
| run: node scripts/publish-to-crates.mjs | |
| - name: Create GitHub Release | |
| if: steps.publish.outputs.published == 'true' || steps.publish.outcome == 'success' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| node scripts/create-github-release.mjs \ | |
| --release-version "${{ steps.version.outputs.new_version }}" \ | |
| --repository "${{ github.repository }}" \ | |
| --prefix "rust-" | |
| - name: Format GitHub release notes | |
| if: steps.publish.outputs.published == 'true' || steps.publish.outcome == 'success' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: node scripts/format-github-release.mjs --release-version "${{ steps.version.outputs.new_version }}" --repository "${{ github.repository }}" --commit-sha "${{ github.sha }}" --prefix "rust-" |