Skapa, testa och distribuera Android-appar

Azure DevOps Services

Du kan konfigurera pipelines för att automatiskt skapa, testa och distribuera Android-program.

Förutsättningar

Du måste ha följande objekt:

  • GitHub-konto. Om du inte har ett GitHub-konto skapar du ett nu.
  • Azure DevOps-projekt. Om du inte har ett projekt skapar du ett nu.

Konfigurera pipeline

Utför följande uppgifter för att konfigurera en pipeline för ett Android-exempelprogram.

  1. Förgrena följande lagringsplats till ditt GitHub-konto för att hämta koden för ett enkelt Android-program.

    https://github.com/MicrosoftDocs/pipelines-android
    
  2. Logga in på din Azure DevOps-organisation och gå till projektet.

  3. Välj Pipelines>Skapa pipeline eller Ny pipeline.

  4. Välj GitHub som plats för källkoden.

    Screenshot showing list of repositories to select from.

    Du kan omdirigeras till GitHub för att logga in. I så fall anger du dina GitHub-autentiseringsuppgifter.

  5. Välj den -android-lagringsplats som du tidigare förgrenade.

  6. Välj Godkänn och installera på skärmen som följer.

    Azure Pipelines genererar en YAML-fil för din pipeline.

  7. Markera Kör.

  8. Checka in direkt till huvudgrenen och välj sedan Kör igen.

  9. Vänta tills körningen har slutförts.

Du har en fungerande YAML-fil (azure-pipelines.yml) på lagringsplatsen som är redo att anpassas.

Dricks

Om du vill göra ändringar i YAML-filen väljer du pipelinen på sidan Pipelines och sedan Redigeraazure-pipelines.yml filen.

Skapa med Gradle

Gradle är ett vanligt byggverktyg som används för att skapa Android-projekt. Mer information om dina alternativ finns i Gradle-uppgiften .

# https://learn.microsoft.com/azure/devops/pipelines/ecosystems/android
pool:
  vmImage: 'macOS-latest'

steps:
- task: Gradle@2
  inputs:
    workingDirectory: ''
    gradleWrapperFile: 'gradlew'
    gradleOptions: '-Xmx3072m'
    publishJUnitResults: false
    testResultsFiles: '**/TEST-*.xml'
    tasks: 'assembleDebug'

Justera byggsökvägen

  • Justera värdet workingDirectory om gradlew filen inte finns i databasens rot. Katalogvärdet bör likna roten på lagringsplatsen, till exempel AndroidApps/MyApp eller $(system.defaultWorkingDirectory)/AndroidApps/MyApp.

  • Justera värdet gradleWrapperFile om gradlew filen inte finns i databasens rot. Filsökvägsvärdet bör likna roten på lagringsplatsen, till exempel AndroidApps/MyApp/gradlew eller $(system.defaultWorkingDirectory)/AndroidApps/MyApp/gradlew.

Justera Gradle-uppgifter

Justera aktivitetsvärdet för den build-variant som du föredrar, till exempel assembleDebug eller assembleRelease. Mer information finns i följande dokumentation om Google Android-utveckling:

Signera och justera ett Android-paket (APK)

Om din version inte redan signerar och zipalign APK lägger du till Android-signeringsaktiviteten i YAML. En APK måste signeras för att köras på en enhet i stället för en emulator. Zipaligering minskar det RAM-minne som används av programmet.

Viktigt!

Vi rekommenderar att du lagrar vart och ett av följande lösenord i en hemlig variabel.

- task: AndroidSigning@2
  inputs:
    apkFiles: '**/*.apk'
    jarsign: true
    jarsignerKeystoreFile: 'pathToYourKeystoreFile'
    jarsignerKeystorePassword: '$(jarsignerKeystorePassword)'
    jarsignerKeystoreAlias: 'yourKeystoreAlias'
    jarsignerKeyPassword: '$(jarsignerKeyPassword)'
    zipalign: true

Testa

Testa på Android-emulatorn

Skapa Bash-uppgiften och kopiera klistra in koden nedan för att installera och köra emulatorn. Glöm inte att ordna emulatorparametrarna så att de passar din testmiljö. Emulatorn startar som en bakgrundsprocess och är tillgänglig i senare uppgifter.

