当前位置:   article > 正文

c++ qt获取电脑的内存_Qt使用github-Actions自动化发行

github action qt

v2-17cfcf072e766ab0b3a339f53ea87ed2_1440w.jpg?source=172ae18b

目录

(放个目录方便预览。目录是从博客复制过来的,点击会跳转到博客)

  • 简介
  • Qt项目的编译流程
  • Qt项目的发布流程
    • 查找依赖
    • 制作包
    • 上传
  • 定制发布流程
    • 发布时机
    • 打包步骤
    • 多平台发布
    • 最终配置
      • windows版的最终配置
      • MacOS最终配置
    • 结果和代码

简介

在上一篇文章《Qt使用github-Actions自动化编译》中,介绍了github-Actions的基本用法,

本文来介绍github-Actions的自动化发布。

结果预览

v2-ee796a229341aa0b0d502d41781e3459_b.jpg

Qt项目的编译流程

先来回顾一下,上一篇文章中的Qt项目的编译流程

  1. 安装Qt环境
    这一步用第三方Action模板:install-qt-action
  2. 获取项目代码
    这一步用Actions官方核心模板:actions/checkout
  3. 执行qmake、make
    这一步用自定义脚本,也可以换成cmake、qbs、gn、ninja等构建工具
  4. 执行test
    这一步可以引入单元测试、自动化UI测试等。暂无完善的方案,以后再说。
  5. 发布
    见下文。

Qt项目的发布流程

Qt程序在编译完成后,发布的大致流程是:

1、 查找依赖库

2、制作压缩包或者安装包

3、上传压缩包或者安装包到网站、网盘。

查找依赖

Qt官方提供的查找依赖库的命令行工具,包括:Windows平台的Windeployqt、MacOS平台的Macosdeployqt。

在这两个平台,只使用Qt库的情况下,这两个工具足够了。

制作包

做压缩包比较简单。(我们常说的‘绿色软件’,就是一个压缩包)

一般安装7z、rar之类的压缩工具,用一条命令行就行了。

涛哥这里再说一下,github-Actions给所有平台都提供了PowerShell,而PowerShell内置了压缩命令Compress-Archive。

使用也很简单,只要路径和名字,例如:

Compress-Archive 

做安装包,Qt官方有功能很全面的安装包制作工具:QtInstallFrameWork, 稍微翻看一下文档或者例子即可。本文先不展开了。

上传

github 本身提供了’Release’功能,每个仓库都有一个’Release’页面

v2-8bb3bd07382e077830a69d5505418e13_b.jpg

可以将打包好的压缩包或者安装包,直接上传上去, 供他人下载。

v2-13eb7a5c531cf8501fb5615d9aa33db8_b.jpg

github-Actions还提供了 创建’Release’、上传’Release’的模板

actions/create-release

actions/upload-release-asset

这两个模板的用法也很简单,在yml文件中直接use就行了,不赘述了。

定制发布流程

前面介绍了一些简单的理论,接下来通过实例,教大家github-Actions的使用。

以HelloActions-Qt项目为例,做一些定制。

需求如下:

1、每次提交代码,同时在Windows、MacOS、Ubuntu、Android、IOS五个平台编译

2、每次提交tag,在windows和MacOS平台制作软件包,并发布到同一个github-‘Release’

需求1已经实现了,着重讨论一下需求2:

发布时机

‘每次提交tag’限定了发布的时机。

涛哥尝试了一番,最终得到答案。

回顾一下, Windows平台的编译配置:

name

steps中的每一个步骤,可以有触发条件。我们可以在这里指定,只有github的事件为tag时才执行:

  1. steps:
  2. 。。。
  3. # tag 打包
  4. - name: package
  5. if: startsWith(github.event.ref, 'refs/tags/')
  6. run: |
  7. 。。。

打包步骤

这里给出一个实际的打包步骤:

  1. # tag 打包
  2. - name: package
  3. if: startsWith(github.event.ref, 'refs/tags/')
  4. env:
  5. VCINSTALLDIR: 'C:Program Files (x86)Microsoft Visual Studio2019EnterpriseVC'
  6. archiveName: ${{ matrix.qt_ver }}-${{ matrix.qt_target }}-${{ matrix.qt_arch }}
  7. targetName: HelloActions-Qt.exe
  8. shell: pwsh
  9. run: |
  10. # 创建文件夹
  11. New-Item -ItemType Directory ${env:archiveName}
  12. # 拷贝exe
  13. Copy-Item bin${env:targetName} ${env:archiveName}
  14. # 拷贝依赖
  15. windeployqt --qmldir . ${env:archiveName}${env:targetName}
  16. # 打包zip
  17. Compress-Archive -Path ${env:archiveName} ${env:archiveName}'.zip'
  18. # 记录环境变量packageName给后续step
  19. $name = ${env:archiveName}
  20. echo "::set-env name=packageName::$name"
  21. # 打印环境变量packageName
  22. Write-Host 'packageName:'${env:packageName}

