Update build scripts (#1829)

This commit is contained in:
Veronica Berglyd Olsen
2024-04-21 12:59:42 +02:00
committed by GitHub
5 changed files with 76 additions and 45 deletions
+45 -13
View File
@@ -9,7 +9,7 @@ jobs:
- name: Python Setup - name: Python Setup
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: "3.11" python-version: "3.12"
architecture: x64 architecture: x64
- name: Install Packages (apt) - name: Install Packages (apt)
@@ -35,15 +35,14 @@ jobs:
novelwriter/assets/manual.pdf novelwriter/assets/manual.pdf
novelwriter/assets/i18n/*.qm novelwriter/assets/i18n/*.qm
if-no-files-found: error if-no-files-found: error
retention-days: 1 retention-days: 14
buildLinux: buildLinux:
needs: buildAssets needs: buildAssets
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: env:
matrix: PYTHON_VERSION: "3.12"
python-version: ["3.11"] LINUX_TAG: "manylinux_2_28_x86_64"
linux-tag: ["manylinux_2_24_x86_64", "manylinux_2_28_x86_64"]
steps: steps:
- name: Python Setup - name: Python Setup
uses: actions/setup-python@v5 uses: actions/setup-python@v5
@@ -64,19 +63,24 @@ jobs:
path: novelwriter/assets path: novelwriter/assets
- name: Build AppImage - name: Build AppImage
run: python pkgutils.py build-appimage --linux-tag ${{ matrix.linux-tag }} --python-version ${{ matrix.python-version }} run: python pkgutils.py build-appimage --linux-tag $LINUX_TAG --python-version $PYTHON_VERSION
- name: Upload Artifacts - name: Upload Artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: AppImage-${{ matrix.python-version }}-${{ matrix.linux-tag }} name: Linux-AppImage
path: dist_appimage path: dist_appimage
if-no-files-found: error if-no-files-found: error
retention-days: 1 retention-days: 14
buildMac: buildMac-AMD64:
needs: buildAssets needs: buildAssets
# Stay on macos-12 due to https://github.com/create-dmg/create-dmg/issues/143
runs-on: macos-12 runs-on: macos-12
env:
PYTHON_VERSION: "3.12"
PACKAGE_ARCH: x86_64
MINICONDA_ARCH: x86_64
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -88,12 +92,40 @@ jobs:
path: novelwriter/assets path: novelwriter/assets
- name: Build App Bundle - name: Build App Bundle
run: ./setup/macos/build.sh run: ./setup/macos/build.sh $PYTHON_VERSION $PACKAGE_ARCH $MINICONDA_ARCH
- name: Upload DMG - name: Upload DMG
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: MacOS-DMG name: MacOS-AMD64-DMG
path: dist_macos path: dist_macos
if-no-files-found: error if-no-files-found: error
retention-days: 1 retention-days: 14
buildMac-M1:
needs: buildAssets
runs-on: macos-14
env:
PYTHON_VERSION: "3.12"
PACKAGE_ARCH: aarch64
MINICONDA_ARCH: arm64
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download Artifacts
uses: actions/download-artifact@v4
with:
name: nw-assets
path: novelwriter/assets
- name: Build App Bundle
run: ./setup/macos/build.sh $PYTHON_VERSION $PACKAGE_ARCH $MINICONDA_ARCH
- name: Upload DMG
uses: actions/upload-artifact@v4
with:
name: MacOS-M1-DMG
path: dist_macos
if-no-files-found: error
retention-days: 14
+5 -8
View File
@@ -32,7 +32,7 @@ from typing import TYPE_CHECKING
from PyQt5.QtWidgets import QApplication, QErrorMessage from PyQt5.QtWidgets import QApplication, QErrorMessage
from novelwriter.config import Config from novelwriter.config import Config
from novelwriter.error import exceptionHandler, logException from novelwriter.error import exceptionHandler
from novelwriter.shared import SharedData from novelwriter.shared import SharedData
if TYPE_CHECKING: # pragma: no cover if TYPE_CHECKING: # pragma: no cover
@@ -198,24 +198,21 @@ def main(sysArgs: list | None = None) -> GuiMain | None:
# Finish initialising config # Finish initialising config
CONFIG.initConfig(confPath, dataPath) CONFIG.initConfig(confPath, dataPath)
if CONFIG.osDarwin: if sys.platform == "darwin":
try: try:
from Foundation import NSBundle # type: ignore from Foundation import NSBundle # type: ignore
bundle = NSBundle.mainBundle() bundle = NSBundle.mainBundle()
info = bundle.localizedInfoDictionary() or bundle.infoDictionary() info = bundle.localizedInfoDictionary() or bundle.infoDictionary()
info["CFBundleName"] = "novelWriter" info["CFBundleName"] = "novelWriter"
except Exception: except Exception:
logger.error("Failed to set application name") pass # Quietly ignore error
logException() elif sys.platform == "win32":
elif CONFIG.osWindows:
try: try:
import ctypes import ctypes
appID = f"io.novelwriter.{__version__}" appID = f"io.novelwriter.{__version__}"
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(appID) # type: ignore ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(appID) # type: ignore
except Exception: except Exception:
logger.error("Failed to set application name") pass # Quietly ignore error
logException()
# Import GUI (after dependency checks), and launch # Import GUI (after dependency checks), and launch
from novelwriter.guimain import GuiMain from novelwriter.guimain import GuiMain
+1 -8
View File
@@ -1073,15 +1073,8 @@ def makeAppImage(sysArgs: list[str]) -> list[str]:
print("") print("")
sys.exit(1) sys.exit(1)
linuxLabel = ""
if not linuxTag.startswith("manylinux_2_28"):
linuxLabel = "-oldlinux"
if not linuxTag.endswith("x86_64"):
# manylinux_2_28 only comes in 64 bit, so this one only applies to older images
linuxLabel += "-32bit"
bldFile = glob.glob(f"{bldDir}/*.AppImage")[0] bldFile = glob.glob(f"{bldDir}/*.AppImage")[0]
outFile = f"{bldDir}/novelWriter-{pkgVers}{linuxLabel}.AppImage" outFile = f"{bldDir}/novelWriter-{pkgVers}.AppImage"
os.rename(bldFile, outFile) os.rename(bldFile, outFile)
shaFile = makeCheckSum(os.path.basename(outFile), cwd=bldDir) shaFile = makeCheckSum(os.path.basename(outFile), cwd=bldDir)
+22 -9
View File
@@ -1,5 +1,18 @@
#! /bin/bash #! /bin/bash
if [[ -z "$1" || -z "$2" || -z "$3" ]]; then
echo "Not enouch input arguments"
exit 1
fi
PYTHON="$1"
ARCH="$2"
CONDA="$3"
echo "Python Version: $PYTHON"
echo "Architecture: $ARCH"
echo "Miniconda Architecture: $CONDA"
# Use RAM disk if possible # Use RAM disk if possible
if [ -d /dev/shm ]; then if [ -d /dev/shm ]; then
TEMP_BASE=/dev/shm TEMP_BASE=/dev/shm
@@ -76,13 +89,13 @@ pushd "$BUILD_DIR"/ || exit 1
# --- Create Miniconda Env ---------------------------------------------------------------------- # # --- Create Miniconda Env ---------------------------------------------------------------------- #
echo "Downloading Miniconda ..." echo "Downloading Miniconda ..."
curl -LO https://repo.continuum.io/miniconda/Miniconda3-latest-MacOSX-x86_64.sh curl -LO https://repo.continuum.io/miniconda/Miniconda3-latest-MacOSX-$CONDA.sh
bash Miniconda3-latest-MacOSX-x86_64.sh -b -p ~/miniconda -f bash Miniconda3-latest-MacOSX-$CONDA.sh -b -p ~/miniconda -f
rm Miniconda3-latest-MacOSX-x86_64.sh rm Miniconda3-latest-MacOSX-$CONDA.sh
export PATH="$HOME/miniconda/bin:$PATH" export PATH="$HOME/miniconda/bin:$PATH"
echo "Creating Conda env ..." echo "Creating Conda env ..."
conda create -n novelWriter -c conda-forge python=3.11 --yes conda create -n novelWriter -c conda-forge python=$PYTHON --yes
source activate novelWriter source activate novelWriter
echo "Installing dictionaries ..." echo "Installing dictionaries ..."
@@ -123,10 +136,10 @@ cp $SRC_DIR/setup/macos/novelwriter.icns novelWriter.app/Contents/Resources/
# Create entry script # Create entry script
echo "Creating entry script ..." echo "Creating entry script ..."
cat > novelWriter.app/Contents/MacOS/novelWriter <<\EOF cat > novelWriter.app/Contents/MacOS/novelWriter << EOF
#!/bin/bash #!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" DIR="\$( cd "\$( dirname "\${BASH_SOURCE[0]}" )" && pwd )"
$DIR/../Resources/bin/python -sE $DIR/../Resources/novelWriter/novelWriter.py $@ \$DIR/../Resources/bin/python -sE \$DIR/../Resources/novelWriter/novelWriter.py \$@
EOF EOF
# Make it executable # Make it executable
@@ -173,8 +186,8 @@ brew install create-dmg
create-dmg --volname "novelWriter $VERSION" --volicon $SRC_DIR/setup/macos/novelwriter.icns \ create-dmg --volname "novelWriter $VERSION" --volicon $SRC_DIR/setup/macos/novelwriter.icns \
--window-pos 200 120 --window-size 800 400 --icon-size 100 \ --window-pos 200 120 --window-size 800 400 --icon-size 100 \
--icon novelWriter.app 200 190 --hide-extension novelWriter.app \ --icon novelWriter.app 200 190 --hide-extension novelWriter.app \
--app-drop-link 600 185 $RLS_DIR/novelWriter-"${VERSION}"-amd64.dmg "$BUILD_DIR"/ --app-drop-link 600 185 $RLS_DIR/novelWriter-"${VERSION}"-$ARCH.dmg "$BUILD_DIR"/
pushd $RLS_DIR || exit 1 pushd $RLS_DIR || exit 1
shasum -a 256 novelWriter-"${VERSION}"-amd64.dmg | tee novelWriter-"${VERSION}"-amd64.dmg.sha256 shasum -a 256 novelWriter-"${VERSION}"-$ARCH.dmg | tee novelWriter-"${VERSION}"-$ARCH.dmg.sha256
popd || exit 1 popd || exit 1
+3 -7
View File
@@ -46,7 +46,6 @@ def testBaseInit_Launch(caplog, monkeypatch, fncPath):
mp.setitem(sys.modules, "Foundation", None) mp.setitem(sys.modules, "Foundation", None)
nwGUI = main(["--testmode", f"--config={fncPath}", f"--data={fncPath}"]) nwGUI = main(["--testmode", f"--config={fncPath}", f"--data={fncPath}"])
assert isinstance(nwGUI, MockGuiMain) assert isinstance(nwGUI, MockGuiMain)
assert "Failed" in caplog.text
CONFIG.osDarwin = osDarwin CONFIG.osDarwin = osDarwin
@@ -58,9 +57,6 @@ def testBaseInit_Launch(caplog, monkeypatch, fncPath):
mp.setitem(sys.modules, "ctypes", None) mp.setitem(sys.modules, "ctypes", None)
nwGUI = main(["--testmode", f"--config={fncPath}", f"--data={fncPath}"]) nwGUI = main(["--testmode", f"--config={fncPath}", f"--data={fncPath}"])
assert isinstance(nwGUI, MockGuiMain) assert isinstance(nwGUI, MockGuiMain)
if not sys.platform.startswith("darwin"):
# For some reason, the test doesn't work on macOS
assert "Failed" in caplog.text
CONFIG.osWindows = osWindows CONFIG.osWindows = osWindows
@@ -161,9 +157,9 @@ def testBaseInit_Imports(caplog, monkeypatch, fncPath):
["--testmode", f"--config={fncPath}", f"--data={fncPath}"] ["--testmode", f"--config={fncPath}", f"--data={fncPath}"]
) )
assert ex.value.code & 4 == 4 # Python version not satisfied assert ex.value.code & 4 == 4 # Python version not satisfied # type: ignore
assert ex.value.code & 8 == 8 # Qt version not satisfied assert ex.value.code & 8 == 8 # Qt version not satisfied # type: ignore
assert ex.value.code & 16 == 16 # PyQt version not satisfied assert ex.value.code & 16 == 16 # PyQt version not satisfied # type: ignore
assert "At least Python" in caplog.messages[0] assert "At least Python" in caplog.messages[0]
assert "At least Qt5" in caplog.messages[1] assert "At least Qt5" in caplog.messages[1]