flatpak.yml 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. name: Flatpak release job
  2. on:
  3. workflow_call:
  4. inputs:
  5. ryujinx_version:
  6. required: true
  7. type: string
  8. concurrency: flatpak-release
  9. jobs:
  10. release:
  11. timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }}
  12. runs-on: ubuntu-latest
  13. env:
  14. NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
  15. GIT_COMMITTER_NAME: "RyujinxBot"
  16. GIT_COMMITTER_EMAIL: "61127645+RyujinxBot@users.noreply.github.com"
  17. RYUJINX_PROJECT_FILE: "src/Ryujinx/Ryujinx.csproj"
  18. NUGET_SOURCES_DESTDIR: "nuget-sources"
  19. RYUJINX_VERSION: "${{ inputs.ryujinx_version }}"
  20. steps:
  21. - uses: actions/checkout@v4
  22. with:
  23. path: Ryujinx
  24. - uses: actions/setup-dotnet@v4
  25. with:
  26. global-json-file: Ryujinx/global.json
  27. - name: Get version info
  28. id: version_info
  29. working-directory: Ryujinx
  30. run: |
  31. echo "git_hash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
  32. - uses: actions/checkout@v4
  33. with:
  34. repository: flathub/org.ryujinx.Ryujinx
  35. token: ${{ secrets.RYUJINX_BOT_PAT }}
  36. submodules: recursive
  37. path: flathub
  38. - name: Install dependencies
  39. run: python -m pip install PyYAML lxml
  40. - name: Restore Nuget packages
  41. # With .NET 8.0.100, Microsoft.NET.ILLink.Tasks isn't restored by default and only seems to appears when publishing.
  42. # So we just publish to grab the dependencies
  43. run: |
  44. dotnet publish -c Release -r linux-x64 Ryujinx/${{ env.RYUJINX_PROJECT_FILE }} --self-contained
  45. dotnet publish -c Release -r linux-arm64 Ryujinx/${{ env.RYUJINX_PROJECT_FILE }} --self-contained
  46. - name: Generate nuget_sources.json
  47. shell: python
  48. run: |
  49. import hashlib
  50. from pathlib import Path
  51. import base64
  52. import binascii
  53. import json
  54. import os
  55. import urllib.request
  56. sources = []
  57. def create_source_from_external(name, version):
  58. full_dir_path = Path(os.environ["NUGET_PACKAGES"]).joinpath(name).joinpath(version)
  59. os.makedirs(full_dir_path, exist_ok=True)
  60. filename = "{}.{}.nupkg".format(name, version)
  61. url = "https://api.nuget.org/v3-flatcontainer/{}/{}/{}".format(
  62. name, version, filename
  63. )
  64. print(f"Processing {url}...")
  65. response = urllib.request.urlopen(url)
  66. sha512 = hashlib.sha512(response.read()).hexdigest()
  67. return {
  68. "type": "file",
  69. "url": url,
  70. "sha512": sha512,
  71. "dest": os.environ["NUGET_SOURCES_DESTDIR"],
  72. "dest-filename": filename,
  73. }
  74. has_added_x64_apphost = False
  75. for path in Path(os.environ["NUGET_PACKAGES"]).glob("**/*.nupkg.sha512"):
  76. name = path.parent.parent.name
  77. version = path.parent.name
  78. filename = "{}.{}.nupkg".format(name, version)
  79. url = "https://api.nuget.org/v3-flatcontainer/{}/{}/{}".format(
  80. name, version, filename
  81. )
  82. with path.open() as fp:
  83. sha512 = binascii.hexlify(base64.b64decode(fp.read())).decode("ascii")
  84. sources.append(
  85. {
  86. "type": "file",
  87. "url": url,
  88. "sha512": sha512,
  89. "dest": os.environ["NUGET_SOURCES_DESTDIR"],
  90. "dest-filename": filename,
  91. }
  92. )
  93. # .NET will not add current installed application host to the list, force inject it here.
  94. if not has_added_x64_apphost and name.startswith('microsoft.netcore.app.host'):
  95. sources.append(create_source_from_external("microsoft.netcore.app.host.linux-x64", version))
  96. has_added_x64_apphost = True
  97. with open("flathub/nuget_sources.json", "w") as fp:
  98. json.dump(sources, fp, indent=4)
  99. - name: Update flatpak metadata
  100. id: metadata
  101. env:
  102. RYUJINX_GIT_HASH: ${{ steps.version_info.outputs.git_hash }}
  103. shell: python
  104. run: |
  105. import hashlib
  106. import hmac
  107. import json
  108. import os
  109. import yaml
  110. from datetime import datetime
  111. from lxml import etree
  112. # Ensure we don't destroy multiline strings
  113. def str_presenter(dumper, data):
  114. if len(data.splitlines()) > 1:
  115. return dumper.represent_scalar("tag:yaml.org,2002:str", data, style="|")
  116. return dumper.represent_scalar("tag:yaml.org,2002:str", data)
  117. yaml.representer.SafeRepresenter.add_representer(str, str_presenter)
  118. yaml_file = "flathub/org.ryujinx.Ryujinx.yml"
  119. xml_file = "flathub/org.ryujinx.Ryujinx.appdata.xml"
  120. with open(yaml_file, "r") as f:
  121. data = yaml.safe_load(f)
  122. for source in data["modules"][0]["sources"]:
  123. if type(source) is str:
  124. continue
  125. if (
  126. source["type"] == "git"
  127. and source["url"] == "https://github.com/Ryujinx/Ryujinx.git"
  128. ):
  129. source["commit"] = os.environ['RYUJINX_GIT_HASH']
  130. is_same_version = data["modules"][0]["build-options"]["env"]["RYUJINX_VERSION"] == os.environ['RYUJINX_VERSION']
  131. with open(os.environ['GITHUB_OUTPUT'], "a") as gh_out:
  132. if is_same_version:
  133. gh_out.write(f"commit_message=Retry update to {os.environ['RYUJINX_VERSION']}")
  134. else:
  135. gh_out.write(f"commit_message=Update to {os.environ['RYUJINX_VERSION']}")
  136. if not is_same_version:
  137. data["modules"][0]["build-options"]["env"]["RYUJINX_VERSION"] = os.environ['RYUJINX_VERSION']
  138. with open(yaml_file, "w") as f:
  139. yaml.safe_dump(data, f, sort_keys=False)
  140. parser = etree.XMLParser(remove_blank_text=True)
  141. tree = etree.parse(xml_file, parser)
  142. root = tree.getroot()
  143. releases = root.find("releases")
  144. element = etree.Element("release")
  145. element.set("version", os.environ['RYUJINX_VERSION'])
  146. element.set("date", datetime.now().date().isoformat())
  147. releases.insert(0, element)
  148. # Ensure 4 spaces
  149. etree.indent(root, space=" ")
  150. with open(xml_file, "wb") as f:
  151. f.write(
  152. etree.tostring(
  153. tree,
  154. pretty_print=True,
  155. encoding="UTF-8",
  156. doctype='<?xml version="1.0" encoding="UTF-8"?>',
  157. )
  158. )
  159. - name: Push flatpak update
  160. working-directory: flathub
  161. env:
  162. COMMIT_MESSAGE: ${{ steps.metadata.outputs.commit_message }}
  163. run: |
  164. git config user.name "${{ env.GIT_COMMITTER_NAME }}"
  165. git config user.email "${{ env.GIT_COMMITTER_EMAIL }}"
  166. git add .
  167. git commit -m "$COMMIT_MESSAGE"
  168. git push origin master