diff --git a/.github/scripts/check_python_version.py b/.github/scripts/check_python_version.py index 9fbb8e1..24a76fd 100644 --- a/.github/scripts/check_python_version.py +++ b/.github/scripts/check_python_version.py @@ -1,6 +1,6 @@ import sys -def check_version(version): +def check_version(version, freethreaded): split_version = version.split('.') if int(split_version[0]) != sys.version_info[0]: return False @@ -8,11 +8,21 @@ def check_version(version): return False if split_version[2] != 'x' and int(split_version[2].split('-')[0]) != sys.version_info[2]: return False + if freethreaded: + try: + if sys._is_gil_enabled(): + return False + except: + return False return True if __name__ == '__main__': version = sys.argv[1] + freethreaded = False + if version.endswith("t"): + freethreaded = True + version = version[:-1] while version.count('.') < 2: version += '.x' - if not check_version(version): + if not check_version(version, freethreaded): raise ValueError('Expected python version to be ' + str(version) + ', got ' + str(sys.version_info.major) + '.' + str(sys.version_info.minor) + '.' + str(sys.version_info.micro) + '.') \ No newline at end of file diff --git a/.github/scripts/create_python_matrix.py b/.github/scripts/create_python_matrix.py index f766882..e8eee1d 100644 --- a/.github/scripts/create_python_matrix.py +++ b/.github/scripts/create_python_matrix.py @@ -18,8 +18,13 @@ short_tag = tag.name.replace('v', '') while short_tag.count('.') > 1: short_tag = short_tag[:-1] - if float(short_tag) >= 2.7 and short_tag not in json_dict['python-version']: + splits = short_tag.split('.') + major = int(splits[0]) + minor = int(splits[1]) + if major == 3 and minor >= 8 and short_tag not in json_dict['python-version']: json_dict['python-version'].append(short_tag) + if minor >= 13: + json_dict['python-version'].append(f"{short_tag}t") with open(os.environ['GITHUB_OUTPUT'], 'a') as fh: print(f'matrix={json.dumps(json_dict)}', file=fh) \ No newline at end of file diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 12da61d..0b2a7b4 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -8,11 +8,10 @@ on: description: Specific version to check type: string allow-prereleases: - required: true - default: false - description: Include prereleases in the check - type: boolean - + required: true + default: false + description: Include prereleases in the check + type: boolean jobs: test_python_build: @@ -24,8 +23,9 @@ jobs: os: [macos-latest, windows-latest, ubuntu-latest] steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v5 with: + persist-credentials: false submodules: recursive - name: Test action with Python ${{ inputs.python-version }} id: build @@ -35,4 +35,4 @@ jobs: allow-build: info allow-prereleases: ${{ inputs.allow-prereleases }} - name: Check Python version - run: python ./.github/scripts/check_python_version.py ${{ inputs.python-version }} \ No newline at end of file + run: python ./.github/scripts/check_python_version.py ${{ inputs.python-version }} diff --git a/.github/workflows/periodic_check.yml b/.github/workflows/periodic_check.yml index c2bcc8a..6253b48 100644 --- a/.github/workflows/periodic_check.yml +++ b/.github/workflows/periodic_check.yml @@ -4,7 +4,6 @@ on: schedule: - cron: 0 0 * * * workflow_dispatch: - jobs: # Create strategy matrix with a python script @@ -15,8 +14,9 @@ jobs: matrix-json: ${{ steps.matrix.outputs.matrix }} steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v5 with: + persist-credentials: false submodules: recursive - name: Update pip run: python -m pip install --upgrade pip @@ -27,7 +27,7 @@ jobs: - name: Create matrix id: matrix run: python ./.github/scripts/create_python_matrix.py true - + # Test the action with all possible combinations of python versions and os test_action: needs: create_matrix @@ -38,14 +38,15 @@ jobs: matrix: ${{ fromJSON(needs.create_matrix.outputs.matrix-json) }} steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v5 with: + persist-credentials: false submodules: recursive - name: Setup Python ${{ matrix.python-version }} - uses: MatteoH2O1999/setup-python@v1 + uses: MatteoH2O1999/setup-python@v6 with: python-version: ${{ matrix.python-version }} allow-build: info cache-build: ${{ matrix.cache }} - name: Check Python version - run: python ./.github/scripts/check_python_version.py ${{ matrix.python-version }} \ No newline at end of file + run: python ./.github/scripts/check_python_version.py ${{ matrix.python-version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 16565fc..32f1602 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,8 +10,10 @@ jobs: update_tags: runs-on: ubuntu-latest name: Update version tags + permissions: + contents: write steps: - name: Update tags - uses: actions/publish-action@v0.2.2 + uses: actions/publish-action@v0.4.0 with: - source-tag: ${{ github.event.release.tag_name }} \ No newline at end of file + source-tag: ${{ github.event.release.tag_name }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b0b71e0..54950f7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,8 +20,9 @@ jobs: matrix-json: ${{ steps.matrix.outputs.matrix }} steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v5 with: + persist-credentials: false submodules: recursive - name: Update pip run: python -m pip install --upgrade pip @@ -32,7 +33,7 @@ jobs: - name: Create matrix id: matrix run: python ./.github/scripts/create_python_matrix.py false - + # Test the action with all possible combinations of python versions and os test_action: needs: create_matrix @@ -43,8 +44,9 @@ jobs: matrix: ${{ fromJSON(needs.create_matrix.outputs.matrix-json) }} steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v5 with: + persist-credentials: false submodules: recursive - name: Setup Python ${{ matrix.python-version }} uses: ./ @@ -52,4 +54,4 @@ jobs: python-version: ${{ matrix.python-version }} allow-build: info - name: Check Python version - run: python ./.github/scripts/check_python_version.py ${{ matrix.python-version }} \ No newline at end of file + run: python ./.github/scripts/check_python_version.py ${{ matrix.python-version }} diff --git a/README.md b/README.md index be4756e..29b3941 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,6 @@ This action wraps around [actions/setup-python](https://github.com/actions/setup - [Table of contents](#table-of-contents) - [Basic usage](#basic-usage) - [Motivation](#motivation) - - [But why? It's deprecated: just use a more recent version](#but-why-its-deprecated-just-use-a-more-recent-version) - - [But why a dedicated action? Just use `ubuntu-20.04` for that 1 job](#but-why-a-dedicated-action-just-use-ubuntu-2004-for-that-1-job) - [Guarantees](#guarantees) - [Known limits](#known-limits) - [Performance](#performance) @@ -22,6 +20,8 @@ This action wraps around [actions/setup-python](https://github.com/actions/setup - [Inputs](#inputs) - [allow-build input](#allow-build-input) - [Outputs](#outputs) + - [FAQ](#faq) + - [No file in (...) matched to \[\*\*/requirements.txt or \*\*/pyproject.toml\], make sure you have checked out the target repository](#no-file-in--matched-to-requirementstxt-or-pyprojecttoml-make-sure-you-have-checked-out-the-target-repository) - [Contributing](#contributing) ## Basic usage @@ -30,18 +30,17 @@ For a more complete view on the actions see [action.yml](action.yml) or look in In general you could replace the original action with this one and it should already work (all its supported inputs are also supported in this one): ```yaml -- uses: MatteoH2O1999/setup-python@v1 +- uses: MatteoH2O1999/setup-python@v6 with: - python-version: '3.6' - cache: pip + python-version: '3.8' ``` But if you wish for a more optimized experience you could use inputs exclusive to this action: ```yaml -- uses: MatteoH2O1999/setup-python@v1 +- uses: MatteoH2O1999/setup-python@v6 with: - python-version: '3.6' + python-version: '3.8' allow-build: info cache-build: true cache: pip @@ -49,37 +48,23 @@ But if you wish for a more optimized experience you could use inputs exclusive t ## Motivation -Since the replacement of `ubuntu-20.04` with `ubuntu-22.04` runner images [actions/setup-python](https://github.com/actions/setup-python) no longer supports `Python 3.6` for the `ubuntu-latest` label. -This broke a large number of pipelines as Python 3.6 is still widely used. - -This made apparent that a way to support deprecated versions was needed. - -### But why? It's deprecated: just use a more recent version - -Yes, in a perfect world that would be the go to solution. -Unfortunately, we do not live in that world, so we can't always choose our dependencies. -In fact, I would be willing to bet that most deprecated dependencies are there despite the developers, not because of them. -That is why this action came about: to offer an easier way to continue supporting deprecated builds even if github does not anymore. - -### But why a dedicated action? Just use `ubuntu-20.04` for that 1 job +While initially this action was meant to guarantee a successful build of all CPython versions `2.7`, it has now become too complex to maintain it. -Once again, that is possible, but that is - -1. not good practice as editing the main job matrix will not edit the "special" one; -2. a pain to maintain as each new deprecated version needs another job to be created. +The new objective of this action is to provide a buffer when something gets yanked out by Github, as this will guarantee that if the pair `(label, version)` works, it will keep working. +Older versions may still work, but no effort will be spent in ensuring so. ## Guarantees -The objective of this action is to guarantee that for every major Python version starting from `2.7` at least one specific version can be successfully installed on the `...-latest` images using the default architecture. +The objective of this action is to guarantee that for every major Python version starting from `3.8` at least one specific version can be successfully installed on the `...-latest` images using the default architecture. -TLDR: If you use the major version specification (`3.6` instead of `3.6.5`) without specifying the architecture as shown in [Basic usage](#basic-usage) this action is guaranteed to work (hopefully...😉) on all the `...-latest` labels. +TLDR: If you use the major version specification (`3.8` instead of `3.8.5`) without specifying the architecture as shown in [Basic usage](#basic-usage) this action is guaranteed to work (hopefully...😉) on all the `...-latest` labels. ## Known limits This action at the moment does not support: -- installing multiple Python versions; -- building PyPy from source; +- installing multiple Python versions +- building PyPy from source - building from source in UNIX systems for a different architecture This actions tries to but does not guarantee to work on any arbitrary pair (`python-version`, `architecture`). @@ -126,6 +111,7 @@ This action supports the following inputs (in bold are the names of the exclusiv |token|The token used to authenticate when fetching Python distributions from [actions/python-versions](https://github.com/actions/python-versions). 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.|example: `TokenString`|`github.token`| |cache-dependency-path|Used to specify the path to dependency files. Supports wildcards or a list of file names for caching multiple dependencies.|example: `path/to/dependency/files`|`''`| |update-environment|Set this option if you want the action to update environment variables.|`true`, `false`|`true`| +|freethreaded| When 'true', use the freethreaded version of Python.|`true`, `false`|`false`| |**cache-build**|Whether to cache the built Python distribution to speed up successive runs.|`true`, `false`|`false`| |**allow-build**|Set the behavior of the action when [actions/setup-python](https://github.com/actions/setup-python) fails and has to be built from source.|`allow`, `info`, `warn`, `error`, `force`|`warn`| @@ -149,6 +135,14 @@ This action will emit the following outputs: |cache-hit|A boolean value to indicate a cache entry was found (for pip, pipenv and poetry).| |python-path|The absolute path to the Python or PyPy executable.| +## FAQ + +### No file in (...) matched to [**/requirements.txt or **/pyproject.toml], make sure you have checked out the target repository + +This is a byproduct of [actions/setup-python](https://github.com/actions/setup-python). +If you wish to cache your pip dependencies, you need to have anywhere in your repository a `requirements.txt` or a `pyproject.toml` file. +The solution in this case is either creating a blank `requirements.txt` file or stop caching pip (in order to do so simply remove `cache: pip` from your `.yml` file). + ## Contributing This action is pretty much only a wrapper for a javascript action. diff --git a/action.yml b/action.yml index 404f247..a4388ea 100644 --- a/action.yml +++ b/action.yml @@ -36,6 +36,9 @@ inputs: allow-prereleases: description: "When 'true', a version range passed to 'python-version' input will match prerelease versions if no GA versions are found. Only 'x.y' version range is supported for CPython." default: false + freethreaded: + description: "When 'true', use the freethreaded version of Python." + default: false outputs: python-version: description: "The installed Python or PyPy version. Useful when given a version range as input." @@ -49,7 +52,7 @@ outputs: runs: using: composite steps: - - uses: MatteoH2O1999/build-and-install-python@004dc2989b38616af18eb8aba45fe49d5f813264 + - uses: MatteoH2O1999/build-and-install-python@a6b9b8e2b6b4f57808cb6b7707b160744354860a id: build with: python-version: ${{ inputs.python-version }} @@ -60,7 +63,8 @@ runs: allow-build: ${{ inputs.allow-build }} token: ${{ inputs.token }} allow-prereleases: ${{ inputs.allow-prereleases }} - - uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0 + freethreaded: ${{ inputs.freethreaded }} + - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c id: setup with: python-version: ${{ steps.build.outputs.python-version }} @@ -70,6 +74,7 @@ runs: token: ${{ inputs.token }} cache-dependency-path: ${{ inputs.cache-dependency-path }} update-environment: ${{ inputs.update-environment }} + freethreaded: ${{ steps.build.outputs.freethreaded }} - run: ${{ github.action_path }}/setup_pip.ps1 shell: pwsh env: