conan-recipe-version.yml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. name: Get Conan Recipe Version
  2. on:
  3. workflow_call:
  4. inputs:
  5. project_name:
  6. required: true
  7. type: string
  8. user:
  9. required: false
  10. default: ultimaker
  11. type: string
  12. additional_buildmetadata:
  13. required: false
  14. default: ""
  15. type: string
  16. outputs:
  17. recipe_id_full:
  18. description: "The full Conan recipe id: <name>/<version>@<user>/<channel>"
  19. value: ${{ jobs.get-semver.outputs.recipe_id_full }}
  20. recipe_id_latest:
  21. description: "The full Conan recipe aliased (latest) id: <name>/(latest)@<user>/<channel>"
  22. value: ${{ jobs.get-semver.outputs.recipe_id_latest }}
  23. recipe_semver_full:
  24. description: "The full semver <Major>.<Minor>.<Patch>-<PreReleaseTag>+<BuildMetaData>"
  25. value: ${{ jobs.get-semver.outputs.semver_full }}
  26. is_release_branch:
  27. description: "is current branch a release branch?"
  28. value: ${{ jobs.get-semver.outputs.release_branch }}
  29. user:
  30. description: "The conan user"
  31. value: ${{ jobs.get-semver.outputs.user }}
  32. channel:
  33. description: "The conan channel"
  34. value: ${{ jobs.get-semver.outputs.channel }}
  35. project_name:
  36. description: "The conan projectname"
  37. value: ${{ inputs.project_name }}
  38. jobs:
  39. get-semver:
  40. runs-on: ubuntu-latest
  41. outputs:
  42. recipe_id_full: ${{ steps.get-conan-broadcast-data.outputs.recipe_id_full }}
  43. recipe_id_latest: ${{ steps.get-conan-broadcast-data.outputs.recipe_id_latest }}
  44. semver_full: ${{ steps.get-conan-broadcast-data.outputs.semver_full }}
  45. is_release_branch: ${{ steps.get-conan-broadcast-data.outputs.is_release_branch }}
  46. user: ${{ steps.get-conan-broadcast-data.outputs.user }}
  47. channel: ${{ steps.get-conan-broadcast-data.outputs.channel }}
  48. steps:
  49. - name: Checkout repo
  50. uses: actions/checkout@v3
  51. if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
  52. with:
  53. fetch-depth: 0
  54. ref: ${{ github.head_ref }}
  55. - name: Checkout repo PR
  56. uses: actions/checkout@v3
  57. if: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
  58. with:
  59. fetch-depth: 0
  60. ref: ${{ github.base_ref }}
  61. - name: Setup Python and pip
  62. uses: actions/setup-python@v4
  63. with:
  64. python-version: "3.11.x"
  65. cache: 'pip'
  66. cache-dependency-path: .github/workflows/requirements-conan-package.txt
  67. - name: Install Python requirements and Create default Conan profile
  68. run: |
  69. pip install -r .github/workflows/requirements-conan-package.txt
  70. pip install gitpython
  71. - id: get-conan-broadcast-data
  72. name: Get Conan broadcast data
  73. run: |
  74. import subprocess
  75. import os
  76. from conan.tools.scm import Version
  77. from conan.errors import ConanException
  78. from git import Repo
  79. repo = Repo('.')
  80. user = "${{ inputs.user }}".lower()
  81. project_name = "${{ inputs.project_name }}"
  82. event_name = "${{ github.event_name }}"
  83. issue_number = "${{ github.ref }}".split('/')[2]
  84. is_tag = "${{ github.ref_type }}" == "tag"
  85. is_release_branch = False
  86. ref_name = "${{ github.base_ref }}" if event_name == "pull_request" else "${{ github.ref_name }}"
  87. buildmetadata = "" if "${{ inputs.additional_buildmetadata }}" == "" else "${{ inputs.additional_buildmetadata }}_"
  88. # FIXME: for when we push a tag (such as an release)
  89. channel = "testing"
  90. if is_tag:
  91. branch_version = Version(ref_name)
  92. is_release_branch = True
  93. channel = "_"
  94. user = "_"
  95. actual_version = f"{branch_version}"
  96. else:
  97. try:
  98. branch_version = Version(repo.active_branch.name)
  99. except ConanException:
  100. branch_version = Version('0.0.0')
  101. if ref_name == f"{branch_version.major}.{branch_version.minor}":
  102. channel = 'stable'
  103. is_release_branch = True
  104. elif ref_name in ("main", "master"):
  105. channel = 'testing'
  106. else:
  107. channel = "_".join(repo.active_branch.name.replace("-", "_").split("_")[:2]).lower()
  108. if "pull_request" in event_name:
  109. channel = f"pr_{issue_number}"
  110. # %% Get the actual version
  111. latest_branch_version = Version("0.0.0")
  112. latest_branch_tag = None
  113. for tag in repo.active_branch.repo.tags:
  114. if str(tag).startswith("firmware") or str(tag).startswith("master"):
  115. continue # Quick-fix for the versioning scheme name of the embedded team in fdm_materials(_private) repo
  116. try:
  117. version = Version(tag)
  118. except ConanException:
  119. continue
  120. if version > latest_branch_version and version < Version("6.0.0"):
  121. # FIXME: stupid old Cura tags 13.04 etc. keep popping up, als the fdm_material tag for firmware are messing with this
  122. latest_branch_version = version
  123. latest_branch_tag = repo.tag(tag)
  124. if latest_branch_tag:
  125. # %% Get the actual version
  126. sha_commit = repo.commit().hexsha[:6]
  127. latest_branch_version_prerelease = latest_branch_version.pre
  128. if latest_branch_version.pre and not "." in str(latest_branch_version.pre):
  129. # The prerealese did not contain a version number, default it to 1
  130. latest_branch_version_prerelease = f"{latest_branch_version.pre}.1"
  131. if event_name == "pull_request":
  132. actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{latest_branch_version.patch}-{str(latest_branch_version_prerelease).lower()}+{buildmetadata}pr_{issue_number}_{sha_commit}"
  133. channel_metadata = f"{channel}_{sha_commit}"
  134. else:
  135. if channel in ("stable", "_", ""):
  136. channel_metadata = f"{sha_commit}"
  137. else:
  138. channel_metadata = f"{channel}_{sha_commit}"
  139. if is_release_branch:
  140. if latest_branch_version.pre == "" and branch_version > latest_branch_version:
  141. actual_version = f"{branch_version.major}.{branch_version.minor}.0-beta.1+{buildmetadata}{channel_metadata}"
  142. elif latest_branch_version.pre == "":
  143. # An actual full release has been created, we are working on patch
  144. bump_up_patch = int(str(latest_branch_version.patch)) + 1
  145. actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{bump_up_patch}-beta.1+{buildmetadata}{channel_metadata}"
  146. elif latest_branch_version.pre is None:
  147. actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{int(latest_branch_version.patch.value) + 1}-beta.1+{buildmetadata}{channel_metadata}"
  148. else:
  149. # An beta release has been created we are working toward a next beta or full release
  150. bump_up_release_tag = int(str(latest_branch_version.pre).split('.')[1]) + 1
  151. actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{latest_branch_version.patch}-{str(latest_branch_version.pre).split('.')[0]}.{bump_up_release_tag}+{buildmetadata}{channel_metadata}"
  152. else:
  153. max_branches_version = Version("0.0.0")
  154. for branch in repo.references:
  155. try:
  156. if "remotes/origin" in branch.abspath:
  157. b_version = Version(branch.name.split("/")[-1])
  158. if b_version < Version("6.0.0") and b_version > max_branches_version:
  159. max_branches_version = b_version
  160. except:
  161. pass
  162. if max_branches_version > latest_branch_version:
  163. actual_version = f"{max_branches_version.major}.{int(str(max_branches_version.minor)) + 1}.0-alpha+{buildmetadata}{channel}_{sha_commit}"
  164. else:
  165. actual_version = f"{latest_branch_version.major}.{int(str(latest_branch_version.minor)) + 1}.0-alpha+{buildmetadata}{channel_metadata}"
  166. # %% Set the environment output
  167. output_env = os.environ["GITHUB_OUTPUT"]
  168. content = ""
  169. if os.path.exists(output_env):
  170. with open(output_env, "r") as f:
  171. content = f.read()
  172. with open(output_env, "w") as f:
  173. f.write(content)
  174. f.writelines(f"name={project_name}\n")
  175. f.writelines(f"version={actual_version}\n")
  176. f.writelines(f"channel={channel}\n")
  177. f.writelines(f"recipe_id_full={project_name}/{actual_version}@{user}/{channel}\n")
  178. f.writelines(f"recipe_id_latest={project_name}/latest@{user}/{channel}\n")
  179. f.writelines(f"semver_full={actual_version}\n")
  180. f.writelines(f"is_release_branch={str(is_release_branch).lower()}\n")
  181. summary_env = os.environ["GITHUB_STEP_SUMMARY"]
  182. with open(summary_env, "w") as f:
  183. f.writelines(f"# {project_name}\n")
  184. f.writelines(f"name={project_name}\n")
  185. f.writelines(f"version={actual_version}\n")
  186. f.writelines(f"channel={channel}\n")
  187. f.writelines(f"recipe_id_full={project_name}/{actual_version}@{user}/{channel}\n")
  188. f.writelines(f"recipe_id_latest={project_name}/latest@{user}/{channel}\n")
  189. f.writelines(f"semver_full={actual_version}\n")
  190. f.writelines(f"is_release_branch={str(is_release_branch).lower()}\n")
  191. shell: python