/ bitrise

Bitrise - Comment créer sa step... et la partager :)

Bonjour à toutes et à tous, aujourd'hui nous allons voir ensemble comment créer sa step (proprement) et la partager à l'ensemble de la communauté Bitrise.

Sommaire

Objectif du tutoriel
Installation du client Bitrise
Initialisation de la step
Les workflows
Spécifications de la step
Réalisation
Annexes

Pour rappel Bitrise est une solution qui permet d'industrialiser vos compilations mobiles (iOS, Android, Xamarin, ReactNative, Ionic etc.) en vous mettant à disposition des machines virtuelles dédiées pendant un laps de temps défini.

Ces machines virtuelles sont lancées à la demande suivant des évènements déclencheurs (activité sur le repository de votre code source par exemple) et exécutent un worflow contenant un ensemble de steps.

Une step c'est une étape (bravo à toute l'équipe de traducteurs...) de votre workflow. Elle va s'exécuter et réaliser une tâche spécifique.

Bitrise propose un catalogue de step prêtes à l'emploi.

bitrise-steps-catalog

Objectif

Ce que je vous propose dans le cadre de ce tutoriel c'est de vous accompagner dans la réalisation d'une step, en vous expliquant les différentes étapes essentielles jusqu'à sa soumission aux équipes Bitrise.

Client en ligne de commande

Bitrise est une solution SAAS mais il est tout de même possible de travailler localement avec. Pour cela nous allons tout d'abord installer le client Bitrise en CLI avec homebrew.

MacBook-Pro-de-spousse:~ spousse$ brew install bitrise

Setup

Nous allons mettre à jour avec un bitrise setup qui va s'occuper de mettre à jour les outils du noyau comme envman, stepman. Installation de plugins de bitrise également avec notamment un pour les steps qui va nous intéresser.

MacBook-Pro-de-spousse:~ spousse$ bitrise setup

  ██████╗ ██╗████████╗██████╗ ██╗███████╗███████╗
  ██╔══██╗██║╚══██╔══╝██╔══██╗██║██╔════╝██╔════╝
  ██████╔╝██║   ██║   ██████╔╝██║███████╗█████╗
  ██╔══██╗██║   ██║   ██╔══██╗██║╚════██║██╔══╝
  ██████╔╝██║   ██║   ██║  ██║██║███████║███████╗
  ╚═════╝ ╚═╝   ╚═╝   ╚═╝  ╚═╝╚═╝╚══════╝╚══════╝

  version: 1.12.0

Setup
Full setup: false
Clean setup: false
Detected OS: darwin

Checking Bitrise Core tools...
[OK] envman (1.1.9): /Users/spousse/.bitrise/tools/envman
[OK] stepman (0.9.37): /Users/spousse/.bitrise/tools/stepman

Doing OS X specific setup
Checking required tools...
[OK] Homebrew 1.5.2: /usr/local/bin/brew
[OK] Homebrew/homebrew-core (git revision f4c7d; last commit 2018-01-30)
[OK] xcodebuild (Xcode 8.1 | Build version 8B62): /usr/bin/xcodebuild
[OK] active Xcode (Command Line Tools) path (xcode-select --print-path): /Applications/Xcode.app/Contents/Developer

Checking Bitrise Plugins...
[OK] Plugin workflow-editor (1.1.3): /Users/spousse/.bitrise/plugins/workflow-editor
[OK] Plugin analytics (0.9.11): /Users/spousse/.bitrise/plugins/analytics
[OK] Plugin init (1.0.1): /Users/spousse/.bitrise/plugins/init
[OK] Plugin step (0.9.5): /Users/spousse/.bitrise/plugins/step

Checking Bitrise Toolkits...
[OK] go (1.9.2): /Users/spousse/.bitrise/toolkits/go/inst/go/bin/go
[OK] bash (GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)): /bin/bash

All the required tools are installed! We're ready to rock!!

To start using bitrise:
* cd into your project's directory (if you're not there already)
* call: bitrise init
* follow the guide

That's all :)

Initialisation de la step

Entrons dans le vif du sujet. Nous allons partir d'un cas concret.
En ce moment j'ai besoin de pouvoir déposer un build sur wetransfer pour l'envoyer à un tiers.

Nous allons concevoir cette step qui upload un fichier sur wetransfer.

