Bump release to v0.34.4 #116
Workflow file for this run
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: Build Release Binaries | |
| on: | |
| push: | |
| tags: | |
| - 'v*' # Triggers on version tags like v0.7.0 | |
| workflow_dispatch: # Allows manual trigger from GitHub UI | |
| inputs: | |
| tag_name: | |
| description: 'Tag name for the release' | |
| required: false | |
| default: 'manual-build' | |
| permissions: | |
| contents: write | |
| packages: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| build: | |
| name: Build ${{ matrix.target }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # macOS Apple Silicon | |
| - os: macos-14 | |
| target: aarch64-apple-darwin | |
| use_cross: false | |
| # Linux x86_64 (musl for static binaries - works on all distros) | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-musl | |
| use_cross: false | |
| # Windows x86_64 | |
| - os: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| use_cross: false | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install cross-compilation tool | |
| if: matrix.use_cross | |
| run: | | |
| cargo install cross --git https://github.com/cross-rs/cross | |
| - name: Install musl tools (Linux musl) | |
| if: matrix.target == 'x86_64-unknown-linux-musl' && !matrix.use_cross | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y musl-tools | |
| - name: Install OpenSSL for Windows | |
| if: matrix.os == 'windows-latest' | |
| run: | | |
| vcpkg install openssl:x64-windows-static-md | |
| echo "OPENSSL_DIR=C:/vcpkg/installed/x64-windows-static-md" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
| echo "OPENSSL_ROOT_DIR=C:/vcpkg/installed/x64-windows-static-md" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
| echo "OPENSSL_INCLUDE_DIR=C:/vcpkg/installed/x64-windows-static-md/include" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
| echo "OPENSSL_LIB_DIR=C:/vcpkg/installed/x64-windows-static-md/lib" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
| echo "VCPKG_ROOT=C:/vcpkg" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
| - name: Cache cargo registry | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cargo/registry | |
| key: ${{ runner.os }}-${{ matrix.target }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-${{ matrix.target }}-cargo-registry- | |
| - name: Cache cargo index | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cargo/git | |
| key: ${{ runner.os }}-${{ matrix.target }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-${{ matrix.target }}-cargo-index- | |
| - name: Cache cargo build | |
| uses: actions/cache@v5 | |
| with: | |
| path: target | |
| key: ${{ runner.os }}-${{ matrix.target }}-cargo-build-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-${{ matrix.target }}-cargo-build- | |
| - name: Set binary extension | |
| id: binary_ext | |
| shell: bash | |
| run: | | |
| if [[ "${{ matrix.os }}" == "windows-latest" ]]; then | |
| echo "ext=.exe" >> $GITHUB_OUTPUT | |
| else | |
| echo "ext=" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Install SQLx CLI | |
| run: cargo install sqlx-cli --no-default-features --features sqlite | |
| - name: Setup database | |
| run: | | |
| sqlx database setup --source torc-server/migrations | |
| env: | |
| DATABASE_URL: sqlite:db/sqlite/dev.db | |
| - name: Build binaries (with cross) | |
| if: matrix.use_cross | |
| run: | | |
| cross build --release --target ${{ matrix.target }} --workspace --all-features | |
| - name: Build binaries (native) | |
| if: "!matrix.use_cross" | |
| run: | | |
| cargo build --workspace --all-features --release --target ${{ matrix.target }} | |
| - name: Create release archive | |
| shell: bash | |
| run: | | |
| mkdir -p release | |
| cd target/${{ matrix.target }}/release | |
| # Determine archive name | |
| if [[ "${{ matrix.os }}" == "windows-latest" ]]; then | |
| ARCHIVE_NAME="torc-${{ matrix.target }}.zip" | |
| 7z a ../../../release/$ARCHIVE_NAME torc.exe torc-server.exe torc-slurm-job-runner.exe torc-dash.exe torc-htpasswd.exe torc-mcp-server.exe | |
| else | |
| ARCHIVE_NAME="torc-${{ matrix.target }}.tar.gz" | |
| tar czf ../../../release/$ARCHIVE_NAME torc torc-server torc-slurm-job-runner torc-dash torc-htpasswd torc-mcp-server | |
| fi | |
| cd ../../../release | |
| ls -lh | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: torc-${{ matrix.target }} | |
| path: release/* | |
| retention-days: 7 | |
| publish-crate: | |
| name: Publish to crates.io | |
| needs: build | |
| runs-on: ubuntu-latest | |
| if: startsWith(github.ref, 'refs/tags/') | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - name: Publish to crates.io | |
| run: cargo publish --locked | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | |
| SQLX_OFFLINE: "true" | |
| create-release: | |
| name: Create GitHub Release | |
| needs: build | |
| runs-on: ubuntu-latest | |
| if: startsWith(github.ref, 'refs/tags/') | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: artifacts | |
| - name: Display structure of downloaded files | |
| run: ls -R artifacts | |
| - name: Create Release | |
| uses: softprops/action-gh-release@v3 | |
| with: | |
| draft: true | |
| generate_release_notes: true | |
| files: | | |
| artifacts/torc-aarch64-apple-darwin/*.tar.gz | |
| artifacts/torc-x86_64-unknown-linux-musl/*.tar.gz | |
| artifacts/torc-x86_64-pc-windows-msvc/*.zip | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| docker: | |
| name: Build and Push Docker Image | |
| needs: build | |
| runs-on: ubuntu-latest | |
| if: startsWith(github.ref, 'refs/tags/') | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Extract version and image name | |
| id: meta | |
| run: | | |
| echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT | |
| echo "image=ghcr.io/${GITHUB_REPOSITORY,,}" >> $GITHUB_OUTPUT | |
| - name: Download Linux musl artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: torc-x86_64-unknown-linux-musl | |
| path: artifact | |
| - name: Extract binaries for Docker build | |
| run: tar xzf artifact/torc-x86_64-unknown-linux-musl.tar.gz -C artifact/ | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and push Docker image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| push: true | |
| build-args: VERSION=${{ steps.meta.outputs.version }} | |
| tags: | | |
| ${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.version }} | |
| ${{ steps.meta.outputs.image }}:latest | |
| deploy-docs: | |
| name: Deploy Versioned Docs | |
| runs-on: ubuntu-latest | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| concurrency: | |
| group: "pages" | |
| cancel-in-progress: false | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Extract version from tag | |
| id: version | |
| run: echo "version=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT | |
| - name: Setup mdBook | |
| uses: peaceiris/actions-mdbook@v2 | |
| with: | |
| mdbook-version: '0.4.52' | |
| - name: Install mdbook-mermaid | |
| run: cargo install mdbook-mermaid@0.16.0 | |
| - name: Build documentation | |
| run: | | |
| cd docs | |
| VERSION="${{ steps.version.outputs.version }}" | |
| # Override site-url and edit-url for this release version | |
| sed -i "s|site-url = \"/torc/\"|site-url = \"/torc/${VERSION}/\"|" book.toml | |
| sed -i "s|edit-url-template = \"https://github.com/NatLabRockies/torc/edit/main/docs/{path}\"|edit-url-template = \"https://github.com/NatLabRockies/torc/tree/${VERSION}/docs/{path}\"|" book.toml | |
| mdbook build | |
| - name: Check documentation links | |
| run: python3 .github/scripts/check-doc-links.py --internal --external | |
| - name: Setup gh-pages branch | |
| run: .github/scripts/gh-pages-setup.sh | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| - name: Deploy versioned docs | |
| run: | | |
| cd gh-pages-deploy | |
| VERSION="${{ steps.version.outputs.version }}" | |
| # Copy build into versioned subdirectory | |
| rm -rf "${VERSION}" | |
| cp -r ../docs/book "${VERSION}" | |
| # Root redirect (only if missing) | |
| if [ ! -f index.html ]; then | |
| cp ../docs/redirect.html index.html | |
| fi | |
| # Update versions.json using inline Python | |
| python3 << 'PYEOF' | |
| import json, os, re, shutil | |
| version = os.environ.get("VERSION", "${{ steps.version.outputs.version }}") | |
| versions_file = "versions.json" | |
| # Load existing or create new | |
| if os.path.exists(versions_file): | |
| with open(versions_file) as f: | |
| data = json.load(f) | |
| else: | |
| data = {"latest_release": None, "versions": []} | |
| # Ensure "latest (dev)" entry exists | |
| has_latest = any(v["version"] == "latest" for v in data["versions"]) | |
| if not has_latest: | |
| data["versions"].insert(0, { | |
| "version": "latest", | |
| "label": "latest (main)", | |
| "path": "/torc/latest/" | |
| }) | |
| # Remove existing entry for this version if present | |
| data["versions"] = [v for v in data["versions"] if v["version"] != version] | |
| # Add new version entry after "latest" | |
| new_entry = { | |
| "version": version, | |
| "label": version, | |
| "path": f"/torc/{version}/" | |
| } | |
| # Find insertion point: after "latest", before other versions | |
| insert_idx = 1 # after "latest" | |
| data["versions"].insert(insert_idx, new_entry) | |
| # Sort release versions by semver (descending), keep "latest" first | |
| def semver_key(v): | |
| if v["version"] == "latest": | |
| return (999, 999, 999) | |
| # Extracts major.minor.patch; pre-release suffixes are ignored for sorting | |
| m = re.match(r"v?(\d+)\.(\d+)\.(\d+)", v["version"]) | |
| if m: | |
| return (int(m.group(1)), int(m.group(2)), int(m.group(3))) | |
| return (0, 0, 0) | |
| data["versions"].sort(key=semver_key, reverse=True) | |
| # Update latest_release | |
| data["latest_release"] = version | |
| # Keep at most MAX_VERSIONS release versions (plus "latest"). | |
| # Older versions beyond this limit are pruned from versions.json and disk. | |
| MAX_VERSIONS = 5 | |
| release_versions = [v for v in data["versions"] if v["version"] != "latest"] | |
| if len(release_versions) > MAX_VERSIONS: | |
| pruned = release_versions[MAX_VERSIONS:] | |
| data["versions"] = [v for v in data["versions"] if v not in pruned] | |
| # Delete directories for pruned versions | |
| for p in pruned: | |
| dir_name = p["version"] | |
| if os.path.isdir(dir_name): | |
| shutil.rmtree(dir_name) | |
| print(f"Pruned old version: {dir_name}") | |
| with open(versions_file, "w") as f: | |
| json.dump(data, f, indent=2) | |
| f.write("\n") | |
| print(f"Updated versions.json: {json.dumps(data, indent=2)}") | |
| PYEOF | |
| env: | |
| VERSION: ${{ steps.version.outputs.version }} | |
| - name: Commit and push | |
| run: | | |
| cd gh-pages-deploy | |
| ../.github/scripts/gh-pages-commit.sh "Deploy docs ${VERSION} from ${GITHUB_SHA::8}" | |
| env: | |
| VERSION: ${{ steps.version.outputs.version }} |