Aller directement à la fin des métadonnées
Aller au début des métadonnées

You are viewing an old version of this content. View the current version.

afficher les différences View Version History

« Afficher la version précédente Vous regardez la version actuelle de cette page. (v. 10) Actuel »

Migration des modules

Résumé

Suite à la migration 4.6, tous les modules n’ont pas été portés. Avec la fin de node 16, et les mises à jour récurrentes de Docker (v2++), il est nécessaire de mettre à jour en continue les modules sur lesquels nous travaillons.

De plus, le plan de rénovation frontend sur React suit son court mais se fera petit à petit.

Liste des modules

https://opendigitaleducation.atlassian.net/l/cp/roTLWHCW

Ticket JIRA et commit

Avant de toucher à un module, il faut créer un ticket JIRA avec comme titre :

  • [Nom de l’app] - Migration 4.6

Après chaque portage, le message de commit doit être le suivant :

  • "chore: #<NUM_TICKET>, up migration 4.6"

Portage

En attendant une image docker avec node 18 apportant stabilité et une installation + rapide avec pnpm, la migration suivante se fait avec node 16 et yarn 1.22.19. Ce sera d’autant plus facile de passer à node 18 par la suite grâce à la montée de version de Gulp 4

Sur chaque module, les fichiers impactés sont les suivants :

  • build.sh

  • gulpfile.js

  • docker-compose.yml

  • package.json

Package.json

  • Montée de versions des dependencies suivantes dans le package.json

"dependencies": {
  "gulp": "4.0.2",
  "gulp-clean": "0.4.0",
  "merge2": "1.1.0",
}
  • Figer toutes les versions des dependencies/devDependencies

    • Retirer les ^

    • Ajouter les champs suivants dans le package.json

"packageManager": "yarn@1.22.19",
"engines": {
  "node": "16 || 18"
}

Gulpfile

Attention, il peut y avoir des spécificités sur certains modules. Bien vérifier et à adapter

Remplacer le gulpfile de l’application par celui-ci :

const gulp = require("gulp");
const webpack = require("webpack-stream");
const merge = require("merge2");
const replace = require("gulp-replace");
const clean = require("gulp-clean");
const argv = require("yargs").argv;
const fs = require("fs");

function dropCache() {
  return gulp
    .src(["./src/main/resources/public/dist"], {
      read: false,
      allowEmpty: true,
    })
    .pipe(clean());
}

function buildDev() {
  return gulp
    .src("./src/main/resources/public")
    .pipe(webpack(require("./webpack.config.js")))
    .on("error", function handleError() {
      this.emit("end"); // Recover from errors
    })
    .pipe(gulp.dest("./src/main/resources/public/dist"));
}

function build(done) {
  const refs = gulp
    .src("./src/main/resources/view-src/**/*.+(html|json)")
    .pipe(replace("@@VERSION", Date.now()))
    .pipe(gulp.dest("./src/main/resources/view"));

  const copyBehaviours = gulp
    .src("./src/main/resources/public/dist/behaviours.js")
    .pipe(gulp.dest("./src/main/resources/public/js"));

  merge[(refs, copyBehaviours)];
  done();
}

gulp.task("drop-cache", dropCache);
gulp.task("build-dev", buildDev);
gulp.task("build", build);

function getModName(fileContent) {
  const getProp = function (prop) {
    return fileContent.split(prop + "=")[1].split(/\r?\n/)[0];
  };
  return (
    getProp("modowner") + "~" + getProp("modname") + "~" + getProp("version")
  );
}

