From a67bd8ab3665aa615698db90ccd15724fe1f8e39 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 16 Jul 2025 21:09:56 -0700 Subject: [PATCH 01/62] Prototyping 5974 * Create Check_Tests.yml * see GHI RustPython/RustPython#5974 --- .github/workflows/Check_Tests.yml | 146 ++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 .github/workflows/Check_Tests.yml diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml new file mode 100644 index 0000000000..e84c7e549d --- /dev/null +++ b/.github/workflows/Check_Tests.yml @@ -0,0 +1,146 @@ +--- +name: CI-5974 +description: "Continuous Integration workflow for GHI 5974." +run-name: Prototyping integration tests ${{ github.ref_name }} +# +# Jobs included: +# - BUILD: Ensures the project compiles correctly +# - BOOTSTRAP: Tests installation across Python versions and locales +# +# Required Secrets: +# NONE + +on: # yamllint disable-line rule:truthy + push: + branches: ["**"] # matches any branch + tags: ["v*"] + +# Declare default permissions as none. +permissions: {} + +env: + # ENVIRONMENT: ${{ (startsWith(github.ref, 'refs/heads/CI-CD-Patch-') }} + # Define Python versions at the top level -- Expected format: X.Y (e.g., 3.13) + PYTHON_DEFAULT: "${{ vars.PYTHON_DEFAULT }}" + PYTHON_OLD_MIN: "${{ vars.PYTHON_OLD_MIN }}" # For Oldest Python versions + PYTHON_OLD_EXTRA: "${{ vars.PYTHON_OLD_EXTRA }}" # For Older Python versions (Extra coverage) + PYTHON_EXPERIMENTAL: "${{ vars.PYTHON_EXPERIMENTAL }}" # For future Python versions + # Define the referance files to pull as a file glob pattern + TEST_MATCH_PATTERN: "Lib/tests/*.py" + +jobs: + TEST-5974: + permissions: + actions: read + contents: read + statuses: write + packages: none + pull-requests: read + security-events: none + if: ${{ (startsWith(github.ref, 'refs/heads/CI-CD-Patch-')) && !cancelled() }} + runs-on: ${{ matrix.os }} + timeout-minutes: 10 + continue-on-error: ${{ matrix.experimental }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-14, macos-15, windows-latest] + python-version: ["${{ vars.PYTHON_OLD_MIN }}", "${{ vars.PYTHON_OLD_EXTRA }}", "${{ vars.PYTHON_DEFAULT }}", "${{ vars.PYTHON_EXPERIMENTAL }}"] + experimental: [true] + include: + - os: ubuntu-latest + python-version: "${{ vars.PYTHON_DEFAULT }}" + experimental: false + - os: macos-latest + python-version: "${{ vars.PYTHON_EXPERIMENTAL }}" + experimental: false + - os: windows-latest + python-version: "${{ vars.PYTHON_DEFAULT }}" + experimental: false + - os: macos-14 + python-version: "${{ vars.PYTHON_DEFAULT }}" + experimental: true + outputs: + bootstrap_status: ${{ steps.smoke_testing.outcome }} + env: + PYTHON_VERSION: ${{ matrix.python-version }} + steps: + - name: Checkout RustPython repository + id: rpython + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + path: rustpython + # ref: + sparse-checkout-cone-mode: false + - id: cpython + name: Fetch Cpython + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + fetch-tags: true + repository: "python/cpython" + path: cpython + sparse-checkout: | + Lib/test + sparse-checkout-cone-mode: true + # checkout ${{ matrix.python-version }} + - name: Enumerate Referance Lib Files + id: reftestfiles + shell: bash + run: | + cd cpython + FILES=$(git ls-files --exclude-standard -- ${{ env.TEST_MATCH_PATTERN }} ) + if [ -z "$FILES" ]; then + printf "%s\n" "::warning file=.github/workflows/Check_Tests.yml:: No Lib/Test Referance files found." + printf "%s\n" "files=" >> "$GITHUB_OUTPUT" + else + printf "%s\n" "Lib/Test Referance files found:" + printf "%s\n" "$FILES" + # Replace line breaks with commas for GitHub Action Output + FILES="${FILES//$'\n'/ }" + printf "%s\n" "files=$FILES" >> "$GITHUB_OUTPUT" + fi + if: ${{ success() }} + # this next part is WIP and needs to be updated with filtering for more control of what parts of the referance lib is used + - name: "Integrate EVERY file" + id: merge_theirs + shell: bash + if: ${{ !cancelled() }} + run: | + for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do + cp -vf cpython/"${referance_file}" rpython/Lib/tests/$(basename "${referance_file}") || printf "::warning, file='%s',title='integration failure':: Could not integrate file.\n" "${referance_file}" ; + done + - id: output_python + name: "bootstrap Python" + shell: bash + run: | + printf "%s\n" "::group::bootstrap-python-env" + printf "python-version=%s\n" "${{ matrix.python-version }}" >> "$GITHUB_OUTPUT" + printf "PYTHON_VERSION=%s\n" "${{ matrix.python-version }}" >> "$GITHUB_ENV" + printf "%s\n" "::endgroup::" + - name: Try Smoke Testing + id: smoke_testing + shell: bash + if: ${{ !cancelled() }} + run: | + cd rpython || exit 13 ; + for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do + # Set the new ulimit value + ulimit -t 30 + printf "Now Testing '%s'\n" "${referance_file}" + # Execute the testing command in a subshell + ( + RUSTPYTHONPATH=Lib cargo run --release Lib/test/$(basename "${referance_file}") || printf "::error, file='%s',title='testing failure':: Could not pass tests for file.\n" "${referance_file}" ; + # should dump a diff or something here + ) ; + # Restore the original ulimit value + ulimit -t "$original_ulimit" + done + # cd "${OLDPWD:-..}" + - name: Post-Clean + id: post-bootstrap + run: | + exit 0 ; # don't break on regression + if: ${{ always() }} + shell: bash From bc3d741841921dc9a614d4f47f30819d848683c0 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 16 Jul 2025 21:15:00 -0700 Subject: [PATCH 02/62] Prototype test of Check_Tests.yml --- .github/workflows/Check_Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index e84c7e549d..850402d82e 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -37,7 +37,7 @@ jobs: packages: none pull-requests: read security-events: none - if: ${{ (startsWith(github.ref, 'refs/heads/CI-CD-Patch-')) && !cancelled() }} + if: ${{ !cancelled() }} runs-on: ${{ matrix.os }} timeout-minutes: 10 continue-on-error: ${{ matrix.experimental }} From 579df4af42a3084ad8ab604c1e5c250662185861 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 16 Jul 2025 21:25:22 -0700 Subject: [PATCH 03/62] Update Check_Tests.yml --- .github/workflows/Check_Tests.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 850402d82e..9af390509f 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -89,7 +89,11 @@ jobs: id: reftestfiles shell: bash run: | + ls -lap ${{ github.workspace }} + printf "\n\n" + ls -lap . cd cpython + ls -lap . FILES=$(git ls-files --exclude-standard -- ${{ env.TEST_MATCH_PATTERN }} ) if [ -z "$FILES" ]; then printf "%s\n" "::warning file=.github/workflows/Check_Tests.yml:: No Lib/Test Referance files found." @@ -101,6 +105,7 @@ jobs: FILES="${FILES//$'\n'/ }" printf "%s\n" "files=$FILES" >> "$GITHUB_OUTPUT" fi + cd ${{ git. if: ${{ success() }} # this next part is WIP and needs to be updated with filtering for more control of what parts of the referance lib is used - name: "Integrate EVERY file" From 3b0b622933b3de4a50900d7568ce5e8ce4d4f1ee Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 16 Jul 2025 21:26:12 -0700 Subject: [PATCH 04/62] Update Check_Tests.yml --- .github/workflows/Check_Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 9af390509f..f4dbc64746 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -89,7 +89,7 @@ jobs: id: reftestfiles shell: bash run: | - ls -lap ${{ github.workspace }} + ls -lap "${{ github.workspace }}" printf "\n\n" ls -lap . cd cpython From 8fb83bbca0e271bf6dbca3b88211077ec54a9fe9 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 16 Jul 2025 21:27:57 -0700 Subject: [PATCH 05/62] Update Check_Tests.yml --- .github/workflows/Check_Tests.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index f4dbc64746..288fb3f1f5 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -89,11 +89,9 @@ jobs: id: reftestfiles shell: bash run: | - ls -lap "${{ github.workspace }}" - printf "\n\n" - ls -lap . - cd cpython - ls -lap . + ls -lap . ; + cd cpython ; + ls -lap . ; FILES=$(git ls-files --exclude-standard -- ${{ env.TEST_MATCH_PATTERN }} ) if [ -z "$FILES" ]; then printf "%s\n" "::warning file=.github/workflows/Check_Tests.yml:: No Lib/Test Referance files found." @@ -105,7 +103,7 @@ jobs: FILES="${FILES//$'\n'/ }" printf "%s\n" "files=$FILES" >> "$GITHUB_OUTPUT" fi - cd ${{ git. + cd .. ; if: ${{ success() }} # this next part is WIP and needs to be updated with filtering for more control of what parts of the referance lib is used - name: "Integrate EVERY file" From 370eeb96ca4ab7f88ebd6ac09bcb13979f5298f8 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 17 Jul 2025 12:21:22 -0700 Subject: [PATCH 06/62] Tweaked Check_Tests.yml --- .github/workflows/Check_Tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 288fb3f1f5..88d61e40fb 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -112,7 +112,7 @@ jobs: if: ${{ !cancelled() }} run: | for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do - cp -vf cpython/"${referance_file}" rpython/Lib/tests/$(basename "${referance_file}") || printf "::warning, file='%s',title='integration failure':: Could not integrate file.\n" "${referance_file}" ; + cp -vf cpython/"${referance_file}" rustpython/Lib/tests/$(basename "${referance_file}") || printf "::warning, file='%s',title='integration failure':: Could not integrate file.\n" "${referance_file}" ; done - id: output_python name: "bootstrap Python" @@ -127,7 +127,7 @@ jobs: shell: bash if: ${{ !cancelled() }} run: | - cd rpython || exit 13 ; + cd rustpython || exit 13 ; for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do # Set the new ulimit value ulimit -t 30 @@ -140,7 +140,7 @@ jobs: # Restore the original ulimit value ulimit -t "$original_ulimit" done - # cd "${OLDPWD:-..}" + cd .. ; - name: Post-Clean id: post-bootstrap run: | From 7032a3cc70646d361879e0d3d7a58a67365a1093 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 17 Jul 2025 12:30:59 -0700 Subject: [PATCH 07/62] Update Check_Tests.yml --- .github/workflows/Check_Tests.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 88d61e40fb..58574e310c 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -26,7 +26,7 @@ env: PYTHON_OLD_EXTRA: "${{ vars.PYTHON_OLD_EXTRA }}" # For Older Python versions (Extra coverage) PYTHON_EXPERIMENTAL: "${{ vars.PYTHON_EXPERIMENTAL }}" # For future Python versions # Define the referance files to pull as a file glob pattern - TEST_MATCH_PATTERN: "Lib/tests/*.py" + TEST_MATCH_PATTERN: "Lib/test/*.py" jobs: TEST-5974: @@ -89,7 +89,6 @@ jobs: id: reftestfiles shell: bash run: | - ls -lap . ; cd cpython ; ls -lap . ; FILES=$(git ls-files --exclude-standard -- ${{ env.TEST_MATCH_PATTERN }} ) @@ -112,7 +111,7 @@ jobs: if: ${{ !cancelled() }} run: | for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do - cp -vf cpython/"${referance_file}" rustpython/Lib/tests/$(basename "${referance_file}") || printf "::warning, file='%s',title='integration failure':: Could not integrate file.\n" "${referance_file}" ; + cp -vf cpython/"${referance_file}" rustpython/"${referance_file}" || printf "::warning, file='%s',title='integration failure':: Could not integrate file.\n" "${referance_file}" ; done - id: output_python name: "bootstrap Python" From c9840458faba15b23827cd927f1dc640ebf4fa6e Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 17 Jul 2025 12:41:55 -0700 Subject: [PATCH 08/62] DEBUG for Check_Tests.yml disabled integrating cpython lib --- .github/workflows/Check_Tests.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 58574e310c..95db4ed30a 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -111,6 +111,7 @@ jobs: if: ${{ !cancelled() }} run: | for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do + printf "::warning, file='%s',title='integration disabled':: SKIPPING integration of file.\n" "${referance_file}" ; cp -vf cpython/"${referance_file}" rustpython/"${referance_file}" || printf "::warning, file='%s',title='integration failure':: Could not integrate file.\n" "${referance_file}" ; done - id: output_python @@ -129,7 +130,7 @@ jobs: cd rustpython || exit 13 ; for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do # Set the new ulimit value - ulimit -t 30 + ulimit -t 45 printf "Now Testing '%s'\n" "${referance_file}" # Execute the testing command in a subshell ( @@ -137,7 +138,7 @@ jobs: # should dump a diff or something here ) ; # Restore the original ulimit value - ulimit -t "$original_ulimit" + ulimit -t $original_ulimit || exit 126 ; done cd .. ; - name: Post-Clean From 42e6bd105b147414e3b85f96918ddf42250fec06 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 17 Jul 2025 13:36:27 -0700 Subject: [PATCH 09/62] DEBUG Check_Tests.yml disable cpython integration and increase ulimit to debug compile timming issues --- .github/workflows/Check_Tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 95db4ed30a..efb3358bbc 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -112,7 +112,7 @@ jobs: run: | for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do printf "::warning, file='%s',title='integration disabled':: SKIPPING integration of file.\n" "${referance_file}" ; - cp -vf cpython/"${referance_file}" rustpython/"${referance_file}" || printf "::warning, file='%s',title='integration failure':: Could not integrate file.\n" "${referance_file}" ; + #cp -vf cpython/"${referance_file}" rustpython/"${referance_file}" || printf "::warning, file='%s',title='integration failure':: Could not integrate file.\n" "${referance_file}" ; done - id: output_python name: "bootstrap Python" @@ -130,7 +130,7 @@ jobs: cd rustpython || exit 13 ; for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do # Set the new ulimit value - ulimit -t 45 + ulimit -t 180 printf "Now Testing '%s'\n" "${referance_file}" # Execute the testing command in a subshell ( From da5c6b692829db2c6251c7f8c2ddbb4cb0e19314 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 17 Jul 2025 13:49:57 -0700 Subject: [PATCH 10/62] DEBUG Check_Tests.yml builds disabled multi-os to test builds in separate step --- .github/workflows/Check_Tests.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index efb3358bbc..2fda6273f2 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -44,7 +44,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-14, macos-15, windows-latest] + os: [ubuntu-latest] # disabled , macos-14, macos-15, windows-latest] python-version: ["${{ vars.PYTHON_OLD_MIN }}", "${{ vars.PYTHON_OLD_EXTRA }}", "${{ vars.PYTHON_DEFAULT }}", "${{ vars.PYTHON_EXPERIMENTAL }}"] experimental: [true] include: @@ -114,6 +114,18 @@ jobs: printf "::warning, file='%s',title='integration disabled':: SKIPPING integration of file.\n" "${referance_file}" ; #cp -vf cpython/"${referance_file}" rustpython/"${referance_file}" || printf "::warning, file='%s',title='integration failure':: Could not integrate file.\n" "${referance_file}" ; done + - name: Pre-Test Build check + id: build_testing + shell: bash + if: ${{ !cancelled() }} + run: | + cd rustpython || exit 13 ; + printf "Now Building '%s'\n" "" + # Execute the testing command in a subshell + ( + RUSTPYTHONPATH=Lib cargo run --release --version || printf "::error, title='build failure':: Could not pass build step for version check.\n" ; + ) ; + cd .. ; - id: output_python name: "bootstrap Python" shell: bash From 7b84e63784324aa39e36e294f98dcb7e453a06ff Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 17 Jul 2025 13:59:00 -0700 Subject: [PATCH 11/62] Update Check_Tests.yml --- .github/workflows/Check_Tests.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 2fda6273f2..15a068295b 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -123,11 +123,12 @@ jobs: printf "Now Building '%s'\n" "" # Execute the testing command in a subshell ( - RUSTPYTHONPATH=Lib cargo run --release --version || printf "::error, title='build failure':: Could not pass build step for version check.\n" ; + RUSTPYTHONPATH=Lib cargo run --release -- --version || printf "::error, title='build failure':: Could not pass build step for version check.\n" ; ) ; cd .. ; - id: output_python name: "bootstrap Python" + if: ${{ !cancelled() }} shell: bash run: | printf "%s\n" "::group::bootstrap-python-env" @@ -137,7 +138,7 @@ jobs: - name: Try Smoke Testing id: smoke_testing shell: bash - if: ${{ !cancelled() }} + if: ${{ success() }} run: | cd rustpython || exit 13 ; for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do @@ -146,7 +147,7 @@ jobs: printf "Now Testing '%s'\n" "${referance_file}" # Execute the testing command in a subshell ( - RUSTPYTHONPATH=Lib cargo run --release Lib/test/$(basename "${referance_file}") || printf "::error, file='%s',title='testing failure':: Could not pass tests for file.\n" "${referance_file}" ; + RUSTPYTHONPATH=Lib cargo run --release -- Lib/test/$(basename "${referance_file}") || printf "::error, file='%s',title='testing failure':: Could not pass tests for file.\n" "${referance_file}" ; # should dump a diff or something here ) ; # Restore the original ulimit value From e8dd40adb4c75975155bd6c1874bf293c7a74e85 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 17 Jul 2025 14:22:19 -0700 Subject: [PATCH 12/62] Fixup Check_Tests.yml more * re-enable integration logic * build before integration * use the python version to checkout the cpython version --- .github/workflows/Check_Tests.yml | 47 +++++++++++++++++-------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 15a068295b..c7ff125206 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -44,8 +44,8 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest] # disabled , macos-14, macos-15, windows-latest] - python-version: ["${{ vars.PYTHON_OLD_MIN }}", "${{ vars.PYTHON_OLD_EXTRA }}", "${{ vars.PYTHON_DEFAULT }}", "${{ vars.PYTHON_EXPERIMENTAL }}"] + os: [ubuntu-latest, macos-15, windows-latest] + python-version: ["${{ vars.PYTHON_DEFAULT }}"] # skip fo now ["${{ vars.PYTHON_OLD_MIN }}", "${{ vars.PYTHON_OLD_EXTRA }}", "${{ vars.PYTHON_DEFAULT }}", "${{ vars.PYTHON_EXPERIMENTAL }}"] experimental: [true] include: - os: ubuntu-latest @@ -63,6 +63,7 @@ jobs: outputs: bootstrap_status: ${{ steps.smoke_testing.outcome }} env: + OS: ${{ runner.os }} PYTHON_VERSION: ${{ matrix.python-version }} steps: - name: Checkout RustPython repository @@ -73,6 +74,18 @@ jobs: path: rustpython # ref: sparse-checkout-cone-mode: false + - name: Pre-Test Build check + id: build_testing + shell: bash + if: ${{ !cancelled() }} + run: | + cd rustpython || exit 13 ; + printf "Now Building '%s'\n" "" + # Execute the testing command in a subshell + ( + RUSTPYTHONPATH=Lib cargo run --release -- --version || printf "::error, title='build failure':: Could not pass build step for version check.\n" ; + ) ; + cd .. ; - id: cpython name: Fetch Cpython uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -84,7 +97,7 @@ jobs: sparse-checkout: | Lib/test sparse-checkout-cone-mode: true - # checkout ${{ matrix.python-version }} + ref: '${{ matrix.python-version }}' - name: Enumerate Referance Lib Files id: reftestfiles shell: bash @@ -111,21 +124,8 @@ jobs: if: ${{ !cancelled() }} run: | for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do - printf "::warning, file='%s',title='integration disabled':: SKIPPING integration of file.\n" "${referance_file}" ; - #cp -vf cpython/"${referance_file}" rustpython/"${referance_file}" || printf "::warning, file='%s',title='integration failure':: Could not integrate file.\n" "${referance_file}" ; + cp -vf cpython/"${referance_file}" rustpython/"${referance_file}" || printf "::warning, file='%s',title='integration failure':: Could not integrate file.\n" "${referance_file}" ; done - - name: Pre-Test Build check - id: build_testing - shell: bash - if: ${{ !cancelled() }} - run: | - cd rustpython || exit 13 ; - printf "Now Building '%s'\n" "" - # Execute the testing command in a subshell - ( - RUSTPYTHONPATH=Lib cargo run --release -- --version || printf "::error, title='build failure':: Could not pass build step for version check.\n" ; - ) ; - cd .. ; - id: output_python name: "bootstrap Python" if: ${{ !cancelled() }} @@ -142,16 +142,21 @@ jobs: run: | cd rustpython || exit 13 ; for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do - # Set the new ulimit value - ulimit -t 180 + if [[ "${OS}" != "Windows" ]] ; then + # Set the new ulimit value + ulimit -t 180 + # TODO: RustPython workaround Windows timeout for hangs + fi ; printf "Now Testing '%s'\n" "${referance_file}" # Execute the testing command in a subshell ( RUSTPYTHONPATH=Lib cargo run --release -- Lib/test/$(basename "${referance_file}") || printf "::error, file='%s',title='testing failure':: Could not pass tests for file.\n" "${referance_file}" ; # should dump a diff or something here ) ; - # Restore the original ulimit value - ulimit -t $original_ulimit || exit 126 ; + if [[ "${OS}" != "Windows" ]] ; then + # Restore the original ulimit value + ulimit -t $original_ulimit || exit 126 ; + fi ; done cd .. ; - name: Post-Clean From e4ea14569a97d0cda4bd28bebb51fbd37a223034 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 17 Jul 2025 14:23:33 -0700 Subject: [PATCH 13/62] Update envs for OS in Check_Tests.yml --- .github/workflows/Check_Tests.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index c7ff125206..df41bb06c4 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -63,7 +63,6 @@ jobs: outputs: bootstrap_status: ${{ steps.smoke_testing.outcome }} env: - OS: ${{ runner.os }} PYTHON_VERSION: ${{ matrix.python-version }} steps: - name: Checkout RustPython repository @@ -138,6 +137,8 @@ jobs: - name: Try Smoke Testing id: smoke_testing shell: bash + env: + OS: ${{ runner.os }} if: ${{ success() }} run: | cd rustpython || exit 13 ; From 62b215952fea21cee83c02827ee34226161e50fb Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 17 Jul 2025 14:46:43 -0700 Subject: [PATCH 14/62] First just-integrate Cpython into Rustpython Automation test for RustPython/RustPython#5974 * PoC testing for GHA to automate part of GHI RustPython/RustPython#5974 * THIS IS AN EXPERIMENT and WIP --- .github/workflows/Check_Tests.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index df41bb06c4..abfe38f331 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -39,13 +39,13 @@ jobs: security-events: none if: ${{ !cancelled() }} runs-on: ${{ matrix.os }} - timeout-minutes: 10 + timeout-minutes: 30 continue-on-error: ${{ matrix.experimental }} strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-15, windows-latest] - python-version: ["${{ vars.PYTHON_DEFAULT }}"] # skip fo now ["${{ vars.PYTHON_OLD_MIN }}", "${{ vars.PYTHON_OLD_EXTRA }}", "${{ vars.PYTHON_DEFAULT }}", "${{ vars.PYTHON_EXPERIMENTAL }}"] + os: [ubuntu-latest, macos-14, macos-15, windows-latest] + python-version: ["${{ vars.PYTHON_OLD_MIN }}", "${{ vars.PYTHON_OLD_EXTRA }}", "${{ vars.PYTHON_DEFAULT }}", "${{ vars.PYTHON_EXPERIMENTAL }}"] experimental: [true] include: - os: ubuntu-latest @@ -60,6 +60,9 @@ jobs: - os: macos-14 python-version: "${{ vars.PYTHON_DEFAULT }}" experimental: true + - os: windows-2025 + python-version: "${{ vars.PYTHON_DEFAULT }}" + experimental: true outputs: bootstrap_status: ${{ steps.smoke_testing.outcome }} env: @@ -117,7 +120,7 @@ jobs: cd .. ; if: ${{ success() }} # this next part is WIP and needs to be updated with filtering for more control of what parts of the referance lib is used - - name: "Integrate EVERY file" + - name: "Integrate Cpython Test file" id: merge_theirs shell: bash if: ${{ !cancelled() }} @@ -142,16 +145,17 @@ jobs: if: ${{ success() }} run: | cd rustpython || exit 13 ; + original_ulimit=$(ulimit -t) ; for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do if [[ "${OS}" != "Windows" ]] ; then # Set the new ulimit value - ulimit -t 180 + ulimit -t 360 # TODO: RustPython workaround Windows timeout for hangs fi ; printf "Now Testing '%s'\n" "${referance_file}" # Execute the testing command in a subshell ( - RUSTPYTHONPATH=Lib cargo run --release -- Lib/test/$(basename "${referance_file}") || printf "::error, file='%s',title='testing failure':: Could not pass tests for file.\n" "${referance_file}" ; + RUSTPYTHONPATH=Lib cargo run --release -- Lib/test/$(basename "${referance_file}") || printf "::error, file='%s',title='testing-failure':: Could not pass tests for file.\n" "${referance_file}" >>&2 ; # should dump a diff or something here ) ; if [[ "${OS}" != "Windows" ]] ; then From 16908ce11dc655d5e3c28e1e86357323f81d0d19 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 17 Jul 2025 14:48:59 -0700 Subject: [PATCH 15/62] Second-Attempt for GHI RustPython/RustPython#5974 * see GHI RustPython/RustPython#5974 --- .github/workflows/Check_Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index abfe38f331..2943d1ed92 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -155,7 +155,7 @@ jobs: printf "Now Testing '%s'\n" "${referance_file}" # Execute the testing command in a subshell ( - RUSTPYTHONPATH=Lib cargo run --release -- Lib/test/$(basename "${referance_file}") || printf "::error, file='%s',title='testing-failure':: Could not pass tests for file.\n" "${referance_file}" >>&2 ; + RUSTPYTHONPATH=Lib cargo run --release -- Lib/test/$(basename "${referance_file}") || printf "::error, file='%s',title='testing-failure':: Could not pass tests for file.\n" "${referance_file}" >2 ; # should dump a diff or something here ) ; if [[ "${OS}" != "Windows" ]] ; then From 765057665bda071e7989d1301b8f9525df1dd858 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 17 Jul 2025 14:57:04 -0700 Subject: [PATCH 16/62] Remove ulimit and re-test * see RustPython/RustPython#5974 --- .github/workflows/Check_Tests.yml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 2943d1ed92..8e2d5fa369 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -145,23 +145,15 @@ jobs: if: ${{ success() }} run: | cd rustpython || exit 13 ; - original_ulimit=$(ulimit -t) ; for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do - if [[ "${OS}" != "Windows" ]] ; then - # Set the new ulimit value - ulimit -t 360 - # TODO: RustPython workaround Windows timeout for hangs - fi ; + # TODO: RustPython workaround Windows timeout for hangs printf "Now Testing '%s'\n" "${referance_file}" # Execute the testing command in a subshell ( RUSTPYTHONPATH=Lib cargo run --release -- Lib/test/$(basename "${referance_file}") || printf "::error, file='%s',title='testing-failure':: Could not pass tests for file.\n" "${referance_file}" >2 ; # should dump a diff or something here ) ; - if [[ "${OS}" != "Windows" ]] ; then - # Restore the original ulimit value - ulimit -t $original_ulimit || exit 126 ; - fi ; + printf "\n---\n" ; done cd .. ; - name: Post-Clean From bcf6261d0677e2c9e79c5b578fea2b9fa6e7a758 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Mon, 21 Jul 2025 11:27:36 -0700 Subject: [PATCH 17/62] Update Check_Tests.yml to attempt auto-fix via fix_test.py * see RustPython/RustPython#5974 --- .github/workflows/Check_Tests.yml | 40 ++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 8e2d5fa369..c0b7bc9f37 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -127,6 +127,7 @@ jobs: run: | for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do cp -vf cpython/"${referance_file}" rustpython/"${referance_file}" || printf "::warning, file='%s',title='integration failure':: Could not integrate file.\n" "${referance_file}" ; + # TODO: attempt test with rustpython/scripts/fix_test.py || revert by re-checkout done - id: output_python name: "bootstrap Python" @@ -148,12 +149,45 @@ jobs: for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do # TODO: RustPython workaround Windows timeout for hangs printf "Now Testing '%s'\n" "${referance_file}" + # vars for subshell but not for workflow + export REF_FILE_NAME=$(basename "${referance_file}") ; + printf "\n::group::%s\n" "${REF_FILE_NAME}" ; + # TODO: test with cpython first + # TODO: add to list of files that need additional prep due to hanging or unexpected failures that need to be removed # Execute the testing command in a subshell - ( - RUSTPYTHONPATH=Lib cargo run --release -- Lib/test/$(basename "${referance_file}") || printf "::error, file='%s',title='testing-failure':: Could not pass tests for file.\n" "${referance_file}" >2 ; + time ( + RUSTPYTHONPATH=Lib cargo run --release -- Lib/test/"${REF_FILE_NAME}" || RAW_COPY_OUTCOME='failing' + if [[ ( -z ${RAW_COPY_OUTCOME} ) ]] ; then + printf "::error, file='%s',title='testing-failure':: Could not copy and pass tests for file.\n" "${referance_file}" >2 ; + ( + RUSTPYTHONPATH=Lib cargo run --release -- ./scripts/fix_test.py --path ./Lib/test/"${REF_FILE_NAME}" || FIX_COPY_OUTCOME='unfixed' ; + ) ; + if [[ ( -z ${RAW_COPY_OUTCOME} ) ]] ; then + printf "::error, file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${referance_file}" >2 ; + # reset broken integration to last rustpython copy + git restore "${referance_file}" || : ; + git checkout -- "${referance_file}" || : ; + # TODO: validate and set FIX_COPY_OUTCOME="reverted" + else + FIX_COPY_OUTCOME="fixed" + RAW_COPY_OUTCOME="incompatable" + fi ; + else + FIX_COPY_OUTCOME="skipped" + RAW_COPY_OUTCOME="compatable" + fi ; + printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; + printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" ; + printf "FIX_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; + printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; # should dump a diff or something here ) ; - printf "\n---\n" ; + wait ; + # cleanup temp env + unset FIX_COPY_OUTCOME 2>/dev/null || : ; + unset RAW_COPY_OUTCOME 2>/dev/null || : ; + unset REF_FILE_NAME 2>/dev/null || : ; + printf "\n::endgroup::\n" ; done cd .. ; - name: Post-Clean From ec878b638de40a7570d89402fe8deddbc63fd819 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Mon, 21 Jul 2025 12:06:14 -0700 Subject: [PATCH 18/62] STYLE fixes for Check_Tests.yml * style fixes --- .github/workflows/Check_Tests.yml | 32 ++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index c0b7bc9f37..6cfabb94e6 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -4,8 +4,7 @@ description: "Continuous Integration workflow for GHI 5974." run-name: Prototyping integration tests ${{ github.ref_name }} # # Jobs included: -# - BUILD: Ensures the project compiles correctly -# - BOOTSTRAP: Tests installation across Python versions and locales +# - TEST-5974: Tests installation across Python versions and locales # # Required Secrets: # NONE @@ -67,6 +66,7 @@ jobs: bootstrap_status: ${{ steps.smoke_testing.outcome }} env: PYTHON_VERSION: ${{ matrix.python-version }} + steps: - name: Checkout RustPython repository id: rpython @@ -85,7 +85,7 @@ jobs: printf "Now Building '%s'\n" "" # Execute the testing command in a subshell ( - RUSTPYTHONPATH=Lib cargo run --release -- --version || printf "::error, title='build failure':: Could not pass build step for version check.\n" ; + RUSTPYTHONPATH=Lib cargo run --release -- --version || printf "::error title='build failure':: Could not pass build step for version check.\n" ; ) ; cd .. ; - id: cpython @@ -119,14 +119,27 @@ jobs: fi cd .. ; if: ${{ success() }} + - name: "License" + id: show-cpython-license + shell: bash + if: ${{ !cancelled() }} + run: | + if [[ -r LICENSE ]] ; then + printf "\n\n" + cat 2 ; + if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then + printf "::error file='%s',title='testing-failure':: Could not copy and pass tests for file.\n" "${referance_file}" >2 ; ( RUSTPYTHONPATH=Lib cargo run --release -- ./scripts/fix_test.py --path ./Lib/test/"${REF_FILE_NAME}" || FIX_COPY_OUTCOME='unfixed' ; ) ; - if [[ ( -z ${RAW_COPY_OUTCOME} ) ]] ; then - printf "::error, file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${referance_file}" >2 ; + if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then + printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${referance_file}" >2 ; # reset broken integration to last rustpython copy git restore "${referance_file}" || : ; git checkout -- "${referance_file}" || : ; @@ -177,10 +190,11 @@ jobs: RAW_COPY_OUTCOME="compatable" fi ; printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; - printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" ; + wait ; # used to force boundry for std out read/write race in UI printf "FIX_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; # should dump a diff or something here + printf "\n\n" ) ; wait ; # cleanup temp env From 7a1122c395d3da80f851979738b973ff56161fc5 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Mon, 21 Jul 2025 12:36:42 -0700 Subject: [PATCH 19/62] More Tweaking of Check_Tests.yml * Prototyping churn --- .github/workflows/Check_Tests.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 6cfabb94e6..bceece70b2 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -104,7 +104,7 @@ jobs: id: reftestfiles shell: bash run: | - cd cpython ; + cd cpython || exit 14 ; ls -lap . ; FILES=$(git ls-files --exclude-standard -- ${{ env.TEST_MATCH_PATTERN }} ) if [ -z "$FILES" ]; then @@ -124,6 +124,7 @@ jobs: shell: bash if: ${{ !cancelled() }} run: | + cd cpython || exit 14 ; if [[ -r LICENSE ]] ; then printf "\n\n" cat 2 ; + printf "::warning file='%s',title='test-warning':: Could not copy and pass tests for file.\n" "${referance_file}" ; ( RUSTPYTHONPATH=Lib cargo run --release -- ./scripts/fix_test.py --path ./Lib/test/"${REF_FILE_NAME}" || FIX_COPY_OUTCOME='unfixed' ; ) ; - if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then - printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${referance_file}" >2 ; + if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then + printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${referance_file}" >>2 ; # reset broken integration to last rustpython copy - git restore "${referance_file}" || : ; - git checkout -- "${referance_file}" || : ; + git restore --ignore-unmerged --worktree --staged "${referance_file}" || : ; + git checkout -f --ignore-unmerged -- "${referance_file}" || : ; # TODO: validate and set FIX_COPY_OUTCOME="reverted" else FIX_COPY_OUTCOME="fixed" @@ -194,7 +196,7 @@ jobs: printf "FIX_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; # should dump a diff or something here - printf "\n\n" + printf "\n\n" ; ) ; wait ; # cleanup temp env From 7b14fb8d7e62cbf29b27ae5d479438522862ea15 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Mon, 21 Jul 2025 17:13:34 -0700 Subject: [PATCH 20/62] Smarter filtering for direct invocation in Check_Tests.yml * With a minimal working PoC for automation of using `scripts/fix_test.py` this has reached the very first milestone of a single working test * Still experimental WIP * see RustPython/RustPython#5974 for context --- .github/workflows/Check_Tests.yml | 95 ++++++++++++++++++------------- 1 file changed, 54 insertions(+), 41 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index bceece70b2..19c02919fd 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -8,6 +8,10 @@ run-name: Prototyping integration tests ${{ github.ref_name }} # # Required Secrets: # NONE +# +# WORK IN PROGRESS +# search for "TODO" in file for more details on what is still un-implemented + on: # yamllint disable-line rule:truthy push: @@ -66,7 +70,7 @@ jobs: bootstrap_status: ${{ steps.smoke_testing.outcome }} env: PYTHON_VERSION: ${{ matrix.python-version }} - + # TODO: move to seperate action steps: - name: Checkout RustPython repository id: rpython @@ -162,48 +166,57 @@ jobs: run: | cd rustpython || exit 13 ; for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do - # TODO: RustPython workaround Windows timeout for hangs - printf "Now Testing '%s'\n" "${referance_file}" - # vars for subshell but not for workflow - export REF_FILE_NAME=$(basename "${referance_file}") ; - printf "\n::group::%s\n" "${REF_FILE_NAME}" ; - # TODO: test with cpython first - # TODO: add to list of files that need additional prep due to hanging or unexpected failures that need to be removed - # Execute the testing command in a subshell - time ( - RUSTPYTHONPATH=Lib cargo run --release -- Lib/test/"${REF_FILE_NAME}" || RAW_COPY_OUTCOME='failing' - if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then - printf "::warning file='%s',title='test-warning':: Could not copy and pass tests for file.\n" "${referance_file}" ; - ( - RUSTPYTHONPATH=Lib cargo run --release -- ./scripts/fix_test.py --path ./Lib/test/"${REF_FILE_NAME}" || FIX_COPY_OUTCOME='unfixed' ; + if [[ ( -f "${referance_file}" ) ]] ; then + # See https://devguide.python.org/testing/run-write-tests + # Heuristic: "if some module does not have unittest.main(), then most likely it does not support direct invocation." + if grep -qF "unittest.main()" "${referance_file}" 2>dev/null ; then + # TODO: RustPython workaround Windows timeout for hangs + printf "Now Testing '%s'\n" "${referance_file}" + # vars for subshell but not for workflow + export REF_FILE_NAME=$(basename "${referance_file}") ; + printf "\n::group::%s\n" "${REF_FILE_NAME}" ; + # TODO: test with cpython first for baseline + # TODO: add to list of files that need additional prep due to hanging or unexpected failures that need to be removed + # Execute the testing command in a subshell + time ( + RUSTPYTHONPATH=Lib cargo run --release -- Lib/test/"${REF_FILE_NAME}" || RAW_COPY_OUTCOME='failing' + if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then + printf "::warning file='%s',title='test-warning':: Could not copy and pass tests for file.\n" "${referance_file}" ; + ( + RUSTPYTHONPATH=Lib cargo run --release -- ./scripts/fix_test.py --path ./Lib/test/"${REF_FILE_NAME}" || FIX_COPY_OUTCOME='unfixed' ; + ) ; + if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then + printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${referance_file}" >>2 ; + # reset broken integration to last rustpython copy + git restore --ignore-unmerged --worktree --staged "${referance_file}" || : ; + git checkout -f --ignore-unmerged -- "${referance_file}" || : ; + # TODO: validate and set FIX_COPY_OUTCOME="reverted" + else + FIX_COPY_OUTCOME="fixed" + RAW_COPY_OUTCOME="incompatable" + fi ; + else + FIX_COPY_OUTCOME="skipped" + RAW_COPY_OUTCOME="compatable" + fi ; + printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; + wait ; # used to force boundry for std out read/write race in UI + printf "FIX_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; + printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; + # should dump a diff or something here + printf "\n\n" ; ) ; - if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then - printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${referance_file}" >>2 ; - # reset broken integration to last rustpython copy - git restore --ignore-unmerged --worktree --staged "${referance_file}" || : ; - git checkout -f --ignore-unmerged -- "${referance_file}" || : ; - # TODO: validate and set FIX_COPY_OUTCOME="reverted" - else - FIX_COPY_OUTCOME="fixed" - RAW_COPY_OUTCOME="incompatable" - fi ; + wait ; + # cleanup temp env + unset FIX_COPY_OUTCOME 2>/dev/null || : ; + unset RAW_COPY_OUTCOME 2>/dev/null || : ; + unset REF_FILE_NAME 2>/dev/null || : ; + printf "\n::endgroup::\n" ; else - FIX_COPY_OUTCOME="skipped" - RAW_COPY_OUTCOME="compatable" - fi ; - printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; - wait ; # used to force boundry for std out read/write race in UI - printf "FIX_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; - printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; - # should dump a diff or something here - printf "\n\n" ; - ) ; - wait ; - # cleanup temp env - unset FIX_COPY_OUTCOME 2>/dev/null || : ; - unset RAW_COPY_OUTCOME 2>/dev/null || : ; - unset REF_FILE_NAME 2>/dev/null || : ; - printf "\n::endgroup::\n" ; + # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. + printf "\nNow Skipping '%s'\n\n" "${referance_file}" ; + fi ; # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. + fi ; done cd .. ; - name: Post-Clean From f1e1e1b1e5e4b66f5928d0c8967c12f878720ab0 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Mon, 21 Jul 2025 17:19:04 -0700 Subject: [PATCH 21/62] regression fix for Check_Tests.yml and re-test * fixes minor regression --- .github/workflows/Check_Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 19c02919fd..e50031908b 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -169,7 +169,7 @@ jobs: if [[ ( -f "${referance_file}" ) ]] ; then # See https://devguide.python.org/testing/run-write-tests # Heuristic: "if some module does not have unittest.main(), then most likely it does not support direct invocation." - if grep -qF "unittest.main()" "${referance_file}" 2>dev/null ; then + if grep -qF "unittest.main()" "${referance_file}" 2>/dev/null ; then # TODO: RustPython workaround Windows timeout for hangs printf "Now Testing '%s'\n" "${referance_file}" # vars for subshell but not for workflow From 14b67adf07cf393444d38c28c3596cd179d5767f Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Tue, 22 Jul 2025 16:23:17 -0700 Subject: [PATCH 22/62] WIP - UNSTABLE --- .github/workflows/Check_Tests.yml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index e50031908b..5f9140614c 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -30,6 +30,8 @@ env: PYTHON_EXPERIMENTAL: "${{ vars.PYTHON_EXPERIMENTAL }}" # For future Python versions # Define the referance files to pull as a file glob pattern TEST_MATCH_PATTERN: "Lib/test/*.py" + TEST_IGNORE_LIST: | + Lib/test/test_builtin.py jobs: TEST-5974: @@ -59,7 +61,7 @@ jobs: experimental: false - os: windows-latest python-version: "${{ vars.PYTHON_DEFAULT }}" - experimental: false + experimental: true - os: macos-14 python-version: "${{ vars.PYTHON_DEFAULT }}" experimental: true @@ -104,12 +106,24 @@ jobs: Lib/test sparse-checkout-cone-mode: true ref: '${{ matrix.python-version }}' + - name: Configure Ignored Referance Lib Files + id: refignorefiles + shell: bash + run: | + cd cpython || exit 14 ; + if [[ -w ".git/info/exclude" ]] ; then + printf "%s\n" ${TEST_IGNORE_LIST:-} >>".git/info/exclude" || : ; + else + printf "::debug::%s\n" "Could not find .git/info/exclude" ; + printf "%s\n" ${TEST_IGNORE_LIST:-} >>".gitignore" || : ; + fi ; + cd .. ; + if: ${{ success() }} - name: Enumerate Referance Lib Files id: reftestfiles shell: bash run: | cd cpython || exit 14 ; - ls -lap . ; FILES=$(git ls-files --exclude-standard -- ${{ env.TEST_MATCH_PATTERN }} ) if [ -z "$FILES" ]; then printf "%s\n" "::warning file=.github/workflows/Check_Tests.yml:: No Lib/Test Referance files found." From d638f069f6ddd061181abd70cfa8f46558e3fb73 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Tue, 22 Jul 2025 18:27:55 -0700 Subject: [PATCH 23/62] Update Check_Tests.yml with unittest logic * add logic for running tests by filtering for test-cases --- .github/workflows/Check_Tests.yml | 87 ++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 6 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 5f9140614c..c043dd3274 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -28,6 +28,8 @@ env: PYTHON_OLD_MIN: "${{ vars.PYTHON_OLD_MIN }}" # For Oldest Python versions PYTHON_OLD_EXTRA: "${{ vars.PYTHON_OLD_EXTRA }}" # For Older Python versions (Extra coverage) PYTHON_EXPERIMENTAL: "${{ vars.PYTHON_EXPERIMENTAL }}" # For future Python versions + # define how mush time before assuming the test has hung in seconds (parsed by sleep) + SUBSHELL_TIMEOUT: 180 # Define the referance files to pull as a file glob pattern TEST_MATCH_PATTERN: "Lib/test/*.py" TEST_IGNORE_LIST: | @@ -178,33 +180,56 @@ jobs: OS: ${{ runner.os }} if: ${{ success() }} run: | + # Custom timeout function (GH-5974 - because ulimit is restricted and windows can't ulimit at all) + # TODO: clean this up + run_with_timeout() { + local timeout=$1 + shift + "$@" & + local pid=$! + ( sleep "$timeout" && kill -HUP "$pid" 2>/dev/null ) & # Send HUP signal after timeout + wait "$pid" + local status=$? + if [ $status -eq 0 ]; then + printf "::debug::%s\n" "Command completed successfully." + elif [ $status -eq 143 ]; then + printf "%s\n" "The command was terminated due to timeout." + else + printf "%s\n" "The command failed with status $status." + fi + } + + export -f run_with_timeout ; + # Usage + # run_with_timeout 360 your_command_here cd rustpython || exit 13 ; for referance_file in ${{ steps.reftestfiles.outputs.files }} ; do if [[ ( -f "${referance_file}" ) ]] ; then # See https://devguide.python.org/testing/run-write-tests # Heuristic: "if some module does not have unittest.main(), then most likely it does not support direct invocation." if grep -qF "unittest.main()" "${referance_file}" 2>/dev/null ; then - # TODO: RustPython workaround Windows timeout for hangs printf "Now Testing '%s'\n" "${referance_file}" # vars for subshell but not for workflow export REF_FILE_NAME=$(basename "${referance_file}") ; - printf "\n::group::%s\n" "${REF_FILE_NAME}" ; + printf "::group::%s\n" "${REF_FILE_NAME}" ; # TODO: test with cpython first for baseline # TODO: add to list of files that need additional prep due to hanging or unexpected failures that need to be removed # Execute the testing command in a subshell time ( - RUSTPYTHONPATH=Lib cargo run --release -- Lib/test/"${REF_FILE_NAME}" || RAW_COPY_OUTCOME='failing' + export RUSTPYTHONPATH=Lib ; + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- Lib/test/"${REF_FILE_NAME}" || RAW_COPY_OUTCOME='failing' if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then printf "::warning file='%s',title='test-warning':: Could not copy and pass tests for file.\n" "${referance_file}" ; ( - RUSTPYTHONPATH=Lib cargo run --release -- ./scripts/fix_test.py --path ./Lib/test/"${REF_FILE_NAME}" || FIX_COPY_OUTCOME='unfixed' ; + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- ./scripts/fix_test.py --path ./Lib/test/"${REF_FILE_NAME}" || FIX_COPY_OUTCOME='unfixed' ; ) ; if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${referance_file}" >>2 ; # reset broken integration to last rustpython copy git restore --ignore-unmerged --worktree --staged "${referance_file}" || : ; git checkout -f --ignore-unmerged -- "${referance_file}" || : ; - # TODO: validate and set FIX_COPY_OUTCOME="reverted" + # TODO: validate and conditionally set + FIX_COPY_OUTCOME="reverted" else FIX_COPY_OUTCOME="fixed" RAW_COPY_OUTCOME="incompatable" @@ -219,6 +244,7 @@ jobs: printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; # should dump a diff or something here printf "\n\n" ; + unset RUSTPYTHONPATH 2>/dev/null || : ; ) ; wait ; # cleanup temp env @@ -228,7 +254,56 @@ jobs: printf "\n::endgroup::\n" ; else # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. - printf "\nNow Skipping '%s'\n\n" "${referance_file}" ; + # TODO: cleanup this regular expression for edge-cases + if grep -qE "^[^cC]*([cC]lass)\s*(.+)(Test)" "${referance_file}" 2>/dev/null ; then + printf "Now Testing test-cases in '%s'\n" "${referance_file}" + # vars for subshell but not for workflow + export REF_TEST_NAME=$(basename -s "py" "${referance_file}") ; + printf "%s\n" "Selected testcase test.${REF_TEST_NAME}" + printf "::group::%s\n" "${REF_FILE_NAME}" ; + # TODO: test with cpython first for baseline + # TODO: add to list of files that need additional prep due to hanging or unexpected failures that need to be removed + # Execute the testing command in a subshell + time ( + export RUSTPYTHONPATH=Lib ; + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- -m unittest -v test.${REF_TEST_NAME} || RAW_COPY_OUTCOME='failing' + if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then + printf "::warning file='%s',title='test-warning':: Could not copy and pass tests for file.\n" "${referance_file}" ; + ( + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- ./scripts/fix_test.py --test test.${REF_TEST_NAME} --path ./Lib/test/"${REF_FILE_NAME}".py || FIX_COPY_OUTCOME='unfixed' ; + ) ; + if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then + printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${referance_file}" >>2 ; + # reset broken integration to last rustpython copy + git restore --ignore-unmerged --worktree --staged "${referance_file}" || : ; + git checkout -f --ignore-unmerged -- "${referance_file}" || : ; + # TODO: validate and conditionally set + FIX_COPY_OUTCOME="reverted" + else + FIX_COPY_OUTCOME="fixed" + RAW_COPY_OUTCOME="incompatable" + fi ; + else + FIX_COPY_OUTCOME="skipped" + RAW_COPY_OUTCOME="compatable" + fi ; + printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Fix:%s\n\n" "${REF_TEST_NAME}" "${RAW_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; + wait ; # used to force boundry for std out read/write race in UI + printf "FIX_COPY_%s.py_OUTCOME=%s\n" "${REF_TEST_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; + printf "RAW_COPY_%s.py_OUTCOME=%s\n" "${REF_TEST_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; + # should dump a diff or something here + printf "\n\n" ; + unset RUSTPYTHONPATH 2>/dev/null || : ; + ) ; + wait ; + # cleanup temp env + unset FIX_COPY_OUTCOME 2>/dev/null || : ; + unset RAW_COPY_OUTCOME 2>/dev/null || : ; + unset REF_TEST_NAME 2>/dev/null || : ; + printf "\n::endgroup::\n" ; + else + printf "\nNow Skipping '%s'\n\n" "${referance_file}" ; + fi ; fi ; # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. fi ; done From 5706652b2f86ff91b208ef5bb8431337a50c573f Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Tue, 22 Jul 2025 18:41:09 -0700 Subject: [PATCH 24/62] Update Check_Tests.yml with shorter timeout limit * let's go from small to large --- .github/workflows/Check_Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index c043dd3274..0c60ed7f21 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -29,7 +29,7 @@ env: PYTHON_OLD_EXTRA: "${{ vars.PYTHON_OLD_EXTRA }}" # For Older Python versions (Extra coverage) PYTHON_EXPERIMENTAL: "${{ vars.PYTHON_EXPERIMENTAL }}" # For future Python versions # define how mush time before assuming the test has hung in seconds (parsed by sleep) - SUBSHELL_TIMEOUT: 180 + SUBSHELL_TIMEOUT: 30 # Define the referance files to pull as a file glob pattern TEST_MATCH_PATTERN: "Lib/test/*.py" TEST_IGNORE_LIST: | From ab1ab435d122968bc8413ed2e3d0415a17cddbc4 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Tue, 22 Jul 2025 19:02:35 -0700 Subject: [PATCH 25/62] DEBUG Check_Tests.yml * more churn --- .github/workflows/Check_Tests.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 0c60ed7f21..b6983ee480 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -49,6 +49,7 @@ jobs: timeout-minutes: 30 continue-on-error: ${{ matrix.experimental }} strategy: + max-parallel: 3 fail-fast: false matrix: os: [ubuntu-latest, macos-14, macos-15, windows-latest] @@ -81,6 +82,7 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false + # repository: "RustPython/RustPython" path: rustpython # ref: sparse-checkout-cone-mode: false @@ -187,15 +189,19 @@ jobs: shift "$@" & local pid=$! - ( sleep "$timeout" && kill -HUP "$pid" 2>/dev/null ) & # Send HUP signal after timeout + ( sleep "$timeout" && kill -HUP "$pid" 2>/dev/null ) & disown + # Send HUP signal after timeout wait "$pid" local status=$? if [ $status -eq 0 ]; then printf "::debug::%s\n" "Command completed successfully." + true ; # force success result elif [ $status -eq 143 ]; then printf "%s\n" "The command was terminated due to timeout." + false ; else printf "%s\n" "The command failed with status $status." + false ; fi } @@ -239,19 +245,18 @@ jobs: RAW_COPY_OUTCOME="compatable" fi ; printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; - wait ; # used to force boundry for std out read/write race in UI printf "FIX_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; # should dump a diff or something here printf "\n\n" ; unset RUSTPYTHONPATH 2>/dev/null || : ; ) ; - wait ; # cleanup temp env unset FIX_COPY_OUTCOME 2>/dev/null || : ; unset RAW_COPY_OUTCOME 2>/dev/null || : ; unset REF_FILE_NAME 2>/dev/null || : ; printf "\n::endgroup::\n" ; + wait ; else # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. # TODO: cleanup this regular expression for edge-cases @@ -295,12 +300,12 @@ jobs: printf "\n\n" ; unset RUSTPYTHONPATH 2>/dev/null || : ; ) ; - wait ; # cleanup temp env unset FIX_COPY_OUTCOME 2>/dev/null || : ; unset RAW_COPY_OUTCOME 2>/dev/null || : ; unset REF_TEST_NAME 2>/dev/null || : ; printf "\n::endgroup::\n" ; + wait ; else printf "\nNow Skipping '%s'\n\n" "${referance_file}" ; fi ; From 5e121495907715e310195314a6fcc852f6f8e2f5 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Tue, 22 Jul 2025 21:30:01 -0700 Subject: [PATCH 26/62] WIP DEBUG STEP --- .github/workflows/Check_Tests.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index b6983ee480..ede754f934 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -35,6 +35,8 @@ env: TEST_IGNORE_LIST: | Lib/test/test_builtin.py +# TODO: cordnate with @arihant2math - to really build out the migration logic + jobs: TEST-5974: permissions: @@ -89,17 +91,19 @@ jobs: - name: Pre-Test Build check id: build_testing shell: bash + env: + OS: ${{ runner.os }} if: ${{ !cancelled() }} run: | cd rustpython || exit 13 ; printf "Now Building '%s'\n" "" # Execute the testing command in a subshell ( - RUSTPYTHONPATH=Lib cargo run --release -- --version || printf "::error title='build failure':: Could not pass build step for version check.\n" ; + RUSTPYTHONPATH=Lib cargo run --release -- --version || printf "::error title='build failure':: Could not pass build step for version check on ${OS}.\n" ; ) ; cd .. ; - id: cpython - name: Fetch Cpython + name: Fetch Referance Cpython ${{ matrix.python-version }} on ${{ matrix.os }} uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false @@ -114,6 +118,7 @@ jobs: id: refignorefiles shell: bash run: | + # TODO: include work from RustPython/scripts/notes.txt cd cpython || exit 14 ; if [[ -w ".git/info/exclude" ]] ; then printf "%s\n" ${TEST_IGNORE_LIST:-} >>".git/info/exclude" || : ; From c1f6dfd3c9dadd343f63faed1ba576be1d9e726f Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 23 Jul 2025 12:07:20 -0700 Subject: [PATCH 27/62] Expand to recurse Lib/test (WIP) * expand to use pattern "Lib/test/*.py Lib/test/**/*.py" * see RustPython/RustPython#5974 for context --- .github/workflows/Check_Tests.yml | 43 +++++++++++++++++-------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index ede754f934..4c9972d1a0 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -31,9 +31,9 @@ env: # define how mush time before assuming the test has hung in seconds (parsed by sleep) SUBSHELL_TIMEOUT: 30 # Define the referance files to pull as a file glob pattern - TEST_MATCH_PATTERN: "Lib/test/*.py" + TEST_MATCH_PATTERN: "Lib/test/*.py Lib/test/**/*.py" TEST_IGNORE_LIST: | - Lib/test/test_builtin.py + Lib/test/*.pyc # TODO: cordnate with @arihant2math - to really build out the migration logic @@ -79,14 +79,14 @@ jobs: PYTHON_VERSION: ${{ matrix.python-version }} # TODO: move to seperate action steps: - - name: Checkout RustPython repository + - name: Checkout RustPython repository on ${{ matrix.os }} id: rpython uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false # repository: "RustPython/RustPython" path: rustpython - # ref: + # ref: main sparse-checkout-cone-mode: false - name: Pre-Test Build check id: build_testing @@ -135,7 +135,7 @@ jobs: cd cpython || exit 14 ; FILES=$(git ls-files --exclude-standard -- ${{ env.TEST_MATCH_PATTERN }} ) if [ -z "$FILES" ]; then - printf "%s\n" "::warning file=.github/workflows/Check_Tests.yml:: No Lib/Test Referance files found." + printf "%s\n" "::warning file=.github/workflows/Check_Tests.yml:: No Lib/Test Referance files found for Cpython ${{ matrix.python-version }} on ${{ matrix.os }}." ; printf "%s\n" "files=" >> "$GITHUB_OUTPUT" else printf "%s\n" "Lib/Test Referance files found:" @@ -157,7 +157,7 @@ jobs: cat > "$GITHUB_OUTPUT" + printf "Configured Cpython %s on %s.\n" '${{ matrix.python-version }}' '${{ matrix.os }}' ; printf "PYTHON_VERSION=%s\n" "${{ matrix.python-version }}" >> "$GITHUB_ENV" printf "%s\n" "::endgroup::" - name: Try Smoke Testing @@ -185,6 +186,7 @@ jobs: shell: bash env: OS: ${{ runner.os }} + CONTEXT_PHRASE: 'for Cpython ${{ matrix.python-version }} on ${{ matrix.os }}' if: ${{ success() }} run: | # Custom timeout function (GH-5974 - because ulimit is restricted and windows can't ulimit at all) @@ -202,12 +204,12 @@ jobs: printf "::debug::%s\n" "Command completed successfully." true ; # force success result elif [ $status -eq 143 ]; then - printf "%s\n" "The command was terminated due to timeout." + printf "::warning title='Timeout'::%s\n" "The command \`$@\` ${CONTEXT_PHRASE} was terminated due to timeout." false ; else - printf "%s\n" "The command failed with status $status." + printf "%s\n" "The command failed with status $status ${CONTEXT_PHRASE}." false ; - fi + fi ; } export -f run_with_timeout ; @@ -230,12 +232,12 @@ jobs: export RUSTPYTHONPATH=Lib ; run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- Lib/test/"${REF_FILE_NAME}" || RAW_COPY_OUTCOME='failing' if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then - printf "::warning file='%s',title='test-warning':: Could not copy and pass tests for file.\n" "${referance_file}" ; + printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${referance_file}" "${referance_file}" "${CONTEXT_PHRASE}" ; ( run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- ./scripts/fix_test.py --path ./Lib/test/"${REF_FILE_NAME}" || FIX_COPY_OUTCOME='unfixed' ; ) ; if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then - printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${referance_file}" >>2 ; + printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests %s.\n" "${referance_file}" "${CONTEXT_PHRASE}" >&2 ; # reset broken integration to last rustpython copy git restore --ignore-unmerged --worktree --staged "${referance_file}" || : ; git checkout -f --ignore-unmerged -- "${referance_file}" || : ; @@ -268,7 +270,7 @@ jobs: if grep -qE "^[^cC]*([cC]lass)\s*(.+)(Test)" "${referance_file}" 2>/dev/null ; then printf "Now Testing test-cases in '%s'\n" "${referance_file}" # vars for subshell but not for workflow - export REF_TEST_NAME=$(basename -s "py" "${referance_file}") ; + export REF_TEST_NAME=$(basename -s ".py" "${referance_file}") ; printf "%s\n" "Selected testcase test.${REF_TEST_NAME}" printf "::group::%s\n" "${REF_FILE_NAME}" ; # TODO: test with cpython first for baseline @@ -278,12 +280,12 @@ jobs: export RUSTPYTHONPATH=Lib ; run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- -m unittest -v test.${REF_TEST_NAME} || RAW_COPY_OUTCOME='failing' if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then - printf "::warning file='%s',title='test-warning':: Could not copy and pass tests for file.\n" "${referance_file}" ; + printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${referance_file}" "${referance_file}" "${CONTEXT_PHRASE}" ; ( - run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- ./scripts/fix_test.py --test test.${REF_TEST_NAME} --path ./Lib/test/"${REF_FILE_NAME}".py || FIX_COPY_OUTCOME='unfixed' ; + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- ./scripts/fix_test.py --path ./Lib/test/"${REF_FILE_NAME}".py || FIX_COPY_OUTCOME='unfixed' ; ) ; if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then - printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${referance_file}" >>2 ; + printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${referance_file}" >&2 ; # reset broken integration to last rustpython copy git restore --ignore-unmerged --worktree --staged "${referance_file}" || : ; git checkout -f --ignore-unmerged -- "${referance_file}" || : ; @@ -298,7 +300,7 @@ jobs: RAW_COPY_OUTCOME="compatable" fi ; printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Fix:%s\n\n" "${REF_TEST_NAME}" "${RAW_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; - wait ; # used to force boundry for std out read/write race in UI + wait ; # used to force boundry for std out read/write race in UI printf "FIX_COPY_%s.py_OUTCOME=%s\n" "${REF_TEST_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; printf "RAW_COPY_%s.py_OUTCOME=%s\n" "${REF_TEST_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; # should dump a diff or something here @@ -313,6 +315,7 @@ jobs: wait ; else printf "\nNow Skipping '%s'\n\n" "${referance_file}" ; + # TODO: record this skip status too fi ; fi ; # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. fi ; @@ -321,6 +324,6 @@ jobs: - name: Post-Clean id: post-bootstrap run: | - exit 0 ; # don't break on regression + exit 0 ; # don't break CI on regression if: ${{ always() }} shell: bash From 3e65b5347fe3f55cfc5df89ebc844bab4d92cb88 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 23 Jul 2025 18:58:13 -0700 Subject: [PATCH 28/62] Initial Refactor for CI-5974 * see RustPython/RustPython#5974 for more * Cleaned up the bootstrapping of the RustPython and CPython Libs by refactoring into re-useable actions. * Work still in progress --- .../actions/CI-5974-Fetch-CPython/action.yaml | 160 ++++++++++++++++++ .../CI-5974-Fetch-RustPython/action.yaml | 112 ++++++++++++ .../CI-5974-Integrate-CPython/action.yaml | 53 ++++++ .github/workflows/Check_Tests.yml | 115 ++++--------- 4 files changed, 354 insertions(+), 86 deletions(-) create mode 100644 .github/actions/CI-5974-Fetch-CPython/action.yaml create mode 100644 .github/actions/CI-5974-Fetch-RustPython/action.yaml create mode 100644 .github/actions/CI-5974-Integrate-CPython/action.yaml diff --git a/.github/actions/CI-5974-Fetch-CPython/action.yaml b/.github/actions/CI-5974-Fetch-CPython/action.yaml new file mode 100644 index 0000000000..9fe5dcbee7 --- /dev/null +++ b/.github/actions/CI-5974-Fetch-CPython/action.yaml @@ -0,0 +1,160 @@ +--- +name: 'Checkout CPython' +description: 'checks-out the given CPython version' +author: 'Mr. Walls' +branding: + icon: 'download-cloud' + color: 'blue' +inputs: + override-repository: + description: | + The GitHub repository to clone CPython from. When running this action on github.com, + the default value is sufficient. Useful for Forks. + required: true + default: ${{ github.server_url == 'https://github.com' && github.repository || 'python/cpython' }} + override-rustpython-path: + description: | + override value for path to the Python Lib. The default is to use the value of the environment + variable 'RUSTPYTHONPATH'. Most users will find the default 'Lib' sufficient. + required: true + default: ${{ github.server_url == 'https://github.com' && github.repository || 'Lib' }} + override-path: + description: | + Path to setup. When running this action on github.com, the default value + is sufficient. MUST be a path to a directory named 'cpython'. + required: true + default: ${{ github.server_url == 'https://github.com' && github.workspace || 'cpython' }} + override-cpython-lib-path: + description: | + override value for path to the CPython Reference Lib. The default is to use the value of the + environment variable 'PYTHONPLATLIBDIR'. Most users will find the default 'Lib' sufficient. + See https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPLATLIBDIR for more. + required: true + default: ${{ github.server_url == 'https://github.com' && github.repository || 'Lib' }} + match: + description: | + Glob-style pattern of files or directories to match and integrate. + Only works with git tracked files. + required: true + type: string + default: 'Lib/test/*.py Lib/test/**/*.py' + ignore: + description: | + List of Glob-style patterns of files or directories to ignore. + Only works with git tracked files. + required: false + type: string + github-token: + description: | + The token used to authenticate when fetching RustPython commits from + https://github.com/RustPython/RustPython.git. When running this action on github.com, + the default value is sufficient. When running on GHES, you can pass a personal access + token for github.com if you are experiencing rate limiting. + default: ${{ github.server_url == 'https://github.com' && github.token || '' }} + required: true + python-version: + description: | + The Cpython version (e.g., any valid release or tag, 3.11, 3.12, 3.13) to override setup. + The default is to use the value of the environment variable 'PYTHON_VERSION'. + default: '3.13' + required: true +outputs: + branch-name: + description: "The name of the branch that was checked-out." + value: ${{ steps.output_branch_name.outputs.branch-name || '' }} + sha: + description: "The SHA of the commit checked-out." + value: ${{ steps.output_sha.outputs.sha || 'HEAD' }} + files: + description: "The downloaded artifact-files." + value: ${{ steps.output_cpython_files.outputs.files }} + +runs: + using: composite + steps: + - name: Fetch Reference Cpython ${{ matrix.python-version }} on ${{ matrix.os }} + id: cpython + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + path: ${{ inputs.override-path }} + fetch-tags: true + sparse-checkout: | + ${{ inputs.override-cpython-lib-path }} + ref: ${{ inputs.python-version }} + repository: ${{ inputs.override-repository }} + # fixed settings + fetch-depth: 0 + sparse-checkout-cone-mode: false + submodules: true + token: ${{ inputs.github-token }} + - id: store_old_path + if: ${{ !cancelled() }} + shell: bash + run: | + cd ${PWD:-.} ; + export OLD_PWD=$(pwd) ; # only local use for bootstrap + printf "initial-path=%s\n" "${OLD_PWD}" >> "$GITHUB_OUTPUT" + - id: output_branch_name + if: ${{ !cancelled() }} + shell: bash + run: | + cd ${{ inputs.override-path }} || exit 14 ; + printf "branch-name=%s\n" $(git name-rev --name-only HEAD | cut -d~ -f1-1) >> "$GITHUB_OUTPUT" + cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; + - id: output_sha + shell: bash + run: | + cd ${{ inputs.override-path }} || exit 14 ; + printf "sha=%s\n" $(git log -1 --format=%H) >> "$GITHUB_OUTPUT" + cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; + - name: Configure Ignored Reference Lib Files + id: refignorefiles + shell: bash + env: + GIT_IGNORE_PATTERN: ${{ inputs.ignore || '' }} + run: | + # TODO: include work from RustPython/scripts/notes.txt + cd ${{ inputs.override-path }} || exit 14 ; + if [[ -w ".git/info/exclude" ]] ; then + printf "%s\n" ${GIT_IGNORE_PATTERN:-} >>".git/info/exclude" || : ; + else + printf "::debug::%s\n" "Could not find .git/info/exclude" ; + printf "%s\n" ${GIT_IGNORE_PATTERN:-} >>".gitignore" || : ; + fi ; + cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; + if: ${{ success() }} + - name: Enumerate Reference Lib Files + id: output_cpython_files + shell: bash + env: + TEST_MATCH_PATTERN: ${{ inputs.match || '' }} + run: | + cd ${{ inputs.override-path }} || exit 14 ; + FILES=$(git ls-files --exclude-standard -- ${{ env.TEST_MATCH_PATTERN }} ) + if [ -z "$FILES" ]; then + printf "%s\n" "::warning file=.github/actions/:: No ${{ inputs.override-cpython-lib-path }} Reference files found for Cpython ${{ inputs.python-version }} on ${{ runner.os }}." ; + printf "%s\n" "files=" >> "$GITHUB_OUTPUT" + else + printf "%s\n" "Reference files found:" + printf "%s\n" "$FILES" + # Replace line breaks with commas for GitHub Action Output + FILES="${FILES//$'\n'/ }" + printf "%s\n" "files=$FILES" >> "$GITHUB_OUTPUT" + fi + cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; + if: ${{ success() }} + - name: "License" + id: show_cpython_license + shell: bash + if: ${{ !cancelled() }} + run: | + cd ${{ inputs.override-path }} || exit 14 ; + if [[ -r LICENSE ]] ; then + printf "\n\n" + cat > "$GITHUB_OUTPUT" + - id: output_branch_name + if: ${{ !cancelled() }} + shell: bash + run: | + cd ${{ inputs.override-path }} || exit 13 ; + printf "branch-name=%s\n" $(git name-rev --name-only HEAD | cut -d~ -f1-1) >> "$GITHUB_OUTPUT" + cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; + - id: output_sha + shell: bash + run: | + cd ${{ inputs.override-path }} || exit 13 ; + printf "sha=%s\n" $(git log -1 --format=%H) >> "$GITHUB_OUTPUT" + cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; + - name: Pre-Test Build check + id: build_rpython + shell: bash + env: + OS: ${{ runner.os }} + if: ${{ !cancelled() }} + run: | + cd ${{ inputs.override-path }} || exit 13 ; + printf "::debug::Now Building '%s'\n" "RustPython" + # Execute the testing command in a subshell + ( + RUSTPYTHONPATH=${{ inputs.override-rustpython-path }} cargo run --release -- --version || printf "::error title='build failure':: Could not pass build step for version check on ${OS}.\n" ; + ) ; + cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; + - id: output_rpython_path + shell: bash + run: | + cd ${{ inputs.override-path }} || exit 13 ; # in case it is relative + cd ${{ inputs.override-rustpython-path }} || exit 13 ; + printf "RUSTPYTHONPATH=%s\n" $(pwd) >> "$GITHUB_ENV" ; + printf "rustpython-lib-path=%s\n" $(pwd) >> "$GITHUB_OUTPUT" ; + cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; diff --git a/.github/actions/CI-5974-Integrate-CPython/action.yaml b/.github/actions/CI-5974-Integrate-CPython/action.yaml new file mode 100644 index 0000000000..02242fd779 --- /dev/null +++ b/.github/actions/CI-5974-Integrate-CPython/action.yaml @@ -0,0 +1,53 @@ +--- +name: 'Integrate Reference Implementation' +description: 'Copy Reference Implementation' +author: 'Mr. Walls' +branding: + icon: 'bar-chart-2' + color: 'purple' +inputs: + into-path: + description: | + Path to Destination. Default is 'rustpython' + required: true + default: ${{ github.server_url == 'https://github.com' && github.workspace || 'rustpython' }} + from-path: + description: | + Path to source. Default is 'cpython' + required: true + default: ${{ github.server_url == 'https://github.com' && github.workspace || 'cpython' }} + files: + description: | + List of paths to copy from source to destination. Default is 'Lib/**/*.py' + required: true + default: ${{ github.server_url == 'https://github.com' && 'Lib/**/*.py' || '' }} + python-version: + description: | + The Cpython version (e.g., any valid release or tag, 3.11, 3.12, 3.13) to override setup. + The default is to use the value of the environment variable 'PYTHON_VERSION'. + default: '3.13' + required: true + +# TODO: fix python version detection logic +# TODO: add verification steps + +runs: + using: composite + steps: + - id: store_old_path + if: ${{ !cancelled() }} + shell: bash + run: | + cd ${PWD:-.} ; + export OLD_PWD=$(pwd) ; # only local use for bootstrap + printf "initial-path=%s\n" "${OLD_PWD}" >> "$GITHUB_OUTPUT" + - name: "Integrate Cpython Test files" + id: merge_theirs + shell: bash + if: ${{ !cancelled() }} + run: | + printf "::group::%s\n" "Copy Reference Implementation" ; + for reference_file in ${{ inputs.files }} ; do + cp -vf ${{ inputs.from-path }}/"${reference_file}" ${{ inputs.to-path }}/"${reference_file}" || printf "::warning file='%s',title='integration failure':: Could not integrate file for Cpython %s on %s.\n" "${reference_file}" '${{ inputs.python-version }}' '${{ runner.os }}' ; + done + printf "\n::endgroup::\n\n" ; diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 4c9972d1a0..956653af43 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -30,7 +30,7 @@ env: PYTHON_EXPERIMENTAL: "${{ vars.PYTHON_EXPERIMENTAL }}" # For future Python versions # define how mush time before assuming the test has hung in seconds (parsed by sleep) SUBSHELL_TIMEOUT: 30 - # Define the referance files to pull as a file glob pattern + # Define the reference files to pull as a file glob pattern TEST_MATCH_PATTERN: "Lib/test/*.py Lib/test/**/*.py" TEST_IGNORE_LIST: | Lib/test/*.pyc @@ -79,98 +79,41 @@ jobs: PYTHON_VERSION: ${{ matrix.python-version }} # TODO: move to seperate action steps: - - name: Checkout RustPython repository on ${{ matrix.os }} - id: rpython + - name: pre-checkout repository for actions uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - # repository: "RustPython/RustPython" - path: rustpython - # ref: main - sparse-checkout-cone-mode: false - - name: Pre-Test Build check - id: build_testing - shell: bash - env: - OS: ${{ runner.os }} - if: ${{ !cancelled() }} - run: | - cd rustpython || exit 13 ; - printf "Now Building '%s'\n" "" - # Execute the testing command in a subshell - ( - RUSTPYTHONPATH=Lib cargo run --release -- --version || printf "::error title='build failure':: Could not pass build step for version check on ${OS}.\n" ; - ) ; - cd .. ; - - id: cpython - name: Fetch Referance Cpython ${{ matrix.python-version }} on ${{ matrix.os }} - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + sparse-checkout: '.github/actions/CI-5974-*' + - name: Checkout RustPython repository on ${{ matrix.os }} + id: fetch-rpython + uses: ./.github/actions/CI-5974-Fetch-RustPython with: - persist-credentials: false - fetch-tags: true - repository: "python/cpython" - path: cpython - sparse-checkout: | - Lib/test - sparse-checkout-cone-mode: true - ref: '${{ matrix.python-version }}' - - name: Configure Ignored Referance Lib Files - id: refignorefiles - shell: bash - run: | - # TODO: include work from RustPython/scripts/notes.txt - cd cpython || exit 14 ; - if [[ -w ".git/info/exclude" ]] ; then - printf "%s\n" ${TEST_IGNORE_LIST:-} >>".git/info/exclude" || : ; - else - printf "::debug::%s\n" "Could not find .git/info/exclude" ; - printf "%s\n" ${TEST_IGNORE_LIST:-} >>".gitignore" || : ; - fi ; - cd .. ; - if: ${{ success() }} - - name: Enumerate Referance Lib Files - id: reftestfiles - shell: bash - run: | - cd cpython || exit 14 ; - FILES=$(git ls-files --exclude-standard -- ${{ env.TEST_MATCH_PATTERN }} ) - if [ -z "$FILES" ]; then - printf "%s\n" "::warning file=.github/workflows/Check_Tests.yml:: No Lib/Test Referance files found for Cpython ${{ matrix.python-version }} on ${{ matrix.os }}." ; - printf "%s\n" "files=" >> "$GITHUB_OUTPUT" - else - printf "%s\n" "Lib/Test Referance files found:" - printf "%s\n" "$FILES" - # Replace line breaks with commas for GitHub Action Output - FILES="${FILES//$'\n'/ }" - printf "%s\n" "files=$FILES" >> "$GITHUB_OUTPUT" - fi - cd .. ; - if: ${{ success() }} - - name: "License" - id: show-cpython-license - shell: bash - if: ${{ !cancelled() }} - run: | - cd cpython || exit 14 ; - if [[ -r LICENSE ]] ; then - printf "\n\n" - cat Date: Wed, 23 Jul 2025 19:08:12 -0700 Subject: [PATCH 29/62] Re:re: Fixup for overlooked regression from initial refactor * see RustPython/RustPython#5974 for more --- .github/workflows/Check_Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 956653af43..cb63c191c0 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -106,7 +106,7 @@ jobs: # this next part is WIP and needs to be updated with filtering for more control of what parts of the reference lib is used - name: "Integrate Cpython Test file" id: merge_theirs - shell: bash + uses: ./.github/actions/CI-5974-Integrate-CPython if: ${{ !cancelled() }} with: from-path: cpython From cad55c68c55220938e942517a5aae60ce44a8732 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 23 Jul 2025 19:14:08 -0700 Subject: [PATCH 30/62] :see_no_evil: Oops! No globbing sparse checkouts, must enumerate --- .github/workflows/Check_Tests.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index cb63c191c0..a56039eb37 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -83,7 +83,11 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - sparse-checkout: '.github/actions/CI-5974-*' + sparse-checkout: | + '.github/actions/CI-5974-Fetch-RustPython' + '.github/actions/CI-5974-Fetch-CPython' + '.github/actions/CI-5974-Integrate-CPython' + # CI-5974-Test-RustPython-Integration WIP - name: Checkout RustPython repository on ${{ matrix.os }} id: fetch-rpython uses: ./.github/actions/CI-5974-Fetch-RustPython From c5b556ebe698f48a34077066949ed4a3518c24f5 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 23 Jul 2025 19:36:51 -0700 Subject: [PATCH 31/62] DEBUG sparse checkout for actions * see RustPython/RustPython#5974 --- .github/workflows/Check_Tests.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index a56039eb37..3f946408bd 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -77,16 +77,18 @@ jobs: bootstrap_status: ${{ steps.smoke_testing.outcome }} env: PYTHON_VERSION: ${{ matrix.python-version }} - # TODO: move to seperate action + # TODO: move to separate action steps: - name: pre-checkout repository for actions uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false + ref: ${{ github.ref || 'HEAD' }} sparse-checkout: | - '.github/actions/CI-5974-Fetch-RustPython' - '.github/actions/CI-5974-Fetch-CPython' - '.github/actions/CI-5974-Integrate-CPython' + .github/actions + .github/actions/CI-5974-Fetch-RustPython + .github/actions/CI-5974-Fetch-CPython + .github/actions/CI-5974-Integrate-CPython # CI-5974-Test-RustPython-Integration WIP - name: Checkout RustPython repository on ${{ matrix.os }} id: fetch-rpython From 464eedb017647910d85c50b484a630173dc41606 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 23 Jul 2025 19:42:47 -0700 Subject: [PATCH 32/62] Minor Regression fix for CI inputs --- .github/actions/CI-5974-Integrate-CPython/action.yaml | 2 +- .github/workflows/Check_Tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/CI-5974-Integrate-CPython/action.yaml b/.github/actions/CI-5974-Integrate-CPython/action.yaml index 02242fd779..3bb6bfe46d 100644 --- a/.github/actions/CI-5974-Integrate-CPython/action.yaml +++ b/.github/actions/CI-5974-Integrate-CPython/action.yaml @@ -48,6 +48,6 @@ runs: run: | printf "::group::%s\n" "Copy Reference Implementation" ; for reference_file in ${{ inputs.files }} ; do - cp -vf ${{ inputs.from-path }}/"${reference_file}" ${{ inputs.to-path }}/"${reference_file}" || printf "::warning file='%s',title='integration failure':: Could not integrate file for Cpython %s on %s.\n" "${reference_file}" '${{ inputs.python-version }}' '${{ runner.os }}' ; + cp -vf ${{ inputs.from-path }}/"${reference_file}" ${{ inputs.into-path }}/"${reference_file}" || printf "::warning file='%s',title='integration failure':: Could not integrate file for Cpython %s on %s.\n" "${reference_file}" '${{ inputs.python-version }}' '${{ runner.os }}' ; done printf "\n::endgroup::\n\n" ; diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 3f946408bd..46556044ea 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -116,7 +116,7 @@ jobs: if: ${{ !cancelled() }} with: from-path: cpython - to-path: rustpython + into-path: rustpython files: | ${{ steps.fetch-cpython.outputs.files }} python-version: ${{ env.PYTHON_VERSION }} From d0469bd72764aa408d410841c49df3b5817de2d7 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 23 Jul 2025 20:57:34 -0700 Subject: [PATCH 33/62] DEBUG Refactor a bit * more churn --- .../actions/CI-5974-Fetch-CPython/action.yaml | 16 +++++++++++++++- .github/workflows/Check_Tests.yml | 10 +++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/.github/actions/CI-5974-Fetch-CPython/action.yaml b/.github/actions/CI-5974-Fetch-CPython/action.yaml index 9fe5dcbee7..ae7638aa0f 100644 --- a/.github/actions/CI-5974-Fetch-CPython/action.yaml +++ b/.github/actions/CI-5974-Fetch-CPython/action.yaml @@ -72,15 +72,29 @@ outputs: runs: using: composite steps: + - name: "Setup Python" + id: output_python + env: + PYTHON_VERSION_INPUT: ${{ inputs.python-version }} + shell: bash + run: | + if [[ -n $PYTHON_VERSION_INPUT ]]; then + printf "python-version=%s\n" "${PYTHON_VERSION_INPUT}" >> "$GITHUB_OUTPUT" + PYTHON_VERSION=${PYTHON_VERSION_INPUT} + else + printf "python-version=%s\n" "${PYTHON_VERSION}" >> "$GITHUB_OUTPUT" + fi + printf "%s\n" "PYTHON_VERSION=${PYTHON_VERSION}" >> "$GITHUB_ENV" - name: Fetch Reference Cpython ${{ matrix.python-version }} on ${{ matrix.os }} id: cpython uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: + persist-credentials: false path: ${{ inputs.override-path }} fetch-tags: true sparse-checkout: | ${{ inputs.override-cpython-lib-path }} - ref: ${{ inputs.python-version }} + ref: ${{ steps.output_python.outputs.python-version }} repository: ${{ inputs.override-repository }} # fixed settings fetch-depth: 0 diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 46556044ea..6693b4ccb6 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -96,19 +96,19 @@ jobs: with: override-path: rustpython override-rustpython-path: Lib - # override-repository: "RustPython/RustPython" - # override-ref: main + override-repository: 'RustPython/RustPython' + override-ref: main - name: Fetch Referance Cpython ${{ matrix.python-version }} on ${{ matrix.os }} id: fetch-cpython uses: ./.github/actions/CI-5974-Fetch-CPython with: # Define the reference files to pull as a file glob pattern match: "Lib/test/*.py Lib/test/**/*.py" - python-version: ${{ env.PYTHON_VERSION }} - # override-path: cpython + python-version: ${{ matrix.python-version }} + override-path: cpython override-cpython-lib-path: 'Lib/test' # override-rustpython-path: ${{ steps.fetch-rpython.outputs.rustpython-lib-path }} - # override-repository: "python/cpython" + override-repository: 'python/cpython' # this next part is WIP and needs to be updated with filtering for more control of what parts of the reference lib is used - name: "Integrate Cpython Test file" id: merge_theirs From 18ec6ed614294dfe63aa7654af0cffc8dfa9ab14 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 23 Jul 2025 21:11:32 -0700 Subject: [PATCH 34/62] DEBUG integration action a bit more * even more churn --- .../actions/CI-5974-Integrate-CPython/action.yaml | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/.github/actions/CI-5974-Integrate-CPython/action.yaml b/.github/actions/CI-5974-Integrate-CPython/action.yaml index 3bb6bfe46d..b08463eb52 100644 --- a/.github/actions/CI-5974-Integrate-CPython/action.yaml +++ b/.github/actions/CI-5974-Integrate-CPython/action.yaml @@ -34,20 +34,15 @@ inputs: runs: using: composite steps: - - id: store_old_path - if: ${{ !cancelled() }} - shell: bash - run: | - cd ${PWD:-.} ; - export OLD_PWD=$(pwd) ; # only local use for bootstrap - printf "initial-path=%s\n" "${OLD_PWD}" >> "$GITHUB_OUTPUT" - name: "Integrate Cpython Test files" id: merge_theirs shell: bash - if: ${{ !cancelled() }} + if: ${{ !cancelled() && inputs.files != '' }} + env: + INPUT_FILES: ${{ inputs.files }} run: | printf "::group::%s\n" "Copy Reference Implementation" ; - for reference_file in ${{ inputs.files }} ; do + for reference_file in ${INPUT_FILES}; do cp -vf ${{ inputs.from-path }}/"${reference_file}" ${{ inputs.into-path }}/"${reference_file}" || printf "::warning file='%s',title='integration failure':: Could not integrate file for Cpython %s on %s.\n" "${reference_file}" '${{ inputs.python-version }}' '${{ runner.os }}' ; - done + done ; printf "\n::endgroup::\n\n" ; From c3f565110e24769f646dd0feda5e87815fc28383 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 24 Jul 2025 14:24:21 -0700 Subject: [PATCH 35/62] Refactored Smoke-testing experiment into re-useable action --- .../action.yaml | 220 ++++++++++++++++++ .github/workflows/Check_Tests.yml | 196 +++------------- 2 files changed, 256 insertions(+), 160 deletions(-) create mode 100644 .github/actions/CI-5974-Test-RustPython-Integration/action.yaml diff --git a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml new file mode 100644 index 0000000000..a24c10e47e --- /dev/null +++ b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml @@ -0,0 +1,220 @@ +--- +name: 'RustPython Smoke-Testing' +description: 'Smoke-Test Integrated Reference Implementation tests' +author: 'Mr. Walls' +inputs: + override-working-dir: + description: | + Path to integrated RustPython clone to smoke test. Default is 'rustpython' + required: true + default: ${{ github.server_url == 'https://github.com' && 'rustpython' || '' }} + override-rustpython-path: + description: | + override value for path to the Python Lib. The default is to use the value of the environment + variable 'RUSTPYTHONPATH'. Most users will find the default 'Lib' sufficient. + required: true + test-files: + description: | + List of paths to CPython Test files from source to destination. Default is 'Lib/test/*.py' + required: true + default: 'Lib/test/*.py' + python-version: + description: | + The Cpython version (e.g., any valid release or tag, 3.11, 3.12, 3.13) to override. + The default is to use the value of the environment variable 'PYTHON_VERSION'. + default: '3.13' + required: true + max-test-time: + description: | + The max time in seconds per test module file run before aborting a test attempt. The default + is deliberately short at a value of 30 seconds to keep total run-time down. + default: '30' + required: true + +# TODO: fix python version detection logic +# TODO: add verification steps + +runs: + using: composite + steps: + - id: output_python + env: + PYTHON_VERSION_INPUT: ${{ inputs.python-version }} + OVERRIDE_RUSTPYTHONPATH_INPUT: ${{ inputs.override-rustpython-path }} + name: "Detect Python" + if: ${{ !cancelled() && inputs.test-files != '' }} + shell: bash + run: | + printf "%s\n" "::group::detect-python-env" + if [[ -n $PYTHON_VERSION_INPUT ]]; then + printf "python-version=%s\n" "${PYTHON_VERSION_INPUT}" >> "$GITHUB_OUTPUT" + PYTHON_VERSION=${PYTHON_VERSION_INPUT} + else + printf "python-version=%s\n" "${PYTHON_VERSION}" >> "$GITHUB_OUTPUT" + fi + if [[ -n $OVERRIDE_RUSTPYTHONPATH_INPUT ]]; then + printf "override-rustpython-path=%s\n" "${OVERRIDE_RUSTPYTHONPATH_INPUT}" >> "$GITHUB_OUTPUT" + OVERRIDE_RUSTPYTHONPATH=${RUSTPYTHONPATH} + else + printf "override-rustpython-path=%s\n" "${RUSTPYTHONPATH:-Lib}" >> "$GITHUB_OUTPUT" + OVERRIDE_RUSTPYTHONPATH="${RUSTPYTHONPATH:-Lib}" + fi + printf "%s\n" "PYTHON_VERSION=${PYTHON_VERSION}" >> "$GITHUB_ENV" + printf "%s\n" "OVERRIDE_RUSTPYTHONPATH=${OVERRIDE_RUSTPYTHONPATH}" >> "$GITHUB_ENV" + printf "Targeting Cpython %s on %s.\n" '${PYTHON_VERSION}' '${{ runner.os }}' ; + printf "%s\n" "::endgroup::" + - id: store_old_path + if: ${{ !cancelled() }} + shell: bash + run: | + cd ${PWD:-.} ; + export OLD_PWD=$(pwd) ; # only local use for bootstrap + printf "initial-path=%s\n" "${OLD_PWD}" >> "$GITHUB_OUTPUT" + - name: "Try Smoke Testing" + id: smoke_test + shell: bash + if: ${{ !cancelled() && inputs.test-files != '' }} + env: + INPUT_FILES: ${{ inputs.files }} + OS: ${{ runner.os }} + CONTEXT_PHRASE: 'for Cpython ${{ steps.output_python.output.python-version }} on ${{ runner.os }}' + SUBSHELL_TIMEOUT: ${{ inputs.max-test-time }} + run: | + # Custom timeout function (GH-5974 - because ulimit is restricted and windows can't ulimit at all) + # TODO: clean this up + run_with_timeout() { + local timeout=$1 + shift + "$@" & + local pid=$! + ( sleep "$timeout" && kill -HUP "$pid" 2>/dev/null ) & disown + # Send HUP signal after timeout + wait "$pid" + local status=$? + if [ $status -eq 0 ]; then + printf "::debug::%s\n" "Command completed successfully." + true ; # force success result + elif [ $status -eq 143 ]; then + printf "::warning title='Timeout'::%s\n" "The command \`$@\` ${CONTEXT_PHRASE} was terminated due to timeout." + false ; + else + printf "%s\n" "The command failed with status $status ${CONTEXT_PHRASE}." + false ; + fi ; + } + + export -f run_with_timeout ; + # Usage + # run_with_timeout 360 your_command_here + cd ${{ inputs.override-working-dir }} || exit 13 ; + for reference_file in ${INPUT_FILES}; do + if [[ ( -f "${reference_file}" ) ]] ; then + # See https://devguide.python.org/testing/run-write-tests + # Heuristic: "if some module does not have unittest.main(), then most likely it does not support direct invocation." + if grep -qF "unittest.main()" "${reference_file}" 2>/dev/null ; then + printf "Now Testing '%s'\n" "${reference_file}" + # vars for subshell but not for workflow + export REF_FILE_NAME=$(basename "${reference_file}") ; + printf "::group::%s\n" "${REF_FILE_NAME}" ; + # TODO: test with cpython first for baseline + # TODO: add to list of files that need additional prep due to hanging or unexpected failures that need to be removed + # Execute the testing command in a subshell + time ( + export RUSTPYTHONPATH=${OVERRIDE_RUSTPYTHONPATH:-Lib} ; + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" || RAW_COPY_OUTCOME='failing' + if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then + printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${reference_file}" "${reference_file}" "${CONTEXT_PHRASE}" ; + ( + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- ./scripts/fix_test.py --path ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" || FIX_COPY_OUTCOME='unfixed' ; + ) ; + if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then + printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" >&2 ; + # reset broken integration to last rustpython copy + git restore --ignore-unmerged --worktree --staged "${reference_file}" || : ; + git checkout -f --ignore-unmerged -- "${reference_file}" || : ; + # TODO: validate and conditionally set + FIX_COPY_OUTCOME="reverted" + else + FIX_COPY_OUTCOME="fixed" + RAW_COPY_OUTCOME="incompatible" + fi ; + else + FIX_COPY_OUTCOME="skipped" + RAW_COPY_OUTCOME="compatible" + fi ; + printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; + printf "FIX_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; + printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; + # should dump a diff or something here + printf "\n\n" ; + unset RUSTPYTHONPATH 2>/dev/null || : ; + ) ; + # cleanup temp env + unset FIX_COPY_OUTCOME 2>/dev/null || : ; + unset RAW_COPY_OUTCOME 2>/dev/null || : ; + unset REF_FILE_NAME 2>/dev/null || : ; + printf "\n::endgroup::\n" ; + wait ; + else + # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. + # TODO: cleanup this regular expression for edge-cases + if grep -qE "^[^cC]*([cC]lass)\s*(.+)(Test)" "${reference_file}" 2>/dev/null ; then + printf "Now Testing test-cases in '%s'\n" "${reference_file}" + # vars for subshell but not for workflow + export REF_TEST_NAME=$(basename -s ".py" "${reference_file}") ; + printf "%s\n" "Selected testcase test.${REF_TEST_NAME}" + printf "::group::%s\n" "${REF_FILE_NAME}" ; + # TODO: test with cpython first for baseline + # TODO: add to list of files that need additional prep due to hanging or unexpected failures that need to be removed + # Execute the testing command in a subshell + time ( + export RUSTPYTHONPATH=${OVERRIDE_RUSTPYTHONPATH:-Lib} ; + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- -m unittest -v test.${REF_TEST_NAME} || RAW_COPY_OUTCOME='failing' + if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then + printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${reference_file}" "${reference_file}" "${CONTEXT_PHRASE}" ; + ( + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- ./scripts/fix_test.py --path ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}".py || FIX_COPY_OUTCOME='unfixed' ; + ) ; + if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then + printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${reference_file}" >&2 ; + # reset broken integration to last rustpython copy + git restore --ignore-unmerged --worktree --staged "${reference_file}" || : ; + git checkout -f --ignore-unmerged -- "${reference_file}" || : ; + # TODO: validate and conditionally set + FIX_COPY_OUTCOME="reverted" + else + FIX_COPY_OUTCOME="fixed" + RAW_COPY_OUTCOME="incompatible" + fi ; + else + FIX_COPY_OUTCOME="skipped" + RAW_COPY_OUTCOME="compatible" + fi ; + printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Fix:%s\n\n" "${REF_TEST_NAME}" "${RAW_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; + wait ; # used to force boundry for std out read/write race in UI + printf "FIX_COPY_%s.py_OUTCOME=%s\n" "${REF_TEST_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; + printf "RAW_COPY_%s.py_OUTCOME=%s\n" "${REF_TEST_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; + # should dump a diff or something here + printf "\n\n" ; + unset RUSTPYTHONPATH 2>/dev/null || : ; + ) ; + # cleanup temp env + unset FIX_COPY_OUTCOME 2>/dev/null || : ; + unset RAW_COPY_OUTCOME 2>/dev/null || : ; + unset REF_TEST_NAME 2>/dev/null || : ; + printf "\n::endgroup::\n" ; + wait ; + else + printf "\nNow Skipping '%s'\n\n" "${reference_file}" ; + # TODO: record this skip status too + fi ; + fi ; # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. + fi ; + done + cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; + - name: Post-Clean + id: post-bootstrap + run: | + exit 0 ; # don't break CI on regression + if: ${{ always() }} + shell: bash diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 6693b4ccb6..ab121fa86b 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -4,7 +4,7 @@ description: "Continuous Integration workflow for GHI 5974." run-name: Prototyping integration tests ${{ github.ref_name }} # # Jobs included: -# - TEST-5974: Tests installation across Python versions and locales +# - TEST-5974: Tests Integration with CPython Tests across Python versions and OSes # # Required Secrets: # NONE @@ -22,20 +22,17 @@ on: # yamllint disable-line rule:truthy permissions: {} env: - # ENVIRONMENT: ${{ (startsWith(github.ref, 'refs/heads/CI-CD-Patch-') }} # Define Python versions at the top level -- Expected format: X.Y (e.g., 3.13) - PYTHON_DEFAULT: "${{ vars.PYTHON_DEFAULT }}" - PYTHON_OLD_MIN: "${{ vars.PYTHON_OLD_MIN }}" # For Oldest Python versions - PYTHON_OLD_EXTRA: "${{ vars.PYTHON_OLD_EXTRA }}" # For Older Python versions (Extra coverage) - PYTHON_EXPERIMENTAL: "${{ vars.PYTHON_EXPERIMENTAL }}" # For future Python versions + PYTHON_DEFAULT: "${{ vars.PYTHON_DEFAULT || '3.13' }}" + PYTHON_OLD_MIN: "${{ vars.PYTHON_OLD_MIN || '3.9' }}" # For Oldest Python versions + PYTHON_OLD_EXTRA: "${{ vars.PYTHON_OLD_EXTRA || '3.11' }}" # For Older Python versions (Extra coverage) + PYTHON_EXPERIMENTAL: "${{ vars.PYTHON_EXPERIMENTAL || 'main' }}" # For future Python versions # define how mush time before assuming the test has hung in seconds (parsed by sleep) SUBSHELL_TIMEOUT: 30 - # Define the reference files to pull as a file glob pattern - TEST_MATCH_PATTERN: "Lib/test/*.py Lib/test/**/*.py" - TEST_IGNORE_LIST: | - Lib/test/*.pyc -# TODO: cordnate with @arihant2math - to really build out the migration logic +# TODO: coordinate with @moreal - to support initial use-case See RustPython/RustPython#5974 +# TODO: coordinate with @arihant2math - to really build out the migration/Reporting logic +# TODO: coordinate with @ShaharNaveh - to really build out the test migration logic jobs: TEST-5974: @@ -48,36 +45,35 @@ jobs: security-events: none if: ${{ !cancelled() }} runs-on: ${{ matrix.os }} - timeout-minutes: 30 + timeout-minutes: 45 continue-on-error: ${{ matrix.experimental }} strategy: max-parallel: 3 fail-fast: false matrix: - os: [ubuntu-latest, macos-14, macos-15, windows-latest] + os: [ubuntu-latest, macos-latest, windows-latest] python-version: ["${{ vars.PYTHON_OLD_MIN }}", "${{ vars.PYTHON_OLD_EXTRA }}", "${{ vars.PYTHON_DEFAULT }}", "${{ vars.PYTHON_EXPERIMENTAL }}"] experimental: [true] include: - os: ubuntu-latest python-version: "${{ vars.PYTHON_DEFAULT }}" experimental: false - - os: macos-latest + - os: macos-15 python-version: "${{ vars.PYTHON_EXPERIMENTAL }}" - experimental: false + experimental: true - os: windows-latest python-version: "${{ vars.PYTHON_DEFAULT }}" experimental: true - os: macos-14 python-version: "${{ vars.PYTHON_DEFAULT }}" - experimental: true + experimental: false - os: windows-2025 python-version: "${{ vars.PYTHON_DEFAULT }}" experimental: true outputs: - bootstrap_status: ${{ steps.smoke_testing.outcome }} + smoke_testing_status: ${{ steps.smoke_testing.outcome }} env: PYTHON_VERSION: ${{ matrix.python-version }} - # TODO: move to separate action steps: - name: pre-checkout repository for actions uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -89,7 +85,7 @@ jobs: .github/actions/CI-5974-Fetch-RustPython .github/actions/CI-5974-Fetch-CPython .github/actions/CI-5974-Integrate-CPython - # CI-5974-Test-RustPython-Integration WIP + .github/actions/CI-5974-Test-RustPython-Integration - name: Checkout RustPython repository on ${{ matrix.os }} id: fetch-rpython uses: ./.github/actions/CI-5974-Fetch-RustPython @@ -97,19 +93,19 @@ jobs: override-path: rustpython override-rustpython-path: Lib override-repository: 'RustPython/RustPython' - override-ref: main - - name: Fetch Referance Cpython ${{ matrix.python-version }} on ${{ matrix.os }} + override-ref: main # Hint: could be changed to ${{ github.ref }} + - name: Fetch Reference Cpython ${{ matrix.python-version }} on ${{ matrix.os }} id: fetch-cpython uses: ./.github/actions/CI-5974-Fetch-CPython with: # Define the reference files to pull as a file glob pattern match: "Lib/test/*.py Lib/test/**/*.py" + # ignore: "Lib/test/*.pyc" python-version: ${{ matrix.python-version }} override-path: cpython override-cpython-lib-path: 'Lib/test' # override-rustpython-path: ${{ steps.fetch-rpython.outputs.rustpython-lib-path }} override-repository: 'python/cpython' - # this next part is WIP and needs to be updated with filtering for more control of what parts of the reference lib is used - name: "Integrate Cpython Test file" id: merge_theirs uses: ./.github/actions/CI-5974-Integrate-CPython @@ -132,147 +128,27 @@ jobs: printf "%s\n" "::endgroup::" - name: Try Smoke Testing id: smoke_testing - shell: bash - env: - OS: ${{ runner.os }} - CONTEXT_PHRASE: 'for Cpython ${{ matrix.python-version }} on ${{ matrix.os }}' - if: ${{ success() }} + use: ./.github/actions/CI-5974-Test-RustPython-Integration + with: + override-working-dir: rustpython + # override-rustpython-path: 'Lib' + test-files: | + ${{ steps.fetch-cpython.outputs.files }} + python-version: ${{ env.PYTHON_VERSION }} + max-test-time: ${{ env.SUBSHELL_TIMEOUT }} # seconds + # this next part is WIP and needs to be updated with logic to summarize the results + - name: Post-Process + id: summarize run: | - # Custom timeout function (GH-5974 - because ulimit is restricted and windows can't ulimit at all) - # TODO: clean this up - run_with_timeout() { - local timeout=$1 - shift - "$@" & - local pid=$! - ( sleep "$timeout" && kill -HUP "$pid" 2>/dev/null ) & disown - # Send HUP signal after timeout - wait "$pid" - local status=$? - if [ $status -eq 0 ]; then - printf "::debug::%s\n" "Command completed successfully." - true ; # force success result - elif [ $status -eq 143 ]; then - printf "::warning title='Timeout'::%s\n" "The command \`$@\` ${CONTEXT_PHRASE} was terminated due to timeout." - false ; - else - printf "%s\n" "The command failed with status $status ${CONTEXT_PHRASE}." - false ; + printf "%s\n\n" "# Results" >> "$GITHUB_STEP_SUMMARY" ; + for TEST_FILE_PATH in ${{ steps.fetch-cpython.outputs.files }}; do + if [ -n ${RAW_COPY_${TEST_FILE_PATH}_OUTCOME} ]; then + printf "%s\n" "* Directly copying the test file \`${TEST_FILE_PATH}\` is ${RAW_COPY_${TEST_FILE_PATH}_OUTCOME}" >> "$GITHUB_STEP_SUMMARY" ; + if [ -n ${FIX_COPY_${TEST_FILE_PATH}_OUTCOME} ]; then + printf "%s\n" "* Copying and Auto-fixing the test file \`${TEST_FILE_PATH}\` was ${FIX_COPY_${TEST_FILE_PATH}_OUTCOME}" >> "$GITHUB_STEP_SUMMARY" ; fi ; - } - - export -f run_with_timeout ; - # Usage - # run_with_timeout 360 your_command_here - cd rustpython || exit 13 ; - for referance_file in ${{ steps.fetch-cpython.outputs.files }} ; do - if [[ ( -f "${referance_file}" ) ]] ; then - # See https://devguide.python.org/testing/run-write-tests - # Heuristic: "if some module does not have unittest.main(), then most likely it does not support direct invocation." - if grep -qF "unittest.main()" "${referance_file}" 2>/dev/null ; then - printf "Now Testing '%s'\n" "${referance_file}" - # vars for subshell but not for workflow - export REF_FILE_NAME=$(basename "${referance_file}") ; - printf "::group::%s\n" "${REF_FILE_NAME}" ; - # TODO: test with cpython first for baseline - # TODO: add to list of files that need additional prep due to hanging or unexpected failures that need to be removed - # Execute the testing command in a subshell - time ( - export RUSTPYTHONPATH=Lib ; - run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- Lib/test/"${REF_FILE_NAME}" || RAW_COPY_OUTCOME='failing' - if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then - printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${referance_file}" "${referance_file}" "${CONTEXT_PHRASE}" ; - ( - run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- ./scripts/fix_test.py --path ./Lib/test/"${REF_FILE_NAME}" || FIX_COPY_OUTCOME='unfixed' ; - ) ; - if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then - printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests %s.\n" "${referance_file}" "${CONTEXT_PHRASE}" >&2 ; - # reset broken integration to last rustpython copy - git restore --ignore-unmerged --worktree --staged "${referance_file}" || : ; - git checkout -f --ignore-unmerged -- "${referance_file}" || : ; - # TODO: validate and conditionally set - FIX_COPY_OUTCOME="reverted" - else - FIX_COPY_OUTCOME="fixed" - RAW_COPY_OUTCOME="incompatable" - fi ; - else - FIX_COPY_OUTCOME="skipped" - RAW_COPY_OUTCOME="compatable" - fi ; - printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; - printf "FIX_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; - printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; - # should dump a diff or something here - printf "\n\n" ; - unset RUSTPYTHONPATH 2>/dev/null || : ; - ) ; - # cleanup temp env - unset FIX_COPY_OUTCOME 2>/dev/null || : ; - unset RAW_COPY_OUTCOME 2>/dev/null || : ; - unset REF_FILE_NAME 2>/dev/null || : ; - printf "\n::endgroup::\n" ; - wait ; - else - # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. - # TODO: cleanup this regular expression for edge-cases - if grep -qE "^[^cC]*([cC]lass)\s*(.+)(Test)" "${referance_file}" 2>/dev/null ; then - printf "Now Testing test-cases in '%s'\n" "${referance_file}" - # vars for subshell but not for workflow - export REF_TEST_NAME=$(basename -s ".py" "${referance_file}") ; - printf "%s\n" "Selected testcase test.${REF_TEST_NAME}" - printf "::group::%s\n" "${REF_FILE_NAME}" ; - # TODO: test with cpython first for baseline - # TODO: add to list of files that need additional prep due to hanging or unexpected failures that need to be removed - # Execute the testing command in a subshell - time ( - export RUSTPYTHONPATH=Lib ; - run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- -m unittest -v test.${REF_TEST_NAME} || RAW_COPY_OUTCOME='failing' - if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then - printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${referance_file}" "${referance_file}" "${CONTEXT_PHRASE}" ; - ( - run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- ./scripts/fix_test.py --path ./Lib/test/"${REF_FILE_NAME}".py || FIX_COPY_OUTCOME='unfixed' ; - ) ; - if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then - printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${referance_file}" >&2 ; - # reset broken integration to last rustpython copy - git restore --ignore-unmerged --worktree --staged "${referance_file}" || : ; - git checkout -f --ignore-unmerged -- "${referance_file}" || : ; - # TODO: validate and conditionally set - FIX_COPY_OUTCOME="reverted" - else - FIX_COPY_OUTCOME="fixed" - RAW_COPY_OUTCOME="incompatable" - fi ; - else - FIX_COPY_OUTCOME="skipped" - RAW_COPY_OUTCOME="compatable" - fi ; - printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Fix:%s\n\n" "${REF_TEST_NAME}" "${RAW_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; - wait ; # used to force boundry for std out read/write race in UI - printf "FIX_COPY_%s.py_OUTCOME=%s\n" "${REF_TEST_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; - printf "RAW_COPY_%s.py_OUTCOME=%s\n" "${REF_TEST_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; - # should dump a diff or something here - printf "\n\n" ; - unset RUSTPYTHONPATH 2>/dev/null || : ; - ) ; - # cleanup temp env - unset FIX_COPY_OUTCOME 2>/dev/null || : ; - unset RAW_COPY_OUTCOME 2>/dev/null || : ; - unset REF_TEST_NAME 2>/dev/null || : ; - printf "\n::endgroup::\n" ; - wait ; - else - printf "\nNow Skipping '%s'\n\n" "${referance_file}" ; - # TODO: record this skip status too - fi ; - fi ; # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. fi ; - done - cd .. ; - - name: Post-Clean - id: post-bootstrap - run: | + done ; exit 0 ; # don't break CI on regression if: ${{ always() }} shell: bash From 32583f56ef350910ad81a9f5651352790c928b45 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 24 Jul 2025 14:28:46 -0700 Subject: [PATCH 36/62] Fix typo regression. --- .github/workflows/Check_Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index ab121fa86b..20da5a3ab8 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -128,7 +128,7 @@ jobs: printf "%s\n" "::endgroup::" - name: Try Smoke Testing id: smoke_testing - use: ./.github/actions/CI-5974-Test-RustPython-Integration + uses: ./.github/actions/CI-5974-Test-RustPython-Integration with: override-working-dir: rustpython # override-rustpython-path: 'Lib' From e4dd8cee3433b679e74e7fc58b525749b93e0ba2 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 24 Jul 2025 14:38:13 -0700 Subject: [PATCH 37/62] :rocket: Prototype --- .../actions/CI-5974-Test-RustPython-Integration/action.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml index a24c10e47e..1de3cec781 100644 --- a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml +++ b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml @@ -75,13 +75,13 @@ runs: shell: bash if: ${{ !cancelled() && inputs.test-files != '' }} env: - INPUT_FILES: ${{ inputs.files }} + INPUT_FILES: ${{ inputs.test-files }} OS: ${{ runner.os }} CONTEXT_PHRASE: 'for Cpython ${{ steps.output_python.output.python-version }} on ${{ runner.os }}' SUBSHELL_TIMEOUT: ${{ inputs.max-test-time }} run: | - # Custom timeout function (GH-5974 - because ulimit is restricted and windows can't ulimit at all) # TODO: clean this up + # Custom timeout function (GH-5974 - because ulimit is restricted and windows can't ulimit at all) run_with_timeout() { local timeout=$1 shift From f2ab01365b6012ee2ced9509b1a7a87e57ddcc2c Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 24 Jul 2025 15:04:24 -0700 Subject: [PATCH 38/62] :see_no_evil: More minor fixes for CI actions --- .github/actions/CI-5974-Integrate-CPython/action.yaml | 11 ++++++----- .../CI-5974-Test-RustPython-Integration/action.yaml | 5 ++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/actions/CI-5974-Integrate-CPython/action.yaml b/.github/actions/CI-5974-Integrate-CPython/action.yaml index b08463eb52..3f49d9d04a 100644 --- a/.github/actions/CI-5974-Integrate-CPython/action.yaml +++ b/.github/actions/CI-5974-Integrate-CPython/action.yaml @@ -3,24 +3,24 @@ name: 'Integrate Reference Implementation' description: 'Copy Reference Implementation' author: 'Mr. Walls' branding: - icon: 'bar-chart-2' + icon: 'copy' color: 'purple' inputs: into-path: description: | Path to Destination. Default is 'rustpython' required: true - default: ${{ github.server_url == 'https://github.com' && github.workspace || 'rustpython' }} + default: 'rustpython' from-path: description: | Path to source. Default is 'cpython' required: true - default: ${{ github.server_url == 'https://github.com' && github.workspace || 'cpython' }} + default: 'cpython' files: description: | List of paths to copy from source to destination. Default is 'Lib/**/*.py' required: true - default: ${{ github.server_url == 'https://github.com' && 'Lib/**/*.py' || '' }} + default: 'Lib/**/*.py' python-version: description: | The Cpython version (e.g., any valid release or tag, 3.11, 3.12, 3.13) to override setup. @@ -28,7 +28,7 @@ inputs: default: '3.13' required: true -# TODO: fix python version detection logic +# TODO: improve python version detection logic # TODO: add verification steps runs: @@ -43,6 +43,7 @@ runs: run: | printf "::group::%s\n" "Copy Reference Implementation" ; for reference_file in ${INPUT_FILES}; do + [[ -d $(dirname ${{ inputs.into-path }}/"${reference_file}" ) ]] || mkdir -v -p -m 751 $(dirname ${{ inputs.into-path }}/"${reference_file}" ) ; cp -vf ${{ inputs.from-path }}/"${reference_file}" ${{ inputs.into-path }}/"${reference_file}" || printf "::warning file='%s',title='integration failure':: Could not integrate file for Cpython %s on %s.\n" "${reference_file}" '${{ inputs.python-version }}' '${{ runner.os }}' ; done ; printf "\n::endgroup::\n\n" ; diff --git a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml index 1de3cec781..0d824d3a47 100644 --- a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml +++ b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml @@ -2,6 +2,9 @@ name: 'RustPython Smoke-Testing' description: 'Smoke-Test Integrated Reference Implementation tests' author: 'Mr. Walls' +branding: + icon: 'check-circle' + color: 'black' inputs: override-working-dir: description: | @@ -77,7 +80,7 @@ runs: env: INPUT_FILES: ${{ inputs.test-files }} OS: ${{ runner.os }} - CONTEXT_PHRASE: 'for Cpython ${{ steps.output_python.output.python-version }} on ${{ runner.os }}' + CONTEXT_PHRASE: 'for Cpython ${{ steps.output_python.outputs.python-version }} on ${{ runner.os }}' SUBSHELL_TIMEOUT: ${{ inputs.max-test-time }} run: | # TODO: clean this up From 708a78a0c70c236d81a68eb6c37b54994864725e Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 24 Jul 2025 19:40:17 -0700 Subject: [PATCH 39/62] Oops! forgot the expansion - retry post-proc summary --- .github/workflows/Check_Tests.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 20da5a3ab8..21678e2c78 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -142,10 +142,10 @@ jobs: run: | printf "%s\n\n" "# Results" >> "$GITHUB_STEP_SUMMARY" ; for TEST_FILE_PATH in ${{ steps.fetch-cpython.outputs.files }}; do - if [ -n ${RAW_COPY_${TEST_FILE_PATH}_OUTCOME} ]; then - printf "%s\n" "* Directly copying the test file \`${TEST_FILE_PATH}\` is ${RAW_COPY_${TEST_FILE_PATH}_OUTCOME}" >> "$GITHUB_STEP_SUMMARY" ; - if [ -n ${FIX_COPY_${TEST_FILE_PATH}_OUTCOME} ]; then - printf "%s\n" "* Copying and Auto-fixing the test file \`${TEST_FILE_PATH}\` was ${FIX_COPY_${TEST_FILE_PATH}_OUTCOME}" >> "$GITHUB_STEP_SUMMARY" ; + if [ -n ${!RAW_COPY_${TEST_FILE_PATH}_OUTCOME} ]; then + printf "%s\n" "* Directly copying the test file \`${TEST_FILE_PATH}\` is ${!RAW_COPY_${TEST_FILE_PATH}_OUTCOME}" >> "$GITHUB_STEP_SUMMARY" ; + if [ -n ${!FIX_COPY_${TEST_FILE_PATH}_OUTCOME} ]; then + printf "%s\n" "* Copying and Auto-fixing the test file \`${TEST_FILE_PATH}\` was ${!FIX_COPY_${TEST_FILE_PATH}_OUTCOME}" >> "$GITHUB_STEP_SUMMARY" ; fi ; fi ; done ; From 9e7a8ec161950b071e69b1e0f550cc23267b9478 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 24 Jul 2025 21:25:43 -0700 Subject: [PATCH 40/62] Improved the final output slightly --- .github/workflows/Check_Tests.yml | 37 ++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 21678e2c78..556e275210 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -140,15 +140,40 @@ jobs: - name: Post-Process id: summarize run: | - printf "%s\n\n" "# Results" >> "$GITHUB_STEP_SUMMARY" ; + printf "%s\n\n%s\n\n" "# Results" "_With CPython ${PYTHON_VERSION}_" >> "$GITHUB_STEP_SUMMARY" ; for TEST_FILE_PATH in ${{ steps.fetch-cpython.outputs.files }}; do - if [ -n ${!RAW_COPY_${TEST_FILE_PATH}_OUTCOME} ]; then - printf "%s\n" "* Directly copying the test file \`${TEST_FILE_PATH}\` is ${!RAW_COPY_${TEST_FILE_PATH}_OUTCOME}" >> "$GITHUB_STEP_SUMMARY" ; - if [ -n ${!FIX_COPY_${TEST_FILE_PATH}_OUTCOME} ]; then - printf "%s\n" "* Copying and Auto-fixing the test file \`${TEST_FILE_PATH}\` was ${!FIX_COPY_${TEST_FILE_PATH}_OUTCOME}" >> "$GITHUB_STEP_SUMMARY" ; - fi ; + # unpack the variable + # RAW_COPY_OUTCOME + EVAL_VAR=$(printf "echo %s" "\${RAW_COPY_${TEST_FILE_PATH}_OUTCOME}") ; + if [ -n $(bash -c "${EVAL_VAR}" ;) ]; then + RAW_COPY_OUTCOME=$(bash -c "${EVAL_VAR}" ;) + fi ; + unset EVAL_VAR 2>/dev/null || : ; + # FIX_COPY_OUTCOME + EVAL_VAR=$(printf "echo %s" "\${FIX_COPY_${TEST_FILE_PATH}_OUTCOME}") ; + if [ -n $(bash -c "${EVAL_VAR}" ;) ]; then + FIX_COPY_OUTCOME=$(bash -c "${EVAL_VAR}" ;) fi ; + unset EVAL_VAR 2>/dev/null || : ; + # Start of summary for loop + if [ -n ${RAW_COPY_OUTCOME} ]; then + if [[ "${RAW_COPY_OUTCOME}" == "compatible" ]] ; then + printf "%s\n" ":ballot_box_with_check: Directly copying the test file \`${TEST_FILE_PATH}\` is ${RAW_COPY_OUTCOME}" >> "$GITHUB_STEP_SUMMARY" ; + else + printf "%s\n" ":black_square_button: Directly copying the test file \`${TEST_FILE_PATH}\` is ${RAW_COPY_OUTCOME}" >> "$GITHUB_STEP_SUMMARY" ; + fi ; + if [ -n ${FIX_COPY_OUTCOME} ]; then + if [[ "${FIX_COPY_OUTCOME}" == "fixed" ]] ; then + printf "%s\n" " :ballot_box_with_check: Copying and Auto-fixing the test file \`${TEST_FILE_PATH}\` was successful" >> "$GITHUB_STEP_SUMMARY" ; + else + printf "%s\n" " :grey_exclamation: Copying and Auto-fixing the test file \`${TEST_FILE_PATH}\` was ${FIX_COPY_OUTCOME}" >> "$GITHUB_STEP_SUMMARY" ; + fi ; # end auto-fix + fi ; + fi ; # end copy + unset RAW_COPY_OUTCOME 2>/dev/null || : ; + unset FIX_COPY_OUTCOME 2>/dev/null || : ; done ; + printf "\n\n---\n" >> "$GITHUB_STEP_SUMMARY" ; exit 0 ; # don't break CI on regression if: ${{ always() }} shell: bash From 7c8894aea66497bb7d15a53b48cfc08ee7076aa7 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 24 Jul 2025 22:15:23 -0700 Subject: [PATCH 41/62] :sparkle: Improved post-proc some more. --- .github/workflows/Check_Tests.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 556e275210..75bd697739 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -142,19 +142,21 @@ jobs: run: | printf "%s\n\n%s\n\n" "# Results" "_With CPython ${PYTHON_VERSION}_" >> "$GITHUB_STEP_SUMMARY" ; for TEST_FILE_PATH in ${{ steps.fetch-cpython.outputs.files }}; do - # unpack the variable + # unpack the variables + NAME_STUB=$(basename ${TEST_FILE_PATH}) ; # RAW_COPY_OUTCOME - EVAL_VAR=$(printf "echo %s" "\${RAW_COPY_${TEST_FILE_PATH}_OUTCOME}") ; + EVAL_VAR=$(printf "echo %s" "\${RAW_COPY_${NAME_STUB}_OUTCOME}") ; if [ -n $(bash -c "${EVAL_VAR}" ;) ]; then RAW_COPY_OUTCOME=$(bash -c "${EVAL_VAR}" ;) fi ; unset EVAL_VAR 2>/dev/null || : ; # FIX_COPY_OUTCOME - EVAL_VAR=$(printf "echo %s" "\${FIX_COPY_${TEST_FILE_PATH}_OUTCOME}") ; + EVAL_VAR=$(printf "echo %s" "\${FIX_COPY_${NAME_STUB}_OUTCOME}") ; if [ -n $(bash -c "${EVAL_VAR}" ;) ]; then FIX_COPY_OUTCOME=$(bash -c "${EVAL_VAR}" ;) fi ; unset EVAL_VAR 2>/dev/null || : ; + unset NAME_STUB 2>/dev/null || : ; # Start of summary for loop if [ -n ${RAW_COPY_OUTCOME} ]; then if [[ "${RAW_COPY_OUTCOME}" == "compatible" ]] ; then From 101b653dbc585e6f52781b732a1db1e053c838e7 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 24 Jul 2025 23:06:57 -0700 Subject: [PATCH 42/62] Add quotes? --- .github/workflows/Check_Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 75bd697739..9f5af966fd 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -143,7 +143,7 @@ jobs: printf "%s\n\n%s\n\n" "# Results" "_With CPython ${PYTHON_VERSION}_" >> "$GITHUB_STEP_SUMMARY" ; for TEST_FILE_PATH in ${{ steps.fetch-cpython.outputs.files }}; do # unpack the variables - NAME_STUB=$(basename ${TEST_FILE_PATH}) ; + NAME_STUB=$(basename "${TEST_FILE_PATH}") ; # RAW_COPY_OUTCOME EVAL_VAR=$(printf "echo %s" "\${RAW_COPY_${NAME_STUB}_OUTCOME}") ; if [ -n $(bash -c "${EVAL_VAR}" ;) ]; then From ebd23cf809329afc38937be3ce8f469b5d3518fb Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Fri, 25 Jul 2025 16:13:40 -0700 Subject: [PATCH 43/62] More cleanup of new actions --- .../CI-5974-Fetch-RustPython/action.yaml | 24 ++++++++++++++++--- .../CI-5974-Integrate-CPython/action.yaml | 19 +++++++++++++-- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/.github/actions/CI-5974-Fetch-RustPython/action.yaml b/.github/actions/CI-5974-Fetch-RustPython/action.yaml index 12e0b0216d..fad6ea1d14 100644 --- a/.github/actions/CI-5974-Fetch-RustPython/action.yaml +++ b/.github/actions/CI-5974-Fetch-RustPython/action.yaml @@ -74,7 +74,11 @@ runs: run: | cd ${PWD:-.} ; export OLD_PWD=$(pwd) ; # only local use for bootstrap - printf "initial-path=%s\n" "${OLD_PWD}" >> "$GITHUB_OUTPUT" + printf "initial-path=%s\n" "${OLD_PWD}" >> "$GITHUB_OUTPUT" ; + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$"ACTIONS_STEP_DEBUG" == "true" ]]; then + printf "::debug::Return directory now set to '%s'\n" "${OLD_PWD}" ; + printf "::debug::Working directory is set to '%s'\n" '${{ inputs.override-path }}' ; + fi ; - id: output_branch_name if: ${{ !cancelled() }} shell: bash @@ -88,6 +92,18 @@ runs: cd ${{ inputs.override-path }} || exit 13 ; printf "sha=%s\n" $(git log -1 --format=%H) >> "$GITHUB_OUTPUT" cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; + - name: "Setup Cargo" + id: output_cargo_args + shell: bash + run: | + if [[ -n $CARGO_ARGS ]]; then + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$"ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS already set to '%s'\n" "${CARGO_ARGS}" ; fi ; + # e.g., CARGO_ARGS=${CARGO_ARGS} + else + CARGO_ARGS="--release" ; + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$"ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS initialized to '%s'\n" "${CARGO_ARGS}" ; fi ; + fi ; + printf "%s\n" "CARGO_ARGS=${CARGO_ARGS}" >> "$GITHUB_ENV" ; - name: Pre-Test Build check id: build_rpython shell: bash @@ -96,11 +112,13 @@ runs: if: ${{ !cancelled() }} run: | cd ${{ inputs.override-path }} || exit 13 ; - printf "::debug::Now Building '%s'\n" "RustPython" + printf "::group::%s\n" "Cargo" >> "$GITHUB_ENV" ; + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$"ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::Now Building '%s'\n" "RustPython" ; fi ; # Execute the testing command in a subshell ( - RUSTPYTHONPATH=${{ inputs.override-rustpython-path }} cargo run --release -- --version || printf "::error title='build failure':: Could not pass build step for version check on ${OS}.\n" ; + RUSTPYTHONPATH=${{ inputs.override-rustpython-path }} cargo run $CARGO_ARGS -- --version || printf "::error title='build failure':: Could not pass build step for version check on ${OS}.\n" ; ) ; + printf "::endgroup::%s\n" >> "$GITHUB_ENV" ; cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; - id: output_rpython_path shell: bash diff --git a/.github/actions/CI-5974-Integrate-CPython/action.yaml b/.github/actions/CI-5974-Integrate-CPython/action.yaml index 3f49d9d04a..5fa43cbf0f 100644 --- a/.github/actions/CI-5974-Integrate-CPython/action.yaml +++ b/.github/actions/CI-5974-Integrate-CPython/action.yaml @@ -28,12 +28,27 @@ inputs: default: '3.13' required: true -# TODO: improve python version detection logic # TODO: add verification steps runs: using: composite steps: + - id: output_python + env: + PYTHON_VERSION_INPUT: ${{ inputs.python-version }} + name: "Detect Python" + if: ${{ inputs.files != '' }} + shell: bash + run: | + # check the python version + if [[ -n $PYTHON_VERSION_INPUT ]]; then + printf "python-version=%s\n" "${PYTHON_VERSION_INPUT}" >> "$GITHUB_OUTPUT" + PYTHON_VERSION=${PYTHON_VERSION_INPUT} + else + printf "python-version=%s\n" "${PYTHON_VERSION}" >> "$GITHUB_OUTPUT" + fi + printf "%s\n" "PYTHON_VERSION=${PYTHON_VERSION}" >> "$GITHUB_ENV" + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$"ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::Targeting Cpython %s.\n" "${PYTHON_VERSION}" ; fi ; - name: "Integrate Cpython Test files" id: merge_theirs shell: bash @@ -44,6 +59,6 @@ runs: printf "::group::%s\n" "Copy Reference Implementation" ; for reference_file in ${INPUT_FILES}; do [[ -d $(dirname ${{ inputs.into-path }}/"${reference_file}" ) ]] || mkdir -v -p -m 751 $(dirname ${{ inputs.into-path }}/"${reference_file}" ) ; - cp -vf ${{ inputs.from-path }}/"${reference_file}" ${{ inputs.into-path }}/"${reference_file}" || printf "::warning file='%s',title='integration failure':: Could not integrate file for Cpython %s on %s.\n" "${reference_file}" '${{ inputs.python-version }}' '${{ runner.os }}' ; + cp -vf ${{ inputs.from-path }}/"${reference_file}" ${{ inputs.into-path }}/"${reference_file}" || printf "::warning file='%s',title='integration failure':: Could not integrate file for Cpython %s on %s.\n" "${reference_file}" '${PYTHON_VERSION}' '${{ runner.os }}' ; done ; printf "\n::endgroup::\n\n" ; From 918fb9d4ae742d636ee9c6a616757b37d5045ac5 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Sat, 26 Jul 2025 12:15:15 -0700 Subject: [PATCH 44/62] Small improvements to the new actions reporting logic WIP * see RustPython/PurstPython#5974 for more --- .../action.yaml | 64 +++++++++++++++++-- .github/workflows/Check_Tests.yml | 54 ++++------------ 2 files changed, 71 insertions(+), 47 deletions(-) diff --git a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml index 0d824d3a47..49e8492a0d 100644 --- a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml +++ b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml @@ -34,7 +34,6 @@ inputs: default: '30' required: true -# TODO: fix python version detection logic # TODO: add verification steps runs: @@ -66,6 +65,24 @@ runs: printf "%s\n" "OVERRIDE_RUSTPYTHONPATH=${OVERRIDE_RUSTPYTHONPATH}" >> "$GITHUB_ENV" printf "Targeting Cpython %s on %s.\n" '${PYTHON_VERSION}' '${{ runner.os }}' ; printf "%s\n" "::endgroup::" + - name: "Check Cargo Setup" + id: output_cargo_args + shell: bash + run: | + if [[ -n $CARGO_ARGS ]]; then + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$"ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS already set to '%s'\n" "${CARGO_ARGS}" ; fi ; + # e.g., CARGO_ARGS=${CARGO_ARGS} + else + CARGO_ARGS="--release" ; + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$"ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS initialized to '%s'\n" "${CARGO_ARGS}" ; fi ; + fi ; + printf "%s\n" "CARGO_ARGS=${CARGO_ARGS}" >> "$GITHUB_ENV" ; + - name: "Prepare Artifact Name" + id: output_artifact_name + if: ${{ !cancelled() }} + shell: bash + run: | + printf "%s\n" "TEST_STEP_SUMMARY=CPython-Summary-Artifact-${{ runner.os }}-${PYTHON_VERSION}.md" >> "$GITHUB_ENV" - id: store_old_path if: ${{ !cancelled() }} shell: bash @@ -110,6 +127,7 @@ runs: # Usage # run_with_timeout 360 your_command_here cd ${{ inputs.override-working-dir }} || exit 13 ; + printf "%s\n\n" "# CPython ${PYTHON_VERSION} Results" > "${TEST_STEP_SUMMARY}" ; for reference_file in ${INPUT_FILES}; do if [[ ( -f "${reference_file}" ) ]] ; then # See https://devguide.python.org/testing/run-write-tests @@ -124,11 +142,11 @@ runs: # Execute the testing command in a subshell time ( export RUSTPYTHONPATH=${OVERRIDE_RUSTPYTHONPATH:-Lib} ; - run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" || RAW_COPY_OUTCOME='failing' + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" || RAW_COPY_OUTCOME='failing' if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${reference_file}" "${reference_file}" "${CONTEXT_PHRASE}" ; ( - run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- ./scripts/fix_test.py --path ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" || FIX_COPY_OUTCOME='unfixed' ; + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- ./scripts/fix_test.py --path ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" || FIX_COPY_OUTCOME='unfixed' ; ) ; if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" >&2 ; @@ -145,6 +163,22 @@ runs: FIX_COPY_OUTCOME="skipped" RAW_COPY_OUTCOME="compatible" fi ; + if [ -n ${RAW_COPY_OUTCOME} ]; then + if [[ "${RAW_COPY_OUTCOME}" == "compatible" ]] ; then + printf "%s\n" ":ballot_box_with_check: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + else + printf "%s\n" ":black_square_button: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + fi ; + if [ -n ${FIX_COPY_OUTCOME} ]; then + if [[ "${FIX_COPY_OUTCOME}" == "fixed" ]] ; then + printf "%s\n\n" " :ballot_box_with_check: Copying and Auto-fixing the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; + else + printf "%s\n\n" " :grey_exclamation: Copying and Auto-fixing the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + fi ; # end auto-fix + else + printf "\n" >> "${TEST_STEP_SUMMARY}" ; # extra space + fi ; + fi ; # end copy printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; printf "FIX_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; @@ -172,11 +206,11 @@ runs: # Execute the testing command in a subshell time ( export RUSTPYTHONPATH=${OVERRIDE_RUSTPYTHONPATH:-Lib} ; - run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- -m unittest -v test.${REF_TEST_NAME} || RAW_COPY_OUTCOME='failing' + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- -m unittest -v test.${REF_TEST_NAME} || RAW_COPY_OUTCOME='failing' if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${reference_file}" "${reference_file}" "${CONTEXT_PHRASE}" ; ( - run_with_timeout ${SUBSHELL_TIMEOUT} cargo run --release -- ./scripts/fix_test.py --path ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}".py || FIX_COPY_OUTCOME='unfixed' ; + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- ./scripts/fix_test.py --path ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}".py || FIX_COPY_OUTCOME='unfixed' ; ) ; if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${reference_file}" >&2 ; @@ -193,6 +227,22 @@ runs: FIX_COPY_OUTCOME="skipped" RAW_COPY_OUTCOME="compatible" fi ; + if [ -n ${RAW_COPY_OUTCOME} ]; then + if [[ "${RAW_COPY_OUTCOME}" == "compatible" ]] ; then + printf "%s\n" ":ballot_box_with_check: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + else + printf "%s\n" ":black_square_button: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + fi ; + if [ -n ${FIX_COPY_OUTCOME} ]; then + if [[ "${FIX_COPY_OUTCOME}" == "fixed" ]] ; then + printf "%s\n\n" " :ballot_box_with_check: Copying and Auto-fixing the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; + else + printf "%s\n\n" " :grey_exclamation: Copying and Auto-fixing the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + fi ; # end auto-fix + else + printf "\n" >> "${TEST_STEP_SUMMARY}" ; # extra space + fi ; + fi ; # end copy printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Fix:%s\n\n" "${REF_TEST_NAME}" "${RAW_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; wait ; # used to force boundry for std out read/write race in UI printf "FIX_COPY_%s.py_OUTCOME=%s\n" "${REF_TEST_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; @@ -209,11 +259,13 @@ runs: wait ; else printf "\nNow Skipping '%s'\n\n" "${reference_file}" ; - # TODO: record this skip status too + printf "%s\n" ":grey_exclamation: Directly copying the filepath \`${reference_file}\` was inconclusive (_testing and validation skipped_)." >> "${TEST_STEP_SUMMARY}" ; + printf "\n" >> "${TEST_STEP_SUMMARY}" ; # extra space fi ; fi ; # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. fi ; done + cat <"${TEST_STEP_SUMMARY}" >> "$GITHUB_STEP_SUMMARY" ; cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; - name: Post-Clean id: post-bootstrap diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 9f5af966fd..f9552d0c73 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -14,14 +14,22 @@ run-name: Prototyping integration tests ${{ github.ref_name }} on: # yamllint disable-line rule:truthy + workflow_dispatch: push: - branches: ["**"] # matches any branch - tags: ["v*"] + paths: + - ".github/workflows/Check_Tests.yaml" + - ".github/actions/CI-5974*" + branches: + - "**" # matches any branch + tags: + - "v*" # Declare default permissions as none. permissions: {} env: + #define cargo args like in cron + CARGO_ARGS: --no-default-features --features stdlib,importlib,encodings,ssl,jit # Define Python versions at the top level -- Expected format: X.Y (e.g., 3.13) PYTHON_DEFAULT: "${{ vars.PYTHON_DEFAULT || '3.13' }}" PYTHON_OLD_MIN: "${{ vars.PYTHON_OLD_MIN || '3.9' }}" # For Oldest Python versions @@ -30,6 +38,7 @@ env: # define how mush time before assuming the test has hung in seconds (parsed by sleep) SUBSHELL_TIMEOUT: 30 + # TODO: coordinate with @moreal - to support initial use-case See RustPython/RustPython#5974 # TODO: coordinate with @arihant2math - to really build out the migration/Reporting logic # TODO: coordinate with @ShaharNaveh - to really build out the test migration logic @@ -136,46 +145,9 @@ jobs: ${{ steps.fetch-cpython.outputs.files }} python-version: ${{ env.PYTHON_VERSION }} max-test-time: ${{ env.SUBSHELL_TIMEOUT }} # seconds - # this next part is WIP and needs to be updated with logic to summarize the results - name: Post-Process id: summarize - run: | - printf "%s\n\n%s\n\n" "# Results" "_With CPython ${PYTHON_VERSION}_" >> "$GITHUB_STEP_SUMMARY" ; - for TEST_FILE_PATH in ${{ steps.fetch-cpython.outputs.files }}; do - # unpack the variables - NAME_STUB=$(basename "${TEST_FILE_PATH}") ; - # RAW_COPY_OUTCOME - EVAL_VAR=$(printf "echo %s" "\${RAW_COPY_${NAME_STUB}_OUTCOME}") ; - if [ -n $(bash -c "${EVAL_VAR}" ;) ]; then - RAW_COPY_OUTCOME=$(bash -c "${EVAL_VAR}" ;) - fi ; - unset EVAL_VAR 2>/dev/null || : ; - # FIX_COPY_OUTCOME - EVAL_VAR=$(printf "echo %s" "\${FIX_COPY_${NAME_STUB}_OUTCOME}") ; - if [ -n $(bash -c "${EVAL_VAR}" ;) ]; then - FIX_COPY_OUTCOME=$(bash -c "${EVAL_VAR}" ;) - fi ; - unset EVAL_VAR 2>/dev/null || : ; - unset NAME_STUB 2>/dev/null || : ; - # Start of summary for loop - if [ -n ${RAW_COPY_OUTCOME} ]; then - if [[ "${RAW_COPY_OUTCOME}" == "compatible" ]] ; then - printf "%s\n" ":ballot_box_with_check: Directly copying the test file \`${TEST_FILE_PATH}\` is ${RAW_COPY_OUTCOME}" >> "$GITHUB_STEP_SUMMARY" ; - else - printf "%s\n" ":black_square_button: Directly copying the test file \`${TEST_FILE_PATH}\` is ${RAW_COPY_OUTCOME}" >> "$GITHUB_STEP_SUMMARY" ; - fi ; - if [ -n ${FIX_COPY_OUTCOME} ]; then - if [[ "${FIX_COPY_OUTCOME}" == "fixed" ]] ; then - printf "%s\n" " :ballot_box_with_check: Copying and Auto-fixing the test file \`${TEST_FILE_PATH}\` was successful" >> "$GITHUB_STEP_SUMMARY" ; - else - printf "%s\n" " :grey_exclamation: Copying and Auto-fixing the test file \`${TEST_FILE_PATH}\` was ${FIX_COPY_OUTCOME}" >> "$GITHUB_STEP_SUMMARY" ; - fi ; # end auto-fix - fi ; - fi ; # end copy - unset RAW_COPY_OUTCOME 2>/dev/null || : ; - unset FIX_COPY_OUTCOME 2>/dev/null || : ; - done ; - printf "\n\n---\n" >> "$GITHUB_STEP_SUMMARY" ; - exit 0 ; # don't break CI on regression if: ${{ always() }} shell: bash + run: | + exit 0 ; # don't break CI on regression From 7d3dc3d7ac6e7ae29ad36efb8450913d56d8e655 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Sun, 27 Jul 2025 18:25:27 -0700 Subject: [PATCH 45/62] Revert triggers for now * too much churn --- .github/workflows/Check_Tests.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index f9552d0c73..24eaaf8d26 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -14,15 +14,9 @@ run-name: Prototyping integration tests ${{ github.ref_name }} on: # yamllint disable-line rule:truthy - workflow_dispatch: push: - paths: - - ".github/workflows/Check_Tests.yaml" - - ".github/actions/CI-5974*" - branches: - - "**" # matches any branch - tags: - - "v*" + branches: ["**"] # matches any branch + tags: ["v*"] # Declare default permissions as none. permissions: {} From 63c6f614eee8f8086c662c38fa8c99f5c9ed1165 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Sun, 27 Jul 2025 18:31:38 -0700 Subject: [PATCH 46/62] Issue with chickens and eggs and the order of things. * yup you guessed it; more churn --- .github/actions/CI-5974-Fetch-RustPython/action.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/CI-5974-Fetch-RustPython/action.yaml b/.github/actions/CI-5974-Fetch-RustPython/action.yaml index fad6ea1d14..75e1cf4d6a 100644 --- a/.github/actions/CI-5974-Fetch-RustPython/action.yaml +++ b/.github/actions/CI-5974-Fetch-RustPython/action.yaml @@ -112,13 +112,13 @@ runs: if: ${{ !cancelled() }} run: | cd ${{ inputs.override-path }} || exit 13 ; - printf "::group::%s\n" "Cargo" >> "$GITHUB_ENV" ; + printf "::group::%s\n" "Cargo" ; if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$"ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::Now Building '%s'\n" "RustPython" ; fi ; # Execute the testing command in a subshell ( RUSTPYTHONPATH=${{ inputs.override-rustpython-path }} cargo run $CARGO_ARGS -- --version || printf "::error title='build failure':: Could not pass build step for version check on ${OS}.\n" ; ) ; - printf "::endgroup::%s\n" >> "$GITHUB_ENV" ; + printf "::endgroup::%s\n" ; cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; - id: output_rpython_path shell: bash From 6a2353c5dd74b008a6f7c4331a1505aba3b05380 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Sun, 27 Jul 2025 18:41:07 -0700 Subject: [PATCH 47/62] More minor fixes * too much churn --- .github/actions/CI-5974-Fetch-RustPython/action.yaml | 6 +++--- .github/actions/CI-5974-Integrate-CPython/action.yaml | 2 +- .../actions/CI-5974-Test-RustPython-Integration/action.yaml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/actions/CI-5974-Fetch-RustPython/action.yaml b/.github/actions/CI-5974-Fetch-RustPython/action.yaml index 75e1cf4d6a..0bcde26ae0 100644 --- a/.github/actions/CI-5974-Fetch-RustPython/action.yaml +++ b/.github/actions/CI-5974-Fetch-RustPython/action.yaml @@ -75,7 +75,7 @@ runs: cd ${PWD:-.} ; export OLD_PWD=$(pwd) ; # only local use for bootstrap printf "initial-path=%s\n" "${OLD_PWD}" >> "$GITHUB_OUTPUT" ; - if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$"ACTIONS_STEP_DEBUG" == "true" ]]; then + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::Return directory now set to '%s'\n" "${OLD_PWD}" ; printf "::debug::Working directory is set to '%s'\n" '${{ inputs.override-path }}' ; fi ; @@ -97,11 +97,11 @@ runs: shell: bash run: | if [[ -n $CARGO_ARGS ]]; then - if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$"ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS already set to '%s'\n" "${CARGO_ARGS}" ; fi ; + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS already set to '%s'\n" "${CARGO_ARGS}" ; fi ; # e.g., CARGO_ARGS=${CARGO_ARGS} else CARGO_ARGS="--release" ; - if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$"ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS initialized to '%s'\n" "${CARGO_ARGS}" ; fi ; + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS initialized to '%s'\n" "${CARGO_ARGS}" ; fi ; fi ; printf "%s\n" "CARGO_ARGS=${CARGO_ARGS}" >> "$GITHUB_ENV" ; - name: Pre-Test Build check diff --git a/.github/actions/CI-5974-Integrate-CPython/action.yaml b/.github/actions/CI-5974-Integrate-CPython/action.yaml index 5fa43cbf0f..dc0d16e5f5 100644 --- a/.github/actions/CI-5974-Integrate-CPython/action.yaml +++ b/.github/actions/CI-5974-Integrate-CPython/action.yaml @@ -48,7 +48,7 @@ runs: printf "python-version=%s\n" "${PYTHON_VERSION}" >> "$GITHUB_OUTPUT" fi printf "%s\n" "PYTHON_VERSION=${PYTHON_VERSION}" >> "$GITHUB_ENV" - if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$"ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::Targeting Cpython %s.\n" "${PYTHON_VERSION}" ; fi ; + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::Targeting Cpython %s.\n" "${PYTHON_VERSION}" ; fi ; - name: "Integrate Cpython Test files" id: merge_theirs shell: bash diff --git a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml index 49e8492a0d..dca3b39865 100644 --- a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml +++ b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml @@ -70,11 +70,11 @@ runs: shell: bash run: | if [[ -n $CARGO_ARGS ]]; then - if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$"ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS already set to '%s'\n" "${CARGO_ARGS}" ; fi ; + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS already set to '%s'\n" "${CARGO_ARGS}" ; fi ; # e.g., CARGO_ARGS=${CARGO_ARGS} else CARGO_ARGS="--release" ; - if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$"ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS initialized to '%s'\n" "${CARGO_ARGS}" ; fi ; + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS initialized to '%s'\n" "${CARGO_ARGS}" ; fi ; fi ; printf "%s\n" "CARGO_ARGS=${CARGO_ARGS}" >> "$GITHUB_ENV" ; - name: "Prepare Artifact Name" From d36c8cad8cf76fd6a3d4935d956ed2812ece2133 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Sun, 27 Jul 2025 18:54:30 -0700 Subject: [PATCH 48/62] Oops Missed one. --- .github/actions/CI-5974-Fetch-RustPython/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/CI-5974-Fetch-RustPython/action.yaml b/.github/actions/CI-5974-Fetch-RustPython/action.yaml index 0bcde26ae0..e5e22b2a5c 100644 --- a/.github/actions/CI-5974-Fetch-RustPython/action.yaml +++ b/.github/actions/CI-5974-Fetch-RustPython/action.yaml @@ -113,7 +113,7 @@ runs: run: | cd ${{ inputs.override-path }} || exit 13 ; printf "::group::%s\n" "Cargo" ; - if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$"ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::Now Building '%s'\n" "RustPython" ; fi ; + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::Now Building '%s'\n" "RustPython" ; fi ; # Execute the testing command in a subshell ( RUSTPYTHONPATH=${{ inputs.override-rustpython-path }} cargo run $CARGO_ARGS -- --version || printf "::error title='build failure':: Could not pass build step for version check on ${OS}.\n" ; From 6534d1c96be13ba6da86a040f88802659f5f218d Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Mon, 25 Aug 2025 11:46:55 -0700 Subject: [PATCH 49/62] [DEMO] Protoytpe from GHI #5974 with rpau from PR #6089 * cc: @youknowone @ShaharNaveh * demo of how to automate RustPython Auto-Patching and upload required testing patches (first attempt, YOLO) * uses ShaharNaveh:auto-updater for rpau (see PR #6089) (Auto Patching and config) * uses automation idea from GHI #5974 (reporting and automation) --- .../CI-6089-Test-RustPython-rapu/action.yaml | 342 ++++++++++++++++++ .github/workflows/Check_Tests.yml | 11 +- 2 files changed, 349 insertions(+), 4 deletions(-) create mode 100644 .github/actions/CI-6089-Test-RustPython-rapu/action.yaml diff --git a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml new file mode 100644 index 0000000000..781c000280 --- /dev/null +++ b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml @@ -0,0 +1,342 @@ +--- +name: 'RustPython Auto Patching' +description: 'R.ust P.ython A.utomated U.pdater Integration' +author: 'Mr. Walls & RustPython Team' +branding: + icon: 'check-circle' + color: 'red' +inputs: + override-working-dir: + description: | + Path to integrated RustPython clone to smoke test and auto-patch. Default is 'rustpython' + required: true + default: ${{ github.server_url == 'https://github.com' && 'rustpython' || '' }} + override-rustpython-path: + description: | + override value for path to the Python Lib. The default is to use the value of the environment + variable 'RUSTPYTHONPATH'. Most users will find the default 'Lib' sufficient. + required: true + override-rpau-workers: + description: | + override value for number of workers for rpau to use. Must be an integer ≥1. + required: true + default: '1' + override-rpau-base-url: + description: | + override value for where to base auto-patches on. Default is + 'https://raw.githubusercontent.com/python/cpython/refs/heads' + required: true + default: 'https://raw.githubusercontent.com/python/cpython/refs/heads' + test-files: + description: | + List of paths to CPython Test files from source to destination. Default is 'Lib/test/*.py' + required: true + default: 'Lib/test/*.py' + python-version: + description: | + The Cpython version (e.g., any valid release or tag, 3.11, 3.12, 3.13) to override. Note + Python 3.12+ is required for R.P.A.U. function. + The default is to use the value of the environment variable 'PYTHON_VERSION'. + default: '3.13' + required: true + max-test-time: + description: | + The max time in seconds per test module file run before aborting a test attempt. The default + is deliberately short at a value of 30 seconds to keep total run-time down. + default: '30' + required: true + +# TODO: add verification steps + +runs: + using: composite + steps: + - id: output_python + env: + PYTHON_VERSION_INPUT: ${{ inputs.python-version }} + OVERRIDE_RUSTPYTHONPATH_INPUT: ${{ inputs.override-rustpython-path }} + name: "Detect Python" + if: ${{ !cancelled() && inputs.test-files != '' }} + shell: bash + run: | + printf "%s\n" "::group::detect-python-env" + if [[ -n $PYTHON_VERSION_INPUT ]]; then + printf "python-version=%s\n" "${PYTHON_VERSION_INPUT}" >> "$GITHUB_OUTPUT" + PYTHON_VERSION=${PYTHON_VERSION_INPUT} + else + printf "python-version=%s\n" "${PYTHON_VERSION}" >> "$GITHUB_OUTPUT" + fi + if [[ -n $OVERRIDE_RUSTPYTHONPATH_INPUT ]]; then + printf "override-rustpython-path=%s\n" "${OVERRIDE_RUSTPYTHONPATH_INPUT}" >> "$GITHUB_OUTPUT" + OVERRIDE_RUSTPYTHONPATH=${RUSTPYTHONPATH} + else + printf "override-rustpython-path=%s\n" "${RUSTPYTHONPATH:-Lib}" >> "$GITHUB_OUTPUT" + OVERRIDE_RUSTPYTHONPATH="${RUSTPYTHONPATH:-Lib}" + fi + printf "%s\n" "PYTHON_VERSION=${PYTHON_VERSION}" >> "$GITHUB_ENV" + printf "%s\n" "OVERRIDE_RUSTPYTHONPATH=${OVERRIDE_RUSTPYTHONPATH}" >> "$GITHUB_ENV" + printf "Targeting Cpython %s on %s.\n" '${PYTHON_VERSION}' '${{ runner.os }}' ; + printf "%s\n" "::endgroup::" + - name: "Check Cargo Setup" + id: output_cargo_args + shell: bash + run: | + if [[ -n $CARGO_ARGS ]]; then + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS already set to '%s'\n" "${CARGO_ARGS}" ; fi ; + # e.g., CARGO_ARGS=${CARGO_ARGS} + else + CARGO_ARGS="--release" ; + if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS initialized to '%s'\n" "${CARGO_ARGS}" ; fi ; + fi ; + printf "%s\n" "CARGO_ARGS=${CARGO_ARGS}" >> "$GITHUB_ENV" ; + - name: "Prepare Artifact Name" + id: output_artifact_name + if: ${{ !cancelled() }} + shell: bash + run: | + printf "%s\n" "TEST_STEP_SUMMARY=CPython-Summary-Artifact-${{ runner.os }}-${PYTHON_VERSION}.md" >> "$GITHUB_ENV" + - id: store_old_path + if: ${{ !cancelled() }} + shell: bash + run: | + cd ${PWD:-.} ; + export OLD_PWD=$(pwd) ; # only local use for bootstrap + printf "initial-path=%s\n" "${OLD_PWD}" >> "$GITHUB_OUTPUT" + - name: "Try Smoke Testing" + id: smoke_test + shell: bash + if: ${{ !cancelled() && inputs.test-files != '' }} + env: + INPUT_FILES: ${{ inputs.test-files }} + WORKER_COUNT: ${{ inputs.workers }} + BASE_REF_URL: ${{ inputs.override-rpau-base-url }} + OS: ${{ runner.os }} + CONTEXT_PHRASE: 'for Cpython ${{ steps.output_python.outputs.python-version }} on ${{ runner.os }}' + SUBSHELL_TIMEOUT: ${{ inputs.max-test-time }} + run: | + # TODO: clean this up + # Custom timeout function (GH-5974 - because ulimit is restricted and windows can't ulimit at all) + run_with_timeout() { + local timeout=$1 + shift + "$@" & + local pid=$! + ( sleep "$timeout" && kill -HUP "$pid" 2>/dev/null ) & disown + # Send HUP signal after timeout + wait "$pid" + local status=$? + if [ $status -eq 0 ]; then + printf "::debug::%s\n" "Command completed successfully." + true ; # force success result + elif [ $status -eq 143 ]; then + printf "::warning title='Timeout'::%s\n" "The command \`$@\` ${CONTEXT_PHRASE} was terminated due to timeout." + false ; + else + printf "%s\n" "The command failed with status $status ${CONTEXT_PHRASE}." + false ; + fi ; + } + + export -f run_with_timeout ; + # Usage + # run_with_timeout 360 your_command_here + cd ${{ inputs.override-working-dir }} || exit 13 ; + mkdir -p Lib-rpau/test || exit 15 ; + printf "%s\n\n" "# CPython ${PYTHON_VERSION} Results" > "${TEST_STEP_SUMMARY}" ; + for reference_file in ${INPUT_FILES}; do + if [[ ( -f "${reference_file}" ) ]] ; then + # See https://devguide.python.org/testing/run-write-tests + # Heuristic: "if some module does not have unittest.main(), then most likely it does not support direct invocation." + if grep -qF "unittest.main()" "${reference_file}" 2>/dev/null ; then + printf "Now Testing '%s'\n" "${reference_file}" + # vars for subshell but not for workflow + export REF_FILE_NAME=$(basename "${reference_file}") ; + printf "::group::%s\n" "${REF_FILE_NAME}" ; + # TODO: test with cpython first for baseline + # Execute the testing command in a subshell + time ( + export RUSTPYTHONPATH=${OVERRIDE_RUSTPYTHONPATH:-Lib} ; + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" || RAW_COPY_OUTCOME='failing' + if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then + printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${reference_file}" "${reference_file}" "${CONTEXT_PHRASE}" ; + printf "::debug:: Will now attempt Rust Python Auto Patch with file %s, and pass re-tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" ; + ( + ‎ run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- -m tools/rpau/src/rpau --workers ${WORKER_COUNT} --default-version "${PYTHON_VERSION}" --base-upstream-url "${BASE_REF_URL}" --include ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" --output-dir "Lib-rpau/test" || PATCH_COPY_OUTCOME='unpatchable' ; + ) ; + if [[ ( -n ${PATCH_COPY_OUTCOME} ) ]] ; then + printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" >&2 ; + printf "::debug:: Will now attempt Auto Suppress Patch with file %s, and pass re-tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" ; + ( + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- ./scripts/fix_test.py --path ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" || FIX_COPY_OUTCOME='unfixed' ; + ) ; + if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then + printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" >&2 ; + # reset broken integration to last rustpython copy + git restore --ignore-unmerged --worktree --staged "${reference_file}" || : ; + git checkout -f --ignore-unmerged -- "${reference_file}" || : ; + # TODO: validate and conditionally set + FIX_COPY_OUTCOME="reverted" + else + PATCH_COPY_OUTCOME="unpatchable" + FIX_COPY_OUTCOME="fixed" + RAW_COPY_OUTCOME="incompatible" + fi ; + else + PATCH_COPY_OUTCOME="patched" + FIX_COPY_OUTCOME="skipped" + RAW_COPY_OUTCOME="incompatible" + fi ; + else + FIX_COPY_OUTCOME="skipped" + PATCH_COPY_OUTCOME="skipped" + RAW_COPY_OUTCOME="compatible" + fi ; + if [ -n ${RAW_COPY_OUTCOME} ]; then + if [[ "${RAW_COPY_OUTCOME}" == "compatible" ]] ; then + printf "%s\n" ":ballot_box_with_check: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + else + printf "%s\n" ":black_square_button: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + fi ; + if [ -n ${PATCH_COPY_OUTCOME} ]; then + if [[ "${PATCH_COPY_OUTCOME}" == "patched" ]] ; then + printf "%s\n\n" " :ballot_box_with_check: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; + else + printf "%s\n\n" " :grey_exclamation: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + fi ; + fi ; # end rpau + if [ -n ${FIX_COPY_OUTCOME} ]; then + if [[ "${FIX_COPY_OUTCOME}" == "fixed" ]] ; then + printf "%s\n\n" " :ballot_box_with_check: Copying and Auto-fixing the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; + else + printf "%s\n\n" " :grey_exclamation: Copying and Auto-fixing the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + fi ; # end auto-fix + else + printf "\n" >> "${TEST_STEP_SUMMARY}" ; # extra space + fi ; + fi ; # end copy + printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Patch:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${PACTH_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; + printf "FIX_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; + printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; + printf "PATCH_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${PATCH_COPY_OUTCOME}" >> "$GITHUB_ENV" ; + # should dump a diff or something here + printf "\n\n" ; + unset RUSTPYTHONPATH 2>/dev/null || : ; + ) ; + # cleanup temp env + unset FIX_COPY_OUTCOME 2>/dev/null || : ; + unset PATCH_COPY_OUTCOME 2>/dev/null || : ; + unset RAW_COPY_OUTCOME 2>/dev/null || : ; + unset REF_FILE_NAME 2>/dev/null || : ; + printf "\n::endgroup::\n" ; + wait ; + else + # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. + # TODO: cleanup this regular expression for edge-cases + if grep -qE "^[^cC]*([cC]lass)\s*(.+)(Test)" "${reference_file}" 2>/dev/null ; then + printf "Now Testing test-cases in '%s'\n" "${reference_file}" + # vars for subshell but not for workflow + export REF_TEST_NAME=$(basename -s ".py" "${reference_file}") ; + printf "%s\n" "Selected testcase test.${REF_TEST_NAME}" + printf "::group::%s\n" "${REF_FILE_NAME}" ; + # TODO: test with cpython first for baseline + # TODO: add to list of files that need additional prep due to hanging or unexpected failures that need to be removed + # Execute the testing command in a subshell + time ( + export RUSTPYTHONPATH=${OVERRIDE_RUSTPYTHONPATH:-Lib} ; + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- -m unittest -v test.${REF_TEST_NAME} || RAW_COPY_OUTCOME='failing' + if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then + printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${reference_file}" "${reference_file}" "${CONTEXT_PHRASE}" ; + printf "::debug:: Will now attempt Rust Python Auto Patch with file %s, and pass re-tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" ; + ( + ‎ run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- -m tools/rpau/src/rpau --workers ${WORKER_COUNT} --default-version "${PYTHON_VERSION}" --base-upstream-url "${BASE_REF_URL}" --include ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}".py --output-dir "Lib-rpau/test" || PATCH_COPY_OUTCOME='unpatchable' ; + ) ; + if [[ ( -n ${PATCH_COPY_OUTCOME} ) ]] ; then + ( + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- ./scripts/fix_test.py --path ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}".py || FIX_COPY_OUTCOME='unfixed' ; + ) ; + if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then + printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${reference_file}" >&2 ; + # reset broken integration to last rustpython copy + git restore --ignore-unmerged --worktree --staged "${reference_file}" || : ; + git checkout -f --ignore-unmerged -- "${reference_file}" || : ; + # TODO: validate and conditionally set + FIX_COPY_OUTCOME="reverted" + else + PATCH_COPY_OUTCOME="unpatchable" + FIX_COPY_OUTCOME="fixed" + RAW_COPY_OUTCOME="incompatible" + fi ; + else + PATCH_COPY_OUTCOME="patched" + FIX_COPY_OUTCOME="skipped" + RAW_COPY_OUTCOME="incompatible" + fi ; + else + FIX_COPY_OUTCOME="skipped" + PATCH_COPY_OUTCOME="skipped" + RAW_COPY_OUTCOME="compatible" + fi ; + if [ -n ${RAW_COPY_OUTCOME} ]; then + if [[ "${RAW_COPY_OUTCOME}" == "compatible" ]] ; then + printf "%s\n" ":ballot_box_with_check: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + else + printf "%s\n" ":black_square_button: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + fi ; + if [ -n ${PATCH_COPY_OUTCOME} ]; then + if [[ "${PATCH_COPY_OUTCOME}" == "patched" ]] ; then + printf "%s\n\n" " :ballot_box_with_check: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; + else + printf "%s\n\n" " :grey_exclamation: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + fi ; + fi ; # end rpau + if [ -n ${FIX_COPY_OUTCOME} ]; then + if [[ "${FIX_COPY_OUTCOME}" == "fixed" ]] ; then + printf "%s\n\n" " :ballot_box_with_check: Copying and Auto-fixing the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; + else + printf "%s\n\n" " :grey_exclamation: Copying and Auto-fixing the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + fi ; # end auto-fix + else + printf "\n" >> "${TEST_STEP_SUMMARY}" ; # extra space + fi ; + fi ; # end copy + printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Patch:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${PACTH_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; + printf "FIX_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; + printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; + printf "PATCH_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${PATCH_COPY_OUTCOME}" >> "$GITHUB_ENV" ; + # should dump a diff or something here + printf "\n\n" ; + unset RUSTPYTHONPATH 2>/dev/null || : ; + ) ; + # cleanup temp env + unset FIX_COPY_OUTCOME 2>/dev/null || : ; + unset PATCH_COPY_OUTCOME 2>/dev/null || : ; + unset RAW_COPY_OUTCOME 2>/dev/null || : ; + unset REF_FILE_NAME 2>/dev/null || : ; + printf "\n::endgroup::\n" ; + wait ; + else + printf "\nNow Skipping '%s'\n\n" "${reference_file}" ; + printf "%s\n" ":grey_exclamation: Directly copying the filepath \`${reference_file}\` was inconclusive (_testing and validation skipped_)." >> "${TEST_STEP_SUMMARY}" ; + printf "\n" >> "${TEST_STEP_SUMMARY}" ; # extra space + fi ; + fi ; # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. + fi ; + done + cat <"${TEST_STEP_SUMMARY}" >> "$GITHUB_STEP_SUMMARY" ; + cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; + - id: upload-rpau + name: "Upload Lib-rpau" + if: ${{ !cancelled() }} + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + path: ${{ steps.output_python.override-rustpython-path }}/Lib-rpau + name: Lib-rpau-${{ github.sha }}-${{ runner.os }}-${{ steps.output_python.outputs.python-version }} + if-no-files-found: ignore + compression-level: 6 + overwrite: true + - name: Post-Clean + id: post-bootstrap + run: | + exit 0 ; # don't break CI on regression + if: ${{ always() }} + shell: bash diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 24eaaf8d26..19cf5cb1d7 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -35,7 +35,7 @@ env: # TODO: coordinate with @moreal - to support initial use-case See RustPython/RustPython#5974 # TODO: coordinate with @arihant2math - to really build out the migration/Reporting logic -# TODO: coordinate with @ShaharNaveh - to really build out the test migration logic +# TODO: coordinate with @ShaharNaveh - see PR #6089 with RPAU jobs: TEST-5974: @@ -89,14 +89,15 @@ jobs: .github/actions/CI-5974-Fetch-CPython .github/actions/CI-5974-Integrate-CPython .github/actions/CI-5974-Test-RustPython-Integration + .github/actions/CI-6089-Test-RustPython-rapu - name: Checkout RustPython repository on ${{ matrix.os }} id: fetch-rpython uses: ./.github/actions/CI-5974-Fetch-RustPython with: override-path: rustpython override-rustpython-path: Lib - override-repository: 'RustPython/RustPython' - override-ref: main # Hint: could be changed to ${{ github.ref }} + override-repository: 'ShaharNaveh/RustPython' + override-ref: auto-updater # Hint: could be changed to ${{ github.ref }} - name: Fetch Reference Cpython ${{ matrix.python-version }} on ${{ matrix.os }} id: fetch-cpython uses: ./.github/actions/CI-5974-Fetch-CPython @@ -131,10 +132,12 @@ jobs: printf "%s\n" "::endgroup::" - name: Try Smoke Testing id: smoke_testing - uses: ./.github/actions/CI-5974-Test-RustPython-Integration + uses: ./.github/actions/CI-6089-Test-RustPython-rapu with: override-working-dir: rustpython # override-rustpython-path: 'Lib' + override-rpau-workers: 1 + override-rpau-base-url: 'https://raw.githubusercontent.com/python/cpython/refs/heads' test-files: | ${{ steps.fetch-cpython.outputs.files }} python-version: ${{ env.PYTHON_VERSION }} From aa209d4ca683c489bb2e17d2a1283331ef0193e8 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Mon, 25 Aug 2025 16:12:34 -0700 Subject: [PATCH 50/62] [DEBUG] Opps misunderstood location of tools dir. * see PR #6089 for rpau --- .../actions/CI-6089-Test-RustPython-rapu/action.yaml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml index 781c000280..1b6cf63fa8 100644 --- a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml +++ b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml @@ -161,7 +161,7 @@ runs: printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${reference_file}" "${reference_file}" "${CONTEXT_PHRASE}" ; printf "::debug:: Will now attempt Rust Python Auto Patch with file %s, and pass re-tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" ; ( - ‎ run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- -m tools/rpau/src/rpau --workers ${WORKER_COUNT} --default-version "${PYTHON_VERSION}" --base-upstream-url "${BASE_REF_URL}" --include ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" --output-dir "Lib-rpau/test" || PATCH_COPY_OUTCOME='unpatchable' ; + ‎ run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- ./tools/rpau/src/rpau/__init__.py --workers ${WORKER_COUNT} --default-version "${PYTHON_VERSION}" --base-upstream-url "${BASE_REF_URL}" --include ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" --output-dir "Lib-rpau/test" || PATCH_COPY_OUTCOME='unpatchable' ; ) ; if [[ ( -n ${PATCH_COPY_OUTCOME} ) ]] ; then printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" >&2 ; @@ -176,6 +176,7 @@ runs: git checkout -f --ignore-unmerged -- "${reference_file}" || : ; # TODO: validate and conditionally set FIX_COPY_OUTCOME="reverted" + PATCH_COPY_OUTCOME="reverted" else PATCH_COPY_OUTCOME="unpatchable" FIX_COPY_OUTCOME="fixed" @@ -199,9 +200,9 @@ runs: fi ; if [ -n ${PATCH_COPY_OUTCOME} ]; then if [[ "${PATCH_COPY_OUTCOME}" == "patched" ]] ; then - printf "%s\n\n" " :ballot_box_with_check: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; + printf "%s\n" " :ballot_box_with_check: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; else - printf "%s\n\n" " :grey_exclamation: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + printf "%s\n" " :grey_exclamation: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; fi ; fi ; # end rpau if [ -n ${FIX_COPY_OUTCOME} ]; then @@ -284,9 +285,9 @@ runs: fi ; if [ -n ${PATCH_COPY_OUTCOME} ]; then if [[ "${PATCH_COPY_OUTCOME}" == "patched" ]] ; then - printf "%s\n\n" " :ballot_box_with_check: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; + printf "%s\n" " :ballot_box_with_check: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; else - printf "%s\n\n" " :grey_exclamation: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + printf "%s\n" " :grey_exclamation: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; fi ; fi ; # end rpau if [ -n ${FIX_COPY_OUTCOME} ]; then From cf5e371cabfc53ae2cf2a2a9f663992f66c1f05e Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 27 Aug 2025 11:09:25 -0700 Subject: [PATCH 51/62] [DEBUG] Attempt to -c invoke rpau tool with modified import (WIP PR #6089 usecase) --- .github/actions/CI-6089-Test-RustPython-rapu/action.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml index 1b6cf63fa8..cb0fa1d0c0 100644 --- a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml +++ b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml @@ -161,7 +161,7 @@ runs: printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${reference_file}" "${reference_file}" "${CONTEXT_PHRASE}" ; printf "::debug:: Will now attempt Rust Python Auto Patch with file %s, and pass re-tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" ; ( - ‎ run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- ./tools/rpau/src/rpau/__init__.py --workers ${WORKER_COUNT} --default-version "${PYTHON_VERSION}" --base-upstream-url "${BASE_REF_URL}" --include ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" --output-dir "Lib-rpau/test" || PATCH_COPY_OUTCOME='unpatchable' ; + ‎ run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- -c "import sys; import os; sys.path.insert(1, os.path.abspath('tools/rpau/src')); import rpau; rpau.main()" --workers ${WORKER_COUNT} --default-version "${PYTHON_VERSION}" --base-upstream-url "${BASE_REF_URL}" --include ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" --output-dir "Lib-rpau/test" || PATCH_COPY_OUTCOME='unpatchable' ; ) ; if [[ ( -n ${PATCH_COPY_OUTCOME} ) ]] ; then printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" >&2 ; @@ -249,7 +249,7 @@ runs: printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${reference_file}" "${reference_file}" "${CONTEXT_PHRASE}" ; printf "::debug:: Will now attempt Rust Python Auto Patch with file %s, and pass re-tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" ; ( - ‎ run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- -m tools/rpau/src/rpau --workers ${WORKER_COUNT} --default-version "${PYTHON_VERSION}" --base-upstream-url "${BASE_REF_URL}" --include ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}".py --output-dir "Lib-rpau/test" || PATCH_COPY_OUTCOME='unpatchable' ; + ‎ run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- -c "import sys; import os; sys.path.insert(1, os.path.abspath('tools/rpau/src')); import rpau; rpau.main()" --workers ${WORKER_COUNT} --default-version "${PYTHON_VERSION}" --base-upstream-url "${BASE_REF_URL}" --include ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}".py --output-dir "Lib-rpau/test" || PATCH_COPY_OUTCOME='unpatchable' ; ) ; if [[ ( -n ${PATCH_COPY_OUTCOME} ) ]] ; then ( From cd3dc0a7a6ce43b2bdbdc27c68e1ca8bed55a2b8 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 27 Aug 2025 17:01:51 -0700 Subject: [PATCH 52/62] [DEBUG] possible workaround for braindead windows runners * see GHI RustPython/RustPython#5974 and PR RustPython/RustPython#6089 --- .../CI-5974-Integrate-CPython/action.yaml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/actions/CI-5974-Integrate-CPython/action.yaml b/.github/actions/CI-5974-Integrate-CPython/action.yaml index dc0d16e5f5..a2145a3304 100644 --- a/.github/actions/CI-5974-Integrate-CPython/action.yaml +++ b/.github/actions/CI-5974-Integrate-CPython/action.yaml @@ -49,6 +49,20 @@ runs: fi printf "%s\n" "PYTHON_VERSION=${PYTHON_VERSION}" >> "$GITHUB_ENV" if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::Targeting Cpython %s.\n" "${PYTHON_VERSION}" ; fi ; + - id: setup_mkdir_option + if: ${{ !cancelled() }} + shell: bash + run: | + # set mkdir options per platform + if [[ ${{ runner.os }} != 'Windows' ]] ; then + printf "mkdir-args=%s\n" "-v -p -m 751" >> "$GITHUB_OUTPUT" + printf "MKDIR_ARGS=%s\n" "-v -p -m 751" >> "$GITHUB_ENV" + else + printf "mkdir-args=%s\n" "-v -p" >> "$GITHUB_OUTPUT" + printf "MKDIR_ARGS=%s\n" "-v -p" >> "$GITHUB_ENV" + fi + shell: bash + if: ${{ !cancelled() && runner.os == 'Windows' }} - name: "Integrate Cpython Test files" id: merge_theirs shell: bash @@ -58,7 +72,7 @@ runs: run: | printf "::group::%s\n" "Copy Reference Implementation" ; for reference_file in ${INPUT_FILES}; do - [[ -d $(dirname ${{ inputs.into-path }}/"${reference_file}" ) ]] || mkdir -v -p -m 751 $(dirname ${{ inputs.into-path }}/"${reference_file}" ) ; + [[ -d $(dirname ${{ inputs.into-path }}/"${reference_file}" ) ]] || mkdir $MKDIR_ARGS $(dirname ${{ inputs.into-path }}/"${reference_file}" ) ; cp -vf ${{ inputs.from-path }}/"${reference_file}" ${{ inputs.into-path }}/"${reference_file}" || printf "::warning file='%s',title='integration failure':: Could not integrate file for Cpython %s on %s.\n" "${reference_file}" '${PYTHON_VERSION}' '${{ runner.os }}' ; done ; printf "\n::endgroup::\n\n" ; From 42254c738ac908331040271b5b830d4b6ef8e1de Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 27 Aug 2025 17:08:58 -0700 Subject: [PATCH 53/62] [DEBUG] Minor Regression fix for double entries. Oops. * see GHI RustPython#5974 and PR RustPython#6089 --- .github/actions/CI-5974-Integrate-CPython/action.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/actions/CI-5974-Integrate-CPython/action.yaml b/.github/actions/CI-5974-Integrate-CPython/action.yaml index a2145a3304..39d49a87b3 100644 --- a/.github/actions/CI-5974-Integrate-CPython/action.yaml +++ b/.github/actions/CI-5974-Integrate-CPython/action.yaml @@ -61,8 +61,6 @@ runs: printf "mkdir-args=%s\n" "-v -p" >> "$GITHUB_OUTPUT" printf "MKDIR_ARGS=%s\n" "-v -p" >> "$GITHUB_ENV" fi - shell: bash - if: ${{ !cancelled() && runner.os == 'Windows' }} - name: "Integrate Cpython Test files" id: merge_theirs shell: bash From 8b8398bf19ecb0e2ca9885803dd795301a47197e Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 27 Aug 2025 17:45:55 -0700 Subject: [PATCH 54/62] [STYLE] Cleaning up the report for CI runs a bit. * see GHI RustPython#5974 and PR RustPython#6089 --- .github/actions/CI-6089-Test-RustPython-rapu/action.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml index cb0fa1d0c0..d917c27d5d 100644 --- a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml +++ b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml @@ -202,7 +202,7 @@ runs: if [[ "${PATCH_COPY_OUTCOME}" == "patched" ]] ; then printf "%s\n" " :ballot_box_with_check: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; else - printf "%s\n" " :grey_exclamation: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + printf "%s\n" " :grey_exclamation: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was ${PATCH_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; fi ; fi ; # end rpau if [ -n ${FIX_COPY_OUTCOME} ]; then @@ -215,7 +215,7 @@ runs: printf "\n" >> "${TEST_STEP_SUMMARY}" ; # extra space fi ; fi ; # end copy - printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Patch:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${PACTH_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; + printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Patch:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${PATCH_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; printf "FIX_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; printf "PATCH_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${PATCH_COPY_OUTCOME}" >> "$GITHUB_ENV" ; @@ -287,7 +287,7 @@ runs: if [[ "${PATCH_COPY_OUTCOME}" == "patched" ]] ; then printf "%s\n" " :ballot_box_with_check: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; else - printf "%s\n" " :grey_exclamation: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + printf "%s\n" " :grey_exclamation: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was ${PATCH_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; fi ; fi ; # end rpau if [ -n ${FIX_COPY_OUTCOME} ]; then @@ -300,7 +300,7 @@ runs: printf "\n" >> "${TEST_STEP_SUMMARY}" ; # extra space fi ; fi ; # end copy - printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Patch:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${PACTH_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; + printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Patch:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${PATCH_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; printf "FIX_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; printf "PATCH_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${PATCH_COPY_OUTCOME}" >> "$GITHUB_ENV" ; From e79c13b9809dfdb8a0d4f2d7da08f0f282747150 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 27 Aug 2025 17:51:38 -0700 Subject: [PATCH 55/62] [DEBUG] Adjust output path to upload at end * see GHI RustPython#5974 and PR RustPython#6089 --- .github/actions/CI-6089-Test-RustPython-rapu/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml index d917c27d5d..6d41a823e9 100644 --- a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml +++ b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml @@ -330,7 +330,7 @@ runs: if: ${{ !cancelled() }} uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: - path: ${{ steps.output_python.override-rustpython-path }}/Lib-rpau + path: '${{ inputs.override-working-dir }}/Lib-rpau' name: Lib-rpau-${{ github.sha }}-${{ runner.os }}-${{ steps.output_python.outputs.python-version }} if-no-files-found: ignore compression-level: 6 From b21103202f45448df3670ad2f82481d4e0a6b34f Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 28 Aug 2025 11:59:10 -0700 Subject: [PATCH 56/62] [PATCH] workaround for elusive patched files * see PR RustPython/RustPython#6089 and GHI RustPython/RustPython#5974 --- .../CI-6089-Test-RustPython-rapu/action.yaml | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml index 6d41a823e9..4439fa9bca 100644 --- a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml +++ b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml @@ -102,6 +102,14 @@ runs: cd ${PWD:-.} ; export OLD_PWD=$(pwd) ; # only local use for bootstrap printf "initial-path=%s\n" "${OLD_PWD}" >> "$GITHUB_OUTPUT" + - id: setup_output_dir + name: Setup Output + if: ${{ !cancelled() && inputs.override-working-dir != '' }} + shell: bash + run: | + cd ${{ inputs.override-working-dir }} || exit 13 ; + mkdir -v -p "${OVERRIDE_RUSTPYTHONPATH:-Lib}-rpau"/test || exit 19 ; + cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; - name: "Try Smoke Testing" id: smoke_test shell: bash @@ -141,7 +149,6 @@ runs: # Usage # run_with_timeout 360 your_command_here cd ${{ inputs.override-working-dir }} || exit 13 ; - mkdir -p Lib-rpau/test || exit 15 ; printf "%s\n\n" "# CPython ${PYTHON_VERSION} Results" > "${TEST_STEP_SUMMARY}" ; for reference_file in ${INPUT_FILES}; do if [[ ( -f "${reference_file}" ) ]] ; then @@ -161,7 +168,7 @@ runs: printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${reference_file}" "${reference_file}" "${CONTEXT_PHRASE}" ; printf "::debug:: Will now attempt Rust Python Auto Patch with file %s, and pass re-tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" ; ( - ‎ run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- -c "import sys; import os; sys.path.insert(1, os.path.abspath('tools/rpau/src')); import rpau; rpau.main()" --workers ${WORKER_COUNT} --default-version "${PYTHON_VERSION}" --base-upstream-url "${BASE_REF_URL}" --include ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" --output-dir "Lib-rpau/test" || PATCH_COPY_OUTCOME='unpatchable' ; + ‎ run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- -c "import sys; import os; sys.path.insert(1, os.path.abspath('tools/rpau/src')); import rpau; rpau.main()" --workers ${WORKER_COUNT} --default-version "${PYTHON_VERSION}" --base-upstream-url "${BASE_REF_URL}" --include ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" --output-dir "${RUSTPYTHONPATH:-Lib}-rpau/test" || PATCH_COPY_OUTCOME='unpatchable' ; ) ; if [[ ( -n ${PATCH_COPY_OUTCOME} ) ]] ; then printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" >&2 ; @@ -325,12 +332,30 @@ runs: done cat <"${TEST_STEP_SUMMARY}" >> "$GITHUB_STEP_SUMMARY" ; cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; + - name: Enumerate Patched Lib Files + id: output_patched_files + shell: bash + env: + TEST_MATCH_PATTERN: '**/Lib-rpau/' + run: | + FILES=$(find . -type d -ipath ${{ env.TEST_MATCH_PATTERN }} -print 2>/dev/null ; ) + if [ -z "$FILES" ]; then + printf "%s\n" "::warning file=.github/actions/:: No Patched files found." ; + printf "%s\n" "files=" >> "$GITHUB_OUTPUT" + else + printf "%s\n" "Reference files found:" + printf "%s\n" "$FILES" + # Replace line breaks with commas for GitHub Action Output + FILES="${FILES//$'\n'/ }" + printf "%s\n" "files=$FILES" >> "$GITHUB_OUTPUT" + fi + if: ${{ success() }} - id: upload-rpau name: "Upload Lib-rpau" if: ${{ !cancelled() }} uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: - path: '${{ inputs.override-working-dir }}/Lib-rpau' + path: '${{ steps.output_patched_files.outputs.files }}' name: Lib-rpau-${{ github.sha }}-${{ runner.os }}-${{ steps.output_python.outputs.python-version }} if-no-files-found: ignore compression-level: 6 From d65b89020094a31d703122113abe04dabfdb5a05 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Sat, 30 Aug 2025 17:48:14 -0700 Subject: [PATCH 57/62] Testing based on examples from PR RustPython/RustPython#6089 --- .github/actions/CI-6089-Test-RustPython-rapu/action.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml index 4439fa9bca..77f1d48305 100644 --- a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml +++ b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml @@ -168,7 +168,7 @@ runs: printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${reference_file}" "${reference_file}" "${CONTEXT_PHRASE}" ; printf "::debug:: Will now attempt Rust Python Auto Patch with file %s, and pass re-tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" ; ( - ‎ run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- -c "import sys; import os; sys.path.insert(1, os.path.abspath('tools/rpau/src')); import rpau; rpau.main()" --workers ${WORKER_COUNT} --default-version "${PYTHON_VERSION}" --base-upstream-url "${BASE_REF_URL}" --include ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" --output-dir "${RUSTPYTHONPATH:-Lib}-rpau/test" || PATCH_COPY_OUTCOME='unpatchable' ; + ‎ run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- ./scripts/lib_updater.py --from ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" --show-patches --output "${RUSTPYTHONPATH:-Lib}-rpau/test/${REF_FILE_NAME}" >> "${RUSTPYTHONPATH:-Lib}-rpau/JSON/${REF_FILE_NAME}.json" || PATCH_COPY_OUTCOME='unpatchable' ; ) ; if [[ ( -n ${PATCH_COPY_OUTCOME} ) ]] ; then printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" >&2 ; @@ -256,7 +256,7 @@ runs: printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${reference_file}" "${reference_file}" "${CONTEXT_PHRASE}" ; printf "::debug:: Will now attempt Rust Python Auto Patch with file %s, and pass re-tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" ; ( - ‎ run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- -c "import sys; import os; sys.path.insert(1, os.path.abspath('tools/rpau/src')); import rpau; rpau.main()" --workers ${WORKER_COUNT} --default-version "${PYTHON_VERSION}" --base-upstream-url "${BASE_REF_URL}" --include ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}".py --output-dir "Lib-rpau/test" || PATCH_COPY_OUTCOME='unpatchable' ; + run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- ./scripts/lib_updater.py --from ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" --show-patches --output "${RUSTPYTHONPATH:-Lib}-rpau/test/${REF_FILE_NAME}" >> "${RUSTPYTHONPATH:-Lib}-rpau/JSON/test.${REF_TEST_NAME}.json" || PATCH_COPY_OUTCOME='unpatchable' ; ) ; if [[ ( -n ${PATCH_COPY_OUTCOME} ) ]] ; then ( From e20f6c58aee42842ba13d4505510b9888302ab73 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Sat, 30 Aug 2025 17:58:01 -0700 Subject: [PATCH 58/62] Oops! forgot to mkdir in setup phase re-try test. * see GHI RustPython/RustPython#5974 and PR RustPython/RustPython#6089 --- .github/actions/CI-6089-Test-RustPython-rapu/action.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml index 77f1d48305..07fb9b361b 100644 --- a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml +++ b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml @@ -109,6 +109,7 @@ runs: run: | cd ${{ inputs.override-working-dir }} || exit 13 ; mkdir -v -p "${OVERRIDE_RUSTPYTHONPATH:-Lib}-rpau"/test || exit 19 ; + mkdir -v -p "${OVERRIDE_RUSTPYTHONPATH:-Lib}-rpau"/JSON || exit 20 ; cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; - name: "Try Smoke Testing" id: smoke_test From 3dd549fd26722ed482da23ece30dbe1c15fbd030 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 3 Sep 2025 16:12:29 -0700 Subject: [PATCH 59/62] Test for new Lib_updater.py script in integration phase (for Lib/test file patching) * see PR RustPython/RustPython#6089 * see GHI RustPython/RustPython#5974 --- .../CI-5974-Integrate-CPython/action.yaml | 8 +- .../CI-6089-Test-RustPython-rapu/action.yaml | 369 ------------------ .github/workflows/Check_Tests.yml | 7 +- 3 files changed, 9 insertions(+), 375 deletions(-) delete mode 100644 .github/actions/CI-6089-Test-RustPython-rapu/action.yaml diff --git a/.github/actions/CI-5974-Integrate-CPython/action.yaml b/.github/actions/CI-5974-Integrate-CPython/action.yaml index 39d49a87b3..16918a3226 100644 --- a/.github/actions/CI-5974-Integrate-CPython/action.yaml +++ b/.github/actions/CI-5974-Integrate-CPython/action.yaml @@ -71,6 +71,12 @@ runs: printf "::group::%s\n" "Copy Reference Implementation" ; for reference_file in ${INPUT_FILES}; do [[ -d $(dirname ${{ inputs.into-path }}/"${reference_file}" ) ]] || mkdir $MKDIR_ARGS $(dirname ${{ inputs.into-path }}/"${reference_file}" ) ; - cp -vf ${{ inputs.from-path }}/"${reference_file}" ${{ inputs.into-path }}/"${reference_file}" || printf "::warning file='%s',title='integration failure':: Could not integrate file for Cpython %s on %s.\n" "${reference_file}" '${PYTHON_VERSION}' '${{ runner.os }}' ; + if [[ "$reference_file" == Lib/test/* ]] ; then + # update patches with lib_updater tool from #6089 + ${{ inputs.into-path }}/scripts/lib_updater.py --from ${{ inputs.into-path }}/"${reference_file}" --to ${{ inputs.from-path }}/"${reference_file}" -o ${{ inputs.into-path }}/"${reference_file}" || \ + printf "::warning file='%s',title='integration failure':: Could not integrate file for Cpython %s on %s.\n" "${reference_file}" '${PYTHON_VERSION}' '${{ runner.os }}' ; + else + cp -vf ${{ inputs.from-path }}/"${reference_file}" ${{ inputs.into-path }}/"${reference_file}" || printf "::warning file='%s',title='integration failure':: Could not integrate file for Cpython %s on %s.\n" "${reference_file}" '${PYTHON_VERSION}' '${{ runner.os }}' ; + fi done ; printf "\n::endgroup::\n\n" ; diff --git a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml b/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml deleted file mode 100644 index 07fb9b361b..0000000000 --- a/.github/actions/CI-6089-Test-RustPython-rapu/action.yaml +++ /dev/null @@ -1,369 +0,0 @@ ---- -name: 'RustPython Auto Patching' -description: 'R.ust P.ython A.utomated U.pdater Integration' -author: 'Mr. Walls & RustPython Team' -branding: - icon: 'check-circle' - color: 'red' -inputs: - override-working-dir: - description: | - Path to integrated RustPython clone to smoke test and auto-patch. Default is 'rustpython' - required: true - default: ${{ github.server_url == 'https://github.com' && 'rustpython' || '' }} - override-rustpython-path: - description: | - override value for path to the Python Lib. The default is to use the value of the environment - variable 'RUSTPYTHONPATH'. Most users will find the default 'Lib' sufficient. - required: true - override-rpau-workers: - description: | - override value for number of workers for rpau to use. Must be an integer ≥1. - required: true - default: '1' - override-rpau-base-url: - description: | - override value for where to base auto-patches on. Default is - 'https://raw.githubusercontent.com/python/cpython/refs/heads' - required: true - default: 'https://raw.githubusercontent.com/python/cpython/refs/heads' - test-files: - description: | - List of paths to CPython Test files from source to destination. Default is 'Lib/test/*.py' - required: true - default: 'Lib/test/*.py' - python-version: - description: | - The Cpython version (e.g., any valid release or tag, 3.11, 3.12, 3.13) to override. Note - Python 3.12+ is required for R.P.A.U. function. - The default is to use the value of the environment variable 'PYTHON_VERSION'. - default: '3.13' - required: true - max-test-time: - description: | - The max time in seconds per test module file run before aborting a test attempt. The default - is deliberately short at a value of 30 seconds to keep total run-time down. - default: '30' - required: true - -# TODO: add verification steps - -runs: - using: composite - steps: - - id: output_python - env: - PYTHON_VERSION_INPUT: ${{ inputs.python-version }} - OVERRIDE_RUSTPYTHONPATH_INPUT: ${{ inputs.override-rustpython-path }} - name: "Detect Python" - if: ${{ !cancelled() && inputs.test-files != '' }} - shell: bash - run: | - printf "%s\n" "::group::detect-python-env" - if [[ -n $PYTHON_VERSION_INPUT ]]; then - printf "python-version=%s\n" "${PYTHON_VERSION_INPUT}" >> "$GITHUB_OUTPUT" - PYTHON_VERSION=${PYTHON_VERSION_INPUT} - else - printf "python-version=%s\n" "${PYTHON_VERSION}" >> "$GITHUB_OUTPUT" - fi - if [[ -n $OVERRIDE_RUSTPYTHONPATH_INPUT ]]; then - printf "override-rustpython-path=%s\n" "${OVERRIDE_RUSTPYTHONPATH_INPUT}" >> "$GITHUB_OUTPUT" - OVERRIDE_RUSTPYTHONPATH=${RUSTPYTHONPATH} - else - printf "override-rustpython-path=%s\n" "${RUSTPYTHONPATH:-Lib}" >> "$GITHUB_OUTPUT" - OVERRIDE_RUSTPYTHONPATH="${RUSTPYTHONPATH:-Lib}" - fi - printf "%s\n" "PYTHON_VERSION=${PYTHON_VERSION}" >> "$GITHUB_ENV" - printf "%s\n" "OVERRIDE_RUSTPYTHONPATH=${OVERRIDE_RUSTPYTHONPATH}" >> "$GITHUB_ENV" - printf "Targeting Cpython %s on %s.\n" '${PYTHON_VERSION}' '${{ runner.os }}' ; - printf "%s\n" "::endgroup::" - - name: "Check Cargo Setup" - id: output_cargo_args - shell: bash - run: | - if [[ -n $CARGO_ARGS ]]; then - if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS already set to '%s'\n" "${CARGO_ARGS}" ; fi ; - # e.g., CARGO_ARGS=${CARGO_ARGS} - else - CARGO_ARGS="--release" ; - if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::CARGO_ARGS initialized to '%s'\n" "${CARGO_ARGS}" ; fi ; - fi ; - printf "%s\n" "CARGO_ARGS=${CARGO_ARGS}" >> "$GITHUB_ENV" ; - - name: "Prepare Artifact Name" - id: output_artifact_name - if: ${{ !cancelled() }} - shell: bash - run: | - printf "%s\n" "TEST_STEP_SUMMARY=CPython-Summary-Artifact-${{ runner.os }}-${PYTHON_VERSION}.md" >> "$GITHUB_ENV" - - id: store_old_path - if: ${{ !cancelled() }} - shell: bash - run: | - cd ${PWD:-.} ; - export OLD_PWD=$(pwd) ; # only local use for bootstrap - printf "initial-path=%s\n" "${OLD_PWD}" >> "$GITHUB_OUTPUT" - - id: setup_output_dir - name: Setup Output - if: ${{ !cancelled() && inputs.override-working-dir != '' }} - shell: bash - run: | - cd ${{ inputs.override-working-dir }} || exit 13 ; - mkdir -v -p "${OVERRIDE_RUSTPYTHONPATH:-Lib}-rpau"/test || exit 19 ; - mkdir -v -p "${OVERRIDE_RUSTPYTHONPATH:-Lib}-rpau"/JSON || exit 20 ; - cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; - - name: "Try Smoke Testing" - id: smoke_test - shell: bash - if: ${{ !cancelled() && inputs.test-files != '' }} - env: - INPUT_FILES: ${{ inputs.test-files }} - WORKER_COUNT: ${{ inputs.workers }} - BASE_REF_URL: ${{ inputs.override-rpau-base-url }} - OS: ${{ runner.os }} - CONTEXT_PHRASE: 'for Cpython ${{ steps.output_python.outputs.python-version }} on ${{ runner.os }}' - SUBSHELL_TIMEOUT: ${{ inputs.max-test-time }} - run: | - # TODO: clean this up - # Custom timeout function (GH-5974 - because ulimit is restricted and windows can't ulimit at all) - run_with_timeout() { - local timeout=$1 - shift - "$@" & - local pid=$! - ( sleep "$timeout" && kill -HUP "$pid" 2>/dev/null ) & disown - # Send HUP signal after timeout - wait "$pid" - local status=$? - if [ $status -eq 0 ]; then - printf "::debug::%s\n" "Command completed successfully." - true ; # force success result - elif [ $status -eq 143 ]; then - printf "::warning title='Timeout'::%s\n" "The command \`$@\` ${CONTEXT_PHRASE} was terminated due to timeout." - false ; - else - printf "%s\n" "The command failed with status $status ${CONTEXT_PHRASE}." - false ; - fi ; - } - - export -f run_with_timeout ; - # Usage - # run_with_timeout 360 your_command_here - cd ${{ inputs.override-working-dir }} || exit 13 ; - printf "%s\n\n" "# CPython ${PYTHON_VERSION} Results" > "${TEST_STEP_SUMMARY}" ; - for reference_file in ${INPUT_FILES}; do - if [[ ( -f "${reference_file}" ) ]] ; then - # See https://devguide.python.org/testing/run-write-tests - # Heuristic: "if some module does not have unittest.main(), then most likely it does not support direct invocation." - if grep -qF "unittest.main()" "${reference_file}" 2>/dev/null ; then - printf "Now Testing '%s'\n" "${reference_file}" - # vars for subshell but not for workflow - export REF_FILE_NAME=$(basename "${reference_file}") ; - printf "::group::%s\n" "${REF_FILE_NAME}" ; - # TODO: test with cpython first for baseline - # Execute the testing command in a subshell - time ( - export RUSTPYTHONPATH=${OVERRIDE_RUSTPYTHONPATH:-Lib} ; - run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" || RAW_COPY_OUTCOME='failing' - if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then - printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${reference_file}" "${reference_file}" "${CONTEXT_PHRASE}" ; - printf "::debug:: Will now attempt Rust Python Auto Patch with file %s, and pass re-tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" ; - ( - ‎ run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- ./scripts/lib_updater.py --from ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" --show-patches --output "${RUSTPYTHONPATH:-Lib}-rpau/test/${REF_FILE_NAME}" >> "${RUSTPYTHONPATH:-Lib}-rpau/JSON/${REF_FILE_NAME}.json" || PATCH_COPY_OUTCOME='unpatchable' ; - ) ; - if [[ ( -n ${PATCH_COPY_OUTCOME} ) ]] ; then - printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" >&2 ; - printf "::debug:: Will now attempt Auto Suppress Patch with file %s, and pass re-tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" ; - ( - run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- ./scripts/fix_test.py --path ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" || FIX_COPY_OUTCOME='unfixed' ; - ) ; - if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then - printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" >&2 ; - # reset broken integration to last rustpython copy - git restore --ignore-unmerged --worktree --staged "${reference_file}" || : ; - git checkout -f --ignore-unmerged -- "${reference_file}" || : ; - # TODO: validate and conditionally set - FIX_COPY_OUTCOME="reverted" - PATCH_COPY_OUTCOME="reverted" - else - PATCH_COPY_OUTCOME="unpatchable" - FIX_COPY_OUTCOME="fixed" - RAW_COPY_OUTCOME="incompatible" - fi ; - else - PATCH_COPY_OUTCOME="patched" - FIX_COPY_OUTCOME="skipped" - RAW_COPY_OUTCOME="incompatible" - fi ; - else - FIX_COPY_OUTCOME="skipped" - PATCH_COPY_OUTCOME="skipped" - RAW_COPY_OUTCOME="compatible" - fi ; - if [ -n ${RAW_COPY_OUTCOME} ]; then - if [[ "${RAW_COPY_OUTCOME}" == "compatible" ]] ; then - printf "%s\n" ":ballot_box_with_check: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; - else - printf "%s\n" ":black_square_button: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; - fi ; - if [ -n ${PATCH_COPY_OUTCOME} ]; then - if [[ "${PATCH_COPY_OUTCOME}" == "patched" ]] ; then - printf "%s\n" " :ballot_box_with_check: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; - else - printf "%s\n" " :grey_exclamation: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was ${PATCH_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; - fi ; - fi ; # end rpau - if [ -n ${FIX_COPY_OUTCOME} ]; then - if [[ "${FIX_COPY_OUTCOME}" == "fixed" ]] ; then - printf "%s\n\n" " :ballot_box_with_check: Copying and Auto-fixing the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; - else - printf "%s\n\n" " :grey_exclamation: Copying and Auto-fixing the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; - fi ; # end auto-fix - else - printf "\n" >> "${TEST_STEP_SUMMARY}" ; # extra space - fi ; - fi ; # end copy - printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Patch:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${PATCH_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; - printf "FIX_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; - printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; - printf "PATCH_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${PATCH_COPY_OUTCOME}" >> "$GITHUB_ENV" ; - # should dump a diff or something here - printf "\n\n" ; - unset RUSTPYTHONPATH 2>/dev/null || : ; - ) ; - # cleanup temp env - unset FIX_COPY_OUTCOME 2>/dev/null || : ; - unset PATCH_COPY_OUTCOME 2>/dev/null || : ; - unset RAW_COPY_OUTCOME 2>/dev/null || : ; - unset REF_FILE_NAME 2>/dev/null || : ; - printf "\n::endgroup::\n" ; - wait ; - else - # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. - # TODO: cleanup this regular expression for edge-cases - if grep -qE "^[^cC]*([cC]lass)\s*(.+)(Test)" "${reference_file}" 2>/dev/null ; then - printf "Now Testing test-cases in '%s'\n" "${reference_file}" - # vars for subshell but not for workflow - export REF_TEST_NAME=$(basename -s ".py" "${reference_file}") ; - printf "%s\n" "Selected testcase test.${REF_TEST_NAME}" - printf "::group::%s\n" "${REF_FILE_NAME}" ; - # TODO: test with cpython first for baseline - # TODO: add to list of files that need additional prep due to hanging or unexpected failures that need to be removed - # Execute the testing command in a subshell - time ( - export RUSTPYTHONPATH=${OVERRIDE_RUSTPYTHONPATH:-Lib} ; - run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- -m unittest -v test.${REF_TEST_NAME} || RAW_COPY_OUTCOME='failing' - if [[ ( -n ${RAW_COPY_OUTCOME} ) ]] ; then - printf "::warning file='%s',title='test-warning':: Could not copy file %s unmodified, and pass tests %s.\n" "${reference_file}" "${reference_file}" "${CONTEXT_PHRASE}" ; - printf "::debug:: Will now attempt Rust Python Auto Patch with file %s, and pass re-tests %s.\n" "${reference_file}" "${CONTEXT_PHRASE}" ; - ( - run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- ./scripts/lib_updater.py --from ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}" --show-patches --output "${RUSTPYTHONPATH:-Lib}-rpau/test/${REF_FILE_NAME}" >> "${RUSTPYTHONPATH:-Lib}-rpau/JSON/test.${REF_TEST_NAME}.json" || PATCH_COPY_OUTCOME='unpatchable' ; - ) ; - if [[ ( -n ${PATCH_COPY_OUTCOME} ) ]] ; then - ( - run_with_timeout ${SUBSHELL_TIMEOUT} cargo run $CARGO_ARGS -- ./scripts/fix_test.py --path ${RUSTPYTHONPATH:-Lib}/test/"${REF_FILE_NAME}".py || FIX_COPY_OUTCOME='unfixed' ; - ) ; - if [[ ( -n ${FIX_COPY_OUTCOME} ) ]] ; then - printf "::error file='%s',title='testing-failure':: Could not copy and auto-fix tests for file.\n" "${reference_file}" >&2 ; - # reset broken integration to last rustpython copy - git restore --ignore-unmerged --worktree --staged "${reference_file}" || : ; - git checkout -f --ignore-unmerged -- "${reference_file}" || : ; - # TODO: validate and conditionally set - FIX_COPY_OUTCOME="reverted" - else - PATCH_COPY_OUTCOME="unpatchable" - FIX_COPY_OUTCOME="fixed" - RAW_COPY_OUTCOME="incompatible" - fi ; - else - PATCH_COPY_OUTCOME="patched" - FIX_COPY_OUTCOME="skipped" - RAW_COPY_OUTCOME="incompatible" - fi ; - else - FIX_COPY_OUTCOME="skipped" - PATCH_COPY_OUTCOME="skipped" - RAW_COPY_OUTCOME="compatible" - fi ; - if [ -n ${RAW_COPY_OUTCOME} ]; then - if [[ "${RAW_COPY_OUTCOME}" == "compatible" ]] ; then - printf "%s\n" ":ballot_box_with_check: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; - else - printf "%s\n" ":black_square_button: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; - fi ; - if [ -n ${PATCH_COPY_OUTCOME} ]; then - if [[ "${PATCH_COPY_OUTCOME}" == "patched" ]] ; then - printf "%s\n" " :ballot_box_with_check: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; - else - printf "%s\n" " :grey_exclamation: Copying and RustPython Auto-Patching the test file \`${reference_file}\` was ${PATCH_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; - fi ; - fi ; # end rpau - if [ -n ${FIX_COPY_OUTCOME} ]; then - if [[ "${FIX_COPY_OUTCOME}" == "fixed" ]] ; then - printf "%s\n\n" " :ballot_box_with_check: Copying and Auto-fixing the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; - else - printf "%s\n\n" " :grey_exclamation: Copying and Auto-fixing the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; - fi ; # end auto-fix - else - printf "\n" >> "${TEST_STEP_SUMMARY}" ; # extra space - fi ; - fi ; # end copy - printf "\n---\n%s Outcome:\n\tDirectly:%s\n\tAuto-Patch:%s\n\tAuto-Fix:%s\n\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" "${PATCH_COPY_OUTCOME}" "${FIX_COPY_OUTCOME}" ; - printf "FIX_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${FIX_COPY_OUTCOME}" >> "$GITHUB_ENV" ; - printf "RAW_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${RAW_COPY_OUTCOME}" >> "$GITHUB_ENV" ; - printf "PATCH_COPY_%s_OUTCOME=%s\n" "${REF_FILE_NAME}" "${PATCH_COPY_OUTCOME}" >> "$GITHUB_ENV" ; - # should dump a diff or something here - printf "\n\n" ; - unset RUSTPYTHONPATH 2>/dev/null || : ; - ) ; - # cleanup temp env - unset FIX_COPY_OUTCOME 2>/dev/null || : ; - unset PATCH_COPY_OUTCOME 2>/dev/null || : ; - unset RAW_COPY_OUTCOME 2>/dev/null || : ; - unset REF_FILE_NAME 2>/dev/null || : ; - printf "\n::endgroup::\n" ; - wait ; - else - printf "\nNow Skipping '%s'\n\n" "${reference_file}" ; - printf "%s\n" ":grey_exclamation: Directly copying the filepath \`${reference_file}\` was inconclusive (_testing and validation skipped_)." >> "${TEST_STEP_SUMMARY}" ; - printf "\n" >> "${TEST_STEP_SUMMARY}" ; # extra space - fi ; - fi ; # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. - fi ; - done - cat <"${TEST_STEP_SUMMARY}" >> "$GITHUB_STEP_SUMMARY" ; - cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; - - name: Enumerate Patched Lib Files - id: output_patched_files - shell: bash - env: - TEST_MATCH_PATTERN: '**/Lib-rpau/' - run: | - FILES=$(find . -type d -ipath ${{ env.TEST_MATCH_PATTERN }} -print 2>/dev/null ; ) - if [ -z "$FILES" ]; then - printf "%s\n" "::warning file=.github/actions/:: No Patched files found." ; - printf "%s\n" "files=" >> "$GITHUB_OUTPUT" - else - printf "%s\n" "Reference files found:" - printf "%s\n" "$FILES" - # Replace line breaks with commas for GitHub Action Output - FILES="${FILES//$'\n'/ }" - printf "%s\n" "files=$FILES" >> "$GITHUB_OUTPUT" - fi - if: ${{ success() }} - - id: upload-rpau - name: "Upload Lib-rpau" - if: ${{ !cancelled() }} - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - path: '${{ steps.output_patched_files.outputs.files }}' - name: Lib-rpau-${{ github.sha }}-${{ runner.os }}-${{ steps.output_python.outputs.python-version }} - if-no-files-found: ignore - compression-level: 6 - overwrite: true - - name: Post-Clean - id: post-bootstrap - run: | - exit 0 ; # don't break CI on regression - if: ${{ always() }} - shell: bash diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 19cf5cb1d7..538d808aaa 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -89,7 +89,6 @@ jobs: .github/actions/CI-5974-Fetch-CPython .github/actions/CI-5974-Integrate-CPython .github/actions/CI-5974-Test-RustPython-Integration - .github/actions/CI-6089-Test-RustPython-rapu - name: Checkout RustPython repository on ${{ matrix.os }} id: fetch-rpython uses: ./.github/actions/CI-5974-Fetch-RustPython @@ -102,7 +101,7 @@ jobs: id: fetch-cpython uses: ./.github/actions/CI-5974-Fetch-CPython with: - # Define the reference files to pull as a file glob pattern + # Define the reference files to pull as a file glob pattern (defaults to ONLY tests) match: "Lib/test/*.py Lib/test/**/*.py" # ignore: "Lib/test/*.pyc" python-version: ${{ matrix.python-version }} @@ -132,12 +131,10 @@ jobs: printf "%s\n" "::endgroup::" - name: Try Smoke Testing id: smoke_testing - uses: ./.github/actions/CI-6089-Test-RustPython-rapu + uses: ./.github/actions/CI-5974-Test-RustPython-Integration with: override-working-dir: rustpython # override-rustpython-path: 'Lib' - override-rpau-workers: 1 - override-rpau-base-url: 'https://raw.githubusercontent.com/python/cpython/refs/heads' test-files: | ${{ steps.fetch-cpython.outputs.files }} python-version: ${{ env.PYTHON_VERSION }} From 64728dfc1e0b6a199d5c8dc4e883938dc9c5267f Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Sun, 28 Sep 2025 12:27:34 -0700 Subject: [PATCH 60/62] [PATCH] Template Regression check in CI/CD * see GHI RustPython/RustPython#5974 --- .../action.yaml | 27 ++++++++++++------- .github/workflows/Check_Tests.yml | 4 +-- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml index dca3b39865..4271feccdd 100644 --- a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml +++ b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml @@ -165,15 +165,19 @@ runs: fi ; if [ -n ${RAW_COPY_OUTCOME} ]; then if [[ "${RAW_COPY_OUTCOME}" == "compatible" ]] ; then - printf "%s\n" ":ballot_box_with_check: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + # printf "%s\n" ":ballot_box_with_check: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + printf "## %s\n| Direct copy | :ballot_box_with_check: %s |\n" "\`${reference_file}\`" "${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; else - printf "%s\n" ":black_square_button: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + # printf "%s\n" ":black_square_button: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + printf "## %s\n| Direct copy | :black_square_button: %s |\n" "\`${reference_file}\`" "${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; fi ; if [ -n ${FIX_COPY_OUTCOME} ]; then if [[ "${FIX_COPY_OUTCOME}" == "fixed" ]] ; then - printf "%s\n\n" " :ballot_box_with_check: Copying and Auto-fixing the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; + # printf "%s\n\n" " :ballot_box_with_check: Copying and Auto-fixing the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; + printf "| Auto‑fix | :ballot_box_with_check: %s |\n\n" "successful" >> "${TEST_STEP_SUMMARY}" ; else - printf "%s\n\n" " :grey_exclamation: Copying and Auto-fixing the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + # printf "%s\n\n" " :grey_exclamation: Copying and Auto-fixing the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + printf "| Auto‑fix | :grey_exclamation: %s |\n\n" "${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; fi ; # end auto-fix else printf "\n" >> "${TEST_STEP_SUMMARY}" ; # extra space @@ -229,15 +233,19 @@ runs: fi ; if [ -n ${RAW_COPY_OUTCOME} ]; then if [[ "${RAW_COPY_OUTCOME}" == "compatible" ]] ; then - printf "%s\n" ":ballot_box_with_check: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + # printf "%s\n" ":ballot_box_with_check: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + printf "## %s\n| Direct copy | :ballot_box_with_check: %s |\n" "\`${reference_file}\`" "${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; else - printf "%s\n" ":black_square_button: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + # printf "%s\n" ":black_square_button: Directly copying the test file \`${reference_file}\` is ${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + printf "## %s\n| Direct copy | :black_square_button: %s |\n" "\`${reference_file}\`" "${RAW_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; fi ; if [ -n ${FIX_COPY_OUTCOME} ]; then if [[ "${FIX_COPY_OUTCOME}" == "fixed" ]] ; then - printf "%s\n\n" " :ballot_box_with_check: Copying and Auto-fixing the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; + # printf "%s\n\n" " :ballot_box_with_check: Copying and Auto-fixing the test file \`${reference_file}\` was successful" >> "${TEST_STEP_SUMMARY}" ; + printf "| Auto‑fix | :ballot_box_with_check: %s |\n\n" "successful" >> "${TEST_STEP_SUMMARY}" ; else - printf "%s\n\n" " :grey_exclamation: Copying and Auto-fixing the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + # printf "%s\n\n" " :grey_exclamation: Copying and Auto-fixing the test file \`${reference_file}\` was ${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; + printf "| Auto‑fix | :grey_exclamation: %s |\n\n" "${FIX_COPY_OUTCOME}" >> "${TEST_STEP_SUMMARY}" ; fi ; # end auto-fix else printf "\n" >> "${TEST_STEP_SUMMARY}" ; # extra space @@ -259,7 +267,8 @@ runs: wait ; else printf "\nNow Skipping '%s'\n\n" "${reference_file}" ; - printf "%s\n" ":grey_exclamation: Directly copying the filepath \`${reference_file}\` was inconclusive (_testing and validation skipped_)." >> "${TEST_STEP_SUMMARY}" ; + # printf "%s\n" ":grey_exclamation: Directly copying the filepath \`${reference_file}\` was inconclusive (_testing and validation skipped_)." >> "${TEST_STEP_SUMMARY}" ; + printf "## %s\n| Direct copy | :grey_exclamation: %s |\n" "\`${reference_file}\`" "inconclusive" >> "${TEST_STEP_SUMMARY}" ; printf "\n" >> "${TEST_STEP_SUMMARY}" ; # extra space fi ; fi ; # TODO: else can not be run directly and needs to be invoked with -m unittest -v test. diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 538d808aaa..176e0ec66b 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -95,8 +95,8 @@ jobs: with: override-path: rustpython override-rustpython-path: Lib - override-repository: 'ShaharNaveh/RustPython' - override-ref: auto-updater # Hint: could be changed to ${{ github.ref }} + override-repository: 'RustPython/RustPython' + override-ref: main # Hint: could be changed to ${{ github.ref }} - name: Fetch Reference Cpython ${{ matrix.python-version }} on ${{ matrix.os }} id: fetch-cpython uses: ./.github/actions/CI-5974-Fetch-CPython From b87cb8aaebf120394ad34291c8df0028542c731a Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Sun, 28 Sep 2025 15:39:02 -0700 Subject: [PATCH 61/62] Apply suggestions from code review with AI assistant Minor changes to defaults and fallback logic as discussed with AI reviewer. Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .github/actions/CI-5974-Fetch-CPython/action.yaml | 7 ++++--- .github/actions/CI-5974-Fetch-RustPython/action.yaml | 7 +++---- .../CI-5974-Test-RustPython-Integration/action.yaml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/actions/CI-5974-Fetch-CPython/action.yaml b/.github/actions/CI-5974-Fetch-CPython/action.yaml index ae7638aa0f..22ec5d9832 100644 --- a/.github/actions/CI-5974-Fetch-CPython/action.yaml +++ b/.github/actions/CI-5974-Fetch-CPython/action.yaml @@ -11,13 +11,14 @@ inputs: The GitHub repository to clone CPython from. When running this action on github.com, the default value is sufficient. Useful for Forks. required: true - default: ${{ github.server_url == 'https://github.com' && github.repository || 'python/cpython' }} + # keep it simple + default: 'python/cpython' override-rustpython-path: description: | override value for path to the Python Lib. The default is to use the value of the environment variable 'RUSTPYTHONPATH'. Most users will find the default 'Lib' sufficient. required: true - default: ${{ github.server_url == 'https://github.com' && github.repository || 'Lib' }} + default: ${{ github.server_url == 'https://github.com' && env.RUSTPYTHONPATH || 'Lib' }} override-path: description: | Path to setup. When running this action on github.com, the default value @@ -30,7 +31,7 @@ inputs: environment variable 'PYTHONPLATLIBDIR'. Most users will find the default 'Lib' sufficient. See https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPLATLIBDIR for more. required: true - default: ${{ github.server_url == 'https://github.com' && github.repository || 'Lib' }} + default: ${{ github.server_url == 'https://github.com' && env.PYTHONPLATLIBDIR || 'Lib' }} match: description: | Glob-style pattern of files or directories to match and integrate. diff --git a/.github/actions/CI-5974-Fetch-RustPython/action.yaml b/.github/actions/CI-5974-Fetch-RustPython/action.yaml index e5e22b2a5c..7d725f64a9 100644 --- a/.github/actions/CI-5974-Fetch-RustPython/action.yaml +++ b/.github/actions/CI-5974-Fetch-RustPython/action.yaml @@ -17,13 +17,14 @@ inputs: The GitHub repository to clone RustPython from. When running this action on github.com, the default value is sufficient. Useful for Forks. required: true + # odd as it looks this is correct default: ${{ github.server_url == 'https://github.com' && github.repository || 'RustPython/RustPython' }} override-rustpython-path: description: | override value for path to the Python Lib. The default is to use the value of the environment variable 'RUSTPYTHONPATH'. Most users will find the default 'Lib' sufficient. required: true - default: ${{ github.server_url == 'https://github.com' && github.repository || 'Lib' }} + default: ${{ github.server_url == 'https://github.com' && env.RUSTPYTHONPATH || 'Lib' }} override-path: description: | Path to setup. When running this action on github.com, the default value @@ -46,11 +47,9 @@ outputs: description: "The SHA of the commit checked-out." value: ${{ steps.output_sha.outputs.sha || 'HEAD' }} rustpython-version: - description: "The python version that was used in the run." - value: '0.4' # TODO: fix this rustpython-lib-path: description: "The python version that was used in the run." - value: ${{ steps.output_rpython_path.output.rustpython-lib-path }} + value: ${{ steps.output_rpython_path.outputs.rustpython-lib-path }} runs: using: composite diff --git a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml index 4271feccdd..0843aaf147 100644 --- a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml +++ b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml @@ -56,7 +56,7 @@ runs: fi if [[ -n $OVERRIDE_RUSTPYTHONPATH_INPUT ]]; then printf "override-rustpython-path=%s\n" "${OVERRIDE_RUSTPYTHONPATH_INPUT}" >> "$GITHUB_OUTPUT" - OVERRIDE_RUSTPYTHONPATH=${RUSTPYTHONPATH} + OVERRIDE_RUSTPYTHONPATH=${OVERRIDE_RUSTPYTHONPATH_INPUT} else printf "override-rustpython-path=%s\n" "${RUSTPYTHONPATH:-Lib}" >> "$GITHUB_OUTPUT" OVERRIDE_RUSTPYTHONPATH="${RUSTPYTHONPATH:-Lib}" From 1960425c18bd1df250fca2cb870a29c57f6bf768 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Sun, 28 Sep 2025 16:23:02 -0700 Subject: [PATCH 62/62] [PATCH] Cleanup from automated review in PR #6176 * implemented fallback on Env logic for select inputs (override still prefered) Ref GHI #5974 --- .../actions/CI-5974-Fetch-CPython/action.yaml | 37 ++++++++++++++++--- .../CI-5974-Fetch-RustPython/action.yaml | 22 +++++++++-- 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/.github/actions/CI-5974-Fetch-CPython/action.yaml b/.github/actions/CI-5974-Fetch-CPython/action.yaml index 22ec5d9832..655a3f0057 100644 --- a/.github/actions/CI-5974-Fetch-CPython/action.yaml +++ b/.github/actions/CI-5974-Fetch-CPython/action.yaml @@ -11,14 +11,13 @@ inputs: The GitHub repository to clone CPython from. When running this action on github.com, the default value is sufficient. Useful for Forks. required: true - # keep it simple default: 'python/cpython' override-rustpython-path: description: | override value for path to the Python Lib. The default is to use the value of the environment variable 'RUSTPYTHONPATH'. Most users will find the default 'Lib' sufficient. required: true - default: ${{ github.server_url == 'https://github.com' && env.RUSTPYTHONPATH || 'Lib' }} + default: '' override-path: description: | Path to setup. When running this action on github.com, the default value @@ -31,7 +30,7 @@ inputs: environment variable 'PYTHONPLATLIBDIR'. Most users will find the default 'Lib' sufficient. See https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPLATLIBDIR for more. required: true - default: ${{ github.server_url == 'https://github.com' && env.PYTHONPLATLIBDIR || 'Lib' }} + default: '' match: description: | Glob-style pattern of files or directories to match and integrate. @@ -86,6 +85,34 @@ runs: printf "python-version=%s\n" "${PYTHON_VERSION}" >> "$GITHUB_OUTPUT" fi printf "%s\n" "PYTHON_VERSION=${PYTHON_VERSION}" >> "$GITHUB_ENV" + - name: "Setup RustPython Lib Path" + id: output_rpython_path + env: + RUST_PYTHON_LIB_PATH_INPUT: ${{ inputs.override-rustpython-path }} + shell: bash + run: | + if [[ -n $RUST_PYTHON_LIB_PATH_INPUT ]]; then + printf "::debug:: Initializing rust-python-path as ${RUST_PYTHON_LIB_PATH_INPUT}" + printf "rust-python-path=%s\n" "${RUST_PYTHON_LIB_PATH_INPUT:-${RUSTPYTHONPATH:-Lib}}" >> "$GITHUB_OUTPUT" + else + printf "::debug:: Initializing rust-python-path as ${RUSTPYTHONPATH:-Lib}" + printf "rust-python-path=%s\n" "${RUSTPYTHONPATH:-Lib}" >> "$GITHUB_OUTPUT" + fi + printf "%s\n" "RUSTPYTHONPATH=${RUST_PYTHON_LIB_PATH_INPUT:-${RUSTPYTHONPATH:-Lib}}" >> "$GITHUB_ENV" + - name: "Setup cPython Lib Path" + id: output_cpython_path + env: + PYTHONPLATLIBDIR_INPUT: ${{ inputs.override-cpython-lib-path }} + shell: bash + run: | + if [[ -n $PYTHONPLATLIBDIR_INPUT ]]; then + printf "::debug:: Initializing cpython-lib-path as ${PYTHONPLATLIBDIR_INPUT}" + printf "cpython-lib-path=%s\n" "${PYTHONPLATLIBDIR_INPUT:-${PYTHONPLATLIBDIR:-Lib}}" >> "$GITHUB_OUTPUT" + else + printf "::debug:: Initializing cpython-lib-path as ${PYTHONPLATLIBDIR:-Lib}" + printf "cpython-lib-path=%s\n" "${PYTHONPLATLIBDIR:-Lib}" >> "$GITHUB_OUTPUT" + fi + printf "%s\n" "PYTHONPLATLIBDIR=${PYTHONPLATLIBDIR_INPUT:-${PYTHONPLATLIBDIR:-Lib}}" >> "$GITHUB_ENV" - name: Fetch Reference Cpython ${{ matrix.python-version }} on ${{ matrix.os }} id: cpython uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -94,7 +121,7 @@ runs: path: ${{ inputs.override-path }} fetch-tags: true sparse-checkout: | - ${{ inputs.override-cpython-lib-path }} + ${{ steps.output_cpython_path.outputs.cpython-lib-path }} ref: ${{ steps.output_python.outputs.python-version }} repository: ${{ inputs.override-repository }} # fixed settings @@ -147,7 +174,7 @@ runs: cd ${{ inputs.override-path }} || exit 14 ; FILES=$(git ls-files --exclude-standard -- ${{ env.TEST_MATCH_PATTERN }} ) if [ -z "$FILES" ]; then - printf "%s\n" "::warning file=.github/actions/:: No ${{ inputs.override-cpython-lib-path }} Reference files found for Cpython ${{ inputs.python-version }} on ${{ runner.os }}." ; + printf "%s\n" "::warning file=.github/actions/:: No ${{ steps.output_cpython_path.outputs.cpython-lib-path }} Reference files found for Cpython ${{ inputs.python-version }} on ${{ runner.os }}." ; printf "%s\n" "files=" >> "$GITHUB_OUTPUT" else printf "%s\n" "Reference files found:" diff --git a/.github/actions/CI-5974-Fetch-RustPython/action.yaml b/.github/actions/CI-5974-Fetch-RustPython/action.yaml index 7d725f64a9..579d8c3344 100644 --- a/.github/actions/CI-5974-Fetch-RustPython/action.yaml +++ b/.github/actions/CI-5974-Fetch-RustPython/action.yaml @@ -24,7 +24,7 @@ inputs: override value for path to the Python Lib. The default is to use the value of the environment variable 'RUSTPYTHONPATH'. Most users will find the default 'Lib' sufficient. required: true - default: ${{ github.server_url == 'https://github.com' && env.RUSTPYTHONPATH || 'Lib' }} + default: '' override-path: description: | Path to setup. When running this action on github.com, the default value @@ -46,7 +46,7 @@ outputs: sha: description: "The SHA of the commit checked-out." value: ${{ steps.output_sha.outputs.sha || 'HEAD' }} - rustpython-version: + # rustpython-version: rustpython-lib-path: description: "The python version that was used in the run." value: ${{ steps.output_rpython_path.outputs.rustpython-lib-path }} @@ -54,6 +54,20 @@ outputs: runs: using: composite steps: + - name: "Setup RustPython Lib Path" + id: setup_rpython_path + env: + RUST_PYTHON_LIB_PATH_INPUT: ${{ inputs.override-rustpython-path }} + shell: bash + run: | + if [[ -n $RUST_PYTHON_LIB_PATH_INPUT ]]; then + printf "::debug:: Initializing rust-python-path as ${RUST_PYTHON_LIB_PATH_INPUT}" + printf "rust-python-path=%s\n" "${RUST_PYTHON_LIB_PATH_INPUT:-${RUSTPYTHONPATH:-Lib}}" >> "$GITHUB_OUTPUT" + else + printf "::debug:: Initializing rust-python-path as ${RUSTPYTHONPATH:-Lib}" + printf "rust-python-path=%s\n" "${RUSTPYTHONPATH:-Lib}" >> "$GITHUB_OUTPUT" + fi + printf "%s\n" "RUSTPYTHONPATH=${RUST_PYTHON_LIB_PATH_INPUT:-${RUSTPYTHONPATH:-Lib}}" >> "$GITHUB_ENV" - name: Checkout repository id: rpython uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -115,7 +129,7 @@ runs: if [[ "$RUNNER_DEBUG" == "true" ]] || [[ "$ACTIONS_STEP_DEBUG" == "true" ]]; then printf "::debug::Now Building '%s'\n" "RustPython" ; fi ; # Execute the testing command in a subshell ( - RUSTPYTHONPATH=${{ inputs.override-rustpython-path }} cargo run $CARGO_ARGS -- --version || printf "::error title='build failure':: Could not pass build step for version check on ${OS}.\n" ; + RUSTPYTHONPATH=${{ steps.setup_rpython_path.outputs.rust-python-path }} cargo run $CARGO_ARGS -- --version || printf "::error title='build failure':: Could not pass build step for version check on ${OS}.\n" ; ) ; printf "::endgroup::%s\n" ; cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; @@ -123,7 +137,7 @@ runs: shell: bash run: | cd ${{ inputs.override-path }} || exit 13 ; # in case it is relative - cd ${{ inputs.override-rustpython-path }} || exit 13 ; + cd ${{ steps.setup_rpython_path.outputs.rust-python-path }} || exit 13 ; printf "RUSTPYTHONPATH=%s\n" $(pwd) >> "$GITHUB_ENV" ; printf "rustpython-lib-path=%s\n" $(pwd) >> "$GITHUB_OUTPUT" ; cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ;