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 # FIXME(ppc): SIGILL running tests, see 200 # https://github.com/rust-lang/libc/pull/4254#issuecomment-2636288713 201 # - target: powerpc-unknown-linux-gnu 202 # - target: powerpc-unknown-linux-gnu 203 # env: 204 # RUST_LIBC_UNSTABLE_GNU_FILE_OFFSET_BITS: 64 205 # artifact-tag: offset-bits64 206 timeout-minutes: 25 207 env: 208 TARGET: ${{ matrix.target }} 209 steps: 210 - uses: actions/checkout@v4 211 - name: Setup Rust toolchain 212 run: ./ci/install-rust.sh 213 - uses: Swatinem/rust-cache@v2 214 with: 215 key: ${{ matrix.target }} 216 217 - name: Add matrix env variables to the environment 218 if: matrix.env 219 run: | 220 echo '${{ toJson(matrix.env) }}' | 221 jq -r 'to_entries | map("\(.key)=\(.value|tostring)") | .[]' >>$GITHUB_ENV 222 shell: bash 223 224 - name: Execute run-docker.sh 225 run: ./ci/run-docker.sh ${{ matrix.target }} 226 227 - name: Create CI artifacts 228 id: create_artifacts 229 if: always() 230 run: ./ci/create-artifacts.py 231 - uses: actions/upload-artifact@v4 232 if: always() && steps.create_artifacts.outcome == 'success' 233 with: 234 name: ${{ env.ARCHIVE_NAME }}-${{ matrix.target }}${{ matrix.artifact-tag && format('-{0}', matrix.artifact-tag) }} 235 path: ${{ env.ARCHIVE_PATH }} 236 retention-days: 5 237 238 test_tier2_vm: 239 name: Test tier2 VM 240 needs: [test_tier1, style_check] 241 runs-on: ubuntu-latest 242 strategy: 243 fail-fast: true 244 matrix: 245 target: 246 - x86_64-pc-solaris 247 timeout-minutes: 25 248 steps: 249 - uses: actions/checkout@v4 250 - name: test on Solaris 251 uses: vmactions/solaris-vm@v1.1.3 252 with: 253 release: "11.4-gcc" 254 usesh: true 255 mem: 4096 256 copyback: false 257 prepare: | 258 set -x 259 source <(curl -s https://raw.githubusercontent.com/psumbera/solaris-rust/refs/heads/main/sh.rust-web-install) 260 rustc --version 261 uname -a 262 run: | 263 export PATH=$HOME/.rust_solaris/bin:$PATH 264 ./ci/run.sh ${{ matrix.target }} 265 266 # One job that "summarizes" the success state of this pipeline. This can then be added to branch 267 # protection, rather than having to add each job separately. 268 success: 269 name: success 270 runs-on: ubuntu-24.04 271 needs: 272 - style_check 273 - test_tier1 274 - test_tier2 275 - test_tier2_vm 276 - verify_build 277 - clippy 278 # GitHub branch protection is exceedingly silly and treats "jobs skipped because a dependency 279 # failed" as success. So we have to do some contortions to ensure the job fails if any of its 280 # dependencies fails. 281 if: always() # make sure this is never "skipped" 282 steps: 283 # Manually check the status of all dependencies. `if: failure()` does not work. 284 - name: check if any dependency failed 285 run: jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' 286