function watchFiles() {
  let springboard = argv.springboard;
  if (!springboard) {
    springboard = "../springboard-open-ent/";
  }
  if (springboard[springboard.length - 1] !== "/") {
    springboard += "/";
  }

  gulp.watch(
    "./src/main/resources/public/ts/**/*.ts",
    gulp.series("drop-cache", "build-dev", "build")
  );

  fs.readFile("./gradle.properties", "utf8", function (err, content) {
    const modName = getModName(content);
    gulp.watch(["./src/main/resources/public/js"], () => {
      console.log("Copying resources to " + springboard + "mods/" + modName);
      gulp
        .src("./src/main/resources/**/*")
        .pipe(gulp.dest(springboard + "mods/" + modName));
    });
    gulp.watch(
      [
        "./src/main/resources/public/template/**/*.html",
        "!./src/main/resources/public/template/entcore/*.html",
      ],
      () => {
        console.log("Copying resources to " + springboard + "mods/" + modName);
        gulp
          .src("./src/main/resources/**/*")
          .pipe(gulp.dest(springboard + "mods/" + modName));
      }
    );

    gulp.watch("./src/main/resources/view/**/*.html", () => {
      console.log("Copying resources to " + springboard + "mods/" + modName);
      gulp
        .src("./src/main/resources/**/*")
        .pipe(gulp.dest(springboard + "mods/" + modName));
    });
  });
}

gulp.task("watch", watchFiles);

exports.watch = gulp.parallel("watch");
exports.build = gulp.series("drop-cache", "build-dev", "build");

build.sh et build-noDocker.sh

  • Supprimer le fichier build-noDocker.sh

  • Remplacer le build.sh par le fichier ci-dessous

  • Pour utiliser les commandes :

    • Avec Docker : build.sh clean

    • Sans Docker : build.sh --no-docker clean

    • etc…

#!/bin/bash

if [ ! -e node_modules ]
then
  mkdir node_modules
fi

case `uname -s` in
  MINGW* | Darwin*)
    USER_UID=1000
    GROUP_UID=1000
    ;;
  *)
    if [ -z ${USER_UID:+x} ]
    then
      USER_UID=`id -u`
      GROUP_GID=`id -g`
    fi
esac

# Options
NO_DOCKER=""
SPRINGBOARD="recette"
for i in "$@"
do
case $i in
  -s=*|--springboard=*)
  SPRINGBOARD="${i#*=}"
  shift
  ;;
  --no-docker*)
  NO_DOCKER="true"
  shift
  ;;
  *)
  ;;
esac
done

clean () {
  if [ "$NO_DOCKER" = "true" ] ; then
    rm -rf node_modules
    rm -f yarn.lock
    gradle clean
  else
    docker-compose run --rm -u "$USER_UID:$GROUP_GID" gradle gradle clean
  fi
}

buildNode () {
  #jenkins
  echo "[buildNode] Get branch name from jenkins env..."
  BRANCH_NAME=`echo $GIT_BRANCH | sed -e "s|origin/||g"`
  if [ "$BRANCH_NAME" = "" ]; then
    echo "[buildNode] Get branch name from git..."
    BRANCH_NAME=`git branch | sed -n -e "s/^\* \(.*\)/\1/p"`
  fi
  if [ "$BRANCH_NAME" = "" ]; then
    echo "[buildNode] Branch name should not be empty!"
    exit -1
  fi

  if [ "$BRANCH_NAME" = 'master' ]; then
      echo "[buildNode] Use entcore version from package.json ($BRANCH_NAME)"
      case `uname -s` in
        MINGW*)
          if [ "$NO_DOCKER" = "true" ] ; then
            yarn install --no-bin-links && yarn upgrade entcore && node_modules/gulp/bin/gulp.js build
          else
            docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links --legacy-peer-deps --force && yarn upgrade entcore && node_modules/gulp/bin/gulp.js build"
          fi
          ;;
        *)
          if [ "$NO_DOCKER" = "true" ] ; then
            yarn install && yarn upgrade entcore && node_modules/gulp/bin/gulp.js build
          else
            docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --legacy-peer-deps --force && yarn upgrade entcore && node_modules/gulp/bin/gulp.js build"
          fi
      esac
  else
      echo "[buildNode] Use entcore tag $BRANCH_NAME"
      case `uname -s` in
        MINGW*)
          if [ "$NO_DOCKER" = "true" ] ; then
            yarn install && yarn upgrade entcore && node_modules/gulp/bin/gulp.js build
          else
            docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --no-bin-links --legacy-peer-deps --force && npm rm --no-save entcore && yarn install --no-save entcore@dev && node_modules/gulp/bin/gulp.js build"
          fi
          ;;
        *)
          if [ "$NO_DOCKER" = "true" ] ; then
            yarn install --no-bin-links && yarn upgrade entcore && node_modules/gulp/bin/gulp.js build
          else
            docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "yarn install --legacy-peer-deps --force && npm rm --no-save entcore && yarn install --no-save entcore@dev && node_modules/gulp/bin/gulp.js build"
          fi
      esac
  fi
}

