conan-recipe-version.yml 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. recipe_user:
  26. description: "The conan user"
  27. value: ${{ jobs.get-semver.outputs.user }}
  28. recipe_channel:
  29. description: "The conan channel"
  30. value: ${{ jobs.get-semver.outputs.channel }}
  31. jobs:
  32. get-semver:
  33. runs-on: ubuntu-latest
  34. outputs:
  35. recipe_id_full: ${{ steps.get-conan-broadcast-data.outputs.recipe_id_full }}
  36. recipe_id_latest: ${{ steps.get-conan-broadcast-data.outputs.recipe_id_latest }}
  37. semver_full: ${{ steps.get-conan-broadcast-data.outputs.semver_full }}
  38. is_release_branch: ${{ steps.get-conan-broadcast-data.outputs.is_release_branch }}
  39. user: ${{ steps.get-conan-broadcast-data.outputs.user }}
  40. channel: ${{ steps.get-conan-broadcast-data.outputs.channel }}
  41. steps:
  42. - name: Checkout repo
  43. uses: actions/checkout@v3
  44. if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
  45. with:
  46. fetch-depth: 0
  47. ref: ${{ github.head_ref }}
  48. - name: Checkout repo PR
  49. uses: actions/checkout@v3
  50. if: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
  51. with:
  52. fetch-depth: 0
  53. ref: ${{ github.event.pull_request.head.ref }}
  54. repository: ${{ github.event.pull_request.head.repo.full_name }}
  55. - name: Setup Python and pip
  56. uses: actions/setup-python@v4
  57. with:
  58. python-version: "3.10.x"
  59. cache: 'pip'
  60. cache-dependency-path: .github/workflows/requirements-conan-package.txt
  61. - name: Install Python requirements and Create default Conan profile
  62. run: |
  63. pip install -r .github/workflows/requirements-conan-package.txt
  64. pip install gitpython
  65. - id: get-conan-broadcast-data
  66. name: Get Conan broadcast data
  67. run: |
  68. import subprocess
  69. from conans import tools
  70. from conans.errors import ConanException
  71. from git import Repo
  72. repo = Repo('.')
  73. user = "${{ github.repository_owner }}".lower()
  74. project_name = "${{ inputs.project_name }}"
  75. event_name = "${{ github.event_name }}"
  76. issue_number = "${{ github.ref }}".split('/')[2]
  77. is_tag = "${{ github.ref_type }}" == "tag"
  78. is_release_branch = False
  79. buildmetadata = "" if "${{ inputs.additional_buildmetadata }}" == "" else "${{ inputs.additional_buildmetadata }}_"
  80. # FIXME: for when we push a tag (such as an release)
  81. channel = "testing"
  82. if is_tag:
  83. branch_version = tools.Version("${{ github.ref_name }}")
  84. is_release_branch = True
  85. channel = "_"
  86. user = "_"
  87. else:
  88. try:
  89. branch_version = tools.Version(repo.active_branch.name)
  90. except ConanException:
  91. branch_version = tools.Version('0.0.0')
  92. if "${{ github.ref_name }}" == f"{branch_version.major}.{branch_version.minor}":
  93. channel = 'stable'
  94. is_release_branch = True
  95. elif "${{ github.ref_name }}" in ("main", "master"):
  96. channel = 'testing'
  97. else:
  98. channel = repo.active_branch.name.split("_")[0].replace("-", "_").lower()
  99. if "pull_request" in event_name:
  100. channel = f"pr_{issue_number}"
  101. # %% Get the actual version
  102. latest_branch_version = tools.Version("0.0.0")
  103. latest_branch_tag = None
  104. for tag in repo.git.tag(merged = True).splitlines():
  105. try:
  106. version = tools.Version(tag)
  107. except ConanException:
  108. continue
  109. if version > latest_branch_version:
  110. latest_branch_version = version
  111. latest_branch_tag = repo.tag(tag)
  112. if latest_branch_tag:
  113. # %% Get the actual version
  114. no_commits = 0
  115. for commit in repo.iter_commits("HEAD"):
  116. if commit == latest_branch_tag.commit:
  117. break
  118. no_commits += 1
  119. if no_commits == 0:
  120. # This is a release
  121. actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{latest_branch_version.patch}"
  122. if channel == "stable":
  123. user = "_"
  124. channel = "_"
  125. else:
  126. if latest_branch_version.prerelease and not "." in latest_branch_version.prerelease:
  127. # The prerealese did not contain a version number, default it to 1
  128. latest_branch_version.prerelease += ".1"
  129. if event_name == "pull_request":
  130. 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}"
  131. else:
  132. if channel in ("stable", "_", ""):
  133. channel_metadata = f"{no_commits}"
  134. else:
  135. channel_metadata = f"{channel}_{no_commits}"
  136. # FIXME: for when we create a new release branch
  137. if latest_branch_version.prerelease == "":
  138. bump_up_minor = int(latest_branch_version.minor) + 1
  139. actual_version = f"{latest_branch_version.major}.{bump_up_minor}.{latest_branch_version.patch}-alpha+{buildmetadata}{channel_metadata}"
  140. else:
  141. actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{latest_branch_version.patch}-{latest_branch_version.prerelease.lower()}+{buildmetadata}{channel_metadata}"
  142. else:
  143. # FIXME: for external PR's
  144. actual_version = f"5.2.0-alpha+{buildmetadata}pr_{issue_number}"
  145. # %% print to output
  146. cmd_name = ["echo", f"::set-output name=name::{project_name}"]
  147. subprocess.call(cmd_name)
  148. cmd_version = ["echo", f"::set-output name=version::{actual_version}"]
  149. subprocess.call(cmd_version)
  150. cmd_channel = ["echo", f"::set-output name=channel::{channel}"]
  151. subprocess.call(cmd_channel)
  152. cmd_id_full= ["echo", f"::set-output name=recipe_id_full::{project_name}/{actual_version}@{user}/{channel}"]
  153. subprocess.call(cmd_id_full)
  154. cmd_id_latest = ["echo", f"::set-output name=recipe_id_latest::{project_name}/latest@{user}/{channel}"]
  155. subprocess.call(cmd_id_latest)
  156. cmd_semver_full = ["echo", f"::set-output name=semver_full::{actual_version}"]
  157. subprocess.call(cmd_semver_full)
  158. cmd_is_release_branch = ["echo", f"::set-output name=is_release_branch::{str(is_release_branch).lower()}"]
  159. subprocess.call(cmd_is_release_branch)
  160. print("::group::Conan Recipe Information")
  161. print(f"name = {project_name}")
  162. print(f"version = {actual_version}")
  163. print(f"user = {user}")
  164. print(f"channel = {channel}")
  165. print(f"recipe_id_full = {project_name}/{actual_version}@{user}/{channel}")
  166. print(f"recipe_id_latest = {project_name}/latest@{user}/{channel}")
  167. print(f"semver_full = {actual_version}")
  168. print(f"is_release_branch = {str(is_release_branch).lower()}")
  169. print("::endgroup::")
  170. shell: python