From 2636c23ca2faa32efcd22e8a065fa8cd671d8c73 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Thu, 24 Jul 2025 18:22:54 +0800 Subject: [PATCH 1/8] .github/workflows/GnuTests.yml: Move variables to env Will make it easier to split the work into 2 jobs. --- .github/workflows/GnuTests.yml | 101 ++++++++++++++++----------------- 1 file changed, 49 insertions(+), 52 deletions(-) diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 74df3792d9a..479ce4b10f7 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -25,6 +25,11 @@ concurrency: env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + TEST_FULL_SUMMARY_FILE: 'gnu-full-result.json' + TEST_ROOT_FULL_SUMMARY_FILE: 'gnu-root-full-result.json' + TEST_SELINUX_FULL_SUMMARY_FILE: 'selinux-gnu-full-result.json' + TEST_SELINUX_ROOT_FULL_SUMMARY_FILE: 'selinux-root-gnu-full-result.json' + REPO_GNU_REF: "v9.7" jobs: gnu: @@ -42,36 +47,28 @@ jobs: ## VARs setup outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } # * config - path_GNU="gnu" - path_GNU_tests="${path_GNU}/tests" - path_UUTILS="uutils" path_reference="reference" - outputs path_GNU path_GNU_tests path_reference path_UUTILS + outputs path_reference # repo_default_branch="$DEFAULT_BRANCH" - repo_GNU_ref="v9.7" repo_reference_branch="$DEFAULT_BRANCH" - outputs repo_default_branch repo_GNU_ref repo_reference_branch + outputs repo_default_branch repo_reference_branch # - SUITE_LOG_FILE="${path_GNU_tests}/test-suite.log" - ROOT_SUITE_LOG_FILE="${path_GNU_tests}/test-suite-root.log" - SELINUX_SUITE_LOG_FILE="${path_GNU_tests}/selinux-test-suite.log" - SELINUX_ROOT_SUITE_LOG_FILE="${path_GNU_tests}/selinux-test-suite-root.log" - TEST_LOGS_GLOB="${path_GNU_tests}/**/*.log" ## note: not usable at bash CLI; [why] double globstar not enabled by default b/c MacOS includes only bash v3 which doesn't have double globstar support + SUITE_LOG_FILE="gnu/tests/test-suite.log" + ROOT_SUITE_LOG_FILE="gnu/tests/test-suite-root.log" + SELINUX_SUITE_LOG_FILE="gnu/tests/selinux-test-suite.log" + SELINUX_ROOT_SUITE_LOG_FILE="gnu/tests/selinux-test-suite-root.log" + TEST_LOGS_GLOB="gnu/tests/**/*.log" ## note: not usable at bash CLI; [why] double globstar not enabled by default b/c MacOS includes only bash v3 which doesn't have double globstar support TEST_FILESET_PREFIX='test-fileset-IDs.sha1#' TEST_FILESET_SUFFIX='.txt' TEST_SUMMARY_FILE='gnu-result.json' - TEST_FULL_SUMMARY_FILE='gnu-full-result.json' - TEST_ROOT_FULL_SUMMARY_FILE='gnu-root-full-result.json' - TEST_SELINUX_FULL_SUMMARY_FILE='selinux-gnu-full-result.json' - TEST_SELINUX_ROOT_FULL_SUMMARY_FILE='selinux-root-gnu-full-result.json' AGGREGATED_SUMMARY_FILE='aggregated-result.json' - outputs SUITE_LOG_FILE ROOT_SUITE_LOG_FILE SELINUX_SUITE_LOG_FILE SELINUX_ROOT_SUITE_LOG_FILE TEST_FILESET_PREFIX TEST_FILESET_SUFFIX TEST_LOGS_GLOB TEST_SUMMARY_FILE TEST_FULL_SUMMARY_FILE TEST_ROOT_FULL_SUMMARY_FILE TEST_SELINUX_FULL_SUMMARY_FILE TEST_SELINUX_ROOT_FULL_SUMMARY_FILE AGGREGATED_SUMMARY_FILE + outputs SUITE_LOG_FILE ROOT_SUITE_LOG_FILE SELINUX_SUITE_LOG_FILE SELINUX_ROOT_SUITE_LOG_FILE TEST_FILESET_PREFIX TEST_FILESET_SUFFIX TEST_LOGS_GLOB TEST_SUMMARY_FILE AGGREGATED_SUMMARY_FILE - name: Checkout code (uutil) uses: actions/checkout@v4 with: - path: '${{ steps.vars.outputs.path_UUTILS }}' + path: 'uutils' persist-credentials: false - uses: dtolnay/rust-toolchain@master with: @@ -79,13 +76,13 @@ jobs: components: rustfmt - uses: Swatinem/rust-cache@v2 with: - workspaces: "./${{ steps.vars.outputs.path_UUTILS }} -> target" + workspaces: "./uutils -> target" - name: Checkout code (GNU coreutils) uses: actions/checkout@v4 with: repository: 'coreutils/coreutils' - path: '${{ steps.vars.outputs.path_GNU }}' - ref: ${{ steps.vars.outputs.repo_GNU_ref }} + path: 'gnu' + ref: ${{ env.REPO_GNU_REF }} submodules: false persist-credentials: false @@ -133,7 +130,7 @@ jobs: git submodule sync --recursive git config submodule.gnulib.url https://github.com/coreutils/gnulib.git git submodule update --init --recursive --depth 1 - working-directory: ${{ steps.vars.outputs.path_GNU }} + working-directory: gnu - name: Retrieve reference artifacts uses: dawidd6/action-download-artifact@v11 @@ -181,7 +178,7 @@ jobs: shell: bash run: | ## Build binaries - cd '${{ steps.vars.outputs.path_UUTILS }}' + cd 'uutils' bash util/build-gnu.sh --release-build - name: Selinux - Generate selinux tests list @@ -208,7 +205,7 @@ jobs: - name: Selinux - Extract testing info from individual logs into JSON shell: bash run : | - lima bash -c "cd ~/work/gnu/ && python3 ../uutils/util/gnu-json-result.py tests > ~/work/gnu/tests-selinux/${{ steps.vars.outputs.TEST_SELINUX_FULL_SUMMARY_FILE }}" + lima bash -c "cd ~/work/gnu/ && python3 ../uutils/util/gnu-json-result.py tests > ~/work/gnu/tests-selinux/${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }}" - name: Selinux/root - Run selinux tests run: | @@ -217,50 +214,50 @@ jobs: - name: Selinux/root - Extract testing info from individual logs into JSON shell: bash run : | - lima bash -c "cd ~/work/gnu/ && python3 ../uutils/util/gnu-json-result.py tests > ~/work/gnu/tests-selinux/${{ steps.vars.outputs.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }}" + lima bash -c "cd ~/work/gnu/ && python3 ../uutils/util/gnu-json-result.py tests > ~/work/gnu/tests-selinux/${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }}" - name: Selinux - Collect test logs and test results run: | - mkdir -p ${{ steps.vars.outputs.path_GNU_tests }}-selinux + mkdir -p gnu/tests-selinux # Copy the test logs from the Lima VM to the host lima bash -c "cp ~/work/gnu/tests/test-suite.log ~/work/gnu/tests-selinux/ || echo 'No test-suite.log found'" lima bash -c "cp ~/work/gnu/tests/test-suite-root.log ~/work/gnu/tests-selinux/ || echo 'No test-suite-root.log found'" - rsync -v -a -e ssh lima-default:~/work/gnu/tests-selinux/ ./${{ steps.vars.outputs.path_GNU_tests }}-selinux/ + rsync -v -a -e ssh lima-default:~/work/gnu/tests-selinux/ ./gnu/tests-selinux/ # Copy SELinux logs to the main test directory for integrated processing - cp -f ${{ steps.vars.outputs.path_GNU_tests }}-selinux/test-suite.log ${{ steps.vars.outputs.path_GNU_tests }}/selinux-test-suite.log - cp -f ${{ steps.vars.outputs.path_GNU_tests }}-selinux/test-suite-root.log ${{ steps.vars.outputs.path_GNU_tests }}/selinux-test-suite-root.log - cp -f ${{ steps.vars.outputs.path_GNU_tests }}-selinux/${{ steps.vars.outputs.TEST_SELINUX_FULL_SUMMARY_FILE }} . - cp -f ${{ steps.vars.outputs.path_GNU_tests }}-selinux/${{ steps.vars.outputs.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} . + cp -f gnu/tests-selinux/test-suite.log gnu/tests/selinux-test-suite.log + cp -f gnu/tests-selinux/test-suite-root.log gnu/tests/selinux-test-suite-root.log + cp -f gnu/tests-selinux/${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} . + cp -f gnu/tests-selinux/${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} . - name: Run GNU tests shell: bash run: | ## Run GNU tests - path_GNU='${{ steps.vars.outputs.path_GNU }}' - path_UUTILS='${{ steps.vars.outputs.path_UUTILS }}' - bash "${path_UUTILS}/util/run-gnu-test.sh" + path_GNU='gnu' + path_UUTILS='uutils' + bash "uutils/util/run-gnu-test.sh" - name: Extract testing info from individual logs into JSON shell: bash run : | - path_UUTILS='${{ steps.vars.outputs.path_UUTILS }}' - python ${path_UUTILS}/util/gnu-json-result.py ${{ steps.vars.outputs.path_GNU_tests }} > ${{ steps.vars.outputs.TEST_FULL_SUMMARY_FILE }} + path_UUTILS='uutils' + python uutils/util/gnu-json-result.py gnu/tests > ${{ env.TEST_FULL_SUMMARY_FILE }} - name: Run GNU root tests shell: bash run: | ## Run GNU root tests - path_GNU='${{ steps.vars.outputs.path_GNU }}' - path_UUTILS='${{ steps.vars.outputs.path_UUTILS }}' - bash "${path_UUTILS}/util/run-gnu-test.sh" run-root + path_GNU='gnu' + path_UUTILS='uutils' + bash "uutils/util/run-gnu-test.sh" run-root - name: Extract testing info from individual logs (run as root) into JSON shell: bash run : | - path_UUTILS='${{ steps.vars.outputs.path_UUTILS }}' - python ${path_UUTILS}/util/gnu-json-result.py ${{ steps.vars.outputs.path_GNU_tests }} > ${{ steps.vars.outputs.TEST_ROOT_FULL_SUMMARY_FILE }} + path_UUTILS='uutils' + python uutils/util/gnu-json-result.py gnu/tests > ${{ env.TEST_ROOT_FULL_SUMMARY_FILE }} - name: Extract/summarize testing info id: summary @@ -269,16 +266,16 @@ jobs: ## Extract/summarize testing info outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } - path_UUTILS='${{ steps.vars.outputs.path_UUTILS }}' + path_UUTILS='uutils' # Check if the file exists - if test -f "${{ steps.vars.outputs.TEST_FULL_SUMMARY_FILE }}" + if test -f "${{ env.TEST_FULL_SUMMARY_FILE }}" then # Look at all individual results and summarize - eval $(python3 ${path_UUTILS}/util/analyze-gnu-results.py -o=${{ steps.vars.outputs.AGGREGATED_SUMMARY_FILE }} ${{ steps.vars.outputs.TEST_FULL_SUMMARY_FILE }} ${{ steps.vars.outputs.TEST_ROOT_FULL_SUMMARY_FILE }} ${{ steps.vars.outputs.TEST_SELINUX_FULL_SUMMARY_FILE }} ${{ steps.vars.outputs.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }}) + eval $(python3 uutils/util/analyze-gnu-results.py -o=${{ steps.vars.outputs.AGGREGATED_SUMMARY_FILE }} ${{ env.TEST_FULL_SUMMARY_FILE }} ${{ env.TEST_ROOT_FULL_SUMMARY_FILE }} ${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} ${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }}) if [[ "$TOTAL" -eq 0 || "$TOTAL" -eq 1 ]]; then - echo "::error ::Failed to parse test results from '${{ steps.vars.outputs.TEST_FULL_SUMMARY_FILE }}'; failing early" + echo "::error ::Failed to parse test results from '${{ env.TEST_FULL_SUMMARY_FILE }}'; failing early" exit 1 fi @@ -302,7 +299,7 @@ jobs: HASH=$(sha1sum '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' | cut --delim=" " -f 1) outputs HASH else - echo "::error ::Failed to find summary of test results (missing '${{ steps.vars.outputs.TEST_FULL_SUMMARY_FILE }}'); failing early" + echo "::error ::Failed to find summary of test results (missing '${{ env.TEST_FULL_SUMMARY_FILE }}'); failing early" exit 1 fi @@ -327,22 +324,22 @@ jobs: uses: actions/upload-artifact@v4 with: name: gnu-full-result - path: ${{ steps.vars.outputs.TEST_FULL_SUMMARY_FILE }} + path: ${{ env.TEST_FULL_SUMMARY_FILE }} - name: Upload root json results uses: actions/upload-artifact@v4 with: name: gnu-root-full-result - path: ${{ steps.vars.outputs.TEST_ROOT_FULL_SUMMARY_FILE }} + path: ${{ env.TEST_ROOT_FULL_SUMMARY_FILE }} - name: Upload selinux json results uses: actions/upload-artifact@v4 with: name: selinux-gnu-full-result - path: ${{ steps.vars.outputs.TEST_SELINUX_FULL_SUMMARY_FILE }} + path: ${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} - name: Upload selinux root json results uses: actions/upload-artifact@v4 with: name: selinux-root-gnu-full-result.json - path: ${{ steps.vars.outputs.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} + path: ${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} - name: Upload aggregated json results uses: actions/upload-artifact@v4 with: @@ -355,10 +352,10 @@ jobs: REF_SUMMARY_FILE='${{ steps.vars.outputs.path_reference }}/aggregated-result/aggregated-result.json' CURRENT_SUMMARY_FILE='${{ steps.vars.outputs.AGGREGATED_SUMMARY_FILE }}' REPO_DEFAULT_BRANCH='${{ steps.vars.outputs.repo_default_branch }}' - path_UUTILS='${{ steps.vars.outputs.path_UUTILS }}' + path_UUTILS='uutils' # Path to ignore file for intermittent issues - IGNORE_INTERMITTENT="${path_UUTILS}/.github/workflows/ignore-intermittent.txt" + IGNORE_INTERMITTENT="uutils/.github/workflows/ignore-intermittent.txt" # Set up comment directory COMMENT_DIR="${{ steps.vars.outputs.path_reference }}/comment" @@ -372,7 +369,7 @@ jobs: echo "Reference summary SHA1/ID: $(sha1sum -- "${REF_SUMMARY_FILE}")" echo "Current summary SHA1/ID: $(sha1sum -- "${CURRENT_SUMMARY_FILE}")" - python3 ${path_UUTILS}/util/compare_test_results.py \ + python3 uutils/util/compare_test_results.py \ --ignore-file "${IGNORE_INTERMITTENT}" \ --output "${COMMENT_LOG}" \ "${CURRENT_SUMMARY_FILE}" "${REF_SUMMARY_FILE}" From e1b37355410331a2915aa730facd7f1b9b1f8b97 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Thu, 24 Jul 2025 18:39:00 +0800 Subject: [PATCH 2/8] .github/workflows/GnuTests.yml: Move all Selinux steps to a separate job --- .github/workflows/GnuTests.yml | 218 +++++++++++++++++++-------------- 1 file changed, 126 insertions(+), 92 deletions(-) diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 479ce4b10f7..02da297e202 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -86,44 +86,6 @@ jobs: submodules: false persist-credentials: false - - name: Selinux - Setup Lima - uses: lima-vm/lima-actions/setup@v1 - id: lima-actions-setup - - - name: Selinux - Cache ~/.cache/lima - uses: actions/cache@v4 - with: - path: ~/.cache/lima - key: lima-${{ steps.lima-actions-setup.outputs.version }} - - - name: Selinux - Start Fedora VM with SELinux - run: limactl start --plain --name=default --cpus=4 --disk=40 --memory=8 --network=lima:user-v2 template://fedora - - - name: Selinux - Setup SSH - uses: lima-vm/lima-actions/ssh@v1 - - - name: Selinux - Verify SELinux Status and Configuration - run: | - lima getenforce - lima ls -laZ /etc/selinux - lima sudo sestatus - - # Ensure we're running in enforcing mode - lima sudo setenforce 1 - lima getenforce - - # Create test files with SELinux contexts for testing - lima sudo mkdir -p /var/test_selinux - lima sudo touch /var/test_selinux/test_file - lima sudo chcon -t etc_t /var/test_selinux/test_file - lima ls -Z /var/test_selinux/test_file # Verify context - - - name: Selinux - Install dependencies in VM - run: | - lima sudo dnf -y update - lima sudo dnf -y install git autoconf autopoint bison texinfo gperf gcc g++ gdb jq libacl-devel libattr-devel libcap-devel libselinux-devel attr rustup clang-devel texinfo-tex wget automake patch quilt - lima rustup-init -y --default-toolchain stable - - name: Override submodule URL and initialize submodules # Use github instead of upstream git server run: | @@ -170,10 +132,6 @@ jobs: echo "After:" locale -a - - name: Selinux - Copy the sources to VM - run: | - rsync -a -e ssh . lima-default:~/work/ - - name: Build binaries shell: bash run: | @@ -181,56 +139,6 @@ jobs: cd 'uutils' bash util/build-gnu.sh --release-build - - name: Selinux - Generate selinux tests list - run: | - # Find and list all tests that require SELinux - lima bash -c "cd ~/work/gnu/ && grep -l 'require_selinux_' -r tests/ > ~/work/uutils/selinux-tests.txt" - lima bash -c "cd ~/work/uutils/ && cat selinux-tests.txt" - - # Count the tests - lima bash -c "cd ~/work/uutils/ && echo 'Found SELinux tests:'; wc -l selinux-tests.txt" - - - name: Selinux - Build for selinux tests - run: | - lima bash -c "cd ~/work/uutils/ && bash util/build-gnu.sh --release-build" - lima bash -c "mkdir -p ~/work/gnu/tests-selinux/" - - - name: Selinux - Run selinux tests - run: | - lima sudo setenforce 1 - lima getenforce - lima cat /proc/filesystems - lima bash -c "cd ~/work/uutils/ && bash util/run-gnu-test.sh \$(cat selinux-tests.txt)" - - - name: Selinux - Extract testing info from individual logs into JSON - shell: bash - run : | - lima bash -c "cd ~/work/gnu/ && python3 ../uutils/util/gnu-json-result.py tests > ~/work/gnu/tests-selinux/${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }}" - - - name: Selinux/root - Run selinux tests - run: | - lima bash -c "cd ~/work/uutils/ && CI=1 bash util/run-gnu-test.sh run-root \$(cat selinux-tests.txt)" - - - name: Selinux/root - Extract testing info from individual logs into JSON - shell: bash - run : | - lima bash -c "cd ~/work/gnu/ && python3 ../uutils/util/gnu-json-result.py tests > ~/work/gnu/tests-selinux/${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }}" - - - name: Selinux - Collect test logs and test results - run: | - mkdir -p gnu/tests-selinux - - # Copy the test logs from the Lima VM to the host - lima bash -c "cp ~/work/gnu/tests/test-suite.log ~/work/gnu/tests-selinux/ || echo 'No test-suite.log found'" - lima bash -c "cp ~/work/gnu/tests/test-suite-root.log ~/work/gnu/tests-selinux/ || echo 'No test-suite-root.log found'" - rsync -v -a -e ssh lima-default:~/work/gnu/tests-selinux/ ./gnu/tests-selinux/ - - # Copy SELinux logs to the main test directory for integrated processing - cp -f gnu/tests-selinux/test-suite.log gnu/tests/selinux-test-suite.log - cp -f gnu/tests-selinux/test-suite-root.log gnu/tests/selinux-test-suite-root.log - cp -f gnu/tests-selinux/${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} . - cp -f gnu/tests-selinux/${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} . - - name: Run GNU tests shell: bash run: | @@ -410,3 +318,129 @@ jobs: else echo "::warning ::Skipping test summary comparison; no prior reference summary is available." fi + + selinux: +# permissions: +# contents: read # for actions/checkout to fetch code + name: Run SELinux GNU tests + runs-on: ubuntu-24.04 + steps: + - name: Checkout code (uutil) + uses: actions/checkout@v4 + with: + path: 'uutils' + persist-credentials: false + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: rustfmt + - uses: Swatinem/rust-cache@v2 + with: + workspaces: "./uutils -> target" + - name: Checkout code (GNU coreutils) + uses: actions/checkout@v4 + with: + repository: 'coreutils/coreutils' + path: 'gnu' + ref: ${{ env.REPO_GNU_REF }} + submodules: false + persist-credentials: false + - name: Selinux - Setup Lima + uses: lima-vm/lima-actions/setup@v1 + id: lima-actions-setup + + - name: Selinux - Cache ~/.cache/lima + uses: actions/cache@v4 + with: + path: ~/.cache/lima + key: lima-${{ steps.lima-actions-setup.outputs.version }} + + - name: Selinux - Start Fedora VM with SELinux + run: limactl start --plain --name=default --cpus=4 --disk=40 --memory=8 --network=lima:user-v2 template://fedora + + - name: Selinux - Setup SSH + uses: lima-vm/lima-actions/ssh@v1 + + - name: Selinux - Verify SELinux Status and Configuration + run: | + lima getenforce + lima ls -laZ /etc/selinux + lima sudo sestatus + + # Ensure we're running in enforcing mode + lima sudo setenforce 1 + lima getenforce + + # Create test files with SELinux contexts for testing + lima sudo mkdir -p /var/test_selinux + lima sudo touch /var/test_selinux/test_file + lima sudo chcon -t etc_t /var/test_selinux/test_file + lima ls -Z /var/test_selinux/test_file # Verify context + + - name: Selinux - Install dependencies in VM + run: | + lima sudo dnf -y update + lima sudo dnf -y install git autoconf autopoint bison texinfo gperf gcc g++ gdb jq libacl-devel libattr-devel libcap-devel libselinux-devel attr rustup clang-devel texinfo-tex wget automake patch quilt + lima rustup-init -y --default-toolchain stable + + - name: Override submodule URL and initialize submodules + # Use github instead of upstream git server + run: | + git submodule sync --recursive + git config submodule.gnulib.url https://github.com/coreutils/gnulib.git + git submodule update --init --recursive --depth 1 + working-directory: gnu + + - name: Selinux - Copy the sources to VM + run: | + rsync -a -e ssh . lima-default:~/work/ + + - name: Selinux - Generate selinux tests list + run: | + # Find and list all tests that require SELinux + lima bash -c "cd ~/work/gnu/ && grep -l 'require_selinux_' -r tests/ > ~/work/uutils/selinux-tests.txt" + lima bash -c "cd ~/work/uutils/ && cat selinux-tests.txt" + + # Count the tests + lima bash -c "cd ~/work/uutils/ && echo 'Found SELinux tests:'; wc -l selinux-tests.txt" + + - name: Selinux - Build for selinux tests + run: | + lima bash -c "cd ~/work/uutils/ && bash util/build-gnu.sh --release-build" + lima bash -c "mkdir -p ~/work/gnu/tests-selinux/" + + - name: Selinux - Run selinux tests + run: | + lima sudo setenforce 1 + lima getenforce + lima cat /proc/filesystems + lima bash -c "cd ~/work/uutils/ && bash util/run-gnu-test.sh \$(cat selinux-tests.txt)" + + - name: Selinux - Extract testing info from individual logs into JSON + shell: bash + run : | + lima bash -c "cd ~/work/gnu/ && python3 ../uutils/util/gnu-json-result.py tests > ~/work/gnu/tests-selinux/${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }}" + + - name: Selinux/root - Run selinux tests + run: | + lima bash -c "cd ~/work/uutils/ && CI=1 bash util/run-gnu-test.sh run-root \$(cat selinux-tests.txt)" + + - name: Selinux/root - Extract testing info from individual logs into JSON + shell: bash + run : | + lima bash -c "cd ~/work/gnu/ && python3 ../uutils/util/gnu-json-result.py tests > ~/work/gnu/tests-selinux/${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }}" + + - name: Selinux - Collect test logs and test results + run: | + mkdir -p gnu/tests-selinux + + # Copy the test logs from the Lima VM to the host + lima bash -c "cp ~/work/gnu/tests/test-suite.log ~/work/gnu/tests-selinux/ || echo 'No test-suite.log found'" + lima bash -c "cp ~/work/gnu/tests/test-suite-root.log ~/work/gnu/tests-selinux/ || echo 'No test-suite-root.log found'" + rsync -v -a -e ssh lima-default:~/work/gnu/tests-selinux/ ./gnu/tests-selinux/ + + # Copy SELinux logs to the main test directory for integrated processing + cp -f gnu/tests-selinux/test-suite.log gnu/tests/selinux-test-suite.log + cp -f gnu/tests-selinux/test-suite-root.log gnu/tests/selinux-test-suite-root.log + cp -f gnu/tests-selinux/${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} . + cp -f gnu/tests-selinux/${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} . From 65c55b7ae1e5c1728aafe50d0dc43f0bb2ad2b92 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Thu, 24 Jul 2025 20:47:45 +0800 Subject: [PATCH 3/8] .github/workflows/GnuTests.yml: Create a new summary job That aggregates between native and selinux results. --- .github/workflows/GnuTests.yml | 400 ++++++++++++++++++--------------- 1 file changed, 222 insertions(+), 178 deletions(-) diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 02da297e202..89ca88a658c 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -30,41 +30,17 @@ env: TEST_SELINUX_FULL_SUMMARY_FILE: 'selinux-gnu-full-result.json' TEST_SELINUX_ROOT_FULL_SUMMARY_FILE: 'selinux-root-gnu-full-result.json' REPO_GNU_REF: "v9.7" + TEST_LOGS_GLOB: "gnu/tests/**/*.log" ## note: not usable at bash CLI; [why] double globstar not enabled by default b/c MacOS includes only bash v3 which doesn't have double globstar support jobs: - gnu: + native: permissions: actions: read # for dawidd6/action-download-artifact to query and download artifacts contents: read # for actions/checkout to fetch code pull-requests: read # for dawidd6/action-download-artifact to query commit hash - name: Run GNU tests + name: Run GNU tests (native) runs-on: ubuntu-24.04 steps: - - name: Initialize workflow variables - id: vars - shell: bash - run: | - ## VARs setup - outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } - # * config - path_reference="reference" - outputs path_reference - # - repo_default_branch="$DEFAULT_BRANCH" - repo_reference_branch="$DEFAULT_BRANCH" - outputs repo_default_branch repo_reference_branch - # - SUITE_LOG_FILE="gnu/tests/test-suite.log" - ROOT_SUITE_LOG_FILE="gnu/tests/test-suite-root.log" - SELINUX_SUITE_LOG_FILE="gnu/tests/selinux-test-suite.log" - SELINUX_ROOT_SUITE_LOG_FILE="gnu/tests/selinux-test-suite-root.log" - TEST_LOGS_GLOB="gnu/tests/**/*.log" ## note: not usable at bash CLI; [why] double globstar not enabled by default b/c MacOS includes only bash v3 which doesn't have double globstar support - TEST_FILESET_PREFIX='test-fileset-IDs.sha1#' - TEST_FILESET_SUFFIX='.txt' - TEST_SUMMARY_FILE='gnu-result.json' - AGGREGATED_SUMMARY_FILE='aggregated-result.json' - - outputs SUITE_LOG_FILE ROOT_SUITE_LOG_FILE SELINUX_SUITE_LOG_FILE SELINUX_ROOT_SUITE_LOG_FILE TEST_FILESET_PREFIX TEST_FILESET_SUFFIX TEST_LOGS_GLOB TEST_SUMMARY_FILE AGGREGATED_SUMMARY_FILE - name: Checkout code (uutil) uses: actions/checkout@v4 with: @@ -94,16 +70,6 @@ jobs: git submodule update --init --recursive --depth 1 working-directory: gnu - - name: Retrieve reference artifacts - uses: dawidd6/action-download-artifact@v11 - # ref: - continue-on-error: true ## don't break the build for missing reference artifacts (may be expired or just not generated yet) - with: - workflow: GnuTests.yml - branch: "${{ steps.vars.outputs.repo_reference_branch }}" - # workflow_conclusion: success ## (default); * but, if commit with failed GnuTests is merged into the default branch, future commits will all show regression errors in GnuTests CI until o/w fixed - workflow_conclusion: completed ## continually recalibrates to last commit of default branch with a successful GnuTests (ie, "self-heals" from GnuTest regressions, but needs more supervision for/of regressions) - path: "${{ steps.vars.outputs.path_reference }}" - name: Install dependencies shell: bash run: | @@ -167,67 +133,6 @@ jobs: path_UUTILS='uutils' python uutils/util/gnu-json-result.py gnu/tests > ${{ env.TEST_ROOT_FULL_SUMMARY_FILE }} - - name: Extract/summarize testing info - id: summary - shell: bash - run: | - ## Extract/summarize testing info - outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } - - path_UUTILS='uutils' - - # Check if the file exists - if test -f "${{ env.TEST_FULL_SUMMARY_FILE }}" - then - # Look at all individual results and summarize - eval $(python3 uutils/util/analyze-gnu-results.py -o=${{ steps.vars.outputs.AGGREGATED_SUMMARY_FILE }} ${{ env.TEST_FULL_SUMMARY_FILE }} ${{ env.TEST_ROOT_FULL_SUMMARY_FILE }} ${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} ${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }}) - - if [[ "$TOTAL" -eq 0 || "$TOTAL" -eq 1 ]]; then - echo "::error ::Failed to parse test results from '${{ env.TEST_FULL_SUMMARY_FILE }}'; failing early" - exit 1 - fi - - output="GNU tests summary = TOTAL: $TOTAL / PASS: $PASS / FAIL: $FAIL / ERROR: $ERROR / SKIP: $SKIP" - echo "${output}" - - if [[ "$FAIL" -gt 0 || "$ERROR" -gt 0 ]]; then - echo "::warning ::${output}" - fi - - jq -n \ - --arg date "$(date --rfc-email)" \ - --arg sha "$GITHUB_SHA" \ - --arg total "$TOTAL" \ - --arg pass "$PASS" \ - --arg skip "$SKIP" \ - --arg fail "$FAIL" \ - --arg xpass "$XPASS" \ - --arg error "$ERROR" \ - '{($date): { sha: $sha, total: $total, pass: $pass, skip: $skip, fail: $fail, xpass: $xpass, error: $error, }}' > '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' - HASH=$(sha1sum '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' | cut --delim=" " -f 1) - outputs HASH - else - echo "::error ::Failed to find summary of test results (missing '${{ env.TEST_FULL_SUMMARY_FILE }}'); failing early" - exit 1 - fi - - # Compress logs before upload (fails otherwise) - gzip ${{ steps.vars.outputs.TEST_LOGS_GLOB }} - - name: Reserve SHA1/ID of 'test-summary' - uses: actions/upload-artifact@v4 - with: - name: "${{ steps.summary.outputs.HASH }}" - path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}" - - name: Reserve test results summary - uses: actions/upload-artifact@v4 - with: - name: test-summary - path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}" - - name: Reserve test logs - uses: actions/upload-artifact@v4 - with: - name: test-logs - path: "${{ steps.vars.outputs.TEST_LOGS_GLOB }}" - name: Upload full json results uses: actions/upload-artifact@v4 with: @@ -238,91 +143,20 @@ jobs: with: name: gnu-root-full-result path: ${{ env.TEST_ROOT_FULL_SUMMARY_FILE }} - - name: Upload selinux json results - uses: actions/upload-artifact@v4 - with: - name: selinux-gnu-full-result - path: ${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} - - name: Upload selinux root json results - uses: actions/upload-artifact@v4 - with: - name: selinux-root-gnu-full-result.json - path: ${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} - - name: Upload aggregated json results - uses: actions/upload-artifact@v4 - with: - name: aggregated-result - path: ${{ steps.vars.outputs.AGGREGATED_SUMMARY_FILE }} - - name: Compare test failures VS reference - shell: bash - run: | - ## Compare test failures VS reference using JSON files - REF_SUMMARY_FILE='${{ steps.vars.outputs.path_reference }}/aggregated-result/aggregated-result.json' - CURRENT_SUMMARY_FILE='${{ steps.vars.outputs.AGGREGATED_SUMMARY_FILE }}' - REPO_DEFAULT_BRANCH='${{ steps.vars.outputs.repo_default_branch }}' - path_UUTILS='uutils' - # Path to ignore file for intermittent issues - IGNORE_INTERMITTENT="uutils/.github/workflows/ignore-intermittent.txt" - - # Set up comment directory - COMMENT_DIR="${{ steps.vars.outputs.path_reference }}/comment" - mkdir -p ${COMMENT_DIR} - echo ${{ github.event.number }} > ${COMMENT_DIR}/NR - COMMENT_LOG="${COMMENT_DIR}/result.txt" - - COMPARISON_RESULT=0 - if test -f "${CURRENT_SUMMARY_FILE}"; then - if test -f "${REF_SUMMARY_FILE}"; then - echo "Reference summary SHA1/ID: $(sha1sum -- "${REF_SUMMARY_FILE}")" - echo "Current summary SHA1/ID: $(sha1sum -- "${CURRENT_SUMMARY_FILE}")" - - python3 uutils/util/compare_test_results.py \ - --ignore-file "${IGNORE_INTERMITTENT}" \ - --output "${COMMENT_LOG}" \ - "${CURRENT_SUMMARY_FILE}" "${REF_SUMMARY_FILE}" - - COMPARISON_RESULT=$? - else - echo "::warning ::Skipping test comparison; no prior reference summary is available at '${REF_SUMMARY_FILE}'." - fi - else - echo "::error ::Failed to find summary of test results (missing '${CURRENT_SUMMARY_FILE}'); failing early" - exit 1 - fi - - if [ ${COMPARISON_RESULT} -eq 1 ]; then - echo "ONLY_INTERMITTENT=false" >> $GITHUB_ENV - echo "::error ::Found new non-intermittent test failures" - exit 1 - else - echo "ONLY_INTERMITTENT=true" >> $GITHUB_ENV - echo "::notice ::No new test failures detected" - fi - - name: Upload comparison log (for GnuComment workflow) - if: success() || failure() # run regardless of prior step success/failure + - name: Compress logs + shell: bash + run : | + # Compress logs before upload (fails otherwise) + gzip ${{ env.TEST_LOGS_GLOB }} + - name: Reserve test logs uses: actions/upload-artifact@v4 with: - name: comment - path: ${{ steps.vars.outputs.path_reference }}/comment/ - - name: Compare test summary VS reference - if: success() || failure() # run regardless of prior step success/failure - shell: bash - run: | - ## Compare test summary VS reference - REF_SUMMARY_FILE='${{ steps.vars.outputs.path_reference }}/test-summary/gnu-result.json' - if test -f "${REF_SUMMARY_FILE}"; then - echo "Reference SHA1/ID: $(sha1sum -- "${REF_SUMMARY_FILE}")" - mv "${REF_SUMMARY_FILE}" main-gnu-result.json - python uutils/util/compare_gnu_result.py - else - echo "::warning ::Skipping test summary comparison; no prior reference summary is available." - fi + name: test-logs + path: "${{ env.TEST_LOGS_GLOB }}" selinux: -# permissions: -# contents: read # for actions/checkout to fetch code - name: Run SELinux GNU tests + name: Run GNU tests (SELinux) runs-on: ubuntu-24.04 steps: - name: Checkout code (uutil) @@ -444,3 +278,213 @@ jobs: cp -f gnu/tests-selinux/test-suite-root.log gnu/tests/selinux-test-suite-root.log cp -f gnu/tests-selinux/${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} . cp -f gnu/tests-selinux/${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} . + + - name: Upload selinux json results + uses: actions/upload-artifact@v4 + with: + name: selinux-gnu-full-result + path: ${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} + + - name: Upload selinux root json results + uses: actions/upload-artifact@v4 + with: + name: selinux-root-gnu-full-result + path: ${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} + + - name: Compress logs + shell: bash + run : | + # Compress logs before upload (fails otherwise) + gzip ${{ env.TEST_LOGS_GLOB }} + - name: Reserve test logs + uses: actions/upload-artifact@v4 + with: + name: selinux-test-logs + path: "${{ env.TEST_LOGS_GLOB }}" + + + aggregate: + needs: [native, selinux] + permissions: + actions: read # for dawidd6/action-download-artifact to query and download artifacts + contents: read # for actions/checkout to fetch code + pull-requests: read # for dawidd6/action-download-artifact to query commit hash + name: Aggregate GNU test results + runs-on: ubuntu-24.04 + steps: + - name: Initialize workflow variables + id: vars + shell: bash + run: | + ## VARs setup + outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } + # * config + path_reference="reference" + outputs path_reference + # + repo_default_branch="$DEFAULT_BRANCH" + repo_reference_branch="$DEFAULT_BRANCH" + outputs repo_default_branch repo_reference_branch + # + TEST_SUMMARY_FILE='gnu-result.json' + AGGREGATED_SUMMARY_FILE='aggregated-result.json' + + outputs TEST_SUMMARY_FILE AGGREGATED_SUMMARY_FILE + - name: Checkout code (uutils) + uses: actions/checkout@v4 + with: + path: 'uutils' + persist-credentials: false + - name: Retrieve reference artifacts + uses: dawidd6/action-download-artifact@v11 + # ref: + continue-on-error: true ## don't break the build for missing reference artifacts (may be expired or just not generated yet) + with: + workflow: GnuTests.yml + branch: "${{ steps.vars.outputs.repo_reference_branch }}" + # workflow_conclusion: success ## (default); * but, if commit with failed GnuTests is merged into the default branch, future commits will all show regression errors in GnuTests CI until o/w fixed + workflow_conclusion: completed ## continually recalibrates to last commit of default branch with a successful GnuTests (ie, "self-heals" from GnuTest regressions, but needs more supervision for/of regressions) + path: "${{ steps.vars.outputs.path_reference }}" + - name: Download selinux json results + uses: actions/download-artifact@v4 + with: + name: selinux-gnu-full-result + path: ${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} + - name: Download selinux root json results + uses: actions/download-artifact@v4 + with: + name: selinux-root-gnu-full-result.json + path: ${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} + - name: Download full json results + uses: actions/download-artifact@v4 + with: + name: gnu-full-result + path: ${{ env.TEST_FULL_SUMMARY_FILE }} + - name: Download root json results + uses: actions/download-artifact@v4 + with: + name: gnu-root-full-result + path: ${{ env.TEST_ROOT_FULL_SUMMARY_FILE }} + - name: Extract/summarize testing info + id: summary + shell: bash + run: | + ## Extract/summarize testing info + outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } + + path_UUTILS='uutils' + + # Check if the file exists + if test -f "${{ env.TEST_FULL_SUMMARY_FILE }}" + then + # Look at all individual results and summarize + eval $(python3 uutils/util/analyze-gnu-results.py -o=${{ steps.vars.outputs.AGGREGATED_SUMMARY_FILE }} ${{ env.TEST_FULL_SUMMARY_FILE }} ${{ env.TEST_ROOT_FULL_SUMMARY_FILE }} ${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} ${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }}) + + if [[ "$TOTAL" -eq 0 || "$TOTAL" -eq 1 ]]; then + echo "::error ::Failed to parse test results from '${{ env.TEST_FULL_SUMMARY_FILE }}'; failing early" + exit 1 + fi + + output="GNU tests summary = TOTAL: $TOTAL / PASS: $PASS / FAIL: $FAIL / ERROR: $ERROR / SKIP: $SKIP" + echo "${output}" + + if [[ "$FAIL" -gt 0 || "$ERROR" -gt 0 ]]; then + echo "::warning ::${output}" + fi + + jq -n \ + --arg date "$(date --rfc-email)" \ + --arg sha "$GITHUB_SHA" \ + --arg total "$TOTAL" \ + --arg pass "$PASS" \ + --arg skip "$SKIP" \ + --arg fail "$FAIL" \ + --arg xpass "$XPASS" \ + --arg error "$ERROR" \ + '{($date): { sha: $sha, total: $total, pass: $pass, skip: $skip, fail: $fail, xpass: $xpass, error: $error, }}' > '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' + HASH=$(sha1sum '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' | cut --delim=" " -f 1) + outputs HASH + else + echo "::error ::Failed to find summary of test results (missing '${{ env.TEST_FULL_SUMMARY_FILE }}'); failing early" + exit 1 + fi + - name: Reserve SHA1/ID of 'test-summary' + uses: actions/upload-artifact@v4 + with: + name: "${{ steps.summary.outputs.HASH }}" + path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}" + - name: Reserve test results summary + uses: actions/upload-artifact@v4 + with: + name: test-summary + path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}" + - name: Upload aggregated json results + uses: actions/upload-artifact@v4 + with: + name: aggregated-result + path: ${{ steps.vars.outputs.AGGREGATED_SUMMARY_FILE }} + - name: Compare test failures VS reference + shell: bash + run: | + ## Compare test failures VS reference using JSON files + REF_SUMMARY_FILE='${{ steps.vars.outputs.path_reference }}/aggregated-result/aggregated-result.json' + CURRENT_SUMMARY_FILE='${{ steps.vars.outputs.AGGREGATED_SUMMARY_FILE }}' + REPO_DEFAULT_BRANCH='${{ steps.vars.outputs.repo_default_branch }}' + path_UUTILS='uutils' + + # Path to ignore file for intermittent issues + IGNORE_INTERMITTENT="uutils/.github/workflows/ignore-intermittent.txt" + + # Set up comment directory + COMMENT_DIR="${{ steps.vars.outputs.path_reference }}/comment" + mkdir -p ${COMMENT_DIR} + echo ${{ github.event.number }} > ${COMMENT_DIR}/NR + COMMENT_LOG="${COMMENT_DIR}/result.txt" + + COMPARISON_RESULT=0 + if test -f "${CURRENT_SUMMARY_FILE}"; then + if test -f "${REF_SUMMARY_FILE}"; then + echo "Reference summary SHA1/ID: $(sha1sum -- "${REF_SUMMARY_FILE}")" + echo "Current summary SHA1/ID: $(sha1sum -- "${CURRENT_SUMMARY_FILE}")" + + python3 uutils/util/compare_test_results.py \ + --ignore-file "${IGNORE_INTERMITTENT}" \ + --output "${COMMENT_LOG}" \ + "${CURRENT_SUMMARY_FILE}" "${REF_SUMMARY_FILE}" + + COMPARISON_RESULT=$? + else + echo "::warning ::Skipping test comparison; no prior reference summary is available at '${REF_SUMMARY_FILE}'." + fi + else + echo "::error ::Failed to find summary of test results (missing '${CURRENT_SUMMARY_FILE}'); failing early" + exit 1 + fi + + if [ ${COMPARISON_RESULT} -eq 1 ]; then + echo "ONLY_INTERMITTENT=false" >> $GITHUB_ENV + echo "::error ::Found new non-intermittent test failures" + exit 1 + else + echo "ONLY_INTERMITTENT=true" >> $GITHUB_ENV + echo "::notice ::No new test failures detected" + fi + - name: Upload comparison log (for GnuComment workflow) + if: success() || failure() # run regardless of prior step success/failure + uses: actions/upload-artifact@v4 + with: + name: comment + path: ${{ steps.vars.outputs.path_reference }}/comment/ + - name: Compare test summary VS reference + if: success() || failure() # run regardless of prior step success/failure + shell: bash + run: | + ## Compare test summary VS reference + REF_SUMMARY_FILE='${{ steps.vars.outputs.path_reference }}/test-summary/gnu-result.json' + if test -f "${REF_SUMMARY_FILE}"; then + echo "Reference SHA1/ID: $(sha1sum -- "${REF_SUMMARY_FILE}")" + mv "${REF_SUMMARY_FILE}" main-gnu-result.json + python uutils/util/compare_gnu_result.py + else + echo "::warning ::Skipping test summary comparison; no prior reference summary is available." + fi From 32e47ae288c7550a7d49ce6d5a33f3ee42b058f1 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Thu, 24 Jul 2025 20:54:13 +0800 Subject: [PATCH 4/8] .github/workflows/GnuTests.yml: Fix log uploading This... didn't work, even in the previous version. (found by Gemini...) --- .github/workflows/GnuTests.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 89ca88a658c..4b5ea428ef2 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -30,7 +30,6 @@ env: TEST_SELINUX_FULL_SUMMARY_FILE: 'selinux-gnu-full-result.json' TEST_SELINUX_ROOT_FULL_SUMMARY_FILE: 'selinux-root-gnu-full-result.json' REPO_GNU_REF: "v9.7" - TEST_LOGS_GLOB: "gnu/tests/**/*.log" ## note: not usable at bash CLI; [why] double globstar not enabled by default b/c MacOS includes only bash v3 which doesn't have double globstar support jobs: native: @@ -144,16 +143,16 @@ jobs: name: gnu-root-full-result path: ${{ env.TEST_ROOT_FULL_SUMMARY_FILE }} - - name: Compress logs + - name: Compress test logs shell: bash run : | # Compress logs before upload (fails otherwise) - gzip ${{ env.TEST_LOGS_GLOB }} - - name: Reserve test logs + gzip gnu/tests/**/*.log + - name: Update test logs uses: actions/upload-artifact@v4 with: name: test-logs - path: "${{ env.TEST_LOGS_GLOB }}" + path: "gnu/tests/**/*.log.gz" selinux: name: Run GNU tests (SELinux) @@ -291,16 +290,16 @@ jobs: name: selinux-root-gnu-full-result path: ${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} - - name: Compress logs + - name: Compress test logs shell: bash run : | # Compress logs before upload (fails otherwise) - gzip ${{ env.TEST_LOGS_GLOB }} - - name: Reserve test logs + gzip gnu/tests-selinux/**/*.log + - name: Upload test logs uses: actions/upload-artifact@v4 with: name: selinux-test-logs - path: "${{ env.TEST_LOGS_GLOB }}" + path: "gnu/tests-selinux/**/*.log.gz" aggregate: From 29d2cf667a77ed79cb4b69caa6fa146cbc0612d2 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Thu, 24 Jul 2025 21:30:48 +0800 Subject: [PATCH 5/8] .github/workflows/GnuTests.yml: Improve aggregate Variables don't always help make things clearer. --- .github/workflows/GnuTests.yml | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 4b5ea428ef2..f2df159fa0b 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -317,13 +317,6 @@ jobs: run: | ## VARs setup outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } - # * config - path_reference="reference" - outputs path_reference - # - repo_default_branch="$DEFAULT_BRANCH" - repo_reference_branch="$DEFAULT_BRANCH" - outputs repo_default_branch repo_reference_branch # TEST_SUMMARY_FILE='gnu-result.json' AGGREGATED_SUMMARY_FILE='aggregated-result.json' @@ -340,10 +333,10 @@ jobs: continue-on-error: true ## don't break the build for missing reference artifacts (may be expired or just not generated yet) with: workflow: GnuTests.yml - branch: "${{ steps.vars.outputs.repo_reference_branch }}" + branch: "${{ env.DEFAULT_BRANCH }}" # workflow_conclusion: success ## (default); * but, if commit with failed GnuTests is merged into the default branch, future commits will all show regression errors in GnuTests CI until o/w fixed workflow_conclusion: completed ## continually recalibrates to last commit of default branch with a successful GnuTests (ie, "self-heals" from GnuTest regressions, but needs more supervision for/of regressions) - path: "${{ steps.vars.outputs.path_reference }}" + path: "reference" - name: Download selinux json results uses: actions/download-artifact@v4 with: @@ -407,12 +400,12 @@ jobs: echo "::error ::Failed to find summary of test results (missing '${{ env.TEST_FULL_SUMMARY_FILE }}'); failing early" exit 1 fi - - name: Reserve SHA1/ID of 'test-summary' + - name: Upload SHA1/ID of 'test-summary' uses: actions/upload-artifact@v4 with: name: "${{ steps.summary.outputs.HASH }}" path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}" - - name: Reserve test results summary + - name: Upload test results summary uses: actions/upload-artifact@v4 with: name: test-summary @@ -426,16 +419,16 @@ jobs: shell: bash run: | ## Compare test failures VS reference using JSON files - REF_SUMMARY_FILE='${{ steps.vars.outputs.path_reference }}/aggregated-result/aggregated-result.json' + REF_SUMMARY_FILE='reference/aggregated-result/aggregated-result.json' CURRENT_SUMMARY_FILE='${{ steps.vars.outputs.AGGREGATED_SUMMARY_FILE }}' - REPO_DEFAULT_BRANCH='${{ steps.vars.outputs.repo_default_branch }}' + REPO_DEFAULT_BRANCH='${{ env.DEFAULT_BRANCH }}' path_UUTILS='uutils' # Path to ignore file for intermittent issues IGNORE_INTERMITTENT="uutils/.github/workflows/ignore-intermittent.txt" # Set up comment directory - COMMENT_DIR="${{ steps.vars.outputs.path_reference }}/comment" + COMMENT_DIR="reference/comment" mkdir -p ${COMMENT_DIR} echo ${{ github.event.number }} > ${COMMENT_DIR}/NR COMMENT_LOG="${COMMENT_DIR}/result.txt" @@ -473,13 +466,13 @@ jobs: uses: actions/upload-artifact@v4 with: name: comment - path: ${{ steps.vars.outputs.path_reference }}/comment/ + path: reference/comment/ - name: Compare test summary VS reference if: success() || failure() # run regardless of prior step success/failure shell: bash run: | ## Compare test summary VS reference - REF_SUMMARY_FILE='${{ steps.vars.outputs.path_reference }}/test-summary/gnu-result.json' + REF_SUMMARY_FILE='reference/test-summary/gnu-result.json' if test -f "${REF_SUMMARY_FILE}"; then echo "Reference SHA1/ID: $(sha1sum -- "${REF_SUMMARY_FILE}")" mv "${REF_SUMMARY_FILE}" main-gnu-result.json From 0b457325bddea141ba01cd780420d7aefaed34a2 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Thu, 24 Jul 2025 21:55:26 +0800 Subject: [PATCH 6/8] .github/workflows/GnuTests.yml: Make selinux and native flow identical Also add some headers to make things easier to follow. --- .github/workflows/GnuTests.yml | 95 +++++++++++++++------------------- 1 file changed, 43 insertions(+), 52 deletions(-) diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index f2df159fa0b..8b733dbbbf2 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -33,14 +33,11 @@ env: jobs: native: - permissions: - actions: read # for dawidd6/action-download-artifact to query and download artifacts - contents: read # for actions/checkout to fetch code - pull-requests: read # for dawidd6/action-download-artifact to query commit hash name: Run GNU tests (native) runs-on: ubuntu-24.04 steps: - - name: Checkout code (uutil) + #### Get the code, setup cache + - name: Checkout code (uutils) uses: actions/checkout@v4 with: path: 'uutils' @@ -60,7 +57,6 @@ jobs: ref: ${{ env.REPO_GNU_REF }} submodules: false persist-credentials: false - - name: Override submodule URL and initialize submodules # Use github instead of upstream git server run: | @@ -69,6 +65,7 @@ jobs: git submodule update --init --recursive --depth 1 working-directory: gnu + #### Build environment setup - name: Install dependencies shell: bash run: | @@ -97,6 +94,7 @@ jobs: echo "After:" locale -a + ### Build - name: Build binaries shell: bash run: | @@ -104,6 +102,7 @@ jobs: cd 'uutils' bash util/build-gnu.sh --release-build + ### Run tests as user - name: Run GNU tests shell: bash run: | @@ -111,13 +110,13 @@ jobs: path_GNU='gnu' path_UUTILS='uutils' bash "uutils/util/run-gnu-test.sh" - - name: Extract testing info from individual logs into JSON shell: bash run : | path_UUTILS='uutils' python uutils/util/gnu-json-result.py gnu/tests > ${{ env.TEST_FULL_SUMMARY_FILE }} + ### Run tests as root - name: Run GNU root tests shell: bash run: | @@ -125,13 +124,13 @@ jobs: path_GNU='gnu' path_UUTILS='uutils' bash "uutils/util/run-gnu-test.sh" run-root - - name: Extract testing info from individual logs (run as root) into JSON shell: bash run : | path_UUTILS='uutils' python uutils/util/gnu-json-result.py gnu/tests > ${{ env.TEST_ROOT_FULL_SUMMARY_FILE }} + ### Upload artifacts - name: Upload full json results uses: actions/upload-artifact@v4 with: @@ -142,7 +141,6 @@ jobs: with: name: gnu-root-full-result path: ${{ env.TEST_ROOT_FULL_SUMMARY_FILE }} - - name: Compress test logs shell: bash run : | @@ -158,7 +156,8 @@ jobs: name: Run GNU tests (SELinux) runs-on: ubuntu-24.04 steps: - - name: Checkout code (uutil) + #### Get the code, setup cache + - name: Checkout code (uutils) uses: actions/checkout@v4 with: path: 'uutils' @@ -178,23 +177,28 @@ jobs: ref: ${{ env.REPO_GNU_REF }} submodules: false persist-credentials: false - - name: Selinux - Setup Lima + - name: Override submodule URL and initialize submodules + # Use github instead of upstream git server + run: | + git submodule sync --recursive + git config submodule.gnulib.url https://github.com/coreutils/gnulib.git + git submodule update --init --recursive --depth 1 + working-directory: gnu + + #### Lima build environment setup + - name: Setup Lima uses: lima-vm/lima-actions/setup@v1 id: lima-actions-setup - - - name: Selinux - Cache ~/.cache/lima + - name: Cache ~/.cache/lima uses: actions/cache@v4 with: path: ~/.cache/lima key: lima-${{ steps.lima-actions-setup.outputs.version }} - - - name: Selinux - Start Fedora VM with SELinux + - name: Start Fedora VM with SELinux run: limactl start --plain --name=default --cpus=4 --disk=40 --memory=8 --network=lima:user-v2 template://fedora - - - name: Selinux - Setup SSH + - name: Setup SSH uses: lima-vm/lima-actions/ssh@v1 - - - name: Selinux - Verify SELinux Status and Configuration + - name: Verify SELinux Status and Configuration run: | lima getenforce lima ls -laZ /etc/selinux @@ -209,26 +213,23 @@ jobs: lima sudo touch /var/test_selinux/test_file lima sudo chcon -t etc_t /var/test_selinux/test_file lima ls -Z /var/test_selinux/test_file # Verify context - - - name: Selinux - Install dependencies in VM + - name: Install dependencies in VM run: | lima sudo dnf -y update lima sudo dnf -y install git autoconf autopoint bison texinfo gperf gcc g++ gdb jq libacl-devel libattr-devel libcap-devel libselinux-devel attr rustup clang-devel texinfo-tex wget automake patch quilt lima rustup-init -y --default-toolchain stable - - - name: Override submodule URL and initialize submodules - # Use github instead of upstream git server + - name: Copy the sources to VM run: | - git submodule sync --recursive - git config submodule.gnulib.url https://github.com/coreutils/gnulib.git - git submodule update --init --recursive --depth 1 - working-directory: gnu + rsync -a -e ssh . lima-default:~/work/ - - name: Selinux - Copy the sources to VM + ### Build + - name: Build binaries run: | - rsync -a -e ssh . lima-default:~/work/ + lima bash -c "cd ~/work/uutils/ && bash util/build-gnu.sh --release-build" + lima bash -c "mkdir -p ~/work/gnu/tests-selinux/" - - name: Selinux - Generate selinux tests list + ### Run tests as user + - name: Generate SELinux tests list run: | # Find and list all tests that require SELinux lima bash -c "cd ~/work/gnu/ && grep -l 'require_selinux_' -r tests/ > ~/work/uutils/selinux-tests.txt" @@ -236,34 +237,28 @@ jobs: # Count the tests lima bash -c "cd ~/work/uutils/ && echo 'Found SELinux tests:'; wc -l selinux-tests.txt" - - - name: Selinux - Build for selinux tests - run: | - lima bash -c "cd ~/work/uutils/ && bash util/build-gnu.sh --release-build" - lima bash -c "mkdir -p ~/work/gnu/tests-selinux/" - - - name: Selinux - Run selinux tests + - name: Run GNU SELinux tests run: | lima sudo setenforce 1 lima getenforce lima cat /proc/filesystems lima bash -c "cd ~/work/uutils/ && bash util/run-gnu-test.sh \$(cat selinux-tests.txt)" - - - name: Selinux - Extract testing info from individual logs into JSON + - name: Extract testing info from individual logs into JSON shell: bash run : | lima bash -c "cd ~/work/gnu/ && python3 ../uutils/util/gnu-json-result.py tests > ~/work/gnu/tests-selinux/${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }}" - - name: Selinux/root - Run selinux tests + ### Run tests as root + - name: Run GNU SELinux root tests run: | lima bash -c "cd ~/work/uutils/ && CI=1 bash util/run-gnu-test.sh run-root \$(cat selinux-tests.txt)" - - - name: Selinux/root - Extract testing info from individual logs into JSON + - name: Extract testing info from individual logs (run as root) into JSON shell: bash run : | lima bash -c "cd ~/work/gnu/ && python3 ../uutils/util/gnu-json-result.py tests > ~/work/gnu/tests-selinux/${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }}" - - name: Selinux - Collect test logs and test results + ### Upload artifacts + - name: Collect test logs and test results from VM run: | mkdir -p gnu/tests-selinux @@ -277,31 +272,27 @@ jobs: cp -f gnu/tests-selinux/test-suite-root.log gnu/tests/selinux-test-suite-root.log cp -f gnu/tests-selinux/${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} . cp -f gnu/tests-selinux/${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} . - - - name: Upload selinux json results + - name: Upload SELinux json results uses: actions/upload-artifact@v4 with: name: selinux-gnu-full-result path: ${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} - - - name: Upload selinux root json results + - name: Upload SELinux root json results uses: actions/upload-artifact@v4 with: name: selinux-root-gnu-full-result path: ${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} - - - name: Compress test logs + - name: Compress SELinux test logs shell: bash run : | # Compress logs before upload (fails otherwise) gzip gnu/tests-selinux/**/*.log - - name: Upload test logs + - name: Upload SELinux test logs uses: actions/upload-artifact@v4 with: name: selinux-test-logs path: "gnu/tests-selinux/**/*.log.gz" - aggregate: needs: [native, selinux] permissions: From accb534659f8b37c791c34b8807736b91b3b2fe4 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Thu, 24 Jul 2025 22:17:21 +0800 Subject: [PATCH 7/8] .github/workflows/GnuTests.yml: More misc cleanup In particular, SELinux flow is simplified, and fixed. Also fix artifact download name. --- .github/workflows/GnuTests.yml | 35 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 8b733dbbbf2..f7e74bd86b7 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -145,12 +145,14 @@ jobs: shell: bash run : | # Compress logs before upload (fails otherwise) - gzip gnu/tests/**/*.log - - name: Update test logs + gzip gnu/tests/*/*.log + - name: Upload test logs uses: actions/upload-artifact@v4 with: name: test-logs - path: "gnu/tests/**/*.log.gz" + path: | + gnu/tests/*.log + gnu/tests/*/*.log.gz selinux: name: Run GNU tests (SELinux) @@ -226,7 +228,6 @@ jobs: - name: Build binaries run: | lima bash -c "cd ~/work/uutils/ && bash util/build-gnu.sh --release-build" - lima bash -c "mkdir -p ~/work/gnu/tests-selinux/" ### Run tests as user - name: Generate SELinux tests list @@ -246,7 +247,7 @@ jobs: - name: Extract testing info from individual logs into JSON shell: bash run : | - lima bash -c "cd ~/work/gnu/ && python3 ../uutils/util/gnu-json-result.py tests > ~/work/gnu/tests-selinux/${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }}" + lima bash -c "cd ~/work/gnu/ && python3 ../uutils/util/gnu-json-result.py tests > ~/work/${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }}" ### Run tests as root - name: Run GNU SELinux root tests @@ -255,23 +256,17 @@ jobs: - name: Extract testing info from individual logs (run as root) into JSON shell: bash run : | - lima bash -c "cd ~/work/gnu/ && python3 ../uutils/util/gnu-json-result.py tests > ~/work/gnu/tests-selinux/${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }}" + lima bash -c "cd ~/work/gnu/ && python3 ../uutils/util/gnu-json-result.py tests > ~/work/${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }}" ### Upload artifacts - name: Collect test logs and test results from VM run: | mkdir -p gnu/tests-selinux - # Copy the test logs from the Lima VM to the host - lima bash -c "cp ~/work/gnu/tests/test-suite.log ~/work/gnu/tests-selinux/ || echo 'No test-suite.log found'" - lima bash -c "cp ~/work/gnu/tests/test-suite-root.log ~/work/gnu/tests-selinux/ || echo 'No test-suite-root.log found'" - rsync -v -a -e ssh lima-default:~/work/gnu/tests-selinux/ ./gnu/tests-selinux/ - - # Copy SELinux logs to the main test directory for integrated processing - cp -f gnu/tests-selinux/test-suite.log gnu/tests/selinux-test-suite.log - cp -f gnu/tests-selinux/test-suite-root.log gnu/tests/selinux-test-suite-root.log - cp -f gnu/tests-selinux/${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} . - cp -f gnu/tests-selinux/${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} . + # Copy the json output back from the Lima VM to the host + rsync -v -a -e ssh lima-default:~/work/*.json ./ + # Copy the test directory now + rsync -v -a -e ssh lima-default:~/work/gnu/tests/ ./gnu/tests-selinux/ - name: Upload SELinux json results uses: actions/upload-artifact@v4 with: @@ -286,12 +281,14 @@ jobs: shell: bash run : | # Compress logs before upload (fails otherwise) - gzip gnu/tests-selinux/**/*.log + gzip gnu/tests-selinux/*/*.log - name: Upload SELinux test logs uses: actions/upload-artifact@v4 with: name: selinux-test-logs - path: "gnu/tests-selinux/**/*.log.gz" + path: | + gnu/tests-selinux/*.log + gnu/tests-selinux/*/*.log.gz aggregate: needs: [native, selinux] @@ -336,7 +333,7 @@ jobs: - name: Download selinux root json results uses: actions/download-artifact@v4 with: - name: selinux-root-gnu-full-result.json + name: selinux-root-gnu-full-result path: ${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} - name: Download full json results uses: actions/download-artifact@v4 From 50743ee8695861a64425d375469e4907f8df1ccc Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Fri, 25 Jul 2025 00:05:02 +0800 Subject: [PATCH 8/8] .github/workflows/GnuTests.yml: Fix aggregate job --- .github/workflows/GnuTests.yml | 96 ++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 46 deletions(-) diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index f7e74bd86b7..aabc597cc0d 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -325,26 +325,30 @@ jobs: # workflow_conclusion: success ## (default); * but, if commit with failed GnuTests is merged into the default branch, future commits will all show regression errors in GnuTests CI until o/w fixed workflow_conclusion: completed ## continually recalibrates to last commit of default branch with a successful GnuTests (ie, "self-heals" from GnuTest regressions, but needs more supervision for/of regressions) path: "reference" - - name: Download selinux json results - uses: actions/download-artifact@v4 - with: - name: selinux-gnu-full-result - path: ${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} - - name: Download selinux root json results - uses: actions/download-artifact@v4 - with: - name: selinux-root-gnu-full-result - path: ${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }} - name: Download full json results uses: actions/download-artifact@v4 with: name: gnu-full-result - path: ${{ env.TEST_FULL_SUMMARY_FILE }} + path: results + merge-multiple: true - name: Download root json results uses: actions/download-artifact@v4 with: name: gnu-root-full-result - path: ${{ env.TEST_ROOT_FULL_SUMMARY_FILE }} + path: results + merge-multiple: true + - name: Download selinux json results + uses: actions/download-artifact@v4 + with: + name: selinux-gnu-full-result + path: results + merge-multiple: true + - name: Download selinux root json results + uses: actions/download-artifact@v4 + with: + name: selinux-root-gnu-full-result + path: results + merge-multiple: true - name: Extract/summarize testing info id: summary shell: bash @@ -354,40 +358,40 @@ jobs: path_UUTILS='uutils' - # Check if the file exists - if test -f "${{ env.TEST_FULL_SUMMARY_FILE }}" - then - # Look at all individual results and summarize - eval $(python3 uutils/util/analyze-gnu-results.py -o=${{ steps.vars.outputs.AGGREGATED_SUMMARY_FILE }} ${{ env.TEST_FULL_SUMMARY_FILE }} ${{ env.TEST_ROOT_FULL_SUMMARY_FILE }} ${{ env.TEST_SELINUX_FULL_SUMMARY_FILE }} ${{ env.TEST_SELINUX_ROOT_FULL_SUMMARY_FILE }}) - - if [[ "$TOTAL" -eq 0 || "$TOTAL" -eq 1 ]]; then - echo "::error ::Failed to parse test results from '${{ env.TEST_FULL_SUMMARY_FILE }}'; failing early" - exit 1 - fi - - output="GNU tests summary = TOTAL: $TOTAL / PASS: $PASS / FAIL: $FAIL / ERROR: $ERROR / SKIP: $SKIP" - echo "${output}" - - if [[ "$FAIL" -gt 0 || "$ERROR" -gt 0 ]]; then - echo "::warning ::${output}" - fi - - jq -n \ - --arg date "$(date --rfc-email)" \ - --arg sha "$GITHUB_SHA" \ - --arg total "$TOTAL" \ - --arg pass "$PASS" \ - --arg skip "$SKIP" \ - --arg fail "$FAIL" \ - --arg xpass "$XPASS" \ - --arg error "$ERROR" \ - '{($date): { sha: $sha, total: $total, pass: $pass, skip: $skip, fail: $fail, xpass: $xpass, error: $error, }}' > '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' - HASH=$(sha1sum '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' | cut --delim=" " -f 1) - outputs HASH - else - echo "::error ::Failed to find summary of test results (missing '${{ env.TEST_FULL_SUMMARY_FILE }}'); failing early" - exit 1 - fi + json_count=$(ls -l results/*.json | wc -l) + if [[ "$json_count" -ne 4 ]]; then + echo "::error ::Failed to download all results json files (expected 4 files, found $json_count); failing early" + ls -lR results || true + exit 1 + fi + + # Look at all individual results and summarize + eval $(python3 uutils/util/analyze-gnu-results.py -o=${{ steps.vars.outputs.AGGREGATED_SUMMARY_FILE }} results/*.json) + + if [[ "$TOTAL" -eq 0 || "$TOTAL" -eq 1 ]]; then + echo "::error ::Failed to parse test results from '${{ env.TEST_FULL_SUMMARY_FILE }}'; failing early" + exit 1 + fi + + output="GNU tests summary = TOTAL: $TOTAL / PASS: $PASS / FAIL: $FAIL / ERROR: $ERROR / SKIP: $SKIP" + echo "${output}" + + if [[ "$FAIL" -gt 0 || "$ERROR" -gt 0 ]]; then + echo "::warning ::${output}" + fi + + jq -n \ + --arg date "$(date --rfc-email)" \ + --arg sha "$GITHUB_SHA" \ + --arg total "$TOTAL" \ + --arg pass "$PASS" \ + --arg skip "$SKIP" \ + --arg fail "$FAIL" \ + --arg xpass "$XPASS" \ + --arg error "$ERROR" \ + '{($date): { sha: $sha, total: $total, pass: $pass, skip: $skip, fail: $fail, xpass: $xpass, error: $error, }}' > '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' + HASH=$(sha1sum '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' | cut --delim=" " -f 1) + outputs HASH - name: Upload SHA1/ID of 'test-summary' uses: actions/upload-artifact@v4 with: