Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scripts de build e servidores de CI: você nunca mais vai querer executar qualquer tarefa de forma manual

Scripts de build e servidores de CI: você nunca mais vai querer executar qualquer tarefa de forma manual

Palestra realizada no TDC Florianópolis 2018

Ione Souza Junior

April 19, 2018
Tweet

More Decks by Ione Souza Junior

Other Decks in Technology

Transcript

  1. Scripts de build e servidores de CI Você nunca mais

    vai querer executar qualquer tarefa de forma manual Ione Souza Junior
  2. Apresentação Ione Souza Junior Desenvolvedor mobile @ Unimestre ❤ Xamarin

  3. O que veremos na apresentação?

  4. O que veremos na apresentação? → Um estudo de caso

    sobre como foi realizado a entrega de um app para diversos clientes → Discutir as dificuldades encontradas → Mostrar as soluções adotadas
  5. História do app

  6. História do app → Era uma vez um ERP... →

    Um app foi desenvolvido integrado ao sistema → App foi publicado, os clientes começaram a usar o app, até que...
  7. História do app → Alguns clientes se demonstraram um pouco

    vaidosos → Eles queriam um app próprio, publicado com seu nome e sua logo
  8. E agora, o que fazer?

  9. Que tal fazer um fork do projeto original?

  10. Fork → O fork foi o começo do fim... →

    Muitos conflitos → A demanda aumentou: mais projetos, mais trabalho, menos tempo para tomar café
  11. E se adotasse-mos uma arquitetura multi-tenant no projeto?

  12. None
  13. Multi-tenant → Não havíamos pensado nisso

  14. Nada parecia adequado, mas... o que realmente precisava ser feito?

  15. O que realmente precisava ser feito? → Alterar drawables Android

    → Alterar resources iOS → Alterar AndroidManifest.xml → Alterar Info.plist → Alterar Entitlements.plist
  16. O que realmente precisava ser feito? → Alterar constantes -

    classe C# → Alterar styles - resource dictionary
  17. A solução que deu certo: Criar um script de build

    Mas como isso funciona??
  18. Iniciamos com um script simples que alterava as imagens dos

    clientes
  19. Mas antes, foi necessário padronizar algumas coisas...

  20. Padronizações - parte I → Criamos uma pasta para armazenar

    as imagens específicas de cada cliente
  21. Padronizações - parte I Solução └─── Core └─── Droid └───

    iOS └─── Build │ └─── script.sh │ └─── Clientes │ └─── Cliente1 │ │ └─── Droid │ │ │ └─── arquivo1.png │ │ │ └─── arquivo2.png │ │ │ │ │ └─── iOS │ │ └─── arquivo1.png │ │ └─── arquivo2.png │ │ │ └─── Cliente2 │ └─── ...
  22. Início do script #!/bin/bash # ./Build/script.sh SOLUTION_DIR=/diretorio/projeto CLIENTE=Cliente1

  23. Início do script #!/bin/bash SOLUTION_DIR=/diretorio/projeto CLIENTE=Cliente1 cp ORIGEM DESTINO

  24. Início do script #!/bin/bash SOLUTION_DIR=/diretorio/projeto CLIENTE=Cliente1 cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/Droid/Resources/drawable/*.png

  25. Início do script #!/bin/bash SOLUTION_DIR=/diretorio/projeto CLIENTE=Cliente1 cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/Droid/Resources/drawable/*.png \ $SOLUTION_DIR/Droid/Resources/drawable/

  26. Início do script #!/bin/bash SOLUTION_DIR=/diretorio/projeto CLIENTE=Cliente1 cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/Droid/Resources/drawable/*.png \ $SOLUTION_DIR/Droid/Resources/drawable/

    cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/Droid/Resources/drawable-hdpi/*.png \ $SOLUTION_DIR/Droid/Resources/drawable-hdpi/
  27. Início do script #!/bin/bash SOLUTION_DIR=/diretorio/projeto CLIENTE=Cliente1 cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/Droid/Resources/drawable/*.png \ $SOLUTION_DIR/Droid/Resources/drawable/

    cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/Droid/Resources/drawable-hdpi/*.png \ $SOLUTION_DIR/Droid/Resources/drawable-hdpi/ cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/iOS/Assets.xcassets/AppIcon.appiconset/*.png \ $SOLUTION_DIR/iOS/Assets.xcassets/AppIcon.appiconset/
  28. Início do script #!/bin/bash SOLUTION_DIR=/diretorio/projeto CLIENTE=Cliente1 cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/Droid/Resources/drawable/*.png \ $SOLUTION_DIR/Droid/Resources/drawable/

    cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/Droid/Resources/drawable-hdpi/*.png \ $SOLUTION_DIR/Droid/Resources/drawable-hdpi/ cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/iOS/Assets.xcassets/AppIcon.appiconset/*.png \ $SOLUTION_DIR/iOS/Assets.xcassets/AppIcon.appiconset/ cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/iOS/Assets.xcassets/LaunchImage.launchimage/*.png \ $SOLUTION_DIR/iOS/Assets.xcassets/LaunchImage.launchimage/
  29. Início do script #!/bin/bash SOLUTION_DIR=/diretorio/projeto CLIENTE=Cliente1 cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/Droid/Resources/drawable/*.png \ $SOLUTION_DIR/Droid/Resources/drawable/

    cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/Droid/Resources/drawable-hdpi/*.png \ $SOLUTION_DIR/Droid/Resources/drawable-hdpi/ cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/iOS/Assets.xcassets/AppIcon.appiconset/*.png \ $SOLUTION_DIR/iOS/Assets.xcassets/AppIcon.appiconset/ cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/iOS/Assets.xcassets/LaunchImage.launchimage/*.png \ $SOLUTION_DIR/iOS/Assets.xcassets/LaunchImage.launchimage/ cp $SOLUTION_DIR/Build/Clientes/$CLIENTE/iOS/Resources/*.png \ $SOLUTION_DIR/iOS/Resources/
  30. O que realmente precisava ser feito? → ✅ Alterar drawables

    Android → ✅ Alterar resources iOS → Alterar AndroidManifest.xml → Alterar Info.plist → Alterar Entitlements.plist
  31. Continuação do script... → Alterar atributos do AndroidManifest.xml → android:label

    → android:versionName → package
  32. Continuação do script - AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"

    android:versionName="1.4" package="com.ionixjunior.app" android:versionCode="4" > <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="26" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" /> <application android:label="Ionix App"></application> </manifest>
  33. Continuação do script - AndroidManifest.xml #!/bin/bash sed

  34. Continuação do script - AndroidManifest.xml #!/bin/bash sed 's'

  35. Continuação do script - AndroidManifest.xml #!/bin/bash sed 's/SEARCH/REPLACE/'

  36. Continuação do script - AndroidManifest.xml #!/bin/bash sed 's#SEARCH#REPLACE#'

  37. Continuação do script - AndroidManifest.xml #!/bin/bash sed 's%SEARCH%REPLACE%'

  38. Continuação do script - AndroidManifest.xml #!/bin/bash sed 's/SEARCH/REPLACE/'

  39. Continuação do script - AndroidManifest.xml #!/bin/bash sed 's/SEARCH/REPLACE/' ARQUIVO_DESTINO

  40. Continuação do script - AndroidManifest.xml #!/bin/bash sed 's/REGEX_SEARCH/REGEX_REPLACE/' ARQUIVO_DESTINO

  41. Continuação do script - AndroidManifest.xml #!/bin/bash sed -i '' 's/REGEX_SEARCH/REGEX_REPLACE/'

    ARQUIVO_DESTINO !
  42. Continuação do script - AndroidManifest.xml #!/bin/bash SOLUTION_DIR=/diretorio/projeto MANIFEST=$SOLUTION_DIR/Droid/Properties/AndroidManifest.xml VERSION_NAME=1.5 APP_NAME=Ionix

    App Corp PACKAGE=com.ionix.corp
  43. Continuação do script - AndroidManifest.xml #!/bin/bash SOLUTION_DIR=/diretorio/projeto MANIFEST=$SOLUTION_DIR/Droid/Properties/AndroidManifest.xml VERSION_NAME=1.5 APP_NAME=Ionix

    App Corp PACKAGE=com.ionix.corp sed -i '' 's/versionName="[0-9.]*"/versionName="'$VERSION_NAME'"/' $MANIFEST
  44. Continuação do script - AndroidManifest.xml #!/bin/bash SOLUTION_DIR=/diretorio/projeto MANIFEST=$SOLUTION_DIR/Droid/Properties/AndroidManifest.xml VERSION_NAME=1.5 APP_NAME=Ionix

    App Corp PACKAGE=com.ionix.corp sed -i '' 's/versionName="[0-9.]*"/versionName="'$VERSION_NAME'"/' $MANIFEST sed -i '' 's/android:label="[a-zA-Zà-úÀ-Ú0-9 ]*"/android:label="'"$APP_NAME"'"/' $MANIFEST
  45. Continuação do script - AndroidManifest.xml #!/bin/bash SOLUTION_DIR=/diretorio/projeto MANIFEST=$SOLUTION_DIR/Droid/Properties/AndroidManifest.xml VERSION_NAME=1.5 APP_NAME=Ionix

    App Corp PACKAGE=com.ionix.corp sed -i '' 's/versionName="[0-9.]*"/versionName="'$VERSION_NAME'"/' $MANIFEST sed -i '' 's/android:label="[a-zA-Zà-úÀ-Ú0-9 ]*"/android:label="'"$APP_NAME"'"/' $MANIFEST sed -i '' 's/package="[a-zA-Z.]*"/package="'$PACKAGE'"/' $MANIFEST !
  46. O que realmente precisava ser feito? → ✅ Alterar drawables

    Android → ✅ Alterar resources iOS → ✅ Alterar AndroidManifest.xml → Alterar Info.plist → Alterar Entitlements.plist
  47. Continuação do script... → Alterar atributos do Info.plist → CFBundleIdentifier

    → CFBundleName → CFBundleShortVersionString
  48. Continuação do script - Info.plist <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist

    PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd" > <plist version="1.0"> <dict> <key>CFBundleIdentifier</key> <string>com.ionixjunior.app</string> <key>CFBundleName</key> <string>Ionix App</string> <key>CFBundleShortVersionString</key> <string>1.4</string> </dict> </plist>
  49. Continuação do script - Info.plist #!/bin/bash SOLUTION_DIR=/diretorio/projeto INFO_PLIST=$SOLUTION_DIR/iOS/Info.plist VERSION_NAME=1.5 APP_NAME=Ionix

    App Corp PACKAGE=com.ionix.corp
  50. Continuação do script - Info.plist #!/bin/bash SOLUTION_DIR=/diretorio/projeto INFO_PLIST=$SOLUTION_DIR/iOS/Info.plist VERSION_NAME=1.5 APP_NAME=Ionix

    App Corp PACKAGE=com.ionix.corp plutil
  51. Continuação do script - Info.plist #!/bin/bash SOLUTION_DIR=/diretorio/projeto INFO_PLIST=$SOLUTION_DIR/iOS/Info.plist VERSION_NAME=1.5 APP_NAME=Ionix

    App Corp PACKAGE=com.ionix.corp plutil -replace
  52. Continuação do script - Info.plist #!/bin/bash SOLUTION_DIR=/diretorio/projeto INFO_PLIST=$SOLUTION_DIR/iOS/Info.plist VERSION_NAME=1.5 APP_NAME=Ionix

    App Corp PACKAGE=com.ionix.corp plutil -replace CFBundleIdentifier
  53. Continuação do script - Info.plist #!/bin/bash SOLUTION_DIR=/diretorio/projeto INFO_PLIST=$SOLUTION_DIR/iOS/Info.plist VERSION_NAME=1.5 APP_NAME=Ionix

    App Corp PACKAGE=com.ionix.corp plutil -replace CFBundleIdentifier -string
  54. Continuação do script - Info.plist #!/bin/bash SOLUTION_DIR=/diretorio/projeto INFO_PLIST=$SOLUTION_DIR/iOS/Info.plist VERSION_NAME=1.5 APP_NAME=Ionix

    App Corp PACKAGE=com.ionix.corp plutil -replace CFBundleIdentifier -string $PACKAGE
  55. Continuação do script - Info.plist #!/bin/bash SOLUTION_DIR=/diretorio/projeto INFO_PLIST=$SOLUTION_DIR/iOS/Info.plist VERSION_NAME=1.5 APP_NAME=Ionix

    App Corp PACKAGE=com.ionix.corp plutil -replace CFBundleIdentifier -string $PACKAGE $INFO_PLIST
  56. Continuação do script - Info.plist #!/bin/bash SOLUTION_DIR=/diretorio/projeto INFO_PLIST=$SOLUTION_DIR/iOS/Info.plist VERSION_NAME=1.5 APP_NAME=Ionix

    App Corp PACKAGE=com.ionix.corp plutil -replace CFBundleIdentifier -string $PACKAGE $INFO_PLIST plutil -replace CFBundleName -string $APP_NAME $INFO_PLIST
  57. Continuação do script - Info.plist #!/bin/bash SOLUTION_DIR=/diretorio/projeto INFO_PLIST=$SOLUTION_DIR/iOS/Info.plist VERSION_NAME=1.5 APP_NAME=Ionix

    App Corp PACKAGE=com.ionix.corp plutil -replace CFBundleIdentifier -string $PACKAGE $INFO_PLIST plutil -replace CFBundleName -string $APP_NAME $INFO_PLIST plutil -replace CFBundleShortVersionString -string $VERSION_NAME $INFO_PLIST
  58. O que realmente precisava ser feito? → ✅ Alterar drawables

    Android → ✅ Alterar resources iOS → ✅ Alterar AndroidManifest.xml → ✅ Alterar Info.plist → Alterar Entitlements.plist
  59. Continuação do script... → Alterar atributos do Entitlements.plist → aps-environment

  60. Continuação do script - Entitlements.plist <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist

    PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd" > <plist version="1.0"> <dict> <key>aps-environment</key> <string>development</string> </dict> </plist>
  61. Continuação do script - Entitlements.plist #!/bin/bash SOLUTION_DIR=/diretorio/projeto ENTITLEMENTS_PLIST=$SOLUTION_DIR/iOS/Entitlements.plist APS_ENVIRONMENT=production plutil

    -replace aps-environment -string $APS_ENVIRONMENT $ENTITLEMENTS_PLIST
  62. O que realmente precisava ser feito? → ✅ Alterar drawables

    Android → ✅ Alterar resources iOS → ✅ Alterar AndroidManifest.xml → ✅ Alterar Info.plist → ✅ Alterar Entitlements.plist Mas ainda não acabou...
  63. O que realmente precisava ser feito? → Alterar constantes -

    classe C# → Alterar styles - resource dictionary
  64. Continuação do script - constantes public static class AppConfig {

    public const string ApiUrl = "https://homol.app.com"; }
  65. Continuação do script - constantes #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_CONFIG=$SOLUTION_DIR/Core/AppConfig.cs API_URL=https://prod.app.com sed

    -i '' 's#ApiUrl = "[a-z:./]*"#ApiUrl = "'$API_URL'"#' $APP_CONFIG
  66. O que realmente precisava ser feito? → ✅ Alterar constantes

    - classe C# → Alterar styles - resource dictionary
  67. Continuação do script - styles - resource dictionary <?xml version="1.0"

    encoding="utf-8"?> <Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Core.App" > <Application.Resources> <ResourceDictionary> <Color x:Key="PrimaryColor">#3F51B5</Color> <Color x:Key="SecondaryColor">#F90000</Color> </ResourceDictionary> </Application.Resources> </Application>
  68. Continuação do script - styles - resource dictionary #!/bin/bash SOLUTION_DIR=/diretorio/projeto

    APP_XAML=$SOLUTION_DIR/Core/App.xaml PRIMARY_COLOR=Green SECONDARY_COLOR=#0000FF sed -i '' 's/"PrimaryColor">[a-zA-Z0-9#]*</"PrimaryColor">'$PRIMARY_COLOR'</' $APP_XAML sed -i '' 's/"SecondaryColor">[a-zA-Z0-9#]*</"SecondaryColor">'$SECONDARY_COLOR'</' $APP_XAML
  69. O que realmente precisava ser feito? → ✅ Alterar constantes

    - classe C# → ✅ Alterar styles - resource dictionary !
  70. Pensa que acabou?

  71. Pensa que acabou? #!/bin/bash SOLUTION_DIR=/diretorio/projeto CLIENTE=Cliente1 MANIFEST=$SOLUTION_DIR/Droid/Properties/AndroidManifest.xml INFO_PLIST=$SOLUTION_DIR/iOS/Info.plist ENTITLEMENTS_PLIST=$SOLUTION_DIR/iOS/Entitlements.plist APP_CONFIG=$SOLUTION_DIR/Core/AppConfig.cs

    API_URL=https://prod.app.com VERSION_NAME=1.5 APP_NAME=Ionix App Corp PACKAGE=com.ionix.corp ... O que tem de "errado"?
  72. Pensa que acabou? #!/bin/bash SOLUTION_DIR=/diretorio/projeto CLIENTE=Cliente1 MANIFEST=$SOLUTION_DIR/Droid/Properties/AndroidManifest.xml INFO_PLIST=$SOLUTION_DIR/iOS/Info.plist ENTITLEMENTS_PLIST=$SOLUTION_DIR/iOS/Entitlements.plist APP_CONFIG=$SOLUTION_DIR/Core/AppConfig.cs

    API_URL=https://prod.app.com VERSION_NAME=1.5 APP_NAME=Ionix App Corp PACKAGE=com.ionix.corp ... As variáveis estão fixas no script
  73. Aqui começa a loucura...

  74. Padronizações - parte II → Criamos um arquivo para armazenar

    as variáveis do build # ./Build/app.ini CLIENTE = Cliente1 API_URL = https://prod.app.com VERSION_NAME = 1.5 APP_NAME = Ionix App Corp PACKAGE = com.ionix.corp
  75. Padronizações - parte II → No script principal, carregamos estas

    variáveis... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini CLIENTE=
  76. Padronizações - parte II → No script principal, carregamos estas

    variáveis... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini CLIENTE=$()
  77. Padronizações - parte II → No script principal, carregamos estas

    variáveis... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini CLIENTE=$(cat $APP_INI) # Vai mostrar o conteúdo de todo o arquivo...
  78. Padronizações - parte II → No script principal, carregamos estas

    variáveis... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini CLIENTE=$(cat $APP_INI | grep "CLIENTE = ") # CLIENTE = Cliente1
  79. Padronizações - parte II → No script principal, carregamos estas

    variáveis... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini CLIENTE=$(cat $APP_INI | grep "CLIENTE = " | awk) #
  80. Padronizações - parte II → No script principal, carregamos estas

    variáveis... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini CLIENTE=$(cat $APP_INI | grep "CLIENTE = " | awk '{print $0}') # CLIENTE = Cliente1
  81. Padronizações - parte II → No script principal, carregamos estas

    variáveis... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini CLIENTE=$(cat $APP_INI | grep "CLIENTE = " | awk '{print $1}') # CLIENTE
  82. Padronizações - parte II → No script principal, carregamos estas

    variáveis... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini CLIENTE=$(cat $APP_INI | grep "CLIENTE = " | awk '{print $2}') # =
  83. Padronizações - parte II → No script principal, carregamos estas

    variáveis... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini CLIENTE=$(cat $APP_INI | grep "CLIENTE = " | awk '{print $3}') # Cliente1
  84. Padronizações - parte II → Outro exemplo... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini

    APP_NAME=
  85. Padronizações - parte II → Outro exemplo... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini

    APP_NAME=$(cat $APP_INI)
  86. Padronizações - parte II → Outro exemplo... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini

    APP_NAME=$(cat $APP_INI | grep "APP_NAME = ") # APP_NAME = Ionix App Corp
  87. Padronizações - parte II → Outro exemplo... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini

    APP_NAME=$(cat $APP_INI | grep "APP_NAME = " | awk '{print $3}') # Ionix Está faltando coisa aí...
  88. Padronizações - parte II → Vamos revisar... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini

    APP_NAME=$(cat $APP_INI | grep "APP_NAME = " | awk '{print $0}') # APP_NAME = Ionix App Corp
  89. Padronizações - parte II → Vamos revisar... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini

    APP_NAME=$(cat $APP_INI | grep "APP_NAME = " | awk '{print $3 " " $4 " " $5}') # Ionix App Corp
  90. Padronizações - parte II → Como deixar isso dinâmico?? ...

    awk '{print $3 " " $4 " " $5}' # Ionix App Corp
  91. Padronizações - parte II → Como deixar isso dinâmico?? ...

    awk '{ {out=$3} }' # APP_NAME = Ionix App Corp # out = Ionix
  92. Padronizações - parte II → Como deixar isso dinâmico?? ...

    awk '{ {out=$3}; for (i=4; i <= NF; i++) { } }' # APP_NAME = Ionix App Corp # out = Ionix # NF = number of fields = 5
  93. Padronizações - parte II → Como deixar isso dinâmico?? ...

    awk '{ {out=$3}; for (i=4; i <= NF; i++) { out=out" "$i } }' # APP_NAME = Ionix App Corp # out = Ionix # out = Ionix App # out = Ionix App Corp
  94. Padronizações - parte II → Como deixar isso dinâmico?? ...

    awk '{{out=$3; for(i=4; i<=NF; i++) { out=out" "$i }; print out}}' # Ionix App Corp !
  95. Padronizações - parte II → Outro exemplo... #!/bin/bash SOLUTION_DIR=/diretorio/projeto APP_INI=$SOLUTION_DIR/Build/app.ini

    MANIFEST = $SOLUTION_DIR/Droid/Properties/AndroidManifest.xml INFO_PLIST = $SOLUTION_DIR/iOS/Info.plist ENTITLEMENTS_PLIST = $SOLUTION_DIR/iOS/Entitlements.plist APP_CONFIG = $SOLUTION_DIR/Core/AppConfig.cs CLIENTE = $(cat $APP_INI | grep "CLIENTE = " | awk '{print $3}') API_URL = $(cat $APP_INI | grep "API_URL = " | awk '{print $3}') VERSION_NAME = $(cat $APP_INI | grep "VERSION_NAME = " | awk '{print $3}') APP_NAME = $(cat $APP_INI | grep "APP_NAME = " | awk '{{out=$3; for(i=4;i<=NF;i++){out=out" "$i}; print out}}') PACKAGE = $(cat $APP_INI | grep "PACKAGE = " | awk '{print $3}')
  96. E para o Windows? Tem??

  97. Tem que criar o .bat

  98. Isso é automatizado?

  99. Não, mas vamos melhorar... vamos configurar na IDE

  100. None
  101. Script → Ajustes no $SOLUTION_DIR #!/bin/bash SOLUTION_DIR=/diretorio/projeto ...

  102. Script → Ajustes no $SOLUTION_DIR #!/bin/bash SOLUTION_DIR=$1 ...

  103. Isso sempre vai executar na minha máquina?

  104. Calma, agora que tudo vai ficar mais legal... Vamos integrar

    ao CI server
  105. Visual Studio App Center

  106. Visual Studio App Center → Muito fácil de usar →

    Ideal para quem está iniciando no mundo DevOps → Poucos cliques e os problemas estão resolvidos
  107. Visual Studio App Center → Build → UI Test →

    Distribuir para grupos de testes e lojas → Diagnóstico de erros → Analytics → Push
  108. Configurando o build

  109. Configurando o build → Conectar o repositório

  110. Configurando o build → Escolher o projeto

  111. Configurando o build → Branches serão listados

  112. Configurando o build → Configurar os branches

  113. Configurando o build → Configurar os branches

  114. Mas como nosso script lê as variáveis do App Center?

  115. Como nosso script lê as variáveis do App Center? →

    Customizações precisaram ser feitas...
  116. Padronizações - parte III → O app.ini não deve ser

    versionado → Então podemos verificar se ele existe no script...
  117. Padronizações - parte III #!/bin/bash # Script antes SOLUTION_DIR=$1 APP_INI=$SOLUTION_DIR/Build/app.ini

    CLIENTE=$(cat $APP_INI | grep "CLIENTE = " | awk '{print $3}')
  118. Padronizações - parte III #!/bin/bash # Script depois :) SOLUTION_DIR=$1

    APP_INI=$SOLUTION_DIR/Build/app.ini if [ -e "$APP_INI" ] then CLIENTE=$(cat $APP_INI | grep "CLIENTE = " | awk '{print $3}') else # Não precisa fazer nada, as variáveis já foram setadas :) fi
  119. Padronizações - parte III → Ainda falta deixar dinâmico o

    $SOLUTION_DIR... → O App Center também tem suas próprias variáveis de ambiente
  120. Padronizações - parte III #!/bin/bash # Script antes SOLUTION_DIR=$1

  121. Padronizações - parte III #!/bin/bash # Script depois :) if

    [ -n "$1" ] then SOLUTION_DIR=$1 else SOLUTION_DIR=$APPCENTER_SOURCE_DIRECTORY fi
  122. Padronizações - parte III → O App Center não vai

    achar esse script sozinho → É necessário criar o script post-clone / pre- build / post-build
  123. Padronizações - parte III Solução └─── Build └─── Droid │

    └─── appcenter-post-clone.sh │ └─── appcenter-pre-build.sh │ └─── appcenter-post-build.sh └─── iOS └─── appcenter-post-clone.sh └─── appcenter-pre-build.sh └─── appcenter-post-build.sh
  124. Padronizações - parte III #!/usr/bin/env bash # Droid/appcenter-pre-build.sh # iOS/appcenter-pre-build.sh

    sh $APPCENTER_SOURCE_DIRECTORY/Build/script.sh !
  125. Você pode acompanhar o resultado da compilação

  126. None
  127. Sabia que você pode contribuir?

  128. Sabia que você pode contribuir? → Projeto App Center Build

    Scripts Examples → https://github.com/Microsoft/appcenter-build- scripts-examples
  129. O processo ainda não acaba O que vimos é o

    mais complicado O restante é bem simples
  130. Publicando o app na loja

  131. Publicando o app na loja → Conectar o projeto a

    loja → Google Play → Apple Store
  132. Publicando o app na loja → Escolher onde publicar →

    Produção → Testes
  133. Publicando o app na loja → Envie o APK ou

    IPA → Adicione o release notes → Ser feliz !
  134. Publicando o app na loja → Limitações no iOS: somente

    é possível enviar release notes em inglês !
  135. Na palestra de hoje vimos que... → É possível compilar

    um app de forma dinâmica → Você vai se encher de repetir as mesmas tarefas → Precisamos fazer a máquina trabalhar mais → Automatização é tudo
  136. Ione Souza Junior Desenvolvedor mobile @ Unimestre @ionixjunior junior@ionixjunior.com.br