1name: CI 2 3on: 4 merge_group: 5 pull_request: 6 branches: 7 - libc-0.2 8 9env: 10 CARGO_TERM_COLOR: always 11 CARGO_TERM_VERBOSE: true 12 LIBC_CI: 1 13 RUSTDOCFLAGS: -Dwarnings 14 RUSTFLAGS: -Dwarnings 15 RUST_BACKTRACE: full 16 17defaults: 18 run: 19 shell: bash 20 21jobs: 22 style_check: 23 name: Style check 24 runs-on: ubuntu-24.04 25 timeout-minutes: 10 26 steps: 27 - uses: actions/checkout@v4 28 - name: Setup Rust toolchain 29 run: ./ci/install-rust.sh && rustup component add rustfmt 30 - name: Check style 31 run: ./ci/style.sh 32 33 clippy: 34 name: Clippy on ${{ matrix.os }} 35 strategy: 36 matrix: 37 os: [ubuntu-24.04, macos-14, windows-2022] 38 runs-on: ${{ matrix.os }} 39 timeout-minutes: 10 40 steps: 41 - uses: actions/checkout@v4 42 - run: rustup update stable --no-self-update 43 - uses: Swatinem/rust-cache@v2 44 # Here we use the latest stable Rust toolchain already installed by GitHub 45 # Ideally we should run it for every target, but we cannot rely on unstable toolchains 46 # due to Clippy not being consistent between them. 47 - run: cargo clippy --workspace --exclude libc-test --exclude ctest-test --all-targets -- -D warnings 48 49 # This runs `cargo build --target ...` for all T1 and T2 targets` 50 verify_build: 51 name: Verify build 52 strategy: 53 matrix: 54 toolchain: [stable, nightly, 1.63.0] 55 os: [ubuntu-24.04, macos-14, windows-2022] 56 include: 57 - toolchain: beta 58 os: ubuntu-24.04 59 runs-on: ${{ matrix.os }} 60 timeout-minutes: 25 61 env: 62 TOOLCHAIN: ${{ matrix.toolchain }} 63 steps: 64 - uses: actions/checkout@v4 65 # Remove `-Dwarnings` at the MSRV since lints may be different or buffier 66 - name: Update RUSTFLAGS 67 run: | 68 set -eux 69 [ "${{ matrix.toolchain }}" = "1.63.0" ] && echo 'RUSTFLAGS=' >> "$GITHUB_ENV" || true 70 71 - name: Setup Rust toolchain 72 run: ./ci/install-rust.sh 73 74 # FIXME(ci): These `du` statements are temporary for debugging cache 75 - name: Target size before restoring cache 76 run: du -sh target | sort -k 2 || true 77 - uses: Swatinem/rust-cache@v2 78 with: 79 key: ${{ matrix.os }}-${{ matrix.toolchain }} 80 - name: Target size after restoring cache 81 run: du -sh target | sort -k 2 || true 82 83 - name: Execute build.sh 84 run: ./ci/verify-build.sh 85 - name: Target size after job completion 86 run: du -sh target | sort -k 2 87 88 test_tier1: 89 name: Test tier1 90 strategy: 91 matrix: 92 include: 93 - target: i686-unknown-linux-gnu 94 docker: true 95 os: ubuntu-24.04 96 - target: i686-unknown-linux-gnu 97 docker: true 98 os: ubuntu-24.04 99 artifact-tag: offset-bits64 100 env: 101 RUST_LIBC_UNSTABLE_GNU_FILE_OFFSET_BITS: 64 102 - target: x86_64-unknown-linux-gnu 103 docker: true 104 os: ubuntu-24.04 105 - target: aarch64-apple-darwin 106 os: macos-14 107 - target: x86_64-pc-windows-gnu 108 os: windows-2022 109 env: 110 ARCH_BITS: 64 111 ARCH: x86_64 112 - target: x86_64-pc-windows-msvc 113 os: windows-2022 114 # FIXME: It currently causes segfaults. 115 #- target: i686-pc-windows-gnu 116 # env: 117 # ARCH_BITS: 32 118 # ARCH: i686 119 - target: i686-pc-windows-msvc 120 os: windows-2022 121 runs-on: ${{ matrix.os }} 122 timeout-minutes: 25 123 env: 124 TARGET: ${{ matrix.target }} 125 steps: 126 - uses: actions/checkout@v4 127 - name: Setup Rust toolchain 128 run: ./ci/install-rust.sh 129 - uses: Swatinem/rust-cache@v2 130 with: 131 key: ${{ matrix.target }} 132 133 - name: Add matrix env variables to the environment 134 if: matrix.env 135 run: | 136 echo '${{ toJson(matrix.env) }}' | 137 jq -r 'to_entries | map("\(.key)=\(.value|tostring)") | .[]' >>$GITHUB_ENV 138 shell: bash 139 140 - name: Run natively 141 if: "!matrix.docker" 142 run: ./ci/run.sh ${{ matrix.target }} 143 - name: Run in Docker 144 if: "matrix.docker" 145 run: ./ci/run-docker.sh ${{ matrix.target }} 146 147 - name: Create CI artifacts 148 id: create_artifacts 149 if: always() 150 run: ./ci/create-artifacts.py 151 - uses: actions/upload-artifact@v4 152 if: always() && steps.create_artifacts.outcome == 'success' 153 with: 154 name: ${{ env.ARCHIVE_NAME }}-${{ matrix.target }}${{ matrix.artifact-tag && format('-{0}', matrix.artifact-tag) }} 155 path: ${{ env.ARCHIVE_PATH }} 156 retention-days: 5 157 158 test_tier2: 159 name: Test tier2 160 needs: [test_tier1, style_check] 161 runs-on: ubuntu-24.04 162 strategy: 163 fail-fast: true 164 max-parallel: 12 165 matrix: 166 target: 167 # FIXME(sparc): this takes much longer to run than any other job, put 168 # it first to make sure it gets a head start. 169 - sparc64-unknown-linux-gnu 170 - aarch64-linux-android 171 - aarch64-unknown-linux-gnu 172 - aarch64-unknown-linux-musl 173 - arm-linux-androideabi 174 - arm-unknown-linux-musleabihf 175 - i686-linux-android 176 - i686-unknown-linux-musl 177 - loongarch64-unknown-linux-gnu 178 - loongarch64-unknown-linux-musl 179 - powerpc64-unknown-linux-gnu 180 - powerpc64le-unknown-linux-gnu 181 - riscv64gc-unknown-linux-gnu 182 - s390x-unknown-linux-gnu 183 - wasm32-unknown-emscripten 184 - wasm32-wasip1 185 - wasm32-wasip2 186 - x86_64-linux-android 187 # FIXME: Exec format error (os error 8) 188 # - x86_64-unknown-linux-gnux32 189 - x86_64-unknown-linux-musl 190 # FIXME: It seems some items in `src/unix/mod.rs` 191 # aren't defined on redox actually. 192 # - x86_64-unknown-redox 193 include: 194 - target: arm-unknown-linux-gnueabihf 195 - target: arm-unknown-linux-gnueabihf 196 env: 197 RUST_LIBC_UNSTABLE_GNU_FILE_OFFSET_BITS: 64 198 artifact-tag: offset-bits64 199 - target: aarch64-unknown-linux-musl 200 env: 201 RUST_LIBC_UNSTABLE_MUSL_V1_2_3: 1 202 - target: arm-unknown-linux-musleabihf 203 env: 204 RUST_LIBC_UNSTABLE_MUSL_V1_2_3: 1 205 - target: i686-unknown-linux-musl 206 env: 207 RUST_LIBC_UNSTABLE_MUSL_V1_2_3: 1 208 - target: loongarch64-unknown-linux-musl 209 env: 210 RUST_LIBC_UNSTABLE_MUSL_V1_2_3: 1 211 # FIXME(ppc): SIGILL running tests, see 212 # https://github.com/rust-lang/libc/pull/4254#issuecomment-2636288713 213 # - target: powerpc-unknown-linux-gnu 214 # - target: powerpc-unknown-linux-gnu 215 # env: 216 # RUST_LIBC_UNSTABLE_GNU_FILE_OFFSET_BITS: 64 217 # artifact-tag: offset-bits64 218 timeout-minutes: 25 219 env: 220 TARGET: ${{ matrix.target }} 221 steps: 222 - uses: actions/checkout@v4 223 - name: Setup Rust toolchain 224 run: ./ci/install-rust.sh 225 - uses: Swatinem/rust-cache@v2 226 with: 227 key: ${{ matrix.target }} 228 229 - name: Add matrix env variables to the environment 230 if: matrix.env 231 run: | 232 echo '${{ toJson(matrix.env) }}' | 233 jq -r 'to_entries | map("\(.key)=\(.value|tostring)") | .[]' >>$GITHUB_ENV 234 shell: bash 235 236 - name: Execute run-docker.sh 237 run: ./ci/run-docker.sh ${{ matrix.target }} 238 239 - name: Create CI artifacts 240 id: create_artifacts 241 if: always() 242 run: ./ci/create-artifacts.py 243 - uses: actions/upload-artifact@v4 244 if: always() && steps.create_artifacts.outcome == 'success' 245 with: 246 name: ${{ env.ARCHIVE_NAME }}-${{ matrix.target }}${{ matrix.artifact-tag && format('-{0}', matrix.artifact-tag) }} 247 path: ${{ env.ARCHIVE_PATH }} 248 retention-days: 5 249 250 test_tier2_vm: 251 name: Test tier2 VM 252 needs: [test_tier1, style_check] 253 runs-on: ubuntu-latest 254 strategy: 255 fail-fast: true 256 matrix: 257 target: 258 - x86_64-pc-solaris 259 timeout-minutes: 25 260 steps: 261 - uses: actions/checkout@v4 262 - name: test on Solaris 263 uses: vmactions/solaris-vm@v1.1.3 264 with: 265 release: "11.4-gcc" 266 usesh: true 267 mem: 4096 268 copyback: false 269 prepare: | 270 set -x 271 source <(curl -s https://raw.githubusercontent.com/psumbera/solaris-rust/refs/heads/main/sh.rust-web-install) 272 rustc --version 273 uname -a 274 run: | 275 export PATH=$HOME/.rust_solaris/bin:$PATH 276 ./ci/run.sh ${{ matrix.target }} 277 278 # One job that "summarizes" the success state of this pipeline. This can then be added to branch 279 # protection, rather than having to add each job separately. 280 success: 281 name: success 282 runs-on: ubuntu-24.04 283 needs: 284 - style_check 285 - test_tier1 286 - test_tier2 287 - test_tier2_vm 288 - verify_build 289 - clippy 290 # GitHub branch protection is exceedingly silly and treats "jobs skipped because a dependency 291 # failed" as success. So we have to do some contortions to ensure the job fails if any of its 292 # dependencies fails. 293 if: always() # make sure this is never "skipped" 294 steps: 295 # Manually check the status of all dependencies. `if: failure()` does not work. 296 - name: check if any dependency failed 297 run: jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' 298