Cómo el equipo de Android de Tunaiku se enfrenta a un aumento de recursos con una nueva estructura de asignación de Suyanwar Wawang | Octubre de 2020

En el mundo de los productos, es posible que hayamos oído hablar de la gestión de modelos tribales. La gestión del modelo de deformación es parte de una estrategia de escalado ágil que se utiliza por primera vez para ayudar al departamento de desarrollo en crecimiento de una empresa. Este enfoque implica dividir los equipos de ingeniería en «unidades» autónomas que trabajan juntas en aspectos específicos del producto. Luego, varias divisiones que trabajan en la misma área comercial, como la tecnología de búsqueda, se agrupan en un equipo más grande llamado tribu. No quiero hablar mucho sobre este modelo, pero el punto es, ¡sí! Usando este modelo, Tunaiku intenta asignar de manera óptima los recursos existentes.

Entonces, ¿cuál es la correlación con el equipo de desarrollo?

La correlación es que necesitamos ajustar nuestro esquema de ramificación de git.

Para su información, en ese momento, nuestro esquema de ramificación de git tiene solo un desarrollo, preparación y master, y nuestros tipos de compilación también se dividen en tres tipos, que son desarrollo, preparación y en vivo. Nuestro diagrama estaba en el diagrama.

Esquema de antiguos tipos de montaje.
Esquema de ramificación antiguo de Git
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
crunchPngs false
ext.alwaysUpdateBuildId = false
}
dev {
initWith buildTypes.debug
buildConfigField "String", "URL_BASE", ""https://dev.google.com""
}
staging {
initWith buildTypes.release
debuggable true
buildConfigField "String", "URL_BASE", ""https://staging.google.com""
}
live {
initWith buildTypes.release
debuggable false
buildConfigField "String", "URL_BASE", ""https://google.com""
}
}
variantFilter { variant ->
if (variant.buildType.name.endsWith('release') || variant.buildType.name.endsWith('debug')) {
// Gradle ignores any variants that satisfy the conditions above.
setIgnore(true)
}
}

Si nos mantenemos en nuestro esquema de ramificación de git actual para admitir varios propósitos de equipo, las funciones de cada equipo se moverán al mismo depósito en cada entorno y tendrán el potencial de romperse o romperse entre sí porque todavía están clasificadas en una aplicación debido a la escala de aplicaciones. De hecho, se puede evitar una verificación exhaustiva del código, pero creemos que hay otra forma de resolver esta dependencia.

Por esta razón, también agregamos una rama de desarrollo y trabajo para cada grupo y creamos otra rama, es decir, la versión que se utilizará como rama combinada de las diversas funciones de grupo que se probaron desde el entorno de trabajo. Para personalizar perfectamente esta rama de git, modificamos nuestra compilación de compilación gradl para que sea una combinación de tipos de compilación y gustos de productos de acuerdo con la cantidad de grupos que existen en Tunaik. El siguiente ejemplo es si hay dos equipos en Tunaiku, a saber, Crecimiento y Experiencia. Este es nuestro diagrama en el diagrama.

Esquema de tipo de ensamblaje actual
Esquema de ramificación actual de Git
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}debug {
crunchPngs false
ext.alwaysUpdateBuildId = false
}dev {
initWith buildTypes.debug
buildConfigField "String", "URL_BASE", ""https://dev.google.com""
}staging {
initWith buildTypes.release
debuggable true
buildConfigField "String", "URL_BASE", ""https://staging.google.com""
}live {
initWith buildTypes.release
debuggable false
buildConfigField "String", "URL_BASE", ""https://google.com""
}
}
variantFilter { variant ->
if (variant.buildType.name.endsWith('release') || variant.buildType.name.endsWith('debug')) {
// Gradle ignores any variants that satisfy the conditions above.
setIgnore(true)
}
}

productFlavors {
growth {
resConfigs "xhdpi"
versionNameSuffix "-growth"
applicationId "com.suyanwar.samplecicd.growth"
}
experience {
resConfigs "xhdpi"
versionNameSuffix "-experience"
applicationId "com.suyanwar.samplecicd.experience"
}
releaseCandidate {
resConfigs "xhdpi"
versionNameSuffix "-rc"
applicationId "com.suyanwar.samplecicd.release"
}
sample {
applicationId "com.suyanwar.samplecicd"
}
}
Variante de compilación actual

