Repository navigation
docs: align README with current Child Timer and automate APK releases #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d7abdf8
5fb1044
cc610c1
998ce30
36d247b
8edbf2c
232a899
21559e9
5e32325
42d2d30
255e584
91d02e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| name: Android build | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
| pull_request: | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| build: | ||
| name: Compile and test | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Check out repository | ||
| uses: actions/checkout@v7 | ||
|
|
||
| - name: Set up JDK 17 | ||
| uses: actions/setup-java@v6 | ||
| with: | ||
| distribution: temurin | ||
| java-version: "17" | ||
| cache: gradle | ||
|
|
||
| - name: Set up Android SDK | ||
| uses: android-actions/setup-android@v4 | ||
|
|
||
| - name: Install Android API 36 build tools | ||
| run: sdkmanager "platforms;android-36" "build-tools;36.0.0" | ||
|
|
||
| - name: Compile debug and release APKs and run unit tests | ||
| run: | | ||
| chmod +x gradlew | ||
| ./gradlew --no-daemon testDebugUnitTest assembleDebug assembleRelease | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| name: Build and publish Android APK | ||
|
|
||
| on: | ||
| push: | ||
| tags: | ||
| - "v*" | ||
|
|
||
| permissions: | ||
| contents: write | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟠 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 Set Also at Prompt for AI agentsIn `.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`. |
||
|
|
||
| jobs: | ||
| release: | ||
| name: Build, sign and publish APK | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Check out tagged source | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 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 Prompt for AI agentsIn `.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`. |
||
| uses: actions/checkout@v7 | ||
|
|
||
| - name: Set up JDK 17 | ||
| uses: actions/setup-java@v6 | ||
| with: | ||
| distribution: temurin | ||
| java-version: "17" | ||
| cache: gradle | ||
|
|
||
| - name: Set up Android SDK | ||
| uses: android-actions/setup-android@v4 | ||
|
|
||
| - name: Install Android API 36 build tools | ||
| run: sdkmanager "platforms;android-36" "build-tools;36.0.0" | ||
|
|
||
| - name: Validate signing secrets and decode keystore | ||
| env: | ||
| ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} | ||
| ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} | ||
| ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} | ||
| ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} | ||
| run: | | ||
| test -n "$ANDROID_KEYSTORE_BASE64" || { echo "::error::Missing secret ANDROID_KEYSTORE_BASE64"; exit 1; } | ||
| test -n "$ANDROID_KEY_ALIAS" || { echo "::error::Missing secret ANDROID_KEY_ALIAS"; exit 1; } | ||
| test -n "$ANDROID_KEYSTORE_PASSWORD" || { echo "::error::Missing secret ANDROID_KEYSTORE_PASSWORD"; exit 1; } | ||
| test -n "$ANDROID_KEY_PASSWORD" || { echo "::error::Missing secret ANDROID_KEY_PASSWORD"; exit 1; } | ||
| printf '%s' "$ANDROID_KEYSTORE_BASE64" | base64 --decode > "$RUNNER_TEMP/child-timer-release.jks" | ||
| test -s "$RUNNER_TEMP/child-timer-release.jks" | ||
| echo "ANDROID_SIGNING_KEYSTORE=$RUNNER_TEMP/child-timer-release.jks" >> "$GITHUB_ENV" | ||
|
|
||
| - name: Build release variant | ||
| run: | | ||
| chmod +x gradlew | ||
| ./gradlew --no-daemon assembleRelease | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 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 Require the unit-test workflow to pass before the release job signs and publishes the APK. Prompt for AI agentsIn `.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. |
||
|
|
||
| - name: Sign and verify APK | ||
| env: | ||
| ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} | ||
| ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} | ||
| ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} | ||
| run: | | ||
| UNSIGNED_APK="app/build/outputs/apk/release/app-release-unsigned.apk" | ||
| test -f "$UNSIGNED_APK" || { echo "::error::Unsigned release APK not found at $UNSIGNED_APK"; exit 1; } | ||
|
|
||
| SDK_ROOT="${ANDROID_SDK_ROOT:-$ANDROID_HOME}" | ||
| APKSIGNER="$SDK_ROOT/build-tools/36.0.0/apksigner" | ||
| test -x "$APKSIGNER" || { echo "::error::apksigner not found at $APKSIGNER"; exit 1; } | ||
|
|
||
| SIGNED_APK="ChildTimer-${GITHUB_REF_NAME}.apk" | ||
| "$APKSIGNER" sign \ | ||
| --ks "$ANDROID_SIGNING_KEYSTORE" \ | ||
| --ks-key-alias "$ANDROID_KEY_ALIAS" \ | ||
| --ks-pass "env:ANDROID_KEYSTORE_PASSWORD" \ | ||
| --key-pass "env:ANDROID_KEY_PASSWORD" \ | ||
| --out "$SIGNED_APK" \ | ||
| "$UNSIGNED_APK" | ||
| "$APKSIGNER" verify --verbose "$SIGNED_APK" | ||
| echo "SIGNED_APK=$SIGNED_APK" >> "$GITHUB_ENV" | ||
|
|
||
| - name: Publish GitHub Release | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: | | ||
| gh release create "$GITHUB_REF_NAME" "$SIGNED_APK" \ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Medium · Failed upload leaves release incomplete When gitHub creates the release but uploading the APK fails, Make publishing idempotent by uploading or replacing the APK asset when the release already exists. Prompt for AI agentsIn `.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. |
||
| --title "Child Timer $GITHUB_REF_NAME" \ | ||
| --generate-notes \ | ||
| --verify-tag | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,60 +1,178 @@ | ||
| # Child Timer 🦁⏱️ | ||
|
|
||
| A cheerful, modern Android visual countdown timer for children, built with Kotlin and Jetpack Compose. Inspired by visual time discs (like the Time Timer), **Child Timer** makes the passage of time concrete, friendly, and engaging for toddlers and young kids through delightful animal companions, routine presets, sound cues, and celebratory star rewards. | ||
|
|
||
| --- | ||
|
|
||
| ## ✨ Features | ||
|
|
||
| - **12 Adorable Animal Companions:** | ||
| - 🦁 **Leo the Lion** (*Léo le Lion*) - Brave & energetic | ||
| - 🦊 **Rusty the Fox** (*Rox le Renard*) - Clever & quick | ||
| - 🐰 **Bunny Hop** (*Pompom le Lapin*) - Playful & joyful | ||
| - 🐼 **Bamboo Panda** (*Bambou le Panda*) - Calm & serene | ||
| - 🦒 **Gigi the Giraffe** (*Gigi la Girafe*) - Tall & curious | ||
| - 🐻 **Barnaby Bear** (*Barnabé l'Ours*) - Big warm hugs | ||
| - 🐒 **Milo the Monkey** (*Ouistiti le Singe*) - Cheerful acrobat | ||
| - 🐊 **Chomp the Croc** (*Croc le Croco*) - Sparkling shiny teeth | ||
| - 🦉 **Hoot the Owl** (*Hibou Sage*) - Wise & focused | ||
| - 🦓 **Zigzag Zebra** (*Zigzag le Zèbre*) - Fast striped sprinter | ||
| - 🐿️ **Nutty Squirrel** (*Noisette l'Écureuil*) - Acorn collector | ||
| - 🐘 **Peanut Elephant** (*Pif l'Éléphant*) - Strong & patient | ||
|
|
||
| - **Visual Countdown Dial:** | ||
| - Time-Timer style colored sweep wedge that shrinks as time passes. | ||
| - Centered animal avatar with breathing pulse animation during countdown. | ||
| - Big, legible MM:SS digital readout. | ||
|
|
||
| - **Routine Presets:** | ||
| - 🪥 **Brush Teeth:** 2 minutes | ||
| - 🧸 **Tidy Up Toys:** 5 minutes | ||
| - 📖 **Story Time:** 10 minutes | ||
| - 🎨 **Drawing & Craft:** 15 minutes | ||
| - 🛁 **Bath & Bubbles:** 20 minutes | ||
| - 💤 **Quiet Nap / Rest:** 30 minutes | ||
| - ⏱️ **Custom Time:** Quick adjustment (+1m, +5m, -1m) | ||
|
|
||
| - **Sound & Haptics Feedback:** | ||
| - Sweet synthesized chimes for Start, Pause, and Completion fanfare via Android's `ToneGenerator`. | ||
| - Optional soft ticking every second. | ||
| - Haptic vibration feedback for tactile responses. | ||
|
|
||
| - **Celebration & Rewards:** | ||
| - Bursting confetti animation on countdown completion. | ||
| - Celebratory animal victory quotes. | ||
| - Star Trophy counter (`+1 ⭐`) to celebrate positive habits and completed routines. | ||
|
|
||
| - **Child Lock & Screen Awake:** | ||
| - Child lock preventing toddlers from accidentally stopping or altering the timer. | ||
| - Keeps the device screen awake during active countdowns. | ||
|
|
||
| --- | ||
|
|
||
| ## 🛠️ Tech Stack & Architecture | ||
|
|
||
| - **Language:** Kotlin 2.3 | ||
| - **UI Framework:** Jetpack Compose (Material Design 3) | ||
| - **Architecture:** MVVM (Model-View-ViewModel) with Kotlin Coroutines and StateFlow | ||
| - **Navigation:** Android Navigation 3 | ||
| - **Audio & Haptics:** `android.media.ToneGenerator` & `android.os.Vibrator` | ||
| - **Target SDK:** 36 (Android 16) / Min SDK: 24 (Android 7.0) | ||
| <div align="center"> | ||
| <h1><img src="app/src/main/res/drawable/ic_app_fox.png" alt="" width="48" valign="middle"> Child Timer</h1> | ||
| <p><strong>Le temps devient visible, simplement.</strong></p> | ||
| <p>Un minuteur visuel Android conçu pour aider les enfants à comprendre le temps qui passe, sans chiffres au cadran ni compte à rebours numérique.</p> | ||
| <p> | ||
| <img src="https://img.shields.io/badge/Plateforme-Android-3DDC84?logo=android&logoColor=white" alt="Android"> | ||
| <img src="https://img.shields.io/badge/Minimum-Android%207.0%2B-4285F4" alt="Android 7.0 minimum"> | ||
| <img src="https://img.shields.io/badge/Langage-Kotlin-7F52FF?logo=kotlin&logoColor=white" alt="Kotlin"> | ||
| <img src="https://img.shields.io/badge/Interface-Jetpack%20Compose-4285F4" alt="Jetpack Compose"> | ||
| </p> | ||
| </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"> | ||
|
sourcery-ai[bot] marked this conversation as resolved.
Resolved
|
||
| </p> | ||
|
|
||
| <p align="center"> | ||
| <a href="ChildTimer.apk?raw=1"><strong>⬇️ Télécharger l’APK Android (build de test)</strong></a><br> | ||
| <sub>Le fichier actuel est identique à <code>app-debug.apk</code>. Pour une version de production signée, consulte les GitHub Releases.</sub> | ||
| </p> | ||
|
|
||
| ## 🧸 À propos | ||
|
|
||
| **Child Timer** est une application Android minimaliste qui représente une durée sous la forme d'un secteur coloré sur un cadran. L'enfant choisit l'un des animaux placés autour du cadran, puis lance le timer. Le secteur turquoise se réduit progressivement jusqu'à la fin du temps choisi. | ||
|
|
||
| L'interface est volontairement immersive : elle fonctionne en **paysage**, masque les barres système Android et maintient l'écran éveillé pendant l'utilisation. | ||
|
|
||
| ## ✨ Fonctionnalités | ||
|
|
||
| - **12 animaux illustrés** disposés autour du cadran. | ||
| - **Durées de 5 à 60 minutes**, par pas de 5 minutes : un animal correspond à une durée. | ||
| - **Cadran sans chiffres** et sans affichage numérique du temps restant. | ||
| - **Secteur turquoise animé** qui matérialise le temps disponible puis diminue pendant le décompte. | ||
| - **Bouton Lecture** qui apparaît après le choix d'un animal. | ||
| - **Retour sonore doux** lors de la sélection et du démarrage, puis une mélodie à la fin. | ||
| - **Vibrations discrètes** pour accompagner certaines interactions. | ||
| - **Petite célébration visuelle** à la fin du timer, avec des étoiles et un renard au centre. | ||
| - **Plein écran paysage** pour que le cadran reste au centre de l'expérience. | ||
|
|
||
| ### Les animaux et leurs durées | ||
|
|
||
| | Position du cadran | Animal | Durée | | ||
| |---|---|---:| | ||
| | 1 h | <img src="app/src/main/res/drawable/ours.png" alt="Ours" width="42"> Ours | 5 min | | ||
| | 2 h | <img src="app/src/main/res/drawable/hibou.png" alt="Hibou" width="42"> Hibou | 10 min | | ||
| | 3 h | <img src="app/src/main/res/drawable/lapin.png" alt="Lapin" width="42"> Lapin | 15 min | | ||
| | 4 h | <img src="app/src/main/res/drawable/renard.png" alt="Renard" width="42"> Renard | 20 min | | ||
| | 5 h | <img src="app/src/main/res/drawable/croco.png" alt="Croco" width="42"> Croco | 25 min | | ||
| | 6 h | <img src="app/src/main/res/drawable/zebre.png" alt="Zèbre" width="42"> Zèbre | 30 min | | ||
| | 7 h | <img src="app/src/main/res/drawable/singe.png" alt="Singe" width="42"> Singe | 35 min | | ||
| | 8 h | <img src="app/src/main/res/drawable/elephant.png" alt="Éléphant" width="42"> Éléphant | 40 min | | ||
| | 9 h | <img src="app/src/main/res/drawable/girafe.png" alt="Girafe" width="42"> Girafe | 45 min | | ||
| | 10 h | <img src="app/src/main/res/drawable/ecureuil.png" alt="Écureuil" width="42"> Écureuil | 50 min | | ||
| | 11 h | <img src="app/src/main/res/drawable/panda.png" alt="Panda" width="42"> Panda | 55 min | | ||
| | 12 h | <img src="app/src/main/res/drawable/lion.png" alt="Lion" width="42"> Lion | 60 min | | ||
|
|
||
|
|
||
| ## ▶️ Utilisation | ||
|
|
||
| 1. Ouvre l'application en mode paysage. | ||
| 2. Touche l'animal correspondant à la durée souhaitée. Le secteur turquoise montre la durée sélectionnée. | ||
| 3. Appuie sur le gros bouton **Lecture** qui apparaît à droite. | ||
| 4. Laisse l'enfant observer le secteur diminuer. À la fin, une animation, un son et une vibration signalent que le temps est écoulé. | ||
|
|
||
| ### Commandes disponibles | ||
|
|
||
| - **Activer ou couper le son :** maintenir le petit moyeu au centre du cadran pendant environ 3 secondes. | ||
| - **Réinitialiser avant la fin :** toucher rapidement le moyeu central 10 fois. | ||
| - **Revenir au choix de durée après la fin :** toucher le renard au centre. | ||
|
|
||
| > Le contrôle du son et la réinitialisation reposent actuellement sur des gestes cachés, plutôt que sur des boutons visibles. | ||
|
|
||
| ## 📱 Compatibilité | ||
|
|
||
| - Android **7.0 (API 24) ou supérieur**. | ||
| - Interface prévue pour le **paysage**. | ||
| - SDK Android ciblé : **36**. | ||
|
|
||
| ## 🛠️ Technologies | ||
|
|
||
| - **Kotlin** | ||
| - **Jetpack Compose** et Material 3 | ||
| - **Android Gradle Plugin 9.0.1** | ||
| - **Gradle 9.1.0** | ||
| - **JDK 17** | ||
| - Sons synthétisés localement via <code>AudioTrack</code> et retour haptique via les API Android. | ||
|
|
||
| ## 🔧 Construire l'application | ||
|
|
||
| ### Prérequis | ||
|
|
||
| Installe un JDK 17 et le SDK Android avec la plateforme Android API 36. | ||
|
|
||
| ### Compiler et tester | ||
|
|
||
| Sur Linux ou macOS : | ||
|
|
||
| ~~~bash | ||
| ./gradlew testDebugUnitTest assembleDebug | ||
| ~~~ | ||
|
|
||
| Sur Windows : | ||
|
|
||
| ~~~bat | ||
| gradlew.bat testDebugUnitTest assembleDebug | ||
| ~~~ | ||
|
|
||
| L'APK de débogage est généré dans : | ||
|
|
||
| ~~~text | ||
| app/build/outputs/apk/debug/app-debug.apk | ||
| ~~~ | ||
|
|
||
| Pour produire la variante release non signée localement : | ||
|
|
||
| ~~~bash | ||
| ./gradlew assembleRelease | ||
| ~~~ | ||
|
|
||
| La variante release n'est pas installable tant qu'elle n'a pas été signée. La procédure de publication automatique est décrite ci-dessous. | ||
|
|
||
| ## 📦 Publier une release APK | ||
|
|
||
| Le workflow GitHub Actions <code>.github/workflows/release-apk.yml</code> est conçu pour construire, signer et joindre l'APK à une **GitHub Release** lorsqu'un tag <code>v*</code> est poussé. Il nécessite une clé de signature privée, à conserver hors du dépôt. | ||
|
|
||
| ### 1. Créer une clé de signature | ||
|
|
||
| Sur ta machine, exécute : | ||
|
|
||
| ~~~bash | ||
| keytool -genkeypair -v -keystore child-timer-release.jks -alias child-timer -keyalg RSA -keysize 2048 -validity 10000 | ||
| ~~~ | ||
|
|
||
| **Conserve précieusement ce fichier et ses mots de passe. Ne commite jamais la clé dans Git.** La même clé doit être réutilisée pour les prochaines versions afin de permettre les mises à jour de l'application. | ||
|
|
||
| ### 2. Ajouter les secrets GitHub | ||
|
|
||
| Dans **Settings → Secrets and variables → Actions**, crée les secrets suivants : | ||
|
|
||
| - <code>ANDROID_KEYSTORE_BASE64</code> : contenu Base64 du fichier <code>.jks</code>. | ||
| - <code>ANDROID_KEY_ALIAS</code> : alias utilisé à la création de la clé (ici <code>child-timer</code>). | ||
| - <code>ANDROID_KEYSTORE_PASSWORD</code> : mot de passe du keystore. | ||
| - <code>ANDROID_KEY_PASSWORD</code> : mot de passe de la clé. | ||
|
|
||
| Sous Windows PowerShell, cette commande copie le contenu Base64 du keystore dans le presse-papiers : | ||
|
|
||
| ~~~powershell | ||
| [Convert]::ToBase64String([IO.File]::ReadAllBytes(".\child-timer-release.jks")) | Set-Clipboard | ||
| ~~~ | ||
|
|
||
| Colle cette valeur uniquement dans le secret GitHub correspondant, jamais dans un fichier du dépôt. | ||
|
|
||
| ### 3. Déclencher la publication | ||
|
|
||
| La version actuelle du projet indique <code>versionName = "1.0"</code>. Après avoir vérifié la version et la configuration, crée puis pousse le tag correspondant : | ||
|
|
||
| ~~~bash | ||
| git tag v1.0 | ||
| git push origin v1.0 | ||
| ~~~ | ||
|
|
||
| Le workflow construit un APK release, le signe, vérifie sa signature puis crée une release avec l'APK en pièce jointe. Les prochaines versions devront augmenter <code>versionCode</code> et mettre à jour <code>versionName</code> dans <code>app/build.gradle.kts</code> avant de pousser leur tag. | ||
|
|
||
| **Avant la toute première release publique**, vérifie également que l'identifiant Android <code>applicationId = "com.aistudio.childtimer.kxrqzp"</code> est bien celui que tu souhaites conserver. Le changer après la publication empêcherait l'APK suivant d'être reconnu comme une mise à jour de cette application. | ||
|
|
||
| Pour installer rapidement la build de test, utilise le lien de téléchargement en haut du README. Les versions de production signées seront disponibles dans les [GitHub Releases](https://github.com/aciderix/Child-timer/releases) une fois la clé de signature configurée. | ||
|
|
||
| ## 🔒 Confidentialité | ||
|
|
||
| Le manifeste Android ne déclare pas de permission réseau ; il déclare uniquement la permission de vibration. Les sons du timer sont synthétisés localement. L'application n'a pas besoin de compte utilisateur pour son fonctionnement actuel. | ||
|
|
||
| ## 🧭 Périmètre actuel | ||
|
|
||
| Cette version est centrée sur le cadran animalier. Elle ne propose pas encore de compte à rebours chiffré, de pause/reprise, de préréglages de routines, de durée personnalisée ou d'historique. Le README décrit volontairement le fonctionnement de l'écran réellement lancé par l'application, et non les anciennes interfaces présentes dans le code source. | ||
|
|
||
| ## 📄 Licence | ||
|
|
||
| Aucun fichier de licence n'est actuellement fourni dans le dépôt. Les conditions de réutilisation et de redistribution restent donc à définir. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 Medium · Feature branch pushes skip CI
When a developer pushes to a non-main branch before opening a pull request, the
pushtrigger matches onlymain, 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