Repository navigation
docs: align README with current Child Timer and automate APK releases - #1
Conversation
Reviewer's GuideLe PR réaligne le README sur l’écran actuel du Child Timer, ajoute l’emplacement de sa capture, met en place une validation Android automatisée et fournit une chaîne de release par tag pour construire, signer et publier l’APK, tout en supprimant la configuration debug dépendante d’un keystore local. Sequence diagram for automated Android validation buildsequenceDiagram
participant GitHub as GitHub Actions
participant Build as Android build workflow
participant Gradle
participant APK as APK outputs
GitHub->>Build: push, pull_request, or workflow_dispatch
Build->>Gradle: testDebugUnitTest
Build->>Gradle: assembleDebug
Build->>Gradle: assembleRelease
Gradle-->>APK: debug and release APKs
Gradle-->>Build: unit test and build results
Sequence diagram for tagged signed APK releasesequenceDiagram
participant GitHub as GitHub Actions
participant Release as Release workflow
participant Gradle
participant Signer as apksigner
participant GitHubRelease as GitHub Release
GitHub->>Release: push tag v*
Release->>Release: validate signing secrets
Release->>Release: decode keystore
Release->>Gradle: assembleRelease
Gradle-->>Release: unsigned release APK
Release->>Signer: sign APK
Signer-->>Release: signed APK
Release->>Signer: verify APK
Release->>GitHubRelease: gh release create with APK
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
There was a problem hiding this comment.
Hey - I've found 6 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path=".github/workflows/release-apk.yml" line_range="9" />
<code_context>
+ - "v*"
+
+permissions:
+ contents: write
+
+jobs:
</code_context>
<issue_to_address>
**Build code can access release credentials**
When a tagged revision or Gradle dependency executes malicious build logic, the checkout action persists its credential, so Gradle build code can read the workflow's `contents: write` token from Git configuration and modify the repository or releases.
Set `persist-credentials: false` for checkout and provide release credentials only to the publishing step.
Also at `.github/workflows/release-apk.yml:17`.
</issue_to_address>
### Comment 2
<location path=".github/workflows/release-apk.yml" line_range="16" />
<code_context>
+ name: Build, sign and publish APK
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out tagged source
+ uses: actions/checkout@v7
+
</code_context>
<issue_to_address>
**Older build can win the release**
When a tag is force-updated while workflows for its old and new targets overlap, an older run checks out the commit from its tag-push event and can finish first, publishing that APK under the tag after the tag has moved to a newer commit; the newer run then cannot create the same release, so its artifact is not published.
Serialize release jobs by tag and verify the event commit is still the tag's target before publishing.
Also at `.github/workflows/release-apk.yml:80`.
</issue_to_address>
### Comment 3
<location path=".github/workflows/release-apk.yml" line_range="80" />
<code_context>
+ env:
+ GH_TOKEN: ${{ github.token }}
+ run: |
+ gh release create "$GITHUB_REF_NAME" "$SIGNED_APK" \
+ --title "Child Timer $GITHUB_REF_NAME" \
+ --generate-notes \
</code_context>
<issue_to_address>
**Failed upload leaves release incomplete**
When gitHub creates the release but uploading the APK fails, `gh release create` leaves the release record behind, and a retry exits when it encounters that existing release instead of attaching the APK, so users are left without a downloadable APK.
Make publishing idempotent by uploading or replacing the APK asset when the release already exists.
</issue_to_address>
### Comment 4
<location path=".github/workflows/release-apk.yml" line_range="50" />
<code_context>
+ - name: Build release variant
+ run: |
+ chmod +x gradlew
+ ./gradlew --no-daemon assembleRelease
+
+ - name: Sign and verify APK
</code_context>
<issue_to_address>
**Untested APK is published**
When a tag points to a commit whose unit tests have failed or have not passed, the release job runs `assembleRelease` without running `testDebugUnitTest` or waiting for the unit-test workflow, so it signs and publishes an unvalidated APK.
Require the unit-test workflow to pass before the release job signs and publishes the APK.
</issue_to_address>
### Comment 5
<location path=".github/workflows/android-build.yml" line_range="6" />
<code_context>
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ workflow_dispatch:
</code_context>
<issue_to_address>
**Feature branch pushes skip CI**
When a developer pushes to a non-main branch before opening a pull request, the `push` trigger matches only `main`, so pushes to other branches without a pull request event do not compile or test the change, despite the description promising validation on pushes.
Remove the branch restriction or configure the intended feature-branch push patterns.
</issue_to_address>
### Comment 6
<location path="README.md" line_range="14" />
<code_context>
+</div>
+
+<p align="center">
+ <img src="docs/screenshots/main-screen.png" alt="Child Timer en mode paysage : cadran circulaire et animaux pour choisir une durée" width="900">
+</p>
+
</code_context>
<issue_to_address>
**README screenshot is missing**
When the README is rendered before `docs/screenshots/main-screen.png` is added, the README references a screenshot file that the PR does not add, so readers see a broken image instead of the app preview.
Add the screenshot at the referenced path or remove the image reference until the file is present.
Also at `README.md:15`.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 5 findings to address first, and a bad or compromised v* tag can run release automation with access to the signing key and permission to publish an APK signed as the app. Reverting the workflow cannot retract a published APK or restore a signing key if it was exposed.
Blocking findings: .github/workflows/release-apk.yml:9, .github/workflows/release-apk.yml:16, .github/workflows/release-apk.yml:80, .github/workflows/release-apk.yml:50, .github/workflows/android-build.yml:6
| - "v*" | ||
|
|
||
| permissions: | ||
| contents: write |
There was a problem hiding this comment.
🟠 High · Build code can access release credentials
When a tagged revision or Gradle dependency executes malicious build logic, the checkout action persists its credential, so Gradle build code can read the workflow's contents: write token from Git configuration and modify the repository or releases.
Set persist-credentials: false for checkout and provide release credentials only to the publishing step.
Also at .github/workflows/release-apk.yml:17.
Prompt for AI agents
In `.github/workflows/release-apk.yml` at line 9:
**Build code can access release credentials**
When a tagged revision or Gradle dependency executes malicious build logic, the checkout action persists its credential, so Gradle build code can read the workflow's `contents: write` token from Git configuration and modify the repository or releases.
Set `persist-credentials: false` for checkout and provide release credentials only to the publishing step.
Also at `.github/workflows/release-apk.yml:17`.| name: Build, sign and publish APK | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Check out tagged source |
There was a problem hiding this comment.
🟡 Medium · Older build can win the release
When a tag is force-updated while workflows for its old and new targets overlap, an older run checks out the commit from its tag-push event and can finish first, publishing that APK under the tag after the tag has moved to a newer commit; the newer run then cannot create the same release, so its artifact is not published.
Serialize release jobs by tag and verify the event commit is still the tag's target before publishing.
Also at .github/workflows/release-apk.yml:80.
Prompt for AI agents
In `.github/workflows/release-apk.yml` at line 16:
**Older build can win the release**
When a tag is force-updated while workflows for its old and new targets overlap, an older run checks out the commit from its tag-push event and can finish first, publishing that APK under the tag after the tag has moved to a newer commit; the newer run then cannot create the same release, so its artifact is not published.
Serialize release jobs by tag and verify the event commit is still the tag's target before publishing.
Also at `.github/workflows/release-apk.yml:80`.| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: | | ||
| gh release create "$GITHUB_REF_NAME" "$SIGNED_APK" \ |
There was a problem hiding this comment.
🟡 Medium · Failed upload leaves release incomplete
When gitHub creates the release but uploading the APK fails, gh release create leaves the release record behind, and a retry exits when it encounters that existing release instead of attaching the APK, so users are left without a downloadable APK.
Make publishing idempotent by uploading or replacing the APK asset when the release already exists.
Prompt for AI agents
In `.github/workflows/release-apk.yml` at line 80:
**Failed upload leaves release incomplete**
When gitHub creates the release but uploading the APK fails, `gh release create` leaves the release record behind, and a retry exits when it encounters that existing release instead of attaching the APK, so users are left without a downloadable APK.
Make publishing idempotent by uploading or replacing the APK asset when the release already exists.| - name: Build release variant | ||
| run: | | ||
| chmod +x gradlew | ||
| ./gradlew --no-daemon assembleRelease |
There was a problem hiding this comment.
🟡 Medium · Untested APK is published
When a tag points to a commit whose unit tests have failed or have not passed, the release job runs assembleRelease without running testDebugUnitTest or waiting for the unit-test workflow, so it signs and publishes an unvalidated APK.
Require the unit-test workflow to pass before the release job signs and publishes the APK.
Prompt for AI agents
In `.github/workflows/release-apk.yml` at line 50:
**Untested APK is published**
When a tag points to a commit whose unit tests have failed or have not passed, the release job runs `assembleRelease` without running `testDebugUnitTest` or waiting for the unit-test workflow, so it signs and publishes an unvalidated APK.
Require the unit-test workflow to pass before the release job signs and publishes the APK.| on: | ||
| push: | ||
| branches: | ||
| - main |
There was a problem hiding this comment.
🟡 Medium · Feature branch pushes skip CI
When a developer pushes to a non-main branch before opening a pull request, the push trigger matches only main, so pushes to other branches without a pull request event do not compile or test the change, despite the description promising validation on pushes.
Remove the branch restriction or configure the intended feature-branch push patterns.
Prompt for AI agents
In `.github/workflows/android-build.yml` at line 6:
**Feature branch pushes skip CI**
When a developer pushes to a non-main branch before opening a pull request, the `push` trigger matches only `main`, so pushes to other branches without a pull request event do not compile or test the change, despite the description promising validation on pushes.
Remove the branch restriction or configure the intended feature-branch push patterns.
Résumé
docs/screenshots/main-screen.png.v*, qui construit, signe et joint l'APK à une GitHub Release.debug.keystoreabsent du dépôt ; Gradle utilisera sa signature debug standard.À faire avant une première release
docs/screenshots/main-screen.png(le README la référence déjà).ANDROID_KEYSTORE_BASE64,ANDROID_KEY_ALIAS,ANDROID_KEYSTORE_PASSWORDetANDROID_KEY_PASSWORD.applicationIdactuel avant la première publication.Le workflow de release ne publiera rien tant qu'un tag n'est pas poussé et que les secrets de signature ne sont pas renseignés. Le build n'a pas été exécuté localement depuis cet environnement ; le workflow de validation du PR doit le vérifier.
Summary by Sourcery
Align the project documentation with the current Child Timer application and establish automated Android build and signed APK release workflows.
New Features:
Bug Fixes:
Enhancements:
CI:
Deployment:
Documentation: