Release release/2025.11.5 #94
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: Release | |
| run-name: Release ${{ github.ref_name }} | |
| on: | |
| # Trigger when pushing to release branches | |
| push: | |
| branches: | |
| - 'release/**' | |
| # Allow manual triggering | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUST_BACKTRACE: 1 | |
| jobs: | |
| # 1. First, run tests and linting as a quality gate. | |
| test: | |
| name: Test & Lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Format check | |
| run: cargo fmt --all -- --check | |
| - name: Clippy | |
| run: cargo clippy --all-targets --all-features -- -D warnings | |
| - name: Run tests | |
| run: cargo test --all --locked | |
| # 2. Build all required binaries for different targets. | |
| # This job runs only after tests have passed. | |
| build: | |
| name: Build Binaries | |
| needs: test | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| asset_name_suffix: linux-x86_64 | |
| - os: macos-latest | |
| target: x86_64-apple-darwin | |
| asset_name_suffix: macos-x86_64 | |
| - os: macos-latest | |
| target: aarch64-apple-darwin | |
| asset_name_suffix: macos-arm64 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| key: ${{ matrix.target }} | |
| - name: Build main binary and plugins | |
| run: cargo build --release --target ${{ matrix.target }} --workspace | |
| - name: Strip binaries for size | |
| run: | | |
| if [[ "${{ runner.os }}" == "Linux" ]]; then | |
| strip target/${{ matrix.target }}/release/repos | |
| strip target/${{ matrix.target }}/release/repos-health | |
| else | |
| strip -x target/${{ matrix.target }}/release/repos | |
| strip -x target/${{ matrix.target }}/release/repos-health | |
| fi | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: build-artifacts-${{ matrix.asset_name_suffix }} | |
| path: | | |
| target/${{ matrix.target }}/release/repos | |
| target/${{ matrix.target }}/release/repos-health | |
| # 3. Create the universal macOS binary from the previously built artifacts. | |
| # This job is very fast as it does not re-compile anything. | |
| package-universal: | |
| name: Package Universal macOS | |
| needs: build | |
| runs-on: macos-latest | |
| steps: | |
| - name: Download macOS arm64 artifacts | |
| uses: actions/download-artifact@v6 | |
| with: | |
| name: build-artifacts-macos-arm64 | |
| path: arm64 | |
| - name: Download macOS x86_64 artifacts | |
| uses: actions/download-artifact@v6 | |
| with: | |
| name: build-artifacts-macos-x86_64 | |
| path: x86_64 | |
| - name: Create universal binaries | |
| run: | | |
| lipo -create -output repos arm64/repos x86_64/repos | |
| lipo -create -output repos-health arm64/repos-health x86_64/repos-health | |
| strip -x repos repos-health | |
| - name: Upload universal artifact | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: build-artifacts-macos-universal | |
| path: | | |
| repos | |
| repos-health | |
| # 4. Determine version, create the GitHub Release, and upload all artifacts. | |
| # This is the final publishing step. | |
| publish: | |
| name: Publish Release | |
| needs: [build, package-universal] | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.set-version.outputs.version }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Determine Version | |
| id: semver | |
| uses: PaulHatch/semantic-version@v5.4.0 | |
| with: | |
| tag_prefix: "v" | |
| major_pattern: "BREAKING CHANGE:" | |
| minor_pattern: "feat:" | |
| search_commit_body: true | |
| short_tags: false | |
| - name: Set VERSION from semantic-version | |
| id: set-version | |
| run: | | |
| VERSION="${{ steps.semver.outputs.version }}" | |
| echo "Using semantic version: $VERSION" | |
| echo "VERSION=$VERSION" >> $GITHUB_ENV | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| - name: Download all build artifacts | |
| uses: actions/download-artifact@v6 | |
| with: | |
| path: dist | |
| - name: Package artifacts for release | |
| id: package | |
| run: | | |
| VERSION=${{ env.VERSION }} | |
| # Package platform-specific artifacts (excludes universal which is handled separately) | |
| for dir in dist/build-artifacts-linux-* dist/build-artifacts-macos-x86_64 dist/build-artifacts-macos-arm64; do | |
| if [ -d "$dir" ]; then | |
| suffix=$(basename "$dir" | sed 's/build-artifacts-//') | |
| tar -czf "repos-${VERSION}-${suffix}.tar.gz" -C "$dir" repos | |
| tar -czf "repos-health-${VERSION}-${suffix}.tar.gz" -C "$dir" repos-health | |
| fi | |
| done | |
| # Package universal macOS artifacts separately | |
| if [ -d "dist/build-artifacts-macos-universal" ]; then | |
| tar -czf "repos-${VERSION}-macos-universal.tar.gz" -C "dist/build-artifacts-macos-universal" repos | |
| tar -czf "repos-health-${VERSION}-macos-universal.tar.gz" -C "dist/build-artifacts-macos-universal" repos-health | |
| fi | |
| # List final assets | |
| ls -lh *.tar.gz | |
| # Create space-separated list of all archives for upload | |
| ASSETS=$(ls *.tar.gz | tr '\n' ' ') | |
| echo "ASSETS<<EOF" >> $GITHUB_ENV | |
| echo "$ASSETS" >> $GITHUB_ENV | |
| echo "EOF" >> $GITHUB_ENV | |
| - name: Create GitHub Release and Upload Assets | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| token: ${{ secrets.PAT_TOKEN }} | |
| tag_name: v${{ env.VERSION }} | |
| name: Release v${{ env.VERSION }} | |
| generate_release_notes: true | |
| draft: true | |
| files: | | |
| *.tar.gz | |
| # 5. After a successful release, create a PR to merge the release branch | |
| # back into main and bump the version for the next development cycle. | |
| sync-main: | |
| name: Sync Back to Main | |
| needs: publish | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.PAT_TOKEN }} # Use PAT for creating PR | |
| - name: Configure Git | |
| run: | | |
| git config user.name "GitHub Action" | |
| git config user.email "action@github.com" | |
| - name: Create version bump branch from main | |
| id: versioning | |
| run: | | |
| RELEASE_VERSION=${{ needs.publish.outputs.version }} | |
| # Calculate next version (e.g., 0.1.0 -> 0.2.0-rc) | |
| MAJOR=$(echo "$RELEASE_VERSION" | cut -d. -f1) | |
| MINOR=$(echo "$RELEASE_VERSION" | cut -d. -f2) | |
| NEXT_MINOR=$((MINOR + 1)) | |
| NEXT_VERSION="${MAJOR}.${NEXT_MINOR}.0-rc" | |
| echo "NEXT_VERSION=${NEXT_VERSION}" >> $GITHUB_ENV | |
| BUMP_BRANCH="chore/version-bump-${NEXT_VERSION}" | |
| echo "BUMP_BRANCH=${BUMP_BRANCH}" >> $GITHUB_ENV | |
| # Create the new branch from the main branch | |
| git fetch origin main | |
| git checkout -b "$BUMP_BRANCH" origin/main | |
| - name: Update Cargo.toml and push branch | |
| run: | | |
| # Update version in Cargo.toml | |
| sed -i "s/^version = \".*\"/version = \"${{ env.NEXT_VERSION }}\"/" Cargo.toml | |
| # Commit changes | |
| git add Cargo.toml | |
| if git diff --cached --quiet; then | |
| echo "No changes to commit" | |
| else | |
| git commit -m "chore: bump version to ${{ env.NEXT_VERSION }}" | |
| fi | |
| # Delete remote branch if exists, then force push | |
| git push origin --delete "${{ env.BUMP_BRANCH }}" 2>/dev/null || true | |
| git push origin "${{ env.BUMP_BRANCH }}" | |
| - name: Create Pull Request | |
| env: | |
| GH_TOKEN: ${{ secrets.PAT_TOKEN }} | |
| run: | | |
| # Check if there are commits to PR | |
| git fetch origin main | |
| COMMITS_AHEAD=$(git rev-list --count origin/main.."${{ env.BUMP_BRANCH }}") | |
| if [ "$COMMITS_AHEAD" -eq "0" ]; then | |
| echo "No commits to create PR for - branch is up to date with main" | |
| exit 0 | |
| fi | |
| # Check if PR already exists | |
| EXISTING_PR=$(gh pr list --head "${{ env.BUMP_BRANCH }}" --base main --json number --jq '.[0].number' 2>/dev/null || echo "") | |
| if [ -n "$EXISTING_PR" ]; then | |
| echo "PR #$EXISTING_PR already exists, skipping creation" | |
| else | |
| gh pr create \ | |
| --base main \ | |
| --head "${{ env.BUMP_BRANCH }}" \ | |
| --title "chore: Post-release version bump to ${{ env.NEXT_VERSION }}" \ | |
| --body "This PR merges the changes from release \`${{ github.ref_name }}\` back into main and prepares for the next development cycle by bumping the version to \`${{ env.NEXT_VERSION }}\`." | |
| fi |