#!/usr/bin/env bash

# Install AVD files
echo "y" | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --install 'system-images;android-27;google_apis;x86'

# Create emulator
echo "no" | $ANDROID_HOME/tools/bin/avdmanager create avd -n xamarin_android_emulator -k 'system-images;android-27;google_apis;x86' --force

$ANDROID_HOME/emulator/emulator -list-avds

echo "Starting emulator"

# Start emulator in background
nohup $ANDROID_HOME/emulator/emulator -avd xamarin_android_emulator -no-snapshot > /dev/null 2>&1 &
$ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done; input keyevent 82'

$ANDROID_HOME/platform-tools/adb devices

echo "Emulator started"

Testa på Azure-värdbaserade enheter

Lägg till App Center-testuppgiften för att testa programmet i ett värdbaserat labb med iOS- och Android-enheter. En kostnadsfri utvärderingsversion av App Center krävs, som senare måste konverteras till betald.

Registrera dig med App Center först.

# App Center test v1
# Test app packages with Visual Studio App Center.
- task: AppCenterTest@1
  inputs:
    appFile: # string. Alias: app. Required. Binary application file path. 
    artifactsDirectory: '$(Build.ArtifactStagingDirectory)/AppCenterTest' # string. Alias: artifactsDir. Required. Artifacts directory. Default: $(Build.ArtifactStagingDirectory)/AppCenterTest.
  # Prepare Tests
    #prepareTests: true # boolean. Alias: enablePrepare. Prepare tests. Default: true.
    frameworkOption: 'appium' # 'appium' | 'espresso' | 'calabash' | 'uitest' | 'xcuitest'. Alias: framework. Required when enablePrepare = true. Test framework. Default: appium.
    #appiumBuildDirectory: # string. Alias: appiumBuildDir. Required when enablePrepare = true && framework = appium. Build directory. 
    #espressoBuildDirectory: # string. Alias: espressoBuildDir. Optional. Use when enablePrepare = true && framework = espresso. Build directory. 
    #espressoTestApkFile: # string. Alias: espressoTestApkPath. Optional. Use when enablePrepare = true && framework = espresso. Test APK path. 
    #calabashProjectDirectory: # string. Alias: calabashProjectDir. Required when enablePrepare = true && framework = calabash. Project directory. 
    #calabashConfigFile: # string. Optional. Use when enablePrepare = true && framework = calabash. Cucumber config file. 
    #calabashProfile: # string. Optional. Use when enablePrepare = true && framework = calabash. Profile to run. 
    #calabashSkipConfigCheck: false # boolean. Optional. Use when enablePrepare = true && framework = calabash. Skip Configuration Check. Default: false.
    #uiTestBuildDirectory: # string. Alias: uitestBuildDir. Required when enablePrepare = true && framework = uitest. Build directory. 
    #uitestStorePath: # string. Optional. Use when enablePrepare = true && framework = uitest. Store file. 
    #uiTestStorePassword: # string. Alias: uitestStorePass. Optional. Use when enablePrepare = true && framework = uitest. Store password. 
    #uitestKeyAlias: # string. Optional. Use when enablePrepare = true && framework = uitest. Key alias. 
    #uiTestKeyPassword: # string. Alias: uitestKeyPass. Optional. Use when enablePrepare = true && framework = uitest. Key password. 
    #uiTestToolsDirectory: # string. Alias: uitestToolsDir. Optional. Use when enablePrepare = true && framework = uitest. Test tools directory. 
    #signInfo: # string. Optional. Use when framework = calabash || framework = uitest. Signing information. 
    #xcUITestBuildDirectory: # string. Alias: xcuitestBuildDir. Optional. Use when enablePrepare = true && framework = xcuitest. Build directory. 
    #xcUITestIpaFile: # string. Alias: xcuitestTestIpaPath. Optional. Use when enablePrepare = true && framework = xcuitest. Test IPA path. 
    #prepareOptions: # string. Alias: prepareOpts. Optional. Use when enablePrepare = true. Additional options. 
  # Run Tests
    #runTests: true # boolean. Alias: enableRun. Run tests. Default: true.
    credentialsOption: 'serviceEndpoint' # 'serviceEndpoint' | 'inputs'. Alias: credsType. Required when enableRun = true. Authentication method. Default: serviceEndpoint.
    #serverEndpoint: # string. Required when enableRun = true && credsType = serviceEndpoint. App Center service connection. 
    #username: # string. Required when enableRun = true && credsType = inputs. App Center username. 
    #password: # string. Required when enableRun = true && credsType = inputs. App Center password. 
    appSlug: # string. Required when enableRun = true. App slug. 
    devices: # string. Required when enableRun = true. Devices. 
    #series: 'master' # string. Optional. Use when enableRun = true. Test series. Default: master.
    #dsymDirectory: # string. Alias: dsymDir. Optional. Use when enableRun = true. dSYM directory. 
    localeOption: 'en_US' # 'da_DK' | 'nl_NL' | 'en_GB' | 'en_US' | 'fr_FR' | 'de_DE' | 'ja_JP' | 'ru_RU' | 'es_MX' | 'es_ES' | 'user'. Alias: locale. Required when enableRun = true. System language. Default: en_US.
    #userDefinedLocale: # string. Optional. Use when enableRun = true && locale = user. Other locale. 
    #loginOptions: # string. Alias: loginOpts. Optional. Use when enableRun = true && credsType = inputs. Additional options for login. 
    #runOptions: # string. Alias: runOpts. Optional. Use when enableRun = true. Additional options for run. 
    #skipWaitingForResults: false # boolean. Alias: async. Optional. Use when enableRun = true. Do not wait for test result. Default: false.
  # Advanced
    #cliFile: # string. Alias: cliLocationOverride. App Center CLI location. 
    #showDebugOutput: false # boolean. Alias: debug. Enable debug output. Default: false.

