build_iAPS.yml 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. name: 4. Build iAPS
  2. run-name: Build iAPS (${{ github.ref_name }})
  3. on:
  4. workflow_dispatch:
  5. ## Remove the "#" sign from the beginning of the line below to get automated builds on push (code changes in your repository)
  6. #push:
  7. schedule:
  8. #- cron: '30 04 1 * *' # Runs at 04:30 UTC on the 1st every month
  9. - cron: '0 8 * * 3' # Checks for updates at 08:00 UTC every Wednesday
  10. - cron: '0 6 1 * *' # Builds the app on the 1st of every month at 06:00 UTC
  11. env:
  12. UPSTREAM_REPO: Artificial-Pancreas/iAPS
  13. UPSTREAM_BRANCH: ${{ github.ref_name }} # branch on upstream repository to sync from (replace with specific branch name if needed)
  14. TARGET_BRANCH: ${{ github.ref_name }} # target branch on fork to be kept in sync, and target branch on upstream to be kept alive (replace with specific branch name if needed)
  15. ALIVE_BRANCH: alive
  16. jobs:
  17. validate:
  18. name: Validate
  19. uses: ./.github/workflows/validate_secrets.yml
  20. secrets: inherit
  21. # Checks if GH_PAT holds workflow permissions
  22. # Checks for existence of alive branch; if non-existent creates it
  23. check_alive_and_permissions:
  24. needs: validate
  25. runs-on: ubuntu-latest
  26. name: Check alive branch and permissions
  27. permissions:
  28. contents: write
  29. outputs:
  30. WORKFLOW_PERMISSION: ${{ steps.workflow-permission.outputs.has_permission }}
  31. steps:
  32. - name: Check for workflow permissions
  33. id: workflow-permission
  34. env:
  35. TOKEN_TO_CHECK: ${{ secrets.GH_PAT }}
  36. run: |
  37. PERMISSIONS=$(curl -sS -f -I -H "Authorization: token ${{ env.TOKEN_TO_CHECK }}" https://api.github.com | grep ^x-oauth-scopes: | cut -d' ' -f2-);
  38. if [[ $PERMISSIONS =~ "workflow" || $PERMISSIONS == "" ]]; then
  39. echo "GH_PAT holds workflow permissions or is fine-grained PAT."
  40. echo "has_permission=true" >> $GITHUB_OUTPUT # Set WORKFLOW_PERMISSION to false.
  41. else
  42. echo "GH_PAT lacks workflow permissions."
  43. echo "Automated build features will be skipped!"
  44. echo "has_permission=false" >> $GITHUB_OUTPUT # Set WORKFLOW_PERMISSION to false.
  45. fi
  46. - name: Check for alive branch
  47. if: steps.workflow-permission.outputs.has_permission == 'true'
  48. env:
  49. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  50. run: |
  51. if [[ "$(gh api -H "Accept: application/vnd.github+json" /repos/${{ github.repository_owner }}/iAPS/branches | jq --raw-output 'any(.name=="alive")')" == "true" ]]; then
  52. echo "Branch 'alive' exists."
  53. echo "ALIVE_BRANCH_EXISTS=true" >> $GITHUB_ENV # Set ALIVE_BRANCH_EXISTS to true
  54. else
  55. echo "Branch 'alive' does not exist."
  56. echo "ALIVE_BRANCH_EXISTS=false" >> $GITHUB_ENV # Set ALIVE_BRANCH_EXISTS to false
  57. fi
  58. - name: Create alive branch
  59. if: env.ALIVE_BRANCH_EXISTS == 'false'
  60. env:
  61. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  62. run: |
  63. # Get ref for Artificial-Pancreas/iAPS:dev
  64. SHA=$(curl -sS https://api.github.com/repos/${{ env.UPSTREAM_REPO }}/git/refs \
  65. | jq '.[] | select(.ref == "refs/heads/dev" ) | .object.sha' \
  66. | tr -d '"'
  67. );
  68. # Create alive branch based on Artificial-Pancreas/iAPS:dev
  69. gh api \
  70. --method POST \
  71. -H "Authorization: token $GITHUB_TOKEN" \
  72. -H "Accept: application/vnd.github.v3+json" \
  73. /repos/${{ github.repository_owner }}/iAPS/git/refs \
  74. -f ref='refs/heads/alive' \
  75. -f sha=$SHA
  76. # Checks for changes in upstream repository; if changes exist prompts sync for build
  77. # Performs keepalive to avoid stale fork
  78. check_latest_from_upstream:
  79. needs: [validate, check_alive_and_permissions]
  80. runs-on: ubuntu-latest
  81. name: Check upstream and keep alive
  82. outputs:
  83. NEW_COMMITS: ${{ steps.sync.outputs.has_new_commits }}
  84. steps:
  85. - name: Checkout target repo
  86. if: |
  87. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  88. (vars.SCHEDULED_BUILD != 'false' || vars.SCHEDULED_SYNC != 'false')
  89. uses: actions/checkout@v4
  90. with:
  91. token: ${{ secrets.GH_PAT }}
  92. ref: alive
  93. - name: Sync upstream changes
  94. if: | # do not run the upstream sync action on the upstream repository
  95. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  96. vars.SCHEDULED_SYNC != 'false' && github.repository_owner != 'Artificial-Pancreas'
  97. id: sync
  98. uses: aormsby/Fork-Sync-With-Upstream-action@v3.4.1
  99. with:
  100. target_sync_branch: ${{ env.ALIVE_BRANCH }}
  101. shallow_since: 6 months ago
  102. target_repo_token: ${{ secrets.GH_PAT }}
  103. upstream_sync_branch: ${{ env.UPSTREAM_BRANCH }}
  104. upstream_sync_repo: ${{ env.UPSTREAM_REPO }}
  105. # Display a sample message based on the sync output var 'has_new_commits'
  106. - name: New commits found
  107. if: |
  108. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  109. vars.SCHEDULED_SYNC != 'false' && steps.sync.outputs.has_new_commits == 'true'
  110. run: echo "New commits were found to sync."
  111. - name: No new commits
  112. if: |
  113. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  114. vars.SCHEDULED_SYNC != 'false' && steps.sync.outputs.has_new_commits == 'false'
  115. run: echo "There were no new commits."
  116. - name: Show value of 'has_new_commits'
  117. if: needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' && vars.SCHEDULED_SYNC != 'false'
  118. run: |
  119. echo ${{ steps.sync.outputs.has_new_commits }}
  120. echo "NEW_COMMITS=${{ steps.sync.outputs.has_new_commits }}" >> $GITHUB_OUTPUT
  121. # Keep repository "alive": add empty commits to ALIVE_BRANCH after "time_elapsed" days of inactivity to avoid inactivation of scheduled workflows
  122. - name: Keep alive
  123. if: |
  124. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  125. (vars.SCHEDULED_BUILD != 'false' || vars.SCHEDULED_SYNC != 'false')
  126. uses: gautamkrishnar/keepalive-workflow@v1 # using the workflow with default settings
  127. with:
  128. time_elapsed: 20 # Time elapsed from the previous commit to trigger a new automated commit (in days)
  129. - name: Show scheduled build configuration message
  130. if: needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION != 'true'
  131. run: |
  132. echo "### :calendar: Scheduled Sync and Build Disabled :mobile_phone_off:" >> $GITHUB_STEP_SUMMARY
  133. echo "You have not yet configured the scheduled sync and build for iAPS's browser build." >> $GITHUB_STEP_SUMMARY
  134. echo "Synchronizing your fork of <code>iAPS</code> with the upstream repository <code>Artificial-Pancreas/iAPS</code> will be skipped." >> $GITHUB_STEP_SUMMARY
  135. echo "If you want to enable automatic builds and updates for your iAPS, please follow the instructions \
  136. under the following path <code>iAPS/fastlane/testflight.md</code>." >> $GITHUB_STEP_SUMMARY
  137. # Builds iAPS
  138. build:
  139. name: Build
  140. needs: [validate, check_alive_and_permissions, check_latest_from_upstream]
  141. runs-on: macos-13
  142. permissions:
  143. contents: write
  144. if: | # runs if started manually, or if sync schedule is set and enabled and scheduled on the first Saturday each month, or if sync schedule is set and enabled and new commits were found
  145. github.event_name == 'workflow_dispatch' ||
  146. (needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  147. (vars.SCHEDULED_BUILD != 'false' && github.event.schedule == '0 6 1 * *') ||
  148. (vars.SCHEDULED_SYNC != 'false' && needs.check_latest_from_upstream.outputs.NEW_COMMITS == 'true' )
  149. )
  150. steps:
  151. # Uncomment to manually select Xcode version if needed
  152. #- name: Select Xcode version
  153. # run: "sudo xcode-select --switch /Applications/Xcode_15.0.1.app/Contents/Developer"
  154. - name: Checkout Repo for syncing
  155. if: |
  156. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  157. vars.SCHEDULED_SYNC != 'false'
  158. uses: actions/checkout@v4
  159. with:
  160. token: ${{ secrets.GH_PAT }}
  161. ref: ${{ env.TARGET_BRANCH }}
  162. - name: Sync upstream changes
  163. if: | # do not run the upstream sync action on the upstream repository
  164. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  165. vars.SCHEDULED_SYNC != 'false' && github.repository_owner != 'Artificial-Pancreas'
  166. id: sync
  167. uses: aormsby/Fork-Sync-With-Upstream-action@v3.4.1
  168. with:
  169. target_sync_branch: ${{ env.TARGET_BRANCH }}
  170. shallow_since: 6 months ago
  171. target_repo_token: ${{ secrets.GH_PAT }}
  172. upstream_sync_branch: ${{ env.UPSTREAM_BRANCH }}
  173. upstream_sync_repo: ${{ env.UPSTREAM_REPO }}
  174. # Display a sample message based on the sync output var 'has_new_commits'
  175. - name: New commits found
  176. if: |
  177. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  178. vars.SCHEDULED_SYNC != 'false' && steps.sync.outputs.has_new_commits == 'true'
  179. run: echo "New commits were found to sync."
  180. - name: No new commits
  181. if: |
  182. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  183. vars.SCHEDULED_SYNC != 'false' && steps.sync.outputs.has_new_commits == 'false'
  184. run: echo "There were no new commits."
  185. - name: Show value of 'has_new_commits'
  186. if: |
  187. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true'
  188. && vars.SCHEDULED_SYNC != 'false'
  189. run: |
  190. echo ${{ steps.sync.outputs.has_new_commits }}
  191. echo "NEW_COMMITS=${{ steps.sync.outputs.has_new_commits }}" >> $GITHUB_OUTPUT
  192. - name: Checkout Repo for building
  193. uses: actions/checkout@v4
  194. with:
  195. token: ${{ secrets.GH_PAT }}
  196. submodules: recursive
  197. ref: ${{ env.TARGET_BRANCH }}
  198. # Patch Fastlane Match to not print tables
  199. - name: Patch Match Tables
  200. run: find /usr/local/lib/ruby/gems -name table_printer.rb | xargs sed -i "" "/puts(Terminal::Table.new(params))/d"
  201. # Install project dependencies
  202. - name: Install project dependencies
  203. run: bundle install
  204. # Build signed iAPS IPA file
  205. - name: Fastlane Build & Archive
  206. run: bundle exec fastlane build_iAPS
  207. env:
  208. TEAMID: ${{ secrets.TEAMID }}
  209. GH_PAT: ${{ secrets.GH_PAT }}
  210. FASTLANE_KEY_ID: ${{ secrets.FASTLANE_KEY_ID }}
  211. FASTLANE_ISSUER_ID: ${{ secrets.FASTLANE_ISSUER_ID }}
  212. FASTLANE_KEY: ${{ secrets.FASTLANE_KEY }}
  213. MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
  214. # Upload to TestFlight
  215. - name: Fastlane upload to TestFlight
  216. run: bundle exec fastlane release
  217. env:
  218. TEAMID: ${{ secrets.TEAMID }}
  219. GH_PAT: ${{ secrets.GH_PAT }}
  220. FASTLANE_KEY_ID: ${{ secrets.FASTLANE_KEY_ID }}
  221. FASTLANE_ISSUER_ID: ${{ secrets.FASTLANE_ISSUER_ID }}
  222. FASTLANE_KEY: ${{ secrets.FASTLANE_KEY }}
  223. MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
  224. # Upload Build artifacts
  225. - name: Upload build log, IPA and Symbol artifacts
  226. if: always()
  227. uses: actions/upload-artifact@v3
  228. with:
  229. name: build-artifacts
  230. path: |
  231. artifacts
  232. buildlog