Compare commits

..

1 Commits

Author SHA1 Message Date
renovate[bot]
bee268b37a chore(deps): Update react monorepo 2026-05-21 23:09:19 +00:00
5 changed files with 1082 additions and 590 deletions

View File

@@ -188,17 +188,6 @@ jobs:
if (latestAppsRun) {
console.log(`Getting individual job statuses for run ${latestAppsRun.id} (status: ${latestAppsRun.status}, conclusion: ${latestAppsRun.conclusion || 'none'})`);
// Map job names to our build targets. Declared outside the try so
// the catch fallback can reuse the same keys.
const jobMappings = {
'Android Phone': ['🤖 Build Android APK (Phone)', 'build-android-phone'],
'Android TV': ['🤖 Build Android APK (TV)', 'build-android-tv'],
'iOS': ['🍎 Build iOS IPA (Phone)', 'build-ios-phone'],
'iOS Unsigned': ['🍎 Build iOS IPA (Phone - Unsigned)', 'build-ios-phone-unsigned'],
'tvOS': ['🍎 Build tvOS IPA', 'build-ios-tv'],
'tvOS Unsigned': ['🍎 Build tvOS IPA (Unsigned)', 'build-ios-tv-unsigned']
};
try {
// Get all jobs for this workflow run
const { data: jobs } = await github.rest.actions.listJobsForWorkflowRun({
@@ -227,6 +216,13 @@ jobs:
return; // Exit early
}
// Map job names to our build targets
const jobMappings = {
'Android Phone': ['🤖 Build Android APK (Phone)', 'build-android-phone'],
'Android TV': ['🤖 Build Android APK (TV)', 'build-android-tv'],
'iOS Phone': ['🍎 Build iOS IPA (Phone)', 'build-ios-phone']
};
// Create individual status for each job
for (const [platform, jobNames] of Object.entries(jobMappings)) {
const job = jobs.jobs.find(j =>
@@ -240,9 +236,7 @@ jobs:
conclusion: job.conclusion,
url: job.html_url,
runId: latestAppsRun.id,
created_at: job.started_at || latestAppsRun.created_at,
started_at: job.started_at,
completed_at: job.completed_at
created_at: job.started_at || latestAppsRun.created_at
};
console.log(`Mapped ${platform} to job: ${job.name} (${job.status}/${job.conclusion || 'none'})`);
} else {
@@ -253,30 +247,22 @@ jobs:
conclusion: latestAppsRun.conclusion,
url: latestAppsRun.html_url,
runId: latestAppsRun.id,
created_at: latestAppsRun.created_at,
started_at: latestAppsRun.run_started_at,
completed_at: latestAppsRun.updated_at
created_at: latestAppsRun.created_at
};
}
}
} catch (error) {
console.log(`Failed to get jobs for run ${latestAppsRun.id}:`, error.message);
// Fallback to workflow-level status for every build target.
// Keys must match jobMappings / buildTargets statusKey values.
const fallbackStatus = {
// Fallback to workflow-level status
buildStatuses['Android Phone'] = buildStatuses['Android TV'] = buildStatuses['iOS Phone'] = {
name: latestAppsRun.name,
status: latestAppsRun.status,
conclusion: latestAppsRun.conclusion,
url: latestAppsRun.html_url,
runId: latestAppsRun.id,
created_at: latestAppsRun.created_at,
started_at: latestAppsRun.run_started_at,
completed_at: latestAppsRun.updated_at
created_at: latestAppsRun.created_at
};
for (const platform of Object.keys(jobMappings)) {
buildStatuses[platform] = fallbackStatus;
}
}
// Collect artifacts if any job has completed successfully
@@ -367,12 +353,10 @@ jobs:
// Process each expected build target individually
const buildTargets = [
{ name: 'Android Phone', platform: '🤖', device: '📱 Phone', statusKey: 'Android Phone', artifactPattern: /android.*phone/i },
{ name: 'Android TV', platform: '🤖', device: '📺 TV', statusKey: 'Android TV', artifactPattern: /android.*tv/i },
{ name: 'iOS', platform: '🍎', device: '📱 Phone', statusKey: 'iOS', artifactPattern: /ios.*phone.*ipa(?!.*unsigned)/i },
{ name: 'iOS Unsigned', platform: '🍎', device: '📱 Phone Unsigned', statusKey: 'iOS Unsigned', artifactPattern: /ios.*phone.*unsigned/i },
{ name: 'tvOS', platform: '🍎', device: '📺 TV', statusKey: 'tvOS', artifactPattern: /ios.*tv.*ipa(?!.*unsigned)/i },
{ name: 'tvOS Unsigned', platform: '🍎', device: '📺 TV Unsigned', statusKey: 'tvOS Unsigned', artifactPattern: /ios.*tv.*unsigned/i }
{ name: 'Android Phone', platform: '🤖', device: '📱', statusKey: 'Android Phone', artifactPattern: /android.*phone/i },
{ name: 'Android TV', platform: '🤖', device: '📺', statusKey: 'Android TV', artifactPattern: /android.*tv/i },
{ name: 'iOS Phone', platform: '🍎', device: '📱', statusKey: 'iOS Phone', artifactPattern: /ios.*phone/i },
{ name: 'iOS TV', platform: '🍎', device: '📺', statusKey: 'iOS TV', artifactPattern: /ios.*tv/i }
];
for (const target of buildTargets) {
@@ -387,31 +371,16 @@ jobs:
let status = '⏳ Pending';
let downloadLink = '*Waiting for build...*';
// tvOS builds are temporarily disabled until feat/tv-interface
// is merged - show them as disabled instead of stuck pending.
if (target.name === 'tvOS' || target.name === 'tvOS Unsigned') {
// Special case for iOS TV - show as disabled
if (target.name === 'iOS TV') {
status = '💤 Disabled';
downloadLink = '*Disabled until feat/tv-interface is merged*';
downloadLink = '*Disabled for now*';
} else if (matchingStatus) {
if (matchingStatus.conclusion === 'success' && matchingArtifact) {
status = '✅ Complete';
const directLink = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${matchingArtifact.workflow_run.id}/artifacts/${matchingArtifact.id}`;
const fileType = target.name.includes('Android') ? 'APK' : 'IPA';
// Format file size
const sizeInMB = (matchingArtifact.size_in_bytes / (1024 * 1024)).toFixed(1);
const sizeInfo = `(${sizeInMB} MB)`;
// Calculate build duration
let durationInfo = '';
if (matchingStatus.started_at && matchingStatus.completed_at) {
const durationMs = new Date(matchingStatus.completed_at) - new Date(matchingStatus.started_at);
const durationMin = Math.floor(durationMs / 60000);
const durationSec = Math.floor((durationMs % 60000) / 1000);
durationInfo = ` - ${durationMin}m ${durationSec}s`;
}
downloadLink = `[📥 Download ${fileType}](${directLink}) ${sizeInfo}${durationInfo}`;
downloadLink = `[📥 Download ${fileType}](${directLink})`;
} else if (matchingStatus.conclusion === 'failure') {
status = `❌ [Failed](${matchingStatus.url})`;
downloadLink = '*Build failed*';
@@ -439,7 +408,7 @@ jobs:
}
}
commentBody += `| ${target.platform} ${target.name} | ${target.device} | ${status} | ${downloadLink} |\n`;
commentBody += `| ${target.platform} ${target.name.split(' ')[0]} | ${target.device} ${target.name.split(' ')[1]} | ${status} | ${downloadLink} |\n`;
}
commentBody += `\n`;

View File

@@ -299,127 +299,67 @@ jobs:
path: build/*.ipa
retention-days: 7
build-ios-tv:
# Temporarily disabled until feat/tv-interface is merged (TV UI not ready).
# Re-enable by removing the `false &&` prefix below.
if: false && (!contains(github.event.head_commit.message, '[skip ci]') && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'streamyfin/streamyfin'))
runs-on: macos-26
name: 🍎 Build tvOS IPA
permissions:
contents: read
steps:
- name: 📥 Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 0
submodules: recursive
show-progress: false
- name: 🍞 Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: latest
- name: 💾 Cache Bun dependencies
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-bun-cache-${{ hashFiles('bun.lock') }}
restore-keys: |
${{ runner.os }}-bun-cache
- name: 📦 Install dependencies and reload submodules
run: |
bun install --frozen-lockfile
bun run submodule-reload
- name: 🛠️ Generate project files
run: bun run prebuild:tv
- name: 🔧 Setup Xcode
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1
with:
xcode-version: "26.2"
- name: 🏗️ Setup EAS
uses: expo/expo-github-action@b184ff86a3c926240f1b6db41764c83a01c02eef # main
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
eas-cache: true
- name: 🚀 Build iOS app
env:
EXPO_TV: 1
run: eas build -p ios --local --non-interactive
- name: 📅 Set date tag
run: echo "DATE_TAG=$(date +%d-%m-%Y_%H-%M-%S)" >> $GITHUB_ENV
- name: 📤 Upload IPA artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: streamyfin-ios-tv-ipa-${{ env.DATE_TAG }}
path: build-*.ipa
retention-days: 7
build-ios-tv-unsigned:
# Temporarily disabled until feat/tv-interface is merged (TV UI not ready).
# Re-enable by removing the `false &&` prefix below.
if: false && (!contains(github.event.head_commit.message, '[skip ci]'))
runs-on: macos-26
name: 🍎 Build tvOS IPA (Unsigned)
permissions:
contents: read
steps:
- name: 📥 Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 0
submodules: recursive
show-progress: false
- name: 🍞 Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: latest
- name: 💾 Cache Bun dependencies
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-bun-cache-${{ hashFiles('bun.lock') }}
restore-keys: |
${{ runner.os }}-bun-cache
- name: 📦 Install dependencies and reload submodules
run: |
bun install --frozen-lockfile
bun run submodule-reload
- name: 🛠️ Generate project files
run: bun run prebuild:tv
- name: 🔧 Setup Xcode
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1
with:
xcode-version: "26.2"
- name: 🚀 Build iOS app
env:
EXPO_TV: 1
run: bun run ios:unsigned-build:tv ${{ github.event_name == 'pull_request' && '-- --verbose' || '' }}
- name: 📅 Set date tag
run: echo "DATE_TAG=$(date +%d-%m-%Y_%H-%M-%S)" >> $GITHUB_ENV
- name: 📤 Upload IPA artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: streamyfin-ios-tv-unsigned-ipa-${{ env.DATE_TAG }}
path: build/*.ipa
retention-days: 7
# Disabled for now - uncomment when ready to build iOS TV
# build-ios-tv:
# if: (!contains(github.event.head_commit.message, '[skip ci]') && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'streamyfin/streamyfin'))
# runs-on: macos-26
# name: 🍎 Build iOS IPA (TV)
# permissions:
# contents: read
#
# steps:
# - name: 📥 Checkout code
# uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
# with:
# ref: ${{ github.event.pull_request.head.sha || github.sha }}
# fetch-depth: 0
# submodules: recursive
# show-progress: false
#
# - name: 🍞 Setup Bun
# uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2.0.2
# with:
# bun-version: latest
#
# - name: 💾 Cache Bun dependencies
# uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
# with:
# path: ~/.bun/install/cache
# key: ${{ runner.os }}-bun-cache-${{ hashFiles('bun.lock') }}
# restore-keys: |
# ${{ runner.os }}-bun-cache
#
# - name: 📦 Install dependencies and reload submodules
# run: |
# bun install --frozen-lockfile
# bun run submodule-reload
#
# - name: 🛠️ Generate project files
# run: bun run prebuild:tv
#
# - name: 🔧 Setup Xcode
# uses: maxim-lobanov/setup-xcode@v1
# with:
# xcode-version: '26.0.1'
#
# - name: 🏗️ Setup EAS
# uses: expo/expo-github-action@main
# with:
# eas-version: latest
# token: ${{ secrets.EXPO_TOKEN }}
# eas-cache: true
#
# - name: 🚀 Build iOS app
# env:
# EXPO_TV: 1
# run: eas build -p ios --local --non-interactive
#
# - name: 📅 Set date tag
# run: echo "DATE_TAG=$(date +%d-%m-%Y_%H-%M-%S)" >> $GITHUB_ENV
#
# - name: 📤 Upload IPA artifact
# uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
# with:
# name: streamyfin-ios-tv-ipa-${{ env.DATE_TAG }}
# path: build-*.ipa
# retention-days: 7

View File

@@ -27,13 +27,13 @@ jobs:
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: 🏁 Initialize CodeQL
uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
with:
languages: ${{ matrix.language }}
queries: +security-extended,security-and-quality
- name: 🛠️ Autobuild
uses: github/codeql-action/autobuild@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
uses: github/codeql-action/autobuild@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
- name: 🧪 Perform CodeQL Analysis
uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5

1392
bun.lock

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,6 @@
"android:tv": "cross-env EXPO_TV=1 expo run:android",
"build:android:local": "cd android && cross-env NODE_ENV=production ./gradlew assembleRelease",
"ios:unsigned-build": "cross-env EXPO_TV=0 bun scripts/ios/build-ios.ts --production",
"ios:unsigned-build:tv": "cross-env EXPO_TV=1 bun scripts/ios/build-ios.ts --production",
"prepare": "husky",
"typecheck": "node scripts/typecheck.js",
"check": "biome check . --max-diagnostics 1000",
@@ -71,13 +70,13 @@
"expo-system-ui": "~6.0.9",
"expo-task-manager": "14.0.9",
"expo-web-browser": "~15.0.10",
"i18next": "^26.0.0",
"i18next": "^25.0.0",
"jotai": "2.16.2",
"lodash": "4.17.23",
"nativewind": "^2.0.11",
"patch-package": "^8.0.0",
"react": "19.1.0",
"react-dom": "19.1.0",
"react": "19.1.7",
"react-dom": "19.1.7",
"react-i18next": "17.0.8",
"react-native": "0.81.5",
"react-native-awesome-slider": "^2.9.0",
@@ -109,7 +108,7 @@
"react-native-uuid": "^2.0.3",
"react-native-volume-manager": "^2.0.8",
"react-native-web": "^0.21.0",
"react-native-worklets": "0.8.3",
"react-native-worklets": "0.5.1",
"sonner-native": "0.21.2",
"tailwindcss": "3.3.2",
"use-debounce": "^10.0.4",
@@ -125,10 +124,10 @@
"@types/react": "19.1.17",
"@types/react-test-renderer": "19.1.0",
"cross-env": "10.1.0",
"expo-doctor": "1.19.7",
"expo-doctor": "1.18.22",
"husky": "9.1.7",
"lint-staged": "17.0.5",
"react-test-renderer": "19.2.3",
"react-test-renderer": "19.2.6",
"typescript": "5.9.3"
},
"expo": {