Run tests Linux multiarch #164
This file contains 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: Run tests Linux multiarch | |
on: | |
workflow_call: | |
pull_request: | |
schedule: | |
# Every day at 2 AM UTC | |
- cron: "0 2 * * *" | |
workflow_dispatch: | |
concurrency: | |
group: linux-multiarch-${{ github.head_ref }}-${{ github.event_name }} | |
cancel-in-progress: true | |
jobs: | |
# Build testing image that would be used to build and run against different platforms | |
# Currently only Linux x64 is tested | |
build-image: | |
if: "github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' || ((github.event_name == 'schedule' || github.event_name == 'workflow_call') && github.repository == 'scala-native/scala-native')" | |
name: Build image | |
runs-on: ubuntu-22.04 | |
outputs: | |
image-name: ${{ steps.build-image.outputs.image-base-name }} | |
strategy: | |
matrix: | |
arch: [linux-arm64, linux-x86] | |
steps: | |
- uses: actions/checkout@v4 | |
# In order to minimize time spend in image build loading we're caching directory of local repository | |
# Starting local registry from cache is faster then loading image tars | |
# https://dev.to/dtinth/caching-docker-builds-in-github-actions-which-approach-is-the-fastest-a-research-18ei | |
# This and next stage (start registry) should be used in every step using built images | |
# Images are cached based on content of Dockerfile | |
# Cache automatically saves content specified paths after executing all steps defined after this one. | |
# It will not update cache on hit. | |
- name: Cache docker | |
uses: actions/cache@v4 | |
with: | |
path: /tmp/docker-registry | |
key: docker-registry-${{ hashFiles('ci-docker/Dockerfile') }}-${{matrix.arch}} | |
# Builds images and saves image base name in output - it allows to re-use it in other steps. | |
- name: Build image | |
id: build-image | |
run: | | |
imageBase="scala-native-testing" | |
imageName="${imageBase}:${{ matrix.arch }}" | |
echo "image-base-name=${imageBase}" >> $GITHUB_OUTPUT | |
echo "image-full-name=${imageName}" >> $GITHUB_OUTPUT | |
. ./ci-docker/env/${{matrix.arch}} | |
docker run -d -p 5000:5000 \ | |
--restart=always \ | |
--name registry \ | |
-v /tmp/docker-registry:/var/lib/registry \ | |
registry:2 && npx wait-on tcp:5000 | |
docker pull localhost:5000/${imageName} || { \ | |
docker buildx ls | |
docker run --privileged --rm tonistiigi/binfmt --install all && \ | |
docker buildx build \ | |
-t ${imageName} \ | |
--cache-from=localhost:5000/${imageName} \ | |
--build-arg BASE_IMAGE=$BASE_IMAGE \ | |
--build-arg LLVM_VERSION=$LLVM_VERSION \ | |
--build-arg BUILD_DEPS="${BUILD_DEPS}" \ | |
--platform ${BUILD_PLATFORM} \ | |
ci-docker && \ | |
docker tag $imageName localhost:5000/${imageName} && \ | |
docker push localhost:5000/${imageName} | |
} | |
#Main tests grid. Builds and runs tests agains multiple combination of GC, Build mode and Scala Version | |
#It can be extended to test against different OS and Arch settings | |
test-runtime: | |
name: Test runtime | |
if: "github.event_name == 'pull_request' || ((github.event_name == 'schedule' || github.event_name == 'workflow_call') && github.repository == 'scala-native/scala-native')" | |
runs-on: ubuntu-22.04 | |
needs: build-image | |
env: | |
ENABLE_EXPERIMENTAL_COMPILER: true | |
SCALANATIVE_TEST_PREFETCH_DEBUG_INFO: 1 | |
strategy: | |
fail-fast: false | |
matrix: | |
arch: [linux-arm64, linux-x86] | |
scala: [3, 3-next] | |
build-mode: [debug, release-fast] | |
lto: [none, thin] | |
gc: [boehm, immix, commix] | |
exclude: | |
# LTO is broken on linux-x86/llvm-10 | |
- arch: linux-x86 | |
lto: thin | |
# Release without LTO produces 1 big file taking long to compile, especially when emulated | |
- build-mode: release-fast | |
lto: none | |
- build-mode: release-size | |
lto: none | |
- build-mode: debug | |
lto: thin | |
# Fails frequently | |
- gc: commix | |
lto: thin | |
# Reduce ammount of builds combinations | |
- gc: immix | |
lto: none | |
- gc: immix | |
build-mode: debug | |
- gc: commix | |
build-mode: debug | |
- gc: boehm | |
build-mode: release-fast | |
- gc: boehm | |
build-mode: release-size | |
- scala: 3-next | |
build-mode: debug | |
- scala: 3-next | |
lto: none | |
- scala: 3-next | |
gc: boehm | |
- scala: 3-next | |
gc: commix | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: ./.github/actions/linux-setup-env | |
with: | |
scala-version: ${{matrix.scala}} | |
- name: Cache docker | |
uses: actions/cache@v4 | |
with: | |
path: /tmp/docker-registry | |
key: docker-registry-${{ hashFiles('ci-docker/Dockerfile') }}-${{matrix.arch}} | |
- name: Prepare native config | |
shell: bash | |
# Following envs CROSS_ are always present in docker container | |
run: | | |
buildMode=${{matrix.build-mode}} | |
if [[ "$buildMode" == "release-fast" ]]; then | |
buildMode=releaseFast | |
elif [[ "$buildMode" == "release-size" ]]; then | |
buildMode=releaseSize | |
fi | |
SetConfigTemplate=$(cat << EOM | |
nativeConfig ~= { prev => | |
val sysRoot: List[String] = | |
if(Seq("linux-x86").contains("${{ matrix.arch }}")) Nil | |
else Option { | |
sys.process.stringSeqToProcess(Seq( | |
s"\${sys.env("CROSS_ROOT")}/bin/\${sys.env("CROSS_TRIPLE")}-gcc", | |
"-print-sysroot" | |
)).!!.trim | |
}.filter(_.nonEmpty) | |
.fold(List.empty[String]){ root => List( | |
s"--sysroot=\${root}", | |
s"--gcc-toolchain=\${sys.env("CROSS_ROOT")}" | |
)}; | |
prev | |
.withMode(scalanative.build.Mode.${buildMode}) | |
.withGC(scalanative.build.GC.${{matrix.gc}}) | |
.withLTO(scalanative.build.LTO.${{matrix.lto}}) | |
.withEmbedResources(true) | |
.withOptimize(true) | |
.withCheck(true) | |
.withCheckFatalWarnings(true) | |
.withTargetTriple(sys.env.get("CROSS_TRIPLE")) | |
.withMultithreading(${{ matrix.gc != 'commix' }}) | |
.withCompileOptions(_ ++ sysRoot ++ List("-fuse-ld=lld")) | |
.withLinkingOptions(_ ++ sysRoot ++ List("-fuse-ld=lld", "-latomic")) | |
} | |
EOM | |
) | |
echo set-native-config=${SetConfigTemplate} >> $GITHUB_ENV | |
# Conditionally disable some of the tests (Scala 2 only) | |
- name: Set filters for partests | |
shell: bash | |
if: ${{ !startsWith(matrix.scala, '3') }} | |
run: | | |
ignoredTestsFile=scala-partest-junit-tests/src/test/resources/${{matrix.scala}}/DenylistedTests.txt | |
echo "" >> ${ignoredTestsFile} | |
echo -e "scala/util/SortingTest.scala\n" >> ${ignoredTestsFile} | |
- name: Run tests | |
env: | |
SCALANATIVE_MODE: "${{matrix.build-mode}}" | |
SCALANATIVE_GC: "${{matrix.gc}}" | |
SCALANATIVE_LTO: "${{matrix.lto}}" | |
# Temporaly excluded due to failures in linux-x86, | |
# missing __mulodi4 symbol used in j.l.Math.addExact(Long,Long) | |
# testsExt${{env.project-version}}/test; | |
TEST_COMMAND: > | |
set sandbox.forBinaryVersion("${{env.binary-version}}")/${{env.set-native-config}}; | |
set tests.forBinaryVersion("${{env.binary-version}}")/${{env.set-native-config}}; | |
set junitTestOutputsNative.forBinaryVersion("${{env.binary-version}}")/${{env.set-native-config}}; | |
set scalaPartestJunitTests.forBinaryVersion("${{env.binary-version}}")/${{env.set-native-config}}; | |
show sandbox${{env.project-version}}/nativeConfig; | |
sandbox${{env.project-version}}/run; | |
testsJVM${{env.project-version}}/test; | |
tests${{env.project-version}}/test; | |
junitTestOutputsNative${{env.project-version}}/test; | |
scalaPartestJunitTests${{env.project-version}}/test | |
uses: nick-fields/retry@v3 | |
with: | |
timeout_minutes: 180 | |
max_attempts: 2 | |
retry_on: error | |
command: ./ci-docker/run-test-gha.sh "${{ needs.build-image.outputs.image-name }}:${{ matrix.arch }}" |