conan-recipe-version.yml 11 KB

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