做一些说明:

  • vs运行时

其中的VCINSTALLDIR环境变量,是给windeployqt用的。有了这个环境变量,windeployqt会去msvc的安装路径提取‘运行时安装程序’。

  • 记录包名称

打包完以后,将包名设置为环境变量,后续的步骤就可以通过环境变量拿到包名字了。

普通的设置环境变量,在步骤执行完成后就失效了,

这里使用github-Actions的‘记录命令’set-env ,具体可以参考文档github-Actions记录命令

文档说不要用双引号,应该都是针对linux的,我试出来的PowerShell用法如下:

  1. $name = ${env:archiveName}
  2. echo "::set-env name=packageName::$name"

先取环境变量到一个局部变量,再在‘记录命令’中引用局部变量。

多平台发布

如果只有一个平台、一种配置,直接用那两个模板就能解决问题。

这是官方给的例子upload-release-asset:

  1. steps:
  2. - name: Checkout code
  3. uses: actions/checkout@master
  4. - name: Build project # This would actually build your project, using zip for an example artifact
  5. run: |
  6. zip --junk-paths my-artifact README.md
  7. - name: Create Release
  8. id: create_release
  9. uses: actions/create-release@v1.0.0
  10. env:
  11. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  12. with:
  13. tag_name: ${{ github.ref }}
  14. release_name: Release ${{ github.ref }}
  15. draft: false
  16. prerelease: false
  17. - name: Upload Release Asset
  18. id: upload-release-asset
  19. uses: actions/upload-release-asset@v1.0.1
  20. env:
  21. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  22. with:
  23. upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
  24. asset_path: ./my-artifact.zip
  25. asset_name: my-artifact.zip
  26. asset_content_type: application/zip

在多平台 或者 多配置的情况下,同一个tag, 只有第一个执行create-release的任务可以成功,后续任务

再次执行create-release时,该tag下已经有了同名的‘Release’,所以会create失败。

这个问题折磨了涛哥好一阵子。找不到现成的解决方案,涛哥就自己实现了一种:

  1. 先用github的REST API去判断该tag下有没有‘Release’:
    没有则执行create-release,并提取upload_url;
    有则提取upload_url。
  2. 最后执行upload-release-asset

调用REST API,涛哥依旧使用了方便的PowerShell,

