From 64011f2f99951e3d167dea72327250740e8edce6 Mon Sep 17 00:00:00 2001 From: Leeksov <78694696+Leeksov@users.noreply.github.com> Date: Mon, 6 Apr 2026 10:00:53 +0300 Subject: [PATCH] Add publishing guide and secret-stripping scripts --- PUBLISHING.md | 87 ++++++++++++++++++++++++++++++++++++++++ scripts/check-secrets.sh | 53 ++++++++++++++++++++++++ scripts/strip-secrets.sh | 86 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 PUBLISHING.md create mode 100755 scripts/check-secrets.sh create mode 100755 scripts/strip-secrets.sh diff --git a/PUBLISHING.md b/PUBLISHING.md new file mode 100644 index 00000000..a60a8104 --- /dev/null +++ b/PUBLISHING.md @@ -0,0 +1,87 @@ +# Publishing Guide + +## Repository Structure + +| Repo | URL | Branch | Content | +|------|-----|--------|---------| +| **Public** | `github.com/GLEGram/GLEGram-iOS` | `main` | Clean code, no secrets | +| **Private** | `github.com/GLEGram/GLEGram-iOS-Private` | `main` | Full code with keys, codesigning | + +## Local Setup + +```bash +cd /Users/leeksov/Desktop/GLEGram-iOS-public + +# Remotes: +# origin → Public repo (GLEGram/GLEGram-iOS) +# private → Private repo (GLEGram/GLEGram-iOS-Private) + +# Branches: +# main → public code (no secrets) +# private → full code (with secrets) +``` + +## Daily Workflow + +### 1. Работа ведётся в ветке `private` + +```bash +git checkout private +# ... делаешь изменения ... +git add -A +git commit -m "Description of changes" +``` + +### 2. Пуш в приватный репо + +```bash +git push private private:main +``` + +### 3. Публикация в публичный репо + +```bash +# Переключиться на public ветку +git checkout main + +# Слить изменения из private +git merge private --no-commit + +# Очистить секреты перед коммитом +./scripts/strip-secrets.sh + +# Проверить что секретов нет +./scripts/check-secrets.sh + +# Закоммитить и запушить +git add -A +git commit -m "Description of changes" +git push origin main +``` + +## Файлы с секретами (автоматически очищаются strip-secrets.sh) + +| Файл | Что содержит | Публичная замена | +|------|-------------|-----------------| +| `Swiftgram/SGConfig/Sources/File.swift` | AES/HMAC ключи, API URL | `nil` значения | +| `build-system/ipa-build-configuration.json` | API ID, Hash, Team ID | `YOUR_*` placeholder | +| `build-system/glegram-appstore-configuration.json` | То же | `YOUR_*` placeholder | +| `build-system/real-codesigning/` | Сертификаты, профили | Пустые папки с README | + +## Скрипты + +### strip-secrets.sh — Удаление секретов перед публикацией + +Запускать ТОЛЬКО в ветке `main` перед коммитом в публичный репо. + +### check-secrets.sh — Проверка отсутствия секретов + +Запускать после strip-secrets.sh для верификации. Если находит секреты — НЕ пушить. + +## Правила + +1. **НИКОГДА** не пушить ветку `private` в `origin` (публичный репо) +2. **ВСЕГДА** запускать `strip-secrets.sh` перед пушем в публичный репо +3. **ВСЕГДА** проверять `check-secrets.sh` перед пушем +4. Новые секреты добавлять ТОЛЬКО в ветку `private` +5. При добавлении нового секретного файла — обновить `strip-secrets.sh` diff --git a/scripts/check-secrets.sh b/scripts/check-secrets.sh new file mode 100755 index 00000000..31768965 --- /dev/null +++ b/scripts/check-secrets.sh @@ -0,0 +1,53 @@ +#!/bin/zsh +# Verify no secrets remain before pushing to public repo + +set -e +cd "$(dirname "$0")/.." + +FOUND=0 + +echo "Checking for secrets..." + +# AES/HMAC keys +if grep -rq "V1wmSaHPBtfwGR7jHozwSkRVQrUVtvUMkb\|QpU3hDanhmp67LDTzL2tjzDuG4qIsCIFn3LMY" . --include="*.swift" --include="*.json" 2>/dev/null; then + echo "FAIL: AES/HMAC keys found!" + FOUND=1 +fi + +# GLEGram API credentials +if grep -rq "31339208\|b7917b274453f075e114f2fef86230d2" . --include="*.swift" --include="*.json" --include="*.bzl" 2>/dev/null; then + echo "FAIL: GLEGram API credentials found!" + FOUND=1 +fi + +# Team ID +if grep -rq "F8A8NWPL78" . --include="*.swift" --include="*.json" --include="*.bzl" 2>/dev/null; then + echo "FAIL: GLEGram Team ID found!" + FOUND=1 +fi + +# SSL pinning hashes +if grep -rq "brDmHiqwkhgPrFDmkcD2IsDUdKLZlyGjGkn0SOGNKFI" . --include="*.swift" --include="*.json" 2>/dev/null; then + echo "FAIL: SSL pinning hashes found!" + FOUND=1 +fi + +# glegram.site in code (not comments) +if grep -rn "glegram.site" . --include="*.swift" --include="*.json" 2>/dev/null | grep -v "//\|/\*\|e\.g\.\|example" | grep -q .; then + echo "FAIL: glegram.site domain in code (not comment)!" + FOUND=1 +fi + +# Real provisioning profiles +if find build-system/real-codesigning -name "*.mobileprovision" -o -name "*.p12" 2>/dev/null | grep -q .; then + echo "FAIL: Real provisioning profiles found!" + FOUND=1 +fi + +if [ "$FOUND" -eq 0 ]; then + echo "ALL CLEAR — safe to push to public repo." +else + echo "" + echo "BLOCKED — fix the issues above before pushing!" + exit 1 +fi diff --git a/scripts/strip-secrets.sh b/scripts/strip-secrets.sh new file mode 100755 index 00000000..bb89bc19 --- /dev/null +++ b/scripts/strip-secrets.sh @@ -0,0 +1,86 @@ +#!/bin/zsh +# Strip secrets before publishing to public repo +# Run ONLY on the 'main' branch + +set -e +cd "$(dirname "$0")/.." + +BRANCH=$(git branch --show-current) +if [ "$BRANCH" != "main" ]; then + echo "ERROR: Run this only on 'main' branch (current: $BRANCH)" + exit 1 +fi + +echo "Stripping secrets for public release..." + +# 1. SGConfig — remove keys +cat > Swiftgram/SGConfig/Sources/File.swift << 'SWIFT' +import Foundation +import BuildConfig + +public struct SGConfig: Codable { + public static let isBetaBuild: Bool = true + public var apiUrl: String = "https://api.swiftgram.app" + public var webappUrl: String = "https://my.swiftgram.app" + public var botUsername: String = "SwiftgramBot" + public var publicKey: String? + public var iaps: [String] = [] + public var supportersApiUrl: String? = nil + public var supportersAesKey: String? = nil + public var supportersHmacKey: String? = nil + public var supportersPinnedCertHashes: [String] = [] + public var demoLoginBackendUrl: String? = nil + public var demoLoginPhonePrefix: String? = nil +} + +private func parseSGConfig(_ jsonString: String) -> SGConfig { + let jsonData = Data(jsonString.utf8) + let decoder = JSONDecoder() + decoder.keyDecodingStrategy = .convertFromSnakeCase + return (try? decoder.decode(SGConfig.self, from: jsonData)) ?? SGConfig() +} + +private let baseAppBundleId = Bundle.main.bundleIdentifier! +private let buildConfig = BuildConfig(baseAppBundleId: baseAppBundleId) +public let SG_CONFIG: SGConfig = parseSGConfig(buildConfig.sgConfig) +public let SG_API_WEBAPP_URL_PARSED = URL(string: SG_CONFIG.webappUrl)! +SWIFT +echo " Stripped: SGConfig" + +# 2. Build configs — replace with templates +for cfg in build-system/ipa-build-configuration.json build-system/glegram-appstore-configuration.json; do + cat > "$cfg" << 'JSON' +{ + "bundle_id": "com.example.GLEGram", + "api_id": "YOUR_API_ID", + "api_hash": "YOUR_API_HASH", + "team_id": "YOUR_TEAM_ID", + "app_center_id": "0", + "is_internal_build": "false", + "is_appstore_build": "true", + "appstore_id": "0", + "app_specific_url_scheme": "tg", + "premium_iap_product_id": "", + "enable_siri": false, + "enable_icloud": false, + "sg_config": "" +} +JSON +done +echo " Stripped: build configs" + +# 3. Real codesigning — empty +rm -rf build-system/real-codesigning/certs/*.p12 build-system/real-codesigning/certs/*.cer 2>/dev/null +rm -rf build-system/real-codesigning/profiles/*.mobileprovision 2>/dev/null +mkdir -p build-system/real-codesigning/certs build-system/real-codesigning/profiles +echo "# Add your certificates here" > build-system/real-codesigning/certs/README.md +echo "# Add your provisioning profiles here" > build-system/real-codesigning/profiles/README.md +echo " Stripped: codesigning" + +# 4. Remove binaries +rm -f build-input/bazel-* scripts/Telegram 2>/dev/null +rm -rf build/ 2>/dev/null +echo " Stripped: binaries" + +echo "" +echo "Done. Run ./scripts/check-secrets.sh before committing."