Skip to content
Snippets Groups Projects
.gitlab-ci.yml 9.25 KiB
Newer Older
image: node:22-alpine
  NPM_GLOBAL_CACHE: ".cache/.npm"
  PAGES_URL: "$CI_PAGES_URL/$CI_COMMIT_REF_SLUG"
  FTP_TARGET: "$CI_COMMIT_REF_SLUG"
  - install
  - build
.e2e_rules: &e2e_rules
  - if: $E2E != null

.get_mr_info: &get_mr_info
  - |
    # Récupérer les informations de la merge request
    if [ -n "$CI_MERGE_REQUEST_IID" ]; then
      echo "Variable MERGE_REQUEST_IID disponible. Récupération des informations depuis la merge request."
      MR_INFO=$(curl --silent --header "PRIVATE-TOKEN: $PROJECT_ACCESS_TOKEN" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID")
    else
      echo "Variable MERGE_REQUEST_IID non disponible. Récupération des informations de la première MR associée à la branche."
      MERGE_REQUESTS=$(curl --silent --header "PRIVATE-TOKEN: $PROJECT_ACCESS_TOKEN" --get --data-urlencode "source_branch=$CI_COMMIT_REF_NAME" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests")
      if [ ! -z "$MERGE_REQUESTS" -a "$MERGE_REQUESTS" != " " -a "$MERGE_REQUESTS" != "[]" ]; then
        MR_INFO=$(echo "$MERGE_REQUESTS" | jq -r .[0])
      fi
    fi      
    echo $MR_INFO

.fail_if_no_mr_info: &fail_if_no_mr
  - |
    if [ -z ${MR_INFO+x} ]; then 
      echo "Erreur > pas de merge request associée à la branche $CI_COMMIT_REF_NAME"
      exit 1
    fi

.exit_if_no_mr_info: &exit_if_no_mr
  - |
    if [ -z ${MR_INFO+x} ]; then 
      echo "Pas de merge request associée à la branche $CI_COMMIT_REF_NAME"
      exit 0
    fi

install:
  stage: install
  cache:
    key: "$CI_COMMIT_REF_SLUG"
    paths:
      - node_modules/
Patriarche Rémi's avatar
Patriarche Rémi committed
    policy: pull-push
  before_script:
    - npm config set cache $NPM_GLOBAL_CACHE
  script:
    - npm install
  stage: build
  cache:
    key: "$CI_COMMIT_REF_SLUG"
    paths:
      - node_modules/
    policy: pull
  before_script:
    - npm config set cache $NPM_GLOBAL_CACHE
  script:
    - npm run build
  artifacts:
    paths:
      - dist
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - if: $CI_PIPELINE_SOURCE == "push" && $DEPLOY == null
    - if: $PUB != null
Patriarche Rémi's avatar
Patriarche Rémi committed
lint:
  stage: build
Patriarche Rémi's avatar
Patriarche Rémi committed
  cache:
    key: "$CI_COMMIT_REF_SLUG"
Patriarche Rémi's avatar
Patriarche Rémi committed
    paths:
      - node_modules/
    policy: pull
  before_script:
    - npm config set cache $NPM_GLOBAL_CACHE
  script:
    - npm run lint
  dependencies: []
    - if: $CI_PIPELINE_SOURCE == "push" && $DEPLOY == null
test:
  stage: build
  cache:
    key: "$CI_COMMIT_REF_SLUG"
    paths:
      - node_modules/
    policy: pull
  before_script:
    - npm config set cache $NPM_GLOBAL_CACHE
  script:
    - npm run test:jest
  dependencies: []
  rules:
    - if: $CI_PIPELINE_SOURCE == "push" && $DEPLOY == null

  stage: build
  cache:
    key: "$CI_COMMIT_REF_SLUG"
    paths:
      - node_modules/
    policy: pull
  before_script:
    - npm config set cache $NPM_GLOBAL_CACHE
  script:
    - npm run storybook:tsc
  dependencies: []
    - if: $CI_PIPELINE_SOURCE == "push" && $DEPLOY == null && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
    key: "$CI_COMMIT_REF_SLUG"
    paths:
      - node_modules/
    policy: pull
  artifacts:
    expire_in: 1h
    when: always
    paths:
      - storybook-static/
  before_script:
    - npm config set cache $NPM_GLOBAL_CACHE
  script:
    - npm run storybook:build
  dependencies: []
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - if: $DEPLOY != null
  stage: deploy
  script:
    - echo "This job configures an environment."
  environment:
    name: storybook/$CI_COMMIT_REF_SLUG
    url: $PAGES_URL
    on_stop: remove_env
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - if: $DEPLOY != null
  stage: deploy
  cache:
    key: "sp-storybook"
    paths:
      - public
  script:
    - rm -rf "public/$CI_COMMIT_REF_SLUG"
  variables:
    GIT_STRATEGY: none # needed to prevent "Couldn't find remote ref" error
  environment:
    name: storybook/$CI_COMMIT_REF_SLUG
    action: stop
  when: manual
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - if: $DEPLOY != null
    key: "sp-storybook"
    paths:
      - public
  script:
    - rm -rf "public/$CI_COMMIT_REF_SLUG"
    - mkdir -p "public/$CI_COMMIT_REF_SLUG"
    - mv storybook-static/* "public/$CI_COMMIT_REF_SLUG"
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - if: $DEPLOY != null
e2e_deploy:
  stage: e2e
  before_script:
    - apk add --no-cache openssh
    - apk add --no-cache lftp
  script:
    - lftp -c "set sftp:auto-confirm yes; set ftp:ssl-allow true; set ssl:verify-certificate no; open sftp://$E2E_FTP_HOSTNAME; user $E2E_FTP_USERNAME $E2E_FTP_PASSWORD; mirror -Rev storybook-static/ /var/www/html/$FTP_TARGET; quit"
  dependencies:
    - build_storybook
  rules:
    - *e2e_rules

e2e_run:
  stage: e2e
  image: mcr.microsoft.com/playwright:v1.49.0-noble
  cache:
    key: "$CI_COMMIT_REF_SLUG"
    paths:
      - node_modules/
    policy: pull
  script:
    - npm config set cache $NPM_GLOBAL_CACHE
    - export CI=true URL=http://$E2E_FTP_HOSTNAME/$FTP_TARGET
    - npx playwright test
  needs:
    - job: e2e_deploy
      artifacts: false
  rules:
    - *e2e_rules

e2e_run_failure:
  stage: e2e
  before_script:
    - apk add --no-cache curl
    - apk add --no-cache jq
  script:
    # Récupérer les métadonnées de la MR
    - *get_mr_info
    - *fail_if_no_mr
    # Récupérer l'iid de la MR
    - MR_IID=$(echo "$MR_INFO" | jq -r .iid)
    # Récupérer le titre de la MR
    - MR_TITLE=$(echo "$MR_INFO" | jq -r .title)
    # Mettre à jour le statut de la MR
    - |
      # Vérifier si le titre contient déjà "Draft:"
      if echo "$MR_TITLE" | grep -Eq '^(Draft:|WIP:)'; then
        echo "La merge request $MR_IID est déjà en statut DRAFT. Aucune action nécessaire."
      else
        # Ajouter "Draft:" au début du titre
        NEW_TITLE="Draft: $MR_TITLE"

        # Mettre à jour la merge request avec le nouveau titre
        curl --silent --request PUT \
          --header "PRIVATE-TOKEN: $PROJECT_ACCESS_TOKEN" \
          --header "Content-Type: application/json" \
          --data "{\"title\": \"$NEW_TITLE\"}" \
          "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$MR_IID"

        echo "La merge request $MR_IID a été repassée en statut DRAFT."
      fi
    # Mettre à jour les labels
    - >-
      curl 
      --request PUT
      --header "PRIVATE-TOKEN: $PROJECT_ACCESS_TOKEN"
      --header "Content-Type: application/json"
      --data '{"remove_labels": "e2e_passed", "add_labels": "e2e_failed"}'
      "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$MR_IID"
  needs:
    - job: e2e_run
      artifacts: false
  rules:
    - *e2e_rules
  when: on_failure

e2e_run_success:
  stage: e2e
  before_script:
    - apk add --no-cache curl
    - apk add --no-cache jq
  script:
    - *get_mr_info
    - *fail_if_no_mr
    - MR_IID=$(echo "$MR_INFO" | jq -r .iid)
    - >-
      curl 
      --request PUT
      --header "PRIVATE-TOKEN: $PROJECT_ACCESS_TOKEN"
      --header "Content-Type: application/json"
      --data '{"remove_labels": "e2e_failed", "add_labels": "e2e_passed"}'
      "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$MR_IID"
  needs:
    - job: e2e_run
      artifacts: false
  rules:
    - *e2e_rules
  when: on_success

mr_status:
  stage: verify
  before_script:
    - apk add --no-cache curl
    - apk add --no-cache jq
  script:
    - *get_mr_info
    - *exit_if_no_mr
    - |
      MR_IID=$(echo "$MR_INFO" | jq -r .iid)
      echo "MR_IID= $MR_IID"
      MR_LABELS=$(echo "$MR_INFO" | jq -r .labels)
      echo "MR_LABELS= $MR_LABELS"
      MR_DRAFT_STATUS=$(echo "$MR_INFO" | jq -r .draft)
      echo "MR_DRAFT_STATUS= $MR_DRAFT_STATUS"

      if [ "$MR_DRAFT_STATUS" = "false" ] && [ "$MR_LABELS" != "${MR_LABELS%"e2e_passed"*}" ]; then
        MR_TITLE=$(echo "$MR_INFO" | jq -r .title)
        echo "MR_TITLE= $MR_TITLE"
        ESCAPED_TITLE=$(printf '%s' "$MR_TITLE" | sed 's/\"/\\\"/g')
        echo "ESCAPED_TITLE= $ESCAPED_TITLE"
        curl --fail-with-body --silent --show-error --request PUT \
          --header "PRIVATE-TOKEN: $PROJECT_ACCESS_TOKEN" \
          --header "Content-Type: application/json" \
          --data "{\"title\":\"Draft: $ESCAPED_TITLE\", \"remove_labels\":\"e2e_passed\"}" \
          "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$MR_IID"
        echo "La merge request $MR_IID a été repassée en statut DRAFT suite au dernier push."
      else
        echo "La merge request $MR_IID ne nécessite pas un retour en draft."
      fi
  dependencies: []
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"

publish_npm:
  stage: publish
  script:
    - echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}">dist/ngx-dsfr/.npmrc
    - npm run publish
  dependencies:
    - build_lib
  rules:
    - if: $PUB != null

publish_storybook:
  stage: publish
  script:
    - apk add --no-cache lftp
    - lftp -c "open $FTP_HOSTNAME; user $FTP_USERNAME $FTP_PASSWORD; mirror -Rev storybook-static/ ngx-dsfr/$FTP_TARGET; quit"
  dependencies:
    - build_storybook
  rules:
    - if: $PUB != null
      variables:
        FTP_TARGET: "$FTP"