# Copyright © SixtyFPS GmbH <info@slint.dev>
# SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0

# Build various demo binaries, c++ packages and documentation and publish them on the website
name: Nightly snapshot

on:
    workflow_dispatch:
        inputs:
            private:
                type: boolean
                default: true
                required: false
                description: "Private build? True means artifacts are only built. False means the artefacts are published (docs, vscode extension) to the web/marketplace"
            release:
                type: boolean
                default: false
                required: false
                description: "Release? Enable options for building binaries for a release (i.e. don't have a -nightly suffix for the extension)"

env:
    # Keep in sync with features in slint_tool_binary.yaml, cpp_package.yaml, api/node/Cargo.toml, and api/python/slint/Cargo.toml
    SLINT_BINARY_FEATURES: "backend-linuxkms-noseat,backend-winit,renderer-femtovg,renderer-skia,renderer-software"
    MACOSX_DEPLOYMENT_TARGET: "11.0"

jobs:
    slint-viewer-binary:
        uses: ./.github/workflows/slint_tool_binary.yaml
        with:
            program: "viewer"
        secrets:
            certificate: ${{ secrets.APPLE_CERTIFICATE_P12 }}
            certificate_password: ${{ secrets.APPLE_CERTIFICATE_P12_PASSWORD }}
            keychain_password: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
            developer_id: ${{ secrets.APPLE_DEV_ID }}
    slint-lsp-binary:
        uses: ./.github/workflows/slint_tool_binary.yaml
        with:
            program: "lsp"
        secrets:
            certificate: ${{ secrets.APPLE_CERTIFICATE_P12 }}
            certificate_password: ${{ secrets.APPLE_CERTIFICATE_P12_PASSWORD }}
            keychain_password: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
            developer_id: ${{ secrets.APPLE_DEV_ID }}
    docs:
        uses: ./.github/workflows/build_docs.yaml
        secrets: inherit
        with:
          release: ${{ github.event.inputs.release }}
          app-id: ${{ vars.READ_WRITE_APP_ID }}

    wasm_demo:
        uses: ./.github/workflows/wasm_demos.yaml
        with:
            build_artifacts: true
    wasm:
        uses: ./.github/workflows/wasm_editor_and_interpreter.yaml
    cpp_package:
        uses: ./.github/workflows/cpp_package.yaml
        with:
            extra_cmake_flags: ${{ github.event.inputs.release != 'true' && '-DCPACK_PACKAGE_VERSION=nightly' || '' }}

    check-for-secrets:
        runs-on: ubuntu-latest
        outputs:
            has-vscode-marketplace-pat: ${{ steps.one.outputs.has-vscode-marketplace-pat }}
            has-openvsx-pat: ${{ steps.one.outputs.has-openvsx-pat }}
        steps:
            - id: one
              run: |
                  [ -n "${{ secrets.VSCODE_MARKETPLACE_PAT }}" ] && echo "has-vscode-marketplace-pat=yes" >> "$GITHUB_OUTPUT"
                  [ -n "${{ secrets.OPENVSX_PAT }}" ] && echo "has-openvsx-pat=yes" >> "$GITHUB_OUTPUT"

    build_vscode_lsp_linux_windows:
        env:
            SLINT_NO_QT: 1
        strategy:
            matrix:
                include:
                    - os: ubuntu-22.04
                      toolchain: x86_64-unknown-linux-gnu
                      binary_built: slint-lsp
                      artifact_name: slint-lsp-x86_64-unknown-linux-gnu
                    - os: windows-2022
                      toolchain: x86_64-pc-windows-msvc
                      binary_built: slint-lsp.exe
                      artifact_name: slint-lsp-x86_64-pc-windows-msvc.exe
                    - os: windows-11-arm
                      toolchain: aarch64-pc-windows-msvc
                      binary_built: slint-lsp.exe
                      artifact_name: slint-lsp-aarch64-pc-windows-msvc.exe
        runs-on: ${{ matrix.os }}
        steps:
            - uses: actions/checkout@v6
            - uses: ./.github/actions/setup-rust
              with:
                  target: ${{ matrix.toolchain }}
            - uses: ./.github/actions/install-linux-dependencies
              with:
                  old-ubuntu: true
            - name: Build LSP
              run: cargo build --target ${{ matrix.toolchain }} --features ${{ env.SLINT_BINARY_FEATURES }} --release -p slint-lsp
            - name: Create artifact directory
              run: |
                  mkdir bin
                  cp target/${{ matrix.toolchain }}/release/${{ matrix.binary_built }} bin/${{ matrix.artifact_name }}
            - name: "Upload LSP Artifact"
              uses: actions/upload-artifact@v7
              with:
                  name: vscode-lsp-binary-${{ matrix.toolchain }}
                  path: |
                      bin

    build_vscode_lsp_macos_x86_64:
        env:
            SLINT_NO_QT: 1
        runs-on: macos-15-intel
        steps:
            - uses: actions/checkout@v6
            - uses: ./.github/actions/setup-rust
              with:
                  target: x86_64-apple-darwin
            - name: Install cargo-bundle
              run: cargo install --version=0.6.0 cargo-bundle
            - name: Build Main LSP Bundle
              working-directory: tools/lsp
              run: cargo bundle --release --features ${{ env.SLINT_BINARY_FEATURES }}
            - name: Create artifact directory
              run: |
                  mkdir bin
                  cp -a target/release/bundle/osx/Slint\ Live\ Preview.app bin
            - name: "Upload LSP Artifact"
              uses: actions/upload-artifact@v7
              with:
                  name: vscode-lsp-binary-x86_64-apple-darwin
                  path: |
                      bin

    build_vscode_lsp_macos_aarch64:
        env:
            SLINT_NO_QT: 1
        runs-on: macos-26
        steps:
            - uses: actions/checkout@v6
            - uses: ./.github/actions/setup-rust
              with:
                  target: aarch64-apple-darwin
            - name: Build AArch64 LSP
              run: cargo build --target aarch64-apple-darwin --features ${{ env.SLINT_BINARY_FEATURES }} --release -p slint-lsp
            - name: Create artifact directory
              run: |
                  mkdir bin
                  cp -a target/aarch64-apple-darwin/release/slint-lsp bin/slint-lsp-aarch64-apple-darwin
            - name: "Upload LSP Artifact"
              uses: actions/upload-artifact@v7
              with:
                  name: vscode-lsp-binary-aarch64-apple-darwin
                  path: |
                      bin

    build_vscode_lsp_macos_bundle:
        needs: [build_vscode_lsp_macos_x86_64, build_vscode_lsp_macos_aarch64]
        runs-on: macos-15
        steps:
            - uses: actions/checkout@v6
              with:
                  path: "src"
            - uses: actions/download-artifact@v8
              with:
                  name: vscode-lsp-binary-x86_64-apple-darwin
            - uses: actions/download-artifact@v8
              with:
                  name: vscode-lsp-binary-aarch64-apple-darwin
                  path: bin
            - name: Add macOS AArch64 binary to bundle
              run: |
                  lipo -create -output tmp Slint\ Live\ Preview.app/Contents/MacOS/slint-lsp bin/slint-lsp-aarch64-apple-darwin
                  mv tmp Slint\ Live\ Preview.app/Contents/MacOS/slint-lsp
                  rm -rf bin
            - uses: ./src/.github/actions/codesign
              with:
                  binary: "Slint Live Preview.app"
                  certificate: ${{ secrets.APPLE_CERTIFICATE_P12 }}
                  certificate_password: ${{ secrets.APPLE_CERTIFICATE_P12_PASSWORD }}
                  keychain_password: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
                  developer_id: ${{ secrets.APPLE_DEV_ID }}
            - name: "Remove temporary source checkout"
              run: rm -rf src
            - name: "Upload LSP macOS bundle Artifact"
              uses: actions/upload-artifact@v7
              with:
                  name: vscode-lsp-binary-darwin
                  path: .

    build_vscode_cross_linux_lsp:
        env:
            SLINT_NO_QT: 1
        strategy:
            matrix:
                target:
                    - armv7-unknown-linux-gnueabihf
                    - aarch64-unknown-linux-gnu
        runs-on: ubuntu-22.04
        steps:
            - uses: actions/checkout@v6
            - uses: ./.github/actions/setup-rust
              with:
                  target: ${{ matrix.target }}
            - uses: baptiste0928/cargo-install@v3
              with:
                  crate: cross
            - name: Build LSP
              run: cross build --target ${{ matrix.target }} --features ${{ env.SLINT_BINARY_FEATURES }} --release -p slint-lsp
            - name: Create artifact directory
              run: |
                  mkdir bin
                  cp target/${{ matrix.target }}/release/slint-lsp bin/slint-lsp-${{ matrix.target }}
            - name: "Upload LSP Artifact"
              uses: actions/upload-artifact@v7
              with:
                  name: vscode-lsp-binary-${{ matrix.target }}
                  path: |
                      bin

    build_vscode_extension:
        needs:
            [
                build_vscode_lsp_linux_windows,
                build_vscode_lsp_macos_bundle,
                build_vscode_cross_linux_lsp,
                check-for-secrets,
            ]
        runs-on: macos-14
        if: ${{ needs.check-for-secrets.outputs.has-openvsx-pat == 'yes' && needs.check-for-secrets.outputs.has-vscode-marketplace-pat == 'yes' }}
        steps:
            - uses: actions/checkout@v6
            - uses: pnpm/action-setup@v5.0.0
              with:
                version: 10.29.3
            - name: Install GNU Sed
              run: brew install gnu-sed
            - uses: actions/setup-node@v6
              with:
                  node-version: 24
                  package-manager-cache: false
            - uses: actions/download-artifact@v8
              with:
                  name: vscode-lsp-binary-x86_64-unknown-linux-gnu
                  path: editors/vscode/bin
            - uses: actions/download-artifact@v8
              with:
                  name: vscode-lsp-binary-x86_64-pc-windows-msvc
                  path: editors/vscode/bin
            - uses: actions/download-artifact@v8
              with:
                  name: vscode-lsp-binary-aarch64-pc-windows-msvc
                  path: editors/vscode/bin
            - uses: actions/download-artifact@v8
              with:
                  name: vscode-lsp-binary-darwin
                  path: editors/vscode/bin
            - uses: actions/download-artifact@v8
              with:
                  name: vscode-lsp-binary-armv7-unknown-linux-gnueabihf
                  path: editors/vscode/bin
            - uses: actions/download-artifact@v8
              with:
                  name: vscode-lsp-binary-aarch64-unknown-linux-gnu
                  path: editors/vscode/bin
            - name: Fix permissions
              run: chmod 755 editors/vscode/bin/* editors/vscode/bin/*.app/Contents/MacOS/*
            - name: "Prepare meta-data files for nightly package"
              env:
                  RELEASE_INPUT: ${{ github.event.inputs.release }}
              working-directory: editors/vscode
              run: |
                  if grep -q 'lines below this marker are stripped from the release' README.md; then
                    gsed -i "/lines below this marker are stripped from the release/,\$d" README.md
                  else
                    echo "Missing strip marker in VS Code Extension README. Either add or fix this script."
                    exit 1
                  fi
                  if [ "$RELEASE_INPUT" != "true" ]; then
                    ../../scripts/prepare_vscode_nightly.sh
                  fi
              shell: bash
            - name: "pnpm install"
              working-directory: editors/vscode
              run: pnpm install --frozen-lockfile
            - name: Install wasm-pack
              run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
            - name: Build package and optionally publish to Visual Studio Marketplace
              id: publishToVSCM
              uses: HaaLeo/publish-vscode-extension@v2
              with:
                  pat: ${{ secrets.VSCODE_MARKETPLACE_PAT }}
                  registryUrl: https://marketplace.visualstudio.com
                  dryRun: ${{ github.event.inputs.private == 'true' || (github.ref != 'refs/heads/pre-release/1.16' && github.event.inputs.release != 'true') }}
                  packagePath: editors/vscode
                  dependencies: false
            - name: Publish to Open VSX Registry
              continue-on-error: true
              if: ${{ github.event.inputs.private != 'true' && (github.ref == 'refs/heads/pre-release/1.16' || github.event.inputs.release == 'true') }}
              uses: HaaLeo/publish-vscode-extension@v2
              with:
                  pat: ${{ secrets.OPENVSX_PAT }}
                  extensionFile: ${{ steps.publishToVSCM.outputs.vsixPath }}
                  packagePath: ""
            - name: "Upload extension artifact"
              uses: actions/upload-artifact@v7
              with:
                  name: slint-vscode.zip
                  path: |
                      ${{ steps.publishToVSCM.outputs.vsixPath }}

    build-figma-plugin:
        runs-on: ubuntu-latest
        steps:
            - uses: actions/checkout@v6
            - uses: actions/setup-node@v6
              with:
                node-version: 24
                package-manager-cache: false
              id: node-install
            - uses: pnpm/action-setup@v5.0.0
              with:
                version: 10.29.3
            - name: Run pnpm install
              working-directory: tools/figma-inspector
              run: pnpm install --frozen-lockfile
            - name: Add build timestamp to readme
              working-directory: tools/figma-inspector/public-zip
              run: echo "Built on $(date '+%d-%m-%Y %H:%M:%S %Z')" >> readme.txt
            - name: Build zip
              working-directory: tools/figma-inspector
              run: pnpm zip
            - name: Prepare Figma plugin artifact
              run: mv *.zip figma-plugin.zip
              working-directory: tools/figma-inspector/zip
            - name: Archive zip
              uses: actions/upload-artifact@v7
              with:
                  name: figma-plugin
                  path: tools/figma-inspector/zip

    #  publish_tree_sitter:
    #    if: github.event.inputs.private != 'true'
    #    runs-on: ubuntu-22.04
    #    steps:
    #      - uses: actions/checkout@v6
    #      - name: Upload artifact
    #        uses: actions/upload-artifact@v7
    #        with:
    #            name: tree-sitter-slint
    #            path: editors/tree-sitter-slint

    publish_artifacts:
        if: ${{ github.event.inputs.private != 'true' }}
        needs: [docs, wasm_demo, wasm, check-for-secrets, android]
        runs-on: ubuntu-22.04
        steps:
            - uses: actions/download-artifact@v8
              with:
                  pattern: docs-*
                  merge-multiple: true
                  path: .

            - name: Generate a token
              id: app-token-website
              uses: actions/create-github-app-token@v3
              with:
                app-id: ${{ vars.READ_WRITE_APP_ID }}
                private-key: ${{ secrets.READ_WRITE_PRIVATE_KEY }}
                repositories: website
            - name: Clone website directory
              uses: actions/checkout@v6
              with:
                repository: slint-ui/website
                ref: prod
                path: website
                token: ${{ steps.app-token-website.outputs.token }}
                persist-credentials: false
            - name: Generate release-docs.html and 404.html
              run: |
                mkdir -p website/output
                cd website && go run generator/generator.go -skip-agreements
            - name: Copy release-docs.html and 404.html
              run: |
                cp website/output/release-docs.html docs/index.html
                cp website/output/404.html docs/404.html
                rm -rf website

            - uses: actions/download-artifact@v8
              with:
                  name: slintpad
                  path: slintpad
            - uses: actions/download-artifact@v8
              with:
                  name: wasm
            - uses: actions/download-artifact@v8
              with:
                  name: wasm_demo
            - uses: actions/download-artifact@v8
              with:
                  name: android-demo
                  path: android

            - uses: actions/checkout@v6
              with:
                path: "slint-src"
                sparse-checkout: .
            - name: Extract Version from Cargo.toml
              id: version
              run: |
                version=$(awk '/^\[workspace.package\]/ {found=1} found && /^version = / {gsub(/version = |"/, "", $0); print $0; exit}' slint-src/Cargo.toml)
                if [[ -z "$version" ]]; then
                  echo "Version not found"
                  exit 1
                fi
                  echo "VERSION=$version" >> $GITHUB_OUTPUT

            - name: Generate a token
              id: app-token
              uses: actions/create-github-app-token@v3
              with:
                app-id: ${{ vars.READ_WRITE_APP_ID }}
                private-key: ${{ secrets.READ_WRITE_PRIVATE_KEY }}
                repositories: www-releases

            - name: Clone www-releases/releases and slintpad directory
              uses: actions/checkout@v6
              if: ${{ github.event.inputs.release  == 'true' }}
              with:
                repository: slint-ui/www-releases
                path: www-releases
                token: ${{ steps.app-token.outputs.token }}
                sparse-checkout: |
                  releases
                  slintpad

            - name: Clone www-releases/snapshots directory
              uses: actions/checkout@v6
              if: ${{ github.event.inputs.release  != 'true' }}
              with:
                repository: slint-ui/www-releases
                path: www-releases
                token: ${{ steps.app-token.outputs.token }}
                sparse-checkout: |
                  snapshots

            - name: Publish Docs and Demos
              working-directory: ./www-releases
              run: |
                if [[ "${{ github.event.inputs.release }}" == "true" ]]; then
                  output_path="releases/${{ steps.version.outputs.VERSION }}"
                else
                  output_path="snapshots/${GITHUB_REF##*/}"
                fi

                rm -rf $output_path/demos
                mkdir -p $output_path/demos

                for demo_subdir in examples,gallery, demos,printerdemo,rust examples,todo,rust examples,todo-mvc,rust examples,slide_puzzle, examples,speedometer,rust examples,memory, examples,imagefilter,rust examples,plotter, examples,opengl_underlay, examples,carousel,rust demos,energy-monitor, demos,weather-demo, demos,home-automation,rust demos,usecases,rust; do
                  IFS=',' read example_or_demo demo subdir <<< "${demo_subdir}"

                  mkdir -p $output_path/demos/$demo
                  cp -a ../$example_or_demo/$demo/$subdir/{pkg,index.html} $output_path/demos/$demo/
                done

                mkdir -p $output_path/demos/android
                cp -a ../android/* $output_path/demos/android/

                rm -rf $output_path/wasm-interpreter
                mkdir -p $output_path/wasm-interpreter
                cp -a ../api/wasm-interpreter/pkg/* ./$output_path/wasm-interpreter/

                rm -rf $output_path/editor
                mkdir -p $output_path/editor
                cp -a ../slintpad/* $output_path/editor/

                if [[ "${{ github.event.inputs.release }}" == "true" ]]; then
                  version="${{ steps.version.outputs.VERSION }}"
                else
                  version="development snapshot"
                fi
                sed -i "s/VERSION/$version/g" ../docs/index.html

                rm -rf $output_path/docs
                mv ../docs $output_path

                # Fix up link to Slint language documentation
                sed -i "s!https://slint.dev/releases/.*/docs/!../../!" $output_path/docs/rust/slint/*.html

            - name: Adjust redirections
              if: github.event.inputs.release == 'true'
              run: |
                sed -i "/1.0.2/! s,[0-9]*\.[0-9]*\.[0-9]*/\(.*\),${{ steps.version.outputs.VERSION }}/\1," www-releases/releases/_redirects

            - name: Adjust slintpad default tag
              if: github.event.inputs.release == 'true'
              run: sed -i "s,XXXX_DEFAULT_TAG_XXXX,v${{ steps.version.outputs.VERSION }}," www-releases/releases/${{ steps.version.outputs.VERSION }}/editor/assets/*.js

            - name: Update versions.txt
              if: github.event.inputs.release == 'true'
              working-directory: www-releases/releases
              run: ls -1d */ | cut -f1 -d'/' | sort --version-sort -r > versions.txt

            - name: Print contents before update
              if: github.event.inputs.release == 'true'
              working-directory: www-releases/releases
              run: cat versions.json

            - name: Update version in versions.json
              if: github.event.inputs.release == 'true'
              working-directory: www-releases/releases
              run: |
                  sed -i '/"name": "development snapshot"/,/"preferred": true,/c\
                          "name": "development snapshot",\
                          "url": "https://snapshots.slint.dev/master/docs/slint"\
                      },\
                      {\
                          "preferred": true,\
                          "version": "${{ steps.version.outputs.VERSION }}",\
                          "url": "https://releases.slint.dev/${{ steps.version.outputs.VERSION }}/docs/slint"\
                      },\
                      {' versions.json

            - name: Print contents before update
              if: github.event.inputs.release == 'true'
              working-directory: www-releases/releases
              run: cat versions.json

            - name: Update SlintPad
              if: github.event.inputs.release == 'true'
              run: |
                rm -rf www-releases/slintpad
                cp -r www-releases/releases/${{ steps.version.outputs.VERSION }}/editor www-releases/slintpad
                for f in 404.html script.js LICENSE.md package.json; do
                  cp www-releases/releases/$f www-releases/slintpad
                done
                echo "${{ steps.version.outputs.VERSION }}" > www-releases/slintpad/versions.txt

            - name: Get GitHub App User ID
              id: get-user-id
              run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT"
              env:
                GH_TOKEN: ${{ steps.app-token.outputs.token }}

            - name: check for diff
              id: www-releases
              working-directory: ./www-releases
              run: |
                git add .
                git add -u .
                git diff-index --cached --quiet HEAD || echo "has-diff=yes" >> "$GITHUB_OUTPUT"

            - name: commit and push
              if: ${{ steps.www-releases.outputs.has-diff == 'yes' }}
              working-directory: ./www-releases
              run: |
                git config user.name '${{ steps.app-token.outputs.app-slug }}[bot]'
                git config user.email '${{ steps.get-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com>'
                git commit --message "Update $NAME from $GITHUB_REPOSITORY" --message "Pull web demos and C++/Rust reference docs from commit $GITHUB_SHA ($GITHUB_REF)"
                git push

    prepare_release:
        if: github.event.inputs.private != 'true'
        needs: [cpp_package, slint-viewer-binary, slint-lsp-binary, build-figma-plugin]
        runs-on: ubuntu-22.04
        permissions:
            contents: write
        steps:
            - uses: actions/download-artifact@v8
              with:
                  pattern: cpp_bin-*
                  merge-multiple: true
            - uses: actions/download-artifact@v8
              with:
                  pattern: cpp_mcu_bin-*
                  merge-multiple: true
            - uses: actions/download-artifact@v8
              with:
                  pattern: slint-compiler-bin-*
                  merge-multiple: true
            - uses: actions/download-artifact@v8
              with:
                  pattern: slint-viewer-*
                  merge-multiple: true
            - uses: actions/download-artifact@v8
              with:
                  pattern: slint-lsp-*
                  merge-multiple: true
            - uses: actions/download-artifact@v8
              with:
                  name: figma-plugin
            - name: Extract files
              run: |
                  ls -l
                  mkdir artifacts
                  mv Slint-cpp-*-win64*.exe artifacts/
                  mv Slint-cpp-*.tar.gz artifacts/
                  mv slint-viewer-linux.tar.gz artifacts/
                  mv slint-viewer-armv7-unknown-linux-gnueabihf.tar.gz artifacts/
                  mv slint-viewer-aarch64-unknown-linux-gnu.tar.gz artifacts/
                  mv slint-viewer-macos.tar.gz artifacts/
                  mv slint-viewer-windows*.zip artifacts/
                  mv slint-lsp-linux.tar.gz artifacts/
                  mv slint-lsp-armv7-unknown-linux-gnueabihf.tar.gz artifacts/
                  mv slint-lsp-aarch64-unknown-linux-gnu.tar.gz artifacts/
                  mv slint-lsp-macos.tar.gz artifacts/
                  mv slint-lsp-windows*.zip artifacts/
                  mv slint-compiler-*.tar.gz artifacts/
                  mv figma-plugin.zip artifacts/
            - uses: actions/checkout@v6
              with:
                path: "slint-src"
                sparse-checkout: docs
            - name: prepare release notes
              id: version
              env:
                   RELEASE_INPUT: ${{ github.event.inputs.release }}
              run: |
                  if [ "$RELEASE_INPUT" != "true" ]; then
                    notes_file=slint-src/docs/nightly-release-notes.md
                    version=nightly
                    download_version=$version
                  else
                    version=$(echo artifacts/Slint-cpp-*-win64-MSVC-AMD64.exe | sed -nre 's/^.*-([0-9]+\.[0-9]+\.[0-9]+).*$/\1/p')
                    if [[ -z "$version" ]]; then
                      echo "Version not found"
                      exit 1
                    fi
                    major_version=`echo $version | sed -e "s,\([0-9]*\)\.[0-9]*\.[0-9]*,\1,"`
                    minor_version=`echo $version | sed -e "s,[0-9]*\.\([0-9]*\)\.[0-9]*,\1,"`
                    notes_file=slint-src/docs/release-notes.md
                    download_version=v$version
                  fi
                  echo "VERSION=$version" >> $GITHUB_OUTPUT
                  cat $notes_file slint-src/docs/release-artifacts.md > release-notes.md
                  branch="${GITHUB_REF#refs/heads/}"
                  feature="${GITHUB_REF##*/}"
                  sed -i -e "s,{branch},$branch,g" release-notes.md
                  sed -i -e "s,{feature},$feature,g" release-notes.md
                  sed -i -e "s,{version},$version,g" release-notes.md
                  sed -i -e "s,{download_version},$download_version,g" release-notes.md
                  sed -i -e "s,{major_version},$major_version,g" release-notes.md
                  sed -i -e "s,{minor_version},$minor_version,g" release-notes.md
                  cat release-notes.md

            - name: generate STM32 template packages
              env:
                RELEASE_INPUT: ${{ github.event.inputs.release }}
              run: |
                git clone https://github.com/slint-ui/slint-cpp-templates-stm32 --depth 1
                cd slint-cpp-templates-stm32
                if [ "$RELEASE_INPUT" = "true" ]; then
                    find . -name "CMakeLists.txt" | xargs sed -i "s/find_package(Slint)/find_package(Slint ${{ steps.version.outputs.VERSION }})/g"
                fi
                for board in stm32h735g-dk stm32h747i-disco; do
                    mv $board  slint-cpp-template-$board
                    zip -r ../artifacts/slint-cpp-template-$board.zip slint-cpp-template-$board/
                done

            - uses: ncipollo/release-action@v1
              if: github.event.inputs.release == 'true'
              with:
                  draft: true
                  artifacts: "artifacts/*"
                  bodyFile: release-notes.md
                  name: ${{ steps.version.outputs.VERSION }}
                  tag: v${{ steps.version.outputs.VERSION }}
                  commit: ${{ github.sha }}
            - uses: ncipollo/release-action@v1
              if: github.event.inputs.release != 'true' && github.ref == 'refs/heads/pre-release/1.16'
              with:
                  allowUpdates: true
                  prerelease: true
                  removeArtifacts: true
                  replacesArtifacts: true
                  artifacts: "artifacts/*"
                  bodyFile: release-notes.md
                  name: nightly
                  tag: nightly
                  commit: ${{ github.sha }}
            - name: trigger stm32 build
              if: github.ref == 'refs/heads/master'
              run: |
                curl -L \
                -X POST \
                -H "Accept: application/vnd.github+json" \
                -H "Authorization: Bearer ${{ secrets.STM32_CPP_TRIGGER }}" \
                -H "X-GitHub-Api-Version: 2022-11-28" \
                https://api.github.com/repos/slint-ui/slint-cpp-templates-stm32/actions/workflows/ci.yaml/dispatches \
                -d '{"ref":"main"}'

    nightly-tests:
        if: github.event.inputs.release != 'true'
        needs: [prepare_release]
        uses: ./.github/workflows/nightly_tests.yaml

    nightly-build-and-test:
        if: github.event.inputs.release != 'true'
        strategy:
            matrix:
                include:
                    - os: ubuntu-22.04
                      name: "Ubuntu 22.04 1.92"
                      rust_version: "1.92"
                      # plotter is excluded because with --all-features, its dependency cause build error because of fontconfig's dlopen feature
                      extra_args: "--exclude plotter"
                    - os: windows-2022
                      name: "Windows 2022 nightly"
                      rust_version: "nightly"
                      extra_args: "--exclude ffmpeg --exclude gstreamer-player"
                    - os: macos-14
                      name: "MacOS 14 nightly"
                      rust_version: "nightly"
                      # plotter is excluded because its dependency doesn't build with Nightly rust: https://github.com/servo/pathfinder/issues/584
                      extra_args: "--exclude ffmpeg --exclude gstreamer-player --exclude plotter"
        uses: ./.github/workflows/build_and_test_reusable.yaml
        with:
            os: ${{ matrix.os }}
            name: ${{ matrix.name }}
            rust_version: ${{ matrix.rust_version }}
            extra_args: ${{ matrix.extra_args }}
            # In the nightly CI run, run cargo update to test if any downstream dependency broke our build
            # Do not update the cache though, as that would trash the cache for the next runner, which uses the non-updated
            # lockfile.
            update: true
            save_if: false

    android:
        env:
            CARGO_APK_RELEASE_KEYSTORE: /home/runner/.android/release.keystore
            CARGO_APK_RELEASE_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
        runs-on: ubuntu-latest
        steps:
            - uses: actions/checkout@v6
            - uses: ./.github/actions/install-linux-dependencies
            - name: Install Android API level 30
              run: ${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager --install "platforms;android-30"
            - name: Cache cargo-apk
              id: cargo-apk-cache
              uses: actions/cache@v5
              with:
                  path: ~/.cargo/bin/cargo-apk
                  key: cargo-apk-cache
            # Only build cargo-apk if not cached
            - uses: dtolnay/rust-toolchain@stable
              if: steps.cargo-apk-cache.outputs.cache-hit != 'true'
            - name: Install cargo-apk
              if: steps.cargo-apk-cache.outputs.cache-hit != 'true'
              run: cargo install cargo-apk

            - uses: ./.github/actions/setup-rust
              with:
                  target: aarch64-linux-android

            - name: dump keystore
              run: |
                  mkdir -p /home/runner/.android
                  echo "${{ secrets.ANDROID_KEYSTORE_BASE64 }}" | base64 --decode > $CARGO_APK_RELEASE_KEYSTORE

            - name: Build energy-monitor example
              run: cargo apk build -p energy-monitor --target aarch64-linux-android --lib --release
            - name: Build todo demo
              run: cargo apk build -p todo --target aarch64-linux-android --lib --release
            - name: Build weather-demo example
              run: cargo apk build -p weather-demo --target aarch64-linux-android --lib --release
            - name: Build usecases demo
              run: cargo apk build -p usecases --target aarch64-linux-android --lib --release
            - name: Build home automation demo
              run: cargo apk build -p home-automation --target aarch64-linux-android --lib --release
            - name: "upload APK artifact"
              uses: actions/upload-artifact@v7
              with:
                  name: android-demo
                  path: |
                    target/release/apk/energy-monitor.apk
                    target/release/apk/todo_lib.apk
                    target/release/apk/weather_demo.apk
                    target/release/apk/usecases_lib.apk
                    target/release/apk/usecases_lib.apk
                    target/release/apk/home_automation_lib.apk