实际的配置如下:

  1. # tag 查询github-Release
  2. - name: queryReleaseWin
  3. id: queryReleaseWin
  4. if: startsWith(github.event.ref, 'refs/tags/')
  5. shell: pwsh
  6. env:
  7. githubFullName: ${{ github.event.repository.full_name }}
  8. ref: ${{ github.event.ref }}
  9. run: |
  10. [string]$tag = ${env:ref}.Substring(${env:ref}.LastIndexOf('/') + 1)
  11. [string]$url = 'https://api.github.com/repos/' + ${env:githubFullName} + '/releases/tags/' + ${tag}
  12. $response={}
  13. try {
  14. $response = Invoke-RestMethod -Uri $url -Method Get
  15. } catch {
  16. Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
  17. Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
  18. # 没查到,输出
  19. echo "::set-output name=needCreateRelease::true"
  20. return
  21. }
  22. [string]$latestUpUrl = $response.upload_url
  23. Write-Host 'latestUpUrl:'$latestUpUrl
  24. if ($latestUpUrl.Length -eq 0) {
  25. # 没查到,输出
  26. echo "::set-output name=needCreateRelease::true"
  27. }
  28. # tag 创建github-Release
  29. - name: createReleaseWin
  30. id: createReleaseWin
  31. if: startsWith(github.event.ref, 'refs/tags/') && steps.queryReleaseWin.outputs.needCreateRelease == 'true'
  32. env:
  33. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  34. uses: actions/create-release@v1.0.0
  35. with:
  36. tag_name: ${{ github.ref }}
  37. release_name: Release ${{ github.ref }}
  38. body: ${{ github.event.head_commit.message }}
  39. draft: false
  40. prerelease: false
  41. # tag 重定向upload_url到环境变量uploadUrl。
  42. - name: getLatestTagRelease
  43. if: startsWith(github.event.ref, 'refs/tags/')
  44. shell: pwsh
  45. env:
  46. githubFullName: ${{ github.event.repository.full_name }}
  47. upUrl: ${{ steps.createReleaseWin.outputs.upload_url }}
  48. ref: ${{ github.event.ref }}
  49. run: |
  50. # upUrl不为空,导出就完事
  51. if (${env:upUrl}.Length -gt 0) {
  52. $v=${env:upUrl}
  53. echo "::set-env name=uploadUrl::$v"
  54. return
  55. }
  56. # upUrl为空则重新获取
  57. [string]$tag = ${env:ref}.Substring(${env:ref}.LastIndexOf('/') + 1)
  58. [string]$url = 'https://api.github.com/repos/' + ${env:githubFullName} + '/releases/tags/' + ${tag}
  59. $response = Invoke-RestMethod -Uri $url -Method Get
  60. [string]$latestUpUrl = $response.upload_url
  61. Write-Host 'latestUpUrl:'$latestUpUrl
  62. # 导出
  63. echo "::set-env name=uploadUrl::$latestUpUrl"
  64. Write-Host 'env uploadUrl:'${env:uploadUrl}
  65. # tag 上传Release
  66. - name: uploadRelease
  67. id: uploadRelease
  68. if: startsWith(github.event.ref, 'refs/tags/')
  69. env:
  70. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  71. uses: actions/upload-release-asset@v1.0.1
  72. with:
  73. upload_url: ${{ env.uploadUrl }}
  74. asset_path: ./${{ env.packageName }}.zip
  75. asset_name: ${{ env.packageName }}.zip
  76. asset_content_type: application/zip

最终配置

