diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..c09b770 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,106 @@ +name: Build + +on: + workflow_call: + +env: + CARGO_TERM_COLOR: always + +jobs: + build-windows: + name: Build Windows (x86_64) + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: x86_64-pc-windows-msvc + + - name: Rust cache + uses: Swatinem/rust-cache@v2 + + - name: Build (release) + run: cargo build --release --locked --target x86_64-pc-windows-msvc + + - name: Stage artifact + shell: pwsh + run: | + New-Item -ItemType Directory -Force -Path dist | Out-Null + Copy-Item -Force target\x86_64-pc-windows-msvc\release\tise.exe dist\tise-windows-x86_64.exe + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: windows + path: dist/tise-windows-x86_64.exe + if-no-files-found: error + + build-linux-gnu: + name: Build Linux glibc (x86_64) + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Rust cache + uses: Swatinem/rust-cache@v2 + + - name: Install Linux build deps + run: | + sudo apt-get update + sudo apt-get install -y \ + binutils \ + libx11-dev \ + libx11-xcb-dev \ + libxkbcommon-dev \ + libwayland-dev \ + libxcb-shape0-dev \ + libxcb-xfixes0-dev + + - name: Build (release) + run: cargo build --release --locked + + - name: Stage artifact + run: | + mkdir -p dist + cp target/release/tise dist/tise-linux-x86_64-gnu + chmod +x dist/tise-linux-x86_64-gnu + + - name: Verify GLIBC compatibility + shell: bash + run: | + set -euo pipefail + bin="dist/tise-linux-x86_64-gnu" + + echo "::group::ldd output" + ldd "$bin" || true + echo "::endgroup::" + + # Determine the newest GLIBC symbol version the binary requires. + # Building on an older runner keeps this requirement low and maximizes distro compatibility. + max_glibc=$(objdump -T "$bin" | grep -oE 'GLIBC_[0-9]+\.[0-9]+' | sort -V | tail -n1 || true) + echo "Max GLIBC required: ${max_glibc:-}" + if [[ -z "${max_glibc}" ]]; then + echo "No GLIBC symbol versions found (unexpected for a GNU build)." + exit 1 + fi + + # ubuntu-22.04 ships glibc 2.35; requiring newer likely breaks older distros. + allowed="GLIBC_2.35" + newest=$(printf '%s\n' "$allowed" "$max_glibc" | sort -V | tail -n1) + if [[ "$newest" != "$allowed" ]]; then + echo "Binary requires $max_glibc, which is newer than allowed $allowed" + exit 1 + fi + echo "OK: $max_glibc <= $allowed" + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: linux-gnu + path: dist/tise-linux-x86_64-gnu + if-no-files-found: error diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 10d44da..96f1a7e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,21 +1,18 @@ -name: CI +name: PremergeCI on: - push: pull_request: env: CARGO_TERM_COLOR: always jobs: - test: - name: fmt + clippy + test (${{ matrix.os }}) - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, windows-latest] + build: + uses: ./.github/workflows/build.yml + test: + name: fmt + clippy + test + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a0d7753..898a4aa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,95 +12,14 @@ env: CARGO_TERM_COLOR: always jobs: - build-windows: - name: Build Windows (x86_64) - runs-on: windows-latest - steps: - - uses: actions/checkout@v4 - - - name: Install Rust - uses: dtolnay/rust-toolchain@stable - with: - targets: x86_64-pc-windows-msvc - - - name: Rust cache - uses: Swatinem/rust-cache@v2 - - - name: Build (release) - run: cargo build --release --locked --target x86_64-pc-windows-msvc - - - name: Stage artifact - shell: pwsh - run: | - New-Item -ItemType Directory -Force -Path dist | Out-Null - Copy-Item -Force target\x86_64-pc-windows-msvc\release\tise.exe dist\tise-windows-x86_64.exe - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: windows - path: dist/tise-windows-x86_64.exe - if-no-files-found: error - - build-linux-musl: - name: Build Linux musl (x86_64) - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Install Rust - uses: dtolnay/rust-toolchain@stable - - - name: Install cross - uses: taiki-e/install-action@v2 - with: - tool: cross - - - name: Build (release, musl) - run: cross build --release --locked --target x86_64-unknown-linux-musl - - - name: Stage artifact - run: | - mkdir -p dist - cp target/x86_64-unknown-linux-musl/release/tise dist/tise-linux-x86_64-musl - chmod +x dist/tise-linux-x86_64-musl - - - name: Verify static linking (musl) - shell: bash - run: | - set -euo pipefail - bin="dist/tise-linux-x86_64-musl" - - echo "::group::file(1) output" - file "$bin" || true - echo "::endgroup::" - - # Accept either fully static or static-PIE. - file "$bin" | grep -Eiq 'statically linked|static-pie' - - echo "::group::ldd output" - set +e - out=$(ldd "$bin" 2>&1) - code=$? - set -e - echo "$out" - echo "ldd exit code: $code" - echo "::endgroup::" - - # For static binaries on glibc, ldd often prints "not a dynamic executable". - echo "$out" | grep -Eiq 'not a dynamic executable|statically linked' - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: linux-musl - path: dist/tise-linux-x86_64-musl - if-no-files-found: error + build: + uses: ./.github/workflows/build.yml publish: name: Publish GitHub Release runs-on: ubuntu-latest - needs: [build-windows, build-linux-musl] + needs: [build] + if: startsWith(github.ref, 'refs/tags/') steps: - name: Download artifacts uses: actions/download-artifact@v4 @@ -113,5 +32,5 @@ jobs: generate_release_notes: true files: | dist/windows/tise-windows-x86_64.exe - dist/linux-musl/tise-linux-x86_64-musl + dist/linux-gnu/tise-linux-x86_64 fail_on_unmatched_files: true