Skip to content

Commit

Permalink
Pin Python Version to 3.12.6 in GitHub Actions, Documentation (#200)
Browse files Browse the repository at this point in the history
* Update BUILDME.md around Version Specification

Re-word some bits, and change the upper section to point to the `tidal_wave/main.__version__` variable.

* Add type hints to pyinstaller.py

* Update GitHub Actions Python version to 3.12.6

* Pin Dockerfile Python to 3.12.6
  • Loading branch information
ebb-earl-co authored Sep 11, 2024
1 parent 68dd44d commit 0c5024c
Show file tree
Hide file tree
Showing 9 changed files with 28 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pyinstaller-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
architecture: "x64"
cache: "pip"
check-latest: false
python-version: "3.12.3"
python-version: "3.12.6"
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip setuptools wheel
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pyinstaller-macos_arm64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ jobs:
with:
cache: "pip"
check-latest: false
python-version: "3.12.3"
python-version: "3.12.6"
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip setuptools wheel
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pyinstaller-macos_x86.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ jobs:
architecture: "x64"
cache: "pip"
check-latest: false
python-version: "3.12.3"
python-version: "3.12.6"
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip pyinstaller setuptools wheel
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pyinstaller-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
with:
architecture: "x64"
cache: "pip"
python-version: "3.12.3"
python-version: "3.12.6"
- name: Install Python dependencies
shell: pwsh
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/python-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12.4"
python-version: "3.12.6"
cache: "pip"

- name: Install dependencies
Expand Down
11 changes: 6 additions & 5 deletions BUILDME.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# Python Package

`tidal-wave` is, first and foremost, a Python project that is built and uploaded to PyPi. Indeed, that is the sole purpose of `pyproject.toml` and `setup.py` at the root of the repository. No frameworks are used for this process such as `poetry` or `pipenv`, just the standard Python `setuptools` and `build`. To that end, the process of building a Python package for a given release is
1. change the line `version = ` in `pyproject.toml` to a new version. At the time of writing this, that would be `"2024.4.3"`. This is because PyPi disallows package name/version duplicates.
2. With a Python virtual environment, or, e.g. on a Debian-based OS, install the APT package `python3-build`, or, with the OS's system-wide Python3 installation, install the `build` package.
1. change the line `__version__ = ` in [`tidal_wave/main.py`](https://github.com/ebb-earl-co/tidal-wave/blob/trunk/tidal_wave/main.py#L32) to a new version. At the time of writing this, that would be `"2024.8.1"`. This is because PyPi disallows package name/version duplicates.
2. With a Python virtual environment, or, e.g. on a Debian-based OS, install the APT package `python3-build`; or, with the OS's system-wide Python3 installation, install the `build` package.
- I like to have a Python3 virtual environment created with the system Python3 in my home directory for all the bits and bobs required in development: `~/.venv`
3. From the repository root, simply run `$ python3 -m build` (or, on Windows, `> venv\Scripts\python.exe -m build`) and let the process run its course.
4. Once that process has finished, there will be two new files in the `dist` subdirectory of the repository root: `dist/tidal-wave-2024.4.3.tar.gz`, and `tidal_wave-2024.4.3-py3-none-any.whl`.
3. From the repository root, simply run `$ python3 -m build` (or, on Windows, `PS> .venv\Scripts\python.exe -m build`) and let the process run its course.
4. Once that process has finished, there will be two new files in the `dist` subdirectory of the repository root: `dist/tidal-wave-2024.8.1.tar.gz`, and `tidal_wave-2024.8.1-py3-none-any.whl`.
5. These binaries are uploaded to PyPi using GitHub Actions: in particular, the [`.github/workflows/python-build.yml`](https://github.com/ebb-earl-co/tidal-wave/blob/trunk/.github/workflows/python-build.yml) file

# `pyinstaller`-Created Binaries
Perhaps *the* tried and true method of packaging up a Python project into a single executable comes from the [PyInstaller](https://pyinstaller.org) project. It is the long-term preferred packaging format for `tidal-wave` as it allows for inclusion of arbitrary binary files into the executable apart from Python 3 itself. This is appealing, as `tidal-wave` fundamentally relies on FFmpeg for its successful execution, and it is desired to ship Python 3, FFmpeg, and the `tidal-wave` package as **one binary executable for each platform**.

However, PyInstaller wants to package up a single Python script into an easily-distributed format, yet `tidal-wave` is a Python *package*: the raison d'être of `pyinstaller.py` is to have a script to which PyInstaller can be pointed to in order to package up the project. It mimics the instructions that Python's `build` uses to build a Python package, but it does so in a single .py file (*not* named setup.py) so that PyInstaller is satisfied. Additionally, PyInstaller would like a virtual environment with `tidal-wave`'s Python dependencies installed already, so the process starts with that:
However, PyInstaller wants to package up a single Python script into an easily-distributed format, yet `tidal-wave` is a Python *package*: the raison d'être of `pyinstaller.py` is to have a script to which PyInstaller can be pointed in order to create an executable out of the project. It mimics the instructions that Python's `build` uses to build a Python package, but it does so in a single .py file (*not* named setup.py) so that PyInstaller is satisfied. Additionally, PyInstaller would like a virtual environment with `tidal-wave`'s Python dependencies installed already, so the process starts with that:
1. Create virtual environment in repository root: `$ "$(command -v python3)" -m venv ./venv` and install `tidal-wave`'s dependencies
- `$ ./venv/bin/python3 -m pip install --upgrade pip setuptools wheel`
- `$ ./venv/bin/python3 -m pip install -r requirements.txt`
Expand All @@ -33,6 +33,7 @@ However, PyInstaller wants to package up a single Python script into an easily-d
4. For `tidal-wave` starting with version 2024.4.1, the following invocation is what creates the artifacts released with every version:
```bash
# FFmpeg 7.0 is compiled before this step in the directory `ffmpeg-n7.0`
# `ffmpeg-n7.0` is exactly [FFmpeg source code at tag n7.0](https://github.com/FFmpeg/FFmpeg/releases/tag/n7.0)
./venv/bin/pyinstaller \
--name tidal-wave_linux \
--paths tidal_wave \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ RUN ./configure \
--enable-small \
&& make -j$(nproc) && make install && hash -r

FROM docker.io/library/python:3.12-slim
FROM docker.io/library/python:3.12.6-slim
LABEL org.opencontainers.image.authors="colinho <github@colin.technology>"
LABEL org.opencontainers.image.description="Waving at the TIDAL music service with Python"
LABEL org.opencontainers.image.documentation="https://github.com/ebb-earl-co/tidal-wave/blob/trunk/README.md"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ $ source .venv/bin/activate
$ (.venv) pip install .
```
### PyInstaller executable
The release artifacts for this project are created with [PyInstaller](https://pyinstaller.org). It bundles Python 3.12.3, FFmpeg 7.0, and the `tidal-wave` program into one binary, licensed under the terms of FFmpeg: with the [GNU Lesser General Public License (LGPL) version 2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html). Installation is as simple as downloading the correct binary for your platform giving it execute permissions, and running it. **Please make sure that the SHA256 checksum of the file that you have downloaded matches the corresponding `.sha256` file on the releases page!**
The release artifacts for this project are created with [PyInstaller](https://pyinstaller.org). It bundles Python 3.12.6, FFmpeg 7.0, and the `tidal-wave` program into one binary, licensed under the terms of FFmpeg: with the [GNU Lesser General Public License (LGPL) version 2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html). Installation is as simple as downloading the correct binary for your platform giving it execute permissions, and running it. **Please make sure that the SHA256 checksum of the file that you have downloaded matches the corresponding `.sha256` file on the releases page!**
#### On Unix-Like
```bash
$ wget https://github.com/ebb-earl-co/tidal-wave/releases/latest/download/tidal-wave_ubuntu_24.04_amd64
Expand Down
22 changes: 15 additions & 7 deletions pyinstaller.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""A version of main.py with current Python syntax just for use with pyinstaller."""
"""A version of main.py with current Python syntax just for use with Pyinstaller."""

from __future__ import annotations

Expand Down Expand Up @@ -144,7 +144,10 @@ def main(
with closing(CacheControl(s)) as session:
match tidal_resource:
case TidalTrack():
track = Track(track_id=tidal_resource.tidal_id, transparent=transparent)
track: Track = Track(
track_id=tidal_resource.tidal_id,
transparent=transparent,
)
track.get(
session=session,
audio_format=audio_format,
Expand All @@ -156,7 +159,10 @@ def main(
track.dump()
raise typer.Exit(code=0)
case TidalAlbum():
album = Album(album_id=tidal_resource.tidal_id, transparent=transparent)
album: Album = Album(
album_id=tidal_resource.tidal_id,
transparent=transparent,
)
album.get(
session=session,
audio_format=audio_format,
Expand All @@ -168,7 +174,7 @@ def main(
album.dump()
raise typer.Exit(code=0)
case TidalArtist():
artist = Artist(
artist: Artist = Artist(
artist_id=tidal_resource.tidal_id,
transparent=transparent,
)
Expand All @@ -181,14 +187,16 @@ def main(
)
raise typer.Exit(code=0)
case TidalVideo():
video = Video(video_id=tidal_resource.tidal_id, transparent=transparent)
video: Video = Video(
video_id=tidal_resource.tidal_id, transparent=transparent
)
video.get(session=session, out_dir=output_directory)

if loglevel == LogLevel.debug:
video.dump()
raise typer.Exit(code=0)
case TidalPlaylist():
playlist = Playlist(
playlist: Playlist = Playlist(
playlist_id=tidal_resource.tidal_id,
transparent=transparent,
)
Expand All @@ -211,7 +219,7 @@ def main(
playlist.dump()
raise typer.Exit(code=0)
case TidalMix():
mix = Mix(mix_id=tidal_resource.tidal_id, transparent=transparent)
mix: Mix = Mix(mix_id=tidal_resource.tidal_id, transparent=transparent)
if no_flatten:
mix.get_elements(
session=session,
Expand Down

0 comments on commit 0c5024c

Please sign in to comment.