windows版的最终配置

  1. name: Windows
  2. on:
  3. # push代码时触发workflow
  4. push:
  5. # 忽略README.md
  6. paths-ignore:
  7. - 'README.md'
  8. - 'LICENSE'
  9. # pull_request时触发workflow
  10. pull_request:
  11. # 忽略README.md
  12. paths-ignore:
  13. - 'README.md'
  14. - 'LICENSE'
  15. jobs:
  16. build:
  17. name: Build
  18. # 运行平台, windows-latest目前是windows server 2019
  19. runs-on: windows-latest
  20. strategy:
  21. # 矩阵配置
  22. matrix:
  23. qt_ver: [5.12.6]
  24. qt_target: [desktop]
  25. qt_arch: [win64_msvc2017_64, win32_msvc2017]
  26. # 额外设置msvc_arch
  27. include:
  28. - qt_arch: win64_msvc2017_64
  29. msvc_arch: x64
  30. qt_arch_install: msvc2017_64
  31. - qt_arch: win32_msvc2017
  32. msvc_arch: x86
  33. qt_arch_install: msvc2017
  34. env:
  35. targetName: HelloActions-Qt.exe
  36. # 步骤
  37. steps:
  38. # 安装Qt
  39. - name: Install Qt
  40. # 使用外部action。这个action专门用来安装Qt
  41. uses: jurplel/install-qt-action@v2.0.0
  42. with:
  43. # Version of Qt to install
  44. version: ${{ matrix.qt_ver }}
  45. # Target platform for build
  46. target: ${{ matrix.qt_target }}
  47. # Architecture for Windows/Android
  48. arch: ${{ matrix.qt_arch }}
  49. # 拉取代码
  50. - uses: actions/checkout@v1
  51. with:
  52. fetch-depth: 1
  53. # 编译msvc
  54. - name: build-msvc
  55. shell: cmd
  56. env:
  57. vc_arch: ${{ matrix.msvc_arch }}
  58. run: |
  59. call "C:Program Files (x86)Microsoft Visual Studio2019EnterpriseVCAuxiliaryBuildvcvarsall.bat" %vc_arch%
  60. qmake
  61. nmake
  62. # tag 打包
  63. - name: package
  64. if: startsWith(github.event.ref, 'refs/tags/')
  65. env:
  66. VCINSTALLDIR: 'C:Program Files (x86)Microsoft Visual Studio2019EnterpriseVC'
  67. archiveName: ${{ matrix.qt_ver }}-${{ matrix.qt_target }}-${{ matrix.qt_arch }}
  68. shell: pwsh
  69. run: |
  70. # 创建文件夹
  71. New-Item -ItemType Directory ${env:archiveName}
  72. # 拷贝exe
  73. Copy-Item bin${env:targetName} ${env:archiveName}
  74. # 拷贝依赖
  75. windeployqt --qmldir . ${env:archiveName}${env:targetName}
  76. # 打包zip
  77. Compress-Archive -Path ${env:archiveName} ${env:archiveName}'.zip'
  78. # 记录环境变量packageName给后续step
  79. $name = ${env:archiveName}
  80. echo "::set-env name=packageName::$name"
  81. # 打印环境变量packageName
  82. Write-Host 'packageName:'${env:packageName}
  83. # tag 查询github-Release
  84. - name: queryReleaseWin
  85. id: queryReleaseWin
  86. if: startsWith(github.event.ref, 'refs/tags/')
  87. shell: pwsh
  88. env:
  89. githubFullName: ${{ github.event.repository.full_name }}
  90. ref: ${{ github.event.ref }}
  91. run: |
  92. [string]$tag = ${env:ref}.Substring(${env:ref}.LastIndexOf('/') + 1)
  93. [string]$url = 'https://api.github.com/repos/' + ${env:githubFullName} + '/releases/tags/' + ${tag}
  94. $response={}
  95. try {
  96. $response = Invoke-RestMethod -Uri $url -Method Get
  97. } catch {
  98. Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
  99. Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
  100. # 没查到,输出
  101. echo "::set-output name=needCreateRelease::true"
  102. return
  103. }
  104. [string]$latestUpUrl = $response.upload_url
  105. Write-Host 'latestUpUrl:'$latestUpUrl
  106. if ($latestUpUrl.Length -eq 0) {
  107. # 没查到,输出
  108. echo "::set-output name=needCreateRelease::true"
  109. }
  110. # tag 创建github-Release
  111. - name: createReleaseWin
  112. id: createReleaseWin
  113. if: startsWith(github.event.ref, 'refs/tags/') && steps.queryReleaseWin.outputs.needCreateRelease == 'true'
  114. env:
  115. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  116. uses: actions/create-release@v1.0.0
  117. with:
  118. tag_name: ${{ github.ref }}
  119. release_name: Release ${{ github.ref }}
  120. body: ${{ github.event.head_commit.message }}
  121. draft: false
  122. prerelease: false
  123. # 重定向upload_url到环境变量uploadUrl。
  124. - name: getLatestTagRelease
  125. # tag 上一步无论成功还是失败都执行
  126. if: startsWith(github.event.ref, 'refs/tags/')
  127. shell: pwsh
  128. env:
  129. githubFullName: ${{ github.event.repository.full_name }}
  130. upUrl: ${{ steps.createReleaseWin.outputs.upload_url }}
  131. ref: ${{ github.event.ref }}
  132. run: |
  133. # upUrl不为空,导出就完事
  134. if (${env:upUrl}.Length -gt 0) {
  135. $v=${env:upUrl}
  136. echo "::set-env name=uploadUrl::$v"
  137. return
  138. }
  139. [string]$tag = ${env:ref}.Substring(${env:ref}.LastIndexOf('/') + 1)
  140. [string]$url = 'https://api.github.com/repos/' + ${env:githubFullName} + '/releases/tags/' + ${tag}
  141. $response = Invoke-RestMethod -Uri $url -Method Get
  142. [string]$latestUpUrl = $response.upload_url
  143. Write-Host 'latestUpUrl:'$latestUpUrl
  144. echo "::set-env name=uploadUrl::$latestUpUrl"
  145. Write-Host 'env uploadUrl:'${env:uploadUrl}
  146. # tag 上传Release
  147. - name: uploadRelease
  148. id: uploadRelease
  149. if: startsWith(github.event.ref, 'refs/tags/')
  150. env:
  151. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  152. uses: actions/upload-release-asset@v1.0.1
  153. with:
  154. upload_url: ${{ env.uploadUrl }}
  155. asset_path: ./${{ env.packageName }}.zip
  156. asset_name: ${{ env.packageName }}.zip
  157. asset_content_type: application/zip

