diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dc33713cf2cd3a958d9f7379da613be426c7fcc3..11c68d4315d153ef672b0031924458ac4be1cd0b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,6 +3,8 @@ pages: - pages, docker image: boileaum/debian-jupyter script: + - pip3 --no-cache-dir install bash_kernel + - python -m bash_kernel.install - mkdir public - ./make_slides.sh artifacts: diff --git a/README.md b/README.md index c9adb36aeae2103a9e85403f4db0e8a879242d3d..70657cdd34d39e2c5902cf5b87fc01b60738458b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # TP GitLab CI -## Execution du notebook jupyter +Le contenu de cette session pratique est publié sur cette [page](https://boileau.pages.math.unistra.fr/tp-gitlab-ci/). + +### Execution du notebook jupyter - [Installer Anaconda](https://www.anaconda.com/download) pour disposer de `jupyter-notebook` - Ajouter le support du noyau bash : diff --git a/pipeline.png b/pipeline.png new file mode 100644 index 0000000000000000000000000000000000000000..f1588d7a54c3efea874c59762d85ba94a5be8705 Binary files /dev/null and b/pipeline.png differ diff --git a/tp-gitlab-ci.ipynb b/tp-gitlab-ci.ipynb index 51fe7418db492e8702266a90eb76a4a9cadfa4f0..5a720fa5aebea923f58a8ca7e5c58df811ce0dfb 100644 --- a/tp-gitlab-ci.ipynb +++ b/tp-gitlab-ci.ipynb @@ -735,16 +735,199 @@ "source": [ "### Provoquez des erreurs\n", "\n", - "Modifier les fichiers\n", + "Modifier les fichiers pour provoquer des erreurs.\n", + "Notez que le test n'est pas exécuté si le build échoue." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Exo3 : Docker pour gérer les dépendances\n", "\n", + "À `helloworld`, on ajoute un programme en python `rosenbrock.py` qui calcule la [fonction de Rosenbrock](https://fr.wikipedia.org/wiki/Fonction_de_Rosenbrock). Ce programme nécessite [`pythran`](http://pythran.readthedocs.io/), un traducteur de python vers C++ qui permet d'accélérer le code python.\n", + "Cet exercice a pour but d'illustrer la gestion des dépendances de compilation avec les conteneurs Docker dans une chaîne GitLab CI.\n", "\n", - "- de build : notez que le test n'est pas exécuté\n", - "- de test : le\n" + "Pour le reproduire, il est nécessaire de :\n", + "1. créer un compte sur [DockerHub](https://hub.docker.com/)\n", + "2. y créer un dépôt vierge intitulé `rosen`\n", + "3. que Docker soit installé sur la machine qui héberge le runner (c'est le cas pour le runner partagé de ce TP)." ] }, { "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "Dans votre clone local, basculez sur `exo3`" + ] + }, + { + "cell_type": "code", + "execution_count": 68, "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "No local changes to save\n", + "Already on 'exo3'\n", + "Your branch is up-to-date with 'origin/exo3'.\n" + ] + } + ], + "source": [ + "cd $TPDIR\n", + "git stash # si vous avez des modifications non enregistrées dans exo2\n", + "git checkout exo3" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "### Entête et étape préliminaire du fichier `.gitlab-ci.yml`\n", + "\n", + "```yaml\n", + "stages:\n", + " - build\n", + " - test\n", + " - release\n", + "\n", + "variables:\n", + " CONTAINER_TEST_IMAGE: boileaum/rosen:$CI_COMMIT_REF_NAME\n", + " CONTAINER_RELEASE_IMAGE: boileaum/rosen:latest\n", + "\n", + "before_script:\n", + " - echo $DOCKERHUB_PASSWD | docker login -u boileaum --password-stdin\n", + "[...]\n", + "```\n", + "\n", + "Pour faire marcher l'exercice :\n", + "1. Remplacez `boileaum` par votre `username` sur DockerHub.\n", + "2. Sur GitLab dans `Settings > CI / CD > Secret variables`, créez une variable `DOCKERHUB_PASSWD` qui contient le mot de passe de votre compte DockerHub." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "### Etape de `build` :\n", + "\n", + "```yaml\n", + "[...]\n", + "b:docker:\n", + " stage: build\n", + " tags:\n", + " - shell, docker\n", + " script:\n", + " - docker build --pull -t $CONTAINER_TEST_IMAGE -f ./docker/Dockerfile-rosen .\n", + " - docker push $CONTAINER_TEST_IMAGE\n", + "[...]\n", + "```\n", + "\n", + "- on construit l'image de test à partir du fichier `./docker/Dockerfile-rosen`\n", + "- on pousse cette image sur DockerHub\n", + "\n", + "> **Note :** l'image `Dockerfile-rosen` est basée sur l'image construite avec `./docker/Dockerfile-pythran` et qui contient les dépendances." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "### Etapes de `test`\n", + "\n", + "```yaml\n", + "[...]\n", + "t:helloworld:\n", + " stage: test\n", + " tags:\n", + " - shell, docker\n", + " script:\n", + " - docker pull $CONTAINER_TEST_IMAGE\n", + " - docker run $CONTAINER_TEST_IMAGE /bin/bash -c 'python test_helloworld.py'\n", + "[...]\n", + "```\n", + "\n", + "- on tire l'image de test\n", + "- on lance les tests unitaires" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "### Etape de livraison\n", + "\n", + "```yaml\n", + "\n", + "[...]\n", + "r:docker:\n", + " stage: release\n", + " tags:\n", + " - shell, docker\n", + " script:\n", + " - docker pull $CONTAINER_TEST_IMAGE\n", + " - docker tag $CONTAINER_TEST_IMAGE $CONTAINER_RELEASE_IMAGE\n", + " - docker push $CONTAINER_RELEASE_IMAGE\n", + " only:\n", + " - exo3\n", + "[...]\n", + "```\n", + "\n", + "On ne fait que tirer l'image de test validée, la renommer, la pousser vers DockerHub." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "### Pipeline complet\n", + "\n", + "\n", + "\n", + "\n", + "Comme le montre ce schéma, l'exécution de différents jobs d'une même étape peut être réalisée en parallèle par différents runners.\n", + "\n", + "Plus d'information " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, "source": [ "## Récupérer un artifact" ]