name: Release on: push: tags: - 'v*.*.*' workflow_dispatch: inputs: version: description: 'Version to release (e.g., 1.0.0)' required: true type: string env: CARGO_TERM_COLOR: always RUST_BACKTRACE: 1 jobs: # Create GitHub release create-release: name: Create Release runs-on: ubuntu-latest outputs: version: ${{ steps.version.outputs.version }} upload_url: ${{ steps.create_release.outputs.upload_url }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Get version id: version run: | if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then VERSION="${{ github.event.inputs.version }}" else VERSION=${GITHUB_REF#refs/tags/v} fi echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" - name: Generate changelog id: changelog run: | # Install git-cliff if needed if ! command -v git-cliff &> /dev/null; then cargo install git-cliff fi # Generate changelog git-cliff --latest --strip all > CHANGELOG.md echo "Generated changelog:" cat CHANGELOG.md - name: Create GitHub release id: create_release uses: actions/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: v${{ steps.version.outputs.version }} release_name: Release v${{ steps.version.outputs.version }} body_path: CHANGELOG.md draft: false prerelease: false # Build release binaries build-release: name: Build Release (${{ matrix.target }}) needs: create-release runs-on: ${{ matrix.os }} strategy: matrix: include: - os: ubuntu-latest target: x86_64-unknown-linux-gnu artifact_name: midstream-linux-x86_64 - os: ubuntu-latest target: aarch64-unknown-linux-gnu artifact_name: midstream-linux-aarch64 - os: macos-latest target: x86_64-apple-darwin artifact_name: midstream-macos-x86_64 - os: macos-latest target: aarch64-apple-darwin artifact_name: midstream-macos-aarch64 - os: windows-latest target: x86_64-pc-windows-msvc artifact_name: midstream-windows-x86_64 steps: - uses: actions/checkout@v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.target }} - name: Setup cache uses: Swatinem/rust-cache@v2 with: shared-key: "release-${{ matrix.target }}" - name: Install cross-compilation tools (Linux ARM) if: matrix.target == 'aarch64-unknown-linux-gnu' run: | sudo apt-get update sudo apt-get install -y gcc-aarch64-linux-gnu - name: Build release binary run: cargo build --release --target ${{ matrix.target }} --all-features - name: Package binary (Unix) if: matrix.os != 'windows-latest' run: | cd target/${{ matrix.target }}/release tar czf ${{ matrix.artifact_name }}.tar.gz midstream mv ${{ matrix.artifact_name }}.tar.gz ../../../ - name: Package binary (Windows) if: matrix.os == 'windows-latest' run: | cd target/${{ matrix.target }}/release 7z a ${{ matrix.artifact_name }}.zip midstream.exe move ${{ matrix.artifact_name }}.zip ../../../ - name: Upload release asset uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ needs.create-release.outputs.upload_url }} asset_path: ./${{ matrix.artifact_name }}.${{ matrix.os == 'windows-latest' && 'zip' || 'tar.gz' }} asset_name: ${{ matrix.artifact_name }}.${{ matrix.os == 'windows-latest' && 'zip' || 'tar.gz' }} asset_content_type: application/octet-stream # Publish crates to crates.io publish-crates: name: Publish to crates.io needs: create-release runs-on: ubuntu-latest if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') steps: - uses: actions/checkout@v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable - name: Setup cache uses: Swatinem/rust-cache@v2 with: shared-key: "publish" - name: Update crate versions run: | VERSION="${{ needs.create-release.outputs.version }}" # Update workspace crate versions for crate in temporal-compare nanosecond-scheduler temporal-attractor-studio temporal-neural-solver strange-loop; do sed -i "s/^version = \".*\"/version = \"$VERSION\"/" crates/$crate/Cargo.toml done # Update main crate version sed -i "s/^version = \".*\"/version = \"$VERSION\"/" Cargo.toml - name: Verify build after version update run: cargo build --workspace --all-features - name: Publish crates in dependency order env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} run: | # Publish in order of dependencies cargo publish -p temporal-compare --allow-dirty sleep 10 cargo publish -p nanosecond-scheduler --allow-dirty sleep 10 cargo publish -p temporal-attractor-studio --allow-dirty sleep 10 cargo publish -p temporal-neural-solver --allow-dirty sleep 10 cargo publish -p strange-loop --allow-dirty sleep 10 # Finally publish main crate cargo publish --allow-dirty # Update documentation update-docs: name: Update Documentation needs: [create-release, publish-crates] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable - name: Setup cache uses: Swatinem/rust-cache@v2 with: shared-key: "docs-release" - name: Build documentation run: cargo doc --workspace --all-features --no-deps - name: Add version badge to docs run: | VERSION="${{ needs.create-release.outputs.version }}" echo "
Version: $VERSION
" \ > target/doc/version.html - name: Deploy documentation uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./target/doc destination_dir: docs/v${{ needs.create-release.outputs.version }} - name: Update latest docs symlink run: | git checkout gh-pages ln -sfn v${{ needs.create-release.outputs.version }} docs/latest git add docs/latest git commit -m "Update latest docs to v${{ needs.create-release.outputs.version }}" git push # Notify on completion release-complete: name: Release Complete needs: [create-release, build-release, publish-crates, update-docs] runs-on: ubuntu-latest if: always() steps: - name: Check release status run: | if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]]; then echo "❌ Release process encountered errors" exit 1 fi echo "✅ Release v${{ needs.create-release.outputs.version }} completed successfully!" echo "📦 Crates published to crates.io" echo "📚 Documentation updated" echo "🎉 Binaries available on GitHub Releases"