117 lines
6.3 KiB
Markdown
117 lines
6.3 KiB
Markdown
# To AI Agent: Implement Server-Hosted Android APK Download Button and Automated Build Deployment Pipeline
|
|
|
|
## 1. Context & Feature Objective
|
|
We are adding a native Android app distribution workflow directly from our self-hosted server backend. Instead of relying purely on app stores, users visiting the web version from an Android device must be able to download the official compiled `.apk` file directly.
|
|
|
|
**Objective:** 1. **Backend Asset Exposure:** Configure a secure, static file directory on the Node.js/Express server to host the production `.apk` binary.
|
|
2. **Build Pipeline Link Automation:** Create a post-build deployment shell script. Every time a new production Android APK is generated (`release`), the script must automatically rename and copy it to the backend's public distribution folder under a persistent file pointer name (`yotrip-latest.apk`).
|
|
3. **Frontend Action Button:** Add an interactive "Tải ứng dụng Android" action row with a download icon inside both the Member and Guest profile menu sheets.
|
|
|
|
---
|
|
|
|
## 2. Technical Architecture & Implementation Steps
|
|
|
|
[Android Build Output] ➔ [deploy-apk.sh Script] ➔ [Backend public/downloads/yotrip-latest.apk]
|
|
▲
|
|
[Frontend UI Button] ➔ ➔ ➔ [Triggers HTTP GET Request] ➔ ➔ ➔ ➔ ➔ ┛
|
|
|
|
### Step 1: Configure Backend Static Asset Folder
|
|
Locate the core server setup file (e.g., `server.ts`, `app.ts`, or `index.js`). Ensure a dedicated folder path named `public/downloads` is created and mapped to express static file serving handlers:
|
|
|
|
```typescript
|
|
import express from 'express';
|
|
import path from 'path';
|
|
|
|
const app = express();
|
|
|
|
// Ensure the directory exists: public/downloads/
|
|
const downloadsDir = path.join(__dirname, '../public/downloads');
|
|
|
|
/* ✅ BACKEND STATIC MIDDLEWARE REGISTRATION
|
|
This exposes the file at: [https://yourdomain.com/downloads/yotrip-latest.apk](https://yourdomain.com/downloads/yotrip-latest.apk)
|
|
*/
|
|
app.use('/downloads', express.static(downloadsDir, {
|
|
setHeaders: (res) => {
|
|
// Force browser engines to download the file directly instead of trying to parse it
|
|
res.set('Content-Type', 'application/vnd.android.package-archive');
|
|
res.set('Content-Disposition', 'attachment; filename="yotrip-latest.apk"');
|
|
}
|
|
}));
|
|
|
|
### Step 2: Automate APK Release Mapping Link (Post-Build Script)
|
|
Create an automation script file named scripts/deploy-apk.sh in the root environment. This script runs instantly after your Android compiler output is generated (e.g., via Gradle ./gradlew assembleRelease or Capacitor/Cordova build actions):
|
|
|
|
#!/bin/bash
|
|
|
|
# Define relative path coordinates
|
|
ANDROID_OUTPUT_PATH="./android/app/build/outputs/apk/release/app-release.apk"
|
|
BACKEND_TARGET_DIR="./backend/public/downloads"
|
|
TARGET_FILE_NAME="yotrip-latest.apk"
|
|
|
|
echo "🚀 Starting automated post-build Android deployment pipeline..."
|
|
|
|
# 1. Verify compiler target exists
|
|
if [ -f "$ANDROID_OUTPUT_PATH" ]; then
|
|
# 2. Ensure target storage folder structure is active
|
|
mkdir -p "$BACKEND_TARGET_DIR"
|
|
|
|
# 3. Copy and force overwrite the old production bundle with the updated version
|
|
cp -f "$ANDROID_OUTPUT_PATH" "$BACKEND_TARGET_DIR/$TARGET_FILE_NAME"
|
|
|
|
echo "✅ Success! New build copied safely to $BACKEND_TARGET_DIR/$TARGET_FILE_NAME"
|
|
echo "🔗 Direct Download Link Active: /downloads/$TARGET_FILE_NAME"
|
|
else
|
|
echo "❌ Critical Error: Android build output artifact not found at $ANDROID_OUTPUT_PATH"
|
|
exit 1
|
|
fi
|
|
|
|
Add "build:android": "cd android && ./gradlew assembleRelease && cd .. && sh scripts/deploy-apk.sh" inside package.json scripts matrix for unified execution hooks.
|
|
|
|
### Step 3: Add Download Trigger into Frontend UI (MapProfileDropdown.tsx)
|
|
Locate the unified dropdown menu component created in the previous layout consolidation phase. Inject the direct-download operational action rows:
|
|
|
|
// Define the static destination asset link helper
|
|
const APK_DOWNLOAD_URL = `${process.env.REACT_APP_API_BASE_URL || ''}/downloads/yotrip-latest.apk`;
|
|
|
|
/* --- INSIDE AUTHENTICATED MEMBER STACK SECTION --- */
|
|
<div className="flex flex-col space-y-1">
|
|
{/* Existing Dashboard, Profile, Create Tour rows... */}
|
|
|
|
{/* NEW: ANDROID APK DIRECT DOWNLOAD BUTTON */}
|
|
<a
|
|
href={APK_DOWNLOAD_URL}
|
|
download="yotrip.apk"
|
|
className="flex items-center gap-3 w-full px-4 py-3 hover:bg-slate-800 rounded-lg text-left text-xs text-slate-200 transition-colors"
|
|
>
|
|
<svg xmlns="[http://www.w3.org/2000/svg](http://www.w3.org/2000/svg)" className="w-4 h-4 text-green-400 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
|
<path strokeLinecap="round" strokeLinejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v1m-4-4l-4 4m0 0l-4-4m4 4V4" />
|
|
</svg>
|
|
<span>Tải ứng dụng Android (APK)</span>
|
|
</a>
|
|
</div>
|
|
|
|
/* --- INSIDE ANONYMOUS GUEST STACK SECTION --- */
|
|
<div className="flex flex-col space-y-1">
|
|
{/* Existing Guest language/theme configurations... */}
|
|
|
|
<div className="h-[1px] bg-slate-800 my-1 mx-2" />
|
|
|
|
{/* NEW: GUEST STATE ANDROID APK DOWNLOAD BUTTON */}
|
|
<a
|
|
href={APK_DOWNLOAD_URL}
|
|
download="yotrip.apk"
|
|
className="flex items-center gap-3 w-full px-4 py-3 hover:bg-slate-800 rounded-lg text-left text-xs text-slate-200 transition-colors"
|
|
>
|
|
<svg xmlns="[http://www.w3.org/2000/svg](http://www.w3.org/2000/svg)" className="w-4 h-4 text-green-400 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
|
<path strokeLinecap="round" strokeLinejoin="round" d="M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z" />
|
|
</svg>
|
|
<span>Cài đặt bản Android (.APK)</span>
|
|
</a>
|
|
|
|
{/* Existing Register/Login Button row below... */}
|
|
</div>
|
|
|
|
## 3. Verification & Acceptance Criteria for AI Agent
|
|
[ ] Deployment Script Validation: Run the build sequence script. Confirm that backend/public/downloads/yotrip-latest.apk updates its file modification timestamp matching the compiler execution timing logs.
|
|
[ ] Direct Download Header Safety: Trigger a request to GET /downloads/yotrip-latest.apk. The network tab response must show content-type: application/vnd.android.package-archive to guarantee mobile devices instantly trigger package installation workflows.
|
|
[ ] UI Integrity Test: Open the drop menu layout panel on a mobile simulator frame. Confirm that clicking the text icon row acts as a standard link target that downloads the binary file smoothly without breaking route navigation states. |