Skip to content

Build Trio (main)

Build Trio (main) #122

Workflow file for this run

name: 4. Build Trio
run-name: Build Trio (${{ 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:
schedule:
- cron: "0 8 * * 3" # Checks for updates at 08:00 UTC every Wednesday
- cron: "0 6 1 * *" # Builds the app on the 1st of every month at 06:00 UTC
env:
UPSTREAM_REPO: nightscout/Trio
UPSTREAM_BRANCH: ${{ github.ref_name }} # branch on upstream repository to sync from (replace 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 (replace with specific branch name if needed)
ALIVE_BRANCH_MAIN: alive-main
ALIVE_BRANCH_DEV: alive-dev
jobs:
# Checks if Distribution certificate is present and valid, optionally nukes and
# creates new certs if the repository variable ENABLE_NUKE_CERTS == 'true'
check_certs:
name: Check certificates
uses: ./.github/workflows/create_certs.yml
secrets: inherit
# Checks if GH_PAT holds workflow permissions
# Checks for existence of alive branch; if non-existent creates it
check_alive_and_permissions:
needs: check_certs
runs-on: ubuntu-latest
name: Check alive branch and permissions
permissions:
contents: write
outputs:
WORKFLOW_PERMISSION: ${{ steps.workflow-permission.outputs.has_permission }}
steps:
- name: Check for workflow permissions
id: workflow-permission
env:
TOKEN_TO_CHECK: ${{ secrets.GH_PAT }}
run: |
PERMISSIONS=$(curl -sS -f -I -H "Authorization: token ${{ env.TOKEN_TO_CHECK }}" https://api.github.com | grep ^x-oauth-scopes: | cut -d' ' -f2-);
if [[ $PERMISSIONS =~ "workflow" || $PERMISSIONS == "" ]]; then
echo "GH_PAT holds workflow permissions or is fine-grained PAT."
echo "has_permission=true" >> $GITHUB_OUTPUT # Set WORKFLOW_PERMISSION to false.
else
echo "GH_PAT lacks workflow permissions."
echo "Automated build features will be skipped!"
echo "has_permission=false" >> $GITHUB_OUTPUT # Set WORKFLOW_PERMISSION to false.
fi
- name: Check for alive branches
if: steps.workflow-permission.outputs.has_permission == 'true'
id: check-alive
env:
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
run: |
branch_list=$(gh api -H "Accept: application/vnd.github+json" /repos/${{ github.repository_owner }}/Trio/branches | jq -r '.[].name')
if echo "$branch_list" | grep -q '^alive-main$'; then
echo "alive-main exists"
echo "ALIVE_MAIN_EXISTS=true" >> $GITHUB_ENV
else
echo "alive-main missing"
echo "ALIVE_MAIN_EXISTS=false" >> $GITHUB_ENV
fi
if echo "$branch_list" | grep -q '^alive-dev$'; then
echo "alive-dev exists"
echo "ALIVE_DEV_EXISTS=true" >> $GITHUB_ENV
else
echo "alive-dev missing"
echo "ALIVE_DEV_EXISTS=false" >> $GITHUB_ENV
fi
- name: Create alive-main branch if missing
if: env.ALIVE_MAIN_EXISTS == 'false'
env:
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
run: |
SHA_MAIN=$(curl -sS -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/repos/${{ env.UPSTREAM_REPO }}/git/refs/heads/main | jq -r '.object.sha')
echo "Creating alive-main from upstream main"
gh api \
--method POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
/repos/${{ github.repository_owner }}/Trio/git/refs \
-f ref='refs/heads/alive-main' \
-f sha=$SHA_MAIN
- name: Create alive-dev branch if missing
if: env.ALIVE_DEV_EXISTS == 'false'
env:
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
run: |
SHA_DEV=$(curl -sS -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/repos/${{ env.UPSTREAM_REPO }}/git/refs/heads/dev | jq -r '.object.sha')
echo "Creating alive-dev from upstream dev"
gh api \
--method POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
/repos/${{ github.repository_owner }}/Trio/git/refs \
-f ref='refs/heads/alive-dev' \
-f sha=$SHA_DEV
# Checks for changes in upstream repository; if changes exist prompts sync for build
# Performs keepalive to avoid stale fork
check_latest_from_upstream:
needs: [check_certs, check_alive_and_permissions]
runs-on: ubuntu-latest
name: Check upstream and keep alive
outputs:
NEW_COMMITS: ${{ steps.sync.outputs.has_new_commits }}
ABORT_SYNC: ${{ steps.check_branch.outputs.ABORT_SYNC }}
steps:
- name: Check if running on main or dev branch
if: |
needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
(vars.SCHEDULED_BUILD != 'false' || vars.SCHEDULED_SYNC != 'false')
id: check_branch
run: |
if [ "${GITHUB_REF##*/}" = "main" ]; then
echo "Running on main branch"
echo "ALIVE_BRANCH=${ALIVE_BRANCH_MAIN}" >> $GITHUB_OUTPUT
echo "ABORT_SYNC=false" >> $GITHUB_OUTPUT
elif [ "${GITHUB_REF##*/}" = "dev" ]; then
echo "Running on dev branch"
echo "ALIVE_BRANCH=${ALIVE_BRANCH_DEV}" >> $GITHUB_OUTPUT
echo "ABORT_SYNC=false" >> $GITHUB_OUTPUT
else
echo "Not running on main or dev branch"
echo "ABORT_SYNC=true" >> $GITHUB_OUTPUT
fi
- name: Checkout target repo
if: |
needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
(vars.SCHEDULED_BUILD != 'false' || vars.SCHEDULED_SYNC != 'false')
uses: actions/checkout@v4
with:
token: ${{ secrets.GH_PAT }}
ref: ${{ steps.check_branch.outputs.ALIVE_BRANCH }}
- name: Sync upstream changes
if: | # do not run the upstream sync action on the upstream repository
needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
vars.SCHEDULED_SYNC != 'false' && github.repository_owner != 'nightscout' && steps.check_branch.outputs.ABORT_SYNC == 'false'
id: sync
uses: aormsby/[email protected]
with:
target_sync_branch: ${{ steps.check_branch.outputs.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: |
needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
vars.SCHEDULED_SYNC != 'false' && steps.sync.outputs.has_new_commits == 'true'
run: echo "New commits were found to sync."
- name: No new commits
if: |
needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
vars.SCHEDULED_SYNC != 'false' && steps.sync.outputs.has_new_commits == 'false'
run: echo "There were no new commits."
- name: Show value of 'has_new_commits'
if: needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' && vars.SCHEDULED_SYNC != 'false' && steps.check_branch.outputs.ABORT_SYNC == 'false'
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
run: |
echo "Keep Alive temporarily removed while gautamkrishnar/keepalive-workflow is not available"
# if: |
# needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
# (vars.SCHEDULED_BUILD != 'false' || vars.SCHEDULED_SYNC != 'false')
# 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)
- name: Show scheduled build configuration message
if: needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION != 'true'
run: |
echo "### :calendar: Scheduled Sync and Build Disabled :mobile_phone_off:" >> $GITHUB_STEP_SUMMARY
echo "You have not yet configured the scheduled sync and build for Trio's browser build." >> $GITHUB_STEP_SUMMARY
echo "Synchronizing your fork of <code>Trio</code> with the upstream repository <code>nightscout/Trio</code> will be skipped." >> $GITHUB_STEP_SUMMARY
echo "If you want to enable automatic builds and updates for your Trio, please follow the instructions \
under the following path <code>Trio/fastlane/testflight.md</code>." >> $GITHUB_STEP_SUMMARY
# Builds Trio
build:
name: Build
needs: [check_certs, check_alive_and_permissions, check_latest_from_upstream]
runs-on: macos-15
permissions:
contents: write
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
github.event_name == 'workflow_dispatch' ||
(needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
(vars.SCHEDULED_BUILD != 'false' && github.event.schedule == '0 6 1 * *') ||
(vars.SCHEDULED_SYNC != 'false' && needs.check_latest_from_upstream.outputs.NEW_COMMITS == 'true' )
)
steps:
- name: Select Xcode version
run: "sudo xcode-select --switch /Applications/Xcode_16.3.app/Contents/Developer"
- name: Checkout Repo for syncing
if: |
needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
vars.SCHEDULED_SYNC != 'false'
uses: actions/checkout@v4
with:
token: ${{ secrets.GH_PAT }}
ref: ${{ env.TARGET_BRANCH }}
- name: Sync upstream changes
if: | # do not run the upstream sync action on the upstream repository
needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
vars.SCHEDULED_SYNC != 'false' && github.repository_owner != 'nightscout' && needs.check_latest_from_upstream.outputs.ABORT_SYNC == 'false'
id: sync
uses: aormsby/[email protected]
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: |
needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
vars.SCHEDULED_SYNC != 'false' && steps.sync.outputs.has_new_commits == 'true' && needs.check_latest_from_upstream.outputs.ABORT_SYNC == 'false'
run: echo "New commits were found to sync."
- name: No new commits
if: |
needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true' &&
vars.SCHEDULED_SYNC != 'false' && steps.sync.outputs.has_new_commits == 'false' && needs.check_latest_from_upstream.outputs.ABORT_SYNC == 'false'
run: echo "There were no new commits."
- name: Show value of 'has_new_commits'
if: |
needs.check_alive_and_permissions.outputs.WORKFLOW_PERMISSION == 'true'
&& vars.SCHEDULED_SYNC != 'false' && needs.check_latest_from_upstream.outputs.ABORT_SYNC == 'false'
run: |
echo ${{ steps.sync.outputs.has_new_commits }}
echo "NEW_COMMITS=${{ steps.sync.outputs.has_new_commits }}" >> $GITHUB_OUTPUT
- name: Checkout Repo for building
uses: actions/checkout@v4
with:
token: ${{ secrets.GH_PAT }}
submodules: recursive
ref: ${{ env.TARGET_BRANCH }}
# Customize Trio: Use patches or download and apply patches from GitHub
- name: Customize Trio
run: |
# Trio workspace patches
# -applies any patches located in the Trio/patches/ directory
if $(ls ./patches/* &> /dev/null); then
git apply ./patches/* --allow-empty -v --whitespace=fix
fi
# Download and apply Trio patches from GitHub:
# Template for customizing Trio code (as opposed to submodule code)
# Remove the "#" sign from the beginning of the line below to activate
# and then replace the alphanumeric string with your SHA, this SHA is NOT valid
#curl https://github.com/nightscout/Trio/commit/d206432b024279ef710df462b20bd464cd9682d4.patch | git apply -v --whitespace=fix
# Download and apply Submodule patches from GitHub:
# Template for customizing submodules (you must edit the submodule name)
# This example is for G7SensorKit showing you can apply multiple commits, in the proper order
# Remove the "#" sign from the beginning of the lines below to activate
# This example applies 3 commits from the scan-fix folder; valid only when these are not already in Trio
#curl https://github.com/loopandlearn/G7SensorKit/commit/ba44beb3d1491c453f4f438443c3f8ba29146ab3.patch | git apply --directory=G7SensorKit -v --whitespace=fix
#curl https://github.com/loopandlearn/G7SensorKit/commit/d86ac8e9cd523d1267587dd70c96597125eef7ab.patch | git apply --directory=G7SensorKit -v --whitespace=fix
#curl https://github.com/loopandlearn/G7SensorKit/commit/205054e7537723c2aec58d807634b4853f687244.patch | git apply --directory=G7SensorKit -v --whitespace=fix
# Add patches for additional customization 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 (#) is strongly recommended to easily tell the individual patches apart.
# Patch Fastlane Match to not print tables
- name: Patch Match Tables
run: |
TABLE_PRINTER_PATH=$(ruby -e 'puts Gem::Specification.find_by_name("fastlane").gem_dir')/match/lib/match/table_printer.rb
if [ -f "$TABLE_PRINTER_PATH" ]; then
sed -i "" "/puts(Terminal::Table.new(params))/d" "$TABLE_PRINTER_PATH"
else
echo "table_printer.rb not found"
exit 1
fi
# Install project dependencies
- name: Install Project Dependencies
run: bundle install
# Sync the GitHub runner clock with the Windows time server (workaround as suggested in https://github.com/actions/runner/issues/2996)
- name: Sync clock
run: sudo sntp -sS time.windows.com
# Build signed Trio IPA file
- name: Fastlane Build & Archive
run: bundle exec fastlane build_trio
env:
TEAMID: ${{ secrets.TEAMID }}
GH_PAT: ${{ secrets.GH_PAT }}
FASTLANE_KEY_ID: ${{ secrets.FASTLANE_KEY_ID }}
FASTLANE_ISSUER_ID: ${{ secrets.FASTLANE_ISSUER_ID }}
FASTLANE_KEY: ${{ secrets.FASTLANE_KEY }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
# Upload to TestFlight
- name: Fastlane upload to TestFlight
run: bundle exec fastlane release
env:
TEAMID: ${{ secrets.TEAMID }}
GH_PAT: ${{ secrets.GH_PAT }}
FASTLANE_KEY_ID: ${{ secrets.FASTLANE_KEY_ID }}
FASTLANE_ISSUER_ID: ${{ secrets.FASTLANE_ISSUER_ID }}
FASTLANE_KEY: ${{ secrets.FASTLANE_KEY }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
# Upload Build artifacts
- name: Upload build log, IPA and Symbol artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: |
artifacts
buildlog