forked from trent_larson/crowd-funder-for-time-pwa
revert BUILDING to master version
This commit is contained in:
781
BUILDING.md
781
BUILDING.md
@@ -1,6 +1,6 @@
|
||||
# Building TimeSafari
|
||||
|
||||
This guide explains how to build TimeSafari for different platforms using our unified build scripts.
|
||||
This guide explains how to build TimeSafari for different platforms.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -9,54 +9,7 @@ For a quick dev environment setup, use [pkgx](https://pkgx.dev).
|
||||
- Node.js (LTS version recommended)
|
||||
- npm (comes with Node.js)
|
||||
- Git
|
||||
- For mobile builds: Android Studio (Android) or Xcode (iOS)
|
||||
- For desktop builds: Capacitor Electron platform
|
||||
|
||||
## Unified Build Scripts
|
||||
|
||||
TimeSafari now uses unified build scripts that automatically handle environment variables, logging, error handling, and timing. All scripts are located in the `scripts/` directory and use a common utilities library.
|
||||
|
||||
### Script Features
|
||||
|
||||
- **Automatic Environment Setup**: Each script sets the correct environment variables for its build type
|
||||
- **Rich Logging**: Colored, timestamped output with different log levels
|
||||
- **Error Handling**: Proper exit codes and graceful failure recovery
|
||||
- **Timing**: Automatic execution time tracking for each step
|
||||
- **Validation**: Checks for required dependencies and files
|
||||
- **CLI Options**: `--help`, `--verbose`, `--env` flags for all scripts
|
||||
|
||||
### Available Scripts
|
||||
|
||||
| Script | Purpose | Command |
|
||||
|--------|---------|---------|
|
||||
| `capacitor-dev.sh` | Capacitor development | `./scripts/capacitor-dev.sh` |
|
||||
| `capacitor-build.sh` | Capacitor build | `./scripts/build-capacitor.sh` |
|
||||
| `web-dev.sh` | Web development | `./scripts/web-dev.sh` |
|
||||
| `web-build.sh` | Web build | `./scripts/build-web.sh` |
|
||||
|
||||
### Environment Variables
|
||||
|
||||
All scripts automatically set the correct environment variables for their build type:
|
||||
|
||||
| Build Type | VITE_PLATFORM | VITE_PWA_ENABLED | VITE_DISABLE_PWA | NODE_ENV |
|
||||
|------------|---------------|------------------|------------------|----------|
|
||||
| `capacitor` | capacitor | false | true | - |
|
||||
| `web` | web | true | false | - |
|
||||
|
||||
### CLI Options
|
||||
|
||||
All scripts support these options:
|
||||
|
||||
```bash
|
||||
# Show help
|
||||
./scripts/build-capacitor.sh --help
|
||||
|
||||
# Enable verbose logging
|
||||
./scripts/build-capacitor.sh --verbose
|
||||
|
||||
# Show environment variables
|
||||
./scripts/build-capacitor.sh --env
|
||||
```
|
||||
- For desktop builds: Additional build tools based on your OS
|
||||
|
||||
## Forks
|
||||
|
||||
@@ -77,104 +30,18 @@ Install dependencies:
|
||||
npm install
|
||||
```
|
||||
|
||||
## Package Management
|
||||
|
||||
TimeSafari uses a mixed package management approach, combining npm and JSR (JavaScript Registry) for optimal dependency management.
|
||||
|
||||
### JSR Integration
|
||||
|
||||
Some packages are installed via JSR for better ESM support and modern TypeScript compatibility:
|
||||
|
||||
```bash
|
||||
# Install JSR packages
|
||||
npx jsr add @nostr/tools
|
||||
```
|
||||
|
||||
### Package Migration History
|
||||
|
||||
#### nostr-tools → @nostr/tools
|
||||
|
||||
**Date**: June 2025
|
||||
**Reason**: Resolved Vite/Rollup build issues with deep imports
|
||||
|
||||
**Before** (npm):
|
||||
|
||||
```typescript
|
||||
import { finalizeEvent } from "nostr-tools/lib/cjs/index.js";
|
||||
import { accountFromExtendedKey } from "nostr-tools/lib/cjs/nip06.js";
|
||||
```
|
||||
|
||||
**After** (JSR):
|
||||
|
||||
```typescript
|
||||
import { finalizeEvent } from "@nostr/tools";
|
||||
import { accountFromExtendedKey } from "@nostr/tools/nip06";
|
||||
```
|
||||
|
||||
**Benefits**:
|
||||
- ✅ Proper ESM support
|
||||
- ✅ No deep import issues with Vite/Rollup
|
||||
- ✅ Better TypeScript compatibility
|
||||
- ✅ Modern package structure
|
||||
|
||||
### Current Package Strategy
|
||||
|
||||
- **npm**: Primary package manager for most dependencies
|
||||
- **JSR**: Used for packages with better ESM support or modern alternatives
|
||||
- **Mixed approach**: Allows using the best package for each dependency
|
||||
|
||||
### When to Use JSR
|
||||
|
||||
Consider using JSR for:
|
||||
- Packages with ESM/CJS compatibility issues in npm
|
||||
- Modern TypeScript-first packages
|
||||
- Packages that work better with modern bundlers
|
||||
- New dependencies where JSR has a better alternative
|
||||
|
||||
### Vite Configuration
|
||||
|
||||
The build system is configured to handle both npm and JSR packages:
|
||||
|
||||
```typescript
|
||||
// vite.config.common.mts
|
||||
resolve: {
|
||||
alias: {
|
||||
'@nostr/tools': path.resolve(__dirname, 'node_modules/@nostr/tools'),
|
||||
'@nostr/tools/nip06': path.resolve(__dirname, 'node_modules/@nostr/tools/nip06'),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Troubleshooting Package Issues
|
||||
|
||||
1. **Build failures with deep imports**
|
||||
- Check if package has ESM/CJS compatibility issues
|
||||
- Consider JSR alternative if available
|
||||
- Update Vite configuration if needed
|
||||
|
||||
2. **TypeScript errors**
|
||||
- Ensure proper type definitions are available
|
||||
- Check package exports in package.json
|
||||
- Verify import paths match package structure
|
||||
|
||||
3. **Mixed package manager issues**
|
||||
- Keep package.json and node_modules in sync
|
||||
- Use `npm install` after JSR package additions
|
||||
- Check for conflicting package versions
|
||||
|
||||
## Web Development
|
||||
|
||||
### Local Development
|
||||
## Web Dev Locally
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Web Build for Server
|
||||
## Web Build for Server
|
||||
|
||||
1. Run the production build:
|
||||
|
||||
```bash
|
||||
rm -rf dist
|
||||
npm run build:web
|
||||
```
|
||||
|
||||
@@ -182,278 +49,57 @@ resolve: {
|
||||
|
||||
2. To test the production build locally:
|
||||
|
||||
You'll likely want to use test locations for the Endorser & image & partner servers; see "DEFAULT_ENDORSER_API_SERVER" & "DEFAULT_IMAGE_API_SERVER" & "DEFAULT_PARTNER_API_SERVER" below.
|
||||
|
||||
```bash
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Environment Configuration
|
||||
### Compile and minify for test & production
|
||||
|
||||
For different environments, create `.env` files:
|
||||
* If there are DB changes: before updating the test server, open browser(s) with current version to test DB migrations.
|
||||
|
||||
* `npx prettier --write ./sw_scripts/`
|
||||
|
||||
* Update the ClickUp tasks & CHANGELOG.md & the version in package.json, run `npm install`.
|
||||
|
||||
* Run a build to make sure package-lock version is updated, linting works, etc: `npm install && npm run build`
|
||||
|
||||
* Commit everything (since the commit hash is used the app).
|
||||
|
||||
* Put the commit hash in the changelog (which will help you remember to bump the version in the step later).
|
||||
|
||||
* Tag with the new version, [online](https://gitea.anomalistdesign.com/trent_larson/crowd-funder-for-time-pwa/releases) or `git tag 1.0.2 && git push origin 1.0.2`.
|
||||
|
||||
* For test, build the app (because test server is not yet set up to build):
|
||||
|
||||
```bash
|
||||
# .env.development
|
||||
VITE_APP_SERVER=https://dev.timesafari.app
|
||||
VITE_DEFAULT_ENDORSER_API_SERVER=https://dev-api.endorser.ch
|
||||
VITE_DEFAULT_IMAGE_API_SERVER=https://dev-image-api.timesafari.app
|
||||
VITE_DEFAULT_PARTNER_API_SERVER=https://dev-partner-api.endorser.ch
|
||||
VITE_DEFAULT_PUSH_SERVER=https://dev.timesafari.app
|
||||
VITE_PASSKEYS_ENABLED=true
|
||||
|
||||
# .env.production
|
||||
VITE_APP_SERVER=https://timesafari.app
|
||||
VITE_DEFAULT_ENDORSER_API_SERVER=https://api.endorser.ch
|
||||
VITE_DEFAULT_IMAGE_API_SERVER=https://image-api.timesafari.app
|
||||
VITE_DEFAULT_PARTNER_API_SERVER=https://partner-api.endorser.ch
|
||||
VITE_DEFAULT_PUSH_SERVER=https://timesafari.app
|
||||
VITE_PASSKEYS_ENABLED=true
|
||||
TIME_SAFARI_APP_TITLE="TimeSafari_Test" VITE_APP_SERVER=https://test.timesafari.app VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app VITE_DEFAULT_PARTNER_API_SERVER=https://test-partner-api.endorser.ch VITE_DEFAULT_PUSH_SERVER=https://test.timesafari.app VITE_PASSKEYS_ENABLED=true npm run build:web
|
||||
```
|
||||
|
||||
## Desktop Build (Capacitor Electron)
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. Install Capacitor CLI:
|
||||
... and transfer to the test server:
|
||||
|
||||
```bash
|
||||
npm install -g @capacitor/cli
|
||||
rsync -azvu -e "ssh -i ~/.ssh/..." dist ubuntutest@test.timesafari.app:time-safari
|
||||
```
|
||||
|
||||
2. Add Electron platform:
|
||||
(Let's replace that with a .env.development or .env.staging file.)
|
||||
|
||||
```bash
|
||||
npx cap add electron
|
||||
```
|
||||
(Note: The test BVC_MEETUPS_PROJECT_CLAIM_ID does not resolve as a URL because it's only in the test DB and the prod redirect won't redirect there.)
|
||||
|
||||
### Development
|
||||
* For prod, get on the server and run the correct build:
|
||||
|
||||
For development with automatic environment setup:
|
||||
... and log onto the server:
|
||||
|
||||
```bash
|
||||
# Build web assets
|
||||
npm run build:capacitor
|
||||
* `pkgx +npm sh`
|
||||
|
||||
# Sync with Capacitor
|
||||
npx cap sync electron
|
||||
* `cd crowd-funder-for-time-pwa && git checkout master && git pull && git checkout 1.0.2 && npm install && npm run build:web && cd -`
|
||||
|
||||
# Open in Electron
|
||||
npx cap open electron
|
||||
```
|
||||
(The plain `npm run build:web` uses the .env.production file.)
|
||||
|
||||
### Production Build
|
||||
* Back up the time-safari/dist folder & deploy: `mv time-safari/dist time-safari-dist-prev-2 && mv crowd-funder-for-time-pwa/dist time-safari/`
|
||||
|
||||
For production builds:
|
||||
|
||||
```bash
|
||||
# Build web assets
|
||||
npm run build:capacitor
|
||||
|
||||
# Sync with Capacitor
|
||||
npx cap sync electron
|
||||
|
||||
# Build Electron app
|
||||
npx cap build electron
|
||||
```
|
||||
|
||||
### Packaging
|
||||
|
||||
Capacitor Electron uses electron-builder for packaging. Configure the build in `capacitor.config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": {
|
||||
"ElectronBuilder": {
|
||||
"buildOptions": {
|
||||
"appId": "app.timesafari.app",
|
||||
"productName": "TimeSafari",
|
||||
"directories": {
|
||||
"output": "dist-electron-packages"
|
||||
},
|
||||
"files": [
|
||||
"dist/**/*",
|
||||
"electron/**/*"
|
||||
],
|
||||
"linux": {
|
||||
"target": ["AppImage", "deb"],
|
||||
"category": "Office"
|
||||
},
|
||||
"mac": {
|
||||
"target": ["dmg", "zip"],
|
||||
"category": "public.app-category.productivity"
|
||||
},
|
||||
"win": {
|
||||
"target": ["nsis", "portable"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Running the Packaged App
|
||||
|
||||
- **Linux**: AppImage files are self-contained executables
|
||||
- **macOS**: `.app` bundles can be dragged to Applications folder
|
||||
- **Windows**: `.exe` installers or portable executables
|
||||
|
||||
## Mobile Builds (Capacitor)
|
||||
|
||||
### Android Build
|
||||
|
||||
Prerequisites: Android Studio with Java SDK installed
|
||||
|
||||
#### Complete Build Process
|
||||
|
||||
Use the unified Android build script:
|
||||
|
||||
```bash
|
||||
./scripts/build-android.sh
|
||||
```
|
||||
|
||||
This script automatically:
|
||||
1. Sets up environment variables for Capacitor
|
||||
2. Cleans previous builds
|
||||
3. Builds web assets
|
||||
4. Builds Capacitor version
|
||||
5. Cleans and builds Gradle project
|
||||
6. Syncs with Capacitor
|
||||
7. Generates assets
|
||||
8. Opens Android Studio
|
||||
|
||||
#### Manual Steps (if needed)
|
||||
|
||||
If you need to run individual steps:
|
||||
|
||||
1. Build the web assets:
|
||||
```bash
|
||||
npm run build:web
|
||||
npm run build:capacitor
|
||||
```
|
||||
|
||||
2. Update Android project:
|
||||
```bash
|
||||
npx cap sync android
|
||||
```
|
||||
|
||||
3. Generate assets:
|
||||
```bash
|
||||
npx capacitor-assets generate --android
|
||||
```
|
||||
|
||||
4. Open in Android Studio:
|
||||
```bash
|
||||
npx cap open android
|
||||
```
|
||||
|
||||
#### Console Build
|
||||
|
||||
For building from the console:
|
||||
|
||||
```bash
|
||||
cd android
|
||||
./gradlew clean
|
||||
./gradlew build -Dlint.baselines.continue=true
|
||||
cd -
|
||||
```
|
||||
|
||||
For creating an `aab` file:
|
||||
|
||||
```bash
|
||||
cd android
|
||||
./gradlew bundleDebug -Dlint.baselines.continue=true
|
||||
cd -
|
||||
```
|
||||
|
||||
For creating a signed release:
|
||||
|
||||
1. Setup signing configuration in `app/gradle.properties.secrets`
|
||||
2. Add signing key file `app/time-safari-upload-key-pkcs12.jks`
|
||||
3. Update version in `app/build.gradle`
|
||||
4. Build release:
|
||||
```bash
|
||||
cd android
|
||||
./gradlew bundleRelease -Dlint.baselines.continue=true
|
||||
cd -
|
||||
```
|
||||
|
||||
The `aab` file will be at `app/build/outputs/bundle/release`.
|
||||
|
||||
### iOS Build
|
||||
|
||||
Prerequisites: macOS with Xcode installed
|
||||
|
||||
#### First-time iOS Configuration
|
||||
|
||||
- Generate certificates inside Xcode
|
||||
- Right-click on App and under Signing & Capabilities set the Team
|
||||
|
||||
#### Build Process
|
||||
|
||||
1. Build the web assets & update iOS:
|
||||
```bash
|
||||
npm run build:web
|
||||
npm run build:capacitor
|
||||
npx cap sync ios
|
||||
```
|
||||
|
||||
2. Generate assets:
|
||||
```bash
|
||||
# Create required directories
|
||||
mkdir -p ios/App/App/Assets.xcassets/AppIcon.appiconset
|
||||
echo '{"images":[]}' > ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json
|
||||
mkdir -p ios/App/App/Assets.xcassets/Splash.imageset
|
||||
echo '{"images":[]}' > ios/App/App/Assets.xcassets/Splash.imageset/Contents.json
|
||||
|
||||
# Generate assets
|
||||
npx capacitor-assets generate --ios
|
||||
```
|
||||
|
||||
3. Update version to match Android & package.json:
|
||||
```bash
|
||||
cd ios/App
|
||||
xcrun agvtool new-version 35
|
||||
perl -p -i -e "s/MARKETING_VERSION = .*;/MARKETING_VERSION = 1.0.2;/g" App.xcodeproj/project.pbxproj
|
||||
cd -
|
||||
```
|
||||
|
||||
4. Open in Xcode:
|
||||
```bash
|
||||
npx cap open ios
|
||||
```
|
||||
|
||||
5. Build and run on simulator or device using Xcode
|
||||
|
||||
#### Release Process
|
||||
|
||||
1. Choose Product -> Destination -> Any iOS Device
|
||||
2. Choose Product -> Archive
|
||||
3. Click Distribute -> App Store Connect
|
||||
4. In App Store Connect, add the build to the distribution
|
||||
|
||||
## Testing
|
||||
|
||||
### Complete Test Suite
|
||||
|
||||
Run all tests with automatic environment setup:
|
||||
|
||||
```bash
|
||||
./scripts/test-all.sh
|
||||
```
|
||||
|
||||
### Mobile Tests
|
||||
|
||||
Run mobile-specific tests:
|
||||
|
||||
```bash
|
||||
./scripts/test-mobile.sh
|
||||
```
|
||||
|
||||
### Environment Testing
|
||||
|
||||
Test environment variable handling:
|
||||
|
||||
```bash
|
||||
./scripts/test-env.sh
|
||||
```
|
||||
* Record the new hash in the changelog. Edit package.json to increment version & add "-beta", `npm install`, commit, and push. Also record what version is on production.
|
||||
|
||||
## Docker Deployment
|
||||
|
||||
@@ -556,11 +202,270 @@ docker run -d \
|
||||
- Check nginx configuration
|
||||
- Verify caching settings
|
||||
|
||||
## Configuration
|
||||
## Desktop Build (Electron)
|
||||
|
||||
### Deep Links
|
||||
### Linux Build
|
||||
|
||||
#### Android Configuration
|
||||
1. Build the electron app in production mode:
|
||||
|
||||
```bash
|
||||
npm run build:electron-prod
|
||||
```
|
||||
|
||||
2. Package the Electron app for Linux:
|
||||
|
||||
```bash
|
||||
# For AppImage (recommended)
|
||||
npm run electron:build-linux
|
||||
|
||||
# For .deb package
|
||||
npm run electron:build-linux-deb
|
||||
```
|
||||
|
||||
3. The packaged applications will be in `dist-electron-packages/`:
|
||||
- AppImage: `dist-electron-packages/TimeSafari-x.x.x.AppImage`
|
||||
- DEB: `dist-electron-packages/timesafari_x.x.x_amd64.deb`
|
||||
|
||||
### macOS Build
|
||||
|
||||
1. Build the electron app in production mode:
|
||||
|
||||
```bash
|
||||
npm run build:web
|
||||
npm run build:electron
|
||||
npm run electron:build-mac
|
||||
```
|
||||
|
||||
2. Package the Electron app for macOS:
|
||||
|
||||
```bash
|
||||
# For Intel Macs
|
||||
npm run electron:build-mac
|
||||
|
||||
# For Universal build (Intel + Apple Silicon)
|
||||
npm run electron:build-mac-universal
|
||||
```
|
||||
|
||||
3. The packaged applications will be in `dist-electron-packages/`:
|
||||
- `.app` bundle: `TimeSafari.app`
|
||||
- `.dmg` installer: `TimeSafari-x.x.x.dmg`
|
||||
- `.zip` archive: `TimeSafari-x.x.x-mac.zip`
|
||||
|
||||
### Code Signing and Notarization (macOS)
|
||||
|
||||
For public distribution on macOS, you need to code sign and notarize your app:
|
||||
|
||||
1. Set up environment variables:
|
||||
```bash
|
||||
export CSC_LINK=/path/to/your/certificate.p12
|
||||
export CSC_KEY_PASSWORD=your_certificate_password
|
||||
export APPLE_ID=your_apple_id
|
||||
export APPLE_ID_PASSWORD=your_app_specific_password
|
||||
```
|
||||
|
||||
2. Build with signing:
|
||||
```bash
|
||||
npm run electron:build-mac
|
||||
```
|
||||
|
||||
### Running the Packaged App
|
||||
|
||||
- **Linux**:
|
||||
- AppImage: Make executable and run
|
||||
```bash
|
||||
chmod +x dist-electron-packages/TimeSafari-*.AppImage
|
||||
./dist-electron-packages/TimeSafari-*.AppImage
|
||||
```
|
||||
- DEB: Install and run
|
||||
```bash
|
||||
sudo dpkg -i dist-electron-packages/timesafari_*_amd64.deb
|
||||
timesafari
|
||||
```
|
||||
|
||||
- **macOS**:
|
||||
- `.app` bundle: Double-click `TimeSafari.app` in Finder
|
||||
- `.dmg` installer:
|
||||
1. Double-click the `.dmg` file
|
||||
2. Drag the app to your Applications folder
|
||||
3. Launch from Applications
|
||||
- `.zip` archive:
|
||||
1. Extract the `.zip` file
|
||||
2. Move `TimeSafari.app` to your Applications folder
|
||||
3. Launch from Applications
|
||||
|
||||
Note: If you get a security warning when running the app:
|
||||
1. Right-click the app
|
||||
2. Select "Open"
|
||||
3. Click "Open" in the security dialog
|
||||
|
||||
### Development Testing
|
||||
|
||||
For testing the Electron build before packaging:
|
||||
|
||||
```bash
|
||||
# Build and run in development mode (includes DevTools)
|
||||
npm run electron:dev
|
||||
|
||||
# Build in production mode and test
|
||||
npm run build:electron-prod && npm run electron:start
|
||||
```
|
||||
|
||||
## Mobile Builds (Capacitor)
|
||||
|
||||
### iOS Build
|
||||
|
||||
Prerequisites: macOS with Xcode installed
|
||||
|
||||
#### First-time iOS Configuration
|
||||
|
||||
- Generate certificates inside XCode.
|
||||
|
||||
- Right-click on App and under Signing & Capabilities set the Team.
|
||||
|
||||
#### Each Release
|
||||
|
||||
0. First time (or if dependencies change):
|
||||
|
||||
- `pkgx +rubygems.org sh`
|
||||
|
||||
- ... and you may have to fix these, especially with pkgx:
|
||||
|
||||
```bash
|
||||
gem_path=$(which gem)
|
||||
shortened_path="${gem_path:h:h}"
|
||||
export GEM_HOME=$shortened_path
|
||||
export GEM_PATH=$shortened_path
|
||||
```
|
||||
|
||||
1. Build the web assets & update ios:
|
||||
|
||||
```bash
|
||||
rm -rf dist
|
||||
npm run build:web
|
||||
npm run build:capacitor
|
||||
npx cap sync ios
|
||||
```
|
||||
|
||||
- If that fails with "Could not find..." then look at the "gem_path" instructions above.
|
||||
|
||||
3. Copy the assets:
|
||||
|
||||
```bash
|
||||
# It makes no sense why capacitor-assets will not run without these but it actually changes the contents.
|
||||
mkdir -p ios/App/App/Assets.xcassets/AppIcon.appiconset
|
||||
echo '{"images":[]}' > ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json
|
||||
mkdir -p ios/App/App/Assets.xcassets/Splash.imageset
|
||||
echo '{"images":[]}' > ios/App/App/Assets.xcassets/Splash.imageset/Contents.json
|
||||
npx capacitor-assets generate --ios
|
||||
```
|
||||
|
||||
4. Bump the version to match Android & package.json:
|
||||
|
||||
```
|
||||
cd ios/App && xcrun agvtool new-version 35 && perl -p -i -e "s/MARKETING_VERSION = .*;/MARKETING_VERSION = 1.0.2;/g" App.xcodeproj/project.pbxproj && cd -
|
||||
# Unfortunately this edits Info.plist directly.
|
||||
#xcrun agvtool new-marketing-version 0.4.5
|
||||
```
|
||||
|
||||
5. Open the project in Xcode:
|
||||
|
||||
```bash
|
||||
npx cap open ios
|
||||
```
|
||||
|
||||
6. Use Xcode to build and run on simulator or device.
|
||||
|
||||
* Select Product -> Destination with some Simulator version. Then click the run arrow.
|
||||
|
||||
7. Release
|
||||
|
||||
* Someday: Under "General" we want to rename a bunch of things to "Time Safari"
|
||||
* Choose Product -> Destination -> Any iOS Device
|
||||
* Choose Product -> Archive
|
||||
* This will trigger a build and take time, needing user's "login" keychain password (user's login password), repeatedly.
|
||||
* If it fails with `building for 'iOS', but linking in dylib (.../.pkgx/zlib.net/v1.3.0/lib/libz.1.3.dylib) built for 'macOS'` then run XCode outside that terminal (ie. not with `npx cap open ios`).
|
||||
* Click Distribute -> App Store Connect
|
||||
* In AppStoreConnect, add the build to the distribution: remove the current build with the "-" when you hover over it, then "Add Build" with the new build.
|
||||
* May have to go to App Review, click Submission, then hover over the build and click "-".
|
||||
* It can take 15 minutes for the build to show up in the list of builds.
|
||||
* You'll probably have to "Manage" something about encryption, disallowed in France.
|
||||
* Then "Save" and "Add to Review" and "Resubmit to App Review".
|
||||
|
||||
### Android Build
|
||||
|
||||
Prerequisites: Android Studio with Java SDK installed
|
||||
|
||||
1. Build the web assets:
|
||||
|
||||
```bash
|
||||
rm -rf dist
|
||||
npm run build:web
|
||||
npm run build:capacitor
|
||||
```
|
||||
|
||||
2. Update Android project with latest build:
|
||||
|
||||
```bash
|
||||
npx cap sync android
|
||||
```
|
||||
|
||||
3. Copy the assets
|
||||
|
||||
```bash
|
||||
npx capacitor-assets generate --android
|
||||
```
|
||||
|
||||
4. Bump version to match iOS & package.json: android/app/build.gradle
|
||||
|
||||
5. Open the project in Android Studio:
|
||||
|
||||
```bash
|
||||
npx cap open android
|
||||
```
|
||||
|
||||
6. Use Android Studio to build and run on emulator or device.
|
||||
|
||||
## Android Build from the console
|
||||
|
||||
```bash
|
||||
cd android
|
||||
./gradlew clean
|
||||
./gradlew build -Dlint.baselines.continue=true
|
||||
cd -
|
||||
```
|
||||
|
||||
... or, to create the `aab` file, `bundle` instead of `build`:
|
||||
|
||||
```bash
|
||||
./gradlew bundleDebug -Dlint.baselines.continue=true
|
||||
```
|
||||
|
||||
... or, to create a signed release:
|
||||
|
||||
* Setup by adding the app/gradle.properties.secrets file (see properties at top of app/build.gradle) and the app/time-safari-upload-key-pkcs12.jks file
|
||||
* In app/build.gradle, bump the versionCode and maybe the versionName
|
||||
* Then `bundleRelease`:
|
||||
|
||||
```bash
|
||||
cd android
|
||||
./gradlew bundleRelease -Dlint.baselines.continue=true
|
||||
cd -
|
||||
```
|
||||
|
||||
... and find your `aab` file at app/build/outputs/bundle/release
|
||||
|
||||
At play.google.com/console:
|
||||
|
||||
- Go to the Testing Track (eg. Closed).
|
||||
- Click "Create new release".
|
||||
- Upload the `aab` file.
|
||||
- Hit "Next".
|
||||
- Save, go to "Publishing Overview" as prompted, and click "Send changes for review".
|
||||
|
||||
- Note that if you add testers, you have to go to "Publishing Overview" and send those changes or your (closed) testers won't see it.
|
||||
|
||||
|
||||
## Android Configuration for deep links
|
||||
|
||||
You must add the following intent filter to the `android/app/src/main/AndroidManifest.xml` file:
|
||||
|
||||
@@ -573,94 +478,4 @@ You must add the following intent filter to the `android/app/src/main/AndroidMan
|
||||
</intent-filter>
|
||||
```
|
||||
|
||||
Note: When using `timesafari://` scheme, you may encounter build errors about missing http(s) scheme and host attributes. This is expected for custom URL schemes.
|
||||
|
||||
#### iOS Configuration
|
||||
|
||||
For iOS deep links, configure the URL scheme in Xcode:
|
||||
|
||||
1. Open the project in Xcode
|
||||
2. Select your app target
|
||||
3. Go to Info tab
|
||||
4. Add URL Types with scheme `timesafari`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Environment Variables Not Set**
|
||||
- Use `--env` flag to check current environment: `./scripts/build-capacitor.sh --env`
|
||||
- Verify `.env` file exists and is properly formatted
|
||||
- Check script output for environment setup messages
|
||||
|
||||
2. **Build Failures**
|
||||
- Use `--verbose` flag for detailed logging: `./scripts/build-capacitor.sh --verbose`
|
||||
- Check prerequisites are installed
|
||||
- Verify all dependencies are installed: `npm install`
|
||||
|
||||
3. **Permission Issues**
|
||||
- Make scripts executable: `chmod +x scripts/*.sh`
|
||||
- Check file permissions on build directories
|
||||
|
||||
4. **Platform-Specific Issues**
|
||||
- **Android**: Verify Android Studio and SDK are properly configured
|
||||
- **iOS**: Ensure Xcode and certificates are set up correctly
|
||||
- **Electron**: Check Capacitor Electron platform installation
|
||||
|
||||
### Getting Help
|
||||
|
||||
- Check script help: `./scripts/build-capacitor.sh --help`
|
||||
- Review script documentation in `scripts/README.md`
|
||||
- Test environment setup: `./scripts/test-env.sh`
|
||||
- Test common utilities: `./scripts/test-common.sh`
|
||||
|
||||
### Platform Support Matrix
|
||||
|
||||
| Platform | Mode | PWA Enabled | Native Features | Notes |
|
||||
|----------|------|-------------|-----------------|-------|
|
||||
| `web` | web | true | false | Standard web browser |
|
||||
| `capacitor` | capacitor | false | true | Mobile app (iOS/Android) |
|
||||
| `electron` | capacitor | false | true | Desktop app (via Capacitor Electron) |
|
||||
|
||||
## Platform Service Architecture
|
||||
|
||||
TimeSafari uses a unified platform service architecture that works across all platforms:
|
||||
|
||||
### Platform Detection
|
||||
|
||||
The `CapacitorPlatformService` automatically detects the platform and adjusts capabilities:
|
||||
|
||||
```typescript
|
||||
getCapabilities(): PlatformCapabilities {
|
||||
const platform = Capacitor.getPlatform();
|
||||
const isElectron = platform === "electron";
|
||||
|
||||
return {
|
||||
hasFileSystem: true,
|
||||
hasCamera: true,
|
||||
isMobile: !isElectron, // false for Electron, true for mobile
|
||||
isIOS: platform === "ios",
|
||||
hasFileDownload: isElectron, // Electron can download files directly
|
||||
needsFileHandlingInstructions: !isElectron, // Mobile needs instructions
|
||||
isNativeApp: true,
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Unified Database Layer
|
||||
|
||||
All platforms use the same SQLite database through Capacitor plugins:
|
||||
|
||||
- **Mobile**: `@capacitor-community/sqlite` plugin
|
||||
- **Desktop**: Same plugin via Capacitor Electron
|
||||
- **Web**: IndexedDB fallback with absurd-sql
|
||||
|
||||
### Feature Parity
|
||||
|
||||
The same Capacitor plugins work across all platforms:
|
||||
|
||||
- File system operations
|
||||
- Camera access
|
||||
- SQLite database
|
||||
- Deep linking
|
||||
- Sharing functionality
|
||||
... though when we tried that most recently it failed to 'build' the APK with: http(s) scheme and host attribute are missing, but are required for Android App Links [AppLinkUrlError]
|
||||
|
||||
Reference in New Issue
Block a user