Behåll artefakter med byggposten

Lägg till uppgifterna Kopiera filer och Publicera byggartefakter. Din APK lagras med byggposten eller testet och distribueras i senare pipelines. Mer information finns i Artefakter.

- task: CopyFiles@2
  inputs:
    contents: '**/*.apk'
    targetFolder: '$(build.artifactStagingDirectory)'
- task: PublishBuildArtifacts@1

Distribuera

Lägg till App Center

Lägg till appcenterdistributionsuppgiften för att distribuera ett program till en grupp testare eller betaanvändare, eller flytta upp programmet till Intune eller Google Play. Ett kostnadsfritt App Center-konto krävs (ingen betalning krävs).

# App Center distribute v3
# Distribute app builds to testers and users via Visual Studio App Center.
- task: AppCenterDistribute@3
  inputs:
    serverEndpoint: # string. Required. App Center service connection. 
    appSlug: # string. Required. App slug. 
    appFile: # string. Alias: app. Required. Binary file path. 
    #buildVersion: # string. Build version. 
    releaseNotesOption: 'input' # 'input' | 'file'. Alias: releaseNotesSelection. Required. Create release notes. Default: input.
    releaseNotesInput: # string. Required when releaseNotesSelection = input. Release notes. 
    #releaseNotesFile: # string. Required when releaseNotesSelection = file. Release notes file. 
    #isMandatory: false # boolean. Require users to update to this release. Default: false.
    destinationType: 'groups' # 'groups' | 'store'. Required. Release destination. Default: groups.
    #distributionGroupId: # string. Alias: destinationGroupIds. Optional. Use when destinationType = groups. Destination IDs. 
    #destinationStoreId: # string. Required when destinationType = store. Destination ID. 
    #isSilent: # boolean. Optional. Use when destinationType = groups. Do not notify testers. Release will still be available to install. 
  # Symbols
    #symbolsOption: 'Apple' # 'Apple' | 'Android' | 'UWP'. Alias: symbolsType. Symbols type. Default: Apple.
    #symbolsPath: # string. Optional. Use when symbolsType == AndroidNative || symbolsType = Windows. Symbols path. 
    #appxsymPath: # string. Optional. Use when symbolsType = UWP. Symbols path (*.appxsym). 
    #symbolsDsymFiles: # string. Alias: dsymPath. Optional. Use when symbolsType = Apple. dSYM path. 
    #symbolsMappingTxtFile: # string. Alias: mappingTxtPath. Optional. Use when symbolsType = Android. Mapping file. 
    #nativeLibrariesPath: # string. Optional. Use when symbolsType == Android. Native Library File Path. 
    #symbolsIncludeParentDirectory: # boolean. Alias: packParentFolder. Optional. Use when symbolsType = Apple. Include all items in parent folder.

