Guard shared vs static properly #1239
This file contains hidden or 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
| on: [push, pull_request] | |
| env: | |
| # Set this to "on" to enable integration tests and "off" to skip integration tests | |
| RUN_INTEGRATION_TESTS: "on" | |
| name: Build | |
| jobs: | |
| set-lib3mf-version: | |
| runs-on: ubuntu-24.04 | |
| outputs: | |
| lib3mf-version: ${{ steps.set-version.outputs.LIB3MF_VERSION }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - name: Run version extraction script and set environment variable | |
| id: set-version | |
| run: | | |
| LIB3MF_VERSION=$(python CI/ci_cd_helper.py extract-version) | |
| echo "LIB3MF_VERSION=$LIB3MF_VERSION" >> $GITHUB_OUTPUT | |
| - name: Echo version for debug | |
| run: echo "LIB3MF_VERSION=${{ steps.set-version.outputs.LIB3MF_VERSION }}" | |
| build-linux-memtest: | |
| runs-on: ubuntu-24.04 | |
| needs: [set-lib3mf-version] | |
| steps: | |
| - run: sudo apt update | |
| - run: sudo apt install -y valgrind uuid-dev | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - run: sh cmake/GenerateMake.sh | |
| - run: cmake --build . --target lib3mf_memcheck | |
| working-directory: ./build | |
| build-linux-ubi8-gcc12: | |
| runs-on: ubuntu-24.04 | |
| needs: [set-lib3mf-version] | |
| env: | |
| LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} | |
| steps: | |
| - run: sudo apt update | |
| - run: sudo apt install -y uuid-dev | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - run: mkdir -p build | |
| - run: zip -r build/bindings.zip Autogenerated/Bindings | |
| - name: Archive bindings | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: bindings.zip | |
| path: build/bindings.zip | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - | |
| name: Docker Build | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./CI/Dockerfile | |
| platforms: linux/amd64 | |
| tags: lib3mf_ubi8:latest | |
| load: true | |
| - | |
| name: Docker Extract | |
| uses: shrink/actions-docker-extract@v3.0.0 | |
| id: extract | |
| with: | |
| image: lib3mf_ubi8:latest | |
| path: out.zip | |
| destination: dist | |
| - run: unzip out.zip | |
| working-directory: ./dist | |
| - name: Upload Artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lib3mf.so | |
| path: dist/lib3mf.so.2 | |
| - name: Extract File Name (CPacked Archive) | |
| run: | | |
| ZIP_FILE=$(ls dist/lib3mf-*.zip) | |
| echo "ARTIFACT_NAME_ZIP=$(basename ${ZIP_FILE})" >> $GITHUB_ENV | |
| shell: bash | |
| - name: Upload Artifact (CPacked Archive) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.ARTIFACT_NAME_ZIP }} | |
| path: dist/${{ env.ARTIFACT_NAME_ZIP }} | |
| - name: Extract File Name (Debian) | |
| run: | | |
| DEB_FILE=$(ls dist/lib3mf-*.deb) | |
| echo "ARTIFACT_NAME_DEB=$(basename ${DEB_FILE})" >> $GITHUB_ENV | |
| shell: bash | |
| - name: Upload Artifact (Debian Archive) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.ARTIFACT_NAME_DEB }} | |
| path: dist/${{ env.ARTIFACT_NAME_DEB }} | |
| - name: Extract File Name (RPM) | |
| run: | | |
| RPM_FILE=$(ls dist/lib3mf-*.rpm) | |
| echo "ARTIFACT_NAME_RPM=$(basename ${RPM_FILE})" >> $GITHUB_ENV | |
| shell: bash | |
| - name: Upload Artifact (RPM Archive) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.ARTIFACT_NAME_RPM }} | |
| path: dist/${{ env.ARTIFACT_NAME_RPM }} | |
| build-macos: | |
| runs-on: macos-15 | |
| needs: [set-lib3mf-version] | |
| env: | |
| LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - run: sh cmake/GenerateMake.sh | |
| - run: cmake --build . | |
| working-directory: ./build | |
| - run: ctest -V | |
| working-directory: ./build | |
| - run: cpack -G ZIP -C Release | |
| working-directory: ./build | |
| - name: Extract File Name | |
| run: | | |
| ZIP_FILE=$(ls build/lib3mf-*.zip) | |
| echo "ARTIFACT_NAME=$(basename ${ZIP_FILE})" >> $GITHUB_ENV | |
| shell: bash | |
| - run: ls -al build/ | |
| - name: Determine macOS dylib | |
| id: find-mac-lib | |
| run: | | |
| set -euo pipefail | |
| MAC_LIB=$(ls build/lib3mf*.dylib | head -n 1) | |
| if [ -z "$MAC_LIB" ]; then | |
| echo "No macOS dylib found in build/" >&2 | |
| exit 1 | |
| fi | |
| echo "MAC_LIB=${MAC_LIB}" >> $GITHUB_ENV | |
| - name: Archive Mac binary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lib3mf.dylib | |
| path: ${{ env.MAC_LIB }} | |
| - name: Upload Artifact (CPacked Archive) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.ARTIFACT_NAME }} | |
| path: build/${{ env.ARTIFACT_NAME }} | |
| build-macos-debug: | |
| runs-on: macos-15 | |
| needs: [set-lib3mf-version] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - run: sh cmake/GenerateMake.sh "Debug" | |
| - run: cmake --build . | |
| working-directory: ./build | |
| - run: ctest -V | |
| working-directory: ./build | |
| - name: Archive Mac binary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lib3mf.debug.dylib | |
| path: build/lib3mf.dylib | |
| codecoverage-macos: | |
| runs-on: macos-15 | |
| needs: [set-lib3mf-version] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - name: Install Prerequisites | |
| run: | | |
| brew install lcov | |
| brew install gcovr | |
| - run: sh cmake/GenerateMake.sh -DBUILD_FOR_CODECOVERAGE=ON | |
| - run: cmake --build . | |
| working-directory: ./build | |
| - run: ./Tests/codecoverage/run_codecoverage.sh | |
| - name: Archive Code Coverage Results | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: codecoverage.zip | |
| path: build/codecoverage.zip | |
| - name: Upload code coverage to codecov | |
| uses: codecov/codecov-action@v3 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: ./build/Test_CPP_Bindings_filtered.info | |
| fail_ci_if_error: false # optional (default = false) | |
| verbose: true # optional (default = false) | |
| build-windows-release: | |
| runs-on: windows-2022 | |
| needs: [set-lib3mf-version] | |
| env: | |
| LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - run: ./cmake/GenerateVS2022.bat | |
| - run: cmake --build . --config Release | |
| working-directory: ./build | |
| - run: ctest -V | |
| working-directory: ./build | |
| - run: cpack -G ZIP -C Release | |
| working-directory: ./build | |
| - name: Extract File Name | |
| run: | | |
| $zipFile = Get-ChildItem build\lib3mf-*.zip -Name | |
| echo "ARTIFACT_NAME=$zipFile" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| shell: pwsh | |
| - name: Archive Windows Release binary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lib3mf.dll | |
| path: build/Release/lib3mf.dll | |
| - name: Archive Windows Release lib | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lib3mf.lib | |
| path: build/Release/lib3mf.lib | |
| - name: Upload Artifact (CPacked Archive) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.ARTIFACT_NAME }} | |
| path: build/${{ env.ARTIFACT_NAME }} | |
| build-windows-debug: | |
| runs-on: windows-2022 | |
| needs: [set-lib3mf-version] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - run: ./cmake/GenerateVS2022.bat | |
| - run: cmake --build . --config Debug | |
| working-directory: ./build | |
| - run: ctest -V | |
| working-directory: ./build | |
| - name: Archive Windows Debug binary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lib3mf.debug.dll | |
| path: build/Debug/lib3mf.dll | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: lib3mf.pdb | |
| path: build/Debug/lib3mf.pdb | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: lib3mf.debug.lib | |
| path: build/Debug/lib3mf.lib | |
| build-windows-32bit: | |
| runs-on: windows-2022 | |
| needs: [set-lib3mf-version] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - run: ./cmake/GenerateVS2022_32bit.bat | |
| - run: cmake --build . --config Release | |
| working-directory: ./build_32bit | |
| - run: ctest -V | |
| working-directory: ./build_32bit | |
| - name: Archive Windows 32 bit Release binary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lib3mf_32bit.dll | |
| path: build_32bit/Release/lib3mf.dll | |
| - name: Archive Windows 32 bit Release lib | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lib3mf_32bit.lib | |
| path: build_32bit/Release/lib3mf.lib | |
| build-mingw-w64: | |
| runs-on: windows-2022 | |
| needs: [set-lib3mf-version] | |
| steps: | |
| - run: choco install mingw -y | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - run: ./cmake/GenerateMinGW.bat | |
| - run: cmake --build . | |
| working-directory: ./build | |
| - run: ctest -V | |
| working-directory: ./build | |
| assemble-sdk: | |
| runs-on: ubuntu-24.04 | |
| needs: [set-lib3mf-version, build-windows-release, build-macos, build-linux-ubi8-gcc12] | |
| env: | |
| LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} | |
| steps: | |
| - run: sudo apt install -y zip unzip | |
| - run: mkdir build | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: false | |
| - name: Download all workflow run artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: ./build | |
| - run: ls -Rlh ./build | |
| - run: unzip bindings.zip/bindings.zip | |
| working-directory: ./build | |
| - run: python3 SDK/GenerateSDK_github.py | |
| - name: Archive SDK artifact (Comprehensive) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lib3mf_sdk.zip | |
| path: build/lib3mf_sdk.zip | |
| deploy-linux: | |
| runs-on: ubuntu-24.04 | |
| needs: [set-lib3mf-version, assemble-sdk] | |
| env: | |
| LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} | |
| steps: | |
| - run: sudo apt install -y zip unzip file | |
| - run: pwd | |
| - run: ls -Rl . | |
| - name: Download lib3mf_sdk artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lib3mf_sdk.zip | |
| path: lib3mf_sdk.zip | |
| - run: ls -Rl . | |
| - name: Unpack the SDK | |
| run: | | |
| unzip lib3mf_sdk.zip/lib3mf_sdk.zip | |
| - name: Build CppDynamic | |
| run: | | |
| sh Examples/CppDynamic/GenerateMake.sh | |
| cd Examples/CppDynamic/build | |
| cmake --build . | |
| ./Example_ExtractInfo ../../Files/Helix.3mf | |
| - name: Build Cpp | |
| run: | | |
| sh Examples/Cpp/GenerateMake.sh | |
| cd Examples/Cpp/build | |
| cmake --build . | |
| ./Example_ExtractInfo ../../Files/Helix.3mf | |
| - name: Python Bindings | |
| run: | | |
| python Examples/Python/extract_info.py Examples/Files/Helix.3mf | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - run: ls -Rl | |
| - name: Download lib3mf cpack (Linux) | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lib3mf-${{ env.LIB3MF_VERSION }}-Linux.zip | |
| path: lib3mf-${{ env.LIB3MF_VERSION }}-Linux.zip | |
| - name: Unpack the cpacked SDK | |
| run: | | |
| unzip lib3mf-${{ env.LIB3MF_VERSION }}-Linux.zip/lib3mf-${{ env.LIB3MF_VERSION }}-Linux.zip && ls -Rl | |
| - name: Build CppDynamic - CPack (Linux) | |
| run: | | |
| sh SDK/CPackExamples/CppDynamic/GenerateMake.sh | |
| cd SDK/CPackExamples/CppDynamic/build | |
| cmake --build . | |
| ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf | |
| - name: Build Cpp - CPack (Linux) | |
| run: | | |
| sh SDK/CPackExamples/Cpp/GenerateMake.sh | |
| cd SDK/CPackExamples/Cpp/build | |
| cmake --build . | |
| ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf | |
| - name: Download lib3mf (Debian Linux) | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb | |
| path: lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb | |
| - name: Check the file type | |
| run: | | |
| file lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb | |
| file lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb/lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb | |
| - run: pwd | |
| - run: ls -Rl . | |
| - name: Install the debian package | |
| run: | | |
| sudo dpkg -i lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb/lib3mf-${{ env.LIB3MF_VERSION }}-Linux.deb | |
| - name: Build CppDynamic - CPack (Debian) | |
| run: | | |
| sh SDK/CPackExamples/CppDynamic/GenerateMake.sh | |
| cd SDK/CPackExamples/CppDynamic/build | |
| cmake --build . | |
| ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf | |
| - name: Build Cpp - CPack (Debian) | |
| run: | | |
| sh SDK/CPackExamples/Cpp/GenerateMake.sh | |
| cd SDK/CPackExamples/Cpp/build | |
| cmake --build . | |
| ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf | |
| - name: Setup Go | |
| uses: actions/setup-go@v4 | |
| with: | |
| go-version: '1.20' | |
| - name: Go Bindings | |
| run: | | |
| cd SDK/Examples/Go | |
| go mod init lib3mfExamples | |
| go get github.com/3MFConsortium/lib3mf.go/v2@v2.4.1 | |
| go build -o create_cube create_cube.go | |
| ./create_cube | |
| deploy-windows: | |
| runs-on: windows-2022 | |
| needs: [set-lib3mf-version, assemble-sdk] | |
| env: | |
| LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} | |
| steps: | |
| - name: Download lib3mf_sdk artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lib3mf_sdk.zip | |
| path: lib3mf_sdk.zip | |
| - name: Unpack the SDK | |
| run: | | |
| unzip lib3mf_sdk.zip/lib3mf_sdk.zip | |
| - name: Build CppDynamic | |
| run: | | |
| ./Examples/CppDynamic/GenerateVS2022.bat | |
| cd Examples/CppDynamic/build | |
| cmake --build . --config Release | |
| ./Release/Example_ExtractInfo.exe ../../Files/Helix.3mf | |
| - name: Build Cpp | |
| run: | | |
| ./Examples/Cpp/GenerateVS2022.bat | |
| cd Examples/Cpp/build | |
| cmake --build . --config Release | |
| ./Release/Example_ExtractInfo.exe ../../Files/Helix.3mf | |
| - name: Python Bindings | |
| run: | | |
| python Examples/Python/extract_info.py Examples/Files/Helix.3mf | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - name: Download lib3mf cpack (Windows) | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lib3mf-${{ env.LIB3MF_VERSION }}-Windows.zip | |
| path: lib3mf-${{ env.LIB3MF_VERSION }}-Windows.zip | |
| - name: Unpack the cpacked SDK | |
| run: | | |
| unzip lib3mf-${{ env.LIB3MF_VERSION }}-Windows.zip/lib3mf-${{ env.LIB3MF_VERSION }}-Windows.zip | |
| - name: Build CppDynamic - CPack (Windows) | |
| run: | | |
| ./SDK/CPackExamples/CppDynamic/GenerateVS2022.bat | |
| cd SDK/CPackExamples/CppDynamic/build | |
| cmake --build . --config Release | |
| ./Release/Example_ExtractInfo.exe ../../../Examples/Files/Helix.3mf | |
| - name: Build Cpp - CPack (Windows) | |
| run: | | |
| ./SDK/CPackExamples/Cpp/GenerateVS2022.bat | |
| cd SDK/CPackExamples/Cpp/build | |
| cmake --build . --config Release | |
| ./Release/Example_ExtractInfo.exe ../../../Examples/Files/Helix.3mf | |
| - name: Setup Go | |
| uses: actions/setup-go@v4 | |
| with: | |
| go-version: '1.20' | |
| - name: Go Bindings | |
| run: | | |
| cd SDK/Examples/Go | |
| go mod init lib3mfExamples | |
| go get github.com/3MFConsortium/lib3mf.go/v2@v2.4.1 | |
| go build -o create_cube.exe create_cube.go | |
| ./create_cube.exe | |
| deploy-macos: | |
| runs-on: macos-latest | |
| needs: [set-lib3mf-version, assemble-sdk] | |
| env: | |
| LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} | |
| steps: | |
| - name: Download lib3mf_sdk artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lib3mf_sdk.zip | |
| path: lib3mf_sdk.zip | |
| - name: Unpack the SDK | |
| run: | | |
| unzip lib3mf_sdk.zip/lib3mf_sdk.zip | |
| - name: Build CppDynamic | |
| run: | | |
| sh Examples/CppDynamic/GenerateMake.sh | |
| cd Examples/CppDynamic/build | |
| cmake --build . | |
| ls -al | |
| ./Example_ExtractInfo ../../Files/Helix.3mf | |
| - name: Build Cpp | |
| run: | | |
| sh Examples/Cpp/GenerateMake.sh | |
| cd Examples/Cpp/build | |
| cmake --build . | |
| ./Example_ExtractInfo ../../Files/Helix.3mf | |
| - name: Python Bindings | |
| run: | | |
| python Examples/Python/extract_info.py Examples/Files/Helix.3mf | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - name: Download lib3mf cpack (Darwin) | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lib3mf-${{ env.LIB3MF_VERSION }}-Darwin.zip | |
| path: lib3mf-${{ env.LIB3MF_VERSION }}-Darwin.zip | |
| - run: ls -Rl . | |
| - name: Unpack the cpacked SDK (Darwin) | |
| run: | | |
| unzip lib3mf-${{ env.LIB3MF_VERSION }}-Darwin.zip/lib3mf-${{ env.LIB3MF_VERSION }}-Darwin.zip | |
| - name: Build CppDynamic - CPack (Darwin) | |
| run: | | |
| sh SDK/CPackExamples/CppDynamic/GenerateMake.sh | |
| cd SDK/CPackExamples/CppDynamic/build | |
| cmake --build . | |
| ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf | |
| - name: Build Cpp - CPack (Darwin) | |
| run: | | |
| sh SDK/CPackExamples/Cpp/GenerateMake.sh | |
| cd SDK/CPackExamples/Cpp/build | |
| cmake --build . | |
| ./Example_ExtractInfo ../../../Examples/Files/Helix.3mf | |
| - name: Setup Go | |
| uses: actions/setup-go@v4 | |
| with: | |
| go-version: '1.20' | |
| - name: Go Bindings | |
| run: | | |
| cd SDK/Examples/Go | |
| go mod init lib3mfExamples | |
| go get github.com/3MFConsortium/lib3mf.go/v2@v2.4.1 | |
| go build -o create_cube create_cube.go | |
| ./create_cube | |
| deploy-source-code-with-submodules: | |
| runs-on: ubuntu-24.04 | |
| needs: [ set-lib3mf-version, assemble-sdk ] | |
| env: | |
| LIB3MF_VERSION: ${{ needs.set-lib3mf-version.outputs.lib3mf-version }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - run: | | |
| mkdir -p lib3mf-${{ env.LIB3MF_VERSION }}-source-with-submodules | |
| rsync -av --progress . ./lib3mf-${{ env.LIB3MF_VERSION }}-source-with-submodules --exclude .git --exclude .gitignore --exclude .github --exclude .gitmodules --exclude *.yml --exclude lib3mf-${{ env.LIB3MF_VERSION }}-source-with-submodules | |
| - name: Upload Artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lib3mf-${{ env.LIB3MF_VERSION }}-source-with-submodules | |
| path: lib3mf-${{ env.LIB3MF_VERSION }}-source-with-submodules | |
| set-integration-tests-status: | |
| runs-on: ubuntu-24.04 | |
| needs: [ deploy-linux, deploy-windows, deploy-macos, deploy-source-code-with-submodules ] | |
| outputs: | |
| run_integration_tests: ${{ steps.set-status.outputs.run_integration_tests }} | |
| steps: | |
| - name: Install prerequisites | |
| if: env.RUN_INTEGRATION_TESTS == 'on' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y unzip wget | |
| - name: Set status | |
| id: set-status | |
| run: | | |
| if [ "${{ env.RUN_INTEGRATION_TESTS }}" == "on" ]; then | |
| echo "run_integration_tests=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "run_integration_tests=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Cache 3MF test suite | |
| if: steps.set-status.outputs.run_integration_tests == 'true' | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/3mf-test-suite | |
| key: 3mf-test-suite-v2.0.0 | |
| - name: Download integration test suite | |
| if: steps.set-status.outputs.run_integration_tests == 'true' | |
| run: | | |
| USER="${{ secrets.THREEMF_TEST_SUITE_DOWNLOAD_USER }}" | |
| PASS="${{ secrets.THREEMF_TEST_SUITE_DOWNLOAD_TOKEN }}" | |
| CACHE_DIR="$HOME/.cache/3mf-test-suite" | |
| SUITE_ZIP="3MF_Conformance_Test_Suites_v2.0.0.zip" | |
| CACHE_ZIP="$CACHE_DIR/$SUITE_ZIP" | |
| mkdir -p "$CACHE_DIR" | |
| if [ ! -f "$CACHE_ZIP" ]; then | |
| wget --user "$USER" \ | |
| --password "$PASS" \ | |
| "https://storage.3mf.dev/remote.php/dav/files/$USER/3MF_CONSORTIUM/GITHUB/$SUITE_ZIP" \ | |
| -O "$CACHE_ZIP" | |
| fi | |
| integration-tests-latest-release: | |
| runs-on: ubuntu-24.04 | |
| needs: [set-integration-tests-status] | |
| if: needs.set-integration-tests-status.outputs.run_integration_tests == 'true' # Single check before the job starts | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.8' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| - name: Get latest lib3mf SDK release info from GitHub API | |
| id: get_lib3mf_release | |
| run: | | |
| echo "LATEST_LIB3MF_URL=$(python CI/ci_cd_helper.py fetch-sdk-url 0 | xargs)" >> $GITHUB_ENV | |
| - name: Download latest lib3mf SDK zip | |
| run: | | |
| wget ${{ env.LATEST_LIB3MF_URL }} -O latest_lib3mf_sdk.zip | |
| - name: Unpack the SDK | |
| run: | | |
| unzip latest_lib3mf_sdk.zip -d lib3mf_sdk | |
| mv lib3mf_sdk/lib3mf_sdk/* lib3mf_sdk/ | |
| rmdir lib3mf_sdk/lib3mf_sdk | |
| - name: Build CppDynamic | |
| run: | | |
| sh lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh | |
| cd lib3mf_sdk/Examples/CppDynamic/build | |
| cmake --build . | |
| ./Example_ExtractInfo ../../Files/Helix.3mf | |
| - name: Restore 3MF test suite cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/3mf-test-suite | |
| key: 3mf-test-suite-v2.0.0 | |
| - name: Unzip integration test suite | |
| run: | | |
| rm -rf test_suites | |
| unzip -o "$HOME/.cache/3mf-test-suite/3MF_Conformance_Test_Suites_v2.0.0.zip" -d test_suites | |
| - name: List files | |
| run: | | |
| ls -al | |
| - name: Copy integration test script | |
| run: | | |
| cp CI/integration_test.py test_suites/ && cp -r lib3mf_sdk/Examples/CppDynamic/build/* test_suites/ | |
| - name: Run integration tests | |
| run: | | |
| cd test_suites && /usr/bin/time -v python integration_test.py 2>&1 | tee latest_sdk_test.log | |
| - name: List MUSTPASS failures and MUSTFAIL passes (latest release) | |
| run: | | |
| echo "MUSTPASS that failed (latest release):" | |
| grep -E 'MUSTPASS file ".*" does not work' test_suites/latest_sdk_test.log | sed -n 's/.*MUSTPASS file "\([^"]*\)".*/\1/p' | sort -u > test_suites/latest_mp_failed.txt || true | |
| cat test_suites/latest_mp_failed.txt || true | |
| echo "\nMUSTFAIL that passed (latest release):" | |
| grep -E 'MUSTFAIL file ".*" works' test_suites/latest_sdk_test.log | sed -n 's/.*MUSTFAIL file "\([^"]*\)".*/\1/p' | sort -u > test_suites/latest_mf_passed.txt || true | |
| cat test_suites/latest_mf_passed.txt || true | |
| { | |
| echo "### Latest release detailed results"; | |
| echo "MUSTPASS failed: $(wc -l < test_suites/latest_mp_failed.txt 2>/dev/null || echo 0)"; | |
| sed 's/^/- /' test_suites/latest_mp_failed.txt 2>/dev/null || true; | |
| echo; | |
| echo "MUSTFAIL passed: $(wc -l < test_suites/latest_mf_passed.txt 2>/dev/null || echo 0)"; | |
| sed 's/^/- /' test_suites/latest_mf_passed.txt 2>/dev/null || true; | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Print results (Checks the total python script execution time) | |
| run: | | |
| LATEST_TIME=$(grep "Elapsed (wall clock) time" test_suites/latest_sdk_test.log | awk '{print $8}') | |
| LATEST_TOTAL_SECONDS=$(echo $LATEST_TIME | awk -F: '{ print ($1 * 60) + $2 }') | |
| echo "Latest SDK execution time in seconds: ${LATEST_TOTAL_SECONDS}" | |
| LATEST_MUSTPASS=$(grep "MUSTPASS files passed" test_suites/latest_sdk_test.log | awk '{print $1}') | |
| LATEST_TOTAL_MUSTPASS=$(grep "MUSTPASS files passed" test_suites/latest_sdk_test.log | awk '{print $3}' | tr -d '()') | |
| LATEST_MUSTFAIL=$(grep "MUSTFAIL files failed" test_suites/latest_sdk_test.log | awk '{print $1}') | |
| LATEST_TOTAL_MUSTFAIL=$(grep "MUSTFAIL files failed" test_suites/latest_sdk_test.log | awk '{print $3}' | tr -d '()') | |
| echo "MUSTPASS: ${LATEST_MUSTPASS} / ${LATEST_TOTAL_MUSTPASS}" | |
| echo "MUSTFAIL: ${LATEST_MUSTFAIL} / ${LATEST_TOTAL_MUSTFAIL}" | |
| integration-tests-last-two-releases: | |
| runs-on: ubuntu-24.04 | |
| needs: [set-integration-tests-status] | |
| if: needs.set-integration-tests-status.outputs.run_integration_tests == 'true' # Single check before the job starts | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.8' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| - name: Get latest lib3mf SDK release info from GitHub API | |
| id: get_latest_release | |
| run: | | |
| echo "LATEST_LIB3MF_URL=$(python CI/ci_cd_helper.py fetch-sdk-url 0 | xargs)" >> $GITHUB_ENV | |
| - name: Get second latest lib3mf SDK release info from GitHub API | |
| id: get_second_latest_release | |
| run: | | |
| echo "SECOND_LATEST_LIB3MF_URL=$(python CI/ci_cd_helper.py fetch-sdk-url 1 | xargs)" >> $GITHUB_ENV | |
| - name: Download latest lib3mf SDK zip | |
| run: | | |
| wget ${{ env.LATEST_LIB3MF_URL }} -O latest_lib3mf_sdk.zip | |
| - name: Download second latest lib3mf SDK zip | |
| run: | | |
| wget ${{ env.SECOND_LATEST_LIB3MF_URL }} -O second_latest_lib3mf_sdk.zip | |
| - name: Unpack the latest SDK | |
| run: | | |
| unzip latest_lib3mf_sdk.zip -d latest_lib3mf_sdk | |
| mv latest_lib3mf_sdk/lib3mf_sdk/* latest_lib3mf_sdk | |
| rmdir latest_lib3mf_sdk/lib3mf_sdk | |
| - name: Unpack the second latest SDK | |
| run: | | |
| unzip second_latest_lib3mf_sdk.zip -d second_latest_lib3mf_sdk | |
| mv second_latest_lib3mf_sdk/lib3mf_sdk/* second_latest_lib3mf_sdk | |
| rmdir second_latest_lib3mf_sdk/lib3mf_sdk | |
| - name: Restore 3MF test suite cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/3mf-test-suite | |
| key: 3mf-test-suite-v2.0.0 | |
| - name: Unzip integration test suite | |
| run: | | |
| rm -rf test_suites | |
| unzip -o "$HOME/.cache/3mf-test-suite/3MF_Conformance_Test_Suites_v2.0.0.zip" -d test_suites | |
| - name: Copy integration test script | |
| run: | | |
| cp CI/integration_test.py test_suites/ | |
| - name: Build and run CppDynamic with latest SDK | |
| run: | | |
| sh latest_lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh | |
| cd latest_lib3mf_sdk/Examples/CppDynamic/build | |
| cmake --build . | |
| cp -r * ../../../../test_suites/ | |
| - name: Run integration tests with latest SDK | |
| run: | | |
| cd test_suites | |
| /usr/bin/time -v python integration_test.py 2>&1 | tee latest_sdk_test.log | |
| - name: Clean up latest SDK binaries | |
| run: | | |
| find test_suites -maxdepth 1 -type f ! -name 'integration_test.py' ! -name 'latest_sdk_test.log' ! -name 'second_latest_sdk_test.log' -exec rm -rf {} + | |
| - name: Build and run CppDynamic with second latest SDK | |
| run: | | |
| sh second_latest_lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh | |
| cd second_latest_lib3mf_sdk/Examples/CppDynamic/build | |
| cmake --build . | |
| echo "First debug" | |
| ls -al ../../../../ | |
| echo "This will fail" | |
| cp -r * ../../../../test_suites/ | |
| - name: Run integration tests with second latest SDK | |
| run: | | |
| cd test_suites | |
| /usr/bin/time -v python integration_test.py 2>&1 | tee second_latest_sdk_test.log | |
| - name: Compare results (Checks the total python script execution time and must pass/fail counts) | |
| run: | | |
| # Extract detailed lists from logs for diffing | |
| grep -E 'MUSTPASS file ".*" does not work' test_suites/latest_sdk_test.log | sed -n 's/.*MUSTPASS file "\([^"]*\)".*/\1/p' | sort -u > test_suites/latest_mp_failed.txt || true | |
| grep -E 'MUSTFAIL file ".*" works' test_suites/latest_sdk_test.log | sed -n 's/.*MUSTFAIL file "\([^"]*\)".*/\1/p' | sort -u > test_suites/latest_mf_passed.txt || true | |
| grep -E 'MUSTPASS file ".*" does not work' test_suites/second_latest_sdk_test.log | sed -n 's/.*MUSTPASS file "\([^"]*\)".*/\1/p' | sort -u > test_suites/second_latest_mp_failed.txt || true | |
| grep -E 'MUSTFAIL file ".*" works' test_suites/second_latest_sdk_test.log | sed -n 's/.*MUSTFAIL file "\([^"]*\)".*/\1/p' | sort -u > test_suites/second_latest_mf_passed.txt || true | |
| echo "=== Latest MUSTPASS failed:"; cat test_suites/latest_mp_failed.txt || true | |
| echo "=== Second Latest MUSTPASS failed:"; cat test_suites/second_latest_mp_failed.txt || true | |
| echo "=== Latest MUSTFAIL passed:"; cat test_suites/latest_mf_passed.txt || true | |
| echo "=== Second Latest MUSTFAIL passed:"; cat test_suites/second_latest_mf_passed.txt || true | |
| # Compute regressions and improvements | |
| comm -23 test_suites/latest_mp_failed.txt test_suites/second_latest_mp_failed.txt > test_suites/regressions_mp_now_failing.txt || true | |
| comm -23 test_suites/latest_mf_passed.txt test_suites/second_latest_mf_passed.txt > test_suites/regressions_mf_now_passing.txt || true | |
| comm -13 test_suites/latest_mp_failed.txt test_suites/second_latest_mp_failed.txt > test_suites/improvements_mp_fixed.txt || true | |
| comm -13 test_suites/latest_mf_passed.txt test_suites/second_latest_mf_passed.txt > test_suites/improvements_mf_fixed.txt || true | |
| echo "=== Regressions - MUSTPASS now failing:"; cat test_suites/regressions_mp_now_failing.txt || true | |
| echo "=== Regressions - MUSTFAIL now passing:"; cat test_suites/regressions_mf_now_passing.txt || true | |
| echo "=== Improvements - MUSTPASS fixed:"; cat test_suites/improvements_mp_fixed.txt || true | |
| echo "=== Improvements - MUSTFAIL fixed:"; cat test_suites/improvements_mf_fixed.txt || true | |
| { | |
| echo "### Last two releases - detailed diffs"; | |
| echo "#### Regressions - MUSTPASS now failing"; sed 's/^/- /' test_suites/regressions_mp_now_failing.txt 2>/dev/null || true; echo; | |
| echo "#### Regressions - MUSTFAIL now passing"; sed 's/^/- /' test_suites/regressions_mf_now_passing.txt 2>/dev/null || true; echo; | |
| echo "#### Improvements - MUSTPASS fixed"; sed 's/^/- /' test_suites/improvements_mp_fixed.txt 2>/dev/null || true; echo; | |
| echo "#### Improvements - MUSTFAIL fixed"; sed 's/^/- /' test_suites/improvements_mf_fixed.txt 2>/dev/null || true; echo; | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| LATEST_TIME=$(grep "Elapsed (wall clock) time" test_suites/latest_sdk_test.log | awk '{print $8}') | |
| SECOND_LATEST_TIME=$(grep "Elapsed (wall clock) time" test_suites/second_latest_sdk_test.log | awk '{print $8}') | |
| LATEST_TOTAL_SECONDS=$(echo $LATEST_TIME | awk -F: '{ print ($1 * 60) + $2 }') | |
| SECOND_LATEST_TOTAL_SECONDS=$(echo $SECOND_LATEST_TIME | awk -F: '{ print ($1 * 60) + $2 }') | |
| echo "Latest SDK execution time in seconds: ${LATEST_TOTAL_SECONDS}" | |
| echo "Second Latest SDK execution time in seconds: ${SECOND_LATEST_TOTAL_SECONDS}" | |
| LATEST_MUSTPASS=$(grep "MUSTPASS files passed" test_suites/latest_sdk_test.log | awk '{print $1}') | |
| LATEST_TOTAL_MUSTPASS=$(grep "MUSTPASS files passed" test_suites/latest_sdk_test.log | awk '{print $3}' | tr -d '()') | |
| SECOND_LATEST_MUSTPASS=$(grep "MUSTPASS files passed" test_suites/second_latest_sdk_test.log | awk '{print $1}') | |
| SECOND_LATEST_TOTAL_MUSTPASS=$(grep "MUSTPASS files passed" test_suites/second_latest_sdk_test.log | awk '{print $3}' | tr -d '()') | |
| LATEST_MUSTFAIL=$(grep "MUSTFAIL files failed" test_suites/latest_sdk_test.log | awk '{print $1}') | |
| LATEST_TOTAL_MUSTFAIL=$(grep "MUSTFAIL files failed" test_suites/latest_sdk_test.log | awk '{print $3}' | tr -d '()') | |
| SECOND_LATEST_MUSTFAIL=$(grep "MUSTFAIL files failed" test_suites/second_latest_sdk_test.log | awk '{print $1}') | |
| SECOND_LATEST_TOTAL_MUSTFAIL=$(grep "MUSTFAIL files failed" test_suites/second_latest_sdk_test.log | awk '{print $3}' | tr -d '()') | |
| echo "Latest MUSTPASS: ${LATEST_MUSTPASS} / ${LATEST_TOTAL_MUSTPASS}" | |
| echo "Second Latest MUSTPASS: ${SECOND_LATEST_MUSTPASS} / ${SECOND_LATEST_TOTAL_MUSTPASS}" | |
| echo "Latest MUSTFAIL: ${LATEST_MUSTFAIL} / ${LATEST_TOTAL_MUSTFAIL}" | |
| echo "Second Latest MUSTFAIL: ${SECOND_LATEST_MUSTFAIL} / ${SECOND_LATEST_TOTAL_MUSTFAIL}" | |
| # Compare the total seconds | |
| if (( $(echo "$LATEST_TOTAL_SECONDS < $SECOND_LATEST_TOTAL_SECONDS" | bc -l) )); then | |
| echo "New release is better in execution time" | |
| else | |
| echo "New release is worse in execution time" | |
| fi | |
| # Compare MUSTPASS and MUSTFAIL counts | |
| # Allow improvements: pass if latest >= second latest for both metrics; fail only on regression | |
| if [ "$LATEST_MUSTPASS" -lt "$SECOND_LATEST_MUSTPASS" ] || [ "$LATEST_MUSTFAIL" -lt "$SECOND_LATEST_MUSTFAIL" ]; then | |
| echo "MUSTPASS or MUSTFAIL counts have regressed" | |
| echo "Regressions detected. See lists above and job summary for files." | |
| exit 1 | |
| else | |
| echo "MUSTPASS and MUSTFAIL counts have improved or stayed the same" | |
| fi | |
| integration-tests-latest-commit: | |
| runs-on: ubuntu-24.04 | |
| needs: [set-integration-tests-status] | |
| if: needs.set-integration-tests-status.outputs.run_integration_tests == 'true' # Single check before the job starts | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.8' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| - name: Download lib3mf_sdk artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lib3mf_sdk.zip | |
| path: lib3mf_sdk.zip | |
| - name: Unpack the SDK | |
| run: | | |
| unzip lib3mf_sdk.zip/lib3mf_sdk.zip -d lib3mf_sdk && ls -al | |
| - name: Build CppDynamic | |
| run: | | |
| sh lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh | |
| cd lib3mf_sdk/Examples/CppDynamic/build | |
| cmake --build . | |
| ./Example_ExtractInfo ../../Files/Helix.3mf | |
| - name: Restore 3MF test suite cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/3mf-test-suite | |
| key: 3mf-test-suite-v2.0.0 | |
| - name: Unzip integration test suite | |
| run: | | |
| rm -rf test_suites | |
| unzip -o "$HOME/.cache/3mf-test-suite/3MF_Conformance_Test_Suites_v2.0.0.zip" -d test_suites | |
| - name: Copy integration test script | |
| run: | | |
| cp CI/integration_test.py test_suites/ && cp -r lib3mf_sdk/Examples/CppDynamic/build/* test_suites/ | |
| - name: Run integration tests | |
| run: | | |
| cd test_suites && /usr/bin/time -v python integration_test.py 2>&1 | tee latest_sdk_test.log | |
| - name: List MUSTPASS failures and MUSTFAIL passes (latest commit) | |
| run: | | |
| echo "MUSTPASS that failed (latest commit):" | |
| grep -E 'MUSTPASS file ".*" does not work' test_suites/latest_sdk_test.log | sed -n 's/.*MUSTPASS file "\([^"]*\)".*/\1/p' | sort -u > test_suites/latest_commit_mp_failed.txt || true | |
| cat test_suites/latest_commit_mp_failed.txt || true | |
| echo "\nMUSTFAIL that passed (latest commit):" | |
| grep -E 'MUSTFAIL file ".*" works' test_suites/latest_sdk_test.log | sed -n 's/.*MUSTFAIL file "\([^"]*\)".*/\1/p' | sort -u > test_suites/latest_commit_mf_passed.txt || true | |
| cat test_suites/latest_commit_mf_passed.txt || true | |
| { | |
| echo "### Latest commit detailed results"; | |
| echo "MUSTPASS failed: $(wc -l < test_suites/latest_commit_mp_failed.txt 2>/dev/null || echo 0)"; | |
| sed 's/^/- /' test_suites/latest_commit_mp_failed.txt 2>/dev/null || true; | |
| echo; | |
| echo "MUSTFAIL passed: $(wc -l < test_suites/latest_commit_mf_passed.txt 2>/dev/null || echo 0)"; | |
| sed 's/^/- /' test_suites/latest_commit_mf_passed.txt 2>/dev/null || true; | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Print results (Checks the total python script execution time) | |
| run: | | |
| LATEST_TIME=$(grep "Elapsed (wall clock) time" test_suites/latest_sdk_test.log | awk '{print $8}') | |
| LATEST_TOTAL_SECONDS=$(echo $LATEST_TIME | awk -F: '{ print ($1 * 60) + $2 }') | |
| echo "Latest SDK execution time in seconds: ${LATEST_TOTAL_SECONDS}" | |
| LATEST_MUSTPASS=$(grep "MUSTPASS files passed" test_suites/latest_sdk_test.log | awk '{print $1}') | |
| LATEST_TOTAL_MUSTPASS=$(grep "MUSTPASS files passed" test_suites/latest_sdk_test.log | awk '{print $3}' | tr -d '()') | |
| LATEST_MUSTFAIL=$(grep "MUSTFAIL files failed" test_suites/latest_sdk_test.log | awk '{print $1}') | |
| LATEST_TOTAL_MUSTFAIL=$(grep "MUSTFAIL files failed" test_suites/latest_sdk_test.log | awk '{print $3}' | tr -d '()') | |
| echo "MUSTPASS: ${LATEST_MUSTPASS} / ${LATEST_TOTAL_MUSTPASS}" | |
| echo "MUSTFAIL: ${LATEST_MUSTFAIL} / ${LATEST_TOTAL_MUSTFAIL}" | |
| # Save counts for comparison in other jobs | |
| echo "LATEST_MUSTPASS=${LATEST_MUSTPASS}" >> $GITHUB_ENV | |
| echo "LATEST_TOTAL_MUSTPASS=${LATEST_TOTAL_MUSTPASS}" >> $GITHUB_ENV | |
| echo "LATEST_MUSTFAIL=${LATEST_MUSTFAIL}" >> $GITHUB_ENV | |
| echo "LATEST_TOTAL_MUSTFAIL=${LATEST_TOTAL_MUSTFAIL}" >> $GITHUB_ENV | |
| integration-test-last-commit-and-last-release: | |
| runs-on: ubuntu-24.04 | |
| needs: [set-integration-tests-status] | |
| if: needs.set-integration-tests-status.outputs.run_integration_tests == 'true' # Single check before the job starts | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.8' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| - name: Download lib3mf_sdk artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lib3mf_sdk.zip | |
| path: lib3mf_sdk.zip | |
| - name: Unpack the SDK | |
| run: | | |
| unzip lib3mf_sdk.zip/lib3mf_sdk.zip -d latest_commit_lib3mf_sdk && ls -al | |
| - name: Build CppDynamic with latest commit SDK | |
| run: | | |
| sh latest_commit_lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh | |
| cd latest_commit_lib3mf_sdk/Examples/CppDynamic/build | |
| cmake --build . | |
| ./Example_ExtractInfo ../../Files/Helix.3mf | |
| - name: Restore 3MF test suite cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/3mf-test-suite | |
| key: 3mf-test-suite-v2.0.0 | |
| - name: Unzip integration test suite | |
| run: | | |
| rm -rf test_suites | |
| unzip -o "$HOME/.cache/3mf-test-suite/3MF_Conformance_Test_Suites_v2.0.0.zip" -d test_suites | |
| - name: Copy integration test script | |
| run: | | |
| cp CI/integration_test.py test_suites/ | |
| - name: Copy latest commit SDK to test suite | |
| run: | | |
| cp -r latest_commit_lib3mf_sdk/Examples/CppDynamic/build/* test_suites/ | |
| - name: Run integration tests with latest commit SDK | |
| run: | | |
| cd test_suites && /usr/bin/time -v python integration_test.py 2>&1 | tee latest_commit_sdk_test.log | |
| - name: Clean up latest SDK binaries | |
| run: | | |
| find test_suites -maxdepth 1 -type f ! -name 'integration_test.py' ! -name '*.log' -exec rm -rf {} + | |
| - name: Get latest lib3mf SDK release info from GitHub API | |
| id: get_latest_release | |
| run: | | |
| echo "LATEST_LIB3MF_URL=$(python CI/ci_cd_helper.py fetch-sdk-url 0 | xargs)" >> $GITHUB_ENV | |
| LATEST_RELEASE_NAME=$(curl -s https://api.github.com/repos/3MFConsortium/lib3mf/releases/latest | grep '"tag_name"' | cut -d '"' -f 4) | |
| echo "LATEST_RELEASE_NAME=${LATEST_RELEASE_NAME}" >> $GITHUB_ENV | |
| - name: Download latest lib3mf SDK release zip | |
| run: | | |
| wget ${{ env.LATEST_LIB3MF_URL }} -O latest_release_lib3mf_sdk.zip | |
| - name: Unpack the SDK from latest release | |
| run: | | |
| unzip latest_release_lib3mf_sdk.zip -d latest_release_lib3mf_sdk | |
| mv latest_release_lib3mf_sdk/lib3mf_sdk/* latest_release_lib3mf_sdk/ | |
| rmdir latest_release_lib3mf_sdk/lib3mf_sdk/ | |
| - name: Build CppDynamic with latest release SDK | |
| run: | | |
| sh latest_release_lib3mf_sdk/Examples/CppDynamic/GenerateMake.sh | |
| cd latest_release_lib3mf_sdk/Examples/CppDynamic/build | |
| cmake --build . | |
| ./Example_ExtractInfo ../../Files/Helix.3mf | |
| - name: Copy latest release SDK to test suite | |
| run: | | |
| cp -r latest_release_lib3mf_sdk/Examples/CppDynamic/build/* test_suites/ | |
| - name: Run integration tests with latest release SDK | |
| run: | | |
| cd test_suites && /usr/bin/time -v python integration_test.py 2>&1 | tee latest_release_sdk_test.log | |
| - name: Compare results (Checks the total python script execution time) | |
| id: compare_results | |
| run: | | |
| # Extract detailed lists from logs for diffing | |
| grep -E 'MUSTPASS file ".*" does not work' test_suites/latest_commit_sdk_test.log | sed -n 's/.*MUSTPASS file "\([^"]*\)".*/\1/p' | sort -u > test_suites/latest_commit_mp_failed.txt || true | |
| grep -E 'MUSTFAIL file ".*" works' test_suites/latest_commit_sdk_test.log | sed -n 's/.*MUSTFAIL file "\([^"]*\)".*/\1/p' | sort -u > test_suites/latest_commit_mf_passed.txt || true | |
| grep -E 'MUSTPASS file ".*" does not work' test_suites/latest_release_sdk_test.log | sed -n 's/.*MUSTPASS file "\([^"]*\)".*/\1/p' | sort -u > test_suites/latest_release_mp_failed.txt || true | |
| grep -E 'MUSTFAIL file ".*" works' test_suites/latest_release_sdk_test.log | sed -n 's/.*MUSTFAIL file "\([^"]*\)".*/\1/p' | sort -u > test_suites/latest_release_mf_passed.txt || true | |
| echo "=== Latest commit MUSTPASS failed:"; cat test_suites/latest_commit_mp_failed.txt || true | |
| echo "=== Latest release MUSTPASS failed:"; cat test_suites/latest_release_mp_failed.txt || true | |
| echo "=== Latest commit MUSTFAIL passed:"; cat test_suites/latest_commit_mf_passed.txt || true | |
| echo "=== Latest release MUSTFAIL passed:"; cat test_suites/latest_release_mf_passed.txt || true | |
| LATEST_COMMIT_TIME=$(grep "Elapsed (wall clock) time" test_suites/latest_commit_sdk_test.log | awk '{print $8}') | |
| LATEST_RELEASE_TIME=$(grep "Elapsed (wall clock) time" test_suites/latest_release_sdk_test.log | awk '{print $8}') | |
| LATEST_COMMIT_TOTAL_SECONDS=$(echo $LATEST_COMMIT_TIME | awk -F: '{ print ($1 * 60) + $2 }') | |
| LATEST_RELEASE_TOTAL_SECONDS=$(echo $LATEST_RELEASE_TIME | awk -F: '{ print ($1 * 60) + $2 }') | |
| echo "Latest commit SDK execution time in seconds: ${LATEST_COMMIT_TOTAL_SECONDS}" | |
| echo "Latest release SDK execution time in seconds: ${LATEST_RELEASE_TOTAL_SECONDS}" | |
| LATEST_COMMIT_MUSTPASS=$(grep "MUSTPASS files passed" test_suites/latest_commit_sdk_test.log | awk '{print $1}') | |
| LATEST_TOTAL_COMMIT_MUSTPASS=$(grep "MUSTPASS files passed" test_suites/latest_commit_sdk_test.log | awk '{print $3}' | tr -d '()') | |
| LATEST_RELEASE_MUSTPASS=$(grep "MUSTPASS files passed" test_suites/latest_release_sdk_test.log | awk '{print $1}') | |
| LATEST_TOTAL_RELEASE_MUSTPASS=$(grep "MUSTPASS files passed" test_suites/latest_release_sdk_test.log | awk '{print $3}' | tr -d '()') | |
| LATEST_COMMIT_MUSTFAIL=$(grep "MUSTFAIL files failed" test_suites/latest_commit_sdk_test.log | awk '{print $1}') | |
| LATEST_TOTAL_COMMIT_MUSTFAIL=$(grep "MUSTFAIL files failed" test_suites/latest_commit_sdk_test.log | awk '{print $3}' | tr -d '()') | |
| LATEST_RELEASE_MUSTFAIL=$(grep "MUSTFAIL files failed" test_suites/latest_release_sdk_test.log | awk '{print $1}') | |
| LATEST_TOTAL_RELEASE_MUSTFAIL=$(grep "MUSTFAIL files failed" test_suites/latest_release_sdk_test.log | awk '{print $3}' | tr -d '()') | |
| echo "Latest commit MUSTPASS: ${LATEST_COMMIT_MUSTPASS} / ${LATEST_TOTAL_COMMIT_MUSTPASS}" | |
| echo "Latest release MUSTPASS: ${LATEST_RELEASE_MUSTPASS} / ${LATEST_TOTAL_RELEASE_MUSTPASS}" | |
| echo "Latest commit MUSTFAIL: ${LATEST_COMMIT_MUSTFAIL} / ${LATEST_TOTAL_COMMIT_MUSTFAIL}" | |
| echo "Latest release MUSTFAIL: ${LATEST_RELEASE_MUSTFAIL} / ${LATEST_TOTAL_RELEASE_MUSTFAIL}" | |
| # Compare MUSTPASS and MUSTFAIL counts | |
| # Allow improvements: pass if latest commit >= latest release for both metrics; fail only on regression | |
| if [ "$LATEST_COMMIT_MUSTPASS" -lt "$LATEST_RELEASE_MUSTPASS" ] || [ "$LATEST_COMMIT_MUSTFAIL" -lt "$LATEST_RELEASE_MUSTFAIL" ]; then | |
| echo "MUSTPASS or MUSTFAIL counts have regressed" | |
| # Highlight exactly which files changed outcome | |
| comm -23 test_suites/latest_commit_mp_failed.txt test_suites/latest_release_mp_failed.txt > test_suites/regressions_commit_mp_now_failing.txt || true | |
| comm -23 test_suites/latest_commit_mf_passed.txt test_suites/latest_release_mf_passed.txt > test_suites/regressions_commit_mf_now_passing.txt || true | |
| echo "=== Regressions (commit vs release) - MUSTPASS now failing:"; cat test_suites/regressions_commit_mp_now_failing.txt || true | |
| echo "=== Regressions (commit vs release) - MUSTFAIL now passing:"; cat test_suites/regressions_commit_mf_now_passing.txt || true | |
| { | |
| echo "### Latest commit vs latest release - regressions"; | |
| echo "#### MUSTPASS now failing"; sed 's/^/- /' test_suites/regressions_commit_mp_now_failing.txt 2>/dev/null || true; echo; | |
| echo "#### MUSTFAIL now passing"; sed 's/^/- /' test_suites/regressions_commit_mf_now_passing.txt 2>/dev/null || true; echo; | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| exit 1 | |
| else | |
| echo "MUSTPASS and MUSTFAIL counts have improved or stayed the same" | |
| fi | |
| # Compare the total seconds | |
| if (( $(echo "$LATEST_COMMIT_TOTAL_SECONDS < $LATEST_RELEASE_TOTAL_SECONDS" | bc -l) )); then | |
| echo "Latest commit is better" | |
| else | |
| echo "Latest release is better" | |
| fi | |
| echo "Latest commit with SHA ${{ github.sha }} ran in ${LATEST_COMMIT_TOTAL_SECONDS} seconds" > results.txt | |
| echo "Latest release with tag ${{ env.LATEST_RELEASE_NAME }} ran in ${LATEST_RELEASE_TOTAL_SECONDS} seconds" >> results.txt | |
| echo "Latest commit MUSTPASS: ${LATEST_COMMIT_MUSTPASS} / ${LATEST_TOTAL_COMMIT_MUSTPASS}" >> results.txt | |
| echo "Latest release MUSTPASS: ${LATEST_RELEASE_MUSTPASS} / ${LATEST_TOTAL_RELEASE_MUSTPASS}" >> results.txt | |
| echo "Latest commit MUSTFAIL: ${LATEST_COMMIT_MUSTFAIL} / ${LATEST_TOTAL_COMMIT_MUSTFAIL}" >> results.txt | |
| echo "Latest release MUSTFAIL: ${LATEST_RELEASE_MUSTFAIL} / ${LATEST_TOTAL_RELEASE_MUSTFAIL}" >> results.txt | |
| - name: Upload results artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: integration-test-results | |
| path: results.txt |