Comment automatiser le déploiement d'une PWA ionic/angular en utilisant uniquement Git et Bash
Faire ces 4 opérations manuellement peut devenir très ennuyeux à la longue mais aussi être une source d'erreur. pour ma part je travaille sur un système d'exploitation Linux, j'ai donc écrit un script shell qui permet d'automatiser ces opérations

Introduction
Ionic Framework est un ensemble d'outils d'interface utilisateur mobile open source permettant de créer des expériences d'applications web et natives de haute qualité et multiplateformes. Il vous permet d'aller plus vite avec une base de programmation unique qui fonctionne partout.
Ionic est un outil assez complet lorsqu'il s'agit de créer une PWA (Progressive Web Application). Si vous ne le savez pas encore, une PWA est une application web qui se compose de pages ou de sites web et qui peut apparaître à l'utilisateur de la même manière que les applications natives ou les applications mobiles.
Ionic ne fait aucune supposition sur la pile technologique (ensemble de technologies) avec laquelle vous ou votre équipe préférez construire. C'est pourquoi Ionic est conçu pour s'intégrer de manière transparente avec tous les meilleurs frameworks frontaux, y compris Angular, React, Vue, ou même aucun framework du tout avec JavaScript vanilla (pur javascript) .
Installation
Pour ma part j'ai utilisé le framework Angular pour développer ma PWA, la mise en place d'Angular et la création d'une application ionic se fait en ligne de commande, grâce à l'outil @ionic/cli
$ npm install -g @ionic/cli
$ ionic start myApp tabs
la première commande va installer @ionic/cli et la seconde va créer un squelette d'application (une architecture de dossiers et une configuration de base) en utilisant le modèle tabs.
Une fois installé vous pouvez lancer un serveur de développement pour voir en temps réel, les changements que vous faites pendant le développement (Live reload), une fois que le développement de votre application est terminé vient la phase de production.
Mise en production
$ ionic build --prod
cette commande crée un dossier de construction avec une construction de production de votre application, ce dossier est www/ par défaut. Configurez votre serveur HTTP préféré afin qu'un visiteur de votre site reçoive index.html, voici un exemple de configuration avec apache :
<IfModule mod_rewrite.c >
RewriteEngine on
RewriteOptions inherit
# let's encrypt ssl
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/.+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^.well-known/acme-challenge - [L]
# redirect to no-www
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
# https redirect
RewriteCond %{HTTPS} !=on
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
</IfModule>
Il ne vous reste plus qu'à envoyer le contenu du dossier www/ généré par la commande précédente vers votre serveur distant (serveur de production). Pour se faire, plusieurs solutions s'offrent à vous, vous pouvez utiliser FTP, AppFlow (qui est une plateforme d'intégration continue (CI) et de déploiement continu (CD) pour ionic), ou tout simplement GIT, c'est cette dernière solution que j'ai personnellement utilisée la première fois 😋👌🏽.
Automatiser le déploiement avec un script Bash
Si vous m'avez bien suivi, vous avez sans doute compris que pour chaque nouvelle version de votre application, vous devrez :
créer un build de production (ionic build -prod).
supprimer les anciens fichiers et les remplacer par les nouveaux (localement).
supprimer les anciens fichiers (en production).
et enfin envoyer les nouveaux fichiers en production.
faire ces 4 opérations manuellement peut devenir très ennuyeux à la longue mais aussi être une source d'erreur. pour ma part je travaille sur un système d'exploitation Linux, j'ai donc écrit un script shell qui permet d'automatiser ces opérations ✌🏽✌🏽.
comme j'ai décidé d'utiliser GIT : supprimer les anciens fichiers et les remplacer par les nouveaux n'est plus un problème, il suffit de versionner nos builds de production et d'envoyer les repos git sur le serveur de production pour pouvoir envoyer progressivement les changements effectués tout en gardant un historique de toutes les anciennes versions ! génial non ?
mais attention ! !! ne versionnez pas le dossier www/, car le contenu de ce dossier est supprimé à chaque compilation et ignoré par git dans le .gitignore du projet ionic dans lequel vous vous trouvez, vous devrez donc créer un nouveau dossier ( repository ) dans lequel vous versionnerez les compilations de production.
BUILD_DEPLOY_DIRECTORY="$HOME/dev/projects/app-build"
BUILD_DEPLOY_REMOTE=$(git config --get remote.origin.url)
BUILD_DIRECTORY="$HOME/dev/projects/app/www" # www or build
BUILD_COMMIT_MESSAGE=$(date +'%c')
R=$(tput setaf 1)
G=$(tput setaf 2)
Y=$(tput setaf 3)
NC=$(tput sgr0)
function angular_cli_build() {
printf "Building the project with angular CLI...\n\n"
ng lint &&
ng build --prod &&
printf "%sApplication built with angular CLI ! %s \n\n" "$G" "$NC"
}
function delete_previous_build() {
printf "Changing directory to build-deploy directory... \n\n"
cd "$BUILD_DEPLOY_DIRECTORY" || exit 2
printf "%sChanged, current directory : (%s) ! %s \n" "$G" "$PWD" "$NC"
printf "%sDeleting previous build files except from (.htaccess)... %s \n\n" "$Y" "$NC"
if [ "$PWD" == "$BUILD_DEPLOY_DIRECTORY" ]; then
rm -vrf $(ls -I ".htaccess" -aI ".git")
printf "%sPrevious build files deleted %s \n\n" "$G" "$NC"
else
printf "%sTrying to delete files in the wrong directory ! %s \n" "$G" "$NC"
exit 1
fi
}
function version_and_deploy() {
printf "Copying new built files from build to build-deploy directory... \n\n"
cp -av "$BUILD_DIRECTORY/." "$BUILD_DEPLOY_DIRECTORY"
printf "%sFiles copied to (%s) ! %s \n\n" "$G" "$BUILD_DEPLOY_DIRECTORY" "$NC"
printf "Versioning new build... \n\n"
git add . &&
git commit -m "build(app): ${BUILD_COMMIT_MESSAGE}" &&
printf "%sNew build versioned %s \n" "$G" "$NC"
printf "%sDeploying to remote server (%s) ... %s \n\n" "$Y" "$BUILD_DEPLOY_REMOTE" "$NC" &&
git push origin master &&
printf "%s Deployed ! %s \n" "$G" "$NC"
}
printf "%sDeploy process started, current directory : (%s) %s \n\n" "$Y" "$PWD" "$NC"
if [ ! -d "$BUILD_DEPLOY_DIRECTORY" ]; then
printf "%sBuild-deploy directory doesn't exist : (%s) %s \n" "$R" "$BUILD_DEPLOY_DIRECTORY" "$NC"
exit 2
fi
angular_cli_build && delete_previous_build && version_and_deploy &&
printf "%s Changing directory to build directory... %s \n" "$G" "$NC"
cd "$BUILD_DIRECTORY" || exit 2
printf "%s Finished ! %s \n\n" "$G" "$NC"
exit 0
Un peu d'explication
Dans le script Shell ci-dessus, je commence par définir des variables, ces variables vont éviter les répétitions mais aussi me permettre de réutiliser le script pour différents projets.
Je définis trois fonctions qui regroupent les opérations à effectuer pour les différentes étapes :
- angular_cli_build : Je commence par m'assurer que le code est bien formaté avec ng lint (vous pouvez également exécuter vos tests) puis ng build -prod ou ionic build -prod pour la compilation de production.
- delete_previous_build : Je vais dans le repository git de ma compilation de production afin de supprimer l'ancienne compilation, avant de supprimer je m'assure que je suis au bon endroit, il n'y a pas de corbeille 😄😉 donc je dois faire attention.
- version_et_deploy : enfin la dernière étape, je commence par copier la nouvelle build de production dans les repos, j'ajoute les changements effectués avec git add . Et je commit les changements avec un message incluant la date de la dernière compilation et enfin j'envoie la nouvelle version de l'application sur le serveur distant avec git push.
Conclusion
L'utilisation de git facilite grandement le déploiement et permet également de conserver un historique des modifications apportées à l'application. Ce processus n'est pas spécifique à ionic, il peut aussi être utilisé pour une application angular ou react avec quelques adaptations, notez que si une erreur survient tout le processus s'arrête (code mal formaté ou test qui ne passe pas) ce qui vous permet d'avoir une sorte de déploiement continu sur votre environnement local (votre ordinateur).