diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml new file mode 100644 index 0000000..0d8b22a --- /dev/null +++ b/.gitea/workflows/release.yaml @@ -0,0 +1,108 @@ +name: Release Build +run-name: Build and Release by ${{ gitea.actor }} + +on: + push: + branches: + - main + +jobs: + build-docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Build and Push Server + run: | + cd server + docker build -t ${{ vars.REGISTRY_URL }}/zen-kanji-server:latest . + docker push ${{ vars.REGISTRY_URL }}/zen-kanji-server:latest + + - name: Build and Push Client + run: | + cd client + docker build \ + --target production-stage \ + --build-arg VITE_API_URL=${{ vars.VITE_API_URL }} \ + -t ${{ vars.REGISTRY_URL }}/zen-kanji-client:latest . + docker push ${{ vars.REGISTRY_URL }}/zen-kanji-client:latest + + build-android-and-release: + runs-on: ubuntu-latest + needs: build-docker + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: "21" + distribution: "temurin" + + - name: Setup Android SDK (Manual) + run: | + export ANDROID_HOME=$HOME/android-sdk + CMDLINE_VERSION=11076708 + + mkdir -p $ANDROID_HOME/cmdline-tools + + echo "Downloading SDK..." + wget -q https://dl.google.com/android/repository/commandlinetools-linux-${CMDLINE_VERSION}_latest.zip -O cmdline-tools.zip + + unzip -q cmdline-tools.zip + mv cmdline-tools $ANDROID_HOME/cmdline-tools/latest + rm cmdline-tools.zip + + yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses || true + + echo "ANDROID_HOME=$ANDROID_HOME" >> $GITHUB_ENV + echo "ANDROID_SDK_ROOT=$ANDROID_HOME" >> $GITHUB_ENV + echo "$ANDROID_HOME/cmdline-tools/latest/bin" >> $GITHUB_PATH + echo "$ANDROID_HOME/platform-tools" >> $GITHUB_PATH + + - name: Install and Build Web App + working-directory: client + env: + VITE_API_URL: ${{ vars.VITE_API_URL }} + run: | + npm ci + npm run build:android + + - name: Sync Capacitor to Android + working-directory: client + run: npx cap sync android + + - name: Decode Keystore + run: | + cd client/android/app + echo "${{ secrets.ANDROID_KEYSTORE_BASE64 }}" | base64 -d > my-release-key.jks + + - name: Build Release APK + working-directory: client/android + env: + RELEASE_KEY_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_RELEASE_KEY_PASSWORD }} + RELEASE_KEY_ALIAS: ${{ secrets.ORG_GRADLE_PROJECT_RELEASE_KEY_ALIAS }} + run: | + chmod +x gradlew + ./gradlew assembleRelease + + - name: Create Release + uses: https://gitea.com/actions/gitea-release-action@v1 + with: + tag_name: v1.0.${{ gitea.run_number }} + name: Release v1.0.${{ gitea.run_number }} + body: | + Automated release for commit ${{ gitea.sha }}. + + **Docker Images:** + - Server: `${{ vars.REGISTRY }}/${{ vars.SERVER_IMAGE }}:latest` + - Client: `${{ vars.REGISTRY }}/${{ vars.CLIENT_IMAGE }}:latest` + files: | + client/android/app/build/outputs/apk/release/*.apk + api_key: ${{ secrets.GITHUB_TOKEN }} diff --git a/client/.env.android b/client/.env.android deleted file mode 100644 index e1418f3..0000000 --- a/client/.env.android +++ /dev/null @@ -1,2 +0,0 @@ -CAP_ENV=dev -VITE_API_URL=https://zenkanji-api.crylia.de diff --git a/client/.gitignore b/client/.gitignore index 0401cea..fa52c07 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -1,5 +1,3 @@ node_modules .env .env.android -my-release-key.jks -gradle.properties diff --git a/client/Dockerfile b/client/Dockerfile index 3e7e8cc..4d81fa8 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -1,15 +1,31 @@ -FROM node:24-alpine AS dev-stage +# Stage 1: Build the Application +FROM node:20-alpine AS build-stage WORKDIR /app +ARG VITE_API_URL +ENV VITE_API_URL=$VITE_API_URL + COPY package*.json ./ - RUN npm ci +COPY . . +RUN npm run build + +FROM node:20-alpine AS dev-stage +WORKDIR /app +COPY package*.json ./ +RUN npm ci COPY . . EXPOSE 5173 CMD ["npm", "run", "dev", "--", "--host"] -FROM dev-stage AS build-stage -ARG VITE_API_URL -ENV VITE_API_URL=$VITE_API_URL -RUN npm run build +FROM nginx:alpine AS production-stage +RUN mkdir -p /run/nginx + +COPY --from=build-stage /app/dist /usr/share/nginx/html + +COPY nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/client/android/app/build.gradle b/client/android/app/build.gradle index 266006c..1d78df7 100644 --- a/client/android/app/build.gradle +++ b/client/android/app/build.gradle @@ -16,12 +16,28 @@ android { } signingConfigs { release { + if (file("my-release-key.jks").exists()) { storeFile file("my-release-key.jks") - storePassword RELEASE_KEY_PASSWORD - keyAlias "my-key-alias" - keyPassword RELEASE_KEY_PASSWORD + if (project.hasProperty("RELEASE_KEY_PASSWORD")) { + storePassword RELEASE_KEY_PASSWORD + keyPassword RELEASE_KEY_PASSWORD + } else if (System.getenv("RELEASE_KEY_PASSWORD") != null) { + storePassword System.getenv("RELEASE_KEY_PASSWORD") + keyPassword System.getenv("RELEASE_KEY_PASSWORD") + } else { + storePassword "missing_password" + keyPassword "missing_password" + } + if (project.hasProperty("RELEASE_KEY_ALIAS")) { + keyAlias RELEASE_KEY_ALIAS + } else if (System.getenv("RELEASE_KEY_ALIAS") != null) { + keyAlias System.getenv("RELEASE_KEY_ALIAS") + } else { + keyAlias "my-key-alias" + } } } + } buildTypes { release { signingConfig signingConfigs.release diff --git a/client/android/gradle.properties b/client/android/gradle.properties new file mode 100644 index 0000000..5e2afb4 --- /dev/null +++ b/client/android/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx1536m +android.useAndroidX=true diff --git a/client/index.html b/client/index.html index 2d09bbf..515ee18 100644 --- a/client/index.html +++ b/client/index.html @@ -5,7 +5,7 @@