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

    View Slide

  2. Apresentação
    Ione Souza Junior
    Desenvolvedor mobile @
    Unimestre
    ❤ Xamarin

    View Slide

  3. O que veremos na apresentação?

    View Slide

  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

    View Slide

  5. História do app

    View Slide

  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...

    View Slide

  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

    View Slide

  8. E agora, o que fazer?

    View Slide

  9. Que tal fazer um fork
    do projeto original?

    View Slide

  10. Fork
    → O fork foi o começo do fim...
    → Muitos conflitos
    → A demanda aumentou: mais projetos, mais
    trabalho, menos tempo para tomar café

    View Slide

  11. E se adotasse-mos uma arquitetura
    multi-tenant no projeto?

    View Slide

  12. View Slide

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

    View Slide

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

    View Slide

  15. O que realmente precisava ser feito?
    → Alterar drawables Android
    → Alterar resources iOS
    → Alterar AndroidManifest.xml
    → Alterar Info.plist
    → Alterar Entitlements.plist

    View Slide

  16. O que realmente precisava ser feito?
    → Alterar constantes - classe C#
    → Alterar styles - resource dictionary

    View Slide

  17. A solução que deu certo:
    Criar um script de build
    Mas como isso funciona??

    View Slide

  18. Iniciamos com um script simples que
    alterava as imagens dos clientes

    View Slide

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

    View Slide

  20. Padronizações - parte I
    → Criamos uma pasta para armazenar as imagens
    específicas de cada cliente

    View Slide

  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
    │ └─── ...

    View Slide

  22. Início do script
    #!/bin/bash
    # ./Build/script.sh
    SOLUTION_DIR=/diretorio/projeto
    CLIENTE=Cliente1

    View Slide

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

    View Slide

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

    View Slide

  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/

    View Slide

  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/

    View Slide

  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/

    View Slide

  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/

    View Slide

  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/

    View Slide

  30. O que realmente precisava ser feito?


    Alterar drawables Android


    Alterar resources iOS
    → Alterar AndroidManifest.xml
    → Alterar Info.plist
    → Alterar Entitlements.plist

    View Slide

  31. Continuação do script...
    → Alterar atributos do AndroidManifest.xml
    → android:label
    → android:versionName
    → package

    View Slide

  32. Continuação do script -
    AndroidManifest.xml

    xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionName="1.4"
    package="com.ionixjunior.app"
    android:versionCode="4"
    >









    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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
    !

    View Slide

  46. O que realmente precisava ser feito?


    Alterar drawables Android


    Alterar resources iOS


    Alterar AndroidManifest.xml
    → Alterar Info.plist
    → Alterar Entitlements.plist

    View Slide

  47. Continuação do script...
    → Alterar atributos do Info.plist
    → CFBundleIdentifier
    → CFBundleName
    → CFBundleShortVersionString

    View Slide

  48. Continuação do script - Info.plist

    "-//Apple//DTD PLIST 1.0//EN"
    "http://www.apple.com/DTDs/PropertyList-1.0.dtd"
    >


    CFBundleIdentifier
    com.ionixjunior.app
    CFBundleName
    Ionix App
    CFBundleShortVersionString
    1.4


    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  58. O que realmente precisava ser feito?


    Alterar drawables Android


    Alterar resources iOS


    Alterar AndroidManifest.xml


    Alterar Info.plist
    → Alterar Entitlements.plist

    View Slide

  59. Continuação do script...
    → Alterar atributos do Entitlements.plist
    → aps-environment

    View Slide

  60. Continuação do script - Entitlements.plist

    "http://www.apple.com/DTDs/PropertyList-1.0.dtd"
    >


    aps-environment
    development


    View Slide

  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

    View Slide

  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...

    View Slide

  63. O que realmente precisava ser feito?
    → Alterar constantes - classe C#
    → Alterar styles - resource dictionary

    View Slide

  64. Continuação do script - constantes
    public static class AppConfig
    {
    public const string ApiUrl = "https://homol.app.com";
    }

    View Slide

  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

    View Slide

  66. O que realmente precisava ser feito?


    Alterar constantes - classe C#
    → Alterar styles - resource dictionary

    View Slide

  67. Continuação do script - styles - resource
    dictionary

    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="Core.App"
    >


    #3F51B5
    #F90000



    View Slide

  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

    View Slide

  69. O que realmente precisava ser feito?


    Alterar constantes - classe C#


    Alterar styles - resource dictionary
    !

    View Slide

  70. Pensa que acabou?

    View Slide

  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"?

    View Slide

  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

    View Slide

  73. Aqui começa a loucura...

    View Slide

  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

    View Slide

  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=

    View Slide

  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=$()

    View Slide

  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...

    View Slide

  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

    View Slide

  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)
    #

    View Slide

  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

    View Slide

  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

    View Slide

  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}')
    # =

    View Slide

  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

    View Slide

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

    View Slide

  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)

    View Slide

  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

    View Slide

  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í...

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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
    !

    View Slide

  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}')

    View Slide

  96. E para o Windows? Tem??

    View Slide

  97. Tem que criar o .bat

    View Slide

  98. Isso é automatizado?

    View Slide

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

    View Slide

  100. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  105. Visual Studio App Center

    View Slide

  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

    View Slide

  107. Visual Studio App Center
    → Build
    → UI Test
    → Distribuir para grupos de testes e lojas
    → Diagnóstico de erros
    → Analytics
    → Push

    View Slide

  108. Configurando o build

    View Slide

  109. Configurando o
    build
    → Conectar o repositório

    View Slide

  110. Configurando o
    build
    → Escolher o projeto

    View Slide

  111. Configurando o
    build
    → Branches serão listados

    View Slide

  112. Configurando o
    build
    → Configurar os branches

    View Slide

  113. Configurando o
    build
    → Configurar os branches

    View Slide

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

    View Slide

  115. Como nosso script lê as variáveis do App
    Center?
    → Customizações precisaram ser feitas...

    View Slide

  116. Padronizações - parte III
    → O app.ini não deve ser versionado
    → Então podemos verificar se ele existe no script...

    View Slide

  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}')

    View Slide

  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

    View Slide

  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

    View Slide

  120. Padronizações - parte III
    #!/bin/bash
    # Script antes
    SOLUTION_DIR=$1

    View Slide

  121. Padronizações - parte III
    #!/bin/bash
    # Script depois :)
    if [ -n "$1" ]
    then
    SOLUTION_DIR=$1
    else
    SOLUTION_DIR=$APPCENTER_SOURCE_DIRECTORY
    fi

    View Slide

  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

    View Slide

  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

    View Slide

  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
    !

    View Slide

  125. Você pode acompanhar
    o resultado da compilação

    View Slide

  126. View Slide

  127. Sabia que você pode contribuir?

    View Slide

  128. Sabia que você pode contribuir?
    → Projeto App Center Build Scripts Examples
    → https://github.com/Microsoft/appcenter-build-
    scripts-examples

    View Slide

  129. O processo ainda não acaba
    O que vimos é o mais complicado
    O restante é bem simples

    View Slide

  130. Publicando o app na loja

    View Slide

  131. Publicando o
    app na loja
    → Conectar o projeto a loja
    → Google Play
    → Apple Store

    View Slide

  132. Publicando o
    app na loja
    → Escolher onde publicar
    → Produção
    → Testes

    View Slide

  133. Publicando o
    app na loja
    → Envie o APK ou IPA
    → Adicione o release notes
    → Ser feliz
    !

    View Slide

  134. Publicando o
    app na loja
    → Limitações no iOS: somente é
    possível enviar release notes
    em inglês
    !

    View Slide

  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

    View Slide

  136. Ione Souza Junior
    Desenvolvedor mobile @ Unimestre
    @ionixjunior
    [email protected]

    View Slide