From 7c26eb9a241a11087c51a1d6dfa34dd66c56c8b1 Mon Sep 17 00:00:00 2001
From: Adrian Castro <22133246+castdrian@users.noreply.github.com>
Date: Sat, 1 Aug 2026 23:43:07 +0200
Subject: [PATCH 1/8] ci(ios): gate hosted build on iOS changes
---
.github/workflows/ci.yml | 38 ++++++++++++++++++++++++++++++++++++--
1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 37e30ec4..ab2444c9 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,8 +10,6 @@ name: ci
# The T3 content tier asserts Pokemon Red facts; scripts/test.sh detects
# data/generated/ is absent and skips it rather than failing.
#
-# Runs alongside release.yml, which is untouched by this file.
-
on:
push:
# Integration branch + release branch. PRs already run via pull_request
@@ -25,6 +23,42 @@ concurrency:
cancel-in-progress: true
jobs:
+ ios-changes:
+ name: detect iOS changes
+ runs-on: ubuntu-latest
+ outputs:
+ changed: ${{ steps.paths.outputs.changed }}
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - id: paths
+ env:
+ BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
+ HEAD_SHA: ${{ github.sha }}
+ run: |
+ if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then
+ echo "changed=true" >> "$GITHUB_OUTPUT"
+ exit 0
+ fi
+ if git diff --name-only "$BASE_SHA" "$HEAD_SHA" | grep -Eq '^(mobile/ios/|scripts/build_ios\.sh$|\.github/workflows/(ci|release)\.yml$)'; then
+ echo "changed=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "changed=false" >> "$GITHUB_OUTPUT"
+ fi
+
+ ios-build:
+ name: iOS build
+ needs: ios-changes
+ if: needs.ios-changes.outputs.changed == 'true'
+ runs-on: macos-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: install xcbeautify
+ run: brew list xcbeautify >/dev/null 2>&1 || brew install xcbeautify
+ - name: build iOS simulator app
+ run: scripts/build_ios.sh --fetch --release
+
headless:
name: headless suites (no ROM)
runs-on: ubuntu-latest
From 5f89def2ceb4dbcbc76b2637e4702f001a27c308 Mon Sep 17 00:00:00 2001
From: Adrian Castro <22133246+castdrian@users.noreply.github.com>
Date: Sat, 1 Aug 2026 23:43:08 +0200
Subject: [PATCH 2/8] ci: select hosted runners for forks
---
.github/workflows/ci.yml | 2 +-
.github/workflows/release.yml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ab2444c9..de8fad26 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -51,7 +51,7 @@ jobs:
name: iOS build
needs: ios-changes
if: needs.ios-changes.outputs.changed == 'true'
- runs-on: macos-latest
+ runs-on: ${{ fromJSON(github.repository == 'bryanthaboi/gen1recomp' && '["self-hosted", "macOS"]' || '"macos-latest"') }}
steps:
- uses: actions/checkout@v4
- name: install xcbeautify
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 5ca8c37e..fb1b313f 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -42,7 +42,7 @@ concurrency:
jobs:
release:
- runs-on: [self-hosted, macOS]
+ runs-on: ${{ fromJSON(github.repository == 'bryanthaboi/gen1recomp' && '["self-hosted", "macOS"]' || '"macos-latest"') }}
steps:
# The self-hosted runner lives under the machine owner's home
From 5f75cfd691628567698f91cf5b5a28e31b199815 Mon Sep 17 00:00:00 2001
From: Adrian Castro <22133246+castdrian@users.noreply.github.com>
Date: Sat, 1 Aug 2026 23:43:11 +0200
Subject: [PATCH 3/8] ci: verify release builds on fork runners
---
.github/workflows/release.yml | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index fb1b313f..efddc626 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -127,6 +127,7 @@ jobs:
echo "tag=$tag" >> "$GITHUB_OUTPUT"
- name: Import signing certificate into a temporary keychain
+ if: github.repository == 'bryanthaboi/gen1recomp'
run: |
set -euo pipefail
KEYCHAIN_PATH="$RUNNER_TEMP/pokemon-signing.keychain-db"
@@ -182,13 +183,17 @@ jobs:
brew list xcbeautify >/dev/null 2>&1 || brew install xcbeautify
- name: Build iOS
+ env:
+ CANONICAL_REPOSITORY: ${{ github.repository == 'bryanthaboi/gen1recomp' }}
run: |
set -euo pipefail
- # Device Release IPA; signs with the Apple Development identity on
- # the runner (auto team detection). Users on other Apple IDs still
- # re-sign or build via docs/ios-install.md.
- scripts/build_ios.sh --fetch --device --release \
- --version "${{ steps.ver.outputs.version }}"
+ if [ "$CANONICAL_REPOSITORY" = true ]; then
+ scripts/build_ios.sh --fetch --device --release \
+ --version "${{ steps.ver.outputs.version }}"
+ else
+ scripts/build_ios.sh --fetch --release \
+ --version "${{ steps.ver.outputs.version }}"
+ fi
- name: Build Anbernic RG34XXSP port
run: |
@@ -198,6 +203,7 @@ jobs:
./build-rg34xxsp.sh --version "${{ steps.ver.outputs.version }}"
- name: Notarize & staple macOS app
+ if: github.repository == 'bryanthaboi/gen1recomp'
run: |
set -euo pipefail
ci_dir="${POKEMON_CI_DIR:-$HOME/.config/pokemon-ci}"
@@ -232,6 +238,7 @@ jobs:
echo "Notarized + stapled ✓"
- name: Stage release assets
+ if: github.repository == 'bryanthaboi/gen1recomp'
id: assets
run: |
set -euo pipefail
@@ -271,6 +278,7 @@ jobs:
cat "$outdir/sha256sums.txt"
- name: Publish GitHub Release
+ if: github.repository == 'bryanthaboi/gen1recomp'
env:
GH_TOKEN: ${{ github.token }}
run: |
@@ -376,6 +384,6 @@ jobs:
echo "Published release $tag"
- name: Clean up signing keychain
- if: always()
+ if: ${{ always() && github.repository == 'bryanthaboi/gen1recomp' }}
run: |
security delete-keychain "$RUNNER_TEMP/pokemon-signing.keychain-db" 2>/dev/null || true
From 1b8b3ad538361c82c72c123c90a5222310d55d02 Mon Sep 17 00:00:00 2001
From: Adrian Castro <22133246+castdrian@users.noreply.github.com>
Date: Sat, 1 Aug 2026 23:43:11 +0200
Subject: [PATCH 4/8] ci(ios): build device release on canonical repo
---
.github/workflows/ci.yml | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index de8fad26..cabc9ca4 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -56,8 +56,15 @@ jobs:
- uses: actions/checkout@v4
- name: install xcbeautify
run: brew list xcbeautify >/dev/null 2>&1 || brew install xcbeautify
- - name: build iOS simulator app
- run: scripts/build_ios.sh --fetch --release
+ - name: build iOS release
+ env:
+ CANONICAL_REPOSITORY: ${{ github.repository == 'bryanthaboi/gen1recomp' }}
+ run: |
+ if [ "$CANONICAL_REPOSITORY" = true ]; then
+ scripts/build_ios.sh --fetch --device --release
+ else
+ scripts/build_ios.sh --fetch --release
+ fi
headless:
name: headless suites (no ROM)
From 00d13d3c35bdc7a32eac0e17035615c7b2fc95e4 Mon Sep 17 00:00:00 2001
From: Adrian Castro <22133246+castdrian@users.noreply.github.com>
Date: Sat, 1 Aug 2026 23:43:12 +0200
Subject: [PATCH 5/8] ci(ios): comment release artifacts on pull requests
---
.github/workflows/ci.yml | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cabc9ca4..598c4dbc 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -22,6 +22,10 @@ concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
+permissions:
+ contents: read
+ pull-requests: write
+
jobs:
ios-changes:
name: detect iOS changes
@@ -52,6 +56,8 @@ jobs:
needs: ios-changes
if: needs.ios-changes.outputs.changed == 'true'
runs-on: ${{ fromJSON(github.repository == 'bryanthaboi/gen1recomp' && '["self-hosted", "macOS"]' || '"macos-latest"') }}
+ outputs:
+ ipa_url: ${{ steps.upload-ipa.outputs.artifact-url }}
steps:
- uses: actions/checkout@v4
- name: install xcbeautify
@@ -65,6 +71,33 @@ jobs:
else
scripts/build_ios.sh --fetch --release
fi
+ - name: upload iOS release artifact
+ id: upload-ipa
+ if: github.repository == 'bryanthaboi/gen1recomp'
+ uses: actions/upload-artifact@v4
+ with:
+ name: gen1recomp-ios-ipa
+ path: dist/ios/gen1recomp.ipa
+ if-no-files-found: error
+ retention-days: 7
+
+ ios-build-comment:
+ name: iOS artifact comment
+ needs: ios-build
+ if: github.event_name == 'pull_request' && github.repository == 'bryanthaboi/gen1recomp' && needs.ios-build.result == 'success'
+ runs-on: ubuntu-latest
+ steps:
+ - name: comment iOS artifact
+ uses: thollander/actions-comment-pull-request@v3
+ with:
+ message: |
+ #### iOS Release IPA
+
+ - [Download gen1recomp.ipa](${{ needs.ios-build.outputs.ipa_url }})
+
+ Automatically generated. [View workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
+ comment-tag: ios-build-result
+ github-token: ${{ secrets.GITHUB_TOKEN }}
headless:
name: headless suites (no ROM)
From 2e46954fe0d80a265235145ee247003482131b1a Mon Sep 17 00:00:00 2001
From: Adrian Castro <22133246+castdrian@users.noreply.github.com>
Date: Sat, 1 Aug 2026 23:56:04 +0200
Subject: [PATCH 6/8] ci(ios): use release signing in verification
---
.github/workflows/ci.yml | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 598c4dbc..44eeba01 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -60,6 +60,25 @@ jobs:
ipa_url: ${{ steps.upload-ipa.outputs.artifact-url }}
steps:
- uses: actions/checkout@v4
+ - name: import signing certificate
+ if: github.repository == 'bryanthaboi/gen1recomp'
+ run: |
+ keychain_path="$RUNNER_TEMP/gen1recomp-ci-signing.keychain-db"
+ ci_dir="${POKEMON_CI_DIR:-$HOME/.config/pokemon-ci}"
+ p12="$ci_dir/signing.p12"
+ passfile="$ci_dir/signing.pass"
+ [ -f "$p12" ] && [ -f "$passfile" ] || exit 1
+ p12pw="$(cat "$passfile")"
+ kcpw="$(openssl rand -base64 24)"
+ echo "::add-mask::$kcpw"
+ security delete-keychain "$keychain_path" 2>/dev/null || true
+ security create-keychain -p "$kcpw" "$keychain_path"
+ security set-keychain-settings "$keychain_path"
+ security unlock-keychain -p "$kcpw" "$keychain_path"
+ security import "$p12" -P "$p12pw" -k "$keychain_path" -T /usr/bin/codesign -T /usr/bin/security
+ security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$kcpw" "$keychain_path" >/dev/null
+ existing="$(security list-keychains -d user | sed -e 's/^[[:space:]]*//' -e 's/"//g')"
+ security list-keychains -d user -s "$keychain_path" $existing
- name: install xcbeautify
run: brew list xcbeautify >/dev/null 2>&1 || brew install xcbeautify
- name: build iOS release
@@ -80,6 +99,9 @@ jobs:
path: dist/ios/gen1recomp.ipa
if-no-files-found: error
retention-days: 7
+ - name: clean up signing keychain
+ if: ${{ always() && github.repository == 'bryanthaboi/gen1recomp' }}
+ run: security delete-keychain "$RUNNER_TEMP/gen1recomp-ci-signing.keychain-db" 2>/dev/null || true
ios-build-comment:
name: iOS artifact comment
From fe16b3259ca5845c48c1d96312cfe38dc66accba Mon Sep 17 00:00:00 2001
From: Adrian Castro <22133246+castdrian@users.noreply.github.com>
Date: Sun, 2 Aug 2026 00:01:53 +0200
Subject: [PATCH 7/8] ci(ios): comment artifacts after pull request builds
---
.github/workflows/ci.yml | 19 ----------
.github/workflows/ios-artifact-comment.yml | 43 ++++++++++++++++++++++
2 files changed, 43 insertions(+), 19 deletions(-)
create mode 100644 .github/workflows/ios-artifact-comment.yml
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 44eeba01..66600641 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -24,7 +24,6 @@ concurrency:
permissions:
contents: read
- pull-requests: write
jobs:
ios-changes:
@@ -103,24 +102,6 @@ jobs:
if: ${{ always() && github.repository == 'bryanthaboi/gen1recomp' }}
run: security delete-keychain "$RUNNER_TEMP/gen1recomp-ci-signing.keychain-db" 2>/dev/null || true
- ios-build-comment:
- name: iOS artifact comment
- needs: ios-build
- if: github.event_name == 'pull_request' && github.repository == 'bryanthaboi/gen1recomp' && needs.ios-build.result == 'success'
- runs-on: ubuntu-latest
- steps:
- - name: comment iOS artifact
- uses: thollander/actions-comment-pull-request@v3
- with:
- message: |
- #### iOS Release IPA
-
- - [Download gen1recomp.ipa](${{ needs.ios-build.outputs.ipa_url }})
-
- Automatically generated. [View workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
- comment-tag: ios-build-result
- github-token: ${{ secrets.GITHUB_TOKEN }}
-
headless:
name: headless suites (no ROM)
runs-on: ubuntu-latest
diff --git a/.github/workflows/ios-artifact-comment.yml b/.github/workflows/ios-artifact-comment.yml
new file mode 100644
index 00000000..7a3fe8b7
--- /dev/null
+++ b/.github/workflows/ios-artifact-comment.yml
@@ -0,0 +1,43 @@
+name: iOS artifact comment
+
+on:
+ workflow_run:
+ workflows: [ci]
+ types: [completed]
+
+permissions:
+ contents: read
+ pull-requests: write
+
+jobs:
+ comment:
+ if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
+ runs-on: ubuntu-latest
+ steps:
+ - id: artifact
+ env:
+ GH_TOKEN: ${{ github.token }}
+ RUN_ID: ${{ github.event.workflow_run.id }}
+ HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
+ HEAD_REPOSITORY: ${{ github.event.workflow_run.head_repository.full_name }}
+ run: |
+ artifact_id="$(gh api "repos/$GITHUB_REPOSITORY/actions/runs/$RUN_ID/artifacts" --jq '.artifacts[] | select(.name == "gen1recomp-ios-ipa") | .id')"
+ [ -n "$artifact_id" ] || exit 0
+ head_owner="${HEAD_REPOSITORY%%/*}"
+ pr_number="$(gh api "repos/$GITHUB_REPOSITORY/pulls?state=open&head=$head_owner:$HEAD_BRANCH" --jq '.[0].number // empty')"
+ [ -n "$pr_number" ] || exit 0
+ echo "artifact_url=https://github.com/$GITHUB_REPOSITORY/actions/runs/$RUN_ID/artifacts/$artifact_id" >> "$GITHUB_OUTPUT"
+ echo "pr_number=$pr_number" >> "$GITHUB_OUTPUT"
+ - name: comment iOS artifact
+ if: steps.artifact.outputs.pr_number != ''
+ uses: thollander/actions-comment-pull-request@v3
+ with:
+ message: |
+ #### iOS Release IPA
+
+ - [Download gen1recomp.ipa](${{ steps.artifact.outputs.artifact_url }})
+
+ Automatically generated. [View workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }})
+ pr-number: ${{ steps.artifact.outputs.pr_number }}
+ comment-tag: ios-build-result
+ github-token: ${{ github.token }}
From 1a2b23a066697255efa403a5b520b6e2db7e45a6 Mon Sep 17 00:00:00 2001
From: Adrian Castro <22133246+castdrian@users.noreply.github.com>
Date: Sun, 2 Aug 2026 00:26:48 +0200
Subject: [PATCH 8/8] ci: configure dependabot for actions
---
.github/dependabot.yml | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 .github/dependabot.yml
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..ca79ca5b
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,6 @@
+version: 2
+updates:
+ - package-ecosystem: github-actions
+ directory: /
+ schedule:
+ interval: weekly