Installera Google Play

Installera Google Play-tillägget och använd följande uppgifter för att automatisera interaktionen med Google Play. Som standard autentiseras dessa uppgifter till Google Play med hjälp av en tjänstanslutning som du konfigurerar.

Frisläpp

Lägg till google play-versionsuppgiften för att släppa en ny Android-appversion till Google Play Store.

- task: GooglePlayRelease@4
  inputs:
    apkFile: '**/*.apk'
    serviceEndpoint: 'yourGooglePlayServiceConnectionName'
    track: 'internal'

Marknadsföra

Lägg till uppgiften Google Play Promote för att höja upp en tidigare släppt Android-programuppdatering från ett spår till ett annat, till exempel alphabeta.

- task: GooglePlayPromote@3
  inputs:
    packageName: 'com.yourCompany.appPackageName'
    serviceEndpoint: 'yourGooglePlayServiceConnectionName'
    sourceTrack: 'internal'
    destinationTrack: 'alpha'

Öka distributionen

Lägg till uppgiften Google Play Increase Rollout för att öka distributionsprocenten för ett program som tidigare släpptes till rollout spåret.

- task: GooglePlayIncreaseRollout@2
  inputs:
    packageName: 'com.yourCompany.appPackageName'
    serviceEndpoint: 'yourGooglePlayServiceConnectionName'
    userFraction: '0.5' # 0.0 to 1.0 (0% to 100%)

Statusuppdatering

Lägg till statusuppdateringsaktiviteten för Google Play för att uppdatera distributionsstatusen för programmet som tidigare släpptes till rollout spåret.

  - task: GooglePlayStatusUpdate@2
    inputs:
      authType: ServiceEndpoint
      packageName: 'com.yourCompany.appPackageName'
      serviceEndpoint: 'yourGooglePlayServiceConnectionName'
      status: 'inProgress' # draft | inProgress | halted | completed

Vanliga frågor

F: Hur gör jag för att skapa apppaket?

S: Du kan skapa och signera apppaketet med ett infogat skript och en säker fil. Det gör du genom att först ladda ned ditt nyckelarkiv och lagra det som en säker fil i biblioteket. Skapa sedan variabler för keystore.password, key.aliasoch key.password i en variabelgrupp.

Använd sedan uppgifterna Ladda ned säker fil och Bash för att ladda ned ditt nyckelarkiv och skapa och signera apppaketet.

I den här YAML-filen laddar du ned en app.keystore säker fil och använder ett bash-skript för att generera ett apppaket. Använd sedan Kopiera filer för att kopiera apppaketet. Därifrån skapar och sparar du en artefakt med Publicera byggartefakt eller använder Google Play-tillägget för att publicera.

- task: DownloadSecureFile@1
  name: keyStore
  displayName: "Download keystore from secure files"
  inputs:
    secureFile: app.keystore

- task: Bash@3
  displayName: "Build and sign App Bundle"
  inputs:
    targetType: "inline"
    script: |
      msbuild -restore $(Build.SourcesDirectory)/myAndroidApp/*.csproj -t:SignAndroidPackage -p:AndroidPackageFormat=aab -p:Configuration=$(buildConfiguration) -p:AndroidKeyStore=True -p:AndroidSigningKeyStore=$(keyStore.secureFilePath) -p:AndroidSigningStorePass=$(keystore.password) -p:AndroidSigningKeyAlias=$(key.alias) -p:AndroidSigningKeyPass=$(key.password)

- task: CopyFiles@2
  displayName: 'Copy deliverables'
  inputs:
    SourceFolder: '$(Build.SourcesDirectory)/myAndroidApp/bin/$(buildConfiguration)'
    Contents: '*.aab'
    TargetFolder: 'drop'