You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

8.9 KiB

Building TimeSafari

This guide explains how to build TimeSafari for different platforms.

Prerequisites

For a quick dev environment setup, use pkgx.

  • Node.js (LTS version recommended)

  • npm (comes with Node.js)

  • Git

  • For Android builds: Android Studio with SDK installed

  • For iOS builds: macOS with Xcode and ruby gems & bundle

    • pkgx +rubygems.org sh

    • ... and you may have to fix these, especially with pkgx

    gem_path=$(which gem)
    shortened_path="${gem_path:h:h}"
    export GEM_HOME=$shortened_path
    export GEM_PATH=$shortened_path
    
  • For desktop builds: Additional build tools based on your OS

Forks

If you have forked this to make your own app, you'll want to customize the iOS & Android files. You can either edit existing ones, or you can remove the ios and android directories and regenerate them before the npx cap sync step in each setup.

npx cap add android
npx cap add ios

You'll also want to edit the deep link configuration (see below).

Initial Setup

Install dependencies:

npm install

Web Dev Locally

npm run dev

Web Build for Server

  1. Run the production build:

    npm run build
    

    The built files will be in the dist directory.

  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.

    npm run serve
    

Compile and minify for test & production

  • 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.

  • 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 later).

  • Tag with the new version, online or git tag 0.3.55 && git push origin 0.3.55.

  • For test, build the app (because test server is not yet set up to build):

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_PASSKEYS_ENABLED=true npm run build

... and transfer to the test server:

rsync -azvu -e "ssh -i ~/.ssh/..." dist ubuntutest@test.timesafari.app:time-safari

(Let's replace that with a .env.development or .env.staging file.)

(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.)

  • For prod, get on the server and run the correct build:

    ... and log onto the server:

    • pkgx +npm sh

    • cd crowd-funder-for-time-pwa && git checkout master && git pull && git checkout 0.3.55 && npm install && npm run build && cd -

    (The plain npm run build uses the .env.production file.)

  • Back up the time-safari/dist folder & deploy: mv time-safari/dist time-safari-dist-prev.0 && mv crowd-funder-for-time-pwa/dist time-safari/

  • Record the new hash in the changelog. Edit package.json to increment version & add "-beta", npm install, and commit. Also record what version is on production.

Docker Deployment

The application can be containerized using Docker for consistent deployment across environments.

Prerequisites

  • Docker installed on your system
  • Docker Compose (optional, for multi-container setups)

Building the Docker Image

  1. Build the Docker image:

    docker build -t timesafari:latest .
    
  2. For development builds with specific environment variables:

    docker build --build-arg NODE_ENV=development -t timesafari:dev .
    

Running the Container

  1. Run the container:

    docker run -d -p 80:80 timesafari:latest
    
  2. For development with hot-reloading:

    docker run -d -p 80:80 -v $(pwd):/app timesafari:dev
    

Using Docker Compose

Create a docker-compose.yml file:

version: '3.8'
services:
  timesafari:
    build: .
    ports:
      - "80:80"
    environment:
      - NODE_ENV=production
    restart: unless-stopped

Run with Docker Compose:

docker-compose up -d

Production Deployment

For production deployment, consider the following:

  1. Use specific version tags instead of 'latest'
  2. Implement health checks
  3. Configure proper logging
  4. Set up reverse proxy with SSL termination
  5. Use Docker secrets for sensitive data

Example production deployment:

# Build with specific version
docker build -t timesafari:1.0.0 .

# Run with production settings
docker run -d \
  --name timesafari \
  -p 80:80 \
  --restart unless-stopped \
  -e NODE_ENV=production \
  timesafari:1.0.0

Troubleshooting Docker

  1. Container fails to start

    • Check logs: docker logs <container_id>
    • Verify port availability
    • Check environment variables
  2. Build fails

    • Ensure all dependencies are in package.json
    • Check Dockerfile syntax
    • Verify build context
  3. Performance issues

    • Monitor container resources: docker stats
    • Check nginx configuration
    • Verify caching settings

Desktop Build (Electron)

Linux Build

  1. Build the electron app in production mode:

    npm run build:electron-prod
    
  2. Package the Electron app for Linux:

    # 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

Running the Packaged App

  • AppImage: Make executable and run

    chmod +x dist-electron-packages/TimeSafari-*.AppImage
    ./dist-electron-packages/TimeSafari-*.AppImage
    
  • DEB: Install and run

    sudo dpkg -i dist-electron-packages/timesafari_*_amd64.deb
    timesafari
    

Development Testing

For testing the Electron build before packaging:

# 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

  1. Build the web assets:

    npm run build:capacitor
    
  2. Update iOS project with latest build:

    npx cap sync ios
    
  3. Copy the assets:

    mkdir -p ios/App/App/Assets.xcassets/AppIcon.appiconset
    npx capacitor-assets generate --ios
    
  4. Open the project in Xcode:

    npx cap open ios
    
  5. Use Xcode to build and run on simulator or device.

First-time iOS Configuration

  • Generate certificates inside XCode.

  • Right-click on App and under Signing & Capabilities set the Team.

Android Build

Prerequisites: Android Studio with SDK installed

  1. Build the web assets:

    rm -rf dist
    npm run build:web
    npm run build:capacitor
    cd android
    ./gradlew clean
    ./gradlew assembleDebug
    
  2. Update Android project with latest build:

    npx cap sync android
    
  3. Copy the assets

    npx capacitor-assets generate --android
    
  4. Open the project in Android Studio:

    npx cap open android
    
  5. Use Android Studio to build and run on emulator or device.

Android Build from the console

cd android
./gradlew clean
./gradlew build -Dlint.baselines.continue=true
cd ..
npx cap run android

... or, to create the aab file, bundle instead of build:

./gradlew bundleDebug -Dlint.baselines.continue=true

... or, to create a signed release, add the app/gradle.properties.secrets file (see properties at top of app/build.gradle) and the app/time-safari-upload-key-pkcs12.jks file, then bundleRelease:

./gradlew bundleRelease -Dlint.baselines.continue=true

You must add the following intent filter to the android/app/src/main/AndroidManifest.xml file:

            <intent-filter android:autoVerify="true">
               <action android:name="android.intent.action.VIEW" />
               <category android:name="android.intent.category.DEFAULT" />
               <category android:name="android.intent.category.BROWSABLE" />
               <data android:scheme="timesafari" />
            </intent-filter>