Skip to content

add alpine 3.12 and expect fails #93

add alpine 3.12 and expect fails

add alpine 3.12 and expect fails #93

name: Test-OpenCvSharp
on:
push:
branches: [ main, feature/docker ]
paths: [ '.github/workflows/test-opencvsharp.yml' ]
workflow_dispatch:
jobs:
build:
name: Build Test
runs-on: ${{ matrix.runs-on }}
defaults:
run:
shell: bash
strategy:
matrix:
include:
- { os: ubuntu.22.04, arch: x64, runs-on: ubuntu-22.04 }
- { os: ubuntu.22.04, arch: arm64, runs-on: ubuntu-22.04-arm }
- { os: win, arch: x64, runs-on: windows-2022 }
- { os: win, arch: x86, runs-on: windows-2022 }
- { os: win, arch: arm64, runs-on: windows-11-arm }
- { os: osx, arch: x64, runs-on: macos-13 }
- { os: osx, arch: arm64, runs-on: macos-14 }
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: oraclelinux:7 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: oraclelinux:7 }
- { os: rhel.8, arch: x64, runs-on: ubuntu-22.04, image: oraclelinux:8 }
- { os: rhel.8, arch: arm64, runs-on: ubuntu-22.04-arm, image: oraclelinux:8 }
- { os: alpine.3.22, arch: x64, runs-on: ubuntu-22.04, image: alpine:3.22 }
- { os: alpine.3.22, arch: arm64, runs-on: ubuntu-22.04-arm, image: alpine:3.22 }
- { os: android, arch: arm64, runs-on: ubuntu-24.04 }
- { os: android, arch: x64, runs-on: ubuntu-24.04 }
steps:
- name: Download OpenCvSharp Artifacts
env:
GH_TOKEN: ${{ github.token }}
run: |
echo "Fetching lastest run of opencvsharp.yml on branch ${{ github.ref_name }}"
RUN_ID=$(gh run list -R ${{ github.repository }} --workflow=opencvsharp.yml --branch=${{ github.ref_name }} --status=success --limit=1 --json databaseId | jq -r '.[0].databaseId')
echo "Latest opencvsharp run ID: $RUN_ID"
echo "Downloading artifact 'opencvsharp-${{ matrix.os }}-${{ matrix.arch }}' from run ${RUN_ID}"
gh run download -R ${{ github.repository }} $RUN_ID --name opencvsharp-${{ matrix.os }}-${{ matrix.arch }} --dir opencvsharp
echo "::group::OpenCvSharp Artifacts"
ls -lR opencvsharp
echo "::endgroup::"
- name: Create test.c
run: |
mkdir -p test
cat > test/test.c <<'EOF'
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
typedef long long uint64;
typedef int ExceptionStatus;
typedef struct { double val[4]; } MyCvScalar;
typedef struct cv_Mat cv_Mat;
#define CV_8UC3 16 /* 8-bit unsigned, 3 channels */
#define IMWRITE_JPEG_QUALITY 1
#define IMWRITE_WEBP_QUALITY 64
/* core */
extern uint64 core_Mat_sizeof(void);
extern ExceptionStatus core_Mat_new3(int rows,int cols,int type, MyCvScalar scalar, cv_Mat **returnValue);
extern ExceptionStatus core_Mat_delete(cv_Mat *self);
/* imgcodecs */
extern ExceptionStatus imgcodecs_imwrite(const char *filename, cv_Mat *img, int *params,int paramsLength,int *returnValue);
extern ExceptionStatus imgcodecs_imread (const char *filename,int flags, cv_Mat **returnValue);
static void CHECK_OK(ExceptionStatus st, const char *msg)
{
if(st != 0) { fprintf(stderr,"%s failed: %d\n", msg, st); exit(st); }
}
static void CHECK_BOOL(int ok, const char *msg)
{
if(!ok) { fprintf(stderr,"%s returned false\n", msg); exit(1); }
}
int main(void)
{
printf("sizeof(Mat) reported by native = %llu\n",
(unsigned long long)core_Mat_sizeof());
cv_Mat *img = NULL;
MyCvScalar black = {0};
CHECK_OK(core_Mat_new3(256, 256, CV_8UC3, black, &img), "core_Mat_new3");
unsigned char *data = NULL;
extern ExceptionStatus core_Mat_data(cv_Mat *self, unsigned char **returnValue);
CHECK_OK(core_Mat_data(img, &data), "core_Mat_data");
for(int y = 0; y < 256; ++y)
{
for(int x = 0; x < 256; ++x)
{
unsigned char *pix = data + (y*256 + x)*3;
pix[0] = (unsigned char)x;
pix[1] = (unsigned char)y;
pix[2] = 128;
}
}
int ok = 0;
CHECK_OK(imgcodecs_imwrite("test.png", img, NULL, 0, &ok), "imwrite PNG");
CHECK_BOOL(ok, "imwrite PNG");
printf("Image saved as test.png\n");
cv_Mat *img2 = NULL;
CHECK_OK(imgcodecs_imread("test.png", /*flags=*/1, &img2), "imread PNG");
printf("Image loaded from test.png\n");
int jpegParams[2] = { IMWRITE_JPEG_QUALITY, 90 };
CHECK_OK(imgcodecs_imwrite("test.jpg", img2,
jpegParams, 2, &ok), "imwrite JPG");
CHECK_BOOL(ok, "imwrite JPG");
printf("Image saved as test.jpg at quality: 90\n");
int webpParams[2] = { IMWRITE_WEBP_QUALITY, 90 };
CHECK_OK(imgcodecs_imwrite("test.webp", img2,
webpParams, 2, &ok), "imwrite WEBP");
CHECK_BOOL(ok, "imwrite WEBP");
printf("Image saved as test.webp at quality: 90\n");
core_Mat_delete(img);
core_Mat_delete(img2);
return 0;
}
EOF
cat test/test.c
- name: Setup MSVC(Windows only)
uses: ilammy/msvc-dev-cmd@v1
if: startsWith(matrix.os, 'win')
with:
arch: ${{ matrix.arch }}
- name: Pull Docker Image
if: matrix.image != ''
run: |
docker pull ${{ matrix.image }}
- name: Start Docker Container
if: matrix.image != ''
run: |
docker run -d --name builder -v "$PWD":${{ github.workspace }} -w ${{ github.workspace }} ${{ matrix.image }} tail -f /dev/null
- name: Install Dependencies in Docker Container
if: matrix.image != ''
run: |
if [[ "${{ matrix.os }}" == "centos.7" || "${{ matrix.os }}" =~ "rhel." ]]; then
script=$(
cat <<'EOS'
set -eux
yum install -y gcc
EOS
)
elif [[ "${{ matrix.os }}" =~ ^alpine ]]; then
script=$(
cat <<'EOS'
set -eux
apk add --no-cache gcc musl-dev
EOS
)
fi
echo "Executing script in Docker container: $script"
docker exec builder /bin/sh -c "$script"
- name: Build Test
run: |
script=$(
cat <<'EOS'
set -eux
cd test
if [[ "${{ runner.os }}" == Windows ]]; then
export MSYS2_ARG_CONV_EXCL="*"
cl /nologo /EHsc test.c ../opencvsharp/lib/OpenCvSharpExtern.lib /link /OUT:test.exe
elif [[ "${{ matrix.os }}" =~ ^osx ]]; then
gcc test.c -L../opencvsharp/lib -lOpenCvSharpExtern -Wl,-rpath,@loader_path -o test.exe
elif [[ "${{ matrix.os }}" == "centos.7" ]]; then
gcc -std=c99 test.c -L../opencvsharp/lib -lOpenCvSharpExtern -Wl,-rpath,'$ORIGIN' -o test.exe
elif [[ "${{ matrix.os }}" == "android" ]]; then
API=24
if [[ "${{ matrix.arch }}" == "arm64" ]]; then
CLANG=aarch64-linux-android${API}-clang
elif [[ "${{ matrix.arch }}" == "x64" ]]; then
CLANG=x86_64-linux-android${API}-clang
else
echo "Unsupported architecture for Android: ${{ matrix.arch }}"
exit 1
fi
$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/$CLANG test.c -L../opencvsharp/lib -lOpenCvSharpExtern -Wl,-rpath,'$ORIGIN' -o test.exe
else
gcc test.c -L../opencvsharp/lib -lOpenCvSharpExtern -Wl,-rpath,'$ORIGIN' -o test.exe
fi
ls -lR
EOS
)
if [[ "${{ matrix.image }}" == "" ]]; then
bash -c "$script"
else
docker exec builder /bin/sh -c "$script"
fi
- name: Copy opencvsharp/lib to test
run: |
cp -r opencvsharp/lib/* test
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: test-${{ matrix.os }}-${{ matrix.arch }}
path: test
android-x64-test:
name: Android x64 Test
runs-on: ubuntu-24.04
needs: build
steps:
- name: Download Artifacts
uses: actions/download-artifact@v4
with:
name: test-android-x64
path: test
- name: chmod+x
run: chmod +x test/test.exe
- name: Enable KVM group perms
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Run Test on Android
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 28
arch: x86_64
target: google_apis
script: |
adb push -a test /data/local/tmp/
adb shell 'cd /data/local/tmp/test && ./test.exe'
raw-test:
name: Raw Test
runs-on: ${{ matrix.runs-on }}
defaults:
run:
shell: bash
needs: build
strategy:
matrix:
include:
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04 }
- { os: centos.7, arch: x64, runs-on: ubuntu-24.04 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm }
- { os: centos.7, arch: arm64, runs-on: ubuntu-24.04-arm }
- { os: rhel.8, arch: x64, runs-on: ubuntu-22.04 }
- { os: rhel.8, arch: x64, runs-on: ubuntu-24.04 }
- { os: rhel.8, arch: arm64, runs-on: ubuntu-22.04-arm }
- { os: rhel.8, arch: arm64, runs-on: ubuntu-24.04-arm }
- { os: ubuntu.22.04, arch: x64, runs-on: ubuntu-22.04 }
- { os: ubuntu.22.04, arch: x64, runs-on: ubuntu-24.04 }
- { os: ubuntu.22.04, arch: arm64, runs-on: ubuntu-22.04-arm }
- { os: ubuntu.22.04, arch: arm64, runs-on: ubuntu-24.04-arm }
- { os: osx, arch: x64, runs-on: macos-13 }
- { os: osx, arch: arm64, runs-on: macos-14 }
- { os: osx, arch: arm64, runs-on: macos-15 }
- { os: win, arch: x64, runs-on: windows-2022 }
- { os: win, arch: x64, runs-on: windows-2025 }
- { os: win, arch: x86, runs-on: windows-2022 }
- { os: win, arch: x86, runs-on: windows-2025 }
- { os: win, arch: arm64, runs-on: windows-11-arm }
steps:
- name: Download Artifacts
uses: actions/download-artifact@v4
with:
name: test-${{ matrix.os }}-${{ matrix.arch }}
path: test
- name: Run Tests
continue-on-error: ${{ matrix.expect-fails || false }}
run: |
chmod +x test/test.exe
cd test && ls
if [[ ${{ matrix.os }} =~ ^osx ]]; then
otool -L ./test.exe
./test.exe
elif [[ ${{ matrix.os }} =~ win ]]; then
./test.exe
else
ldd ./test.exe
./test.exe
fi
docker-test:
name: Docker Test
runs-on: ${{ matrix.runs-on }}
defaults:
run:
shell: bash
needs: raw-test
strategy:
matrix:
include:
# centos:7 is glibc 2.17, compiled with gcc 4.8.5
# supports centos.7+, rhel.7+, debian:8+(glibc 2.19), ubuntu:14.04+(glibc 2.19)
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: centos:7 }
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: oraclelinux:8 }
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: oraclelinux:9 }
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: debian:8 }
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: debian:9 }
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: debian:10 }
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: debian:11 }
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: debian:12 }
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: ubuntu:14.04 }
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: ubuntu:16.04 }
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: ubuntu:18.04 }
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: ubuntu:20.04 }
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: ubuntu:22.04 }
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: ubuntu:24.04 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: centos:7 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: oraclelinux:8 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: oraclelinux:9 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: debian:9 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: debian:10 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: debian:11 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: debian:12 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: ubuntu:14.04 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: ubuntu:16.04 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: ubuntu:18.04 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: ubuntu:20.04 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: ubuntu:22.04 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: ubuntu:24.04 }
# rhel.8 is glibc 2.28, compiled with gcc 8.5.0
# supports rhel.8+, debian:10+(glibc 2.28), ubuntu:20.04+(glibc 2.31)
# these images will fails
- { os: rhel.8, arch: x64, runs-on: ubuntu-22.04, image: centos:7, expect-fails: true }
- { os: rhel.8, arch: x64, runs-on: ubuntu-22.04, image: debian:9, expect-fails: true }
- { os: rhel.8, arch: x64, runs-on: ubuntu-22.04, image: ubuntu:18.04, expect-fails: true }
- { os: rhel.8, arch: arm64, runs-on: ubuntu-22.04-arm, image: centos:7, expect-fails: true }
- { os: rhel.8, arch: arm64, runs-on: ubuntu-22.04-arm, image: debian:9, expect-fails: true }
- { os: rhel.8, arch: arm64, runs-on: ubuntu-22.04-arm, image: ubuntu:18.04, expect-fails: true }
- { os: rhel.8, arch: x64, runs-on: ubuntu-22.04, image: oraclelinux:8 }
- { os: rhel.8, arch: x64, runs-on: ubuntu-22.04, image: oraclelinux:9 }
- { os: rhel.8, arch: x64, runs-on: ubuntu-22.04, image: debian:10 }
- { os: rhel.8, arch: x64, runs-on: ubuntu-22.04, image: debian:11 }
- { os: rhel.8, arch: x64, runs-on: ubuntu-22.04, image: debian:12 }
- { os: rhel.8, arch: x64, runs-on: ubuntu-22.04, image: ubuntu:20.04 }
- { os: rhel.8, arch: x64, runs-on: ubuntu-22.04, image: ubuntu:22.04 }
- { os: rhel.8, arch: x64, runs-on: ubuntu-22.04, image: ubuntu:24.04 }
- { os: rhel.8, arch: arm64, runs-on: ubuntu-22.04-arm, image: oraclelinux:8 }
- { os: rhel.8, arch: arm64, runs-on: ubuntu-22.04-arm, image: oraclelinux:9 }
- { os: rhel.8, arch: arm64, runs-on: ubuntu-22.04-arm, image: debian:10 }
- { os: rhel.8, arch: arm64, runs-on: ubuntu-22.04-arm, image: debian:11 }
- { os: rhel.8, arch: arm64, runs-on: ubuntu-22.04-arm, image: debian:12 }
- { os: rhel.8, arch: arm64, runs-on: ubuntu-22.04-arm, image: ubuntu:20.04 }
- { os: rhel.8, arch: arm64, runs-on: ubuntu-22.04-arm, image: ubuntu:22.04 }
- { os: rhel.8, arch: arm64, runs-on: ubuntu-22.04-arm, image: ubuntu:24.04 }
# ubuntu 22.04 is glibc 2.35, compiled with gcc 11.2.0
# supports ubuntu:22.04+, debian:11+(glibc 2.31), ubuntu:20.04+(glibc 2.31)
# these images will fails
- { os: ubuntu.22.04, arch: x64, runs-on: ubuntu-22.04, image: oraclelinux:8, expect-fails: true }
- { os: ubuntu.22.04, arch: x64, runs-on: ubuntu-22.04, image: debian:11, expect-fails: true }
- { os: ubuntu.22.04, arch: x64, runs-on: ubuntu-22.04, image: ubuntu:20.04, expect-fails: true }
- { os: ubuntu.22.04, arch: arm64, runs-on: ubuntu-22.04-arm, image: oraclelinux:8, expect-fails: true }
- { os: ubuntu.22.04, arch: arm64, runs-on: ubuntu-22.04-arm, image: debian:11, expect-fails: true }
- { os: ubuntu.22.04, arch: arm64, runs-on: ubuntu-22.04-arm, image: ubuntu:20.04, expect-fails: true }
- { os: ubuntu.22.04, arch: x64, runs-on: ubuntu-22.04, image: oraclelinux:9 }
- { os: ubuntu.22.04, arch: x64, runs-on: ubuntu-22.04, image: debian:12 }
- { os: ubuntu.22.04, arch: x64, runs-on: ubuntu-22.04, image: ubuntu:22.04 }
- { os: ubuntu.22.04, arch: x64, runs-on: ubuntu-22.04, image: ubuntu:24.04 }
- { os: ubuntu.22.04, arch: arm64, runs-on: ubuntu-22.04-arm, image: oraclelinux:9 }
- { os: ubuntu.22.04, arch: arm64, runs-on: ubuntu-22.04-arm, image: debian:12 }
- { os: ubuntu.22.04, arch: arm64, runs-on: ubuntu-22.04-arm, image: ubuntu:22.04 }
- { os: ubuntu.22.04, arch: arm64, runs-on: ubuntu-22.04-arm, image: ubuntu:24.04 }
# alpine 3.22 is musl-libc 1.2.5, compiled with gcc 14.2.0
# should supports alpine:3.13+(musl-libc 1.2.2)
- { os: alpine.3.22, arch: x64, runs-on: ubuntu-22.04, image: alpine:3.12, expect-fails: true } # musl-libc 1.1.24
- { os: alpine.3.22, arch: x64, runs-on: ubuntu-22.04, image: alpine:3.13 } # musl-libc 1.2.2
- { os: alpine.3.22, arch: x64, runs-on: ubuntu-22.04, image: alpine:3.16 } # musl-libc 1.2.3
- { os: alpine.3.22, arch: x64, runs-on: ubuntu-22.04, image: alpine:3.18 } # musl-libc 1.2.4
- { os: alpine.3.22, arch: x64, runs-on: ubuntu-22.04, image: alpine:3.19 } # musl-libc 1.2.4_git20230717
- { os: alpine.3.22, arch: x64, runs-on: ubuntu-22.04, image: alpine:3.20 } # musl-libc 1.2.5
- { os: alpine.3.22, arch: x64, runs-on: ubuntu-22.04, image: alpine:3.22 }
- { os: alpine.3.22, arch: x64, runs-on: ubuntu-22.04, image: alpine:edge }
- { os: alpine.3.22, arch: arm64, runs-on: ubuntu-22.04-arm, image: alpine:3.12, expect-fails: true }
- { os: alpine.3.22, arch: arm64, runs-on: ubuntu-22.04-arm, image: alpine:3.13 }
- { os: alpine.3.22, arch: arm64, runs-on: ubuntu-22.04-arm, image: alpine:3.16 }
- { os: alpine.3.22, arch: arm64, runs-on: ubuntu-22.04-arm, image: alpine:3.18 }
- { os: alpine.3.22, arch: arm64, runs-on: ubuntu-22.04-arm, image: alpine:3.19 }
- { os: alpine.3.22, arch: arm64, runs-on: ubuntu-22.04-arm, image: alpine:3.20 }
- { os: alpine.3.22, arch: arm64, runs-on: ubuntu-22.04-arm, image: alpine:3.22 }
- { os: alpine.3.22, arch: arm64, runs-on: ubuntu-22.04-arm, image: alpine:edge }
steps:
- name: Download Artifacts
uses: actions/download-artifact@v4
with:
name: test-${{ matrix.os }}-${{ matrix.arch }}
path: test
- name: Start Docker Container
run: |
docker run -d --name runner -v "$PWD":${{ github.workspace }} -w ${{ github.workspace }} ${{ matrix.image }} tail -f /dev/null
- name: Run Tests
continue-on-error: ${{ matrix.expect-fails || false }}
run: |
chmod +x test/test.exe
docker exec runner /bin/sh -c "cd test && ls && ldd ./test.exe && ./test.exe"