├── .gitattributes ├── Dockerfile ├── .github └── ISSUE_TEMPLATE │ └── bug_report.md ├── LICENSE ├── action.yml ├── entrypoint.sh ├── .gitignore └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM cdrx/pyinstaller-linux 2 | 3 | COPY entrypoint.sh /entrypoint.sh 4 | RUN chmod +x /entrypoint.sh 5 | 6 | ENTRYPOINT ["/entrypoint.sh"] 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Fizban 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | # action.yaml 2 | name: "PyInstaller Linux" 3 | description: "Customisable GitHub Action to package your python code with PyInstaller for Linux" 4 | branding: 5 | icon: "box" 6 | color: "blue" 7 | inputs: 8 | path: 9 | description: "Directory containing source code & .spec file (optional requirements.txt)." 10 | required: True 11 | default: src 12 | pypi_url: 13 | description: "Specify a custom URL for PYPI" 14 | required: False 15 | default: https://pypi.python.org/ 16 | pypi_index_url: 17 | description: "Specify a custom URL for PYPI Index" 18 | required: False 19 | default: https://pypi.python.org/simple 20 | spec: 21 | description: "Specify a file path for .spec file" 22 | required: False 23 | default: "" 24 | tkinter: 25 | description: "Specify whether to install Tkinter or not" 26 | required: False 27 | default: "false" 28 | requirements: 29 | description: 'Specify a file path for requirements.txt file' 30 | required: False 31 | default: "requirements.txt" 32 | gooey: 33 | description: "Specify whether to install Gooey or not" 34 | required: False 35 | default: "true" 36 | outputs: 37 | output: 38 | description: "The output of PyInstaller" 39 | 40 | runs: 41 | using: "docker" 42 | image: "Dockerfile" 43 | args: 44 | - ${{ inputs.path }} #$1 45 | - ${{ inputs.pypi_url }} #$2 46 | - ${{ inputs.pypi_index_url }} #$3 47 | - ${{ inputs.spec }} #$4 48 | - ${{ inputs.tkinter }} #$5 49 | - ${{ inputs.requirements }} #$6 50 | - ${{ inputs.gooey }} #$7 51 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -i 2 | 3 | # Fail on errors. 4 | # set -im 5 | 6 | # Make sure .bashrc is sourced 7 | . /root/.bashrc 8 | 9 | # Allow the workdir to be set using an env var. 10 | # Useful for CI pipiles which use docker for their build steps 11 | # and don't allow that much flexibility to mount volumes 12 | SRCDIR=$1 13 | 14 | PYPI_URL=$2 15 | 16 | PYPI_INDEX_URL=$3 17 | 18 | WORKDIR=${SRCDIR:-/src} 19 | 20 | SPEC_FILE=${4:-*.spec} 21 | 22 | /root/.pyenv/shims/python -m pip install --upgrade pip wheel setuptools 23 | 24 | # 25 | # In case the user specified a custom URL for PYPI, then use 26 | # that one, instead of the default one. 27 | # 28 | if [[ "$PYPI_URL" != "https://pypi.python.org/" ]] || \ 29 | [[ "$PYPI_INDEX_URL" != "https://pypi.python.org/simple" ]]; then 30 | # the funky looking regexp just extracts the hostname, excluding port 31 | # to be used as a trusted-host. 32 | mkdir -p /root/.pip 33 | echo "[global]" > /root/.pip/pip.conf 34 | echo "index = $PYPI_URL" >> /root/.pip/pip.conf 35 | echo "index-url = $PYPI_INDEX_URL" >> /root/.pip/pip.conf 36 | echo "trusted-host = $(echo $PYPI_URL | perl -pe 's|^.*?://(.*?)(:.*?)?/.*$|$1|')" >> /root/.pip/pip.conf 37 | 38 | echo "Using custom pip.conf: " 39 | cat /root/.pip/pip.conf 40 | fi 41 | 42 | cd $WORKDIR 43 | 44 | 45 | if [[ $7 == "true" ]]; then 46 | echo "UPDATE PACKAGE" 47 | apt-get update 48 | echo "UPGRADE PACKAGE" 49 | apt-get upgrade -y 50 | 51 | echo "Install Gooey Dependencies" 52 | apt-get install -y libwxbase3.0-0v5 libwxgtk-media3.0-gtk3-0v5 libwxgtk-webview3.0-gtk3-0v5 \ 53 | libwxgtk3.0-gtk3-0v5 python3-wxgtk-media4.0 python3-wxgtk-webview4.0 python3-wxgtk4.0 \ 54 | libgtk-3-dev libjpeg-dev 55 | # /root/.pyenv/shims/pip install gooey 56 | fi # [$7] 57 | 58 | if [ -f $6 ]; then 59 | /root/.pyenv/shims/pip install -r $6 60 | fi # [ -f $6 ] 61 | 62 | 63 | /root/.pyenv/shims/pyinstaller --clean -y --dist ./dist/linux --workpath /tmp $SPEC_FILE 64 | 65 | chown -R --reference=. ./dist/linux -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # celery beat schedule file 95 | celerybeat-schedule 96 | 97 | # SageMath parsed files 98 | *.sage.py 99 | 100 | # Environments 101 | .env 102 | .venv 103 | env/ 104 | venv/ 105 | ENV/ 106 | env.bak/ 107 | venv.bak/ 108 | 109 | # Spyder project settings 110 | .spyderproject 111 | .spyproject 112 | 113 | # Rope project settings 114 | .ropeproject 115 | 116 | # mkdocs documentation 117 | /site 118 | 119 | # mypy 120 | .mypy_cache/ 121 | .dmypy.json 122 | dmypy.json 123 | 124 | # Pyre type checker 125 | .pyre/ 126 | 127 | # Contains example 128 | src/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyInstaller-Action-Linux 2 | 3 | Github Action for building executables with PyInstaller for running on Linux 4 | 5 | To build your application, you need to specify where your source code is via the `path` argument, this defaults to `src`. 6 | 7 | The source code directory should have your `.spec` file that PyInstaller generates. If you don't have one, you'll need to run PyInstaller once locally to generate it. Also if you have another program `.spec` file you can set specific pyinstaller `.spec` file by `spec: ` 8 | 9 | If the `src` folder has a `requirements.txt` file, the packages will be installed into the environment before PyInstaller runs. 10 | 11 | If you wish to specify a package mirror, this is possibly via the `pypi_url` and/or the `pypi_index_url`, these defaults are: 12 | 13 | - `pypi_url` = `https://pypi.python.org/` 14 | - `pypi_index_url` = `https://pypi.python.org/simple` 15 | 16 | If the application requires `Tkinter`, ensure to use the `tkinter` branch of this repository (eg JackMcKew/pyinstaller-action-linux@tkinter), as this will undergo the steps to install `tkinter` and please set the `tkinter` argument to true (this is under the `with` similar to how path is defined). Note that this will slow the action down considerably as Python will need to be uninstalled & rebuilt once `tkinter` is installed 17 | 18 | > If you are using the default Python `gitignore` file, ensure to remove `.spec` 19 | 20 | ## Example usage 21 | 22 | Include this in your `.github/workflows/main.yaml`: 23 | 24 | ```yaml 25 | - name: PyInstaller Linux 26 | uses: JackMcKew/pyinstaller-action-linux@main 27 | with: 28 | path: src 29 | ``` 30 | 31 | ## Full Example 32 | 33 | Here is an entire workflow for: 34 | 35 | - Packaging an application with PyInstaller 36 | - Uploading the packaged executable as an artifact 37 | 38 | ``` yaml 39 | 40 | name: Package Application with Pyinstaller 41 | 42 | on: 43 | push: 44 | branches: [ master ] 45 | pull_request: 46 | branches: [ master ] 47 | 48 | jobs: 49 | build: 50 | 51 | runs-on: ubuntu-latest 52 | 53 | steps: 54 | - uses: actions/checkout@v2 55 | 56 | - name: Package Application 57 | uses: JackMcKew/pyinstaller-action-linux@main 58 | with: 59 | path: src 60 | 61 | - uses: actions/upload-artifact@v2 62 | with: 63 | name: name-of-artifact 64 | path: src/dist/linux 65 | ``` 66 | 67 | 68 | ## Python 3.10 69 | 70 | If you are running into problems, please try using the branch `python3.10`: 71 | 72 | ``` yaml 73 | - name: PyInstaller Linux 74 | uses: JackMcKew/pyinstaller-action-linux@python3.10 75 | with: 76 | path: src 77 | ``` 78 | 79 | 80 | ## Sources 81 | 82 | A big thank you to all the contributors over at , this action is just a modified version of their docker container, thank you! 83 | --------------------------------------------------------------------------------