summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/deploy_github_releases.yml126
-rw-r--r--AGENTS.md17
-rw-r--r--secrets/keystore.cipherbin0 -> 4288 bytes
-rw-r--r--secrets/props.cipherbin0 -> 176 bytes
4 files changed, 33 insertions, 110 deletions
diff --git a/.github/workflows/deploy_github_releases.yml b/.github/workflows/deploy_github_releases.yml
index 8dbdbcf5..5c5ea147 100644
--- a/.github/workflows/deploy_github_releases.yml
+++ b/.github/workflows/deploy_github_releases.yml
@@ -1,127 +1,41 @@
-name: Publish APS binaries to GitHub Releases
+name: Publish HardenedPass to GitHub Releases
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
jobs:
- build:
- name: Build release binaries
+ release:
+ name: Build and publish signed release
runs-on: ubuntu-latest
+ permissions:
+ contents: write
steps:
- name: Setup build environment
uses: danixland/Android-Password-Store/.github/reusable-workflows/setup-gradle@master
- - name: Decrypt secrets
+ - name: Decrypt signing secrets
shell: bash
run: scripts/signing-setup.sh "$ENCRYPT_KEY"
env:
ENCRYPT_KEY: ${{ secrets.ENCRYPT_KEY }}
- - name: Build release binaries
+ - name: Build signed release APK
shell: bash
- run: ./gradlew :app:assembleFreeRelease :app:assembleNonFreeRelease :app:bundleNonFreeRelease
- env:
- SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
-
- - name: Upload non-free release APK
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
- with:
- name: APS Non-Free Release APK
- path: app/build/outputs/apk/nonFree/release/app-nonFree-release.apk
-
- - name: Upload non-free release Bundle
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
- with:
- name: APS Non-Free Release Bundle
- path: app/build/outputs/bundle/nonFreeRelease/app-nonFree-release.aab
+ run: ./gradlew :app:assembleRelease
- - name: Upload free release APK
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
- with:
- name: APS Free Release APK
- path: app/build/outputs/apk/free/release/app-free-release.apk
-
- - name: Clean secrets
+ - name: Clean signing secrets
if: "${{ always() }}"
run: scripts/signing-cleanup.sh
- create_github_release:
- name: Create GitHub Release
- runs-on: ubuntu-latest
- needs: build
- steps:
- - name: Checkout
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
-
- - name: Get Non-Free Release APK
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
- with:
- name: APS Non-Free Release APK
- path: artifacts/nonFree
-
- - name: Get Non-Free Bundle
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
- with:
- name: APS Non-Free Release Bundle
- path: artifacts/nonFree
-
- - name: Get Free Release APK
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
- with:
- name: APS Free Release APK
- path: artifacts/free
-
- - name: Get Changelog Entry
- id: changelog_reader
- uses: mindsers/changelog-reader-action@32aa5b4c155d76c94e4ec883a223c947b2f02656 # v2.2.3
- with:
- version: ${{ github.ref }}
- path: ./CHANGELOG.md
-
- - name: Create Release
- id: create_release
- uses: actions/create-release@0cb9c9b65d5d1901c1f53e5e66eaf4afd303e70e # v1.1.4
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- tag_name: ${{ github.ref }}
- release_name: ${{ github.ref }}
- body: ${{ steps.changelog_reader.outputs.changes }}
- draft: true
- prerelease: false
-
- - name: Get the version
- id: get_version
- shell: bash
- run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
-
- - name: Upload Non-Free Release Apk
- uses: actions/upload-release-asset@e8f9f06c4b078e705bd2ea027f0926603fc9b4d5 # v1.0.2
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- upload_url: ${{ steps.create_release.outputs.upload_url }}
- asset_path: ./artifacts/nonFree/app-nonFree-release.apk
- asset_name: APS-nonFree_${{ steps.get_version.outputs.VERSION }}.apk
- asset_content_type: application/vnd.android.package-archive
-
- - name: Upload Non-Free Release Bundle
- uses: actions/upload-release-asset@e8f9f06c4b078e705bd2ea027f0926603fc9b4d5 # v1.0.2
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- upload_url: ${{ steps.create_release.outputs.upload_url }}
- asset_path: ./artifacts/nonFree/app-nonFree-release.aab
- asset_name: APS-nonFree_${{ steps.get_version.outputs.VERSION }}.aab
- asset_content_type: application/octet-stream
-
- - name: Upload Free Release Apk
- uses: actions/upload-release-asset@e8f9f06c4b078e705bd2ea027f0926603fc9b4d5 # v1.0.2
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- upload_url: ${{ steps.create_release.outputs.upload_url }}
- asset_path: ./artifacts/free/app-free-release.apk
- asset_name: APS-free_${{ steps.get_version.outputs.VERSION }}.apk
- asset_content_type: application/vnd.android.package-archive
+ - name: Create draft release
+ shell: bash
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ TAG: ${{ github.ref_name }}
+ run: |
+ apk="HardenedPass_${TAG}.apk"
+ cp app/build/outputs/apk/release/app-release.apk "$apk"
+ sha256sum "$apk" > "$apk.sha256"
+ gh release create "$TAG" "$apk" "$apk.sha256" --draft --title "$TAG" \
+ --notes "See [CHANGELOG.md](https://github.com/${GITHUB_REPOSITORY}/blob/${TAG}/CHANGELOG.md)."
diff --git a/AGENTS.md b/AGENTS.md
index 0222ad6b..887fcb2a 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -143,7 +143,16 @@ Last run: 2026-11-02.
## Releases
-Not set up yet. Upstream's encrypted signing keystore was removed (only upstream could decrypt
-it). `deploy_github_releases.yml` needs a keystore of our own, encrypted with
-`scripts/encrypt-secret.sh` into `secrets/`, and the `ENCRYPT_KEY` secret. A different signing
-key means the APK cannot update over upstream's install while `applicationId` is unchanged.
+Signed with the maintainer's own key (certificate `CN=HardenedPass`, SHA-256
+`72:50:16:66:9E:48:2F:9A:C3:71:DE:E8:DF:19:A2:A1:B3:4F:A7:6D:1A:F0:5B:2A:23:78:47:25:B1:B4:9C:83`).
+The master copy lives outside the repo, never in it. Losing it means installed copies can never
+be updated again.
+
+- Local: `keystore.jks` and `keystore.properties` at the repo root (gitignored, `/keystore.*`)
+ make `./gradlew :app:assembleRelease` produce a signed `app-release.apk`.
+- CI: `secrets/keystore.cipher` and `secrets/props.cipher` are those two files encrypted with
+ `openssl enc -aes-256-cbc -md sha256 -pbkdf2`; the key is the `ENCRYPT_KEY` repository
+ secret. `scripts/signing-setup.sh` decrypts them, `signing-cleanup.sh` deletes them.
+- Pushing a `vX.Y.Z` tag runs `deploy_github_releases.yml`: it builds the signed APK and creates
+ a draft GitHub Release with `HardenedPass_vX.Y.Z.apk` and its `.sha256`.
+- Never print, log or commit the keystore password or `ENCRYPT_KEY`.
diff --git a/secrets/keystore.cipher b/secrets/keystore.cipher
new file mode 100644
index 00000000..999cf521
--- /dev/null
+++ b/secrets/keystore.cipher
Binary files differ
diff --git a/secrets/props.cipher b/secrets/props.cipher
new file mode 100644
index 00000000..4afdd22b
--- /dev/null
+++ b/secrets/props.cipher
Binary files differ