Debido a que nuestro gradle admite el nuevo esquema de ramificación de git, el siguiente paso es modificar la configuración en Circle CI. Reconocemos que al utilizar el antiguo esquema de ramificación de git, no hemos implementado la integración y la entrega continuas. Entonces, cuando nuestra tarea de función se fusiona en una rama de desarrollo, actualizaremos a QA para sacarla de la rama de desarrollo.

Luego, a medida que crecen los recursos humanos, nos damos cuenta de que CI / CD es importante para optimizar el desarrollo de nuestro desempeño. Así que hice un ejemplo simple para un CI / CD con el antiguo esquema de ramificación de git. Espero que esté familiarizado con el comando básico de Circle CI y la integración de Fastlane.

version: 2.1
references:
container_config: &container_config
docker:
- image: circleci/android:api-29

working_directory: ~/repo

environment:
JVM_OPTS: -Xmx2048m
GRADLE_OPTS: -Xmx1536m -XX:+HeapDumpOnOutOfMemoryError -Dorg.gradle.caching=true -Dorg.gradle.configureondemand=true -Dkotlin.compiler.execution.strategy=in-process -Dkotlin.incremental=false
TERM: dumb

shell: /bin/bash --login -o pipefail
commands:
#======================================#
setup_dependencies:
description: "Setup All Req Dependency"
steps:
- checkout
- restore_cache:
keys:
- v1-dependencies-{{ checksum "build.gradle" }}
- v1-dependencies-
- run:
name: Update Dependencies
command: sudo apt-get update
- run:
name: Upgrade Dependencies
command: sudo apt-get upgrade
- run:
name: Download Ruby
command: sudo apt-get install ruby-full build-essential
- run:
name: Install Bundler
command: sudo gem install bundler && bundle update
- run:
name: Set Ruby Version
command: echo "ruby-2.4" > ~/.ruby-version
- run:
name: Download Ruby Dependencies
command: bundle check || bundle install --path vendor/bundle
- run:
name: Install Bundle
command: bundle install
- run:
name: Install Fastlane
command: sudo gem install fastlane --no-rdoc --no-ri
- run:
name: Update Bundle
command: bundle update --bundler
- run:
name: Install Fastlane AppCenter
command: fastlane add_plugin appcenter
- run:
name: Download jdk 8
command: wget -qO - https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | sudo apt-key add - && sudo apt-get update && sudo apt-get install software-properties-common && sudo apt-get update && sudo add-apt-repository --yes https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ && sudo apt-get update && sudo apt-get install adoptopenjdk-8-hotspot
- run:
name: Setup Java Home
command: echo 'export JAVA_HOME=/usr/lib/jvm/adoptopenjdk-8-hotspot-amd64' >> ~/.bash_profile
- run:
name: Check Java Version
command: java -version && sudo update-alternatives --config java && echo $JAVA_HOME
#======================================#
build_deploy_development:
description: "Build and Deploy Development"
steps:
- run:
name: Build Project
command: ./gradlew assembleDev
- store_artifacts:
path: app/build/outputs/apk/dev
destination: dev
- run:
name: Deploy Update
command: bundle exec fastlane deployToAppCenter pathapk:app/build/outputs/apk/dev/app-dev.apk appname:SampleCICD
build_deploy_staging:
description: "Build and Deploy Staging"
steps:
- run:
name: Build Project
command: ./gradlew assembleStaging
- store_artifacts:
path: app/build/outputs/apk/staging
destination: staging
- run:
name: Deploy Update
command: bundle exec fastlane deployToAppCenter pathapk:app/build/outputs/apk/staging/app-staging.apk appname:SampleCICD
build_deploy_live:
description: "Build and Deploy Live"
steps:
- run:
name: Build Project
command: ./gradlew assembleLive
- store_artifacts:
path: app/build/outputs/apk/live
destination: live
- run:
name: Deploy Update
command: bundle exec fastlane deployToAppCenter pathapk:app/build/outputs/apk/live/app-live.apk appname:SampleCICD

