name: Build plugin on: push: branches: - main tags: - 'v*' pull_request: branches: - main env: PLUGIN_NAME: QodeAssist QT_VERSION: 6.8.3 QT_CREATOR_VERSION: 16.0.1 QT_CREATOR_VERSION_INTERNAL: 16.0.1 MACOS_DEPLOYMENT_TARGET: "11.0" CMAKE_VERSION: "3.29.6" NINJA_VERSION: "1.12.1" jobs: build: name: ${{ matrix.config.name }} runs-on: ${{ matrix.config.os }} outputs: tag: ${{ steps.git.outputs.tag }} strategy: matrix: config: - { name: "Windows Latest MSVC", artifact: "Windows-x64", os: windows-latest, platform: windows_x64, cc: "cl", cxx: "cl", environment_script: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat", } - { name: "Ubuntu 22.04 GCC", artifact: "Linux-x64", os: ubuntu-22.04, platform: linux_x64, cc: "gcc", cxx: "g++" } - { name: "macOS Latest Clang", artifact: "macOS-universal", os: macos-latest, platform: mac_x64, cc: "clang", cxx: "clang++" } steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' - name: Checkout submodules id: git shell: cmake -P {0} run: | if (${{github.ref}} MATCHES "tags/v(.*)") file(APPEND "$ENV{GITHUB_OUTPUT}" "tag=${CMAKE_MATCH_1}") else() file(APPEND "$ENV{GITHUB_OUTPUT}" "tag=${{github.run_id}}") endif() - name: Download Ninja and CMake uses: lukka/get-cmake@latest with: cmakeVersion: ${{ env.CMAKE_VERSION }} ninjaVersion: ${{ env.NINJA_VERSION }} - name: Install dependencies shell: cmake -P {0} run: | if ("${{ runner.os }}" STREQUAL "Linux") execute_process( COMMAND sudo apt update ) execute_process( COMMAND sudo apt install # build dependencies libgl1-mesa-dev libgtest-dev libgmock-dev # runtime dependencies for tests (Qt is downloaded outside package manager, # thus minimal dependencies must be installed explicitly) libsecret-1-0 libxcb-cursor0 libxcb-icccm4 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-render0 libxcb-shape0 libxcb-shm0 libxcb-sync1 libxcb-xfixes0 libxcb-xkb1 libxkbcommon-x11-0 xvfb RESULT_VARIABLE result ) if (NOT result EQUAL 0) message(FATAL_ERROR "Failed to install dependencies") endif() endif() - name: Download Qt id: qt shell: cmake -P {0} run: | set(qt_version "$ENV{QT_VERSION}") string(REPLACE "." "" qt_version_dotless "${qt_version}") if ("${{ runner.os }}" STREQUAL "Windows") set(url_os "windows_x86") set(qt_package_arch_suffix "win64_msvc2022_64") set(qt_dir_prefix "${qt_version}/msvc2022_64") set(qt_package_suffix "-Windows-Windows_11_23H2-MSVC2022-Windows-Windows_11_23H2-X86_64") elseif ("${{ runner.os }}" STREQUAL "Linux") set(url_os "linux_x64") if (qt_version VERSION_LESS "6.7.0") set(qt_package_arch_suffix "gcc_64") else() set(qt_package_arch_suffix "linux_gcc_64") endif() set(qt_dir_prefix "${qt_version}/gcc_64") set(qt_package_suffix "-Linux-RHEL_8_10-GCC-Linux-RHEL_8_10-X86_64") elseif ("${{ runner.os }}" STREQUAL "macOS") set(url_os "mac_x64") set(qt_package_arch_suffix "clang_64") set(qt_dir_prefix "${qt_version}/macos") set(qt_package_suffix "-MacOS-MacOS_14-Clang-MacOS-MacOS_14-X86_64-ARM64") endif() set(qt_base_url "https://download.qt.io/online/qtsdkrepository/${url_os}/desktop/qt6_${qt_version_dotless}/qt6_${qt_version_dotless}") file(DOWNLOAD "${qt_base_url}/Updates.xml" ./Updates.xml SHOW_PROGRESS) file(READ ./Updates.xml updates_xml) string(REGEX MATCH "qt.qt6.*([0-9+-.]+)" updates_xml_output "${updates_xml}") set(qt_package_version ${CMAKE_MATCH_1}) file(MAKE_DIRECTORY qt6) # Save the path for other steps file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qt6" qt_dir) file(APPEND "$ENV{GITHUB_OUTPUT}" "qt_dir=${qt_dir}") message("Downloading Qt to ${qt_dir}") function(downloadAndExtract url archive) message("Downloading ${url}") file(DOWNLOAD "${url}" ./${archive} SHOW_PROGRESS) execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ../${archive} WORKING_DIRECTORY qt6) endfunction() foreach(package qtbase qtdeclarative) downloadAndExtract( "${qt_base_url}/qt.qt6.${qt_version_dotless}.${qt_package_arch_suffix}/${qt_package_version}${package}${qt_package_suffix}.7z" ${package}.7z ) endforeach() foreach(package qt5compat qtshadertools) downloadAndExtract( "${qt_base_url}/qt.qt6.${qt_version_dotless}.addons.${package}.${qt_package_arch_suffix}/${qt_package_version}${package}${qt_package_suffix}.7z" ${package}.7z ) endforeach() function(downloadAndExtractLibicu url archive) message("Downloading ${url}") file(DOWNLOAD "${url}" ./${archive} SHOW_PROGRESS) execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ../../${archive} WORKING_DIRECTORY qt6/lib) endfunction() # uic depends on libicu*.so if ("${{ runner.os }}" STREQUAL "Linux") if (qt_version VERSION_LESS "6.7.0") set(uic_suffix "Rhel7.2-x64") else() set(uic_suffix "Rhel8.6-x86_64") endif() downloadAndExtractLibicu( "${qt_base_url}/qt.qt6.${qt_version_dotless}.${qt_package_arch_suffix}/${qt_package_version}icu-linux-${uic_suffix}.7z" icu.7z ) endif() - name: Download Qt Creator uses: qt-creator/install-dev-package@v1.2 with: version: ${{ env.QT_CREATOR_VERSION }} unzip-to: 'qtcreator' - name: Extract Qt Creator id: qt_creator shell: cmake -P {0} run: | file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qtcreator" qtc_dir) file(APPEND "$ENV{GITHUB_OUTPUT}" "qtc_dir=${qtc_dir}") - name: Build shell: cmake -P {0} run: | set(ENV{CC} ${{ matrix.config.cc }}) set(ENV{CXX} ${{ matrix.config.cxx }}) set(ENV{MACOSX_DEPLOYMENT_TARGET} "${{ env.MACOS_DEPLOYMENT_TARGET }}") if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x") execute_process( COMMAND "${{ matrix.config.environment_script }}" && set OUTPUT_FILE environment_script_output.txt ) file(STRINGS environment_script_output.txt output_lines) foreach(line IN LISTS output_lines) if (line MATCHES "^([a-zA-Z0-9_-]+)=(.*)$") set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}") endif() endforeach() endif() set(ENV{NINJA_STATUS} "[%f/%t %o/sec] ") if ("${{ runner.os }}" STREQUAL "macOS") set(ENV{CMAKE_OSX_ARCHITECTURES} "x86_64;arm64") endif() set(build_plugin_py "scripts/build_plugin.py") foreach(dir "share/qtcreator/scripts" "Qt Creator.app/Contents/Resources/scripts" "Contents/Resources/scripts") if(EXISTS "${{ steps.qt_creator.outputs.qtc_dir }}/${dir}/build_plugin.py") set(build_plugin_py "${dir}/build_plugin.py") break() endif() endforeach() execute_process( COMMAND python -u "${{ steps.qt_creator.outputs.qtc_dir }}/${build_plugin_py}" --name "$ENV{PLUGIN_NAME}-$ENV{QT_CREATOR_VERSION}-${{ matrix.config.artifact }}" --src . --build build --qt-path "${{ steps.qt.outputs.qt_dir }}" --qtc-path "${{ steps.qt_creator.outputs.qtc_dir }}" --output-path "$ENV{GITHUB_WORKSPACE}" RESULT_VARIABLE result ) if (NOT result EQUAL 0) string(REGEX MATCH "FAILED:.*$" error_message "${output}") string(REPLACE "\n" "%0A" error_message "${error_message}") message("::error::${error_message}") message(FATAL_ERROR "Build failed") endif() - name: Upload uses: actions/upload-artifact@v4 with: path: ./${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}.7z name: ${{ env.PLUGIN_NAME}}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}.7z # The json is the same for all platforms, but we need to save one - name: Upload plugin json if: startsWith(matrix.config.os, 'ubuntu') uses: actions/upload-artifact@v4 with: name: ${{ env.PLUGIN_NAME }}-origin-json path: ./build/build/${{ env.PLUGIN_NAME }}.json - name: Run unit tests if: startsWith(matrix.config.os, 'ubuntu') run: | xvfb-run ./build/build/test/QodeAssistTest update_json: if: contains(github.ref, 'tags/v') runs-on: ubuntu-22.04 needs: build steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: actions/setup-node@v4 with: node-version: '20' - name: Download the JSON file uses: actions/download-artifact@v4 with: name: ${{ env.PLUGIN_NAME }}-origin-json path: ./${{ env.PLUGIN_NAME }}-origin - name: Store Release upload_url run: | RELEASE_HTML_URL=$(echo "${{github.event.repository.html_url}}/releases/download/v${{ needs.build.outputs.tag }}") echo "RELEASE_HTML_URL=${RELEASE_HTML_URL}" >> $GITHUB_ENV - name: Run the Node.js script to update JSON env: QT_TOKEN: ${{ secrets.TOKEN }} API_URL: ${{ secrets.API_URL }} run: | node .github/scripts/registerPlugin.js ${{ env.RELEASE_HTML_URL }} ${{ env.PLUGIN_NAME }} ${{ env.QT_CREATOR_VERSION }} ${{ env.QT_CREATOR_VERSION_INTERNAL }} ${{ env.QT_TOKEN }} ${{ env.API_URL }} - name: Delete previous json artifacts uses: geekyeggo/delete-artifact@v5 with: name: ${{ env.PLUGIN_NAME }}*-json - name: Upload the modified JSON file as an artifact uses: actions/upload-artifact@v4 with: name: plugin-json path: .github/scripts/${{ env.PLUGIN_NAME }}.json release: if: contains(github.ref, 'tags/v') runs-on: ubuntu-latest needs: [build, update_json] steps: - name: Download artifacts uses: actions/download-artifact@v4 with: path: release-with-dirs - name: Fixup artifacts run: | mkdir release mv release-with-dirs/*/* release/ - name: Create Release id: create_release uses: softprops/action-gh-release@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: v${{ needs.build.outputs.tag }} files: release/* draft: false prerelease: false