From e2be8c3dcca0cea278e0bf8de4addbc625227a6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Barto=C5=88?= Date: Thu, 29 Aug 2024 12:55:32 +0200 Subject: [PATCH] Add workflow for mingw-w64-gcc package testing --- .github/scripts/build-package.sh | 5 +- .github/scripts/patch-dejagnu.sh | 14 ++ .../build-and-test-mingw-w64-gcc.yml | 78 +++++++++ .github/workflows/build-package.yml | 53 +++++- patches/dejagnu/0001-local-exec.patch | 159 ++++++++++++++++++ 5 files changed, 301 insertions(+), 8 deletions(-) create mode 100755 .github/scripts/patch-dejagnu.sh create mode 100644 .github/workflows/build-and-test-mingw-w64-gcc.yml create mode 100644 patches/dejagnu/0001-local-exec.patch diff --git a/.github/scripts/build-package.sh b/.github/scripts/build-package.sh index 73101d3..8774f88 100755 --- a/.github/scripts/build-package.sh +++ b/.github/scripts/build-package.sh @@ -9,15 +9,18 @@ PACKAGE_REPOSITORY=$1 CLEAN_BUILD=${CLEAN_BUILD:-0} INSTALL_PACKAGE=${INSTALL_PACKAGE:-0} NO_EXTRACT=${NO_EXTRACT:-0} +NO_CHECK=${NO_CHECK:-1} +NO_ARCHIVE=${NO_ARCHIVE:-0} ARGUMENTS="--syncdeps \ --rmdeps \ --noconfirm \ --noprogressbar \ - --nocheck \ --skippgpcheck \ --force \ $([ "$NO_EXTRACT" = 1 ] && echo "--noextract" || echo "") \ + $([ "$NO_CHECK" = 1 ] && echo "--nocheck " || echo "") \ + $([ "$NO_ARCHIVE" = 1 ] && echo "--noarchive" || echo "") \ $([ "$CLEAN_BUILD" = 1 ] && echo "--cleanbuild" || echo "") \ $([ "$INSTALL_PACKAGE" = 1 ] && echo "--install" || echo "")" diff --git a/.github/scripts/patch-dejagnu.sh b/.github/scripts/patch-dejagnu.sh new file mode 100755 index 0000000..acf858a --- /dev/null +++ b/.github/scripts/patch-dejagnu.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e # exit on error +set -x # echo on +set -o pipefail # fail of any command in pipeline is an error + +DIR="`dirname ${BASH_SOURCE[0]}`/../.." +DIR=`realpath $DIR` + +pushd / + echo "::group::Patch Dejagnu" + patch -p1 -b -i "$DIR/patches/dejagnu/0001-local-exec.patch" + echo "::endgroup::" +popd diff --git a/.github/workflows/build-and-test-mingw-w64-gcc.yml b/.github/workflows/build-and-test-mingw-w64-gcc.yml new file mode 100644 index 0000000..c684c98 --- /dev/null +++ b/.github/workflows/build-and-test-mingw-w64-gcc.yml @@ -0,0 +1,78 @@ +name: Build and test mingw-w64-gcc + +on: + pull_request: + workflow_dispatch: + inputs: + packages_repository: + description: "MSYS2 packages repository to build from" + type: string + default: "Windows-on-ARM-Experiments/MINGW-packages" + packages_branch: + description: "MSYS2 packages branch to build from" + type: string + default: "woarm64" + arch: + description: 'Architecture that should be built and tested' + required: false + default: 'aarch64' + tag: + description: 'Tag to use for the artifact' + required: true + gcc_module: + description: 'GCC module to test' + required: false + default: 'gcc-c' + gcc_test_filter: + description: 'GCC test filter' + required: false + default: 'compile.exp=103818.c' + workflow_call: + inputs: + packages_repository: + type: string + packages_branch: + type: string + arch: + type: string + tag: + type: string + gcc_module: + type: string + gcc_test_filter: + type: string + +jobs: + build-and-test-mingw-w64-gcc: + name: Build and test mingw-w64-gcc + uses: ./.github/workflows/build-package.yml + with: + package_name: mingw-w64-gcc + packages_repository: ${{ inputs.packages_repository || 'Windows-on-ARM-Experiments/MINGW-packages' }} + packages_branch: ${{ inputs.packages_branch || 'woarm64' }} + runner_arch: ${{ inputs.arch || 'aarch64' }} + cross: false + check: true + check_module: ${{ inputs.gcc_module || '' }} + check_filter: ${{ inputs.gcc_test_filter || '' }} + + create-summary: + needs: build-and-test-mingw-w64-gcc + name: Create summary + runs-on: ubuntu-latest + + steps: + - name: Checkout mingw-woarm64-build repository + uses: actions/checkout@v4 + with: + repository: Windows-on-ARM-Experiments/mingw-woarm64-build + + - name: Download test results artifacts + uses: actions/download-artifact@v4 + with: + name: mingw-w64-gcc-test-results + path: ${{ github.workspace }}/test-results + + - name: Create summary + run: | + .github/scripts/toolchain/create-gcc-summary.sh ${{ github.workspace }}/test-results >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/build-package.yml b/.github/workflows/build-package.yml index 97c09ce..a6b1b9e 100644 --- a/.github/workflows/build-package.yml +++ b/.github/workflows/build-package.yml @@ -18,6 +18,10 @@ on: description: "Architecture to build on" type: string default: "x86_64" + cross: + description: "Use MSYS2 -> MINGW cross-compiler" + type: boolean + default: false needs: description: "Parent workflow job dependencies" type: string @@ -25,6 +29,18 @@ on: description: "Install additional dependencies" type: string default: "" + check: + description: "Enable check step after the package is built" + type: boolean + default: false + check_module: + description: "Module to test" + type: string + default: "" + check_filter: + description: "Test filter" + type: string + default: "" defaults: run: @@ -32,8 +48,12 @@ defaults: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CROSS_BUILD: ${{ inputs.runner_arch == 'aarch64' && '1' || '0' }} + CROSS_BUILD: ${{ inputs.cross && '1' || '0' }} CLEAN_BUILD: 1 + NO_CHECK: ${{ inputs.check && '0' || '1' }} + NO_ARCHIVE: ${{ inputs.check && '1' || '0' }} + MODULE: ${{ inputs.check_module }} + FILTER: ${{ inputs.check_filter }} jobs: build: @@ -41,11 +61,13 @@ jobs: runs-on: >- ${{ fromJson(inputs.runner_arch == 'aarch64' && '["Windows", "ARM64", "Blackhex"]' - || '["windows-latest"]') }} + || (inputs.check && '["Windows", "X64", "GCC"]' || '["windows-latest"]') + ) }} + timeout-minutes: ${{ inputs.check && 720 || 180 }} steps: - name: Kill hanging processes - if: ${{ inputs.runner_arch == 'aarch64' }} + if: ${{ inputs.runner_arch == 'aarch64' || inputs.check }} shell: powershell run: | tasklist @@ -62,7 +84,7 @@ jobs: git config --global core.longpaths true - name: Fix $PATH - if: ${{ inputs.runner_arch == 'aarch64' }} + if: ${{ inputs.runner_arch == 'aarch64' || inputs.check }} shell: powershell run: | Write-Output "GITHUB_PATH: $env:GITHUB_PATH" @@ -120,8 +142,11 @@ jobs: mingw-w64-x86_64-jq \ base-devel \ ${{ contains(inputs.packages_repository, 'MINGW') - && 'mingw-w64-cross-mingwarm64-gcc mingw-w64-cross-mingwarm64-windows-default-manifest mingw-w64-x86_64-gcc-libs' - || '' }} \ + && (inputs.cross + && 'mingw-w64-cross-mingwarm64-gcc mingw-w64-cross-mingwarm64-windows-default-manifest mingw-w64-x86_64-gcc-libs' + || 'mingw-w64-aarch64-gcc') + || '' }} \ + ${{ inputs.check && 'dejagnu' || ''}} ${{ inputs.dependencies }} - name: Download artifacts @@ -139,6 +164,11 @@ jobs: run: | `cygpath "${{ github.workspace }}"`/.github/scripts/pthread-headers-hack-before.sh + - name: Patch Dejagnu + if: ${{ inputs.check }} + run: | + `cygpath "${{ github.workspace }}"`/.github/scripts/patch-dejagnu.sh + - name: Setup MINGWARM64 environment if: ${{ inputs.runner_arch == 'aarch64' }} run: | @@ -156,7 +186,7 @@ jobs: key: ${{ inputs.package_name }}-ccache-${{ steps.enable-ccache.outputs.timestamp }} restore-keys: ${{ inputs.package_name }}- - - name: Build ${{ inputs.package_name }} + - name: Build ${{ inputs.check && 'and test' || '' }} ${{ inputs.package_name }} working-directory: ${{ github.workspace }}/packages/${{ inputs.package_name }} run: | `cygpath "${{ github.workspace }}"`/.github/scripts/build-package.sh ${{ inputs.packages_repository }} @@ -169,12 +199,21 @@ jobs: key: ${{ inputs.package_name }}-ccache-${{ steps.enable-ccache.outputs.timestamp }} - name: Upload ${{ inputs.package_name }} + if: ${{ !inputs.check }} uses: actions/upload-artifact@v4 with: name: ${{ inputs.package_name }} retention-days: 7 path: ${{ github.workspace }}/packages/${{ inputs.package_name }}/*.pkg.tar.zst + - name: Upload ${{ inputs.package_name }} test results + if: ${{ inputs.check }} + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.package_name }}-test-results + retention-days: 14 + path: ${{ github.workspace }}/packages/${{ inputs.package_name }}/src/test-results + - name: Upload build folder if: failure() uses: actions/upload-artifact@v4 diff --git a/patches/dejagnu/0001-local-exec.patch b/patches/dejagnu/0001-local-exec.patch new file mode 100644 index 0000000..86d664b --- /dev/null +++ b/patches/dejagnu/0001-local-exec.patch @@ -0,0 +1,159 @@ +--- a/usr/share/dejagnu/remote.exp ++++ b/usr/share/dejagnu/remote.exp +@@ -164,14 +164,7 @@ + # ignore SIGHUP. + global errorInfo + if { $inp eq "" && $outp eq "" } { +- set id -1 +- set result [catch "eval spawn -ignore SIGHUP \{${commandline}\}" pid] +- if { $result == 0 } { +- set result2 0 +- } else { +- set pid 0 +- set result2 5 +- } ++ set status [catch "exec timeout -k 5 10 $commandline" output] + } else { + # Use a command pipeline with open. + if { $inp ne "" } { +@@ -205,78 +198,80 @@ + } + set pid [pid $id] + set result [catch "spawn -ignore SIGHUP -leaveopen $id" result2] +- } +- # Prepend "-" to each pid, to generate the "process group IDs" needed by +- # kill. +- set pgid "-[join $pid { -}]" +- verbose "pid is $pid $pgid" +- if { $result != 0 || $result2 != 0 } { +- # This shouldn't happen. +- if {[info exists errorInfo]} { +- set foo $errorInfo +- } else { +- set foo "" ++ ++ # Prepend "-" to each pid, to generate the "process group IDs" needed by ++ # kill. ++ set pgid "-[join $pid { -}]" ++ verbose "pid is $pid $pgid" ++ if { $result != 0 || $result2 != 0 } { ++ # This shouldn't happen. ++ if {[info exists errorInfo]} { ++ set foo $errorInfo ++ } else { ++ set foo "" ++ } ++ verbose "spawn -open $id failed, $result $result2, $foo" ++ catch "close $id" ++ return [list -1 "spawn failed"] + } +- verbose "spawn -open $id failed, $result $result2, $foo" +- catch "close $id" +- return [list -1 "spawn failed"] +- } + +- set got_eof 0 +- set output "" ++ set got_eof 0 ++ set output "" + +- # Wait for either $timeout seconds to elapse, or for the program to +- # exit. +- expect { +- -i $spawn_id -timeout $timeout -re ".+" { +- append output $expect_out(buffer) +- exp_continue -continue_timer +- } +- timeout { +- warning "program timed out" +- } +- eof { +- set got_eof 1 ++ # Wait for either $timeout seconds to elapse, or for the program to ++ # exit. ++ expect { ++ -i $spawn_id -timeout $timeout -re ".+" { ++ append output $expect_out(buffer) ++ exp_continue -continue_timer ++ } ++ timeout { ++ warning "program timed out" ++ } ++ eof { ++ set got_eof 1 ++ } + } +- } + +- # If we didn't get EOF, we have to kill the poor defenseless program. +- if { $got_eof } { +- set pid -1 +- } +- set r2 [close_wait_program $spawn_id $pid wres] +- if { $id > 0 } { +- if { $pid > 0 } { +- # If timed-out, don't wait for all the processes associated +- # with the pipeline to terminate as a stuck one would cause +- # us to hang. +- catch {fconfigure $id -blocking false} ++ # If we didn't get EOF, we have to kill the poor defenseless program. ++ if { $got_eof } { ++ set pid -1 + } +- set r2 [catch "close $id" res] +- } else { +- verbose "waitres is $wres" 2 +- if { $r2 == 0 } { +- set r2 [lindex $wres 3] +- if { [llength $wres] > 4 } { +- if { [lindex $wres 4] eq "CHILDKILLED" } { +- set r2 1 +- } ++ set r2 [close_wait_program $spawn_id $pid wres] ++ if { $id > 0 } { ++ if { $pid > 0 } { ++ # If timed-out, don't wait for all the processes associated ++ # with the pipeline to terminate as a stuck one would cause ++ # us to hang. ++ catch {fconfigure $id -blocking false} + } +- if { $r2 != 0 } { +- set res $wres ++ set r2 [catch "close $id" res] ++ } else { ++ verbose "waitres is $wres" 2 ++ if { $r2 == 0 } { ++ set r2 [lindex $wres 3] ++ if { [llength $wres] > 4 } { ++ if { [lindex $wres 4] eq "CHILDKILLED" } { ++ set r2 1 ++ } ++ } ++ if { $r2 != 0 } { ++ set res $wres ++ } else { ++ set res "" ++ } + } else { +- set res "" ++ set res "wait failed" + } ++ } ++ if { $r2 != 0 || $res ne "" || ! $got_eof } { ++ verbose "close result is $res" ++ set status 1 + } else { +- set res "wait failed" ++ set status 0 + } + } +- if { $r2 != 0 || $res ne "" || ! $got_eof } { +- verbose "close result is $res" +- set status 1 +- } else { +- set status 0 +- } ++ + verbose "output is $output status $status" + if { $outp eq "" || $outp eq "|& cat" } { + return [list $status $output]