jobs:
build_development:
<<: *container_config
steps:
- setup_dependencies
- build_deploy_development
build_staging:
<<: *container_config
steps:
- setup_dependencies
- build_deploy_staging
build_live:
<<: *container_config
steps:
- setup_dependencies
- build_deploy_live

workflows:
version: 3
build_and_deploy:
jobs:
- build_development:
filters:
branches:
only:
- development
- build_staging:
filters:
branches:
only:
- staging
- build_live:
filters:
branches:
only:
- master

Sí, este es el código de mi config.yml dentro de la carpeta .circleci. Debido a que usamos fastlane, deberíamos proporcionar Gemfile en el proyecto raíz para definir nuestra dependencia de fastlane y la carpeta fastlane para crear una declaración fastlane.

Aquí está mi Gemfile

source "https://rubygems.org"

gem "fastlane"
gem "rake"

plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
eval_gemfile(plugins_path) if File.exist?(plugins_path)

Y mi comando fastlane dentro de Fastfile. Solo el tiene deployToAppCenter mando.

fastlane_version "2.145.0"
default_platform :android
platform :android do
desc "Deploy Squad APK to AppCenter"
lane :deployToAppCenter do |options|
appcenter_upload(
api_token: "<Your api token from App Center>",
owner_name: "<Your repository from App Center>",
app_name: options[:appname],
file: options[:pathapk]
)
end
end

Y como usamos fastlane-plugin-appcenter, deberíamos registrar este complemento en Pluginfile

gem 'fastlane-plugin-appcenter'

La configuración era buena, pero cuando pasamos a nuestro nuevo esquema de ramificación de git, necesitamos modificar nuestro config.yml para admitir una combinación de tipos de compilación y sabores de productos. Este es nuestro config.yml, que se ha adaptado al nuevo esquema de ramificación de git.

version: 2.1
references:
container_config: &container_config
docker:
- image: circleci/android:api-29

working_directory: ~/repo

environment:
JVM_OPTS: -Xmx2048m
GRADLE_OPTS: -Xmx1536m -XX:+HeapDumpOnOutOfMemoryError -Dorg.gradle.caching=true -Dorg.gradle.configureondemand=true -Dkotlin.compiler.execution.strategy=in-process -Dkotlin.incremental=false
TERM: dumb

shell: /bin/bash --login -o pipefail
commands:
#======================================#
setup_dependencies:
description: "Setup All Req Dependency"
steps:
- checkout
- restore_cache:
keys:
- v1-dependencies-{{ checksum "build.gradle" }}
- v1-dependencies-
- run:
name: Update Dependencies
command: sudo apt-get update
- run:
name: Upgrade Dependencies
command: sudo apt-get upgrade
- run:
name: Download Ruby
command: sudo apt-get install ruby-full build-essential
- run:
name: Install Bundler
command: sudo gem install bundler && bundle update
- run:
name: Set Ruby Version
command: echo "ruby-2.4" > ~/.ruby-version
- run:
name: Download Ruby Dependencies
command: bundle check || bundle install --path vendor/bundle
- run:
name: Install Bundle
command: bundle install
- run:
name: Install Fastlane
command: sudo gem install fastlane --no-rdoc --no-ri
- run:
name: Update Bundle
command: bundle update --bundler
- run:
name: Install Fastlane AppCenter
command: fastlane add_plugin appcenter
- run:
name: Download jdk 8
command: wget -qO - https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | sudo apt-key add - && sudo apt-get update && sudo apt-get install software-properties-common && sudo apt-get update && sudo add-apt-repository --yes https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ && sudo apt-get update && sudo apt-get install adoptopenjdk-8-hotspot
- run:
name: Setup Java Home
command: echo 'export JAVA_HOME=/usr/lib/jvm/adoptopenjdk-8-hotspot-amd64' >> ~/.bash_profile
- run:
name: Check Java Version
command: java -version && sudo update-alternatives --config java && echo $JAVA_HOME
#======================================#
build_deploy_development_growth:
description: "Build and Deploy Development Growth"
steps:
- run:
name: Build Project
command: ./gradlew assembleGrowthDev
- store_artifacts:
path: app/build/outputs/apk/growth/dev
destination: dev
- run:
name: Deploy Update
command: bundle exec fastlane deployToAppCenter pathapk:app/build/outputs/apk/growth/dev/app-growth-dev.apk appname:SampleCICD-Growth
build_deploy_development_experience:
description: "Build and Deploy Development Experience"
steps:
- run:
name: Build Project
command: ./gradlew assembleExperienceDev
- store_artifacts:
path: app/build/outputs/apk/experience/dev
destination: dev
- run:
name: Deploy Update
command: bundle exec fastlane deployToAppCenter pathapk:app/build/outputs/apk/experience/dev/app-experience-dev.apk appname:SampleCICD-Experience
build_deploy_staging_growth:
description: "Build and Deploy Staging Growth"
steps:
- run:
name: Build Project
command: ./gradlew assembleGrowthStaging
- store_artifacts:
path: app/build/outputs/apk/growth/staging
destination: staging
- run:
name: Deploy Update
command: bundle exec fastlane deployToAppCenter pathapk:app/build/outputs/apk/growth/staging/app-growth-staging.apk appname:SampleCICD-Growth
build_deploy_staging_experience:
description: "Build and Deploy Staging Experience"
steps:
- run:
name: Build Project
command: ./gradlew assembleExperienceStaging
- store_artifacts:
path: app/build/outputs/apk/experience/staging
destination: staging
- run:
name: Deploy Update
command: bundle exec fastlane deployToAppCenter pathapk:app/build/outputs/apk/experience/staging/app-experience-staging.apk appname:SampleCICD-Experience
build_deploy_release_candidate:
description: "Build and Deploy Release Candidate"
steps:
- run:
name: Build Project
command: ./gradlew assembleReleaseCandidateStaging
- store_artifacts:
path: app/build/outputs/apk/releaseCandidate/staging
destination: staging
- run:
name: Deploy Update
command: bundle exec fastlane deployToAppCenter pathapk:app/build/outputs/apk/releaseCandidate/staging/app-releaseCandidate-staging.apk appname:SampleCICD-Release
build_deploy_live:
description: "Build and Deploy Live"
steps:
- run:
name: Build Project
command: ./gradlew assembleSampleLive
- store_artifacts:
path: app/build/outputs/apk/sample/live
destination: live
- run:
name: Deploy Update
command: bundle exec fastlane deployToAppCenter pathapk:app/build/outputs/apk/sample/live/app-sample-live.apk appname:SampleCICD

jobs:
build_development_growth:
<<: *container_config
steps:
- setup_dependencies
- build_deploy_development_growth
build_development_experience:
<<: *container_config
steps:
- setup_dependencies
- build_deploy_development_experience
build_staging_growth:
<<: *container_config
steps:
- setup_dependencies
- build_deploy_staging_growth
build_staging_experience:
<<: *container_config
steps:
- setup_dependencies
- build_deploy_staging_experience
build_release_candidate:
<<: *container_config
steps:
- setup_dependencies
- build_deploy_release_candidate
build_live:
<<: *container_config
steps:
- setup_dependencies
- build_deploy_live

workflows:
version: 3
build_and_deploy:
jobs:
- build_development_growth:
filters:
branches:
only:
- development-growth
- build_development_experience:
filters:
branches:
only:
- development-experience
- build_staging_growth:
filters:
branches:
only:
- staging-growth
- build_staging_experience:
filters:
branches:
only:
- staging-experience
- build_release_candidate:
filters:
branches:
only:
- release
- build_live:
filters:
branches:
only:
- master

Lo más probable es que, como antes, acabamos de crear otro comando y tarea para admitir múltiples variantes de ensamblaje y lo registramos en flujos de trabajo con algunas condiciones, como se mencionó anteriormente.

Creo que eso es todo lo que puedo compartir sobre cómo el equipo de Android tunaik se enfrenta a un recurso en crecimiento con una nueva estructura de asignación. No dudes en comentar y preguntar. ¡Gracias!

Enlace:
https://www.productplan.com/glossary/tribe-model-management/

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *