Écriture des slides
Signed-off-by: ynerant <ynerant@crans.org>
This commit is contained in:
parent
d0becd4063
commit
143aae2e48
|
@ -10,6 +10,7 @@ venv
|
|||
*.nav
|
||||
*.out
|
||||
*.pdf
|
||||
*.pyg
|
||||
*.snm
|
||||
*.synctex.gz
|
||||
*.toc
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 164 KiB |
Binary file not shown.
After Width: | Height: | Size: 593 KiB |
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
|
@ -1,10 +1,58 @@
|
|||
\documentclass[handout,aspectratio=169]{beamer}
|
||||
%\documentclass[handout,aspectratio=169]{beamer}
|
||||
\documentclass[aspectratio=169]{beamer}
|
||||
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage{lmodern}
|
||||
\usepackage[francais]{babel}
|
||||
\usepackage[french]{babel}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{ulem}
|
||||
\usepackage{listings}
|
||||
\lstset{
|
||||
inputencoding=utf8,
|
||||
mathescape,
|
||||
basicstyle=\tiny\ttfamily,
|
||||
numberstyle=\scriptsize\ttfamily\color{gray},
|
||||
showstringspaces=false,
|
||||
tabsize=2,
|
||||
numbers=left,
|
||||
xleftmargin=8mm,
|
||||
frame=lines,
|
||||
framexleftmargin=8mm,
|
||||
framerule=1pt,
|
||||
rulecolor=\color{green!50!black},
|
||||
backgroundcolor=\color{green!5},
|
||||
commentstyle=\color{gray},
|
||||
morecomment=[l][commentstyle]{//},
|
||||
classoffset=0,
|
||||
keywords={Pour, allant, Si, alors, Sinon, Fin},
|
||||
keywordstyle=\color{blue!75},
|
||||
classoffset=1,
|
||||
morekeywords={Afficher},
|
||||
keywordstyle=\color{green!50!black},
|
||||
classoffset=0,
|
||||
morestring=[b]",
|
||||
stringstyle=\color{red!75},
|
||||
literate=
|
||||
{é}{{\'e}}{1}%
|
||||
{è}{{\`e}}{1}%
|
||||
{à}{{\`a}}{1}%
|
||||
{â}{{\^a}}{1}%%%
|
||||
{ç}{{\c{c}}}{1}%
|
||||
{œ}{{\oe}}{1}%
|
||||
{ù}{{\`u}}{1}%
|
||||
{É}{{\'E}}{1}%
|
||||
{È}{{\`E}}{1}%
|
||||
{À}{{\`A}}{1}%
|
||||
{Ç}{{\c{C}}}{1}%
|
||||
{Œ}{{\OE}}{1}%
|
||||
{Ê}{{\^E}}{1}%
|
||||
{ê}{{\^e}}{1}%
|
||||
{î}{{\^i}}{1}%
|
||||
{ï}{{\"i}}{1}%%%
|
||||
{ô}{{\^o}}{1}%
|
||||
{û}{{\^u}}{1}%
|
||||
}
|
||||
|
||||
\usetheme[sectiontitle]{crans}
|
||||
|
||||
|
@ -19,50 +67,581 @@
|
|||
\maketitle
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\tableofcontents[subsubsectionstyle=hide]
|
||||
\end{frame}
|
||||
\section{Introduction}
|
||||
|
||||
\section{Example}
|
||||
\subsection{Discussion avec un chatbot}
|
||||
|
||||
\subsection{Block}
|
||||
|
||||
\begin{frame}
|
||||
\begin{block}{Title block}
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||
\end{block}
|
||||
\begin{block}{}
|
||||
No title Block \\
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||
\end{block}
|
||||
\begin{exampleblock}{Example Block}
|
||||
Example text (ugly)
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{exampleblock}{Introduction avec un petit chatbot}
|
||||
\begin{lstlisting}[language=bash]
|
||||
git clone https://gitlab.crans.org/ynerant/seminaire-ci.git
|
||||
cd seminaire-ci
|
||||
git checkout v1
|
||||
python3 main.py
|
||||
\end{lstlisting}
|
||||
\end{exampleblock}
|
||||
\begin{alertblock}{Alert Block}
|
||||
Alert Text
|
||||
\end{alertblock}
|
||||
\end{frame}
|
||||
|
||||
\subsection{Lists}
|
||||
\subsection{Des erreurs}
|
||||
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{block}{Le script ne semble pas fonctionner}
|
||||
\begin{lstlisting}[language=Python]
|
||||
File "/tmp/seminaire-ci/main.py", line 7
|
||||
print "Bienvenue dans le chatbot du séminaire de l'intégration continue !"
|
||||
^
|
||||
SyntaxError: Missing parentheses in call to 'print'.
|
||||
Did you mean print("Bienvenue dans le chatbot du séminaire de l'intégration continue !")?
|
||||
\end{lstlisting}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\includegraphics[width=180px]{img/re2o-500.png} \includegraphics[width=180px]{img/note-500.png}
|
||||
\includegraphics[width=180px]{img/youtube-500.jpg}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\begin{block}{Trois solutions}
|
||||
Il existe différents types de développeurs
|
||||
\begin{itemize}
|
||||
\item Celui/celle qui fait confiance à son code
|
||||
\pause
|
||||
\item Celui/celle qui ne fait pas confiance à son code et qui teste tout
|
||||
en permance
|
||||
\pause
|
||||
\item Celui/celle qui ne fait pas confiance à son code et qui embauche un
|
||||
esclave pour tout tester en permanence
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
|
||||
\pause
|
||||
|
||||
\og{} Le code prouve que ça marche \fg{}
|
||||
|
||||
\og{} De toute façon ce que j'ai écrit peut rien péter \fg{}
|
||||
\end{frame}
|
||||
|
||||
\subsection{Comment éviter les erreurs ?}
|
||||
|
||||
\begin{frame}
|
||||
\begin{itemize}
|
||||
\item Item 1
|
||||
\item Item 2
|
||||
\begin{itemize}
|
||||
\item Subitem 1
|
||||
\item Subitem 2
|
||||
\end{itemize}
|
||||
\item Relire 100 fois son code
|
||||
\pause
|
||||
\item Réfléchir avant d'écrire, prendre du recul
|
||||
\pause
|
||||
\item Tester son code après chaque modification
|
||||
\pause
|
||||
\item Utiliser un analyseur syntaxique
|
||||
\pause
|
||||
\item Tester automatiquement et régulièrement le code
|
||||
\end{itemize}
|
||||
\begin{enumerate}
|
||||
\item item 1
|
||||
\begin{enumerate}
|
||||
\item item 1.1
|
||||
\end{enumerate}
|
||||
\item
|
||||
\item
|
||||
\item
|
||||
\end{enumerate}
|
||||
|
||||
\end{frame}
|
||||
|
||||
\section{Correction des erreurs}
|
||||
|
||||
\subsection{Analyseur syntaxique}
|
||||
|
||||
\begin{frame}
|
||||
\begin{block}{Rôle d'un analyseur syntaxique}
|
||||
\begin{itemize}
|
||||
\item Lit le code sans l'exécuter ni le compiler
|
||||
\item Vérifie que la syntaxe est cohérente
|
||||
\item Repère les erreurs les plus courantes et suggère des modifications
|
||||
\item S'assure de l'uniformité du code et du respect de certaines
|
||||
conventions
|
||||
\item Existe dans la quasi-totalité des langages
|
||||
\item En Python : Flake8 et Pylint
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{exampleblock}{Installation des analyseurs}
|
||||
\begin{lstlisting}[language=bash]
|
||||
(sudo apt install python3-virtualenv / sudo pacman -S python-virtualenv)
|
||||
(python3 -m venv venv)
|
||||
(source venv/bin/activate)
|
||||
pip3 install pylint flake8
|
||||
\end{lstlisting}
|
||||
\end{exampleblock}
|
||||
|
||||
\begin{exampleblock}{Analyse du code}
|
||||
En lancant \texttt{pylint main.py} :
|
||||
\begin{lstlisting}[language=Python]
|
||||
************* Module main
|
||||
main.py:7:11: E0001: Missing parentheses in call to 'print'.
|
||||
Did you mean print("Bienvenue dans le chatbot du séminaire de l'intégration continue !")?
|
||||
(<unknown>, line 7) (syntax-error)
|
||||
\end{lstlisting}
|
||||
\end{exampleblock}
|
||||
|
||||
$\implies$ On n'a pas eu besoin d'exécuter le code
|
||||
\end{frame}
|
||||
|
||||
\subsection{Intégration continue}
|
||||
|
||||
\begin{frame}
|
||||
\begin{itemize}
|
||||
\item Appeler ce script à la main $\to$ laborieux
|
||||
\item Solution : utiliser \sout{un esclave} de l'intégration continue
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\begin{block}{Qu'est-ce qu'une intégration continue ?}
|
||||
\begin{itemize}
|
||||
\item Script appelé après commit envoyé au serveur distant
|
||||
\item Utile pour analyser et tester le code
|
||||
\item Mais également pour déployer le projet automatiquement
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{exampleblock}{Analyse syntaxique automatique}
|
||||
\texttt{git checkout v2}
|
||||
|
||||
Dans le fichier \texttt{.gitlab-ci.yml} :
|
||||
\begin{lstlisting}[]
|
||||
flake8:
|
||||
image: python:3-alpine
|
||||
before_script:
|
||||
- pip install flake8 --no-cache-dir
|
||||
script: flake8 main.py
|
||||
|
||||
pylint:
|
||||
image: python:3-alpine
|
||||
before_script:
|
||||
- pip install pylint --no-cache-dir
|
||||
script: pylint main.py
|
||||
\end{lstlisting}
|
||||
|
||||
Résultat : \url{https://gitlab.crans.org/ynerant/seminaire-ci/-/pipelines/5595}
|
||||
\end{exampleblock}
|
||||
\end{frame}
|
||||
|
||||
\subsection{Nettoyer son code}
|
||||
|
||||
\begin{frame}
|
||||
\begin{block}{Utilité d'un analyseur syntaxique}
|
||||
\begin{itemize}
|
||||
\item \texttt{git checkout v2.5}
|
||||
\item Le script peut être lancé, mais le code n'est pas propre
|
||||
\item Un code bien écrit est un code qui peut être lu et maintenu
|
||||
\item Quelques règles standards :
|
||||
\begin{itemize}
|
||||
\item Lignes ne faisant pas plus de 79 caractères
|
||||
\item Code bien indenté
|
||||
\item Pas de variable inutile
|
||||
\item Code bien aéré (mais pas trop)
|
||||
\item Code documenté et commenté
|
||||
\item Imports triés
|
||||
\item Beaucoup d'options ...
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{exampleblock}{Analyse du code}
|
||||
En lancant \texttt{pylint main.py} sur le commit \texttt{v2.5} :
|
||||
\begin{lstlisting}[language=Python]
|
||||
************* Module main
|
||||
main.py:23:0: C0301: Line too long (104/100) (line-too-long)
|
||||
main.py:32:0: C0301: Line too long (469/100) (line-too-long)
|
||||
main.py:39:0: C0301: Line too long (192/100) (line-too-long)
|
||||
main.py:16:0: W0622: Redefining built-in 'help' (redefined-builtin)
|
||||
main.py:91:0: W0622: Redefining built-in 'quit' (redefined-builtin)
|
||||
main.py:1:0: C0114: Missing module docstring (missing-module-docstring)
|
||||
main.py:6:0: C0116: Missing function or method docstring (missing-function-docstring)
|
||||
main.py:42:0: C0103: Argument name "a" does not conform to snake_case naming style
|
||||
(invalid-name)
|
||||
main.py:42:0: C0103: Argument name "b" does not conform to snake_case naming style
|
||||
(invalid-name)
|
||||
main.py:42:0: C0103: Argument name "c" does not conform to snake_case naming style
|
||||
(invalid-name)
|
||||
main.py:42:0: R0912: Too many branches (17/12) (too-many-branches)
|
||||
main.py:96:4: R1722: Consider using sys.exit() (consider-using-sys-exit)
|
||||
|
||||
------------------------------------------------------------------
|
||||
Your code has been rated at 8.03/10 (previous run: 8.03/10, +0.00)
|
||||
\end{lstlisting}
|
||||
\end{exampleblock}
|
||||
\end{frame}
|
||||
|
||||
\subsection{Faire marcher son code}
|
||||
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{block}{Un code bien écrit n'est pas un code qui marche}
|
||||
\texttt{git checkout v5}
|
||||
|
||||
En lançant \texttt{python3 main.py} :
|
||||
\begin{lstlisting}
|
||||
Bienvenue dans le chatbot du séminaire de l'intégration continue !
|
||||
Veuillez taper une commande. Tapez "aide" pour afficher l'aide.
|
||||
> calcul 1 2 3
|
||||
Traceback (most recent call last):
|
||||
File "/tmp/seminaire-ci/main.py", line 110, in <module>
|
||||
main()
|
||||
File "/tmp/seminaire-ci/main.py", line 27, in main
|
||||
print(globals()[args[0]](*args[1:]))
|
||||
File "/tmp/seminaire-ci/main.py", line 90, in calcul
|
||||
result = left % right
|
||||
TypeError: not all arguments converted during string formatting
|
||||
\end{lstlisting}
|
||||
|
||||
$\implies$ le code est bien écrit, mais ne fait pas ce qu'on veut
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{block}{Utilisation de l'intégration continue}
|
||||
\texttt{git checkout v6}
|
||||
|
||||
On ajoute au fichier \texttt{.gitlab-ci.yml} :
|
||||
\begin{lstlisting}
|
||||
test:
|
||||
stage: test
|
||||
image: python:3-alpine
|
||||
script: python main.py
|
||||
\end{lstlisting}
|
||||
|
||||
Le code est bien exécuté :
|
||||
\url{https://gitlab.crans.org/ynerant/seminaire-ci/-/jobs/13865}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\subsection{Environnement de tests}
|
||||
|
||||
\begin{frame}
|
||||
\begin{block}{Utiliser un environnement de test}
|
||||
\begin{itemize}
|
||||
\item Impossible d'exécuter le script pas d'entrée à fournir
|
||||
\item Impossible de choisir quoi tester et de vérifier la bonne
|
||||
exécution du programme
|
||||
\pause
|
||||
\item Solution : utiliser un environnement adapté et des tests unitaires
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{exampleblock}{Avec Pytest}
|
||||
\texttt{git checkout v8} \\
|
||||
\texttt{pip3 install pytest} \\
|
||||
Dans le fichier \texttt{main\_test.py} :
|
||||
\begin{lstlisting}[language=Python]
|
||||
import unittest
|
||||
|
||||
import main
|
||||
|
||||
|
||||
def test_aide():
|
||||
res = main.commande("aide")
|
||||
lines = res.split("\n")
|
||||
assert len(lines) == 6
|
||||
assert lines[0].startswith("aide")
|
||||
assert lines[1].startswith("seminaire")
|
||||
assert lines[2].startswith("blague")
|
||||
assert lines[3].startswith("calcul")
|
||||
assert lines[4].startswith("tri")
|
||||
assert lines[5].startswith("stop")
|
||||
\end{lstlisting}
|
||||
On a ajouté une fonction \texttt{commande}
|
||||
\end{exampleblock}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{exampleblock}{Avec Pytest}
|
||||
\texttt{pytest .}
|
||||
\begin{lstlisting}[language=Python]
|
||||
============================= test session starts =============================
|
||||
platform linux -- Python 3.9.1, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
|
||||
rootdir: /tmp/seminaire-ci
|
||||
collected 1 item
|
||||
main_test.py F [100%]
|
||||
================================== FAILURES ===================================
|
||||
__________________________________ test_aide __________________________________
|
||||
|
||||
def test_aide():
|
||||
res = main.commande("aide")
|
||||
> lines = res.split("\n")
|
||||
E AttributeError: 'NoneType' object has no attribute 'split'
|
||||
|
||||
main_test.py:17: AttributeError
|
||||
---------------------------- Captured stdout call -----------------------------
|
||||
aide Affiche l aide
|
||||
[...]
|
||||
=========================== short test summary info ===========================
|
||||
FAILED main_test.py::test_aide - AttributeError: 'NoneType' object has no at...
|
||||
============================== 1 failed in 0.03s ==============================
|
||||
\end{lstlisting}
|
||||
\end{exampleblock}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{exampleblock}{Avec Pytest, après réparation de l'erreur}
|
||||
\texttt{git checkout v9} \\
|
||||
\texttt{pytest .}
|
||||
\begin{lstlisting}[language=Python]
|
||||
============================= test session starts =============================
|
||||
platform linux -- Python 3.9.1, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
|
||||
rootdir: /tmp/seminaire-ci
|
||||
collected 1 item
|
||||
|
||||
main_test.py . [100%]
|
||||
|
||||
============================== 1 passed in 0.01s ==============================
|
||||
\end{lstlisting}
|
||||
\end{exampleblock}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{exampleblock}{Un meilleur environnement de tests}
|
||||
\texttt{git checkout v10} \\
|
||||
On utilise une classe pour mieux construire son environnement
|
||||
\begin{lstlisting}[language=Python]
|
||||
import unittest
|
||||
|
||||
import main
|
||||
|
||||
|
||||
class TestMain(unittest.TestCase):
|
||||
def test_aide(self):
|
||||
res = main.commande("aide")
|
||||
lines = res.split("\n")
|
||||
self.assertEqual(len(lines), 6)
|
||||
self.assertTrue(lines[0].startswith("aide"))
|
||||
self.assertTrue(lines[1].startswith("seminaire"))
|
||||
self.assertTrue(lines[2].startswith("blague"))
|
||||
self.assertTrue(lines[3].startswith("calcul"))
|
||||
self.assertTrue(lines[4].startswith("tri"))
|
||||
self.assertTrue(lines[5].startswith("stop"))
|
||||
\end{lstlisting}
|
||||
\end{exampleblock}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\begin{block}{Qu'est-ce qu'un bon test unitaire ?}
|
||||
\begin{itemize}
|
||||
\item \og{} Unitaire \fg{} : on ne teste qu'une seule fonctionnalité à la
|
||||
fois
|
||||
\item Clair
|
||||
\item Pertinent
|
||||
\item Non-trivial
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\subsection{Couverture}
|
||||
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{block}{Couverture}
|
||||
\begin{itemize}
|
||||
\item Les tests unitaires exécutent une partie du code
|
||||
\item Il est possible de mesurer quelle partie du code est exécutée et
|
||||
testée
|
||||
\item On parle de \textit{couverture} du code (\textit{coverage} en anglais)
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
|
||||
\begin{exampleblock}{Calcul de la couverture du code}
|
||||
\begin{itemize}
|
||||
\item \texttt{git checkout v11}
|
||||
\item \texttt{pip install pytest-cov}
|
||||
\item \texttt{pytest --showlocals --cov=main --cov=main\_test --cov-report=term-missing .}
|
||||
\end{itemize}
|
||||
\end{exampleblock}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{exampleblock}{Calcul de couverture}
|
||||
\texttt{pytest --showlocals --cov=main --cov=main\_test --cov-report=term-missing .}
|
||||
\begin{lstlisting}
|
||||
============================= test session starts =============================
|
||||
platform linux -- Python 3.9.1, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
|
||||
rootdir: /tmp/seminaire-ci
|
||||
plugins: cov-2.11.1
|
||||
collected 1 item
|
||||
main_test.py . [100%]
|
||||
----------- coverage: platform linux, python 3.9.1-final-0 -----------
|
||||
Name Stmts Miss Cover Missing
|
||||
--------------------------------------------
|
||||
main.py 41 27 34% 21-27, 54, 70, 82-98, 105, 112-113, 117
|
||||
main_test.py 14 0 100%
|
||||
--------------------------------------------
|
||||
TOTAL 55 27 51%
|
||||
|
||||
============================== 1 passed in 0.05s ==============================
|
||||
\end{lstlisting}
|
||||
Exercice pour le plaisir : couvrir et tester correctement la totalité du code
|
||||
\end{exampleblock}
|
||||
\end{frame}
|
||||
|
||||
\subsection{Lutter contre le nazisme}
|
||||
|
||||
\begin{frame}
|
||||
\begin{block}{Configuration de l'analyse et des tests}
|
||||
\begin{itemize}
|
||||
\item \og{} Ohh vraiment je dois faire ça \fg{}, \og{} 79 caractères c'est
|
||||
pas assez \fg{}, \og{} Je ne veux/peux pas couvrir cette ligne \fg{}
|
||||
\item Couvrir et tester sont des très bonnes pratiques en règle générale
|
||||
\item Tout est configurable, y compris pour ajouter des exceptions
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\section{Déploiement}
|
||||
|
||||
\subsection{Artefacts}
|
||||
|
||||
\begin{frame}
|
||||
\begin{block}{Rôle d'une intégration continue}
|
||||
Une intégration continue permet :
|
||||
\begin{itemize}
|
||||
\item d'analyser automatiquement la structure du code
|
||||
\item de tester automatiquement le projet
|
||||
\item \textit{a fortiori} de donner un indicateur aux autres personnes de
|
||||
la qualité du projet via des badges
|
||||
\pause
|
||||
\item De construire et de déployer automatiquement le projet
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{block}{Construction du projet}
|
||||
\texttt{git checkout v16} \\
|
||||
Un script d'intégration ne se limite pas aux tests : il peut compiler des
|
||||
projets
|
||||
|
||||
Exemple avec la compilation automatique \LaTeX{} de ces slides :
|
||||
\begin{lstlisting}
|
||||
slides:
|
||||
image: aergus/latex
|
||||
script:
|
||||
- latexmk -cd -pdf slides/seminaire-ci.tex
|
||||
\end{lstlisting}
|
||||
L'intégration continue génère un fichier \texttt{seminaire-ci.pdf} dans son
|
||||
script
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{block}{Construction du projet}
|
||||
\texttt{git checkout v16} \\
|
||||
Il est possible d'exporter certains fichiers compilés :
|
||||
\begin{lstlisting}
|
||||
slides:
|
||||
image: aergus/latex
|
||||
script:
|
||||
- latexmk -cd -pdf slides/seminaire-ci.tex
|
||||
artifacts:
|
||||
paths:
|
||||
- slides/seminaire-ci.pdf
|
||||
expire_in: 1 mo
|
||||
\end{lstlisting}
|
||||
Ici, les slides sont compilées et le fichier PDF généré est exporté et
|
||||
stocké pendant 1 mois :
|
||||
\url{https://gitlab.crans.org/ynerant/seminaire-ci/-/jobs/13826/artifacts/browse}
|
||||
(à des fins d'exemple, la limitation d'un mois à été retirée)
|
||||
|
||||
Particulièrement utile pour générer des binaires à partir du code source
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\subsection{Déploiement automatisé}
|
||||
|
||||
\begin{frame}
|
||||
\begin{block}{Déployer son projet}
|
||||
\begin{itemize}
|
||||
\item Une fois le projet dans une version stable et bien testé, le projet
|
||||
peut être installé
|
||||
\item Si on a suffisamment confiance en ses tests, possibilité de le faire
|
||||
automatiquement
|
||||
\item Deux solutions principales :
|
||||
\begin{itemize}
|
||||
\item Envoyer un signal (\textit{webhook}) aux services concernés
|
||||
\item Directement déployer le serveur ce qu'il faut $\to$ nécessite
|
||||
d'être simple à déployer et d'être peu distribué (projet développé
|
||||
dans un but interne : site, latex, ...)
|
||||
\end{itemize}
|
||||
\item Pour des gros projets, on privilégie la première option
|
||||
\item Attention aux droits donnés à Gitlab
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[containsverbatim]
|
||||
\begin{block}{Déployer son projet}
|
||||
Les slides de ce séminaire sont automatiquement déployées sur
|
||||
\url{https://ynerant.fr/gitlab/seminaire-ci.pdf} :
|
||||
\begin{lstlisting}
|
||||
slides:
|
||||
stage: compile_slides
|
||||
image: aergus/latex
|
||||
before_script:
|
||||
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
|
||||
- eval $$(ssh-agent -s)
|
||||
- echo "$$SSH_KEY" | tr -d '\r' | ssh-add - > /dev/null
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 0700 ~/.ssh
|
||||
- ssh-keyscan ynerant.fr >> ~/.ssh/known_hosts
|
||||
- chmod 0644 ~/.ssh/known_hosts
|
||||
script:
|
||||
- latexmk -cd -pdf slides/seminaire-ci.tex
|
||||
- scp slides/seminaire-ci.pdf gitlab-ci@ynerant.fr:gitlab-ftp/seminaire-ci.pdf
|
||||
\end{lstlisting}
|
||||
\end{block}
|
||||
|
||||
Autre exemple : \url{https://gitlab.crans.org/nounous/homepage} déploie
|
||||
automatiquement \url{https://crans.org/}
|
||||
\end{frame}
|
||||
|
||||
\subsection{Webhooks}
|
||||
|
||||
\begin{frame}
|
||||
\begin{block}{Webhooks}
|
||||
Un \textit{webhook} est un événement envoyé à un service externe pour
|
||||
signaler un changement d'état.
|
||||
|
||||
Exemples de webhooks :
|
||||
|
||||
\begin{itemize}
|
||||
\item Message sur une plateforme de communication (IRC, Matrix, Discord,
|
||||
\ldots)
|
||||
\item Compilation automatique de documentation
|
||||
\item Traduction
|
||||
\item Compilation et déploiement du projet sur un service externe (Docker,
|
||||
PyPI ou autre gestionnaire de paquets, \ldots)
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\section{Conclusion}
|
||||
|
||||
\begin{frame}
|
||||
\begin{exampleblock}{En résumé}
|
||||
\begin{itemize}
|
||||
\item Analyser statiquement son code permet d'assurer qu'il est
|
||||
syntaxiquement correct et qu'il est surtout lisible
|
||||
\item Tester efficacement son projet assure son bon fonctionnement et
|
||||
évite des erreurs imprévues
|
||||
\item Ces tâches peuvent se faire automatiquement après chaque commit par
|
||||
le biais d'une intégration continue
|
||||
\item Il est enfin possible de construire et déployer son projet
|
||||
automatiquement
|
||||
\item Une intégration continue efficace est souvent signe d'un projet bien
|
||||
géré
|
||||
\end{itemize}
|
||||
\end{exampleblock}
|
||||
|
||||
\pause
|
||||
|
||||
\begin{block}{}
|
||||
\textit{Gérer} un projet n'est pas uniquement \textit{coder} un projet.
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
\end{document}
|
||||
|
|
Loading…
Reference in New Issue