diff --git a/.github/workflows/ci-comprehensive-build-test.yml b/.github/workflows/ci-comprehensive-build-test.yml index f80a58011..286d7280b 100644 --- a/.github/workflows/ci-comprehensive-build-test.yml +++ b/.github/workflows/ci-comprehensive-build-test.yml @@ -18,7 +18,6 @@ name: "ci-build-matrix" permissions: contents: read - pull-requests: read on: workflow_dispatch: @@ -49,7 +48,7 @@ env: jobs: ############################################################################# - # Job 1: Standard Project Builds (Tools Only - No Fuzzing) + # Job 1: Standard Project Builds ############################################################################# standard-builds: name: "Standard • ${{ matrix.os }} • ${{ matrix.compiler }} • ${{ matrix.build_type }}" @@ -107,6 +106,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --global --add safe.directory "$GITHUB_WORKSPACE" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -118,6 +118,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -135,6 +136,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -147,6 +149,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true sed -i.bak 's/^ find_package(wxWidgets COMPONENTS core base REQUIRED)/ # find_package(wxWidgets COMPONENTS core base REQUIRED) # Disabled for CFL/g' Build/Cmake/CMakeLists.txt sed -i.bak 's/^ ADD_SUBDIRECTORY(Tools\/wxProfileDump)/ # ADD_SUBDIRECTORY(Tools\/wxProfileDump) # Disabled for CFL/g' Build/Cmake/CMakeLists.txt sed -i.bak 's/^ message(FATAL_ERROR "wxWidgets not found/ # message(FATAL_ERROR "wxWidgets not found/g' Build/Cmake/CMakeLists.txt @@ -155,31 +158,35 @@ jobs: shell: bash --noprofile --norc {0} env: BASH_ENV: /dev/null + MATRIX_COMPILER: ${{ matrix.compiler }} run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true - if [ "${{ matrix.compiler }}" = "gcc" ]; then - echo "CC=gcc" >> $GITHUB_ENV - echo "CXX=g++" >> $GITHUB_ENV + if [ "$MATRIX_COMPILER" = "gcc" ]; then + echo "CC=gcc" >> "$GITHUB_ENV" + echo "CXX=g++" >> "$GITHUB_ENV" else - echo "CC=clang" >> $GITHUB_ENV - echo "CXX=clang++" >> $GITHUB_ENV + echo "CC=clang" >> "$GITHUB_ENV" + echo "CXX=clang++" >> "$GITHUB_ENV" fi - name: Configure CMake shell: bash --noprofile --norc {0} env: BASH_ENV: /dev/null + MATRIX_BUILD_TYPE: ${{ matrix.build_type }} run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true mkdir -p Build && cd Build cmake ../Build/Cmake \ - -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ + -DCMAKE_BUILD_TYPE="$MATRIX_BUILD_TYPE" \ -DENABLE_SHARED_LIBS=ON \ -DENABLE_STATIC_LIBS=ON \ -DENABLE_TOOLS=ON @@ -188,8 +195,10 @@ jobs: shell: bash --noprofile --norc {0} env: BASH_ENV: /dev/null + MATRIX_COMPILER: ${{ matrix.compiler }} run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -197,8 +206,13 @@ jobs: # Enable ccache if available if command -v ccache >/dev/null 2>&1; then export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - export CC="ccache ${{ matrix.compiler == 'gcc' && 'gcc' || 'clang' }}" - export CXX="ccache ${{ matrix.compiler == 'gcc' && 'g++' || 'clang++' }}" + if [ "$MATRIX_COMPILER" = "gcc" ]; then + export CC="ccache gcc" + export CXX="ccache g++" + else + export CC="ccache clang" + export CXX="ccache clang++" + fi fi cd Build @@ -254,6 +268,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -270,196 +285,7 @@ jobs: fi ############################################################################# - # Job 2: Fuzzer Builds (Debug + Full Instrumentation) - ############################################################################# - fuzzer-builds: - name: "Fuzzer • ${{ matrix.os }} • Debug+Instrumentation" - runs-on: ${{ matrix.os }} - timeout-minutes: 30 - defaults: - run: - shell: bash --noprofile --norc {0} - - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest] - - steps: - - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - ref: ${{ env.CHECKOUT_REF }} - fetch-depth: 0 - persist-credentials: false - - - name: Cache Dependencies - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - with: - path: | - /var/cache/apt/archives - ~/.cache/ccache - key: fuzzer-deps-${{ hashFiles('Build/Cmake/CMakeLists.txt', 'Testing/Fuzzing/CMakeLists.txt') }} - restore-keys: | - fuzzer-deps- - - - name: Configure Git Environment - shell: bash --noprofile --norc {0} - env: - BASH_ENV: /dev/null - run: | - set -euo pipefail - git config --global --add safe.directory "$GITHUB_WORKSPACE" - git config --global credential.helper "" - unset GITHUB_TOKEN || true - - - name: Install Dependencies - shell: bash --noprofile --norc {0} - env: - BASH_ENV: /dev/null - run: | - set -euo pipefail - git config --add safe.directory "$PWD" - git config --global credential.helper "" - unset GITHUB_TOKEN || true - sudo apt-get update -qq - sudo apt-get install -y \ - build-essential cmake clang llvm ccache \ - libpng-dev libxml2-dev libtiff-dev nlohmann-json3-dev - ccache --zero-stats || true - - - name: Disable wxWidgets for CFL - shell: bash --noprofile --norc {0} - env: - BASH_ENV: /dev/null - run: | - set -euo pipefail - sed -i 's/^ find_package(wxWidgets COMPONENTS core base REQUIRED)/# find_package(wxWidgets COMPONENTS core base REQUIRED) # Disabled for CFL/g' Build/Cmake/CMakeLists.txt - sed -i 's/^ ADD_SUBDIRECTORY(Tools\/wxProfileDump)/# ADD_SUBDIRECTORY(Tools\/wxProfileDump) # Disabled for CFL/g' Build/Cmake/CMakeLists.txt - sed -i 's/^ message(FATAL_ERROR "wxWidgets not found/ # message(FATAL_ERROR "wxWidgets not found/g' Build/Cmake/CMakeLists.txt - - - name: Configure Fuzzer Build - shell: bash --noprofile --norc {0} - env: - BASH_ENV: /dev/null - run: | - set -euo pipefail - git config --add safe.directory "$PWD" - git config --global credential.helper "" - unset GITHUB_TOKEN || true - mkdir -p Build-fuzzing && cd Build-fuzzing - CC=clang CXX=clang++ cmake ../Build/Cmake \ - -DCMAKE_BUILD_TYPE=Debug \ - -DENABLE_FUZZING=ON \ - -DENABLE_STATIC_LIBS=ON \ - -DENABLE_SHARED_LIBS=ON \ - -DENABLE_TOOLS=OFF - - - name: Build Fuzzers - shell: bash --noprofile --norc {0} - env: - BASH_ENV: /dev/null - run: | - set -euo pipefail - git config --add safe.directory "$PWD" - git config --global credential.helper "" - unset GITHUB_TOKEN || true - # Enable ccache - if command -v ccache >/dev/null 2>&1; then - export PATH="/usr/lib/ccache:$PATH" - export CC="ccache clang" - export CXX="ccache clang++" - fi - cd Build-fuzzing - echo "::group::Fuzzer Build Output" - BUILD_START=$(date +%s) - make -j$(nproc) 2>&1 | tee build-fuzzing.log - BUILD_END=$(date +%s) - echo "::endgroup::" - BUILD_TIME=$((BUILD_END - BUILD_START)) - echo "::notice title=Fuzzer Build Time::Fuzzer build completed in ${BUILD_TIME}s" - if grep -iE '(error|failed|undefined reference|cannot find)' build-fuzzing.log; then - echo "::error title=Fuzzer Build Failed::Fuzzer build errors detected" - exit 1 - fi - # Show ccache stats - if command -v ccache >/dev/null 2>&1; then - echo "::group::ccache Statistics" - ccache --show-stats || true - echo "::endgroup::" - fi - - - name: Verify Fuzzer Build - shell: bash --noprofile --norc {0} - env: - BASH_ENV: /dev/null - run: | - set -euo pipefail - git config --add safe.directory "$PWD" - git config --global credential.helper "" - unset GITHUB_TOKEN || true - FUZZER_COUNT=$(ls Build-fuzzing/Testing/Fuzzing/icc_*_fuzzer 2>/dev/null | wc -l) - echo "::notice title=Fuzzer Count::Built $FUZZER_COUNT fuzzers" - # Note: Fuzzer count varies by platform and configuration - # Just verify at least 1 fuzzer was built - if [ "$FUZZER_COUNT" -lt 1 ]; then - echo "::error title=Fuzzer Verification Failed::Expected at least 1 fuzzer, got $FUZZER_COUNT" - exit 1 - fi - - - name: Upload Fuzzer Build Artifacts (on failure) - if: failure() - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 - with: - name: fuzzer-build-logs - path: | - Build-fuzzing/build-fuzzing.log - Build-fuzzing/CMakeCache.txt - Build-fuzzing/CMakeFiles/CMakeError.log - Build-fuzzing/CMakeFiles/CMakeOutput.log - Build-fuzzing/Testing/Fuzzing/*.log - retention-days: 7 - - - name: Upload Fuzzer Executables (on success) - if: success() - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 - with: - name: fuzzer-executables-debug-instrumentation - path: Build-fuzzing/Testing/Fuzzing/*_fuzzer - retention-days: 14 - compression-level: 9 - - - name: Test Fuzzers - shell: bash --noprofile --norc {0} - env: - BASH_ENV: /dev/null - run: | - set -euo pipefail - git config --add safe.directory "$PWD" - git config --global credential.helper "" - unset GITHUB_TOKEN || true - cd Build-fuzzing/Testing/Fuzzing - # Verify all 14 fuzzers are built and executable - EXPECTED_FUZZERS="icc_apply_fuzzer icc_applynamedcmm_fuzzer icc_applyprofiles_fuzzer icc_calculator_fuzzer icc_dump_fuzzer icc_fromxml_fuzzer icc_io_fuzzer icc_link_fuzzer icc_multitag_fuzzer icc_profile_fuzzer icc_roundtrip_fuzzer icc_spectral_fuzzer icc_toxml_fuzzer icc_v5dspobs_fuzzer" - PASS=0 - FAIL=0 - for f in $EXPECTED_FUZZERS; do - if [ -x "$f" ]; then - PASS=$((PASS + 1)) - echo "✓ $f" - else - FAIL=$((FAIL + 1)) - echo "✗ $f (not found or not executable)" - fi - done - echo "::notice title=Fuzzer Build Verification::$PASS of 14 fuzzers built successfully" - if [ "$FAIL" -gt 0 ]; then - echo "::error title=Fuzzer Build Failed::$FAIL fuzzers missing or not executable" - exit 1 - fi - - ############################################################################# - # Job 3: Sanitizer Builds (Individual Sanitizers) + # Job 2: Sanitizer Builds (Individual Sanitizers) ############################################################################# sanitizer-builds: name: "Sanitizer • ${{ matrix.sanitizer }} • ${{ matrix.build_type }}" @@ -506,6 +332,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --global --add safe.directory "$GITHUB_WORKSPACE" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -516,6 +343,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -530,6 +358,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true sed -i 's/^ find_package(wxWidgets COMPONENTS core base REQUIRED)/# find_package(wxWidgets COMPONENTS core base REQUIRED) # Disabled for CFL/g' Build/Cmake/CMakeLists.txt sed -i 's/^ ADD_SUBDIRECTORY(Tools\/wxProfileDump)/# ADD_SUBDIRECTORY(Tools\/wxProfileDump) # Disabled for CFL/g' Build/Cmake/CMakeLists.txt sed -i 's/^ message(FATAL_ERROR "wxWidgets not found/ # message(FATAL_ERROR "wxWidgets not found/g' Build/Cmake/CMakeLists.txt @@ -538,13 +367,16 @@ jobs: shell: bash --noprofile --norc {0} env: BASH_ENV: /dev/null + MATRIX_SANITIZER: ${{ matrix.sanitizer }} + MATRIX_BUILD_TYPE: ${{ matrix.build_type }} run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true mkdir -p Build && cd Build - case "${{ matrix.sanitizer }}" in + case "$MATRIX_SANITIZER" in asan) OPTS="-DENABLE_ASAN=ON" ;; @@ -556,7 +388,7 @@ jobs: ;; esac CC=clang CXX=clang++ cmake ../Build/Cmake \ - -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ + -DCMAKE_BUILD_TYPE="$MATRIX_BUILD_TYPE" \ $OPTS - name: Build with Sanitizer @@ -565,6 +397,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -581,6 +414,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -605,7 +439,7 @@ jobs: compression-level: 9 ############################################################################# - # Job 4: Build Option Matrix (Test Each Option Independently) + # Job 3: Build Option Matrix (Test Each Option Independently) ############################################################################# option-matrix: name: "Option • ${{ matrix.option_name }}" @@ -646,6 +480,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --global --add safe.directory "$GITHUB_WORKSPACE" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -656,6 +491,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -670,6 +506,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true sed -i 's/^ find_package(wxWidgets COMPONENTS core base REQUIRED)/# find_package(wxWidgets COMPONENTS core base REQUIRED) # Disabled for CFL/g' Build/Cmake/CMakeLists.txt sed -i 's/^ ADD_SUBDIRECTORY(Tools\/wxProfileDump)/# ADD_SUBDIRECTORY(Tools\/wxProfileDump) # Disabled for CFL/g' Build/Cmake/CMakeLists.txt sed -i 's/^ message(FATAL_ERROR "wxWidgets not found/ # message(FATAL_ERROR "wxWidgets not found/g' Build/Cmake/CMakeLists.txt @@ -678,15 +515,17 @@ jobs: shell: bash --noprofile --norc {0} env: BASH_ENV: /dev/null + MATRIX_CMAKE_OPTS: ${{ matrix.cmake_opts }} run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true mkdir -p Build && cd Build cmake Cmake/ \ -DCMAKE_BUILD_TYPE=Release \ - ${{ matrix.cmake_opts }} + $MATRIX_CMAKE_OPTS - name: Build shell: bash --noprofile --norc {0} @@ -694,6 +533,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -705,7 +545,7 @@ jobs: fi ############################################################################# - # Job 5: Windows Build (MSVC) + # Job 4: Windows Build (MSVC) ############################################################################# windows-build: name: "Windows • MSVC • ${{ matrix.build_type }}" @@ -756,6 +596,8 @@ jobs: - name: Configure shell: pwsh + env: + MATRIX_BUILD_TYPE: ${{ matrix.build_type }} run: | Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' @@ -765,19 +607,21 @@ jobs: cmake -B build -S . ` -DCMAKE_TOOLCHAIN_FILE="..\..\scripts\buildsystems\vcpkg.cmake" ` -DVCPKG_MANIFEST_MODE=OFF ` - -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} ` + -DCMAKE_BUILD_TYPE="$env:MATRIX_BUILD_TYPE" ` -Wno-dev - name: Build shell: pwsh + env: + MATRIX_BUILD_TYPE: ${{ matrix.build_type }} run: | Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $ProgressPreference = 'SilentlyContinue' if (Test-Path Env:GITHUB_TOKEN) { Remove-Item Env:GITHUB_TOKEN -ErrorAction SilentlyContinue } cd Build/Cmake - cmake --build build --config ${{ matrix.build_type }} -- /m /maxcpucount - cmake --build build --config ${{ matrix.build_type }} -- /m /maxcpucount + cmake --build build --config "$env:MATRIX_BUILD_TYPE" -- /m /maxcpucount + cmake --build build --config "$env:MATRIX_BUILD_TYPE" -- /m /maxcpucount - name: Test shell: pwsh @@ -796,7 +640,7 @@ jobs: .\CreateAllProfiles.bat ############################################################################# - # Job 6: Version Header Generation Test + # Job 5: Version Header Generation Test ############################################################################# version-header-test: name: "Version Headers • Build Directory Generation" @@ -820,6 +664,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --global --add safe.directory "$GITHUB_WORKSPACE" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -830,6 +675,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -842,6 +688,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true sed -i 's/^ find_package(wxWidgets COMPONENTS core base REQUIRED)/# find_package(wxWidgets COMPONENTS core base REQUIRED) # Disabled for CFL/g' Build/Cmake/CMakeLists.txt sed -i 's/^ ADD_SUBDIRECTORY(Tools\/wxProfileDump)/# ADD_SUBDIRECTORY(Tools\/wxProfileDump) # Disabled for CFL/g' Build/Cmake/CMakeLists.txt sed -i 's/^ message(FATAL_ERROR "wxWidgets not found/ # message(FATAL_ERROR "wxWidgets not found/g' Build/Cmake/CMakeLists.txt @@ -852,6 +699,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -865,6 +713,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -879,7 +728,7 @@ jobs: echo "✅ Version headers correctly generated in build directory" ############################################################################# - # Job 7: Clean/Rebuild Cycle Test + # Job 6: Clean/Rebuild Cycle Test ############################################################################# clean-rebuild-test: name: "Clean/Rebuild Cycle Test" @@ -903,6 +752,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --global --add safe.directory "$GITHUB_WORKSPACE" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -913,6 +763,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -925,6 +776,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true sed -i 's/^ find_package(wxWidgets COMPONENTS core base REQUIRED)/# find_package(wxWidgets COMPONENTS core base REQUIRED) # Disabled for CFL/g' Build/Cmake/CMakeLists.txt sed -i 's/^ ADD_SUBDIRECTORY(Tools\/wxProfileDump)/# ADD_SUBDIRECTORY(Tools\/wxProfileDump) # Disabled for CFL/g' Build/Cmake/CMakeLists.txt sed -i 's/^ message(FATAL_ERROR "wxWidgets not found/ # message(FATAL_ERROR "wxWidgets not found/g' Build/Cmake/CMakeLists.txt @@ -935,6 +787,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -943,7 +796,7 @@ jobs: make -j$(nproc) TOOL_COUNT_1=$(find Tools -type f -executable | wc -l) echo "Initial build: $TOOL_COUNT_1 tools" - echo "TOOL_COUNT_1=$TOOL_COUNT_1" >> $GITHUB_ENV + echo "TOOL_COUNT_1=$TOOL_COUNT_1" >> "$GITHUB_ENV" - name: Clean shell: bash --noprofile --norc {0} @@ -951,6 +804,7 @@ jobs: BASH_ENV: /dev/null run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -967,8 +821,10 @@ jobs: shell: bash --noprofile --norc {0} env: BASH_ENV: /dev/null + TOOL_COUNT_1: ${{ env.TOOL_COUNT_1 }} run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true git config --add safe.directory "$PWD" git config --global credential.helper "" unset GITHUB_TOKEN || true @@ -976,19 +832,19 @@ jobs: make -j$(nproc) TOOL_COUNT_2=$(find Tools -type f -executable | wc -l) echo "After rebuild: $TOOL_COUNT_2 tools" - if [ "$TOOL_COUNT_2" -ne "${{ env.TOOL_COUNT_1 }}" ]; then - echo "ERROR: Rebuild produced different number of tools ($TOOL_COUNT_2 vs ${{ env.TOOL_COUNT_1 }})" + if [ "$TOOL_COUNT_2" -ne "$TOOL_COUNT_1" ]; then + echo "ERROR: Rebuild produced different number of tools ($TOOL_COUNT_2 vs $TOOL_COUNT_1)" exit 1 fi echo "✅ Clean/rebuild cycle successful" ############################################################################# - # Job 8: Final Summary + # Job 7: Final Summary ############################################################################# final-summary: name: "Test Summary" runs-on: ubuntu-latest - needs: [standard-builds, fuzzer-builds, sanitizer-builds, option-matrix, windows-build, version-header-test, clean-rebuild-test] + needs: [standard-builds, sanitizer-builds, option-matrix, windows-build, version-header-test, clean-rebuild-test] if: always() steps: @@ -996,8 +852,15 @@ jobs: shell: bash --noprofile --norc {0} env: BASH_ENV: /dev/null + RESULT_STANDARD: ${{ needs.standard-builds.result }} + RESULT_SANITIZER: ${{ needs.sanitizer-builds.result }} + RESULT_OPTION: ${{ needs.option-matrix.result }} + RESULT_WINDOWS: ${{ needs.windows-build.result }} + RESULT_VERSION: ${{ needs.version-header-test.result }} + RESULT_CLEAN: ${{ needs.clean-rebuild-test.result }} run: | set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true { echo "# Comprehensive Build & Test Results" echo "" @@ -1031,9 +894,6 @@ jobs: echo "- ✅ Shared libs only" echo "- ✅ Static libs only" echo "" - echo "### Fuzzing" - echo "- ✅ 14 libFuzzer harnesses (Debug + Full Instrumentation)" - echo "" echo "### Special Tests" echo "- ✅ Version header generation (build directory)" echo "- ✅ Clean source tree after build" @@ -1043,16 +903,15 @@ jobs: echo "" echo "| Job | Status |" echo "|-----|--------|" - echo "| Standard Builds | ${{ needs.standard-builds.result }} |" - echo "| Fuzzer Builds | ${{ needs.fuzzer-builds.result }} |" - echo "| Sanitizer Builds | ${{ needs.sanitizer-builds.result }} |" - echo "| Option Matrix | ${{ needs.option-matrix.result }} |" - echo "| Windows Build | ${{ needs.windows-build.result }} |" - echo "| Version Header Test | ${{ needs.version-header-test.result }} |" - echo "| Clean/Rebuild Test | ${{ needs.clean-rebuild-test.result }} |" + echo "| Standard Builds | $(sanitize_line "$RESULT_STANDARD") |" + echo "| Sanitizer Builds | $(sanitize_line "$RESULT_SANITIZER") |" + echo "| Option Matrix | $(sanitize_line "$RESULT_OPTION") |" + echo "| Windows Build | $(sanitize_line "$RESULT_WINDOWS") |" + echo "| Version Header Test | $(sanitize_line "$RESULT_VERSION") |" + echo "| Clean/Rebuild Test | $(sanitize_line "$RESULT_CLEAN") |" echo "" echo "---" echo "" echo "**Compliance:** Hoyt shell/PowerShell prologue standards" echo "**Reference:** llmcjf/actions/" - } >> $GITHUB_STEP_SUMMARY + } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/ci-docker-latest.yml b/.github/workflows/ci-docker-latest.yml new file mode 100644 index 000000000..9af1bcb35 --- /dev/null +++ b/.github/workflows/ci-docker-latest.yml @@ -0,0 +1,210 @@ +############################################################### +# +# Copyright (c) 2025-2026 International Color Consortium. +# All rights reserved. +# https://color.org +# +# +# Intent: ci-docker-latest +# +# Last Updated: 026-02-13 14:45:57 UTC by David Hoyt +# Update Branch Info +# Test sbom + attest & Test +# Add: artifact-metadata: write +# +# +# +# +############################################################### +# Intent: Build and publish iccDEV Docker container Release +############################################################### + +name: ci-docker-latest + +permissions: + contents: read + packages: write + id-token: write + attestations: write + artifact-metadata: write + +on: + workflow_dispatch: + push: + branches: [master, dockerfiles] + paths: + - 'Dockerfile' + - '.github/workflows/ci-docker-latest.yml' + +jobs: + build: + name: "Build iccDEV Docker" + runs-on: ubuntu-latest + timeout-minutes: 30 + defaults: + run: + shell: bash --noprofile --norc {0} + + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Lowercase image name + id: image + run: echo "name=ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/iccdev" >> "$GITHUB_OUTPUT" + + - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 + + - name: Docker meta + id: meta + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 + with: + images: ${{ steps.image.outputs.name }} + tags: | + type=sha + type=raw,value=latest,enable={{is_default_branch}} + - name: Log in to GHCR + if: github.event_name != 'pull_request' + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + id: build-push + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2 + with: + context: . + file: ./Dockerfile + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + provenance: mode=max + sbom: true + + - name: Generate SBOM + if: github.event_name != 'pull_request' + uses: anchore/sbom-action@2d094306a78d7bde297684f0120dfb41969c38c2 # v0.22.2 + with: + image: ${{ steps.image.outputs.name }}@${{ steps.build-push.outputs.digest }} + format: spdx-json + output-file: sbom.spdx.json + + - name: Attest build provenance + if: github.event_name != 'pull_request' + uses: actions/attest-build-provenance@c44148e5bf178192efd8947e07a0d439a356c60b # v3.2.0 + with: + subject-name: ${{ steps.image.outputs.name }} + subject-digest: ${{ steps.build-push.outputs.digest }} + push-to-registry: true + + - name: Attest SBOM + if: github.event_name != 'pull_request' + uses: actions/attest-sbom@b74e95116c27d38263fc426c93ebfca07aa6197b # v3.0.0 + with: + subject-name: ${{ steps.image.outputs.name }} + subject-digest: ${{ steps.build-push.outputs.digest }} + sbom-path: sbom.spdx.json + push-to-registry: true + + - name: Upload SBOM + if: github.event_name != 'pull_request' + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: iccdev-sbom + path: sbom.spdx.json + retention-days: 90 + + - name: Build local test image + run: docker build -f Dockerfile -t iccdev-test:latest . + + - name: Verify tools + env: + BASH_ENV: /dev/null + run: | + set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true + git config --add safe.directory "$PWD" + git config --global credential.helper "" + unset GITHUB_TOKEN || true + TOOL_COUNT=$(docker run --rm iccdev-test:latest bash -c \ + 'find /opt/iccdev/Build/Tools -type f -executable | wc -l') + echo "Tools built: $TOOL_COUNT" + if [ "$TOOL_COUNT" -lt 12 ]; then + echo "::error::Expected at least 12 tools, found $TOOL_COUNT" + exit 1 + fi + MISSING=$(docker run --rm iccdev-test:latest bash -c \ + 'ldd /opt/iccdev/Build/Tools/IccToXml/iccToXml 2>&1 | grep -c "not found" || true') + if [ "$MISSING" != "0" ]; then + echo "::error::Missing runtime shared libraries" + docker run --rm iccdev-test:latest bash -c \ + 'ldd /opt/iccdev/Build/Tools/IccToXml/iccToXml 2>&1 | grep "not found"' + exit 1 + fi + echo "### Build Results" >> "$GITHUB_STEP_SUMMARY" + echo "- Tools: $(sanitize_line "$TOOL_COUNT")" >> "$GITHUB_STEP_SUMMARY" + echo "- Runtime deps: All resolved ✅" >> "$GITHUB_STEP_SUMMARY" + TOOL_LIST=$(docker run --rm iccdev-test:latest bash -c \ + 'find /opt/iccdev/Build/Tools -type f -executable -exec basename {} \; | sort') + { + echo '```' + sanitize_print "$TOOL_LIST" + echo '' + echo '```' + } >> "$GITHUB_STEP_SUMMARY" + - name: Test tool execution + env: + BASH_ENV: /dev/null + run: | + set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true + git config --add safe.directory "$PWD" + git config --global credential.helper "" + unset GITHUB_TOKEN || true + FAILURES=0 + echo "### Tool Tests" >> "$GITHUB_STEP_SUMMARY" + for tool in iccToXml iccFromXml iccDumpProfile iccRoundTrip; do + OUT=$(docker run --rm iccdev-test:latest "$tool" 2>&1 || true) + if echo "$OUT" | grep -qiE "Usage:|IccProfLib"; then + echo "✅ $tool" >> "$GITHUB_STEP_SUMMARY" + else + echo "::error::Tool test failed: $tool" + echo "❌ $tool" >> "$GITHUB_STEP_SUMMARY" + FAILURES=$((FAILURES + 1)) + fi + done + if [ "$FAILURES" -gt 0 ]; then + echo "::error::$FAILURES tool test(s) failed" + exit 1 + fi + - name: Test iccToXml profile conversion + env: + BASH_ENV: /dev/null + run: | + set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true + git config --add safe.directory "$PWD" + git config --global credential.helper "" + unset GITHUB_TOKEN || true + echo "### iccToXml Profile Conversion" >> "$GITHUB_STEP_SUMMARY" + docker run --rm iccdev-test:latest bash -c ' + set -euo pipefail + cd /opt/iccdev + iccToXml Testing/sRGB_v4_ICC_preference.icc /tmp/sRGB_v4.xml + test -s /tmp/sRGB_v4.xml || { echo "ERROR: output XML is empty"; exit 1; } + ls -lh /tmp/sRGB_v4.xml + echo "=== First 20 lines of XML output ===" + head -20 /tmp/sRGB_v4.xml + ' 2>&1 | tee /tmp/iccToXml-output.txt + { + echo '```' + sanitize_print "$(cat /tmp/iccToXml-output.txt)" + echo '' + echo '```' + } >> "$GITHUB_STEP_SUMMARY" + - name: Cleanup + if: always() + run: docker rmi iccdev-test:latest || true \ No newline at end of file diff --git a/.github/workflows/ci-docker-nixos.yml b/.github/workflows/ci-docker-nixos.yml new file mode 100644 index 000000000..a0ce3c1ce --- /dev/null +++ b/.github/workflows/ci-docker-nixos.yml @@ -0,0 +1,201 @@ +############################################################### +# +# Copyright (c) 2025-2026 International Color Consortium. +# All rights reserved. +# https://color.org +# +# +# Intent: ci-docker-nixos +# +# Last Updated: 2026-02-13 13:58:11 UTC by David Hoyt +# Initial workflow with SBOM + attestations +# Test Updated Scoping +# +############################################################### +# Intent: Build and publish iccDEV NixOS Docker container +############################################################### + +name: ci-docker-nixos + +permissions: + contents: read + packages: write + id-token: write + attestations: write + artifact-metadata: write + +on: + workflow_dispatch: + push: + branches: [master, dockerfiles] + paths: + - 'Dockerfile.nixos' + - '.github/workflows/ci-docker-nixos.yml' + +jobs: + build: + name: "Build iccDEV NixOS Docker" + runs-on: ubuntu-latest + timeout-minutes: 45 + defaults: + run: + shell: bash --noprofile --norc {0} + + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Lowercase image name + id: image + run: echo "name=ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/iccdev-nixos" >> "$GITHUB_OUTPUT" + + - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 + + - name: Docker meta + id: meta + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 + with: + images: ${{ steps.image.outputs.name }} + tags: | + type=sha + type=raw,value=latest,enable={{is_default_branch}} + + - name: Log in to GHCR + if: github.event_name != 'pull_request' + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + id: build-push + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2 + with: + context: . + file: ./Dockerfile.nixos + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + provenance: mode=max + sbom: true + + - name: Generate SBOM + if: github.event_name != 'pull_request' + uses: anchore/sbom-action@2d094306a78d7bde297684f0120dfb41969c38c2 # v0.22.2 + with: + image: ${{ steps.image.outputs.name }}@${{ steps.build-push.outputs.digest }} + format: spdx-json + output-file: sbom.spdx.json + + - name: Attest build provenance + if: github.event_name != 'pull_request' + uses: actions/attest-build-provenance@c44148e5bf178192efd8947e07a0d439a356c60b # v3.2.0 + with: + subject-name: ${{ steps.image.outputs.name }} + subject-digest: ${{ steps.build-push.outputs.digest }} + push-to-registry: true + + - name: Attest SBOM + if: github.event_name != 'pull_request' + uses: actions/attest-sbom@b74e95116c27d38263fc426c93ebfca07aa6197b # v3.0.0 + with: + subject-name: ${{ steps.image.outputs.name }} + subject-digest: ${{ steps.build-push.outputs.digest }} + sbom-path: sbom.spdx.json + push-to-registry: true + + - name: Upload SBOM + if: github.event_name != 'pull_request' + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: iccdev-nixos-sbom + path: sbom.spdx.json + retention-days: 90 + + - name: Build local test image + run: docker build -f Dockerfile.nixos -t iccdev-nixos-test:latest . + + - name: Verify tools + env: + BASH_ENV: /dev/null + run: | + set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true + git config --add safe.directory "$PWD" + git config --global credential.helper "" + unset GITHUB_TOKEN || true + TOOL_COUNT=$(docker run --rm iccdev-nixos-test:latest sh -c \ + 'find /workspace/iccDEV/Build/Tools -type f -executable | wc -l') + echo "Tools built: $TOOL_COUNT" + if [ "$TOOL_COUNT" -lt 12 ]; then + echo "::error::Expected at least 12 tools, found $TOOL_COUNT" + exit 1 + fi + echo "### NixOS Build Results" >> "$GITHUB_STEP_SUMMARY" + echo "- Tools: $(sanitize_line "$TOOL_COUNT")" >> "$GITHUB_STEP_SUMMARY" + TOOL_LIST=$(docker run --rm iccdev-nixos-test:latest sh -c \ + 'find /workspace/iccDEV/Build/Tools -type f -executable -exec basename {} \; | sort') + { + echo '```' + sanitize_print "$TOOL_LIST" + echo '' + echo '```' + } >> "$GITHUB_STEP_SUMMARY" + + - name: Test tool execution + env: + BASH_ENV: /dev/null + run: | + set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true + git config --add safe.directory "$PWD" + git config --global credential.helper "" + unset GITHUB_TOKEN || true + FAILURES=0 + echo "### Tool Tests" >> "$GITHUB_STEP_SUMMARY" + for tool in iccToXml iccFromXml iccDumpProfile iccRoundTrip; do + OUT=$(docker run --rm iccdev-nixos-test:latest "$tool" 2>&1 || true) + if echo "$OUT" | grep -qiE "Usage:|IccProfLib"; then + echo "✅ $tool" >> "$GITHUB_STEP_SUMMARY" + else + echo "::error::Tool test failed: $tool" + echo "❌ $tool" >> "$GITHUB_STEP_SUMMARY" + FAILURES=$((FAILURES + 1)) + fi + done + if [ "$FAILURES" -gt 0 ]; then + echo "::error::$FAILURES tool test(s) failed" + exit 1 + fi + + - name: Test iccToXml profile conversion + env: + BASH_ENV: /dev/null + run: | + set -euo pipefail + source .github/scripts/sanitize-sed.sh 2>/dev/null || true + git config --add safe.directory "$PWD" + git config --global credential.helper "" + unset GITHUB_TOKEN || true + echo "### iccToXml Profile Conversion" >> "$GITHUB_STEP_SUMMARY" + docker run --rm iccdev-nixos-test:latest sh -c ' + set -euo pipefail + cd /workspace/iccDEV + iccToXml Testing/sRGB_v4_ICC_preference.icc /tmp/sRGB_v4.xml + test -s /tmp/sRGB_v4.xml || { echo "ERROR: output XML is empty"; exit 1; } + ls -lh /tmp/sRGB_v4.xml + echo "=== First 20 lines of XML output ===" + head -20 /tmp/sRGB_v4.xml + ' 2>&1 | tee /tmp/iccToXml-output.txt + { + echo '```' + sanitize_print "$(cat /tmp/iccToXml-output.txt)" + echo '' + echo '```' + } >> "$GITHUB_STEP_SUMMARY" + + - name: Cleanup + if: always() + run: docker rmi iccdev-nixos-test:latest || true diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..96d0b006b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,60 @@ +############################################################### +# Copyright (c) 2025-2026 International Color Consortium. +# All rights reserved. +# https://color.org +# +# Intent: iccDEV ci-docker-build +# +# Last Updated: 2026-02-12 00:14:22 UTC by David Hoyt +# +############################################################### + +FROM ubuntu:26.04@sha256:fed6ddb82c61194e1814e93b59cfcb6759e5aa33c4e41bb3782313c2386ed6df AS builder +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + build-essential cmake make \ + libxml2-dev nlohmann-json3-dev \ + libtiff-dev libjpeg-dev libpng-dev zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* + +COPY . /opt/iccdev +RUN cd /opt/iccdev \ + && sed -i '/find_package(wxWidgets COMPONENTS core base REQUIRED)/,/endif()/ s/^/# /' Build/Cmake/CMakeLists.txt \ + && cd Build \ + && cmake -DCMAKE_BUILD_TYPE=Release Cmake \ + && make -j"$(nproc)" \ + && rm -rf /opt/iccdev/.git + +RUN echo "=== Libraries ===" \ + && ls -lh /opt/iccdev/Build/IccProfLib/libIccProfLib2* \ + && ls -lh /opt/iccdev/Build/IccXML/libIccXML2* \ + && echo "=== Tools ===" \ + && find /opt/iccdev/Build/Tools -type f -executable | sort + +FROM ubuntu:26.04@sha256:fed6ddb82c61194e1814e93b59cfcb6759e5aa33c4e41bb3782313c2386ed6df +ENV DEBIAN_FRONTEND=noninteractive + +LABEL org.opencontainers.image.title="iccDEV Build Container" \ + org.opencontainers.image.description="Container v2.0.0.82" \ + org.opencontainers.image.licenses="BSD-3-Clause" \ + org.opencontainers.image.vendor="International Color Consortium" \ + org.opencontainers.image.source="https://github.com/InternationalColorConsortium/iccDEV" + +RUN apt-get update && apt-get install -y --no-install-recommends \ + libxml2-16 libtiff6 libjpeg8 libpng16-16t64 zlib1g \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=builder /opt/iccdev /opt/iccdev + +RUN groupadd -r iccdev \ + && useradd -r -g iccdev -d /opt/iccdev -s /bin/bash iccdev \ + && chown -R iccdev:iccdev /opt/iccdev + +ENV PATH="/opt/iccdev/Build/Tools/IccToXml:/opt/iccdev/Build/Tools/IccFromXml:/opt/iccdev/Build/Tools/IccDumpProfile:/opt/iccdev/Build/Tools/IccApplyNamedCmm:/opt/iccdev/Build/Tools/IccRoundTrip:/opt/iccdev/Build/Tools/IccFromCube:/opt/iccdev/Build/Tools/IccApplyProfiles:/opt/iccdev/Build/Tools/IccApplySearch:/opt/iccdev/Build/Tools/IccApplyToLink:/opt/iccdev/Build/Tools/IccJpegDump:/opt/iccdev/Build/Tools/IccPngDump:/opt/iccdev/Build/Tools/IccSpecSepToTiff:/opt/iccdev/Build/Tools/IccTiffDump:/opt/iccdev/Build/Tools/IccV5DspObsToV4Dsp:${PATH}" + +USER iccdev +WORKDIR /opt/iccdev + +CMD ["bash"] \ No newline at end of file diff --git a/Dockerfile.nixos b/Dockerfile.nixos new file mode 100644 index 000000000..862f588f8 --- /dev/null +++ b/Dockerfile.nixos @@ -0,0 +1,138 @@ +############################################################### +# Copyright (c) 2025-2026 International Color Consortium. +# All rights reserved. +# https://color.org +# +# Dockerfile for iccDEV Build Container using NixOS +# Based on nixos/nix Docker image +# +# Last Updated: 2026-02-09 23:50:57 UTC by David Hoyt +# +# Build command: +# docker build -f Dockerfile.nixos -t iccdev-nixos:latest . +# +# Run command: +# docker run -it --rm iccdev-nixos:latest +# +# Testing with volume mount: +# docker run -it --rm -v /path/to/icc/files:/data iccdev-nixos:latest +# +############################################################### + +# Use official NixOS Docker image +FROM nixos/nix:2.33.2@sha256:c6ebd12d96b3374ee15e3986c15aa43f5e49310634f17afcaaf4dafe4f6732b2 + +LABEL org.opencontainers.image.title="iccDEV Build Container (NixOS)" \ + org.opencontainers.image.description="iccDEV built with Nix package manager" \ + org.opencontainers.image.licenses="BSD-3-Clause" \ + org.opencontainers.image.vendor="International Color Consortium" \ + org.opencontainers.image.source="https://github.com/InternationalColorConsortium/iccDEV" \ + org.opencontainers.image.url="https://github.com/InternationalColorConsortium/iccDEV" \ + org.opencontainers.image.documentation="https://github.com/InternationalColorConsortium/iccDEV/tree/master/docs" + +# Set working directory +WORKDIR /workspace + +# Copy source and build using nix-shell +# Build from checked-out source with all dependencies including wxWidgets +COPY . /workspace/iccDEV +RUN nix-shell -p cmake gcc gnumake pkg-config libxml2 libtiff libjpeg libpng nlohmann_json zlib wxGTK32 --run ' \ + export NIX_LDFLAGS="-ltiff $NIX_LDFLAGS" && \ + cd /workspace/iccDEV && \ + echo "=== Building iccDEV ===" && \ + cd Build && \ + cmake -DCMAKE_BUILD_TYPE=Release Cmake && \ + make -j$(nproc) && \ + echo "=== Build Complete ===" && \ + echo "Built tools:" && \ + find ./Tools -name "icc*" -type f -executable | wc -l && \ + echo "Built libraries:" && \ + find . -name "*.so*" -o -name "*.a" | grep -E "IccProf|IccXML" | wc -l \ + ' \ + && rm -rf /workspace/iccDEV/.git + +# Set PATH to include all built tools +ENV PATH="/workspace/iccDEV/Build/Tools/IccApplyNamedCmm:\ +/workspace/iccDEV/Build/Tools/IccApplyProfiles:\ +/workspace/iccDEV/Build/Tools/IccApplySearch:\ +/workspace/iccDEV/Build/Tools/IccApplyToLink:\ +/workspace/iccDEV/Build/Tools/IccDumpProfile:\ +/workspace/iccDEV/Build/Tools/IccFromCube:\ +/workspace/iccDEV/Build/Tools/IccFromXml:\ +/workspace/iccDEV/Build/Tools/IccJpegDump:\ +/workspace/iccDEV/Build/Tools/IccPngDump:\ +/workspace/iccDEV/Build/Tools/IccRoundTrip:\ +/workspace/iccDEV/Build/Tools/IccSpecSepToTiff:\ +/workspace/iccDEV/Build/Tools/IccTiffDump:\ +/workspace/iccDEV/Build/Tools/IccToXml:\ +/workspace/iccDEV/Build/Tools/IccV5DspObsToV4Dsp:\ +/workspace/iccDEV/Build/Tools/wxProfileDump:\ +${PATH}" + +# Set library path +ENV LD_LIBRARY_PATH="/workspace/iccDEV/Build/IccProfLib:/workspace/iccDEV/Build/IccXML" + +# Set working directory to iccDEV +WORKDIR /workspace/iccDEV + +# Create welcome script in workspace +RUN cat > /workspace/welcome.sh << 'EOF' +#!/usr/bin/env sh +echo "" +echo "============================================================" +echo "==== International Color Consortium | https://color.org ====" +echo "==== iccDEV Build Container (NixOS) ========================" +echo "============================================================" +echo "" +echo "All iccDEV tools are available on PATH:" +echo "" +echo "Command-line tools (14):" +echo " - iccApplyNamedCmm - iccFromXml" +echo " - iccApplyProfiles - iccJpegDump" +echo " - iccApplySearch - iccPngDump" +echo " - iccApplyToLink - iccRoundTrip" +echo " - iccDumpProfile - iccSpecSepToTiff" +echo " - iccFromCube - iccTiffDump" +echo " - iccToXml - iccV5DspObsToV4Dsp" +echo "" +echo "GUI tool (1):" +echo " - iccDumpProfileGui" +echo "" +echo "iccDEV Libraries (in /workspace/iccDEV/Build):" +echo "" +echo "Shared Libraries (.so):" +echo " - IccProfLib/libIccProfLib2.so -> libIccProfLib2.so." +echo " - IccXML/libIccXML2.so -> libIccXML2.so." +echo "" +echo "Static Libraries (.a):" +echo " - IccProfLib/libIccProfLib2-static.a" +echo " - IccXML/libIccXML2-static.a" +echo "" +echo "Example usage:" +echo " iccDumpProfile Testing/sRGB_v4_ICC_preference.icc ALL" +echo " iccToXml Testing/sRGB_v4_ICC_preference.icc output.xml" +echo "" +echo "Testing directory: /workspace/iccDEV/Testing" +echo "Build directory: /workspace/iccDEV/Build" +echo "" +echo "To list all tools and libraries:" +echo " find Build/Tools -type f -executable -name 'icc*'" +echo " find Build -name 'libIcc*.so*' -o -name 'libIcc*.a'" +echo "" +echo "To run all tests:" +echo " cd Testing && sh CreateAllProfiles.sh" +echo "" +echo "================================================" +echo "" +EOF + +RUN chmod +x /workspace/welcome.sh + +# Run as non-root user (NixOS manages /etc via symlinks, write entries directly) +RUN echo 'iccdev:x:1000:' >> /etc/group \ + && echo 'iccdev:x:1000:1000:iccdev:/workspace:/bin/sh' >> /etc/passwd \ + && chown -R 1000:1000 /workspace +USER iccdev + +# Default command: show welcome and start interactive shell +CMD ["sh", "-c", "/workspace/welcome.sh && exec sh"]