diff --git a/.github/workflows/installers.yml b/.github/workflows/installers.yml index ead3b7a87a..4ebea0660b 100644 --- a/.github/workflows/installers.yml +++ b/.github/workflows/installers.yml @@ -24,9 +24,28 @@ on: default: false required: true type: boolean + nightly: + description: 'Upload to nightly release' + default: false + required: true + type: boolean + os_list: + description: 'List of OS(-variant)s to build for' + default: "windows, linux-modern, linux-legacy, macos-x64, macos-arm64" + required: true + type: string + schedule: + # Daily at 5:20 CET + - cron: '20 4 * * *' + +env: + CURA_CONAN_VERSION: ${{ inputs.cura_conan_version }} + ENTERPRISE: ${{ inputs.enterprise }} + STAGING: ${{ inputs.staging }} jobs: windows-installer: + if: ${{ contains(inputs.os_list, 'windows') }} uses: ./.github/workflows/windows.yml with: cura_conan_version: ${{ inputs.cura_conan_version }} @@ -38,6 +57,7 @@ jobs: secrets: inherit linux-modern-installer: + if: ${{ contains(inputs.os_list, 'linux-modern') }} uses: ./.github/workflows/linux.yml with: cura_conan_version: ${{ inputs.cura_conan_version }} @@ -49,6 +69,7 @@ jobs: secrets: inherit linux-legacy-installer: + if: ${{ contains(inputs.os_list, 'linux-legacy') }} uses: ./.github/workflows/linux.yml with: cura_conan_version: ${{ inputs.cura_conan_version }} @@ -60,6 +81,7 @@ jobs: secrets: inherit macos-installer: + if: ${{ contains(inputs.os_list, 'macos-x64') }} uses: ./.github/workflows/macos.yml with: cura_conan_version: ${{ inputs.cura_conan_version }} @@ -71,6 +93,7 @@ jobs: secrets: inherit macos-arm-installer: + if: ${{ contains(inputs.os_list, 'macos-arm64') }} uses: ./.github/workflows/macos.yml with: cura_conan_version: ${{ inputs.cura_conan_version }} @@ -79,4 +102,211 @@ jobs: staging: ${{ inputs.staging }} architecture: ARM64 operating_system: self-hosted - secrets: inherit \ No newline at end of file + secrets: inherit + + # Run and update nightly release when the nightly input is set to true or if the schedule is triggered + update-nightly-release: + if: ${{ always() && (! cancelled()) && contains(needs.*.result, 'success') && (! contains(needs.*.result, 'failure')) && (inputs.nightly || github.event_name == 'schedule') }} + runs-on: ubuntu-latest + needs: [ windows-installer, linux-modern-installer, linux-legacy-installer, macos-installer, macos-arm-installer ] + steps: + - name: Checkout + uses: actions/checkout@v3 + + # It's not necessary to download all three, but it does make sure we have at least one if an OS is skipped. + + - name: Download the run info + if: ${{ contains(inputs.os_list, 'macos-x64') || contains(inputs.os_list, 'macos-arm64') }} + uses: actions/download-artifact@v2 + with: + name: macos-run-info + + - name: Download the run info II + if: ${{ contains(inputs.os_list, 'linux-modern') || contains(inputs.os_list, 'linux-legacy') }} + uses: actions/download-artifact@v2 + with: + name: linux-run-info + + - name: Download the run info III + if: ${{ contains(inputs.os_list, 'windows') }} + uses: actions/download-artifact@v2 + with: + name: windows-run-info + + - name: Set the run info as environment variables + run: | + . run_info.sh + + - name: Output the name file name and extension + id: filename + shell: python + run: | + import os + import datetime + enterprise = "-Enterprise" if "${{ inputs.enterprise }}" == "true" else "" + os_list = [x.strip() for x in "${{ inputs.os_list }}".split(",")] + if 'linux-modern' in os_list: + linux_modern = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-linux-modern-X64" + if 'linux-legacy' in os_list: + linux_legacy = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-linux-X64" + if 'macos-x64' in os_list: + mac_x64_dmg = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-macos-X64" + mac_x64_pkg = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-macos-X64" + if 'macos-arm64' in os_list: + mac_arm_dmg = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-macos-ARM64" + mac_arm_pkg = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-macos-ARM64" + if 'windows' in os_list: + win_msi = installer_filename = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-win64-X64" + win_exe = installer_filename = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-win64-X64" + nightly_name = "UltiMaker-Cura-" + os.getenv('CURA_VERSION_FULL').split("+")[0] + nightly_creation_time = str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) + output_env = os.environ["GITHUB_OUTPUT"] + content = "" + if os.path.exists(output_env): + with open(output_env, "r") as f: + content = f.read() + with open(output_env, "w") as f: + f.write(content) + if 'linux-modern' in os_list: + f.writelines(f"LINUX_MODERN={linux_modern}\n") + if 'linux-legacy' in os_list: + f.writelines(f"LINUX_LEGACY={linux_legacy}\n") + if 'macos-x64' in os_list: + f.writelines(f"MAC_X64_DMG={mac_x64_dmg}\n") + f.writelines(f"MAC_X64_PKG={mac_x64_pkg}\n") + if 'macos-arm64' in os_list: + f.writelines(f"MAC_ARM_DMG={mac_arm_dmg}\n") + f.writelines(f"MAC_ARM_PKG={mac_arm_pkg}\n") + if 'windows' in os_list: + f.writelines(f"WIN_MSI={win_msi}\n") + f.writelines(f"WIN_EXE={win_exe}\n") + f.writelines(f"NIGHTLY_NAME={nightly_name}\n") + f.writelines(f"NIGHTLY_TIME={nightly_creation_time}\n") + + - name: Download linux modern installer jobs artifacts + if: ${{ contains(inputs.os_list, 'linux-modern') }} + uses: actions/download-artifact@v2 + with: + name: ${{ steps.filename.outputs.LINUX_MODERN }}-AppImage + path: installers + + - name: Download linux legacy installer jobs artifacts + if: ${{ contains(inputs.os_list, 'linux-legacy') }} + uses: actions/download-artifact@v2 + with: + name: ${{ steps.filename.outputs.LINUX_LEGACY }}-AppImage + path: installers + + - name: Download mac x64 dmg installer jobs artifacts + if: ${{ contains(inputs.os_list, 'macos-x64') }} + uses: actions/download-artifact@v2 + with: + name: ${{ steps.filename.outputs.MAC_X64_DMG }}-dmg + path: installers + + - name: Download mac x64 pkg installer jobs artifacts + if: ${{ contains(inputs.os_list, 'macos-x64') }} + uses: actions/download-artifact@v2 + with: + name: ${{ steps.filename.outputs.MAC_X64_PKG }}-pkg + path: installers + + - name: Download mac arm dmg installer jobs artifacts + if: ${{ contains(inputs.os_list, 'macos-arm64') }} + uses: actions/download-artifact@v2 + with: + name: ${{ steps.filename.outputs.MAC_ARM_DMG }}-dmg + path: installers + + - name: Download mac arm pkg installer jobs artifacts + if: ${{ contains(inputs.os_list, 'macos-arm64') }} + uses: actions/download-artifact@v2 + with: + name: ${{ steps.filename.outputs.MAC_ARM_PKG }}-pkg + path: installers + + - name: Download win msi installer jobs artifacts + if: ${{ contains(inputs.os_list, 'windows') }} + uses: actions/download-artifact@v2 + with: + name: ${{ steps.filename.outputs.WIN_MSI }}-msi + path: installers + + - name: Download win exe installer jobs artifacts + if: ${{ contains(inputs.os_list, 'windows') }} + uses: actions/download-artifact@v2 + with: + name: ${{ steps.filename.outputs.WIN_EXE }}-exe + path: installers + + - name: Rename Linux (modern) installer to nightlies + if: ${{ contains(inputs.os_list, 'linux-modern') }} + run: | + mv installers/${{ steps.filename.outputs.LINUX_MODERN }}.AppImage installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-linux-modern-X64.AppImage + + - name: Rename Linux (legacy) installer to nightlies + if: ${{ contains(inputs.os_list, 'linux-legacy') }} + run: | + mv installers/${{ steps.filename.outputs.LINUX_LEGACY }}.AppImage installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-linux-X64.AppImage + + - name: Rename MacOS (X64) installers to nightlies + if: ${{ contains(inputs.os_list, 'macos-x64') }} + run: | + mv installers/${{ steps.filename.outputs.MAC_X64_DMG }}.dmg installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-macos-X64.dmg + mv installers/${{ steps.filename.outputs.MAC_X64_PKG }}.pkg installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-macos-X64.pkg + + - name: Rename MacOS (ARM-64) installers to nightlies + if: ${{ contains(inputs.os_list, 'macos-arm64') }} + run: | + mv installers/${{ steps.filename.outputs.MAC_ARM_DMG }}.dmg installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-macos-ARM64.dmg + mv installers/${{ steps.filename.outputs.MAC_ARM_PKG }}.pkg installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-macos-ARM64.pkg + + - name: Rename Windows installers to nightlies + if: ${{ contains(inputs.os_list, 'windows') }} + run: | + mv installers/${{ steps.filename.outputs.WIN_MSI }}.msi installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-win64-X64.msi + mv installers/${{ steps.filename.outputs.WIN_EXE }}.exe installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-win64-X64.exe + + - name: Update nightly release for Linux (modern) + if: ${{ contains(inputs.os_list, 'linux-modern') }} + run: | + gh release upload nightly installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-linux-modern-X64.AppImage --clobber + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Update nightly release for Linux (legacy) + if: ${{ contains(inputs.os_list, 'linux-legacy') }} + run: | + gh release upload nightly installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-linux-X64.AppImage --clobber + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Update nightly release for MacOS (X64) + if: ${{ contains(inputs.os_list, 'macos-x64') }} + run: | + gh release upload nightly installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-macos-X64.dmg --clobber + gh release upload nightly installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-macos-X64.pkg --clobber + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Update nightly release for MacOS (ARM-64) + if: ${{ contains(inputs.os_list, 'macos-arm64') }} + run: | + gh release upload nightly installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-macos-ARM64.dmg --clobber + gh release upload nightly installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-macos-ARM64.pkg --clobber + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Update nightly release for Windows + if: ${{ contains(inputs.os_list, 'windows') }} + run: | + gh release upload nightly installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-win64-X64.msi --clobber + gh release upload nightly installers/${{ steps.filename.outputs.NIGHTLY_NAME }}-win64-X64.exe --clobber + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Update nightly release description (with date) + run: | + gh release edit nightly --title "${{ steps.filename.outputs.NIGHTLY_NAME }}" --notes "Nightly release created on: ${{ steps.filename.outputs.NIGHTLY_TIME }}" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 2e15584299..caf2ee74d3 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -250,6 +250,20 @@ jobs: dist/${{ steps.filename.outputs.INSTALLER_FILENAME }}.AppImage retention-days: 5 + - name: Write the run info + shell: python + run: | + import os + with open("run_info.sh", "w") as f: + f.writelines(f'echo "CURA_VERSION_FULL={os.environ["CURA_VERSION_FULL"]}" >> $GITHUB_ENV\n') + - name: Upload the run info + uses: actions/upload-artifact@v3 + with: + name: linux-run-info + path: | + run_info.sh + retention-days: 5 + notify-export: if: ${{ always() }} needs: [ cura-installer-create ] diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index af1fc3d12b..3667705952 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -264,6 +264,21 @@ jobs: dist/${{ steps.filename.outputs.INSTALLER_FILENAME }}.pkg retention-days: 5 + - name: Write the run info + shell: python + run: | + import os + with open("run_info.sh", "w") as f: + f.writelines(f'echo "CURA_VERSION_FULL={os.environ["CURA_VERSION_FULL"]}" >> $GITHUB_ENV\n') + + - name: Upload the run info + uses: actions/upload-artifact@v3 + with: + name: macos-run-info + path: | + run_info.sh + retention-days: 5 + notify-export: if: ${{ always() }} diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index df9056d454..f6de818eb4 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -256,6 +256,23 @@ jobs: dist/${{steps.filename.outputs.INSTALLER_FILENAME }}.exe retention-days: 5 + # NOTE: The extension is .sh, since this isn't going to build-environment, so not on the Win build image. + - name: Write the run info + shell: python + run: | + import os + with open("run_info.sh", "w") as f: + f.writelines(f'echo "CURA_VERSION_FULL={os.environ["CURA_VERSION_FULL"]}" >> $GITHUB_ENV\n') + + # NOTE: The extension is .sh, since this isn't going to build-environment, so not on the Win build image. + - name: Upload the run info + uses: actions/upload-artifact@v3 + with: + name: windows-run-info + path: | + run_info.sh + retention-days: 5 + notify-export: if: ${{ always() }} needs: [ cura-installer-create ] diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index a2edde95a8..783c6230b8 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -50,6 +50,7 @@ from UM.Settings.Validator import Validator from UM.View.SelectionPass import SelectionPass # For typing. from UM.Workspace.WorkspaceReader import WorkspaceReader from UM.i18n import i18nCatalog +from UM.Version import Version from cura import ApplicationMetadata from cura.API import CuraAPI from cura.API.Account import Account @@ -616,6 +617,16 @@ class CuraApplication(QtApplication): def _onEngineCreated(self): self._qml_engine.addImageProvider("print_job_preview", PrintJobPreviewImageProvider.PrintJobPreviewImageProvider()) + version = Version(self.getVersion()) + if hasattr(sys, "frozen") and version.hasPostFix() and "beta" not in version.getPostfixType(): + self._qml_engine.rootObjects()[0].setTitle(f"{ApplicationMetadata.CuraAppDisplayName} {ApplicationMetadata.CuraVersion}") + message = Message( + self._i18n_catalog.i18nc("@info:warning", + f"This version is not intended for production use. If you encounter any issues, please report them on our GitHub page, mentioning the full version {self.getVersion()}"), + lifetime = 0, + title = self._i18n_catalog.i18nc("@info:title", "Nightly build"), + message_type = Message.MessageType.WARNING) + message.show() @pyqtProperty(bool) def needToShowUserAgreement(self) -> bool: