From f0fc9188d6e9bd11296d919be2a2e551cfcb5c41 Mon Sep 17 00:00:00 2001 From: bjornoleh <63544115+bjornoleh@users.noreply.github.com> Date: Wed, 12 Jul 2023 03:23:01 +0200 Subject: [PATCH] Add scheduled sync and build, and allow for customization of Loop with GitHub Actions / Fastlane builds (#43) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Scheduled sync and build, with option to customize Loop Changed template for scheduled runs to every month Added env variables for - upstream and target repo/branches - sync upstream 'true'/'false' - customize app 'true'/'false' Added sync action (aormsby/Fork-Sync-With-Upstream-action) to the (sync and) build job Added gautamkrishnar/keepalive-workflow to avoid expiration of scheduled workflows due to repository inactivity (60 days max). Adds an empty commit to fork if no activity during the last 27 days. Added Customize Loop action, which - applies any patches located in the LoopWorkspace/patches/ directory (@billybooth) - downloads (wget) and applies submodule patches specified in build_loop.yml Added (commented-out) CustomTypeOne/LoopPatches as templates for Loop and LoopKit submodule patches. * Add ./patches/save_patches_here.md * build_loop.yml: update patch templates for submodules * build_loop.yml: comment out patch template for submodule Loop * build_loop.yml: patch template app name = CustomLoop * Update build_loop.yml: fix typo * Update save_patches_here.md: fix typo * build_loop.yml: delete test_mode * build_loop.yml: remove env CUSTOMIZE_APP * Update build_loop.yml: remove remaining env CUSTOMIZE_APP refs * build_loop.yml: remove '--exclude=' from 'git apply' * Create update.yml - runs on a frequent schedule - checks out LoopWorkspace `main` - compares and syncs with LoopKit/LoopWorkspace (unless owner = LoopKit) - keepalive action adds empty commits to LoopKit/LoopWorkspace `main` after `time_elapsed` days to to avoid inactivation of scheduled workflows, when these updates are passed on to forks (only if owner = LoopKit) - launches build_loop.yml workflow on forks to sync and build if new commits are found (unless owner = LoopKit) * Remove keepalive action from build_loop.yml - keepalive action moved to update.yml * Adapt build_loop.yml and update.yml to be run in an "actions" branch to be set as default, and used to trigger scheduled builds of the main branch. Empty commits are added to an "actions" branch only (must be created by the user and set as default) to keep this branch "alive" and allow scheduled workflows to run uninterrupted (max 60 days of inactivity). The empty commits will not be included in the resulting TestFlight builds of main. Removed conditionals regarding LoopKit repository. * build_loop.yml: Add job names for `secrets` and `upstream_sync_and_build` * update.yml: shorter job name for `check_latest_from_upstream`: Check upstream * build_loop.yml: use curl instead of wget for downloading patches * Changes to build_loop.yml and update.yml: build_loop.yml: -Remove sync action from build_loop.yml -build on schedule on the 1th every month for a predictable build schedule well within the 90 day TestFlight limit. The time of day should be chosen as a time where ongoing changes are unlikely during releases (nighttime). -rename env TARGET_BRANCH to BUILD_BRANCH - use current branch as BUILD_BRANCH for easy switching to building main or dev (manually insert alternative branch names as needed) update.yml: - check for updates every day - use current branch name for UPSTREAM_BRANCH and TARGET_BRANCH, to easily switch between dev and main by changing default branch, without any code changes. - do not run the upstream sync action on the upstream LoopKit repository - time_elapsed: 50 days for keepalive action * Add branch name to run-names - with round brackets around branch name for readability: (${{ github.ref_name }}) * Remove mention of setting TARGET_BRANCH as default, since its not fixed * Move update and keep alive features to build_loop.yml - Checks for updates nightly - Ensures repository activity - Launches Build job if new commits are found, or if run manually - Workflow file cleanup * Delete update.yml * testflight.md: update GH_PAT instructions * Change the Expiration selection to `No expiration`. * Select the `repo` and `workflow` permission scopes. * testflight.md instructions: Create a branch named "alive" * testflight.md: rephrase section on ‘Create a branch named "alive"’ --- .github/workflows/build_loop.yml | 124 ++++++++++++++++++++++++++++--- fastlane/testflight.md | 18 ++++- patches/save_patches_here.md | 1 + 3 files changed, 130 insertions(+), 13 deletions(-) create mode 100644 patches/save_patches_here.md diff --git a/.github/workflows/build_loop.yml b/.github/workflows/build_loop.yml index 77720d477..35516da0b 100644 --- a/.github/workflows/build_loop.yml +++ b/.github/workflows/build_loop.yml @@ -1,34 +1,136 @@ name: 4. Build Loop -run-name: Build Loop ${{ github.ref_name }} +run-name: Build Loop (${{ github.ref_name }}) on: workflow_dispatch: ## Remove the "#" sign from the beginning of the line below to get automated builds on push (code changes in your repository) #push: - ## Remove the "#" sign from the beginning of the two lines below to get automated builds every two months - #schedule: - #- cron: '0 17 1 */2 *' # Runs at 17:00 UTC on the 1st in Jan, Mar, May, Jul, Sep and Nov. + schedule: + - cron: '0 04 * * *' # Checks for updates at 04:00 UTC every day + - cron: '0 04 1 * *' # Builds the app on the 1th every month + +env: + UPSTREAM_REPO: LoopKit/LoopWorkspace + UPSTREAM_BRANCH: ${{ github.ref_name }} # branch on upstream repository to sync from (relpace with specific branch name if needed) + TARGET_BRANCH: ${{ github.ref_name }} # target branch on fork to be kept in sync, and target branch on upstream to be kept alive (relpace with specific branch name if needed) + ALIVE_BRANCH: alive + SYNC_UPSTREAM: 'true' # set to 'false' or 'true' to disable / enable syncing of fork with upstream repository jobs: - secrets: - uses: ./.github/workflows/validate_secrets.yml - secrets: inherit + check_latest_from_upstream: + runs-on: ubuntu-latest + name: Check upstream and keep alive + outputs: + NEW_COMMITS: ${{ steps.sync.outputs.has_new_commits }} + + steps: + - name: Checkout target repo + uses: actions/checkout@v3 + with: + token: ${{ secrets.GH_PAT }} + ref: alive + + - name: Sync upstream changes + if: ${{ env.SYNC_UPSTREAM == 'true' }} && github.repository_owner != 'LoopKit' # do not run the upstream sync action on the upstream repository + id: sync + uses: aormsby/Fork-Sync-With-Upstream-action@v3.4 + with: + target_sync_branch: ${{ env.ALIVE_BRANCH }} + shallow_since: 6 months ago + target_repo_token: ${{ secrets.GH_PAT }} + upstream_sync_branch: ${{ env.UPSTREAM_BRANCH }} + upstream_sync_repo: ${{ env.UPSTREAM_REPO }} + + # Display a sample message based on the sync output var 'has_new_commits' + - name: New commits found + if: steps.sync.outputs.has_new_commits == 'true' + run: echo "New commits were found to sync." + - name: No new commits + if: steps.sync.outputs.has_new_commits == 'false' + run: echo "There were no new commits." + + - name: Show value of 'has_new_commits' + run: | + echo ${{ steps.sync.outputs.has_new_commits }} + echo "NEW_COMMITS=${{ steps.sync.outputs.has_new_commits }}" >> $GITHUB_OUTPUT + + # Keep repository "alive": add empty commits to ALIVE_BRANCH after "time_elapsed" days of inactivity to avoid inactivation of scheduled workflows + - name: Keep alive + uses: gautamkrishnar/keepalive-workflow@v1 # using the workflow with default settings + with: + time_elapsed: 20 # Time elapsed from the previous commit to trigger a new automated commit (in days) + build: - needs: secrets + name: Build + needs: check_latest_from_upstream runs-on: macos-13 + if: ${{ github.event_name == 'workflow_dispatch' || github.event.schedule == '0 04 1 * *' || needs.check_latest_from_upstream.outputs.NEW_COMMITS == 'true' }} # runs if started manually, or if scheduled on the first each month, or if new commits were found steps: - # Uncomment to manually select latest Xcode if needed - - name: Select Latest Xcode + - name: Select Xcode version run: "sudo xcode-select --switch /Applications/Xcode_14.3.1.app/Contents/Developer" - # Checks-out the repo - name: Checkout Repo uses: actions/checkout@v3 with: + token: ${{ secrets.GH_PAT }} submodules: recursive + ref: ${{ env.TARGET_BRANCH }} + + - name: Sync upstream changes + if: ${{ env.SYNC_UPSTREAM == 'true' }} && github.repository_owner != 'LoopKit' # do not run the upstream sync action on the upstream repository + id: sync + uses: aormsby/Fork-Sync-With-Upstream-action@v3.4 + with: + target_sync_branch: ${{ env.TARGET_BRANCH }} + shallow_since: 6 months ago + target_repo_token: ${{ secrets.GH_PAT }} + upstream_sync_branch: ${{ env.UPSTREAM_BRANCH }} + upstream_sync_repo: ${{ env.UPSTREAM_REPO }} + + # Display a sample message based on the sync output var 'has_new_commits' + - name: New commits found + if: steps.sync.outputs.has_new_commits == 'true' + run: echo "New commits were found to sync." + + - name: No new commits + if: steps.sync.outputs.has_new_commits == 'false' + run: echo "There were no new commits." + - name: Show value of 'has_new_commits' + run: | + echo ${{ steps.sync.outputs.has_new_commits }} + echo "NEW_COMMITS=${{ steps.sync.outputs.has_new_commits }}" >> $GITHUB_OUTPUT + + # Customize Loop: Download and apply patches + - name: Customize Loop + run: | + + # LoopWorkspace patches + # -applies any patches located in the LoopWorkspace/patches/ directory + if $(ls ./patches/* &> /dev/null); then + git apply ./patches/* --allow-empty -v --whitespace=fix + fi + + # Submodule Loop patches: + # Template for customizing submodule Loop (changes Loop app name to "CustomLoop") + # Remove the "#" sign from the beginning of the line below to activate: + #curl https://github.com/loopnlearn/Loop/commit/d206432b024279ef710df462b20bd464cd9682d4.patch | git apply --directory=Loop -v --whitespace=fix + + # Submodule LoopKit patches: + # General template for customizing submodule LoopKit + # Copy url from a GitHub commit or pull request and insert below, and remove the "#" sign from the beginning of the line to activate: + #curl url_to_github_commit.patch | git apply --directory=LoopKit -v --whitespace=fix + + # Submodule xxxxx patches: + + # Add patches for customization of additional submodules by following the templates above, + # and make sure to specify the submodule by setting "--directory=(submodule_name)". + # Several patches may be added per submodule. + # Adding comments (#) may be useful to easily tell the individual patches apart. + + # Patch Fastlane Match to not print tables - name: Patch Match Tables run: find /usr/local/lib/ruby/gems -name table_printer.rb | xargs sed -i "" "/puts(Terminal::Table.new(params))/d" diff --git a/fastlane/testflight.md b/fastlane/testflight.md index 2a44847cc..e763353d3 100644 --- a/fastlane/testflight.md +++ b/fastlane/testflight.md @@ -48,8 +48,8 @@ Log into your GitHub account to create a personal access token; this is one of t 1. Create a [new personal access token](https://github.com/settings/tokens/new): * Enter a name for your token, use "FastLane Access Token". - * Change the selection to 90 days. - * Select the `repo` permission scope. + * Change the Expiration selection to `No expiration`. + * Select the `repo` and `workflow` permission scopes. * Click "Generate token". * Copy the token and record it. It will be used below as `GH_PAT`. @@ -159,6 +159,20 @@ You do not need to fill out the next form. That is for submitting to the app sto 1. On the right side, click "Run Workflow", and tap the green `Run workflow` button. 1. Wait, and within a minute or two you should see a green checkmark indicating the workflow succeeded. +## Create a branch named "alive" + +TestFlight builds expire after 90 days. This process you are implementing here will update and rebuild Loop periodically, and requires that you create a branch named "alive" so that GitHub will not inactivate the scheduled rebuild if no code updates are made. + +The "alive" branch will only receive some additional commits to its history, and is not used for building the app. + +1. Go to the "Code" tab of your LoopWorkspace repository. +1. Click the branch selection dropdown button, and then `View all branches`. +1. Click the green "New branch" button (upper right). +1. Type `alive` in the "New branch name" field. +1. Select `LoopKit/LoopWorkspace` as "Source". +1. Select `dev` in the branch dropdown. +1. Click the green "Create new branch" button. + ## Build Loop 1. Click on the "Actions" tab of your LoopWorkspace repository. diff --git a/patches/save_patches_here.md b/patches/save_patches_here.md new file mode 100644 index 000000000..3320e1041 --- /dev/null +++ b/patches/save_patches_here.md @@ -0,0 +1 @@ +LoopWorkspace-level patches can be saved in this directory (LoopWorkspace/patches/)