Skip to content

Extract memo information from PNG file Comment tag and display in Knitting Progress window #159

Extract memo information from PNG file Comment tag and display in Knitting Progress window

Extract memo information from PNG file Comment tag and display in Knitting Progress window #159

# This workflow builds the AYAB release packages
# for Windows, Mac OSX, and Ubuntu/Debian Linux.
#
# The build starts when a version tag is pushed.
# Release assets are also uploaded as workflow
# artifacts, so that they are still available
# for test releases after the release and its
# tag have been deleted.
#
# Script adapted from https://github.com/trappitsch/fbs-release-github-actions
#
# @author Tom Price
# @date July 2020
name: Build
on: [push, pull_request]
env:
PYTHON_VERSION: 3.11.9
jobs:
build-windows:
name: Create and upload Windows build
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0 # necessary for `git describe`
- uses: ./.github/actions/init-environment
id: vars
- name: Get firmware version matching manifest
shell: bash
working-directory: src/main/resources/base/ayab/firmware/
run: |
curl --fail -O '${{ steps.vars.outputs.firmware-url }}'
- name: Install dependencies
shell: pwsh
run: |
choco install vcredist2010 # fixes dependency on msvcr100.dll
python -m pip install --upgrade pip
python -m pip install -r requirements.build.txt
python -m pip install -r windows-build\windows_build_requirements.txt
- name: Convert UI and translation files
run: |
bash setup-environment.ps1
- name: Remove unneeded files
shell: bash
run: |
rm src/main/python/main/ayab/*_gui.ui
rm src/main/python/main/ayab/ayab_logo_rc.qrc
- name: Change line endings to CRLF
shell: bash
run: |
for f in $(ls /main/python/main/ayab/*_gui.py)
do
unix2dos $f
done
for f in $(ls /main/python/main/ayab/engine/*_gui.py)
do
unix2dos $f
done
# The OpenSSL-based backend for QtNetwork requires the OpenSSL dynamic
# libraries but they are not packaged with Qt or PySide. Pyinstaller
# tries to find them for us and make them available, but does not
# always succeed, see https://github.com/pyinstaller/pyinstaller/issues/8857
# What we can do instead is disable the OpenSSL backend by deleting the
# relevant plugin — this way, Pyinstaller won't package OpenSSL DLLs,
# and Qt will silently fall back to the `schannel` backend that uses
# native Windows libraries. Note that deleting the plugin is an approach
# that is actually suggested in the Qt documentation, see
# https://doc.qt.io/qt-6/ssl.html#considerations-while-packaging-your-application
- name: Remove OpenSSL QtNetwork backend
shell: bash
run: |
find "$(python -c 'import PySide6;print(PySide6.__path__[0])')" -iname qopensslbackend.dll -delete
- name: Build app
shell: pwsh
run: python -m fbs freeze
- name: Create installer
shell: pwsh
run: |
python -m fbs installer
Move-Item -Path target\AYABSetup.exe -Destination target\AYAB-${{ steps.vars.outputs.tag }}.exe
- name: Attach installer to release
uses: ncipollo/release-action@v1
if: steps.vars.outputs.do-release == 'true'
with:
token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ steps.vars.outputs.tag }}
commit: ${{ steps.vars.outputs.sha }}
# Default to draft and prerelease to let a human check the release before it goes live
draft: true
prerelease: false
allowUpdates: true
artifacts: target/AYAB-${{ steps.vars.outputs.tag }}.exe
artifactContentType: application/exe
replacesArtifacts: true
# Avoid overwriting a release that may have been manually edited
omitNameDuringUpdate: true
omitBodyDuringUpdate: true
omitDraftDuringUpdate: true
omitPrereleaseDuringUpdate: true
- uses: actions/upload-artifact@v4
with:
name: AYAB-${{ steps.vars.outputs.tag }}.exe
path: target/AYAB-${{ steps.vars.outputs.tag }}.exe
build-macos:
name: Create and upload Mac OSX build
runs-on: macos-14
env:
APPLE_CERTIFICATE_NAME: ${{ secrets.APPLE_CERTIFICATE_NAME }}
APPLE_STORE_CONNECT_KEY_ID: ${{ secrets.APPLE_STORE_CONNECT_KEY_ID }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0 # necessary for `git describe`
- uses: ./.github/actions/init-environment
id: vars
- name: Get firmware version matching manifest
shell: bash
working-directory: src/main/resources/base/ayab/firmware/
run: |
curl --fail -O '${{ steps.vars.outputs.firmware-url }}'
- name: Install dependencies
run: |
mkdir tmp-wheel/
python -m pip install delocate==0.11.0
# Find platform values on e.g. https://pypi.org/project/numpy/1.26.4/#files
python -m pip download --only-binary=:all: --platform macosx_10_09_x86_64 "$(grep numpy requirements.build.txt)"
python -m pip download --only-binary=:all: --platform macosx_11_0_arm64 "$(grep numpy requirements.build.txt)"
delocate-fuse numpy*arm* numpy*x86* -w tmp-wheel/
python -m pip download --only-binary=:all: --platform macosx_10_10_x86_64 "$(grep Pillow requirements.build.txt)"
python -m pip download --only-binary=:all: --platform macosx_11_0_arm64 "$(grep Pillow requirements.build.txt)"
delocate-fuse Pillow*arm* Pillow*x86* -w tmp-wheel/
python -m pip download --only-binary=:all: --platform macosx_10_9_x86_64 "$(grep simpleaudio requirements.build.txt)"
python -m pip download --only-binary=:all: --platform macosx_11_0_arm64 "$(grep simpleaudio requirements.build.txt)"
delocate-fuse simpleaudio*arm* simpleaudio*x86* -w tmp-wheel/
python -m pip download --only-binary=:all: --platform=macosx_10_9_universal2 "$(grep bitarray requirements.build.txt)"
python -m pip install tmp-wheel/*.whl bitarray*.whl
python -m pip install --no-binary charset_normalizer -r requirements.build.txt
- name: Convert UI and translation files
run: |
bash setup-environment.ps1
- name: Remove unneeded files
run: |
rm src/main/python/main/ayab/*_gui.ui
rm src/main/python/main/ayab/ayab_logo_rc.qrc
- name: Import Apple developer certificate
if: env.APPLE_CERTIFICATE_NAME
uses: apple-actions/import-codesign-certs@63fff01cd422d4b7b855d40ca1e9d34d2de9427d # v3
with:
p12-file-base64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
p12-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
- name: Build app
run: |
python -m fbs freeze
- name: Sign app
shell: bash
run: |
# - If an actual certificate is not available, we default the identity to "-" to enable
# ad-hoc signing, and disable the hardened runtime.
# - We sign the `avrdude_mac` binary explicitly since `--deep` misses it because it
# is not in a directory meant to contain executables.
codesign_identity=${APPLE_CERTIFICATE_NAME:-"-"}
if [[ -n "$APPLE_CERTIFICATE_NAME" ]]; then
codesign_options="--options=runtime"
fi
codesign -s "$codesign_identity" $codesign_options \
--force --all-architectures --timestamp --deep \
./target/AYAB-mac.app/Contents/Resources/ayab/firmware/avrdude_mac \
./target/AYAB-mac.app
- name: Create disk image
id: diskimage
run: |
python -m fbs installer
mv target/AYAB.dmg target/AYAB-${{ steps.vars.outputs.tag }}.dmg
echo 'name=AYAB-${{ steps.vars.outputs.tag }}.dmg' >> "$GITHUB_OUTPUT"
echo 'path=target/AYAB-${{ steps.vars.outputs.tag }}.dmg' >> "$GITHUB_OUTPUT"
- name: Sign disk image
if: steps.vars.outputs.do-release == 'true' && env.APPLE_CERTIFICATE_NAME
run: |
codesign -s "$APPLE_CERTIFICATE_NAME" --force --all-architectures --timestamp \
'${{ steps.diskimage.outputs.path }}'
- name: Submit disk image for notarization
if: steps.vars.outputs.do-release == 'true' && env.APPLE_STORE_CONNECT_KEY_ID
env:
APPLE_STORE_CONNECT_ISSUER: ${{ secrets.APPLE_STORE_CONNECT_ISSUER }}
APPLE_STORE_CONNECT_KEY_BASE64: ${{ secrets.APPLE_STORE_CONNECT_KEY_BASE64 }}
run: |
printenv APPLE_STORE_CONNECT_KEY_BASE64 | base64 --decode > apple-store-connect.key
# Submit the disk image for notarization and wait
xcrun notarytool submit '${{ steps.diskimage.outputs.path }}' \
-k apple-store-connect.key -d "$APPLE_STORE_CONNECT_KEY_ID" -i "$APPLE_STORE_CONNECT_ISSUER" \
--wait
# Staple the notarization ticket to the disk image
xcrun stapler staple -v '${{ steps.diskimage.outputs.path }}'
- name: Upload disk image as artifact
uses: actions/upload-artifact@v4
with:
name: ${{ steps.diskimage.outputs.name }}
path: ${{ steps.diskimage.outputs.path }}
- name: Attach disk image to release
uses: ncipollo/release-action@v1
if: steps.vars.outputs.do-release == 'true'
with:
tag: ${{ steps.vars.outputs.tag }}
# Default to draft and prerelease to let a human check the release before it goes live
draft: true
prerelease: false
allowUpdates: true
artifacts: ${{ steps.diskimage.outputs.path }}
artifactContentType: application/dmg
replacesArtifacts: true
# Avoid overwriting a release that may have been manually edited
omitNameDuringUpdate: true
omitBodyDuringUpdate: true
omitDraftDuringUpdate: true
omitPrereleaseDuringUpdate: true
# see https://github.com/AppImage/AppImageKit/wiki/Bundling-Python-apps
build-appimage:
name: Create and upload Linux AppImage release
runs-on: ubuntu-22.04
env:
# Using a specific Python version for Linux builds due to python-appimage availability
PYTHON_VERSION: 3.11.12
steps:
- name: Checkout repo into AppDir
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0 # necessary for `git describe`
- uses: ./.github/actions/init-environment
id: vars
- name: Get firmware version matching manifest
shell: bash
working-directory: src/main/resources/base/ayab/firmware/
run: |
curl --fail -O '${{ steps.vars.outputs.firmware-url }}'
- name: Install Python modules
run: |
sudo apt-get install -y avrdude libasound2-dev
python -m pip install --upgrade pip
python -m pip install --upgrade setuptools
python -m pip install -r requirements.build.txt
- name: Convert UI and translation files
run: |
bash setup-environment.ps1
- name: Relocate
run: |
mkdir git
shopt -s extglob dotglob
cp -r !(git) git
shopt -u dotglob
- name: Download AppImage of Python designed for manylinux
run: wget -c https://github.com/niess/python-appimage/releases/download/python${{steps.vars.outputs.python-minor}}/${{steps.vars.outputs.python-appimage}}
- name: Extract the AppImage
run: |
chmod +x ${{steps.vars.outputs.python-appimage}}
./${{steps.vars.outputs.python-appimage}} --appimage-extract
- name: Move repo
run: mv git/* squashfs-root
- name: Install dependencies
run: |
cd squashfs-root
sudo apt-get install -y avrdude libasound2-dev
./AppRun -m pip install --upgrade pip
# hack to fix setup.py script with faulty include
./AppRun -m pip install --global-option=build_ext --global-option="-I$(pwd)/opt/${{steps.vars.outputs.python-minor}}/include/${{steps.vars.outputs.python-minor}}" simpleaudio
./AppRun -m pip install -r requirements.build.txt
- name: Add AppDir subdirectories to PATH
run: |
echo "usr/bin" >> $GITHUB_PATH
echo "opt/${{steps.vars.outputs.python-minor}}/bin" >> $GITHUB_PATH
- name: Remove unneeded files
run: |
rm squashfs-root/src/main/python/main/ayab/*_gui.ui
rm squashfs-root/src/main/python/main/ayab/ayab_logo_rc.qrc
rm squashfs-root/src/main/python/main/ayab/engine/lowercase_e_rc.qrc
rm squashfs-root/src/main/python/main/ayab/engine/lowercase_e_reversed_rc.qrc
- name: Replace AppRun
run: |
cd squashfs-root
rm AppRun
cp linux-build/appimage/AppRun .
- name: Add icon
run: |
cd squashfs-root
rm -f *.png
rm -rf usr/share/icons/
cp linux-build/appimage/ayab.png ayab.png
mkdir -p usr/share/icons/hicolor/128x128/apps/
cp ayab.png usr/share/icons/hicolor/128x128/apps/
- name: Create desktop file
run: |
cd squashfs-root
rm -f python*.desktop
mkdir -p usr/share/applications/
rm -f usr/share/applications/*.desktop
cp linux-build/appimage/com.ayab_knitting.ayab.desktop com.ayab_knitting.ayab.desktop
cp com.ayab_knitting.ayab.desktop usr/share/applications/com.ayab_knitting.ayab.desktop
- name: Add metadata
run: |
cd squashfs-root
mkdir -p usr/share/metainfo/
rm -f usr/share/metainfo/*.appdata.xml
cp linux-build/appimage/ayab.appdata.xml usr/share/metainfo/
- name: Convert to AppImage
run: |
wget -c https://github.com/$(wget -q https://github.com/probonopd/go-appimage/releases/expanded_assets/continuous -O - | grep appimagetool-.*-x86_64.AppImage | head -n 1 | cut -d '"' -f 2)
chmod +x appimagetool-*-x86_64.AppImage
chmod 755 squashfs-root
sudo apt install appstream
VERSION=${{steps.vars.outputs.tag}} ./appimagetool-*-x86_64.AppImage squashfs-root/
sudo apt remove appstream
mv ayab-${{ steps.vars.outputs.tag }}-x86_64.AppImage AYAB-${{ steps.vars.outputs.tag }}-x86_64.AppImage
- name: Attach AppImage to release
uses: ncipollo/release-action@v1
if: steps.vars.outputs.do-release == 'true'
with:
token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ steps.vars.outputs.tag }}
commit: ${{ steps.vars.outputs.sha }}
allowUpdates: true
artifacts: AYAB-${{ steps.vars.outputs.tag }}-x86_64.AppImage
artifactContentType: application/AppImage
replacesArtifacts: true
# Default to draft and prerelease to let a human check the release before it goes live
draft: true
prerelease: false
# Avoid overwriting a release that may have been manually edited
omitNameDuringUpdate: true
omitBodyDuringUpdate: true
omitDraftDuringUpdate: true
omitPrereleaseDuringUpdate: true
- uses: actions/upload-artifact@v4
with:
name: AYAB-${{ steps.vars.outputs.tag }}-x86_64.AppImage
path: AYAB-${{ steps.vars.outputs.tag }}-x86_64.AppImage