biucingcli 0.9.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- biucingcli/__init__.py +5 -0
- biucingcli/cli.py +849 -0
- biucingcli/template_data/android/template/.editorconfig +9 -0
- biucingcli/template_data/android/template/.gitignore +26 -0
- biucingcli/template_data/android/template/.mise.toml +3 -0
- biucingcli/template_data/android/template/Brewfile +6 -0
- biucingcli/template_data/android/template/Makefile +103 -0
- biucingcli/template_data/android/template/README.md +163 -0
- biucingcli/template_data/android/template/app/build.gradle.kts +178 -0
- biucingcli/template_data/android/template/app/proguard-rules.pro +1 -0
- biucingcli/template_data/android/template/app/src/androidTest/java/app/HomeRouteUiTest.kt +21 -0
- biucingcli/template_data/android/template/app/src/main/AndroidManifest.xml +18 -0
- biucingcli/template_data/android/template/app/src/main/java/app/MainActivity.kt +36 -0
- biucingcli/template_data/android/template/app/src/main/res/values/strings.xml +4 -0
- biucingcli/template_data/android/template/app/src/main/res/values/themes.xml +8 -0
- biucingcli/template_data/android/template/app/src/test/java/app/AppSmokeTest.kt +19 -0
- biucingcli/template_data/android/template/build.gradle.kts +27 -0
- biucingcli/template_data/android/template/core/designsystem/build.gradle.kts +33 -0
- biucingcli/template_data/android/template/core/designsystem/src/main/java/designsystem/Components.kt +75 -0
- biucingcli/template_data/android/template/core/designsystem/src/main/java/designsystem/DesignTokens.kt +23 -0
- biucingcli/template_data/android/template/core/designsystem/src/main/java/designsystem/Theme.kt +110 -0
- biucingcli/template_data/android/template/core/model/build.gradle.kts +26 -0
- biucingcli/template_data/android/template/core/model/src/main/java/model/Greeting.kt +6 -0
- biucingcli/template_data/android/template/core/model/src/test/java/model/GreetingTest.kt +16 -0
- biucingcli/template_data/android/template/core/network/build.gradle.kts +26 -0
- biucingcli/template_data/android/template/core/network/src/main/java/network/AppEnvironment.kt +17 -0
- biucingcli/template_data/android/template/core/testing/build.gradle.kts +27 -0
- biucingcli/template_data/android/template/core/testing/src/main/java/testing/FakeAppEnvironmentProvider.kt +13 -0
- biucingcli/template_data/android/template/docs/release-delivery.md +68 -0
- biucingcli/template_data/android/template/docs/release-signing.properties.example +20 -0
- biucingcli/template_data/android/template/fastlane/.env.example +22 -0
- biucingcli/template_data/android/template/fastlane/Appfile +1 -0
- biucingcli/template_data/android/template/fastlane/Fastfile +121 -0
- biucingcli/template_data/android/template/feature/home/build.gradle.kts +35 -0
- biucingcli/template_data/android/template/feature/home/src/main/java/home/HomeRoute.kt +38 -0
- biucingcli/template_data/android/template/feature/settings/build.gradle.kts +34 -0
- biucingcli/template_data/android/template/feature/settings/src/main/java/settings/SettingsRoute.kt +35 -0
- biucingcli/template_data/android/template/gradle/libs.versions.toml +35 -0
- biucingcli/template_data/android/template/gradle/verification-metadata.xml +3462 -0
- biucingcli/template_data/android/template/gradle/wrapper/gradle-wrapper.jar +0 -0
- biucingcli/template_data/android/template/gradle/wrapper/gradle-wrapper.jar.sha256 +1 -0
- biucingcli/template_data/android/template/gradle/wrapper/gradle-wrapper.properties +10 -0
- biucingcli/template_data/android/template/gradle.properties +4 -0
- biucingcli/template_data/android/template/gradlew +252 -0
- biucingcli/template_data/android/template/gradlew.bat +94 -0
- biucingcli/template_data/android/template/scripts/artifact-info +11 -0
- biucingcli/template_data/android/template/scripts/bootstrap +17 -0
- biucingcli/template_data/android/template/scripts/doctor +133 -0
- biucingcli/template_data/android/template/scripts/setup-android-sdk +23 -0
- biucingcli/template_data/android/template/scripts/sync-gradle-wrapper +19 -0
- biucingcli/template_data/android/template/scripts/verify-gradle-supply-chain +61 -0
- biucingcli/template_data/android/template/scripts/verify-release-artifact +104 -0
- biucingcli/template_data/android/template/settings.gradle.kts +25 -0
- biucingcli/template_data/android/template.json +146 -0
- biucingcli/template_data/apple/template/.gitignore +28 -0
- biucingcli/template_data/apple/template/.mise.toml +4 -0
- biucingcli/template_data/apple/template/.swiftformat +10 -0
- biucingcli/template_data/apple/template/.swiftlint.yml +33 -0
- biucingcli/template_data/apple/template/App/Config/ProjectDescriptionHelpers/Module.swift +6 -0
- biucingcli/template_data/apple/template/App/Config/XCConfig/Base.xcconfig +4 -0
- biucingcli/template_data/apple/template/App/Project.swift +66 -0
- biucingcli/template_data/apple/template/App/Targets/App/Resources/.gitkeep +1 -0
- biucingcli/template_data/apple/template/App/Targets/App/Sources/AppEntry.swift +9 -0
- biucingcli/template_data/apple/template/App/Targets/App/Sources/HomeView.swift +18 -0
- biucingcli/template_data/apple/template/App/Targets/App/Sources/HomeViewModel.swift +38 -0
- biucingcli/template_data/apple/template/App/Targets/AppTests/Sources/AppTests.swift +59 -0
- biucingcli/template_data/apple/template/Brewfile +8 -0
- biucingcli/template_data/apple/template/Makefile +128 -0
- biucingcli/template_data/apple/template/Packages/AppServices/Package.swift +20 -0
- biucingcli/template_data/apple/template/Packages/AppServices/Sources/AppServices/StarterMetadata.swift +52 -0
- biucingcli/template_data/apple/template/Packages/DesignSystem/Package.swift +20 -0
- biucingcli/template_data/apple/template/Packages/DesignSystem/Sources/DesignSystem/Theme.swift +8 -0
- biucingcli/template_data/apple/template/README.md +133 -0
- biucingcli/template_data/apple/template/Tuist.swift +8 -0
- biucingcli/template_data/apple/template/Workspace.swift +11 -0
- biucingcli/template_data/apple/template/docs/release-delivery.md +55 -0
- biucingcli/template_data/apple/template/fastlane/.env.example +20 -0
- biucingcli/template_data/apple/template/fastlane/Appfile +3 -0
- biucingcli/template_data/apple/template/fastlane/Fastfile +126 -0
- biucingcli/template_data/apple/template/fastlane/Matchfile +7 -0
- biucingcli/template_data/apple/template/scripts/bootstrap +9 -0
- biucingcli/template_data/apple/template/scripts/doctor +163 -0
- biucingcli/template_data/apple/template/scripts/setup-xcode +6 -0
- biucingcli/template_data/apple/template/scripts/test-destination +42 -0
- biucingcli/template_data/apple/template/scripts/verify-release-identity +88 -0
- biucingcli/template_data/apple/template.json +110 -0
- biucingcli/template_data/frontend/template/.dockerignore +8 -0
- biucingcli/template_data/frontend/template/.env.example +1 -0
- biucingcli/template_data/frontend/template/.gitignore +7 -0
- biucingcli/template_data/frontend/template/.npmrc +1 -0
- biucingcli/template_data/frontend/template/.prettierignore +2 -0
- biucingcli/template_data/frontend/template/.prettierrc.json +4 -0
- biucingcli/template_data/frontend/template/Dockerfile +25 -0
- biucingcli/template_data/frontend/template/Dockerfile.dev +35 -0
- biucingcli/template_data/frontend/template/Dockerfile.dev.full +40 -0
- biucingcli/template_data/frontend/template/Makefile +137 -0
- biucingcli/template_data/frontend/template/README.md +146 -0
- biucingcli/template_data/frontend/template/compose.dev.yaml +29 -0
- biucingcli/template_data/frontend/template/eslint.config.js +27 -0
- biucingcli/template_data/frontend/template/index.html +12 -0
- biucingcli/template_data/frontend/template/nginx.conf +11 -0
- biucingcli/template_data/frontend/template/package.json +50 -0
- biucingcli/template_data/frontend/template/playwright.production.config.ts +21 -0
- biucingcli/template_data/frontend/template/playwright.smoke.config.ts +19 -0
- biucingcli/template_data/frontend/template/pnpm-lock.yaml +4054 -0
- biucingcli/template_data/frontend/template/public/.gitkeep +1 -0
- biucingcli/template_data/frontend/template/scripts/browser-smoke-production +55 -0
- biucingcli/template_data/frontend/template/scripts/doctor +46 -0
- biucingcli/template_data/frontend/template/src/App.test.tsx +18 -0
- biucingcli/template_data/frontend/template/src/App.tsx +5 -0
- biucingcli/template_data/frontend/template/src/components/MetricCard.tsx +14 -0
- biucingcli/template_data/frontend/template/src/components/TaskPanel.tsx +32 -0
- biucingcli/template_data/frontend/template/src/config/env.ts +3 -0
- biucingcli/template_data/frontend/template/src/hooks/useProjectOverview.ts +24 -0
- biucingcli/template_data/frontend/template/src/index.css +208 -0
- biucingcli/template_data/frontend/template/src/main.tsx +11 -0
- biucingcli/template_data/frontend/template/src/pages/HomePage.tsx +60 -0
- biucingcli/template_data/frontend/template/src/router/AppRouter.tsx +14 -0
- biucingcli/template_data/frontend/template/src/services/api/client.ts +33 -0
- biucingcli/template_data/frontend/template/src/services/projectOverview.ts +39 -0
- biucingcli/template_data/frontend/template/src/test/setup.ts +1 -0
- biucingcli/template_data/frontend/template/src/types/projectOverview.ts +22 -0
- biucingcli/template_data/frontend/template/src/vite-env.d.ts +9 -0
- biucingcli/template_data/frontend/template/tests/browser-smoke.spec.ts +16 -0
- biucingcli/template_data/frontend/template/tests/production-browser-smoke.spec.ts +22 -0
- biucingcli/template_data/frontend/template/tsconfig.json +21 -0
- biucingcli/template_data/frontend/template/vite.config.ts +12 -0
- biucingcli/template_data/frontend/template.json +81 -0
- biucingcli/template_data/harmonyos/template/.gitignore +21 -0
- biucingcli/template_data/harmonyos/template/.mise.toml +2 -0
- biucingcli/template_data/harmonyos/template/AppScope/app.json5 +10 -0
- biucingcli/template_data/harmonyos/template/AppScope/resources/base/element/string.json +8 -0
- biucingcli/template_data/harmonyos/template/AppScope/resources/base/media/background.svg +3 -0
- biucingcli/template_data/harmonyos/template/AppScope/resources/base/media/foreground.svg +4 -0
- biucingcli/template_data/harmonyos/template/AppScope/resources/base/media/layered_image.json +6 -0
- biucingcli/template_data/harmonyos/template/Makefile +106 -0
- biucingcli/template_data/harmonyos/template/README.md +152 -0
- biucingcli/template_data/harmonyos/template/build-profile.json5 +36 -0
- biucingcli/template_data/harmonyos/template/code-linter.json5 +12 -0
- biucingcli/template_data/harmonyos/template/docs/release-signing.local.properties.example +14 -0
- biucingcli/template_data/harmonyos/template/entry/build-profile.json5 +9 -0
- biucingcli/template_data/harmonyos/template/entry/hvigorfile.ts +6 -0
- biucingcli/template_data/harmonyos/template/entry/oh-package.json5 +9 -0
- biucingcli/template_data/harmonyos/template/entry/src/main/ets/core/config/AppConfig.ets +10 -0
- biucingcli/template_data/harmonyos/template/entry/src/main/ets/core/designsystem/Tokens.ets +28 -0
- biucingcli/template_data/harmonyos/template/entry/src/main/ets/entryability/EntryAbility.ets +29 -0
- biucingcli/template_data/harmonyos/template/entry/src/main/ets/pages/Index.ets +47 -0
- biucingcli/template_data/harmonyos/template/entry/src/main/ets/pages/Settings.ets +96 -0
- biucingcli/template_data/harmonyos/template/entry/src/main/module.json5 +34 -0
- biucingcli/template_data/harmonyos/template/entry/src/main/resources/base/element/color.json +24 -0
- biucingcli/template_data/harmonyos/template/entry/src/main/resources/base/element/string.json +12 -0
- biucingcli/template_data/harmonyos/template/entry/src/main/resources/base/media/app_icon.svg +5 -0
- biucingcli/template_data/harmonyos/template/entry/src/main/resources/base/profile/main_pages.json +6 -0
- biucingcli/template_data/harmonyos/template/entry/src/test/List.test.ets +11 -0
- biucingcli/template_data/harmonyos/template/hvigor/hvigor-config.json5 +8 -0
- biucingcli/template_data/harmonyos/template/hvigorfile.ts +6 -0
- biucingcli/template_data/harmonyos/template/oh-package-lock.json5 +19 -0
- biucingcli/template_data/harmonyos/template/oh-package.json5 +13 -0
- biucingcli/template_data/harmonyos/template/scripts/artifact-info +31 -0
- biucingcli/template_data/harmonyos/template/scripts/bootstrap +38 -0
- biucingcli/template_data/harmonyos/template/scripts/doctor +147 -0
- biucingcli/template_data/harmonyos/template/scripts/lint +105 -0
- biucingcli/template_data/harmonyos/template/scripts/release-build +199 -0
- biucingcli/template_data/harmonyos/template/scripts/release-preflight +109 -0
- biucingcli/template_data/harmonyos/template/scripts/test +28 -0
- biucingcli/template_data/harmonyos/template/scripts/verify-release-artifact +173 -0
- biucingcli/template_data/harmonyos/template/scripts/verify-supply-chain +70 -0
- biucingcli/template_data/harmonyos/template.json +134 -0
- biucingcli/template_data/microservice/template/.air.toml +11 -0
- biucingcli/template_data/microservice/template/.dockerignore +5 -0
- biucingcli/template_data/microservice/template/.gitignore +4 -0
- biucingcli/template_data/microservice/template/.mise.toml +3 -0
- biucingcli/template_data/microservice/template/Brewfile +7 -0
- biucingcli/template_data/microservice/template/Dockerfile +44 -0
- biucingcli/template_data/microservice/template/Dockerfile.dev +50 -0
- biucingcli/template_data/microservice/template/Makefile +145 -0
- biucingcli/template_data/microservice/template/README.md +191 -0
- biucingcli/template_data/microservice/template/api/buf.gen.yaml +11 -0
- biucingcli/template_data/microservice/template/api/buf.yaml +11 -0
- biucingcli/template_data/microservice/template/api/proto/service/v1/service.proto +18 -0
- biucingcli/template_data/microservice/template/cmd/server/main.go +81 -0
- biucingcli/template_data/microservice/template/compose.dev.yaml +49 -0
- biucingcli/template_data/microservice/template/configs/config.yaml +18 -0
- biucingcli/template_data/microservice/template/deploy/compose.yaml +35 -0
- biucingcli/template_data/microservice/template/deploy/otel-collector.yaml +15 -0
- biucingcli/template_data/microservice/template/go.mod +53 -0
- biucingcli/template_data/microservice/template/go.sum +138 -0
- biucingcli/template_data/microservice/template/internal/config/config.go +112 -0
- biucingcli/template_data/microservice/template/internal/config/config_test.go +92 -0
- biucingcli/template_data/microservice/template/internal/handler/health.go +25 -0
- biucingcli/template_data/microservice/template/internal/handler/ping.go +25 -0
- biucingcli/template_data/microservice/template/internal/model/health.go +8 -0
- biucingcli/template_data/microservice/template/internal/model/ping.go +7 -0
- biucingcli/template_data/microservice/template/internal/repository/.gitkeep +1 -0
- biucingcli/template_data/microservice/template/internal/router/router.go +26 -0
- biucingcli/template_data/microservice/template/internal/runtime/server.go +116 -0
- biucingcli/template_data/microservice/template/internal/runtime/server_test.go +161 -0
- biucingcli/template_data/microservice/template/internal/service/health.go +26 -0
- biucingcli/template_data/microservice/template/internal/service/ping.go +23 -0
- biucingcli/template_data/microservice/template/internal/telemetry/telemetry.go +56 -0
- biucingcli/template_data/microservice/template/internal/transport/grpc.go +51 -0
- biucingcli/template_data/microservice/template/internal/transport/ping.go +28 -0
- biucingcli/template_data/microservice/template/scripts/bootstrap +29 -0
- biucingcli/template_data/microservice/template/scripts/doctor +115 -0
- biucingcli/template_data/microservice/template/tests/server_test.go +153 -0
- biucingcli/template_data/microservice/template.json +114 -0
- biucingcli/template_data/web-service/template/.air.toml +11 -0
- biucingcli/template_data/web-service/template/.dockerignore +5 -0
- biucingcli/template_data/web-service/template/.gitignore +5 -0
- biucingcli/template_data/web-service/template/.mise.toml +2 -0
- biucingcli/template_data/web-service/template/Brewfile +5 -0
- biucingcli/template_data/web-service/template/Dockerfile +41 -0
- biucingcli/template_data/web-service/template/Dockerfile.dev +45 -0
- biucingcli/template_data/web-service/template/Makefile +113 -0
- biucingcli/template_data/web-service/template/README.md +164 -0
- biucingcli/template_data/web-service/template/cmd/server/main.go +50 -0
- biucingcli/template_data/web-service/template/compose.dev.yaml +28 -0
- biucingcli/template_data/web-service/template/compose.yaml +14 -0
- biucingcli/template_data/web-service/template/configs/config.yaml +10 -0
- biucingcli/template_data/web-service/template/go.mod +36 -0
- biucingcli/template_data/web-service/template/go.sum +89 -0
- biucingcli/template_data/web-service/template/internal/config/config.go +84 -0
- biucingcli/template_data/web-service/template/internal/config/config_test.go +88 -0
- biucingcli/template_data/web-service/template/internal/handler/health.go +25 -0
- biucingcli/template_data/web-service/template/internal/handler/ping.go +25 -0
- biucingcli/template_data/web-service/template/internal/handler/user.go +40 -0
- biucingcli/template_data/web-service/template/internal/model/health.go +6 -0
- biucingcli/template_data/web-service/template/internal/model/ping.go +7 -0
- biucingcli/template_data/web-service/template/internal/model/user.go +7 -0
- biucingcli/template_data/web-service/template/internal/repository/.gitkeep +1 -0
- biucingcli/template_data/web-service/template/internal/repository/user.go +37 -0
- biucingcli/template_data/web-service/template/internal/router/router.go +28 -0
- biucingcli/template_data/web-service/template/internal/runtime/server.go +76 -0
- biucingcli/template_data/web-service/template/internal/runtime/server_test.go +139 -0
- biucingcli/template_data/web-service/template/internal/service/health.go +22 -0
- biucingcli/template_data/web-service/template/internal/service/ping.go +23 -0
- biucingcli/template_data/web-service/template/internal/service/user.go +27 -0
- biucingcli/template_data/web-service/template/scripts/bootstrap +23 -0
- biucingcli/template_data/web-service/template/scripts/doctor +83 -0
- biucingcli/template_data/web-service/template/tests/server_test.go +160 -0
- biucingcli/template_data/web-service/template.json +88 -0
- biucingcli/template_data/worker/template/.dockerignore +3 -0
- biucingcli/template_data/worker/template/.gitignore +2 -0
- biucingcli/template_data/worker/template/.mise.toml +2 -0
- biucingcli/template_data/worker/template/Brewfile +1 -0
- biucingcli/template_data/worker/template/Dockerfile +19 -0
- biucingcli/template_data/worker/template/Dockerfile.dev +9 -0
- biucingcli/template_data/worker/template/Makefile +105 -0
- biucingcli/template_data/worker/template/README.md +164 -0
- biucingcli/template_data/worker/template/cmd/worker/main.go +41 -0
- biucingcli/template_data/worker/template/compose.dev.yaml +29 -0
- biucingcli/template_data/worker/template/configs/config.json +11 -0
- biucingcli/template_data/worker/template/go.mod +3 -0
- biucingcli/template_data/worker/template/go.sum +1 -0
- biucingcli/template_data/worker/template/internal/config/config.go +108 -0
- biucingcli/template_data/worker/template/internal/config/config_test.go +86 -0
- biucingcli/template_data/worker/template/internal/runtime/runner.go +199 -0
- biucingcli/template_data/worker/template/internal/runtime/runner_test.go +215 -0
- biucingcli/template_data/worker/template/internal/task/heartbeat.go +19 -0
- biucingcli/template_data/worker/template/scripts/bootstrap +6 -0
- biucingcli/template_data/worker/template/scripts/doctor +41 -0
- biucingcli/template_data/worker/template/tests/worker_test.go +44 -0
- biucingcli/template_data/worker/template.json +100 -0
- biucingcli/templates.py +902 -0
- biucingcli-0.9.1.dist-info/METADATA +204 -0
- biucingcli-0.9.1.dist-info/RECORD +269 -0
- biucingcli-0.9.1.dist-info/WHEEL +5 -0
- biucingcli-0.9.1.dist-info/entry_points.txt +2 -0
- biucingcli-0.9.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
SHELL := /bin/zsh
|
|
2
|
+
|
|
3
|
+
APP_NAME={{PROJECT_NAME}}
|
|
4
|
+
WORKTREE_ROOT ?= $(shell git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
5
|
+
WORKTREE_LABEL ?= $(shell basename "$(WORKTREE_ROOT)" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-' | sed 's/^-//; s/-$$//')
|
|
6
|
+
WORKTREE_ID ?= $(shell printf '%s' "$(WORKTREE_ROOT)" | shasum | cut -c1-8)
|
|
7
|
+
WORKTREE_SLUG ?= $(APP_NAME)-$(WORKTREE_ID)
|
|
8
|
+
DERIVED_DATA_PATH ?= $(WORKTREE_ROOT)/DerivedData/$(WORKTREE_ID)
|
|
9
|
+
SWIFTPM_BUILD_PATH ?= $(WORKTREE_ROOT)/.build/$(WORKTREE_ID)
|
|
10
|
+
TUIST_HOME ?= $(WORKTREE_ROOT)/.cache/tuist/$(WORKTREE_ID)/home
|
|
11
|
+
TUIST_XDG_CACHE_HOME ?= $(WORKTREE_ROOT)/.cache/tuist/$(WORKTREE_ID)/xdg-cache
|
|
12
|
+
TUIST_XDG_STATE_HOME ?= $(WORKTREE_ROOT)/.cache/tuist/$(WORKTREE_ID)/xdg-state
|
|
13
|
+
TUIST_XDG_CONFIG_HOME ?= $(WORKTREE_ROOT)/.cache/tuist/$(WORKTREE_ID)/xdg-config
|
|
14
|
+
TUIST_TMPDIR ?= $(WORKTREE_ROOT)/.cache/tuist/$(WORKTREE_ID)/tmp
|
|
15
|
+
SWIFTLINT_CACHE ?= $(WORKTREE_ROOT)/.swiftlint-cache/$(WORKTREE_ID)
|
|
16
|
+
SWIFTFORMAT_CACHE ?= $(WORKTREE_ROOT)/.swiftformat.cache/$(WORKTREE_ID)
|
|
17
|
+
DEBUG_BUNDLE_SUFFIX ?= .$(WORKTREE_ID)
|
|
18
|
+
EFFECTIVE_BUNDLE_IDENTIFIER ?= {{BUNDLE_IDENTIFIER}}$(DEBUG_BUNDLE_SUFFIX)
|
|
19
|
+
RELEASE_BUNDLE_IDENTIFIER := {{BUNDLE_IDENTIFIER}}
|
|
20
|
+
TUIST_DEBUG_BUNDLE_SUFFIX := $(DEBUG_BUNDLE_SUFFIX)
|
|
21
|
+
XCODEBUILD := xcodebuild -derivedDataPath $(DERIVED_DATA_PATH)
|
|
22
|
+
TUIST_ENV := HOME=$(TUIST_HOME) XDG_CACHE_HOME=$(TUIST_XDG_CACHE_HOME) XDG_STATE_HOME=$(TUIST_XDG_STATE_HOME) XDG_CONFIG_HOME=$(TUIST_XDG_CONFIG_HOME) TMPDIR=$(TUIST_TMPDIR)
|
|
23
|
+
TEST_DESTINATION ?= $(shell ./scripts/test-destination {{APPLE_PLATFORM}} 2>/dev/null || printf '%s' '{{XCODEBUILD_DESTINATION}}')
|
|
24
|
+
|
|
25
|
+
export TUIST_HOME
|
|
26
|
+
export TUIST_XDG_CACHE_HOME
|
|
27
|
+
export TUIST_XDG_STATE_HOME
|
|
28
|
+
export TUIST_XDG_CONFIG_HOME
|
|
29
|
+
export TUIST_TMPDIR
|
|
30
|
+
export DEBUG_BUNDLE_SUFFIX
|
|
31
|
+
export TUIST_DEBUG_BUNDLE_SUFFIX
|
|
32
|
+
|
|
33
|
+
.PHONY: bootstrap doctor generate release-generate release-identity-check clean build test lint verify format release-doctor archive beta release worktree-info worktree-doctor clean-worktree help
|
|
34
|
+
|
|
35
|
+
bootstrap:
|
|
36
|
+
$(TUIST_ENV) WORKTREE_ID=$(WORKTREE_ID) ./scripts/bootstrap
|
|
37
|
+
|
|
38
|
+
doctor:
|
|
39
|
+
$(TUIST_ENV) WORKTREE_ID=$(WORKTREE_ID) ./scripts/doctor
|
|
40
|
+
|
|
41
|
+
generate:
|
|
42
|
+
mkdir -p "$(TUIST_HOME)" "$(TUIST_XDG_CACHE_HOME)" "$(TUIST_XDG_STATE_HOME)" "$(TUIST_XDG_CONFIG_HOME)" "$(TUIST_TMPDIR)"
|
|
43
|
+
$(TUIST_ENV) tuist install
|
|
44
|
+
$(TUIST_ENV) tuist generate --no-open
|
|
45
|
+
|
|
46
|
+
release-generate:
|
|
47
|
+
@if [ -n "$(DEBUG_BUNDLE_SUFFIX)" ]; then printf '%s\n' "Release generation ignores DEBUG_BUNDLE_SUFFIX=$(DEBUG_BUNDLE_SUFFIX) and uses $(RELEASE_BUNDLE_IDENTIFIER)."; fi
|
|
48
|
+
$(MAKE) --no-print-directory DEBUG_BUNDLE_SUFFIX= generate
|
|
49
|
+
|
|
50
|
+
release-identity-check:
|
|
51
|
+
./scripts/verify-release-identity workspace
|
|
52
|
+
|
|
53
|
+
clean:
|
|
54
|
+
tuist clean
|
|
55
|
+
|
|
56
|
+
build:
|
|
57
|
+
$(XCODEBUILD) \
|
|
58
|
+
-workspace {{PROJECT_NAME}}.xcworkspace \
|
|
59
|
+
-scheme {{SWIFT_MODULE_NAME}} \
|
|
60
|
+
-destination '{{XCODEBUILD_DESTINATION}}' \
|
|
61
|
+
build
|
|
62
|
+
|
|
63
|
+
test:
|
|
64
|
+
$(XCODEBUILD) \
|
|
65
|
+
-workspace {{PROJECT_NAME}}.xcworkspace \
|
|
66
|
+
-scheme {{SWIFT_MODULE_NAME}} \
|
|
67
|
+
-destination '$(TEST_DESTINATION)' \
|
|
68
|
+
test
|
|
69
|
+
|
|
70
|
+
lint:
|
|
71
|
+
mkdir -p "$(SWIFTLINT_CACHE)"
|
|
72
|
+
swiftlint lint --cache-path $(SWIFTLINT_CACHE)
|
|
73
|
+
|
|
74
|
+
verify: doctor lint test build
|
|
75
|
+
|
|
76
|
+
format:
|
|
77
|
+
mkdir -p "$(SWIFTFORMAT_CACHE)"
|
|
78
|
+
swiftformat . --cache $(SWIFTFORMAT_CACHE)
|
|
79
|
+
|
|
80
|
+
release-doctor:
|
|
81
|
+
fastlane release_doctor
|
|
82
|
+
|
|
83
|
+
archive:
|
|
84
|
+
@if [ -n "$(DEBUG_BUNDLE_SUFFIX)" ]; then printf '%s\n' "Archive ignores DEBUG_BUNDLE_SUFFIX=$(DEBUG_BUNDLE_SUFFIX) and uses $(RELEASE_BUNDLE_IDENTIFIER)."; fi
|
|
85
|
+
DEBUG_BUNDLE_SUFFIX= fastlane archive
|
|
86
|
+
|
|
87
|
+
beta:
|
|
88
|
+
@if [ -n "$(DEBUG_BUNDLE_SUFFIX)" ]; then printf '%s\n' "Beta delivery ignores DEBUG_BUNDLE_SUFFIX=$(DEBUG_BUNDLE_SUFFIX) and uses $(RELEASE_BUNDLE_IDENTIFIER)."; fi
|
|
89
|
+
DEBUG_BUNDLE_SUFFIX= fastlane beta
|
|
90
|
+
|
|
91
|
+
release:
|
|
92
|
+
@if [ -n "$(DEBUG_BUNDLE_SUFFIX)" ]; then printf '%s\n' "App Store delivery ignores DEBUG_BUNDLE_SUFFIX=$(DEBUG_BUNDLE_SUFFIX) and uses $(RELEASE_BUNDLE_IDENTIFIER)."; fi
|
|
93
|
+
DEBUG_BUNDLE_SUFFIX= fastlane release
|
|
94
|
+
|
|
95
|
+
worktree-info:
|
|
96
|
+
@printf '%s\n' "Project: {{PROJECT_NAME}}"
|
|
97
|
+
@printf '%s\n' "Worktree root: $(WORKTREE_ROOT)"
|
|
98
|
+
@printf '%s\n' "WORKTREE_LABEL: $(WORKTREE_LABEL)"
|
|
99
|
+
@printf '%s\n' "WORKTREE_ID: $(WORKTREE_ID)"
|
|
100
|
+
@printf '%s\n' "WORKTREE_SLUG: $(WORKTREE_SLUG)"
|
|
101
|
+
@printf '%s\n' "DerivedData: $(DERIVED_DATA_PATH)"
|
|
102
|
+
@printf '%s\n' "SwiftPM build path: $(SWIFTPM_BUILD_PATH)"
|
|
103
|
+
@printf '%s\n' "Tuist HOME: $(TUIST_HOME)"
|
|
104
|
+
@printf '%s\n' "Tuist XDG cache: $(TUIST_XDG_CACHE_HOME)"
|
|
105
|
+
@printf '%s\n' "Tuist XDG state: $(TUIST_XDG_STATE_HOME)"
|
|
106
|
+
@printf '%s\n' "Tuist XDG config: $(TUIST_XDG_CONFIG_HOME)"
|
|
107
|
+
@printf '%s\n' "Tuist tmp: $(TUIST_TMPDIR)"
|
|
108
|
+
@printf '%s\n' "SwiftLint cache: $(SWIFTLINT_CACHE)"
|
|
109
|
+
@printf '%s\n' "SwiftFormat cache: $(SWIFTFORMAT_CACHE)"
|
|
110
|
+
@printf '%s\n' "Debug bundle suffix: $(DEBUG_BUNDLE_SUFFIX)"
|
|
111
|
+
@printf '%s\n' "Debug bundle identifier: $(EFFECTIVE_BUNDLE_IDENTIFIER)"
|
|
112
|
+
@printf '%s\n' "Release bundle identifier: $(RELEASE_BUNDLE_IDENTIFIER)"
|
|
113
|
+
@printf '%s\n' "Test destination: $(TEST_DESTINATION)"
|
|
114
|
+
|
|
115
|
+
worktree-doctor:
|
|
116
|
+
@printf '%s\n' "Checking Apple worktree isolation..."
|
|
117
|
+
@test -n "$(WORKTREE_ID)" || (printf '%s\n' "WORKTREE_ID is empty" && exit 1)
|
|
118
|
+
@case "$(DERIVED_DATA_PATH)" in "$(WORKTREE_ROOT)"/*) ;; *) printf '%s\n' "DerivedData should stay inside this worktree: $(DERIVED_DATA_PATH)"; exit 1;; esac
|
|
119
|
+
@case "$(TUIST_HOME)" in "$(WORKTREE_ROOT)"/*) ;; *) printf '%s\n' "Tuist home should stay inside this worktree: $(TUIST_HOME)"; exit 1;; esac
|
|
120
|
+
@case "$(TUIST_XDG_CACHE_HOME)" in "$(WORKTREE_ROOT)"/*) ;; *) printf '%s\n' "Tuist cache should stay inside this worktree: $(TUIST_XDG_CACHE_HOME)"; exit 1;; esac
|
|
121
|
+
@if [ -f fastlane/.env ]; then printf '%s\n' "fastlane/.env is local to this worktree and must remain untracked."; fi
|
|
122
|
+
@printf '%s\n' "Apple worktree isolation looks ready."
|
|
123
|
+
|
|
124
|
+
clean-worktree:
|
|
125
|
+
rm -rf "$(DERIVED_DATA_PATH)" "$(SWIFTPM_BUILD_PATH)" "$(TUIST_HOME)" "$(TUIST_XDG_CACHE_HOME)" "$(TUIST_XDG_STATE_HOME)" "$(TUIST_XDG_CONFIG_HOME)" "$(TUIST_TMPDIR)" "$(SWIFTLINT_CACHE)" "$(SWIFTFORMAT_CACHE)"
|
|
126
|
+
|
|
127
|
+
help:
|
|
128
|
+
@printf '%s\n' "Common commands:" " make bootstrap Prepare project dependencies and tooling" " make doctor Check the local environment" " make lint Run static checks" " make test Run automated tests" " make verify Run the template quality gate" " make build Build the project" " make clean Remove generated build state" " make help Show this command contract"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// swift-tools-version: 6.0
|
|
2
|
+
import PackageDescription
|
|
3
|
+
|
|
4
|
+
let package = Package(
|
|
5
|
+
name: "AppServices",
|
|
6
|
+
platforms: [
|
|
7
|
+
{{SWIFTPM_SUPPORTED_PLATFORM}}
|
|
8
|
+
],
|
|
9
|
+
products: [
|
|
10
|
+
.library(
|
|
11
|
+
name: "AppServices",
|
|
12
|
+
targets: ["AppServices"]
|
|
13
|
+
)
|
|
14
|
+
],
|
|
15
|
+
targets: [
|
|
16
|
+
.target(
|
|
17
|
+
name: "AppServices"
|
|
18
|
+
)
|
|
19
|
+
]
|
|
20
|
+
)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
public struct StarterFact: Equatable {
|
|
4
|
+
public let label: String
|
|
5
|
+
public let systemImage: String
|
|
6
|
+
public let value: String
|
|
7
|
+
|
|
8
|
+
public init(label: String, systemImage: String, value: String) {
|
|
9
|
+
self.label = label
|
|
10
|
+
self.systemImage = systemImage
|
|
11
|
+
self.value = value
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public protocol ReleaseChecklistProviding {
|
|
16
|
+
func releaseChecklistItems() -> [String]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public struct DefaultReleaseChecklistProvider: ReleaseChecklistProviding {
|
|
20
|
+
public let bundleIdentifier: String
|
|
21
|
+
public let developmentTeam: String
|
|
22
|
+
|
|
23
|
+
public init(bundleIdentifier: String, developmentTeam: String) {
|
|
24
|
+
self.bundleIdentifier = bundleIdentifier
|
|
25
|
+
self.developmentTeam = developmentTeam
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public func releaseChecklistItems() -> [String] {
|
|
29
|
+
[
|
|
30
|
+
"Confirm signing for \(developmentTeam).",
|
|
31
|
+
"Verify bundle identifier \(bundleIdentifier).",
|
|
32
|
+
"Run make release-doctor before archiving.",
|
|
33
|
+
"Upload beta builds through make beta."
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public enum StarterFactBuilder {
|
|
39
|
+
public static func overviewFacts(
|
|
40
|
+
bundleIdentifier: String,
|
|
41
|
+
platformName: String,
|
|
42
|
+
minimumOSVersion: String,
|
|
43
|
+
developmentTeam: String
|
|
44
|
+
) -> [StarterFact] {
|
|
45
|
+
[
|
|
46
|
+
StarterFact(label: "Bundle ID", systemImage: "shippingbox", value: bundleIdentifier),
|
|
47
|
+
StarterFact(label: "Platform", systemImage: "app", value: platformName),
|
|
48
|
+
StarterFact(label: "Minimum OS", systemImage: "gear", value: minimumOSVersion),
|
|
49
|
+
StarterFact(label: "Team", systemImage: "person.3", value: developmentTeam)
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// swift-tools-version: 6.0
|
|
2
|
+
import PackageDescription
|
|
3
|
+
|
|
4
|
+
let package = Package(
|
|
5
|
+
name: "DesignSystem",
|
|
6
|
+
platforms: [
|
|
7
|
+
{{SWIFTPM_SUPPORTED_PLATFORM}}
|
|
8
|
+
],
|
|
9
|
+
products: [
|
|
10
|
+
.library(
|
|
11
|
+
name: "DesignSystem",
|
|
12
|
+
targets: ["DesignSystem"]
|
|
13
|
+
)
|
|
14
|
+
],
|
|
15
|
+
targets: [
|
|
16
|
+
.target(
|
|
17
|
+
name: "DesignSystem"
|
|
18
|
+
)
|
|
19
|
+
]
|
|
20
|
+
)
|
biucingcli/template_data/apple/template/Packages/DesignSystem/Sources/DesignSystem/Theme.swift
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import SwiftUI
|
|
2
|
+
|
|
3
|
+
public enum BiucingTheme {
|
|
4
|
+
public static let titleFont = Font.system(.title2, design: .rounded).weight(.semibold)
|
|
5
|
+
public static let sectionTitleFont = Font.system(.headline, design: .rounded).weight(.semibold)
|
|
6
|
+
public static let bodyFont = Font.system(.body, design: .rounded)
|
|
7
|
+
public static let captionFont = Font.system(.footnote, design: .rounded)
|
|
8
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# {{DISPLAY_NAME}}
|
|
2
|
+
|
|
3
|
+
This project was generated by BiucingCLI as a Tuist-based Apple app starter for a mid-sized team.
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
|
|
7
|
+
- Swift
|
|
8
|
+
- SwiftUI
|
|
9
|
+
- Tuist
|
|
10
|
+
- Swift Package Manager
|
|
11
|
+
- fastlane
|
|
12
|
+
|
|
13
|
+
## Platform
|
|
14
|
+
|
|
15
|
+
- Target platform: `{{APPLE_PLATFORM_NAME}}`
|
|
16
|
+
- Minimum OS version: `{{MINIMUM_OS_VERSION}}`
|
|
17
|
+
|
|
18
|
+
## Repository Layout
|
|
19
|
+
|
|
20
|
+
- `App/`: Tuist project manifests and app targets
|
|
21
|
+
- `Packages/`: internal Swift packages for shared code
|
|
22
|
+
`Packages/AppServices` holds starter metadata and release-checklist services
|
|
23
|
+
`Packages/DesignSystem` holds shared fonts and visual primitives
|
|
24
|
+
- `fastlane/`: beta and release automation
|
|
25
|
+
- `docs/release-delivery.md`: signing, TestFlight, and App Store Connect delivery setup
|
|
26
|
+
- `scripts/`: bootstrap and environment checks
|
|
27
|
+
- `.swiftlint.yml`: default lint rules for app and package sources
|
|
28
|
+
- `.swiftformat`: default formatting rules for Swift sources
|
|
29
|
+
|
|
30
|
+
## Getting Started
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
make bootstrap
|
|
34
|
+
make doctor
|
|
35
|
+
make generate
|
|
36
|
+
make lint
|
|
37
|
+
make test
|
|
38
|
+
make release-doctor
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Worktree Workflow
|
|
42
|
+
|
|
43
|
+
Each worktree derives a human-readable `WORKTREE_LABEL` from its directory name
|
|
44
|
+
and a hash-based `WORKTREE_ID` from the worktree root path. Override
|
|
45
|
+
`WORKTREE_ID` when you want a shorter or stable value across renamed folders:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
WORKTREE_ID=feature-a make worktree-info
|
|
49
|
+
WORKTREE_ID=feature-a make generate
|
|
50
|
+
WORKTREE_ID=feature-a make test
|
|
51
|
+
WORKTREE_ID=feature-a make clean-worktree
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`make worktree-info` prints the isolated DerivedData, SwiftPM, Tuist, SwiftLint,
|
|
55
|
+
SwiftFormat, and debug bundle identifier values. `make worktree-doctor` checks
|
|
56
|
+
that cache paths stay under this worktree. Debug builds use
|
|
57
|
+
`DEBUG_BUNDLE_SUFFIX` by default so two worktrees can install side by side in
|
|
58
|
+
Simulator; set `DEBUG_BUNDLE_SUFFIX=` to keep the generated bundle identifier.
|
|
59
|
+
|
|
60
|
+
## Standard Commands
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
make bootstrap
|
|
64
|
+
make doctor
|
|
65
|
+
make generate
|
|
66
|
+
make release-generate
|
|
67
|
+
make release-identity-check
|
|
68
|
+
make build
|
|
69
|
+
make lint
|
|
70
|
+
make format
|
|
71
|
+
make test
|
|
72
|
+
make verify
|
|
73
|
+
make release-doctor
|
|
74
|
+
make archive
|
|
75
|
+
make beta
|
|
76
|
+
make release
|
|
77
|
+
make clean
|
|
78
|
+
make help
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`make doctor` validates Xcode selection, `xcodebuild`, Tuist, Swift, SwiftLint, SwiftFormat, fastlane, and simulator/runtime visibility before you spend time on `make generate`, `make build`, or `make test`.
|
|
82
|
+
|
|
83
|
+
`DEBUG_BUNDLE_SUFFIX` is a local Debug/worktree identity only. Normal `make generate`, `make build`, and `make test` workflows keep the suffix so parallel worktrees can install side by side. `make release-generate`, `make archive`, `make beta`, and `make release` always discard it and use the configured release bundle identifier.
|
|
84
|
+
|
|
85
|
+
## Configuration
|
|
86
|
+
|
|
87
|
+
- Platform: `{{APPLE_PLATFORM_NAME}}`
|
|
88
|
+
- Bundle identifier: `{{BUNDLE_IDENTIFIER}}`
|
|
89
|
+
- Minimum OS version: `{{MINIMUM_OS_VERSION}}`
|
|
90
|
+
- Development team: `{{DEVELOPMENT_TEAM}}`
|
|
91
|
+
- Formatting and linting are configured through `.swiftformat` and `.swiftlint.yml`
|
|
92
|
+
- `make doctor` checks simulator readiness as a hard requirement for iOS-family starters and a warning-only signal for macOS starters.
|
|
93
|
+
|
|
94
|
+
## Release Setup
|
|
95
|
+
|
|
96
|
+
`development_team` is written into `App/Project.swift` as the `DEVELOPMENT_TEAM` build setting. Replace the starter value with the Apple Developer team that should sign debug, beta, and release builds for this app.
|
|
97
|
+
|
|
98
|
+
`bundle_identifier` is used for the main app target, and the template automatically derives the test target as `{{BUNDLE_IDENTIFIER}}.tests`. Choose a reverse-DNS identifier that is unique inside your Apple Developer account before connecting certificates, provisioning profiles, or TestFlight flows.
|
|
99
|
+
|
|
100
|
+
Before a real beta or release handoff, the team needs to supply:
|
|
101
|
+
|
|
102
|
+
- a valid Apple Developer team with signing access
|
|
103
|
+
- a bundle identifier registered in the Apple Developer portal
|
|
104
|
+
- certificates and provisioning profiles synced through `fastlane match`
|
|
105
|
+
- an App Store Connect API key JSON file referenced by `APP_STORE_CONNECT_API_KEY_PATH`
|
|
106
|
+
- a private signing repository referenced by `MATCH_GIT_URL`
|
|
107
|
+
|
|
108
|
+
Copy `fastlane/.env.example` to `fastlane/.env`, place the API key JSON under the ignored `credentials/` directory, and replace the placeholders. Keep real `.env`, API key, private-key, certificate-container, and provisioning-profile files in your CI secret manager or an ignored local directory. See `docs/release-delivery.md` for the full setup path.
|
|
109
|
+
|
|
110
|
+
`make release-doctor` validates the local release environment before a native archive spends time building. `make release-identity-check` separately verifies that the generated Release workspace resolves the exact configured bundle identifier.
|
|
111
|
+
|
|
112
|
+
`make archive` regenerates the workspace without a debug suffix, verifies the Release build settings before signing sync, runs lint and tests, builds a signed App Store archive, and verifies the archive bundle identifier before returning the artifact.
|
|
113
|
+
|
|
114
|
+
`make beta` runs the archive lane and uploads the signed ipa/pkg to TestFlight.
|
|
115
|
+
|
|
116
|
+
`make release` runs the archive lane and uploads the signed ipa/pkg to App Store Connect. It does not submit for review by default; set `APP_STORE_SUBMIT_FOR_REVIEW=true` only after metadata, screenshots, review information, privacy details, and compliance answers are ready.
|
|
117
|
+
|
|
118
|
+
## Notes
|
|
119
|
+
|
|
120
|
+
- `Tuist.swift` is the repo-wide Tuist configuration.
|
|
121
|
+
- `Workspace.swift` defines the generated workspace composition.
|
|
122
|
+
- `App/Project.swift` is the source of truth for the app target graph.
|
|
123
|
+
- `Packages/AppServices` is the shared home for starter facts and release-checklist logic that would otherwise grow inside the app target too quickly.
|
|
124
|
+
- `Packages/DesignSystem` is a local Swift package consumed by the app target.
|
|
125
|
+
- The starter package split is intentionally simple: keep UI-focused primitives in `DesignSystem`, and move metadata, services, or non-UI helpers into `AppServices`.
|
|
126
|
+
- `AppTests` includes starter examples for a small view-model test and a mocked service dependency.
|
|
127
|
+
- `make doctor` is the fastest way to catch missing Xcode, Tuist, fastlane, or simulator setup before native commands fail later.
|
|
128
|
+
- `fastlane/Appfile` reads `FASTLANE_USER` and `DEVELOPMENT_TEAM_ID` while keeping the generated bundle identifier as the stable app identity.
|
|
129
|
+
- `fastlane/Fastfile` owns release credential checks, `match` signing sync, signed archive creation, TestFlight upload, and App Store Connect upload.
|
|
130
|
+
- `scripts/verify-release-identity` prevents a worktree debug suffix from reaching signing or an uploaded archive by checking both Release build settings and the final xcarchive.
|
|
131
|
+
- `.gitignore` protects the recommended `credentials/` and `signing/` directories plus common Apple private-key and provisioning-profile formats. It does not protect files already tracked or force-added with `git add -f`.
|
|
132
|
+
- `{{APPLE_PLATFORM_OUTPUT_NOTE}}`
|
|
133
|
+
- Generated `.xcodeproj` and `.xcworkspace` files should not be edited manually.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Release Delivery
|
|
2
|
+
|
|
3
|
+
The generated starter includes fastlane lanes for release credential checks, signed archive creation, TestFlight upload, and App Store Connect upload.
|
|
4
|
+
|
|
5
|
+
## One-Time Setup
|
|
6
|
+
|
|
7
|
+
1. Register `{{BUNDLE_IDENTIFIER}}` in Apple Developer and App Store Connect.
|
|
8
|
+
2. Create an App Store Connect API key with access to manage builds for the app.
|
|
9
|
+
3. Save the fastlane API key JSON as `credentials/app-store-connect-api-key.json` locally and keep it untracked.
|
|
10
|
+
4. Create a private certificate repository for `fastlane match`.
|
|
11
|
+
5. Copy `fastlane/.env.example` to `fastlane/.env` and replace the placeholders.
|
|
12
|
+
6. Run the first certificate/profile sync from a trusted machine:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
MATCH_ALLOW_WRITE=true fastlane match appstore
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
After the first sync, keep `MATCH_ALLOW_WRITE=false` on developer and CI machines so release jobs consume known signing material instead of mutating it.
|
|
19
|
+
|
|
20
|
+
## Commands
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
make release-doctor
|
|
24
|
+
make release-generate
|
|
25
|
+
make release-identity-check
|
|
26
|
+
make archive
|
|
27
|
+
make beta
|
|
28
|
+
make release
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
- `make release-doctor` validates local release credentials and signing configuration.
|
|
32
|
+
- `make release-generate` regenerates the workspace with the configured release bundle identifier and ignores any `DEBUG_BUNDLE_SUFFIX` inherited from a worktree or shell.
|
|
33
|
+
- `make release-identity-check` verifies the Release target's resolved `PRODUCT_BUNDLE_IDENTIFIER` before signing material is requested.
|
|
34
|
+
- `make archive` generates and verifies the Release workspace, lints, tests, syncs App Store signing, builds a signed archive, and verifies the xcarchive bundle identifier.
|
|
35
|
+
- `make beta` runs `archive` and uploads the signed ipa/pkg to TestFlight.
|
|
36
|
+
- `make release` runs `archive` and uploads the signed ipa/pkg to App Store Connect.
|
|
37
|
+
|
|
38
|
+
By default, `make release` uploads the binary but does not submit it for review. Set `APP_STORE_SUBMIT_FOR_REVIEW=true` only after metadata, screenshots, review information, privacy details, and compliance answers are ready.
|
|
39
|
+
|
|
40
|
+
## Release Identity Boundary
|
|
41
|
+
|
|
42
|
+
`DEBUG_BUNDLE_SUFFIX` belongs only to local Debug/worktree workflows. Archive, beta, and release lanes always clear it, even when a caller exports a non-empty value. The delivery pipeline compares both the generated Release build settings and `Info.plist` inside the final xcarchive with `{{BUNDLE_IDENTIFIER}}`; any missing or different value stops the lane before upload.
|
|
43
|
+
|
|
44
|
+
## Local Secrets
|
|
45
|
+
|
|
46
|
+
Keep these files local or in your CI secret store:
|
|
47
|
+
|
|
48
|
+
- `fastlane/.env`
|
|
49
|
+
- `credentials/app-store-connect-api-key.json`
|
|
50
|
+
- `.p8`, `.p12`, and `.pfx` private-key containers
|
|
51
|
+
- `.mobileprovision` and `.provisionprofile` files
|
|
52
|
+
|
|
53
|
+
The template also ignores the legacy root name `app-store-connect-api-key.json` and credential JSON files directly under `fastlane/`. Keep `.env.example` as placeholders only. Do not commit API keys, certificate repository credentials, provisioning profiles, or Apple ID sessions.
|
|
54
|
+
|
|
55
|
+
Ignore rules only protect untracked files and do not override `git add -f`. If real credentials have already been committed, revoke or rotate them first, remove them from the index, and assess whether repository history must be rewritten.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
DEVELOPMENT_TEAM_ID={{DEVELOPMENT_TEAM}}
|
|
2
|
+
FASTLANE_USER=developer@example.com
|
|
3
|
+
|
|
4
|
+
# JSON format supported by fastlane api_key_path. Store it in the ignored credentials directory.
|
|
5
|
+
APP_STORE_CONNECT_API_KEY_PATH=credentials/app-store-connect-api-key.json
|
|
6
|
+
|
|
7
|
+
# Private git repository used by fastlane match for certificates and profiles.
|
|
8
|
+
MATCH_GIT_URL=git@github.com:your-org/apple-certificates.git
|
|
9
|
+
MATCH_GIT_BRANCH=main
|
|
10
|
+
MATCH_TYPE=appstore
|
|
11
|
+
|
|
12
|
+
# Keep release machines read-only by default. Set true only during first-time certificate/profile setup.
|
|
13
|
+
MATCH_ALLOW_WRITE=false
|
|
14
|
+
|
|
15
|
+
# Optional delivery controls.
|
|
16
|
+
TESTFLIGHT_SKIP_WAITING=true
|
|
17
|
+
TESTFLIGHT_CHANGELOG=
|
|
18
|
+
APP_STORE_SKIP_METADATA=true
|
|
19
|
+
APP_STORE_SKIP_SCREENSHOTS=true
|
|
20
|
+
APP_STORE_SUBMIT_FOR_REVIEW=false
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
default_platform(:{{FASTLANE_PLATFORM}})
|
|
2
|
+
|
|
3
|
+
APP_IDENTIFIER = "{{BUNDLE_IDENTIFIER}}"
|
|
4
|
+
APP_STORE_PLATFORM = "{{APP_STORE_PLATFORM}}"
|
|
5
|
+
TEAM_ID = ENV.fetch("DEVELOPMENT_TEAM_ID", "{{DEVELOPMENT_TEAM}}")
|
|
6
|
+
PROJECT_ROOT = File.expand_path("..", __dir__)
|
|
7
|
+
WORKSPACE = "{{PROJECT_NAME}}.xcworkspace"
|
|
8
|
+
SCHEME = "{{SWIFT_MODULE_NAME}}"
|
|
9
|
+
ARCHIVE_PATH = "build/release/{{SWIFT_MODULE_NAME}}.xcarchive"
|
|
10
|
+
OUTPUT_DIRECTORY = "build/release"
|
|
11
|
+
|
|
12
|
+
def env_true?(name, default: false)
|
|
13
|
+
value = ENV[name]
|
|
14
|
+
return default if value.nil? || value.empty?
|
|
15
|
+
|
|
16
|
+
%w[1 true yes y].include?(value.downcase)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def require_env_file(name)
|
|
20
|
+
value = ENV[name]
|
|
21
|
+
UI.user_error!("Set #{name}. See fastlane/.env.example.") if value.to_s.empty?
|
|
22
|
+
path = File.expand_path(value, PROJECT_ROOT)
|
|
23
|
+
UI.user_error!("#{name} does not exist: #{path}") unless File.file?(path)
|
|
24
|
+
path
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def require_env_value(name)
|
|
28
|
+
value = ENV[name]
|
|
29
|
+
UI.user_error!("Set #{name}. See fastlane/.env.example.") if value.to_s.empty?
|
|
30
|
+
value
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def app_store_api_key_path
|
|
34
|
+
require_env_file("APP_STORE_CONNECT_API_KEY_PATH")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def signing_git_url
|
|
38
|
+
require_env_value("MATCH_GIT_URL")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def built_artifact_options
|
|
42
|
+
ipa_path = Actions.lane_context[SharedValues::IPA_OUTPUT_PATH]
|
|
43
|
+
pkg_path = Actions.lane_context[SharedValues::PKG_OUTPUT_PATH]
|
|
44
|
+
|
|
45
|
+
return { ipa: ipa_path } if ipa_path && File.exist?(ipa_path)
|
|
46
|
+
return { pkg: pkg_path } if pkg_path && File.exist?(pkg_path)
|
|
47
|
+
|
|
48
|
+
UI.user_error!("No signed ipa/pkg was produced by build_app.")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def sync_app_store_signing
|
|
52
|
+
match(
|
|
53
|
+
type: ENV.fetch("MATCH_TYPE", "appstore"),
|
|
54
|
+
app_identifier: APP_IDENTIFIER,
|
|
55
|
+
team_id: TEAM_ID,
|
|
56
|
+
git_url: signing_git_url,
|
|
57
|
+
git_branch: ENV.fetch("MATCH_GIT_BRANCH", "main"),
|
|
58
|
+
readonly: !env_true?("MATCH_ALLOW_WRITE", default: false),
|
|
59
|
+
api_key_path: app_store_api_key_path
|
|
60
|
+
)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def build_signed_app
|
|
64
|
+
build_app(
|
|
65
|
+
workspace: WORKSPACE,
|
|
66
|
+
scheme: SCHEME,
|
|
67
|
+
clean: true,
|
|
68
|
+
configuration: "Release",
|
|
69
|
+
export_method: "app-store",
|
|
70
|
+
export_team_id: TEAM_ID,
|
|
71
|
+
derived_data_path: ENV.fetch("DERIVED_DATA_PATH", "DerivedData/release"),
|
|
72
|
+
archive_path: ARCHIVE_PATH,
|
|
73
|
+
output_directory: OUTPUT_DIRECTORY,
|
|
74
|
+
xcodebuild_formatter: ENV.fetch("XCODEBUILD_FORMATTER", "xcbeautify")
|
|
75
|
+
)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
platform :{{FASTLANE_PLATFORM}} do
|
|
79
|
+
desc "Validate release credentials and signing configuration"
|
|
80
|
+
lane :release_doctor do
|
|
81
|
+
app_store_api_key_path
|
|
82
|
+
signing_git_url
|
|
83
|
+
UI.user_error!("Set DEVELOPMENT_TEAM_ID or replace the template development_team value.") if TEAM_ID == "DEVELOPMENT_TEAM_ID"
|
|
84
|
+
UI.success("Release credentials and signing configuration are present.")
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
desc "Build a signed App Store archive without uploading"
|
|
88
|
+
lane :archive do
|
|
89
|
+
release_doctor
|
|
90
|
+
sh("make release-generate")
|
|
91
|
+
sh("make release-identity-check")
|
|
92
|
+
sh("make lint")
|
|
93
|
+
sh("make test")
|
|
94
|
+
sync_app_store_signing
|
|
95
|
+
build_signed_app
|
|
96
|
+
sh("./scripts/verify-release-identity", "archive", ARCHIVE_PATH)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
desc "Build, sign, and upload a beta build to TestFlight"
|
|
100
|
+
lane :beta do
|
|
101
|
+
archive
|
|
102
|
+
upload_to_testflight(
|
|
103
|
+
api_key_path: app_store_api_key_path,
|
|
104
|
+
app_identifier: APP_IDENTIFIER,
|
|
105
|
+
app_platform: APP_STORE_PLATFORM,
|
|
106
|
+
skip_waiting_for_build_processing: env_true?("TESTFLIGHT_SKIP_WAITING", default: true),
|
|
107
|
+
changelog: ENV["TESTFLIGHT_CHANGELOG"],
|
|
108
|
+
**built_artifact_options
|
|
109
|
+
)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
desc "Build, sign, and upload an App Store Connect release build"
|
|
113
|
+
lane :release do
|
|
114
|
+
archive
|
|
115
|
+
upload_to_app_store(
|
|
116
|
+
api_key_path: app_store_api_key_path,
|
|
117
|
+
app_identifier: APP_IDENTIFIER,
|
|
118
|
+
platform: APP_STORE_PLATFORM,
|
|
119
|
+
force: true,
|
|
120
|
+
skip_metadata: env_true?("APP_STORE_SKIP_METADATA", default: true),
|
|
121
|
+
skip_screenshots: env_true?("APP_STORE_SKIP_SCREENSHOTS", default: true),
|
|
122
|
+
submit_for_review: env_true?("APP_STORE_SUBMIT_FOR_REVIEW", default: false),
|
|
123
|
+
**built_artifact_options
|
|
124
|
+
)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
git_url(ENV.fetch("MATCH_GIT_URL", "git@github.com:your-org/apple-certificates.git"))
|
|
2
|
+
git_branch(ENV.fetch("MATCH_GIT_BRANCH", "main"))
|
|
3
|
+
storage_mode("git")
|
|
4
|
+
type(ENV.fetch("MATCH_TYPE", "appstore"))
|
|
5
|
+
app_identifier(["{{BUNDLE_IDENTIFIER}}"])
|
|
6
|
+
team_id(ENV.fetch("DEVELOPMENT_TEAM_ID", "{{DEVELOPMENT_TEAM}}"))
|
|
7
|
+
readonly(ENV.fetch("MATCH_ALLOW_WRITE", "false") != "true")
|