La petite nouveauté c'est que depuis la version 1.6 du client Bitrise en CLI, la création d'une step est simplifiée. Mettez vous dans un répertoire de travail, et lancez la commande bitrise :step create

MacBook-Pro-de-spousse:~ spousse$ bitrise :step create
Who are you / who's the author? : kawaiseb
What's the title / name of the Step? : wetransfer
Generated Step ID (from provided Title): wetransfer
Please provide a summary : Upload files to wetransfer and share a short url to download
Please provide a description : This step send files to wetransfer. Wetransfer give you a short url to download files. Limit 2GO.

Renseignez en mode pas à pas toutes les informations sur la step.

What's the primary category of this Step?
Please select from the list:
[1] : access-control
[2] : artifact-info
[3] : installer
[4] : deploy
[5] : utility
[6] : dependency
[7] : code-sign
[8] : build
[9] : test
[10] : notification
(type in the option's number, then hit Enter) : 5

Je me place dans la catégorie utility.

Toolkit: the entry/base language of the Step.
Our recommendation is to use Bash for very simple Steps
 and for more complex ones use another language, one which we have toolkit support for.
If you're just getting started with Step development our suggestion is to select Bash,
 as that's the easiest option. It's possible to convert the step later, if needed.
Note: Of course even if you select e.g. Bash as the entry language, you can run other scripts from there,
 so it's possible to write the majority of the step's code in e.g. Ruby,
 and have an entry Bash script which does nothing else except running the Ruby script.
Which toolkit (language) would you like to use?
Please select from the list:
[1] : bash
[2] : go
(type in the option's number, then hit Enter) : 1

Dans mon cas, j'ai choisi de faire la step en nodejs, le script sera lancé en bash donc choix 1).

Website & source code URL:
Will you host the source code on GitHub? [YES/no]: YES
What's your GitHub username (user/org where you'll register the step's repository)? : kawaiseb
We'll use https://github.com/kawaiseb/bitrise-step-wetransfer as the website/repo URL for this step.
Please when you create the repository on GitHub for the step
 create it under the user/org: kawaiseb
 and the name of the repository should be: bitrise-step-wetransfer

Creating Step directory at: /Users/spousse/bitrise-step-wetransfer
 * [OK] created: /Users/spousse/bitrise-step-wetransfer/README.md
 * [OK] created: /Users/spousse/bitrise-step-wetransfer/LICENSE
 * [OK] created: /Users/spousse/bitrise-step-wetransfer/.gitignore
 * [OK] created: /Users/spousse/bitrise-step-wetransfer/step.yml
 * [OK] created: /Users/spousse/bitrise-step-wetransfer/bitrise.yml
 * [OK] created: /Users/spousse/bitrise-step-wetransfer/.bitrise.secrets.yml
 * [OK] created: /Users/spousse/bitrise-step-wetransfer/step.sh

Initializing git repository in step directory ...
 $ git "init"
 $ git "remote" "add" "origin" "https://github.com/kawaiseb/bitrise-step-wetransfer"

Step is ready!

You can find it at: /Users/spousse/bitrise-step-wetransfer

TIP: cd into /Users/spousse/bitrise-step-wetransfer and run bitrise run test for a quick test drive!

Je décide de mettre la step sur github. Le répertoire de ma step est créé, ainsi que l'ensemble des fichiers nécessaires.

On vérifie que le workflow de test se lance bien...

MacBook-Pro-de-spousse:bitrise-step-wetransfer spousse$ bitrise run test

Achtung !

Il y a quelques règles fondamentales à savoir avant de commencer...

  1. Toutes les variables d'entrée / sortie que l'on manipule dans les steps sont des variables d'environnement
  2. Il n'existe qu'un seul type pour les variables d'environnement : STRING
  3. Si vous créez une variable d'environnement dans un processus enfant, elle ne sera pas visible du processus parent

Je le reprécise, car cela m'a posé quelques soucis :)

Plus de détail ici : http://devcenter.bitrise.io/bitrise-cli/most-important-concepts/

Les workflows

bitrise.yml

Ce fichier est en fait le fichier de configuration principal. Il va permettre de déclarer un ou plusieurs workflow et définir une ou plusieurs step à éxécuter. C'est en sorte votre ordonnanceur, que vous retrouverez sur le cloud. Ce fichier est au format YAML.

Regardons de plus prêt quelques éléments du fichier...

Les variables d'environnement

Nous avons une serie de variables déclarées de façon globale à notre application. Ces variables sont réutilisables de n'importe où par la suite.

app:
  envs:

  # If you want to share this step into a StepLib
  - BITRISE_STEP_ID: wetransfer
  - BITRISE_STEP_VERSION: "0.0.4"
  - BITRISE_STEP_GIT_CLONE_URL: https://github.com/kawaiseb/bitrise-step-wetransfer.git
  - MY_STEPLIB_REPO_FORK_GIT_URL: https://github.com/kawaiseb/bitrise-steplib

Pour la variable MY_STEPLIB_REPO_FORK_GIT_URL il va falloir au préalable forker le projet bitrise-steplib . En effet c'est dans ce projet que sera placée notre step au final.

Le workflow de test

Le worflow intitulé test contient une step avec un script bash qui va afficher la variable d'environnement déclarée plus haut. Rien de bien passionnant pour le moment.

workflows:
  test:
    steps:
    - script:
        inputs:
        - content: |
            #!/bin/bash
            echo "Just an example 'secrets' print."
            echo "The value of 'A_SECRET_PARAM' is: $A_SECRET_PARAM"

Le workflow de test permettra plus tard de tester votre step en ligne de commande mais également par Bitrise.

La spécification

Revenons à nos moutons. Je vais déclarer tous les paramètres dont j'ai besoin pour réaliser l'upload vers wetransfer. Voici ce dont j'ai besoin :

  • L'email de l'émetteur
  • L'email du/des destinataires
  • Un petit message pour accompagner le lien
  • Le / Les fichiers à envoyer à wetransfer

Ce n'est pas plus compliqué que cela. Une fois le problème posé voici comment le résoudre.

Réalisation

La description de la step (step.yml)

La source ici : https://github.com/kawaiseb/bitrise-step-wetransfer/blob/master/step.yml

C'est dans ce fichier que nous allons décrire le fonctionnement de la step et indiquer l'ensemble des paramètres nécessaires à son bon fonctionnement.

Je ne vais pas entrer dans tous les détails, ce qui m'intéresse dans mon cas ce sont les variables d'entrées :

inputs:
  # All parameter we need to upload files to wetransfer
  - wtu_mailsender:
    opts:
      title: Email of the sender
      is_expand: true
      is_required: true

  - wtu_mailreceiver:
    opts:
      title: One or more email separated by coma for receiver
      is_required: true

Cela se matérialisera ainsi :

Capture-d-e-cran-2018-02-19-a--08.09.34

La mention is_expand permet de déplier directement la description du champs
La mention is_required permet de préciser que la variable est requise.

Et ainsi de suite pour tous les paramètres attendus. Possibilité de faire des listes également. Par exemple pour le mode debug je souhaite juste faire un enum {yes, no}.

 # Debug mode desactivated by default
  - wtu_debug_mode: "no"
    opts:
      title: "Debug mode ?"
      description: |
        Step prints additional debug information if this option
        is enabled
      is_expand: true
      is_required: false
      value_options:
        - "yes"
        - "no"

Prendra la forme...

Capture-d-e-cran-2018-02-19-a--08.12.30

L'éxécution de la step (step.sh)

La source ici : https://github.com/kawaiseb/bitrise-step-wetransfer/blob/master/step.sh

C'est ce fichier qui va être exécuté à chaque lancement de la step. Suite à aux retours de Bitrise, j'ai du procéder à quelques modifications. La plus importante c'est ne pas modifier le répertoire de travail. C'est ce qui est préconisé par Bitrise.

Au final, le step.sh va lancer mon script nodejs avec la série de paramètres qui auront été entrés dans l'interface de configuration de la step.

#!/bin/bash
set -ex

THIS_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

npm install --prefix $THIS_SCRIPT_DIR wetransfert --save

$THIS_SCRIPT_DIR/upload.js "${wtu_debug_mode}" "${wtu_mailsender}" "${wtu_mailreceiver}" "${wtu_filepath}" "${wtu_message}" "${wtu_language}"

Le script principal (upload.js)

La source ici : https://github.com/kawaiseb/bitrise-step-wetransfer/blob/master/upload.js

Je ne vais pas entrer sur le détail du script, ce n'est pas vraiment l'objet du tutoriel, comprenez juste qu'il est a peu prêt possible d'écrire dans le langage de son choix. Il faut juste penser que sa step sera chargée sur une machine virtuelle, et qu'il faudra juste prendre quelques précautions pour s'assurer que la machine dispose du bon interprêteur pour lancer votre script.

Le script transfer.js prend des arguments sur l'entrée standard qui correspondent aux paramètres attendus et fournis par la step.

#!/usr/bin/env node

const fs = require('fs');
const { upload } = require('wetransfert');

// USAGE : node wetransfertupload.js debug sender receiver filepath message lang

let debug = process.argv[2]; //debug true/false
let sender = process.argv[3]; //email of the sender
let receivers = process.argv[4]; //email of the receiver
let filepath = process.argv[5]; //filepath where files to send are
let message = process.argv[6]; //body of the mail
let lang = process.argv[7]; //langage of the mail
let tabReceivers;

// testing parameters
if(debug == null || sender == null || receivers == null || filepath == null || lang == null) {
  console.log('ERROR : One or more parameters are invalid');
  return 1;
}

Ce qui est important c'est de pouvoir notamment signifier à l'utilisateur assez rapidement lorsque la step n'a pas tous les paramètres requis. Je ne suis pas allé très loin dans cette première version. D'autant que nous précisons une valeur à is_required dans le step.yml.

Mais par exemple je pourrais vérifier que le répertoire donné existe bien et contient bien des fichiers, si ce n'est pas le cas je renvoie directement une erreur. Cela évite de perdre du temps et d'interrompre la step directement.

L'audit de la step

Notre step est terminée, nous allons vérifier que tout est ok en lançant l'audit de notre step via la commande :

MacBook-Pro-de-spousse:bitrise-step-wetransfer spousse$ bitrise run audit-this-step

A priori c'est la conformité de step.yml qui est testée ici. Si tout s'est bien passé on voit apparaitre un :

+ stepman audit --step-yml ./step.yml
INFO[13:47:49]  * [OK] Success audit (./step.yml)

Fork du projet bitrise-steplib

L'objectif au final est de mettre sa step dans le projet bitrise-steplib et de faire une PR à Bitrise qui validera la step (ou non).

Faites un fork du projet : https://github.com/bitrise-io/bitrise-steplib

Ensuite renseignez bien l'url du fork dans le fichier bitrise.yml

- MY_STEPLIB_REPO_FORK_GIT_URL: https://github.com/kawaiseb/bitrise-steplib

Une fois cette opération effectuée, on peut partager sa step.

Partager la step

Lancer la commande :

bitrise-step-wetransfer [master] bitrise run share-this-step

Cette commande va préparer la PR vers stepLib. Il n'y aura plus qu'a la soumettre à Bitrise.

Capture-d-e-cran-2018-02-18-a--22.56.41

Bon... Je ne vous cache pas qu'il m'a fallu m'y reprendre à 3 reprises :)

Capture-d-e-cran-2018-02-19-a--10.44.11

pour qu'elle soit acceptée voici les principales raisons du refus des équipes Bitrise :

  • Nettoyage de la step, j'avais laissé pas mal de choses inutiles
  • Mauvais respect des guidelines sur les noms de variables. Les variables d'input doivent être en minuscule, celles d'output en majuscule par exemple
  • Ensuite dans ma step je faisais un changement de directory ce qui effectivement pouvait avoir un impact pour une personne qui exécutait ma step dans son worklow

Conclusion

Bon voilà comment se passe la réalisation d'une step et son partage. Le truc sympa c'est que vous pouvez utiliser la technologie de votre choix, on aurait très bien pu faire un script en Ruby, en php, bref je n'ai pas vu de limites. La seule limite c'est de préinstaller les dépendances nécessaires.

N'hésitez pas à m'écrire des commentaires, posez vos questions ou me dire si certains points ne sont pas suffisament clairs :)

Annexes

Vous retrouvez les sources de la step en question ici : https://github.com/kawaiseb/bitrise-step-wetransfer

Le projet bitrise-steplib de bitrise qu'il conviendra de forker : https://github.com/bitrise-io/bitrise-steplib

Le lib nodejs pour utiliser l'API wetransfer : https://www.npmjs.com/package/wetransfert

Le site Bitrise :
https://www.bitrise.io

Le forum de discussion, sont bien réactifs :
https://discuss.bitrise.io/