MacOS最终配置

  1. name: MacOS
  2. on:
  3. push:
  4. paths-ignore:
  5. - 'README.md'
  6. - 'LICENSE'
  7. pull_request:
  8. paths-ignore:
  9. - 'README.md'
  10. - 'LICENSE'
  11. jobs:
  12. build:
  13. name: Build
  14. runs-on: ${{ matrix.os }}
  15. strategy:
  16. matrix:
  17. os: [macos-latest]
  18. qt_ver: [5.12.6]
  19. qt_arch: [clang_64]
  20. env:
  21. targetName: HelloActions-Qt
  22. steps:
  23. - name: Install Qt
  24. uses: jurplel/install-qt-action@v2.0.0
  25. with:
  26. version: ${{ matrix.qt_ver }}
  27. - uses: actions/checkout@v1
  28. with:
  29. fetch-depth: 1
  30. - name: build macos
  31. run: |
  32. qmake
  33. make
  34. # tag 打包
  35. - name: package
  36. if: startsWith(github.event.ref, 'refs/tags/')
  37. run: |
  38. # 拷贝依赖
  39. macdeployqt bin/${targetName}.app -qmldir=. -verbose=1 -dmg
  40. # tag 查询github-Release
  41. - name: queryRelease
  42. id: queryReleaseMacos
  43. if: startsWith(github.event.ref, 'refs/tags/')
  44. shell: pwsh
  45. env:
  46. githubFullName: ${{ github.event.repository.full_name }}
  47. ref: ${{ github.event.ref }}
  48. run: |
  49. [string]$tag = ${env:ref}.Substring(${env:ref}.LastIndexOf('/') + 1)
  50. [string]$url = 'https://api.github.com/repos/' + ${env:githubFullName} + '/releases/tags/' + ${tag}
  51. $response={}
  52. try {
  53. $response = Invoke-RestMethod -Uri $url -Method Get
  54. } catch {
  55. Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
  56. Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
  57. # 没查到,输出
  58. echo "::set-output name=needCreateRelease::true"
  59. return
  60. }
  61. [string]$latestUpUrl = $response.upload_url
  62. Write-Host 'latestUpUrl:'$latestUpUrl
  63. if ($latestUpUrl.Length -eq 0) {
  64. # 没查到,输出
  65. echo "::set-output name=needCreateRelease::true"
  66. }
  67. # tag 创建github-Release
  68. - name: createReleaseWin
  69. id: createReleaseWin
  70. if: startsWith(github.event.ref, 'refs/tags/') && steps.queryReleaseMacos.outputs.needCreateRelease == 'true'
  71. env:
  72. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  73. uses: actions/create-release@v1.0.0
  74. with:
  75. tag_name: ${{ github.ref }}
  76. release_name: Release ${{ github.ref }}
  77. body: ${{ github.event.head_commit.message }}
  78. draft: false
  79. prerelease: false
  80. # 重定向upload_url到环境变量uploadUrl。
  81. - name: getLatestTagRelease
  82. # tag 上一步无论成功还是失败都执行
  83. if: startsWith(github.event.ref, 'refs/tags/')
  84. shell: pwsh
  85. env:
  86. githubFullName: ${{ github.event.repository.full_name }}
  87. upUrl: ${{ steps.queryReleaseMacos.outputs.upload_url }}
  88. ref: ${{ github.event.ref }}
  89. run: |
  90. # upUrl不为空,导出就完事
  91. if (${env:upUrl}.Length -gt 0) {
  92. $v=${env:upUrl}
  93. echo "::set-env name=uploadUrl::$v"
  94. return
  95. }
  96. [string]$tag = ${env:ref}.Substring(${env:ref}.LastIndexOf('/') + 1)
  97. [string]$url = 'https://api.github.com/repos/' + ${env:githubFullName} + '/releases/tags/' + ${tag}
  98. $response = Invoke-RestMethod -Uri $url -Method Get
  99. [string]$latestUpUrl = $response.upload_url
  100. Write-Host 'latestUpUrl:'$latestUpUrl
  101. echo "::set-env name=uploadUrl::$latestUpUrl"
  102. Write-Host 'env uploadUrl:'${env:uploadUrl}
  103. # tag 上传Release
  104. - name: uploadRelease
  105. id: uploadRelease
  106. if: startsWith(github.event.ref, 'refs/tags/')
  107. env:
  108. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  109. uses: actions/upload-release-asset@v1.0.1
  110. with:
  111. upload_url: ${{ env.uploadUrl }}
  112. asset_path: ./bin/${{ env.targetName }}.dmg
  113. asset_name: ${{ env.targetName }}.dmg
  114. asset_content_type: application/applefile

结果和代码

v2-13eb7a5c531cf8501fb5615d9aa33db8_b.jpg

代码在github HelloActions-Qt

另外在涛哥的Qml控件库TaoQuick,也使用了这一套配置 TaoQuick

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/595339
推荐阅读
相关标签
  

闽ICP备14008679号