Compare commits

...

11 Commits

Author SHA1 Message Date
Gauvain
ae37cfad3b ci(pr-title): post the title-lint comment on fork PRs via workflow_run
pull_request gives fork PRs a read-only token, so the sticky comment can't be
posted from pr-title.yml. Split the comment into pr-title-comment.yml
(workflow_run), which runs from the base branch with a write token and works for
forks. pr-title.yml stays the required check (runs on the PR branch, forks
included, no deadlock) and hands the lint result to the commenter via an
artifact. workflow_run only fires once this workflow is on the default branch, so
it activates for fork PRs after merge; the required check is unaffected.
2026-07-07 01:13:12 +02:00
Gauvain
0966186e81 ci(pr-title): revert to pull_request — pull_request_target can't run a workflow new in the PR
A pull_request_target workflow executes from the BASE branch, so pr-title.yml
(added in this PR, absent on develop) never runs under it — leaving the required
'Validate PR Title' check stuck in Expected. Back to pull_request so the check
runs from the PR branch. The fork-PR write-token improvement can be revisited in
a follow-up once this workflow exists on develop. Keep the success() guard and
the per-PR concurrency group.
2026-07-07 00:41:46 +02:00
Gauvain
a48416967e Merge branch 'develop' into ci/parallel-steps
Keep the parallel: step structure; adopt develop's Xcode 26.5 → 26.6 bump.
2026-07-07 00:38:46 +02:00
renovate[bot]
ed8744389b chore(deps): Update dependency xcode to v26.6 (#1793)
Some checks are pending
🏗️ Build Apps / 🤖 Build Android APK (Phone) (push) Waiting to run
🏗️ Build Apps / 🤖 Build Android APK (TV) (push) Waiting to run
🏗️ Build Apps / 🍎 Build iOS IPA (Phone) (push) Waiting to run
🏗️ Build Apps / 🍎 Build iOS IPA (Phone - Unsigned) (push) Waiting to run
🏗️ Build Apps / 🍎 Build tvOS IPA (push) Waiting to run
🏗️ Build Apps / 🍎 Build tvOS IPA (Unsigned) (push) Waiting to run
🔒 Lockfile Consistency Check / 🔍 Check bun.lock and package.json consistency (push) Waiting to run
🛡️ CodeQL Analysis / 🔎 Analyze with CodeQL (actions) (push) Waiting to run
🛡️ CodeQL Analysis / 🔎 Analyze with CodeQL (javascript-typescript) (push) Waiting to run
🏷️🔀Merge Conflict Labeler / 🏷️ Labeling Merge Conflicts (push) Waiting to run
🚦 Security & Quality Gate / 📝 Validate PR Title (push) Waiting to run
🚦 Security & Quality Gate / 🔍 Vulnerable Dependencies (push) Waiting to run
🚦 Security & Quality Gate / 🚑 Expo Doctor Check (push) Waiting to run
🚦 Security & Quality Gate / 🔍 Lint & Test (check) (push) Waiting to run
🚦 Security & Quality Gate / 🔍 Lint & Test (format) (push) Waiting to run
🚦 Security & Quality Gate / 🔍 Lint & Test (i18n:check) (push) Waiting to run
🚦 Security & Quality Gate / 🔍 Lint & Test (lint) (push) Waiting to run
🚦 Security & Quality Gate / 🔍 Lint & Test (typecheck) (push) Waiting to run
🛡️ Trivy Security Scan / 🔎 Filesystem scan (push) Waiting to run
2026-07-07 00:33:41 +02:00
Gauvain
04be0bf796 ci(pr-title): use pull_request_target and guard the cleanup with success()
pull_request_target gives fork PRs a write token so the title-lint sticky
comment posts for external contributors (the workflow only reads the title and
comments — it never checks out or runs PR code). Also AND the delete-comment
step with success() so a crashed lint run (not a lint violation) can't leave
error_message unset and wrongly delete the error comment.
2026-07-07 00:13:41 +02:00
renovate[bot]
b879026745 chore(deps): Update dependency expo-doctor to v1.20.0 (#1792) 2026-07-06 23:57:06 +02:00
Gauvain
c54131307c ci: drop full history fetch from lint and lockfile jobs
Biome, tsc and the i18n/lockfile scripts only read the working tree,
so a shallow clone is enough. Also run checkout and Bun setup in
parallel in update-issue-form for consistency.
2026-07-05 15:11:21 +02:00
Gauvain
2df9d37f34 ci(lint): move PR title validation to its own workflow
Job-level 'edited' skips left matrix checks with an unexpanded
${{ matrix.command }} name and required checks stuck in Expected.
Filtering at the trigger level removes the phantom run entirely:
title edits now only run the PR title check.
2026-07-05 15:10:59 +02:00
Gauvain
b211b2356c ci: restore main branch comments on expo-github-action pins 2026-07-05 15:10:34 +02:00
Gauvain
211657b042 ci(lint): stop re-running heavy jobs on PR title edits
The quality gate ran its full matrix on every PR edit event even though
title/body edits cannot change the code: only validate_pr_title needs
them. Gate the heavy jobs on action != 'edited', add the missing
concurrency group (Renovate PRs currently run the whole gate twice per
commit), cache Bun dependencies like the other workflows, drop the
unused setup-node step, and run checkout/Bun setup in parallel.
2026-07-05 03:22:49 +02:00
Gauvain
1b51342888 ci: run independent setup steps in parallel
Use the GitHub Actions parallel-steps feature (2026-06-25) to group
setup steps with no dependency between them: checkout, toolchains
(Bun/JDK/Xcode), the EAS CLI install and the disk-space cleanup now run
concurrently, and the Bun/Gradle cache restores overlap. On the iOS
jobs, Xcode/EAS setup previously ran after the ~2 min prebuild despite
not needing it.

Also in release.yml: queue successive release runs in order
(queue: max) instead of dropping the extra pending run, and fix the
expo-github-action pin comment (the pinned SHA is tag v9.0.0, not
main).
2026-07-05 03:22:42 +02:00
10 changed files with 407 additions and 294 deletions

View File

@@ -30,64 +30,66 @@ jobs:
actions: write # dispatch artifact-comment.yml to refresh the PR comment actions: write # dispatch artifact-comment.yml to refresh the PR comment
steps: steps:
- name: 🗑️ Free Disk Space - parallel:
uses: BRAINSia/free-disk-space@7048ffbf50819342ac964ef3998a51c2564a8a75 # v2.1.3 - name: 🗑️ Free Disk Space
with: uses: BRAINSia/free-disk-space@7048ffbf50819342ac964ef3998a51c2564a8a75 # v2.1.3
tool-cache: false with:
mandb: true tool-cache: false
android: false mandb: true
dotnet: true android: false
haskell: true dotnet: true
large-packages: false haskell: true
docker-images: true large-packages: false
swap-storage: false docker-images: true
swap-storage: false
- name: 📥 Checkout code - name: 📥 Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
ref: ${{ github.event.pull_request.head.sha || github.sha }} ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 0 fetch-depth: 0
submodules: recursive submodules: recursive
show-progress: false show-progress: false
- name: 🍞 Setup Bun - name: 🍞 Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with: with:
# renovate: datasource=npm depName=bun # renovate: datasource=npm depName=bun
bun-version: "1.3.14" bun-version: "1.3.14"
- name: 💾 Cache Bun dependencies - name: ☕ Set up JDK 17
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0 # ubuntu-26.04 defaults to JDK 25, which breaks the RN/AGP native build
with: # (Kotlin falls back to JVM_23, the foojay toolchain + CMake configure
path: ~/.bun/install/cache # fail). Pin Temurin 17 for a deterministic Android build.
key: ${{ runner.os }}-${{ runner.arch }}-bun-${{ hashFiles('bun.lock') }} uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0
restore-keys: | with:
${{ runner.os }}-${{ runner.arch }}-bun- distribution: temurin
java-version: "17"
- parallel:
- name: 💾 Cache Bun dependencies
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-${{ runner.arch }}-bun-${{ hashFiles('bun.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-bun-
- name: 💾 Cache Gradle global
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
with:
path: |
~/.gradle/caches/modules-2
~/.gradle/wrapper
key: ${{ runner.os }}-${{ runner.arch }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-gradle-
- name: 📦 Install dependencies and reload submodules - name: 📦 Install dependencies and reload submodules
run: | run: |
bun install --frozen-lockfile bun install --frozen-lockfile
bun run submodule-reload bun run submodule-reload
- name: ☕ Set up JDK 17
# ubuntu-26.04 defaults to JDK 25, which breaks the RN/AGP native build
# (Kotlin falls back to JVM_23, the foojay toolchain + CMake configure
# fail). Pin Temurin 17 for a deterministic Android build.
uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0
with:
distribution: temurin
java-version: "17"
- name: 💾 Cache Gradle global
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
with:
path: |
~/.gradle/caches/modules-2
~/.gradle/wrapper
key: ${{ runner.os }}-${{ runner.arch }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-gradle-
- name: 🛠️ Generate project files - name: 🛠️ Generate project files
run: bun run prebuild run: bun run prebuild
@@ -130,64 +132,66 @@ jobs:
actions: write # dispatch artifact-comment.yml to refresh the PR comment actions: write # dispatch artifact-comment.yml to refresh the PR comment
steps: steps:
- name: 🗑️ Free Disk Space - parallel:
uses: BRAINSia/free-disk-space@7048ffbf50819342ac964ef3998a51c2564a8a75 # v2.1.3 - name: 🗑️ Free Disk Space
with: uses: BRAINSia/free-disk-space@7048ffbf50819342ac964ef3998a51c2564a8a75 # v2.1.3
tool-cache: false with:
mandb: true tool-cache: false
android: false mandb: true
dotnet: true android: false
haskell: true dotnet: true
large-packages: false haskell: true
docker-images: true large-packages: false
swap-storage: false docker-images: true
swap-storage: false
- name: 📥 Checkout code - name: 📥 Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
ref: ${{ github.event.pull_request.head.sha || github.sha }} ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 0 fetch-depth: 0
submodules: recursive submodules: recursive
show-progress: false show-progress: false
- name: 🍞 Setup Bun - name: 🍞 Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with: with:
# renovate: datasource=npm depName=bun # renovate: datasource=npm depName=bun
bun-version: "1.3.14" bun-version: "1.3.14"
- name: 💾 Cache Bun dependencies - name: ☕ Set up JDK 17
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0 # ubuntu-26.04 defaults to JDK 25, which breaks the RN/AGP native build
with: # (Kotlin falls back to JVM_23, the foojay toolchain + CMake configure
path: ~/.bun/install/cache # fail). Pin Temurin 17 for a deterministic Android build.
key: ${{ runner.os }}-${{ runner.arch }}-bun-${{ hashFiles('bun.lock') }} uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0
restore-keys: | with:
${{ runner.os }}-${{ runner.arch }}-bun- distribution: temurin
java-version: "17"
- parallel:
- name: 💾 Cache Bun dependencies
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-${{ runner.arch }}-bun-${{ hashFiles('bun.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-bun-
- name: 💾 Cache Gradle global
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
with:
path: |
~/.gradle/caches/modules-2
~/.gradle/wrapper
key: ${{ runner.os }}-${{ runner.arch }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-gradle-
- name: 📦 Install dependencies and reload submodules - name: 📦 Install dependencies and reload submodules
run: | run: |
bun install --frozen-lockfile bun install --frozen-lockfile
bun run submodule-reload bun run submodule-reload
- name: ☕ Set up JDK 17
# ubuntu-26.04 defaults to JDK 25, which breaks the RN/AGP native build
# (Kotlin falls back to JVM_23, the foojay toolchain + CMake configure
# fail). Pin Temurin 17 for a deterministic Android build.
uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0
with:
distribution: temurin
java-version: "17"
- name: 💾 Cache Gradle global
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
with:
path: |
~/.gradle/caches/modules-2
~/.gradle/wrapper
key: ${{ runner.os }}-${{ runner.arch }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-gradle-
- name: 🛠️ Generate project files - name: 🛠️ Generate project files
run: bun run prebuild:tv run: bun run prebuild:tv
@@ -229,19 +233,33 @@ jobs:
actions: write # dispatch artifact-comment.yml to refresh the PR comment actions: write # dispatch artifact-comment.yml to refresh the PR comment
steps: steps:
- name: 📥 Checkout code - parallel:
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: 📥 Checkout code
with: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
ref: ${{ github.event.pull_request.head.sha || github.sha }} with:
fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha || github.sha }}
submodules: recursive fetch-depth: 0
show-progress: false submodules: recursive
show-progress: false
- name: 🍞 Setup Bun - name: 🍞 Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with: with:
# renovate: datasource=npm depName=bun # renovate: datasource=npm depName=bun
bun-version: "1.3.14" bun-version: "1.3.14"
- name: 🔧 Setup Xcode
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1
with:
# renovate: datasource=custom.xcode depName=xcode versioning=loose
xcode-version: "26.6"
- name: 🏗️ Setup EAS
uses: expo/expo-github-action@eab7a230208c952974db8c3245cfd78402c7b385 # main
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
eas-cache: true
- name: 💾 Cache Bun dependencies - name: 💾 Cache Bun dependencies
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0 uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
@@ -259,19 +277,6 @@ jobs:
- name: 🛠️ Generate project files - name: 🛠️ Generate project files
run: bun run prebuild run: bun run prebuild
- name: 🔧 Setup Xcode
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1
with:
# renovate: datasource=custom.xcode depName=xcode versioning=loose
xcode-version: "26.5"
- name: 🏗️ Setup EAS
uses: expo/expo-github-action@eab7a230208c952974db8c3245cfd78402c7b385 # main
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
eas-cache: true
- name: 🚀 Build iOS app - name: 🚀 Build iOS app
env: env:
EXPO_TV: 0 EXPO_TV: 0
@@ -301,19 +306,26 @@ jobs:
actions: write # dispatch artifact-comment.yml to refresh the PR comment actions: write # dispatch artifact-comment.yml to refresh the PR comment
steps: steps:
- name: 📥 Checkout code - parallel:
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: 📥 Checkout code
with: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
ref: ${{ github.event.pull_request.head.sha || github.sha }} with:
fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha || github.sha }}
submodules: recursive fetch-depth: 0
show-progress: false submodules: recursive
show-progress: false
- name: 🍞 Setup Bun - name: 🍞 Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with: with:
# renovate: datasource=npm depName=bun # renovate: datasource=npm depName=bun
bun-version: "1.3.14" bun-version: "1.3.14"
- name: 🔧 Setup Xcode
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1
with:
# renovate: datasource=custom.xcode depName=xcode versioning=loose
xcode-version: "26.6"
- name: 💾 Cache Bun dependencies - name: 💾 Cache Bun dependencies
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0 uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
@@ -331,12 +343,6 @@ jobs:
- name: 🛠️ Generate project files - name: 🛠️ Generate project files
run: bun run prebuild run: bun run prebuild
- name: 🔧 Setup Xcode
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1
with:
# renovate: datasource=custom.xcode depName=xcode versioning=loose
xcode-version: "26.5"
- name: 🚀 Build iOS app - name: 🚀 Build iOS app
env: env:
EXPO_TV: 0 EXPO_TV: 0
@@ -368,19 +374,33 @@ jobs:
actions: write # dispatch artifact-comment.yml to refresh the PR comment actions: write # dispatch artifact-comment.yml to refresh the PR comment
steps: steps:
- name: 📥 Checkout code - parallel:
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: 📥 Checkout code
with: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
ref: ${{ github.event.pull_request.head.sha || github.sha }} with:
fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha || github.sha }}
submodules: recursive fetch-depth: 0
show-progress: false submodules: recursive
show-progress: false
- name: 🍞 Setup Bun - name: 🍞 Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with: with:
# renovate: datasource=npm depName=bun # renovate: datasource=npm depName=bun
bun-version: "1.3.14" bun-version: "1.3.14"
- name: 🔧 Setup Xcode
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1
with:
# renovate: datasource=custom.xcode depName=xcode versioning=loose
xcode-version: "26.6"
- name: 🏗️ Setup EAS
uses: expo/expo-github-action@eab7a230208c952974db8c3245cfd78402c7b385 # main
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
eas-cache: true
- name: 💾 Cache Bun dependencies - name: 💾 Cache Bun dependencies
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0 uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
@@ -398,19 +418,6 @@ jobs:
- name: 🛠️ Generate project files - name: 🛠️ Generate project files
run: bun run prebuild:tv run: bun run prebuild:tv
- name: 🔧 Setup Xcode
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1
with:
# renovate: datasource=custom.xcode depName=xcode versioning=loose
xcode-version: "26.5"
- name: 🏗️ Setup EAS
uses: expo/expo-github-action@eab7a230208c952974db8c3245cfd78402c7b385 # main
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
eas-cache: true
- name: 🚀 Build iOS app - name: 🚀 Build iOS app
env: env:
EXPO_TV: 1 EXPO_TV: 1
@@ -438,19 +445,26 @@ jobs:
actions: write # dispatch artifact-comment.yml to refresh the PR comment actions: write # dispatch artifact-comment.yml to refresh the PR comment
steps: steps:
- name: 📥 Checkout code - parallel:
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: 📥 Checkout code
with: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
ref: ${{ github.event.pull_request.head.sha || github.sha }} with:
fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha || github.sha }}
submodules: recursive fetch-depth: 0
show-progress: false submodules: recursive
show-progress: false
- name: 🍞 Setup Bun - name: 🍞 Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with: with:
# renovate: datasource=npm depName=bun # renovate: datasource=npm depName=bun
bun-version: "1.3.14" bun-version: "1.3.14"
- name: 🔧 Setup Xcode
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1
with:
# renovate: datasource=custom.xcode depName=xcode versioning=loose
xcode-version: "26.6"
- name: 💾 Cache Bun dependencies - name: 💾 Cache Bun dependencies
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0 uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
@@ -468,12 +482,6 @@ jobs:
- name: 🛠️ Generate project files - name: 🛠️ Generate project files
run: bun run prebuild:tv run: bun run prebuild:tv
- name: 🔧 Setup Xcode
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1
with:
# renovate: datasource=custom.xcode depName=xcode versioning=loose
xcode-version: "26.5"
- name: 🚀 Build iOS app - name: 🚀 Build iOS app
env: env:
EXPO_TV: 1 EXPO_TV: 1

View File

@@ -18,19 +18,19 @@ jobs:
contents: read contents: read
steps: steps:
- name: 📥 Checkout repository - parallel:
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: 📥 Checkout repository
with: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
ref: ${{ github.event.pull_request.head.sha || github.sha }} with:
show-progress: false ref: ${{ github.event.pull_request.head.sha || github.sha }}
submodules: recursive show-progress: false
fetch-depth: 0 submodules: recursive
- name: 🍞 Setup Bun - name: 🍞 Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with: with:
# renovate: datasource=npm depName=bun # renovate: datasource=npm depName=bun
bun-version: "1.3.14" bun-version: "1.3.14"
- name: 💾 Cache Bun dependencies - name: 💾 Cache Bun dependencies
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0 uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0

View File

@@ -20,14 +20,15 @@ jobs:
issues: write issues: write
contents: read contents: read
steps: steps:
- name: 📥 Checkout repository - parallel:
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: 📥 Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: 🍞 Setup Bun - name: 🍞 Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with: with:
# renovate: datasource=npm depName=bun # renovate: datasource=npm depName=bun
bun-version: "1.3.14" bun-version: "1.3.14"
- name: 🔍 Detect duplicate issues - name: 🔍 Detect duplicate issues
run: bun scripts/detect-duplicate-issue.ts run: bun scripts/detect-duplicate-issue.ts

View File

@@ -2,7 +2,7 @@ name: 🚦 Security & Quality Gate
on: on:
pull_request: pull_request:
types: [opened, edited, synchronize, reopened] types: [opened, synchronize, reopened]
branches: [develop, master] branches: [develop, master]
workflow_dispatch: workflow_dispatch:
push: push:
@@ -11,39 +11,11 @@ on:
permissions: permissions:
contents: read contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
validate_pr_title:
name: "📝 Validate PR Title"
if: github.event_name == 'pull_request'
runs-on: ubuntu-26.04
permissions:
pull-requests: write
contents: read
steps:
- uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1
id: lint_pr_title
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4
if: always() && (steps.lint_pr_title.outputs.error_message != null)
with:
header: pr-title-lint-error
message: |
Hey there and thank you for opening this pull request! 👋🏼
We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/).
**Error details:**
```
${{ steps.lint_pr_title.outputs.error_message }}
```
- if: ${{ steps.lint_pr_title.outputs.error_message == null }}
uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4
with:
header: pr-title-lint-error
delete: true
dependency-review: dependency-review:
name: 🔍 Vulnerable Dependencies name: 🔍 Vulnerable Dependencies
runs-on: ubuntu-26.04 runs-on: ubuntu-26.04
@@ -67,18 +39,26 @@ jobs:
name: 🚑 Expo Doctor Check name: 🚑 Expo Doctor Check
runs-on: ubuntu-26.04 runs-on: ubuntu-26.04
steps: steps:
- name: 🛒 Checkout repository - parallel:
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: 🛒 Checkout repository
with: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
ref: ${{ github.event.pull_request.head.sha || github.sha }} with:
submodules: recursive ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 0 submodules: recursive
- name: 🍞 Setup Bun - name: 🍞 Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
# renovate: datasource=npm depName=bun
bun-version: "1.3.14"
- name: 💾 Cache Bun dependencies
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
with: with:
# renovate: datasource=npm depName=bun path: ~/.bun/install/cache
bun-version: "1.3.14" key: ${{ runner.os }}-${{ runner.arch }}-bun-${{ hashFiles('bun.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-bun-
- name: 📦 Install dependencies (bun) - name: 📦 Install dependencies (bun)
run: bun install --frozen-lockfile run: bun install --frozen-lockfile
@@ -103,24 +83,26 @@ jobs:
- "i18n:check" - "i18n:check"
steps: steps:
- name: "📥 Checkout PR code" - parallel:
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: "📥 Checkout PR code"
with: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
ref: ${{ github.event.pull_request.head.sha || github.sha }} with:
submodules: recursive ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 0 submodules: recursive
- name: "🟢 Setup Node.js" - name: "🍞 Setup Bun"
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with: with:
# renovate: datasource=node-version depName=node versioning=node # renovate: datasource=npm depName=bun
node-version: "24.18.0" bun-version: "1.3.14"
- name: "🍞 Setup Bun" - name: 💾 Cache Bun dependencies
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
with: with:
# renovate: datasource=npm depName=bun path: ~/.bun/install/cache
bun-version: "1.3.14" key: ${{ runner.os }}-${{ runner.arch }}-bun-${{ hashFiles('bun.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-bun-
- name: "📦 Install dependencies" - name: "📦 Install dependencies"
run: bun install --frozen-lockfile run: bun install --frozen-lockfile

76
.github/workflows/pr-title-comment.yml vendored Normal file
View File

@@ -0,0 +1,76 @@
name: 📝 PR Title Comment
# Posts / updates / deletes the PR-title lint sticky comment with a write token,
# so it works on FORK PRs too (the pull_request-triggered pr-title.yml only has a
# read-only token on forks). workflow_run runs from the base branch with the base
# repo's token. This is comment-only — the required check stays pr-title.yml.
on:
workflow_run:
workflows: ["📝 PR Title"]
types: [completed]
permissions:
contents: read
actions: read # download the artifact from the triggering run
pull-requests: write # post/update/delete the sticky comment
concurrency:
group: pr-title-comment-${{ github.event.workflow_run.id }}
cancel-in-progress: true
jobs:
comment:
if: github.event.workflow_run.event == 'pull_request'
runs-on: ubuntu-26.04
steps:
- name: ⬇️ Download lint result
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh run download "${{ github.event.workflow_run.id }}" \
--repo "${{ github.repository }}" \
--name pr-title-result \
--dir result
- name: 🔎 Read result
id: result
run: |
echo "number=$(cat result/number)" >> "$GITHUB_OUTPUT"
if [ -s result/error ]; then
echo "has_error=true" >> "$GITHUB_OUTPUT"
else
echo "has_error=false" >> "$GITHUB_OUTPUT"
fi
- name: 📥 Load error message
if: steps.result.outputs.has_error == 'true'
run: |
{
echo "LINT_ERROR<<PR_TITLE_ERR_EOF"
cat result/error
echo
echo "PR_TITLE_ERR_EOF"
} >> "$GITHUB_ENV"
- name: 💬 Post title error
if: steps.result.outputs.has_error == 'true'
uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4
with:
number: ${{ steps.result.outputs.number }}
header: pr-title-lint-error
message: |
Hey there and thank you for opening this pull request! 👋🏼
We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/).
**Error details:**
```
${{ env.LINT_ERROR }}
```
- name: 🧹 Clear title error
if: steps.result.outputs.has_error == 'false'
uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4
with:
number: ${{ steps.result.outputs.number }}
header: pr-title-lint-error
delete: true

42
.github/workflows/pr-title.yml vendored Normal file
View File

@@ -0,0 +1,42 @@
name: 📝 PR Title
on:
pull_request:
types: [opened, edited, synchronize, reopened]
branches: [develop, master]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
validate_pr_title:
name: "📝 Validate PR Title"
runs-on: ubuntu-26.04
steps:
- uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1
id: lint_pr_title
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Fork PRs only get a read-only GITHUB_TOKEN here, so the sticky comment
# is posted from the privileged pr-title-comment.yml (workflow_run). Hand
# off the result (PR number + lint error) as an artifact for it to read.
- if: always()
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
LINT_ERROR: ${{ steps.lint_pr_title.outputs.error_message }}
run: |
mkdir -p pr-title-result
printf '%s' "$PR_NUMBER" > pr-title-result/number
printf '%s' "$LINT_ERROR" > pr-title-result/error
- if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: pr-title-result
path: pr-title-result/
retention-days: 1

View File

@@ -13,6 +13,8 @@ name: 🚀 Release (EAS build + submit)
concurrency: concurrency:
group: release-${{ github.ref }} group: release-${{ github.ref }}
cancel-in-progress: false cancel-in-progress: false
# Queue successive releases in order instead of dropping the extra pending run.
queue: max
on: on:
push: push:
@@ -63,18 +65,26 @@ jobs:
artifact_name: streamyfin-android-tv-apk artifact_name: streamyfin-android-tv-apk
steps: steps:
- name: 📥 Checkout code - parallel:
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: 📥 Checkout code
with: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
fetch-depth: 0 with:
submodules: recursive fetch-depth: 0
show-progress: false submodules: recursive
show-progress: false
- name: 🍞 Setup Bun - name: 🍞 Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with: with:
# renovate: datasource=npm depName=bun # renovate: datasource=npm depName=bun
bun-version: "1.3.14" bun-version: "1.3.14"
- name: 🏗️ Setup EAS
uses: expo/expo-github-action@eab7a230208c952974db8c3245cfd78402c7b385 # main
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
eas-cache: true
- name: 💾 Cache Bun dependencies - name: 💾 Cache Bun dependencies
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0 uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
@@ -89,13 +99,6 @@ jobs:
bun install --frozen-lockfile bun install --frozen-lockfile
bun run submodule-reload bun run submodule-reload
- name: 🏗️ Setup EAS
uses: expo/expo-github-action@eab7a230208c952974db8c3245cfd78402c7b385 # main
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
eas-cache: true
# tvOS uses credentialsSource: local — restore the gitignored # tvOS uses credentialsSource: local — restore the gitignored
# credentials.json + cert + provisioning profiles from secrets. # credentials.json + cert + provisioning profiles from secrets.
- name: 🔐 Restore tvOS signing credentials - name: 🔐 Restore tvOS signing credentials

View File

@@ -25,19 +25,20 @@ jobs:
contents: write contents: write
pull-requests: write pull-requests: write
steps: steps:
- name: 📥 Checkout repository - parallel:
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: 📥 Checkout repository
with: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
# On `release` events GITHUB_SHA is the tagged commit — without this the with:
# script would regenerate the form from the tag's (stale) copy and the bot # On `release` events GITHUB_SHA is the tagged commit — without this the
# PR would revert any form edits made on develop since that release. # script would regenerate the form from the tag's (stale) copy and the bot
ref: develop # PR would revert any form edits made on develop since that release.
ref: develop
- name: 🍞 Setup Bun - name: 🍞 Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with: with:
# renovate: datasource=npm depName=bun # renovate: datasource=npm depName=bun
bun-version: "1.3.14" bun-version: "1.3.14"
- name: 🔢 Populate version dropdown from GitHub releases - name: 🔢 Populate version dropdown from GitHub releases
id: populate id: populate

View File

@@ -109,7 +109,7 @@
"@types/react": "~19.2.10", "@types/react": "~19.2.10",
"@types/react-test-renderer": "19.1.0", "@types/react-test-renderer": "19.1.0",
"cross-env": "10.1.0", "cross-env": "10.1.0",
"expo-doctor": "1.19.9", "expo-doctor": "1.20.0",
"husky": "9.1.7", "husky": "9.1.7",
"lint-staged": "17.0.8", "lint-staged": "17.0.8",
"react-test-renderer": "19.2.3", "react-test-renderer": "19.2.3",
@@ -1015,7 +1015,7 @@
"expo-device": ["expo-device@56.0.4", "", { "dependencies": { "ua-parser-js": "^0.7.33" }, "peerDependencies": { "expo": "*" } }, "sha512-ucVcGPkvBrl2QHuy7XcYex2Y6BETvJ6TREutZrwLGUDnlvbpKS8KfQoNZOpvkyo5Nmm9RrasYQ0CrXmBHho2mg=="], "expo-device": ["expo-device@56.0.4", "", { "dependencies": { "ua-parser-js": "^0.7.33" }, "peerDependencies": { "expo": "*" } }, "sha512-ucVcGPkvBrl2QHuy7XcYex2Y6BETvJ6TREutZrwLGUDnlvbpKS8KfQoNZOpvkyo5Nmm9RrasYQ0CrXmBHho2mg=="],
"expo-doctor": ["expo-doctor@1.19.9", "", { "bin": { "expo-doctor": "bin/expo-doctor.js" } }, "sha512-SJW5HxEDQ9f5QdFvrUwfbdJZ4HI0EAAxsrJqrHBFjKBum+uSOcEIZPLRibwNQLTHOwTO1TWNLiMlF9sDUBWeYw=="], "expo-doctor": ["expo-doctor@1.20.0", "", { "bin": { "expo-doctor": "bin/expo-doctor.js" } }, "sha512-YL0uGQGZ65tWOCOiDH6BFzBkx/9N46MyBUdRfa4t6iuG4tbLg/phRrhmuaNm99QJVMqYtt3ksRbFCzuYOuX20Q=="],
"expo-file-system": ["expo-file-system@56.0.8", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-NrH41/8snGIBSbYicwVLB4txPdgCATd7ZYhMAGS3YJZ9GbnduhlAoV4/YCbGayjrbpE9bJb/6wegPL/zmvRMnQ=="], "expo-file-system": ["expo-file-system@56.0.8", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-NrH41/8snGIBSbYicwVLB4txPdgCATd7ZYhMAGS3YJZ9GbnduhlAoV4/YCbGayjrbpE9bJb/6wegPL/zmvRMnQ=="],

View File

@@ -132,7 +132,7 @@
"@types/react": "~19.2.10", "@types/react": "~19.2.10",
"@types/react-test-renderer": "19.1.0", "@types/react-test-renderer": "19.1.0",
"cross-env": "10.1.0", "cross-env": "10.1.0",
"expo-doctor": "1.19.9", "expo-doctor": "1.20.0",
"husky": "9.1.7", "husky": "9.1.7",
"lint-staged": "17.0.8", "lint-staged": "17.0.8",
"react-test-renderer": "19.2.3", "react-test-renderer": "19.2.3",