diff --git a/.github/workflows/create-apps.yml b/.github/workflows/create-apps.yml new file mode 100644 index 00000000..ce880f3a --- /dev/null +++ b/.github/workflows/create-apps.yml @@ -0,0 +1,86 @@ +name: Create executables + +on: + pull_request: + types: [labeled] + +jobs: + build: + if: contains(github.event.pull_request.labels.*.name, 'create-builds') + strategy: + fail-fast: false + matrix: + os: + - macos-latest + - ubuntu-latest + - windows-latest + + runs-on: ${{ matrix.os }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies (Bash) + if: runner.os != 'Windows' + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install pyinstaller + pip install yahooquery + pip install tkmacosx + shell: bash + + - name: Install dependencies (PowerShell) + if: runner.os == 'Windows' + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install pyinstaller + pip install yahooquery + pip install tkmacosx + shell: pwsh + + - name: Create executable (macOS) + if: matrix.os == 'macos-latest' + run: | + pyinstaller --onefile --noconsole --add-data "assets:assets" user_interface.py + hdiutil create -volname UserInterface -srcfolder dist/ -ov -format UDZO user_interface.dmg + shell: bash + + - name: Create executable (Linux) + if: matrix.os == 'ubuntu-latest' + run: | + pyinstaller --onefile --noconsole --add-data "assets:assets" user_interface.py + shell: bash + + - name: Create executable (Windows) + if: matrix.os == 'windows-latest' + run: | + pyinstaller --onefile --noconsole --add-data "assets;assets" user_interface.py + shell: pwsh + + - name: Upload executable (macOS) + if: matrix.os == 'macos-latest' + uses: actions/upload-artifact@v4 + with: + name: user_interface-macOS + path: user_interface.dmg + + - name: Upload executable (Linux) + if: matrix.os == 'ubuntu-latest' + uses: actions/upload-artifact@v4 + with: + name: user_interface-Linux + path: dist/user_interface + + - name: Upload executable (Windows) + if: matrix.os == 'windows-latest' + uses: actions/upload-artifact@v4 + with: + name: user_interface-Windows + path: dist/user_interface.exe \ No newline at end of file diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 949f0900..73d8c724 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -10,7 +10,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: 'Set up Python ${{ matrix.python-version }}' - uses: actions/setup-python@v3 + uses: actions/setup-python@v5 with: python-version: '3.12' - name: Install dependencies diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..dec4323d --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,158 @@ +name: Build and Create Release + +on: + push: +# branches: +# - main +# pull_request: null + tags: + - 'v*.*.*' + +jobs: + build: + strategy: + fail-fast: false + matrix: + os: [macos-latest, ubuntu-latest, windows-latest] + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies (Bash) + if: runner.os != 'Windows' + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install pyinstaller + pip install yahooquery + pip install tkmacosx + shell: bash + + - name: Install dependencies (PowerShell) + if: runner.os == 'Windows' + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install pyinstaller + pip install yahooquery + pip install tkmacosx + shell: pwsh + + - name: Create executable (macOS) + if: matrix.os == 'macos-latest' + run: | + pyinstaller --onefile --noconsole --add-data "assets:assets" user_interface.py + hdiutil create -volname UserInterface -srcfolder dist/ -ov -format UDZO dist/user_interface.dmg + shell: bash + + - name: Create executable (Linux) + if: matrix.os == 'ubuntu-latest' + run: | + pyinstaller --onefile --noconsole --add-data "assets:assets" user_interface.py + shell: bash + + - name: Create executable (Windows) + if: matrix.os == 'windows-latest' + run: | + pyinstaller --onefile --noconsole --add-data "assets;assets" user_interface.py + shell: pwsh + + - name: Upload artifacts (macOS) + if: matrix.os == 'macos-latest' + uses: actions/upload-artifact@v4 + with: + name: user_interface-macOS + path: dist/user_interface.dmg + + - name: Upload artifacts (Linux) + if: matrix.os == 'ubuntu-latest' + uses: actions/upload-artifact@v4 + with: + name: user_interface-Linux + path: dist/user_interface + + - name: Upload artifacts (Windows) + if: matrix.os == 'windows-latest' + uses: actions/upload-artifact@v4 + with: + name: user_interface-Windows + path: dist/user_interface.exe + + release: + needs: build + runs-on: ubuntu-latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download macOS artifact + uses: actions/download-artifact@v4 + with: + name: user_interface-macOS + path: ./artifacts/macos + + - name: Download Linux artifact + uses: actions/download-artifact@v4 + with: + name: user_interface-Linux + path: ./artifacts/linux + + - name: Download Windows artifact + uses: actions/download-artifact@v4 + with: + name: user_interface-Windows + path: ./artifacts/windows + + - name: Install Ruby + run: sudo apt-get install ruby-full + + - name: Install GitHub Changelog Generator + run: sudo gem install github_changelog_generator + + - name: Generate CHANGELOG + run: | + github_changelog_generator -u cortisiko -p stockAnalysis --token ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + id: create_release + uses: actions/create-release@v1 + with: + tag_name: {{ github.ref }} + release_name: Release {{ github.ref }} + body_path: CHANGELOG.md + draft: true + prerelease: true + + - name: Upload Release Asset (macOS) + uses: actions/upload-release-asset@v1 + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./artifacts/macos/user_interface.dmg + asset_name: user_interface.dmg + asset_content_type: application/octet-stream + + - name: Upload Release Asset (Linux) + uses: actions/upload-release-asset@v1 + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./artifacts/linux/user_interface + asset_name: user_interface + asset_content_type: application/octet-stream + + - name: Upload Release Asset (Windows) + uses: actions/upload-release-asset@v1 + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./artifacts/windows/user_interface.exe + asset_name: user_interface-Windows.exe + asset_content_type: application/octet-stream \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..984fcde3 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog + + +### New Features 🎉 + +### Infra Changes 🛠 + +### Tests Changes 🤖 + +### Bug Fixes 🐛 + diff --git a/app/MainPage.png b/assets/MainPage.png similarity index 100% rename from app/MainPage.png rename to assets/MainPage.png diff --git a/app/charticon2ICO.ico b/assets/charticon2ICO.ico similarity index 100% rename from app/charticon2ICO.ico rename to assets/charticon2ICO.ico diff --git a/assets/charticon2ICO.png b/assets/charticon2ICO.png new file mode 100644 index 00000000..ba8abe67 Binary files /dev/null and b/assets/charticon2ICO.png differ diff --git a/app/stockx.ico b/assets/stockx.ico similarity index 100% rename from app/stockx.ico rename to assets/stockx.ico diff --git a/user_interface.py b/user_interface.py index 8589ee74..090e3b91 100644 --- a/user_interface.py +++ b/user_interface.py @@ -19,7 +19,15 @@ # Add the project root directory to the Python path -sys.path.append(os.path.dirname(os.path.dirname(__file__))) +if getattr(sys, 'frozen', False): + # If running as a PyInstaller bundle + # pylint: disable=protected-access + bundle_dir = sys._MEIPASS +else: + # If running in a normal Python environment + bundle_dir = os.path.abspath(os.path.dirname(__file__)) + +icon_path = os.path.join(bundle_dir, "assets/charticon2ICO.ico") class UserInterFace(tk.Tk): @@ -31,7 +39,7 @@ def __init__(self): tk.Tk.__init__(self) self.window_title = self.title("Stock Analyzer") container = tk.Frame(self) - self.icon_image = Image.open("app/charticon2ICO.ico") + self.icon_image = Image.open(icon_path) self.icon_photo = ImageTk.PhotoImage(self.icon_image) # Set the window icon @@ -104,6 +112,7 @@ def on_closing(self): """ print("Cleaning up and closing the application...") self.destroy() + sys.exit(0) # Ensure the application exits if __name__ == "__main__":