From d40a63ec4af95d77816d5c3098424892a17e1a08 Mon Sep 17 00:00:00 2001 From: gronod Date: Sun, 14 Jun 2026 11:28:14 +0100 Subject: [PATCH] ci: add release signing configuration and tag validation to workflows --- .gitea/workflows/release.yml | 58 +++++++++++++++++++++++++++++------ .github/workflows/release.yml | 38 +++++++++++++++++++---- app/build.gradle.kts | 13 ++++++++ 3 files changed, 93 insertions(+), 16 deletions(-) diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 473b380..741e3f0 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -1,3 +1,8 @@ +# Required Gitea secrets: +# SIGNING_KEYSTORE_BASE64 - base64-encoded Android release keystore +# SIGNING_STORE_PASSWORD - keystore password +# SIGNING_KEY_ALIAS - key alias +# SIGNING_KEY_PASSWORD - key password name: Build and Release APK on: @@ -8,9 +13,16 @@ on: jobs: build-and-release: runs-on: ubuntu-latest - permissions: - contents: write steps: + - name: Validate tag format + run: | + if [[ "${{ github.ref_name }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Tag ${{ github.ref_name }} is valid." + else + echo "Invalid tag format: ${{ github.ref_name }}. Expected vN.N.N" + exit 1 + fi + - name: Checkout Repository uses: actions/checkout@v4 @@ -26,14 +38,40 @@ jobs: - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 - - name: Test and Build Debug APK - run: chmod +x ./gradlew && ./gradlew test && ./gradlew assembleDebug + - name: Decode keystore + run: | + echo "${{ secrets.SIGNING_KEYSTORE_BASE64 }}" | base64 -d > release.keystore + + - name: Export signing environment variables + run: | + echo "SIGNING_STORE_FILE=$(pwd)/release.keystore" >> $GITHUB_ENV + echo "SIGNING_STORE_PASSWORD=${{ secrets.SIGNING_STORE_PASSWORD }}" >> $GITHUB_ENV + echo "SIGNING_KEY_ALIAS=${{ secrets.SIGNING_KEY_ALIAS }}" >> $GITHUB_ENV + echo "SIGNING_KEY_PASSWORD=${{ secrets.SIGNING_KEY_PASSWORD }}" >> $GITHUB_ENV + + - name: Test and Build Release APK + run: chmod +x ./gradlew && ./gradlew test assembleRelease - name: Rename APK - run: mv app/build/outputs/apk/debug/app-debug.apk app/build/outputs/apk/debug/esp32-aldl-dashboard-${{ github.ref_name }}.apk + run: | + mkdir -p artifacts + cp app/build/outputs/apk/release/app-release.apk artifacts/esp32-aldl-dashboard-${{ github.ref_name }}.apk - - name: Create Release and Upload APK - uses: softprops/action-gh-release@v2 - with: - files: app/build/outputs/apk/debug/esp32-aldl-dashboard-${{ github.ref_name }}.apk - \ No newline at end of file + - name: Create Gitea Release + id: create_release + run: | + response=$(curl -s -X POST \ + -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + -H "Content-Type: application/json" \ + -d "{\"tag_name\":\"${{ github.ref_name }}\",\"name\":\"Release ${{ github.ref_name }}\",\"body\":\"Auto-generated release for ${{ github.ref_name }}.\"}" \ + "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases") + echo "release_response=$response" >> $GITHUB_ENV + + - name: Upload APK to Gitea Release + run: | + upload_url=$(echo "$release_response" | grep -o '"url":"[^"]*' | head -1 | cut -d'"' -f4) + curl -s -X POST \ + -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + -H "Content-Type: application/vnd.android.package-archive" \ + --data-binary @artifacts/esp32-aldl-dashboard-${{ github.ref_name }}.apk \ + "${upload_url}/assets?name=esp32-aldl-dashboard-${{ github.ref_name }}.apk" \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 755b0a3..cfec5e8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,3 +1,8 @@ +# Required GitHub secrets: +# SIGNING_KEYSTORE_BASE64 - base64-encoded Android release keystore +# SIGNING_STORE_PASSWORD - keystore password +# SIGNING_KEY_ALIAS - key alias +# SIGNING_KEY_PASSWORD - key password name: Build and Release APK on: @@ -11,6 +16,15 @@ jobs: permissions: contents: write steps: + - name: Validate tag format + run: | + if [[ "${{ github.ref_name }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Tag ${{ github.ref_name }} is valid." + else + echo "Invalid tag format: ${{ github.ref_name }}. Expected vN.N.N" + exit 1 + fi + - name: Checkout Repository uses: actions/checkout@v4 @@ -26,15 +40,27 @@ jobs: - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 - - name: Test and Build Debug APK - run: chmod +x ./gradlew && ./gradlew test && ./gradlew assembleDebug + - name: Decode keystore + run: | + echo "${{ secrets.SIGNING_KEYSTORE_BASE64 }}" | base64 -d > release.keystore + + - name: Export signing environment variables + run: | + echo "SIGNING_STORE_FILE=$(pwd)/release.keystore" >> $GITHUB_ENV + echo "SIGNING_STORE_PASSWORD=${{ secrets.SIGNING_STORE_PASSWORD }}" >> $GITHUB_ENV + echo "SIGNING_KEY_ALIAS=${{ secrets.SIGNING_KEY_ALIAS }}" >> $GITHUB_ENV + echo "SIGNING_KEY_PASSWORD=${{ secrets.SIGNING_KEY_PASSWORD }}" >> $GITHUB_ENV + + - name: Test and Build Release APK + run: chmod +x ./gradlew && ./gradlew test assembleRelease - name: Rename APK - run: mv app/build/outputs/apk/debug/app-debug.apk app/build/outputs/apk/debug/esp32-aldl-dashboard-${{ github.ref_name }}.apk + run: | + mkdir -p artifacts + cp app/build/outputs/apk/release/app-release.apk artifacts/esp32-aldl-dashboard-${{ github.ref_name }}.apk - name: Create Release and Upload APK uses: softprops/action-gh-release@v2 with: - files: app/build/outputs/apk/debug/esp32-aldl-dashboard-${{ github.ref_name }}.apk - generate_release_notes: true - \ No newline at end of file + files: artifacts/esp32-aldl-dashboard-${{ github.ref_name }}.apk + generate_release_notes: true \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 21b1220..f138e19 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -16,8 +16,21 @@ android { versionName = "1.0" } + signingConfigs { + create("release") { + val storeFilePath = System.getenv("SIGNING_STORE_FILE") + if (storeFilePath != null) { + storeFile = file(storeFilePath) + storePassword = System.getenv("SIGNING_STORE_PASSWORD") + keyAlias = System.getenv("SIGNING_KEY_ALIAS") + keyPassword = System.getenv("SIGNING_KEY_PASSWORD") + } + } + } + buildTypes { release { + signingConfig = signingConfigs.getByName("release") isMinifyEnabled = false proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") }