diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..77f5152 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,96 @@ +name: Build, upload artifact and create release + +on: + push: + tags: + - "*.*.*" + pull_request: + types: [opened, reopened, synchronize, ready_for_review, labeled] + +jobs: + build: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v4 + with: + python-version: 3.9 + + - name: Install dependencies + run: pip3 install -r requirements.txt + + - name: Install PyInstaller + run: pip install pyinstaller + + - name: Create PyInstaller spec file + run: pyi-makespec --onefile dance.py + + - name: Edit PyInstaller spec file to include static folder + shell: pwsh + run: | + $specFile = Get-Content dance.spec + $specFile = $specFile -replace "datas=\[\]", "datas=[('static', 'static')]" + $specFile | Set-Content dance.spec + + - name: Build executable + run: pyinstaller dance.spec + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: joydance-win64-executable + path: dist/dance.exe + + test_run_artifact: + needs: build + runs-on: windows-latest + steps: + - uses: actions/download-artifact@v4 + with: + name: joydance-win64-executable + path: ./dist + - name: Run the artifact + run: | + Start-Process -FilePath "./dist/dance.exe" + Start-Sleep -Seconds 30 # Run for 30 seconds + Stop-Process -Name "dance" # Replace with the actual process name if different + shell: pwsh + + create_release: + needs: test_run_artifact + runs-on: ubuntu-latest + if: ${{ startsWith(github.ref, 'refs/tags/') }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Determine Tags to use for changelog + id: determine_tags + run: | + # Get the latest tag + LATEST_TAG=$(git describe --tags --abbrev=0) + + # Get the tag before the latest tag + PREVIOUS_TAG=$(git describe --tags --abbrev=0 $LATEST_TAG^) + + echo "Latest tag: $LATEST_TAG" + echo "Previous tag: $PREVIOUS_TAG" + echo "PREVIOUS_TAG=$PREVIOUS_TAG" >> $GITHUB_ENV + echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_ENV + + - name: Create Changelog + run: git log --pretty=format:"%h - %s (@%an)" $PREVIOUS_TAG..$LATEST_TAG > ${{ github.workspace }}-${{ github.env.LATEST_TAG }}-CHANGELOG.txt + + - uses: actions/download-artifact@v4 + with: + name: joydance-win64-executable + path: ./dist + + - uses: softprops/action-gh-release@v2 + with: + files: ./dist/dance.exe + body_path: ${{ github.workspace }}-${{ github.env.LATEST_TAG }}-CHANGELOG.txt + tag_name: ${{ github.env.LATEST_TAG }} diff --git a/dance.py b/dance.py index 346b98e..61a128f 100644 --- a/dance.py +++ b/dance.py @@ -1,9 +1,11 @@ import asyncio import json import logging +import os import platform import re import socket +import sys import time from configparser import ConfigParser from enum import Enum @@ -278,16 +280,6 @@ async def on_startup(app): if JOYDANCE_VERSION != latest_version: print('\033[93m{}\033[00m'.format('Version {} is available: https://github.com/redphx/joydance'.format(latest_version))) - -async def html_handler(request): - config = dict((parse_config()).items('joydance')) - with open('static/index.html', 'r') as f: - html = f.read() - html = html.replace('[[CONFIG]]', json.dumps(config)) - html = html.replace('[[VERSION]]', JOYDANCE_VERSION) - return web.Response(text=html, content_type='text/html') - - async def ws_send_response(ws, cmd, data): resp = { 'cmd': 'resp_' + cmd.value, @@ -325,21 +317,38 @@ async def websocket_handler(request): return ws -def favicon_handler(request): - return web.FileResponse('static/favicon.png') - - app = web.Application() app['joydance_connections'] = {} app['joycons_info'] = {} app.on_startup.append(on_startup) + +if getattr(sys, 'frozen', False): + # if you are running in a |PyInstaller| bundle + extDataDir = sys._MEIPASS + #you should use extDataDir as the path to your file +else: + # we are running in a normal Python environment + extDataDir = os.getcwd() + #you should use extDataDir as the path to your file + +def favicon_handler(request): + return web.FileResponse(os.path.join(extDataDir, 'static/favicon.png')) + +async def html_handler(request): + config = dict((parse_config()).items('joydance')) + with open(os.path.join(extDataDir,'static/index.html'), 'r') as f: + html = f.read() + html = html.replace('[[CONFIG]]', json.dumps(config)) + html = html.replace('[[VERSION]]', JOYDANCE_VERSION) + return web.Response(text=html, content_type='text/html') + app.add_routes([ web.get('/', html_handler), web.get('/favicon.png', favicon_handler), web.get('/ws', websocket_handler), - web.static('/css', 'static/css'), - web.static('/js', 'static/js'), + web.static('/css', os.path.join(extDataDir, 'static/css')), + web.static('/js', os.path.join(extDataDir, 'static/js')), ]) web.run_app(app, port=32623)