Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Navitabs
rootGravid i DK (Android) - Leverancebeskrivelse


Indholdsfortegnelse

Table of Contents


Introduktion

Formål

Formålet med dette dokument, er at beskrive systemkrav og opsætning for udviklere på projektet. Desuden beskrive en række værktøjer, der hjælper med udviklingen, som er anvendt i projektet.

Sammenhæng med øvrige dokumenter

-


Udvikling

Krav for at bygge projektet

For at bygge projektet skal det åbnes i Android Studio (https://developer.android.com/studio - Version 4.2+ - Projektet er senest udviklet og bygget med version 2025.1.4) og derefter vil alle dependencies blive synkroniseret vha. gradle.

Appen bruger JDK 17 og Gradle 8.14.3.

Dertil kræver byg af APK/bundles eller Release versioner at man har oprettet en local.properties  fil i roden af projektet, som indeholder keystore password, key alias og key password i formattet:

Code Block
keystore_password=SuperSecretPassword
private_alias=MyKeyAlias
private_password=MyPrivatePasswordHere

Det er vigtigt at denne fil IKKE ikke uploades til version control (Den er pt. inkluderet i .gitignore), da denne ikke skal være offentlig tilgængelig. Der er ikke en afklaring på, hvordan denne fil deles mellem udviklere.

Ovenstående er subject for change ifb.

Jira
serverNSI JIRA
serverIde64c3bc3-001c-3439-bc53-f7a235a8cd61
keyDGAF-1937

NSP Header

I Android Studio (som er en variant af IntelliJ) skal man huske at tilføje NSP's copyright header under Preferences → Editor → Copyright → Copyright Profiles. For at lave en generisk header som skifter copyright årstal, kan følgende template bruges:

Code Block
titleNSP Header til IntelliJ
The MIT License
  
Original work sponsored and donated by The Danish Health Data Authority (http://www.sundhedsdatastyrelsen.dk)
  
Copyright (C) $today.year The Danish Health Data Authority (http://www.sundhedsdatastyrelsen.dk)
  
  
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
  
  
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
  
  
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Når dette er sat, vil alle filer i projektet få indsat headeren automatisk ved oprettelse af filen.

Tools

Projektet indeholder en række tools, der anvendes under udvikling.

Generering af strings.xml

Alle strings er oprettet i et Localizely projekt (Claus Leth Gregersen er owner på projektet): https://app.localizely.com/projects/3278b0a4-b1a5-4277-ba70-3159fb9dac9b/main/dashboard

...

NSP Header

I Android Studio (som er en variant af IntelliJ) skal man tilføje NSP's copyright header under Preferences → Editor → Copyright → Copyright Profiles. 

For at lave en generisk header som skifter copyright årstal, kan følgende template bruges:

Code Block
titleNSP Header til IntelliJ
The MIT License

Original work sponsored and donated by The Danish Health Data Authority (http://www.sundhedsdatastyrelsen.dk)

Copyright (C) $originalComment.match("Copyright \(C\) (\d+)", 1, "-")$today.year The Danish Health Data Authority (http://www.sundhedsdatastyrelsen.dk)


Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:


The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.


THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Når dette er sat, vil alle filer i projektet få indsat headeren automatisk ved oprettelse af filen. Den påkrævede copyright på filerne bliver også opretholdt ved hjælp af Spotless, som fejler hvis den scanner .kt, .kts eller .xml filer uden headeren.

Copyright headeren som Spotless bruger ligger i mappen spotless/ med versioner til hver af de 3 filtyper som kræver headeren.

spotless
├── copyright.kt
├── copyright.kts
└── copyright.xml

Tools

Projektet indeholder en række tools, der anvendes under udvikling.

Generering af strings.xml

Alle strings er oprettet i et Localizely projekt: https://app.localizely.com/projects/3278b0a4-b1a5-4277-ba70-3159fb9dac9b/main/dashboard

For at hente nye strings i projektet skal man tilføje en fil kaldet "localizely-cli.json" i roden af projektet. Indholdet af filen skal være:

{
"project_id": PROJECT_ID,
"api_token": API_TOKEN,
"languages": [ "da" ],
"branch": "main",
"export_type": "android_xml",
"output_directory": "./core/shared/src/main/res/values"
}
Erstat PROJECT_ID med id'et for localizely projeket. Erstat API_TOKEN med en personlig read token for localizely. Begge dele kan tilgås fra localizely konsolen.

For at opdatere strings.xml filen med seneste opdateringer fra Localizely, skal man via CLI i roden af projektet køre:

...

Hvis macOS afviser, at køre CLI applikationen, kan du gå til System Preferences -> Security & Privacy og trykke "Open Anyway". CLI'en er et hjemmelavet custom lavet Rust værktøj, der anvendes indtil Localizely kommer med deres eget officielle CLI (skulle være klar i løbet af august 2021). Det er altså ikke signeret korrekt, hvorfor macOS advarer imod programmet.

...

Alle modeller som snakker sammen med backenden bliver genereret ud fra backendens OpenAPI specifikation.

Hvis udvikleren vil opdatere til en ny version af modellerne, skal man først opdatere models-version.config med den version af backenden, som modellerne skal genereres ud fra (Det er kun versionsnummer, "gm-api-" skal ikke med)
Herefter kører man et autogenererings script til MacOS, som køres fra roden af projektet på følgende måde:

Code Block
languagebash
./generatemodels.sh

Når man kører ./generatemodels.sh, så vil alle scriptets dependencies blive tjekket, og hvis at en dependency mangler vil man blive guidet til hvilke kommandoer der skal bruges for at få dem hentet.

generatemodel.sh dependencies

openapi-generator (min. version 5.1.0) (https://github.com/OpenAPITools/openapi-generator): Bruges til autogen af modeller ud fra speccen. 

subversion (https://subversion.apache.org/packages.html): Bruges til at hente speccen ned lokalt

ktlint (https://github.com/pinterest/ktlint): Bruges til at formatere outputtet fra openapi-generator

Konfiguration

delte strings ligger i `shared`-modulet, som er inkluderet i alle andre moduler. Siden alle moduler har deres egen R-fil, kan den delte strings R-fil importeres ind i filen ved at bruge:

Code Block
titleSharedR import
import dk.nsp.mingraviditet.core.shared.R as sharedR


Signering

For at bygge release udgaver til Google Play / Firebase, skal de signeres med MinGraviditets Keystore (MinGraviditetKeystore20211203.jks). 

For at bygge lokalt kræver det man har local.properties  filen i roden af projektet, som indeholder keystore password, key alias og key password i formatet:

Code Block
storePassword=SuperSecretPassword
private_alias=MyKeyAlias
private_password=MyPrivatePasswordHere

Det er vigtigt at informationen i local.properties filen og selve keystore filen (.jks) IKKE ikke uploades til version control (De er pt. inkluderet i .gitignore).

For at kunne bygge skal disse filer være tilgængelige på maskinen der bliver bygget på:

local.properties
signing
├── MinGraviditetKeystore20211203.jks
└── min-graviditet-test-4807133482ad.json


storePassword, keyAlias og keyPassword som bruges til signering af releases ligger som secret variables i azure. 

Konfiguration

Beskrivelse af de nuværende konfigurationer kan findes på Installationsvejledningen https://www.nspop.Beskrivelse af de nuværende konfigurationer kan findes på Installationsvejledningen https://www.nspop.dk/pages/viewpage.action?pageId=121373687#GravidiDK(Android)Installationsvejledning-Indledning

...

Alle bygge konfigurationer skal findes i projektets build.gradle.kts filer. Der findes en build.gradle.kts som deles af hele projektet og derunder findes der en build.gradle.kts for hvert modul af appen (App, Api, Repo, Shared)

Hvert modul har deres eget ansvarsområde, så api/build.gradle.kts definerer f.eks. hvilke endpoints APIet skal ramme og app/buid.gradle sætter suffix på pakkenavnet, så det er muligt at have flere versioner af appen installeret på samme tiddependencies som det modul har brug for.

Library versioner er defineret i dependencies.gradle

Versionering

Appen versioneres efter almindelig major.minor.patch (version code). Projektet er opdelt i moduler, så styring af disse er samlet i root project build.gradle i de to properties navngivet versionName  og versionCode .

Version name er tiltænkt man manuelt opdatere når man laver changes som er passende på en af de tre niveauer.
Version code er IKKE tiltænkt at blive opdateret manuelt, da denne skal opdateres med Fastlane vha. 

fastlane BumpReleaseVersion

(Se forklaring af lane under afsnittet Fastlane)

Tags

Releases af appen markeres med Git tags på formen release/major.minor.patch_versioncode 

Det er ikke tilladt at lave en release, uden der er et tilhørende tag på det commit man bygger fra (Dette er pt. ikke håndhævet ved manuelle byg, så dette er udviklerens eget ansvar at overholde).

Denne regel er indbygget i vores lanes i Fastlane, som et pre-check for at kunne køre de lanes som uploader appen - Heraf grunden til at Fastlane er anbefalt til ditribution.

Distribution

Distribution af test apps til ThePerfectApp (TPA)

For at distribuere test apps til TPA, skal man bruges Release build-typen, som beskrevet under Installationsvejledning. Dette kræver at man har et signing certifikat fra app'ens KeyStore.

For at versionen bliver synlig for dem som ønsker at tilgå test-appen, skal versionsnummeret (version code) være højere end det forrige.

Hvis versionsnummeret er lavere end den forrige version vil den blive gemt væk under "Browse all builds" og da TPA linket som set i installationsvejledningen kun bruger nyeste version.

Manuelt

Hvis man ønsker at uploade et byg manuelt, skal man lave et release-build af den variant man ønsker at uploade. Før dette gøres skal man have en bruger på insp.tpa.io med developer rettigheder.

Under siden Min Graviditet (Android) trykker man på Manage Project (oppe i højre hjørne) → Upload new build

Fastlane (anbefalet)

Hele processen med at bygge og uploade til TPA er blevet automatiseret med værktøjet Fastlane (https://fastlane.tools/).

Krav og installationsvejledninger kan findes på https://docs.fastlane.tools/getting-started/android/setup/#installing-fastlane

Ved at bruge kommandoen fastlane før man alle de mulige "lanes" frem, hvor man får nedenstående output.

gradle/libs.version.toml . Hvis udvikleren ønsker at opdatere versionerne, bruges 

Code Block
./gradlew dependencyUpdates

Læs mere i projektets README.md

 BuildLogic modulet

Projektet indeholder et vigtig gradle modul, som er med til at sætte alle android modulerne op på en ensartet måde; :build-logic.

Modulet er med til at sætte gradle versioning catalogs op og indeholder inkluderer en modul kalder :convention 

:convention er en samling af gradle plugins, som kan bruges af appens moduler, f.eks. bruger feature modulerne det gradle plugin som hedder "mingraviditet.android.feature" og er defineret i filen AndroidFeatureConventionPlugin.kt

I :convention er der også defineret appens minimum version, targetSdk, flavors og generelle kotlin & compose opsætning.

Versionering

Appen versioneres efter almindelig major.minor.patch (version code). Projektet er opdelt i moduler, så styring af disse er samlet i root project build.gradle.kts i de to properties navngivet versionName  og versionCode .

Version name er tiltænkt man manuelt opdatere når man laver changes som er passende på en af de tre niveauer.
Version code bliver automatisk forhøjet for hvert commit på den pågældende branch

Tags

Releases af appen markeres med Git tags på formen release/major.minor.patch_versioncode 

Det er ikke tilladt at lave en release, uden der er et tilhørende tag på det commit man bygger fra (Dette er pt. ikke håndhævet ved manuelle byg, så dette er udviklerens eget ansvar at overholde).

Denne regel er indbygget i vores lanes i Fastlane, som et pre-check for at kunne køre de lanes som uploader appen - Heraf grunden til at Fastlane er anbefalt til distribution.

Distribution

Fastlane

Hele processen med at bygge og uploade til Firebase er blevet automatiseret med værktøjet Fastlane (https://fastlane.tools/).

Krav og installationsvejledninger kan findes på https://docs.fastlane.tools/getting-started/android/setup/#installing-fastlane

Ved at bruge kommandoen fastlane før man alle de mulige "lanes" frem, hvor man får nedenstående output.

Code Block
languagebash
+-----------------------------------------------------------------
Code Block
languagebash
Welcome to fastlane! Here's what your app is set up to do:
+--------+-------------------------------------+--------------------------------------------------------+
|+
|                                       Available lanes to run                         Available lanes to run                                         |
+--|
+--------+-------------------------------------+------+--------------------------------------------------+
| Number | Lane Name                           | Description  |  Description                                        |
+--------+----------------------------------------+----------------------------------------------------------+
| 1--+
| 1      | android setGitTag                      | Add version tag to commit                        |
| 2      | android bumpReleaseVersion             | Bump, commit, tag and (optionally) push commit   |
|        |                                        | and tag                                          |
| 3      | android allUnitTests                   |                                                  |
| 4      | android generateQaReports              | Checks that git is in a correct state and we     |
|        |                                        | have a tag. Then generates Unit Test and         |
|        |                                        | Coverage reports                                 |
| 5      | android uploadForInternalTest          | Upload Internal Test version to Firebase         |
| 6      | android uploadForInternalTestMockMitId | Upload Internal Test MockMitID version to        |
|        |                                        | Firebase                                         |
| 7      | android bumpReleaseVersion uploadForDev                   | Bump, commit, tag and (optionally) push commit and tag Upload dev version to Firebase                   |
| 28      | android uploadForGooglePlay uploadForProjectEnvironment | Upload Project Environment version to TPA    | Build GooglePlay .aab and upload to Google Play  |
|  3      |   android uploadForInternalTest       | Upload Internal Test version to TPA                    |
| 4  | (Takes the Service |account androidjson uploadForTest1file path as a   |
|        | Upload Test1 version to TPA                            |
| 5      | android uploadForTest2   param)           | Upload Test2 version to TPA                            |
| 0      | cancel                                 | No selection, exit fastlane!                           |
+--------+-------------------------------------+---+-----------------------------------------------------+
[14:57:20]: Which number would you like to run??


 Lanes

bumpReleaseVersion

Kører 4 operationer

  1. Opdaterer version code ud fra antallet af commits (På tværs af repositoriets branches) og skriver det ind i root projects ./build.gradle 
  2. Commiter koden
  3. Opretter et release tag i git
  4. Giver udvikleren valget om at pushe commitet og det oprettede tag til remote repository

Efter denne operation er kørt (såfremt man valgte at sige ja til pkt. 4), vil det commit man står på være klar til lave en release.

 Release lanes

Fælles for alle release lanes er at de kører en pre_release_actions lane, som sørger for at git er i et korrekt state for at bygge og uploade en release udgave af den valgte flavor.

  1. uploadForProjectEnvironment:
    • Flavor: ProjectEnv
    • TPA Track: ProjectEnv
  2. uploadForInternalTest
    • Flavor: internalTest
    • TPA Track: internalTest
  3. uploadForTest1
    • Flavor: Staging1
    • TPA Track: Test1
  4. uploadForTest2
    • Flavor: Staging2
    • TPA Track: Test2

Release

  1. og skriver det ind i root projects ./build.gradle.kts
  2. Commiter koden
  3. Opretter et release tag i git
  4. Giver udvikleren valget om at pushe commitet og det oprettede tag til remote repository

Efter denne operation er kørt (såfremt man valgte at sige ja til pkt. 4), vil det commit man står på være klar til lave en release.

 Release lanes

Der kan releases til Firebase vha uploadForInternalTest, uploadForInternalTestMockMitId, uploadForDev og til GooglePlay ved hjælp af uploadForGooglePlay. 

Release til Google Play

For at kunne release kræves det at man har adgang til Sundhedsdatastyrelsens Google Play projekt.
Projektet er opsat i Google Play til at benytte sig af app bundles (.aab). 

For at ensarte byg og upload af Google Play udgaven af appen, er der lavet en Fastlane lane uploadForGooglePlay som tager én parameter service_account_json_file  (Som er den path hvor .json filen med info om den Google Cloud service account, som er tilknyttet Google Play projektet, befinder sig).

Denne lane bygger en .aab og uploader den til Google Play, så den kan findes under App bundle explorer  , herfra følges standard release procedure i Google Play.-