buildGradle () {
  if [ "$NO_DOCKER" = "true" ] ; then
    gradle shadowJar install publishToMavenLocal
  else
    docker-compose run --rm -u "$USER_UID:$GROUP_GID" gradle gradle shadowJar install publishToMavenLocal
  fi
}

publish () {
  if [ -e "?/.gradle" ] && [ ! -e "?/.gradle/gradle.properties" ]
  then
    echo "odeUsername=$NEXUS_ODE_USERNAME" > "?/.gradle/gradle.properties"
    echo "odePassword=$NEXUS_ODE_PASSWORD" >> "?/.gradle/gradle.properties"
    echo "sonatypeUsername=$NEXUS_SONATYPE_USERNAME" >> "?/.gradle/gradle.properties"
    echo "sonatypePassword=$NEXUS_SONATYPE_PASSWORD" >> "?/.gradle/gradle.properties"
  fi
  if [ "$NO_DOCKER" = "true" ] ; then
    gradle publish
  else
    docker-compose run --rm -u "$USER_UID:$GROUP_GID" gradle gradle publish
  fi
}

watch () {
  if [ "$NO_DOCKER" = "true" ] ; then
    node_modules/gulp/bin/gulp.js watch --springboard=../recette
  else
    docker-compose run --rm -u "$USER_UID:$GROUP_GID" node sh -c "node_modules/gulp/bin/gulp.js watch --springboard=/home/node/$SPRINGBOARD"
  fi
}

for param in "$@"
do
  case $param in
    clean)
      clean
      ;;
    buildNode)
      buildNode
      ;;
    buildGradle)
      buildGradle
      ;;
    install)
      buildNode && buildGradle
      ;;
    watch)
      watch
      ;;
    publish)
      publish
      ;;
    *)
      echo "Invalid argument : $param"
  esac
  if [ ! $? -eq 0 ]; then
    exit 1
  fi
done

Docker Compose

Remplacer le fichier existant par celui-ci :

version: "3"
services:
  gradle:
    image: opendigitaleducation/gradle:4.5.1
    working_dir: /home/gradle/project
    volumes:
      - ./:/home/gradle/project
      - ~/.m2:/home/gradle/.m2
      - ~/.gradle:/home/gradle/.gradle

  node:
    image: opendigitaleducation/node:16-alpine
    working_dir: /home/node/app
    volumes:
      - ./:/home/node/app
      - ~/.npm:/.npm
      - ../recette:/home/node/recette

Tests

Pour s’assurer que tout fonctionne, suivre la démarche ci-dessous :

  • build.sh clean

  • build.sh buildNode

    • va installer puis compiler l’application angularjs

  • build.sh buildGradle

  • build.sh watch

    • penser à indiquer le bon chemin de son springboard / ode-dev-server

  • s’assurer que l’application démarre et fonctionnement normalement en local

  • s’assurer que le build Jenkins fonctionne à 💯 %

  • vérifier que l’application démarre et fonctionne normalement sur un environnement de recette

si besoin d’aide, voir l’exemple sur l’application scrapbook

https://code.web-education.net/one/scrap-book/tree/develop-pedago

  • Aucune étiquette

0 commentaires

Vous n'êtes pas connecté. Toutes vos modifications seront marquées comme réalisées par anonyme. Vous pouvez vous connecter si vous disposez déjà d'un compte.