build_Open-iAPS.yml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. name: 4. Build Open-iAPS
  2. run-name: Build Open-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: nightscout/Open-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 }}/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.GH_PAT }}
  62. run: |
  63. # get ref for nightscout/Open-iAPS:main
  64. response=$(curl --request GET \
  65. --url "https://api.github.com/repos/${{ env.UPSTREAM_REPO }}/git/refs/heads/main" \
  66. --header "Authorization: Bearer $GITHUB_TOKEN" \
  67. --silent)
  68. echo "API Response: $response"
  69. SHA=$(echo "$response" | jq -r '.object.sha')
  70. if [ "$SHA" = "null" ]; then
  71. echo "Error: Unable to retrieve SHA for the main branch."
  72. exit 1
  73. fi
  74. echo "SHA of main branch: $SHA";
  75. # Create alive branch based on nightscout/Open-iAPS:main
  76. gh api \
  77. --method POST \
  78. -H "Authorization: token $GITHUB_TOKEN" \
  79. -H "Accept: application/vnd.github.v3+json" \
  80. /repos/${{ github.repository }}/git/refs \
  81. -f ref='refs/heads/alive' \
  82. -f sha=$SHA
  83. # Checks for changes in upstream repository; if changes exist prompts sync for build
  84. # Performs keepalive to avoid stale fork
  85. check_latest_from_upstream:
  86. needs: [validate, check_alive_and_permissions]
  87. runs-on: ubuntu-latest
  88. name: Check upstream and keep alive
  89. outputs:
  90. NEW_COMMITS: ${{ steps.sync.outputs.has_new_commits }}
  91. steps:
  92. - name: Checkout target repo
  93. if: |
  94. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  95. (vars.SCHEDULED_BUILD != 'false' || vars.SCHEDULED_SYNC != 'false')
  96. uses: actions/checkout@v4
  97. with:
  98. token: ${{ secrets.GH_PAT }}
  99. ref: alive
  100. - name: Sync upstream changes
  101. if: | # do not run the upstream sync action on the upstream repository
  102. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  103. vars.SCHEDULED_SYNC != 'false' && github.repository_owner != 'nightscout'
  104. id: sync
  105. uses: aormsby/Fork-Sync-With-Upstream-action@v3.4.1
  106. with:
  107. target_sync_branch: ${{ env.ALIVE_BRANCH }}
  108. shallow_since: 6 months ago
  109. target_repo_token: ${{ secrets.GH_PAT }}
  110. upstream_sync_branch: ${{ env.UPSTREAM_BRANCH }}
  111. upstream_sync_repo: ${{ env.UPSTREAM_REPO }}
  112. # Display a sample message based on the sync output var 'has_new_commits'
  113. - name: New commits found
  114. if: |
  115. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  116. vars.SCHEDULED_SYNC != 'false' && steps.sync.outputs.has_new_commits == 'true'
  117. run: echo "New commits were found to sync."
  118. - name: No new commits
  119. if: |
  120. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  121. vars.SCHEDULED_SYNC != 'false' && steps.sync.outputs.has_new_commits == 'false'
  122. run: echo "There were no new commits."
  123. - name: Show value of 'has_new_commits'
  124. if: needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' && vars.SCHEDULED_SYNC != 'false'
  125. run: |
  126. echo ${{ steps.sync.outputs.has_new_commits }}
  127. echo "NEW_COMMITS=${{ steps.sync.outputs.has_new_commits }}" >> $GITHUB_OUTPUT
  128. # Keep repository "alive": add empty commits to ALIVE_BRANCH after "time_elapsed" days of inactivity to avoid inactivation of scheduled workflows
  129. - name: Keep alive
  130. if: |
  131. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  132. (vars.SCHEDULED_BUILD != 'false' || vars.SCHEDULED_SYNC != 'false')
  133. uses: gautamkrishnar/keepalive-workflow@v1 # using the workflow with default settings
  134. with:
  135. time_elapsed: 20 # Time elapsed from the previous commit to trigger a new automated commit (in days)
  136. - name: Show scheduled build configuration message
  137. if: needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION != 'true'
  138. run: |
  139. echo "### :calendar: Scheduled Sync and Build Disabled :mobile_phone_off:" >> $GITHUB_STEP_SUMMARY
  140. echo "You have not yet configured the scheduled sync and build for Open-iAPS's browser build." >> $GITHUB_STEP_SUMMARY
  141. echo "Synchronizing your fork of <code>Open-iAPS</code> with the upstream repository <code>nightscout/Open-iAPS</code> will be skipped." >> $GITHUB_STEP_SUMMARY
  142. echo "If you want to enable automatic builds and updates for your Open-iAPS, please follow the instructions \
  143. under the following path <code>Open-iAPS/fastlane/testflight.md</code>." >> $GITHUB_STEP_SUMMARY
  144. # Builds Open-iAPS
  145. build:
  146. name: Build
  147. needs: [validate, check_alive_and_permissions, check_latest_from_upstream]
  148. runs-on: macos-13
  149. permissions:
  150. contents: write
  151. 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
  152. github.event_name == 'workflow_dispatch' ||
  153. (needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  154. (vars.SCHEDULED_BUILD != 'false' && github.event.schedule == '0 6 1 * *') ||
  155. (vars.SCHEDULED_SYNC != 'false' && needs.check_latest_from_upstream.outputs.NEW_COMMITS == 'true' )
  156. )
  157. steps:
  158. # Uncomment to manually select Xcode version if needed
  159. #- name: Select Xcode version
  160. # run: "sudo xcode-select --switch /Applications/Xcode_15.0.1.app/Contents/Developer"
  161. - name: Checkout Repo for syncing
  162. if: |
  163. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  164. vars.SCHEDULED_SYNC != 'false'
  165. uses: actions/checkout@v4
  166. with:
  167. token: ${{ secrets.GH_PAT }}
  168. ref: ${{ env.TARGET_BRANCH }}
  169. - name: Sync upstream changes
  170. if: | # do not run the upstream sync action on the upstream repository
  171. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  172. vars.SCHEDULED_SYNC != 'false' && github.repository_owner != 'nightscout'
  173. id: sync
  174. uses: aormsby/Fork-Sync-With-Upstream-action@v3.4.1
  175. with:
  176. target_sync_branch: ${{ env.TARGET_BRANCH }}
  177. shallow_since: 6 months ago
  178. target_repo_token: ${{ secrets.GH_PAT }}
  179. upstream_sync_branch: ${{ env.UPSTREAM_BRANCH }}
  180. upstream_sync_repo: ${{ env.UPSTREAM_REPO }}
  181. # Display a sample message based on the sync output var 'has_new_commits'
  182. - name: New commits found
  183. if: |
  184. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  185. vars.SCHEDULED_SYNC != 'false' && steps.sync.outputs.has_new_commits == 'true'
  186. run: echo "New commits were found to sync."
  187. - name: No new commits
  188. if: |
  189. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
  190. vars.SCHEDULED_SYNC != 'false' && steps.sync.outputs.has_new_commits == 'false'
  191. run: echo "There were no new commits."
  192. - name: Show value of 'has_new_commits'
  193. if: |
  194. needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true'
  195. && vars.SCHEDULED_SYNC != 'false'
  196. run: |
  197. echo ${{ steps.sync.outputs.has_new_commits }}
  198. echo "NEW_COMMITS=${{ steps.sync.outputs.has_new_commits }}" >> $GITHUB_OUTPUT
  199. - name: Checkout Repo for building
  200. uses: actions/checkout@v4
  201. with:
  202. token: ${{ secrets.GH_PAT }}
  203. submodules: recursive
  204. ref: ${{ env.TARGET_BRANCH }}
  205. # Patch Fastlane Match to not print tables
  206. - name: Patch Match Tables
  207. run: find /usr/local/lib/ruby/gems -name table_printer.rb | xargs sed -i "" "/puts(Terminal::Table.new(params))/d"
  208. # Install project dependencies
  209. - name: Install project dependencies
  210. run: bundle install
  211. # Build signed Open-iAPS IPA file
  212. - name: Fastlane Build & Archive
  213. run: bundle exec fastlane build_open_iaps
  214. env:
  215. TEAMID: ${{ secrets.TEAMID }}
  216. GH_PAT: ${{ secrets.GH_PAT }}
  217. FASTLANE_KEY_ID: ${{ secrets.FASTLANE_KEY_ID }}
  218. FASTLANE_ISSUER_ID: ${{ secrets.FASTLANE_ISSUER_ID }}
  219. FASTLANE_KEY: ${{ secrets.FASTLANE_KEY }}
  220. MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
  221. # Upload to TestFlight
  222. - name: Fastlane upload to TestFlight
  223. run: bundle exec fastlane release
  224. env:
  225. TEAMID: ${{ secrets.TEAMID }}
  226. GH_PAT: ${{ secrets.GH_PAT }}
  227. FASTLANE_KEY_ID: ${{ secrets.FASTLANE_KEY_ID }}
  228. FASTLANE_ISSUER_ID: ${{ secrets.FASTLANE_ISSUER_ID }}
  229. FASTLANE_KEY: ${{ secrets.FASTLANE_KEY }}
  230. MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
  231. # Upload Build artifacts
  232. - name: Upload build log, IPA and Symbol artifacts
  233. if: always()
  234. uses: actions/upload-artifact@v3
  235. with:
  236. name: build-artifacts
  237. path: |
  238. artifacts
  239. buildlog