9 Commits

Author SHA1 Message Date
Devin Bot
a28239cf60 chore: release v1.0.9 2026-10-23 17:07:28 -07:00
Devin Bot
966115c456 added logo img 2026-10-23 15:38:27 -07:00
2c0cc5c933 Merge branch 'main' of https://gitlab.com/vyla-entertainment/go 2026-10-03 12:16:10 -07:00
0e385aae9e chore: release v1.0.8 2026-10-03 12:15:18 -07:00
cd18f09142 Android TV build support 2026-09-26 09:41:32 -04:00
bd321520c9 chore: release v1.0.7 2026-09-16 18:47:31 -07:00
c869101923 chore: release v1.0.6 2026-09-09 14:48:05 -07:00
feccab9aa1 update 2026-09-09 14:39:54 -07:00
82c91334f6 fixed security issues, ty zstrike 2026-09-09 14:36:37 -07:00
10 changed files with 125 additions and 12 deletions

BIN
assets/logos/white_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -20,33 +20,91 @@ function cleanBuildDir() {
fs.mkdirSync(BUILD_DIR, { recursive: true }); fs.mkdirSync(BUILD_DIR, { recursive: true });
} }
function removeSensitiveFiles(dir) {
if (!fs.existsSync(dir)) return;
const gitDir = path.join(dir, '.git');
if (fs.existsSync(gitDir)) {
fs.rmSync(gitDir, { recursive: true, force: true });
}
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
if (entry.name === '.git') {
fs.rmSync(fullPath, { recursive: true, force: true });
} else {
removeSensitiveFiles(fullPath);
}
} else {
if (
entry.name.startsWith('.env') ||
entry.name.endsWith('.key') ||
entry.name.endsWith('.pem') ||
entry.name === 'credentials.json' ||
entry.name === '.gitlab-ci.yml'
) {
fs.rmSync(fullPath, { force: true });
}
}
}
}
function clonePrivateRepo(repoConfig, targetDir) { function clonePrivateRepo(repoConfig, targetDir) {
if (fs.existsSync(targetDir)) { if (fs.existsSync(targetDir)) {
fs.rmSync(targetDir, { recursive: true, force: true }); fs.rmSync(targetDir, { recursive: true, force: true });
} }
const token = process.env.GITLAB_TOKEN || process.env.VYLA_GITLAB_TOKEN; const token = process.env.GITLAB_TOKEN || process.env.VYLA_GITLAB_TOKEN;
const auth = token ? `oauth2:${token}@` : ''; const repoUrl = `https://gitlab.com/${GITLAB_GROUP}/${repoConfig.name}.git`;
const repoUrl = `https://${auth}gitlab.com/${GITLAB_GROUP}/${repoConfig.name}.git`;
execSync(`git clone --depth 1 --branch ${repoConfig.branch} ${repoUrl} ${targetDir}`, { stdio: 'inherit' }); try {
if (token) {
const authHeader = Buffer.from(`oauth2:${token.trim()}`).toString('base64');
execSync(
`git -c "http.extraHeader=Authorization: Basic ${authHeader}" clone --depth 1 --branch ${repoConfig.branch} ${repoUrl} "${targetDir}"`,
{ stdio: 'inherit' }
);
} else {
execSync(
`git clone --depth 1 --branch ${repoConfig.branch} ${repoUrl} "${targetDir}"`,
{ stdio: 'inherit' }
);
}
} finally {
const gitFolder = path.join(targetDir, '.git');
if (fs.existsSync(gitFolder)) {
fs.rmSync(gitFolder, { recursive: true, force: true });
}
}
} }
async function build() { async function build() {
cleanBuildDir(); cleanBuildDir();
for (const [key, config] of Object.entries(REPO_CONFIG)) { for (const [key, config] of Object.entries(REPO_CONFIG)) {
const targetDir = path.join(__dirname, key); const targetDir = path.join(__dirname, key);
console.log(`Cloning ${config.name}...`);
clonePrivateRepo(config, targetDir); clonePrivateRepo(config, targetDir);
console.log(`Installing production dependencies for ${config.name}...`);
execSync('npm install --omit=dev', { cwd: targetDir, stdio: 'inherit' }); execSync('npm install --omit=dev', { cwd: targetDir, stdio: 'inherit' });
removeSensitiveFiles(targetDir);
} }
const zip = new AdmZip(); const zip = new AdmZip();
const configDir = path.join(__dirname, 'config'); const configDir = path.join(__dirname, 'config');
if (fs.existsSync(configDir)) { if (fs.existsSync(configDir)) {
removeSensitiveFiles(configDir);
zip.addLocalFolder(configDir, 'config'); zip.addLocalFolder(configDir, 'config');
} }
for (const repo of REPOS) { for (const repo of REPOS) {
const srcRepo = path.join(__dirname, repo); const srcRepo = path.join(__dirname, repo);
removeSensitiveFiles(srcRepo);
zip.addLocalFolder(srcRepo, repo); zip.addLocalFolder(srcRepo, repo);
} }
@@ -54,6 +112,20 @@ async function build() {
if (fs.existsSync(zipPath)) fs.rmSync(zipPath, { force: true }); if (fs.existsSync(zipPath)) fs.rmSync(zipPath, { force: true });
zip.writeZip(zipPath); zip.writeZip(zipPath);
const verificationZip = new AdmZip(zipPath);
const leakedEntries = verificationZip.getEntries().filter(e =>
e.entryName.includes('.git/') ||
e.entryName.includes('.git\\') ||
e.entryName.startsWith('.env') ||
e.entryName.includes('/.env') ||
e.entryName.endsWith('config/encrypted-credentials.json')
);
if (leakedEntries.length > 0) {
fs.rmSync(zipPath, { force: true });
throw new Error(`SECURITY ABORT: Archive contains forbidden files:\n${leakedEntries.map(e => e.entryName).join('\n')}`);
}
const hash = crypto.createHash('sha256'); const hash = crypto.createHash('sha256');
hash.update(fs.readFileSync(zipPath)); hash.update(fs.readFileSync(zipPath));
const checksum = hash.digest('hex'); const checksum = hash.digest('hex');
@@ -68,6 +140,8 @@ async function build() {
for (const repo of REPOS) { for (const repo of REPOS) {
fs.rmSync(path.join(__dirname, repo), { recursive: true, force: true }); fs.rmSync(path.join(__dirname, repo), { recursive: true, force: true });
} }
console.log('Build complete and verified clean.');
} }
build().catch(err => { build().catch(err => {

Submodule frontend deleted from e23979cbe0

View File

@@ -1,6 +1,6 @@
{ {
"name": "vyla-go", "name": "vyla-go",
"version": "1.0.3", "version": "1.0.9",
"description": "Vyla Go Mobile Launcher", "description": "Vyla Go Mobile Launcher",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {
@@ -16,11 +16,11 @@
"@tauri-apps/plugin-opener": "^2.0.0", "@tauri-apps/plugin-opener": "^2.0.0",
"@tauri-apps/plugin-process": "^2.0.0", "@tauri-apps/plugin-process": "^2.0.0",
"@tauri-apps/plugin-shell": "^2.0.0", "@tauri-apps/plugin-shell": "^2.0.0",
"@vyla-entertainment/sdk": "^1.11.0", "@vyla-entertainment/sdk": "^1.18.0",
"adm-zip": "^0.6.0", "adm-zip": "^0.6.0",
"express": "^4.19.2" "express": "^4.19.2"
}, },
"devDependencies": { "devDependencies": {
"@tauri-apps/cli": "^2.0.0" "@tauri-apps/cli": "^2.0.0"
} }
} }

View File

@@ -32,11 +32,21 @@ function incrementVersion() {
function gitCommitAndTag(version) { function gitCommitAndTag(version) {
try { try {
execSync('git add package.json src-tauri/tauri.conf.json', { stdio: 'inherit' }); execSync('git add package.json src-tauri/tauri.conf.json', { stdio: 'inherit' });
execSync(`git commit -m "chore: release ${version}"`, { stdio: 'inherit' }); try {
execSync(`git tag -a ${version} -m "Release ${version}"`, { stdio: 'inherit' }); execSync(`git commit -m "chore: release ${version}"`, { stdio: 'inherit' });
} catch (_) {
console.log('Working tree clean, skipping commit.');
}
try {
execSync(`git tag -a ${version} -m "Release ${version}"`, { stdio: 'inherit' });
} catch (_) {
console.log(`Tag ${version} already exists locally.`);
}
execSync('git push origin HEAD --tags', { stdio: 'inherit' }); execSync('git push origin HEAD --tags', { stdio: 'inherit' });
} catch (e) { } catch (e) {
console.warn('Git operations failed (non-fatal):', e.message); console.warn('Git push failed (will fallback to GitLab API ref):', e.message);
} }
} }
@@ -94,6 +104,11 @@ async function createRelease(version, assets) {
const payload = assets.payload; const payload = assets.payload;
const manifest = assets.manifest; const manifest = assets.manifest;
let branch = 'main';
try {
branch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim() || 'main';
} catch (_) { }
const description = [ const description = [
`## Automated Release ${version}`, `## Automated Release ${version}`,
'', '',
@@ -110,6 +125,7 @@ async function createRelease(version, assets) {
const body = JSON.stringify({ const body = JSON.stringify({
name: `Vyla Go Release ${version}`, name: `Vyla Go Release ${version}`,
tag_name: tag, tag_name: tag,
ref: branch,
description, description,
assets: { assets: {
links: [ links: [

View File

@@ -13,6 +13,14 @@ val tauriProperties = Properties().apply {
} }
} }
configurations.all {
resolutionStrategy {
force("com.fasterxml.jackson.core:jackson-databind:2.13.5")
force("com.fasterxml.jackson.core:jackson-core:2.13.5")
force("com.fasterxml.jackson.core:jackson-annotations:2.13.5")
}
}
android { android {
compileSdk = 36 compileSdk = 36
namespace = "com.vyla.go" namespace = "com.vyla.go"
@@ -23,6 +31,9 @@ android {
targetSdk = 36 targetSdk = 36
versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt() versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0") versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
ndk {
abiFilters.addAll(listOf("arm64-v8a", "armeabi-v7a", "x86_64"))
}
} }
signingConfigs { signingConfigs {
create("release") { create("release") {
@@ -59,6 +70,11 @@ android {
useLegacyPackaging = true useLegacyPackaging = true
} }
} }
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
isCoreLibraryDesugaringEnabled = true
}
} }
rust { rust {
@@ -74,6 +90,7 @@ dependencies {
testImplementation("junit:junit:4.13.2") testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.4") androidTestImplementation("androidx.test.ext:junit:1.1.4")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0")
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4")
} }
apply(from = "tauri.build.gradle.kts") apply(from = "tauri.build.gradle.kts")

View File

@@ -2,15 +2,19 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
<uses-feature android:name="android.software.leanback" android:required="false" />
<application <application
android:label="@string/app_name" android:label="@string/app_name"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:banner="@drawable/tv_banner"
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config" android:networkSecurityConfig="@xml/network_security_config"
android:largeHeap="true" android:largeHeap="true"
android:extractNativeLibs="true" android:extractNativeLibs="true"
android:supportsRtl="true"
android:theme="@style/Theme.vyla_go"> android:theme="@style/Theme.vyla_go">
<activity <activity
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
@@ -22,6 +26,10 @@
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity> </activity>
</application> </application>
</manifest> </manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -21,7 +21,6 @@ open class BuildTask : DefaultTask() {
runTauriCli(executable) runTauriCli(executable)
} catch (e: Exception) { } catch (e: Exception) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) { if (Os.isFamily(Os.FAMILY_WINDOWS)) {
// Try different Windows-specific extensions
val fallbacks = listOf( val fallbacks = listOf(
"$executable.exe", "$executable.exe",
"$executable.cmd", "$executable.cmd",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "Vyla Go", "productName": "Vyla Go",
"version": "1.0.3", "version": "1.0.9",
"identifier": "com.vyla.go", "identifier": "com.vyla.go",
"build": { "build": {
"beforeDevCommand": "", "beforeDevCommand": "",