ai-chat-android-auto / commit
Add GitLab CI pipeline for signed release builds
.gitlab-ci.yml | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 33 ++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..5f16305 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,61 @@ +# Triggered on any tag push. Push a tag of the form v1.2.3 to produce a +# signed release APK and publish it to the project's Releases page. +# +# Required CI/CD variables (Settings → CI/CD → Variables, all masked): +# KEYSTORE_BASE64 – release keystore encoded as base64 +# (generate with: base64 -i release.jks | pbcopy) +# KEYSTORE_STORE_PASSWORD – keystore password +# KEYSTORE_KEY_ALIAS – key alias inside the keystore +# KEYSTORE_KEY_PASSWORD – key password + +stages: + - build + - release + +build: + stage: build + image: jangrewe/gitlab-ci-android:34 + rules: + - if: $CI_COMMIT_TAG + before_script: + - chmod +x ./gradlew + - echo "$KEYSTORE_BASE64" | base64 -d > keystore.jks + - echo "release.storeFile=../keystore.jks" > local.properties + - echo "release.storePassword=$KEYSTORE_STORE_PASSWORD" >> local.properties + - echo "release.keyAlias=$KEYSTORE_KEY_ALIAS" >> local.properties + - echo "release.keyPassword=$KEYSTORE_KEY_PASSWORD" >> local.properties + script: + - ./gradlew assembleRelease + - | + curl --silent --show-error --fail \ + --header "JOB-TOKEN: $CI_JOB_TOKEN" \ + --upload-file app/build/outputs/apk/release/app-release.apk \ + "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/apk/${CI_COMMIT_TAG}/ai-chat-android-auto-${CI_COMMIT_TAG}.apk" + artifacts: + name: "ai-chat-android-auto-$CI_COMMIT_TAG" + paths: + - app/build/outputs/apk/release/app-release.apk + expire_in: 30 days + cache: + key: gradle + paths: + - .gradle/ + +release: + stage: release + image: registry.gitlab.com/gitlab-org/release-cli:latest + rules: + - if: $CI_COMMIT_TAG + needs: + - build + script: + - echo "Publishing release $CI_COMMIT_TAG" + release: + tag_name: $CI_COMMIT_TAG + name: "$CI_COMMIT_TAG" + description: "Download the signed APK from the assets section below." + assets: + links: + - name: "ai-chat-android-auto-$CI_COMMIT_TAG.apk" + url: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/apk/${CI_COMMIT_TAG}/ai-chat-android-auto-${CI_COMMIT_TAG}.apk" + link_type: package diff --git a/README.md b/README.md index 4336eec..379f5c2 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,38 @@ The interface requires two methods: ./gradlew assembleRelease ``` -Signing credentials go in `local.properties` (gitignored). See `local.properties.example`. +Signing credentials go in `local.properties` (gitignored): + +```properties +release.storeFile=path/to/release.jks +release.storePassword=... +release.keyAlias=... +release.keyPassword=... +``` + +--- + +## Releasing + +Push a tag to trigger the CI pipeline, which builds a signed APK, uploads it to +the Package Registry, and creates a GitLab Release with a download link. + +```bash +git tag v1.2.3 && git push origin v1.2.3 +``` + +The release will appear under **Deploy → Releases** in the GitLab sidebar. + +### CI/CD variables + +Configure these in **Settings → CI/CD → Variables** (all masked): + +| Variable | Description | +|---|---| +| `KEYSTORE_BASE64` | Release keystore encoded as base64 (`base64 -i release.jks`) | +| `KEYSTORE_STORE_PASSWORD` | Keystore password | +| `KEYSTORE_KEY_ALIAS` | Key alias within the keystore | +| `KEYSTORE_KEY_PASSWORD` | Key password | ---