feat: reorganize repository with csharp and rust folders #4
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 | |
| RUSTFLAGS: -Dwarnings | |
| defaults: | |
| run: | |
| working-directory: rust | |
| jobs: | |
| # === DETECT CHANGES - determines which jobs should run === | |
| detect-changes: | |
| name: Detect Changes | |
| runs-on: ubuntu-latest | |
| if: github.event_name != 'workflow_dispatch' | |
| outputs: | |
| rs-changed: ${{ steps.changes.outputs.rs-changed }} | |
| toml-changed: ${{ steps.changes.outputs.toml-changed }} | |
| mjs-changed: ${{ steps.changes.outputs.mjs-changed }} | |
| docs-changed: ${{ steps.changes.outputs.docs-changed }} | |
| workflow-changed: ${{ steps.changes.outputs.workflow-changed }} | |
| any-code-changed: ${{ steps.changes.outputs.any-code-changed }} | |
| rust-code-changed: ${{ steps.changes.outputs.rust-code-changed }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20.x' | |
| - name: Detect changes | |
| id: changes | |
| working-directory: . | |
| env: | |
| GITHUB_EVENT_NAME: ${{ github.event_name }} | |
| GITHUB_BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| GITHUB_HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| run: node scripts/detect-code-changes.mjs | |
| # === CHANGELOG CHECK - only runs on PRs with code changes === | |
| changelog: | |
| name: Changelog Fragment Check | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes] | |
| if: github.event_name == 'pull_request' && needs.detect-changes.outputs.rust-code-changed == 'true' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Check for changelog fragments | |
| working-directory: . | |
| run: | | |
| # Get list of fragment files (excluding README and template) | |
| FRAGMENTS=$(find rust/changelog.d -name "*.md" ! -name "README.md" 2>/dev/null | wc -l) | |
| if [ "$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 " Create a new .md file in rust/changelog.d/ with your changes" | |
| 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 - found $FRAGMENTS fragment(s)" | |
| # === LINT AND FORMAT CHECK === | |
| lint: | |
| name: Lint and Format Check | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes] | |
| if: | | |
| github.event_name == 'push' || | |
| github.event_name == 'workflow_dispatch' || | |
| needs.detect-changes.outputs.rs-changed == 'true' || | |
| needs.detect-changes.outputs.toml-changed == 'true' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt, clippy | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20.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 | |
| - name: Run Clippy | |
| run: cargo clippy --all-targets --all-features | |
| - name: Check file size limit | |
| working-directory: . | |
| run: node scripts/check-file-size.mjs --lang rust | |
| # === TEST === | |
| test: | |
| name: Test (${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| needs: [detect-changes, changelog] | |
| if: always() && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || needs.changelog.result == 'success' || needs.changelog.result == 'skipped') | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - 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 | |
| - name: Run doc tests | |
| run: cargo test --doc --verbose | |
| # === BUILD === | |
| 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@v4 | |
| - 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: Build release | |
| run: cargo build --release --verbose | |
| - name: Check package | |
| run: cargo package --list | |
| # === AUTO RELEASE === | |
| auto-release: | |
| name: Auto Release | |
| needs: [lint, test, build] | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20.x' | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Determine bump type from changelog fragments | |
| id: bump_type | |
| working-directory: . | |
| run: node scripts/get-bump-type.mjs --dir rust/changelog.d | |
| - name: Check if version already released or no fragments | |
| id: check | |
| run: | | |
| # Check if there are changelog fragments | |
| if [ "${{ steps.bump_type.outputs.has_fragments }}" != "true" ]; then | |
| # No fragments - check if current version tag exists | |
| CURRENT_VERSION=$(grep -Po '(?<=^version = ")[^"]*' Cargo.toml) | |
| if git rev-parse "rust-v$CURRENT_VERSION" >/dev/null 2>&1; then | |
| echo "No changelog fragments and rust-v$CURRENT_VERSION already released" | |
| echo "should_release=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "No changelog fragments but rust-v$CURRENT_VERSION not yet released" | |
| echo "should_release=true" >> $GITHUB_OUTPUT | |
| echo "skip_bump=true" >> $GITHUB_OUTPUT | |
| fi | |
| else | |
| echo "Found changelog fragments, proceeding with release" | |
| echo "should_release=true" >> $GITHUB_OUTPUT | |
| echo "skip_bump=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' | |
| working-directory: . | |
| run: | | |
| node scripts/version-and-commit-rust.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 = ")[^"]*' Cargo.toml) | |
| echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT | |
| - name: Build release | |
| if: steps.check.outputs.should_release == 'true' | |
| run: cargo build --release | |
| - name: Create GitHub Release | |
| if: steps.check.outputs.should_release == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| working-directory: . | |
| run: | | |
| node scripts/create-github-release.mjs \ | |
| --release-version "${{ steps.current_version.outputs.version }}" \ | |
| --repository "${{ github.repository }}" \ | |
| --tag-prefix "rust-v" | |
| # === MANUAL RELEASE === | |
| manual-release: | |
| name: Manual Release | |
| needs: [lint, test, build] | |
| if: github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20.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 | |
| working-directory: . | |
| 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/collect-changelog.mjs --dir rust/changelog.d --output rust/CHANGELOG.md | |
| else | |
| echo "No changelog fragments found, skipping collection" | |
| fi | |
| - name: Version and commit | |
| id: version | |
| working-directory: . | |
| run: | | |
| node scripts/version-and-commit-rust.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 | |
| - name: Create GitHub Release | |
| if: steps.version.outputs.version_committed == 'true' || steps.version.outputs.already_released == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| working-directory: . | |
| run: | | |
| node scripts/create-github-release.mjs \ | |
| --release-version "${{ steps.version.outputs.new_version }}" \ | |
| --repository "${{ github.repository }}" \ | |
| --tag-prefix "rust-v" |