diff --git a/.github/workflows/test-and-publish.yaml b/.github/workflows/test-and-publish.yaml index c066d4f9..ad562623 100644 --- a/.github/workflows/test-and-publish.yaml +++ b/.github/workflows/test-and-publish.yaml @@ -15,8 +15,8 @@ on: required: false options: - '' - - 'ubuntu-20.04' - - 'macos-12' + - 'ubuntu-22.04' + - 'macos-15-intel' - 'macos-14' - 'windows-2022' debug_enabled_python: @@ -31,6 +31,7 @@ on: - '3.11' - '3.12' - '3.13' + - '3.14' build_type: type: choice description: 'Choose the build type to use' @@ -49,6 +50,8 @@ env: # don't upgrade outdated brew packages because the process is too slow HOMEBREW_NO_INSTALL_UPGRADE: 1 HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1 + # apt-get should run in noninteractive mode + DEBIAN_FRONTEND: noninteractive defaults: run: @@ -64,16 +67,14 @@ jobs: strategy: fail-fast: false matrix: - # Use Ubuntu 20.04 / macOS 13 x86_64 / macOS 14 arm64 + Python 3.10 to build SpiderMonkey - os: [ 'ubuntu-20.04', 'macos-13', 'macos-14', 'pi' ] # macOS 14 runner exclusively runs on M1 hardwares - # see https://github.blog/changelog/2024-01-30-github-actions-macos-14-sonoma-is-now-available + # Use Ubuntu 22.04 / macOS 15 x86_64 / macOS 14 arm64 + Python 3.10 to build SpiderMonkey + os: [ 'ubuntu-22.04', 'macos-15-intel', 'macos-14', 'ubuntu-22.04-arm' ] # macOS 14 runner exclusively runs on M1 hardwares + # see https://github.blog/changelog/2024-01-30-github-actions-macos-14-sonoma-is-now-available python_version: [ '3.10' ] runs-on: ${{ matrix.os }} + container: ${{ (startsWith(matrix.os, 'ubuntu') && 'ubuntu:20.04') || null }} # Use the Ubuntu 20.04 container inside Ubuntu 22.04 runner to build steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python_version }} - name: Read the mozilla-central commit hash to be used run: echo "MOZCENTRAL_VERSION=$(cat mozcentral.version)" >> $GITHUB_ENV - name: Cache spidermonkey build @@ -83,14 +84,58 @@ jobs: path: | ./_spidermonkey_install/* key: spidermonkey-${{ env.MOZCENTRAL_VERSION }}-${{ runner.os }}-${{ runner.arch }} - lookup-only: true # skip download + - name: Setup container + if: ${{ startsWith(matrix.os, 'ubuntu') && steps.cache-spidermonkey.outputs.cache-hit != 'true' }} + run: | + apt-get update -y + apt-get install -y sudo libnss3-dev libssl-dev + apt-get install -y curl make git build-essential + apt-get install -y zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev # required for pyenv + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata + echo "AGENT_TOOLSDIRECTORY=/" >> $GITHUB_ENV # do not use the Python installation cached for Ubuntu 22.04 + - name: Setup LLVM + if: ${{ startsWith(matrix.os, 'ubuntu') && steps.cache-spidermonkey.outputs.cache-hit != 'true' }} + run: | + apt-get install -y llvm clang + apt-get install -y lsb-release wget software-properties-common gnupg + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + ./llvm.sh 18 # install LLVM version 18 + update-alternatives --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-18 18 + update-alternatives --install /usr/bin/clang clang /usr/bin/clang-18 18 + update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-18 18 + clang --version + clang++ --version + - name: Setup Python + if: ${{ startsWith(matrix.os, 'ubuntu') && steps.cache-spidermonkey.outputs.cache-hit != 'true' }} + run: | + # Use pyenv to install Python version that is not available via `actions/setup-python` + unset PYENV_ROOT + curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash + echo "$HOME/.pyenv/bin" >> $GITHUB_PATH # ~/.bashrc file is not read, so we need to add to GITHUB_PATH manually + echo "$HOME/.pyenv/shims" >> $GITHUB_PATH + echo "PYENV_ROOT=$HOME/.pyenv" >> $GITHUB_ENV + export PATH="$HOME/.pyenv/bin:$PATH" + pyenv install $PYTHON_VERSION + pyenv global $PYTHON_VERSION + env: + PYTHON_VERSION: ${{ matrix.python_version }} + - uses: actions/setup-python@v5 + if: ${{ !startsWith(matrix.os, 'ubuntu') && steps.cache-spidermonkey.outputs.cache-hit != 'true' }} + with: + python-version: ${{ matrix.python_version }} - name: Setup XCode - if: ${{ (matrix.os == 'macos-13' || matrix.os == 'macos-14') && steps.cache-spidermonkey.outputs.cache-hit != 'true' }} - # SpiderMonkey requires XCode SDK version at least 13.3 - run: sudo xcode-select -switch /Applications/Xcode_14.3.app + if: ${{ matrix.os == 'macos-15-intel' && steps.cache-spidermonkey.outputs.cache-hit != 'true' }} + # Xcode 16.x removed the old linker behaviour (-ld64 or -ld_classic) that SpiderMonkey relies on, so we need to switch to an older version + run: sudo xcode-select -switch /Applications/Xcode_16.0.app - name: Build spidermonkey if: ${{ steps.cache-spidermonkey.outputs.cache-hit != 'true' }} run: ./setup.sh + - name: Upload spidermonkey build as CI artifacts + uses: actions/upload-artifact@v4 + with: + name: spidermonkey-${{ env.MOZCENTRAL_VERSION }}-${{ runner.os }}-${{ runner.arch }} + path: ./_spidermonkey_install/ build-spidermonkey-win: runs-on: windows-2022 # SpiderMonkey requires Visual Studio 2022 or newer. @@ -106,7 +151,6 @@ jobs: path: | ./_spidermonkey_install/* key: spidermonkey-${{ env.MOZCENTRAL_VERSION }}-${{ runner.os }}-${{ runner.arch }} - lookup-only: true # skip download - name: Install dependencies if: ${{ steps.cache-spidermonkey.outputs.cache-hit != 'true' }} shell: powershell @@ -127,26 +171,63 @@ jobs: # see https://groups.google.com/u/1/a/mozilla.org/g/dev-platform/c/hF51Q3j6ca8 USE_MINTTY: 0 run: /c/mozilla-build/start-shell.bat -use-full-path -here ./setup.sh + - name: Upload spidermonkey build as CI artifacts + uses: actions/upload-artifact@v4 + with: + name: spidermonkey-${{ env.MOZCENTRAL_VERSION }}-${{ runner.os }}-${{ runner.arch }} + path: ./_spidermonkey_install/ build-and-test: needs: [build-spidermonkey-unix, build-spidermonkey-win] strategy: fail-fast: false matrix: - os: [ 'ubuntu-20.04', 'macos-12', 'macos-14', 'windows-2022', 'pi' ] - python_version: [ '3.8', '3.9', '3.10', '3.11', '3.12', '3.13' ] + os: [ 'ubuntu-22.04', 'macos-15-intel', 'macos-14', 'windows-2022', 'ubuntu-22.04-arm' ] + python_version: [ '3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14' ] runs-on: ${{ matrix.os }} + container: ${{ (startsWith(matrix.os, 'ubuntu') && 'ubuntu:20.04') || null }} steps: + - name: Setup container + if: ${{ startsWith(matrix.os, 'ubuntu') }} + run: | + apt-get update -y + apt-get install -y sudo libnss3-dev libssl-dev + apt-get install -y curl zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev # required for pyenv + apt-get install -y git # required for `actions/checkout` + apt-get install -y nodejs npm # required for pminit to build + apt-get install -y build-essential + apt-get install -y strace # required to run JS tests + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata # tzdata may ask for user interaction if not explicitly installed here + echo "AGENT_TOOLSDIRECTORY=/" >> $GITHUB_ENV # do not use the Python installation cached for Ubuntu 22.04 + git config --global --add safe.directory '*' # silence "git failed because of dubious ownership" + + # CMake 3.25 or higher is required + apt-get install -y ca-certificates gpg wget + wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null + echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ focal main' | sudo tee /etc/apt/sources.list.d/kitware.list >/dev/null + apt-get update -y && apt-get install -y cmake - uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 # fetch all history for all branches and tags # poetry-dynamic-versioning needs git tags to produce the correct version number + - name: Setup Python + if: ${{ startsWith(matrix.os, 'ubuntu') }} + run: | + # Use pyenv to install Python version that is not available via `actions/setup-python` + unset PYENV_ROOT + curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash + echo "$HOME/.pyenv/bin" >> $GITHUB_PATH # ~/.bashrc file is not read, so we need to add to GITHUB_PATH manually + echo "$HOME/.pyenv/shims" >> $GITHUB_PATH + echo "PYENV_ROOT=$HOME/.pyenv" >> $GITHUB_ENV + export PATH="$HOME/.pyenv/bin:$PATH" + pyenv install $PYTHON_VERSION + pyenv global $PYTHON_VERSION + env: + PYTHON_VERSION: ${{ matrix.python_version }} - uses: actions/setup-python@v5 + if: ${{ !startsWith(matrix.os, 'ubuntu') }} with: python-version: ${{ matrix.python_version }} - - name: Remove old poetry cache - run: rm -rf ~/.cache/pypoetry - if: ${{ matrix.os == 'pi' }} - name: Setup Poetry uses: snok/install-poetry@v1 with: @@ -163,13 +244,14 @@ jobs: fi echo "Installing python deps" poetry self add "poetry-dynamic-versioning[plugin]" + echo "Use the correct Python version we've set up" poetry env use python$PYTHON_VERSION || poetry env use python3 # use the correct Python version we've set up poetry install --no-root --only=dev echo "Installed Dependencies" env: PYTHON_VERSION: ${{ matrix.python_version }} - name: Build Docs # only build docs once - if: ${{ matrix.os == 'ubuntu-20.04' && matrix.python_version == '3.11' }} + if: ${{ matrix.os == 'ubuntu-22.04' && matrix.python_version == '3.11' }} run: | sudo apt-get install -y graphviz # the newest version in Ubuntu 20.04 repository is 1.8.17, but we need Doxygen 1.9 series @@ -179,8 +261,8 @@ jobs: rm -rf doxygen-1.9.7 doxygen-1.9.7.linux.bin.tar.gz BUILD_DOCS=1 BUILD_TYPE=None poetry install - name: Upload Doxygen-generated docs as CI artifacts - if: ${{ matrix.os == 'ubuntu-20.04' && matrix.python_version == '3.11' }} - uses: actions/upload-artifact@v3 + if: ${{ matrix.os == 'ubuntu-22.04' && matrix.python_version == '3.11' }} + uses: actions/upload-artifact@v4 with: name: docs-${{ github.run_id }}-${{ github.sha }} path: ./build/docs/html/ @@ -207,7 +289,7 @@ jobs: BUILD_TYPE=${WORKFLOW_BUILD_TYPE:-"Debug"} poetry build --format=wheel ls -lah ./dist/ - name: Make the wheels we build also support lower versions of macOS - if: ${{ matrix.os == 'macos-12' || matrix.os == 'macos-14' }} + if: ${{ matrix.os == 'macos-15-intel' || matrix.os == 'macos-14' }} # Change the platform tag part of the wheel filename to `macosx_11_0_xxx` (means to support macOS 11.0 and above) # See https://packaging.python.org/en/latest/specifications/binary-distribution-format/#file-format # A wheel package file will only be selected by pip to install if the platform tag satisfies, regardless of whether the binary compatibility actually is. @@ -218,53 +300,26 @@ jobs: mv "$file" "$(echo "$file" | sed -E 's/macosx_[0-9]+_[0-9]+/macosx_11_0/')"; done - name: Upload wheel as CI artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: wheel-${{ github.run_id }}-${{ github.sha }} + name: wheel-${{ github.run_id }}-${{ github.sha }}-${{ runner.os }}_${{ runner.arch }}_Python${{ matrix.python_version }} path: ./dist/ - - name: Set cores to get stored in /cores - if: ${{ matrix.os != 'windows-2022' }} - # TODO (Caleb Aikens) figure out how to get Windows core dumps - run: | - sudo mkdir -p /cores - sudo chmod 777 /cores - # Core filenames will be of the form osname.pythonversion.executable.pid.timestamp: - if [[ "$OSTYPE" == "linux-gnu"* ]]; then - sudo bash -c 'echo "/cores/${OSTYPE}.$(poetry run python --version).%e.%p.%t" > /proc/sys/kernel/core_pattern' - else - sudo sysctl kern.corefile="/cores/${OSTYPE}.$(poetry run python --version).%e.%p.%y" - fi - name: Run Python tests (pytest) run: | - if [[ "$OSTYPE" == "linux-gnu"* || "$OSTYPE" == "darwin"* ]]; then - # TODO (Caleb Aikens) figure out how to get Windows core dumps - ulimit -c unlimited - fi WORKFLOW_BUILD_TYPE=${{ inputs.build_type }} BUILD_TYPE=${WORKFLOW_BUILD_TYPE:-"Debug"} poetry run python -m pip install --force-reinstall --verbose ./dist/* poetry run python -m pytest tests/python - name: Run JS tests (peter-jr) if: ${{ (success() || failure()) }} run: | - if [[ "$OSTYPE" == "linux-gnu"* || "$OSTYPE" == "darwin"* ]]; then - # TODO (Caleb Aikens) figure out how to get Windows core dumps - ulimit -c unlimited - fi poetry run bash ./peter-jr ./tests/js/ - name: SSH debug session if: ${{ (success() || failure()) && github.event_name == 'workflow_dispatch' && inputs.debug_enabled_os == matrix.os && inputs.debug_enabled_python == matrix.python_version}} uses: fawazahmed0/action-debug@main with: credentials: "admin:admin" - - name: Upload core dumps as CI artifacts - uses: actions/upload-artifact@v3 - if: ${{ matrix.os != 'windows-2022' && failure() }} - # TODO (Caleb Aikens) figure out how to get Windows core dumps - with: - name: cores-${{ matrix.os }}-${{ matrix.python_version }} - path: /cores sdist: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 with: @@ -282,26 +337,13 @@ jobs: poetry build --format=sdist ls -lah ./dist/ - name: Upload sdist as CI artifacts - uses: actions/upload-artifact@v3 - with: - name: wheel-${{ github.run_id }}-${{ github.sha }} - path: ./dist/ - check-install-from-sdist: - needs: sdist - runs-on: ubuntu-24.04 - steps: - - uses: actions/setup-python@v5 - with: - python-version: '3.10' - - name: Download wheels built - uses: actions/download-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: wheel-${{ github.run_id }}-${{ github.sha }} + name: wheel-${{ github.run_id }}-${{ github.sha }}-sdist path: ./dist/ - - run: pip install ./dist/pythonmonkey-*.tar.gz publish: needs: [build-and-test, sdist] - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 if: ${{ success() && github.event_name == 'push' && github.ref_type == 'tag' }} steps: # no need to checkout @@ -310,9 +352,10 @@ jobs: python-version: '3.9' - run: pip install twine - name: Download wheels built - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - name: wheel-${{ github.run_id }}-${{ github.sha }} + pattern: wheel-${{ github.run_id }}-${{ github.sha }}-* + merge-multiple: true path: ./dist/ - run: ls -lah ./dist/ - name: Publish package @@ -324,7 +367,7 @@ jobs: # Implement a very basic Python package repository (https://peps.python.org/pep-0503/) # and deploy the static files to GitHub Pages needs: [build-and-test, sdist] - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 if: ${{ (success() || failure()) && (github.ref_name == 'main' || github.ref_type == 'tag') }} # publish nightly builds regardless of tests failure permissions: # grant GITHUB_TOKEN the permissions required to make a Pages deployment pages: write @@ -335,12 +378,13 @@ jobs: steps: # don't checkout - name: Download wheels built - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - name: wheel-${{ github.run_id }}-${{ github.sha }} + pattern: wheel-${{ github.run_id }}-${{ github.sha }}-* + merge-multiple: true path: ./dist/ - name: Download docs html generated by Doxygen - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: docs-${{ github.run_id }}-${{ github.sha }} path: ./docs/ @@ -374,16 +418,16 @@ jobs: html+="