From a67bd8ab3665aa615698db90ccd15724fe1f8e39 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 16 Jul 2025 21:09:56 -0700 Subject: [PATCH 01/68] 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 00000000000..e84c7e549d4 --- /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/68] 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 e84c7e549d4..850402d82ea 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/68] 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 850402d82ea..9af390509fa 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/68] 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 9af390509fa..f4dbc647466 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/68] 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 f4dbc647466..288fb3f1f53 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/68] 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 288fb3f1f53..88d61e40fba 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/68] 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 88d61e40fba..58574e310cd 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/68] 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 58574e310cd..95db4ed30a4 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/68] 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 95db4ed30a4..efb3358bbc6 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/68] 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 efb3358bbc6..2fda6273f2f 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/68] 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 2fda6273f2f..15a068295bd 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/68] 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 15a068295bd..c7ff1252068 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/68] 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 c7ff1252068..df41bb06c43 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/68] 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 df41bb06c43..abfe38f3318 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/68] 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 abfe38f3318..2943d1ed929 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/68] 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 2943d1ed929..8e2d5fa3693 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/68] 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 8e2d5fa3693..c0b7bc9f371 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/68] 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 c0b7bc9f371..6cfabb94e6d 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/68] 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 6cfabb94e6d..bceece70b2a 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/68] 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 bceece70b2a..19c02919fdb 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/68] 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 19c02919fdb..e50031908b9 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/68] 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 e50031908b9..5f9140614c5 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/68] 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 5f9140614c5..c043dd3274e 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/68] 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 c043dd3274e..0c60ed7f215 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/68] 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 0c60ed7f215..b6983ee480c 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/68] 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 b6983ee480c..ede754f9343 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/68] 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 ede754f9343..4c9972d1a09 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/68] 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 00000000000..9fe5dcbee74 --- /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 00000000000..02242fd779a --- /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 4c9972d1a09..956653af437 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/68] 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 956653af437..cb63c191c0e 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/68] :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 cb63c191c0e..a56039eb379 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/68] 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 a56039eb379..3f946408bdb 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/68] 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 02242fd779a..3bb6bfe46d8 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 3f946408bdb..46556044ea2 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/68] 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 9fe5dcbee74..ae7638aa0f9 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 46556044ea2..6693b4ccb69 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/68] 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 3bb6bfe46d8..b08463eb522 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/68] 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 00000000000..a24c10e47e7 --- /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 6693b4ccb69..ab121fa86b5 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/68] 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 ab121fa86b5..20da5a3ab86 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/68] :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 a24c10e47e7..1de3cec7813 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/68] :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 b08463eb522..3f49d9d04a8 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 1de3cec7813..0d824d3a475 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/68] 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 20da5a3ab86..21678e2c781 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/68] 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 21678e2c781..556e2752109 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/68] :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 556e2752109..75bd697739f 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/68] 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 75bd697739f..9f5af966fd9 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/68] 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 12e0b0216d5..fad6ea1d14e 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 3f49d9d04a8..5fa43cbf0f8 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/68] 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 0d824d3a475..49e8492a0d7 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 9f5af966fd9..f9552d0c738 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/68] 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 f9552d0c738..24eaaf8d262 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/68] 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 fad6ea1d14e..75e1cf4d6a0 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/68] 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 75e1cf4d6a0..0bcde26ae04 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 5fa43cbf0f8..dc0d16e5f57 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 49e8492a0d7..dca3b39865f 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/68] 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 0bcde26ae04..e5e22b2a5c2 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/68] [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 00000000000..781c000280e --- /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 24eaaf8d262..19cf5cb1d7c 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/68] [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 781c000280e..1b6cf63fa8b 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/68] [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 1b6cf63fa8b..cb0fa1d0c05 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/68] [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 dc0d16e5f57..a2145a33049 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/68] [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 a2145a33049..39d49a87b3f 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/68] [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 cb0fa1d0c05..d917c27d5d3 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/68] [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 d917c27d5d3..6d41a823e9e 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/68] [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 6d41a823e9e..4439fa9bcaf 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/68] 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 4439fa9bcaf..77f1d48305f 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/68] 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 77f1d48305f..07fb9b361b9 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/68] 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 39d49a87b3f..16918a3226d 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 07fb9b361b9..00000000000 --- 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 19cf5cb1d7c..538d808aaa1 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/68] [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 dca3b39865f..4271feccdd2 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 538d808aaa1..176e0ec66b1 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/68] 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 ae7638aa0f9..22ec5d9832c 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 e5e22b2a5c2..7d725f64a90 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 4271feccdd2..0843aaf147c 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/68] [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 22ec5d9832c..655a3f0057b 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 7d725f64a90..579d8c3344c 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 ; From d39c6ec61bb03a092c779a774b3af8d6f9c83190 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Tue, 10 Feb 2026 17:51:07 -0800 Subject: [PATCH 63/68] [CI] Add primitive json format of results as uploaded artifact These changes are part of PR RustPython/RustPython#6176 and relate to GHI RustPython/RustPython#5974 * This draft is a prototype and may have too much data. --- .../actions/CI-5974-Fetch-CPython/action.yaml | 2 +- .../action.yaml | 17 +++++++++ .github/workflows/Check_Tests.yml | 38 +++++++++++++++++-- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/.github/actions/CI-5974-Fetch-CPython/action.yaml b/.github/actions/CI-5974-Fetch-CPython/action.yaml index 655a3f0057b..abc04c5ee50 100644 --- a/.github/actions/CI-5974-Fetch-CPython/action.yaml +++ b/.github/actions/CI-5974-Fetch-CPython/action.yaml @@ -54,7 +54,7 @@ inputs: 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 Cpython version (e.g., any valid release or tag, 3.12, 3.13, 3.14) to override setup. The default is to use the value of the environment variable 'PYTHON_VERSION'. default: '3.13' required: true diff --git a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml index 0843aaf147c..510038bc97e 100644 --- a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml +++ b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml @@ -276,6 +276,23 @@ runs: done cat <"${TEST_STEP_SUMMARY}" >> "$GITHUB_STEP_SUMMARY" ; cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; + - name: Format GitHub Actions environment file to JSON + id: summarize + if: ${{ always() }} + shell: bash + run: | + echo '{}' > formatted_env.json # Initialize an empty JSON file + jq -Rn 'inputs | split("=") | { (.[0]): .[1] }' < "$GITHUB_ENV" | jq -s 'add' > formatted_env.json + - name: Upload JSON as artifact + if: ${{ !cancelled() }} + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + with: + name: formatted-env-${{ runner.os }}-${{ inputs.python-version }}-${{ github.sha }} + path: formatted_env.json + if-no-files-found: ignore + compression-level: 9 + retention-days: 1 + overwrite: true - name: Post-Clean id: post-bootstrap run: | diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 176e0ec66b1..c0e60567350 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -17,6 +17,17 @@ on: # yamllint disable-line rule:truthy push: branches: ["**"] # matches any branch tags: ["v*"] + workflow_dispatch: + inputs: + python-version: + description: Target python version to target. Expected format: X.Y (e.g., 3.14) + type: string + default: "3.14" + inputs: + subshell-timeout: + description: Max time in seconds before marking a subshell as hung (per-subshell). + type: int + default: 30 # Declare default permissions as none. permissions: {} @@ -24,13 +35,13 @@ 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' }}" + # Define Python versions at the top level -- Expected format: X.Y (e.g., 3.14) + PYTHON_DEFAULT: "${{ inputs.python-version || vars.PYTHON_DEFAULT || '3.14' }}" 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_OLD_EXTRA: "${{ vars.PYTHON_OLD_EXTRA || '3.12' }}" # 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 + SUBSHELL_TIMEOUT: ${{ inputs.subshell-timeout || 30 }} # TODO: coordinate with @moreal - to support initial use-case See RustPython/RustPython#5974 @@ -139,6 +150,25 @@ jobs: ${{ steps.fetch-cpython.outputs.files }} python-version: ${{ env.PYTHON_VERSION }} max-test-time: ${{ env.SUBSHELL_TIMEOUT }} # seconds + - name: Format GitHub Actions environment file to JSON + id: summarize + if: ${{ always() }} + shell: bash + run: | + echo '{}' > formatted_env.json # Initialize an empty JSON file + jq -Rn 'inputs | split("=") | { (.[0]): .[1] }' < "$GITHUB_ENV" | jq -s 'add' > formatted_env.json + + - name: Upload JSON as artifact + if: ${{ !cancelled() }} + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + with: + name: formatted-env + path: formatted_env.json + if-no-files-found: ignore + compression-level: 9 + retention-days: 1 + overwrite: true + - name: Post-Process id: summarize if: ${{ always() }} From 82104f8f81b7d9e467261a59b36278b6b8301a64 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Tue, 10 Feb 2026 17:56:58 -0800 Subject: [PATCH 64/68] [CI] regression fix --- .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 c0e60567350..81042423ffe 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -20,12 +20,12 @@ on: # yamllint disable-line rule:truthy workflow_dispatch: inputs: python-version: - description: Target python version to target. Expected format: X.Y (e.g., 3.14) + description: 'Target python version to target. Expected format: X.Y (e.g., 3.14)' type: string default: "3.14" inputs: subshell-timeout: - description: Max time in seconds before marking a subshell as hung (per-subshell). + description: 'Max time in seconds before marking a subshell as hung (per-subshell).' type: int default: 30 From 6ef67dbd68ef1f0a68306163b30b5037e2e348c0 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Tue, 10 Feb 2026 18:00:02 -0800 Subject: [PATCH 65/68] [CI] RERERE more churn (sorry) --- .github/workflows/Check_Tests.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 81042423ffe..2eac11213ba 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -23,8 +23,7 @@ on: # yamllint disable-line rule:truthy description: 'Target python version to target. Expected format: X.Y (e.g., 3.14)' type: string default: "3.14" - inputs: - subshell-timeout: + subshell-timeout: description: 'Max time in seconds before marking a subshell as hung (per-subshell).' type: int default: 30 From 67750efb4f88c3153880545022cb5355b9a873ce Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Tue, 10 Feb 2026 18:02:02 -0800 Subject: [PATCH 66/68] [CI] RERERE more churn (sorry) --- .github/actions/CI-5974-Test-RustPython-Integration/action.yaml | 1 - .github/workflows/Check_Tests.yml | 2 +- 2 files changed, 1 insertion(+), 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 510038bc97e..15137a24144 100644 --- a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml +++ b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml @@ -277,7 +277,6 @@ runs: cat <"${TEST_STEP_SUMMARY}" >> "$GITHUB_STEP_SUMMARY" ; cd ${{ steps.store_old_path.outputs.initial-path }} || exit 15 ; - name: Format GitHub Actions environment file to JSON - id: summarize if: ${{ always() }} shell: bash run: | diff --git a/.github/workflows/Check_Tests.yml b/.github/workflows/Check_Tests.yml index 2eac11213ba..a1b15a1202b 100644 --- a/.github/workflows/Check_Tests.yml +++ b/.github/workflows/Check_Tests.yml @@ -150,7 +150,7 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} max-test-time: ${{ env.SUBSHELL_TIMEOUT }} # seconds - name: Format GitHub Actions environment file to JSON - id: summarize + id: reformat_json if: ${{ always() }} shell: bash run: | From f0634088ebe68fde721913e237c3ab86cde1854e Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Tue, 10 Feb 2026 19:00:18 -0800 Subject: [PATCH 67/68] [CI] Improved generation of json files --- .../action.yaml | 52 +++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml index 15137a24144..ff8769d8869 100644 --- a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml +++ b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml @@ -252,7 +252,7 @@ runs: 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 + wait ; # used to force boundary 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 @@ -280,8 +280,54 @@ runs: if: ${{ always() }} shell: bash run: | - echo '{}' > formatted_env.json # Initialize an empty JSON file - jq -Rn 'inputs | split("=") | { (.[0]): .[1] }' < "$GITHUB_ENV" | jq -s 'add' > formatted_env.json + # Initialize empty JSON object + echo '{}' > formatted_env.json + # Define patterns for variables to include (allowlist approach) + INCLUDE_PATTERNS=( + '^FIX_COPY_.*_OUTCOME=' + '^RAW_COPY_.*_OUTCOME=' + '^PYTHON_VERSION=' + '^TEST_STEP_SUMMARY=' + '^CARGO_ARGS=' + '^OVERRIDE_RUSTPYTHONPATH=' + '^RUNNER_OS=' + '^SUBSHELL_TIMEOUT=' + '^GITHUB_SHA=' + ) + # Define patterns for sensitive variables to always exclude (denylist) + EXCLUDE_PATTERNS=( + 'TOKEN' + 'SECRET' + 'PASSWORD' + 'KEY' + 'CREDENTIAL' + 'AUTH' + '_PWD' + 'GITHUB_TOKEN' + ) + # Filter GITHUB_ENV to include only safe, relevant variables + # Initialize a JSON object + echo "{" > formatted_env.json + # Filter GITHUB_ENV to include only safe, relevant variables + grep -E "$(IFS='|'; echo "${INCLUDE_PATTERNS[*]}")" "$GITHUB_ENV" | \ + grep -viE "$(IFS='|'; echo "${EXCLUDE_PATTERNS[*]}")" | \ + while IFS='=' read -r key value; do + # Append each key-value pair to the JSON file + # Escape characters that need to be escaped in JSON + escaped_key=$(echo "$key" | jq -R @json) + escaped_value=$(echo "$value" | jq -R @json) + echo " $escaped_key: $escaped_value," >> formatted_env.json + done + # Remove the trailing comma and close the JSON object + sed -i '$ s/,$//' formatted_env.json + echo "}" >> formatted_env.json + # Verify the output contains data + if [[ -s formatted_env.json ]] && jq -e 'length > 0' formatted_env.json >/dev/null 2>&1; then + echo "::debug::Successfully created filtered environment JSON with $(jq 'length' formatted_env.json) variables" + else + echo "::warning::No matching environment variables found to export" + echo '{}' > formatted_env.json + fi - name: Upload JSON as artifact if: ${{ !cancelled() }} uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 From a1459c039f8f6d568cf7f49b9e13b6c8e06a68bd Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Wed, 11 Feb 2026 17:16:58 -0800 Subject: [PATCH 68/68] [CI] debugging the JSON format --- .../action.yaml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml index ff8769d8869..9ca4e30c25a 100644 --- a/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml +++ b/.github/actions/CI-5974-Test-RustPython-Integration/action.yaml @@ -280,8 +280,6 @@ runs: if: ${{ always() }} shell: bash run: | - # Initialize empty JSON object - echo '{}' > formatted_env.json # Define patterns for variables to include (allowlist approach) INCLUDE_PATTERNS=( '^FIX_COPY_.*_OUTCOME=' @@ -307,7 +305,7 @@ runs: ) # Filter GITHUB_ENV to include only safe, relevant variables # Initialize a JSON object - echo "{" > formatted_env.json + echo "{" > formatted_env.json || true ; # Filter GITHUB_ENV to include only safe, relevant variables grep -E "$(IFS='|'; echo "${INCLUDE_PATTERNS[*]}")" "$GITHUB_ENV" | \ grep -viE "$(IFS='|'; echo "${EXCLUDE_PATTERNS[*]}")" | \ @@ -317,7 +315,7 @@ runs: escaped_key=$(echo "$key" | jq -R @json) escaped_value=$(echo "$value" | jq -R @json) echo " $escaped_key: $escaped_value," >> formatted_env.json - done + done ; # Remove the trailing comma and close the JSON object sed -i '$ s/,$//' formatted_env.json echo "}" >> formatted_env.json @@ -325,9 +323,13 @@ runs: if [[ -s formatted_env.json ]] && jq -e 'length > 0' formatted_env.json >/dev/null 2>&1; then echo "::debug::Successfully created filtered environment JSON with $(jq 'length' formatted_env.json) variables" else - echo "::warning::No matching environment variables found to export" - echo '{}' > formatted_env.json - fi + if [[ -s formatted_env.json ]] ; then + echo "::debug::Incompletely created environment JSON with unknown variables" + else + echo "::warning::No matching environment variables found to export" + echo '{}' > formatted_env.json + fi ; + fi ; - name: Upload JSON as artifact if: ${{ !cancelled() }} uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0