From 2b214d81416683efd500fb804cf899b322c95ebe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20HOVINNE?=
 <jean-francois.hovinne@ext.ec.europa.eu>
Date: Thu, 9 Nov 2023 12:14:54 +0100
Subject: [PATCH] feat: Set Node.js 20.x as default, remove RH7 and Ubuntu
 18.04 support (breaking change, fixes #11)

---
 README.md                     |   7 +-
 RELEASES.md                   |   8 ++-
 defaults/main.yml             |   2 +-
 meta/main.yml                 |   2 -
 molecule/custom/converge.yml  |   6 +-
 molecule/default/molecule.yml |  14 ----
 molecule/default/verify.yml   |  16 -----
 tasks/main.yml                |  18 +++++-
 tasks/setup-Amazon.yml        | 117 ++++++++++++++++++++++++++++++++++
 tasks/setup-RedHat.yml        |   4 --
 10 files changed, 149 insertions(+), 45 deletions(-)
 create mode 100644 tasks/setup-Amazon.yml

diff --git a/README.md b/README.md
index 4ef78be..66c3bfe 100644
--- a/README.md
+++ b/README.md
@@ -11,10 +11,15 @@ Requirements
 Role Variables
 --------------
 
-- `nodejs_version`: Sets the Node.js version to install ("12.x", "13.x", "14.x", "15.x", etc.).
+- `nodejs_version`: Sets the Node.js version to install ("16.x", "18.x", "20.x", etc).
+
+The default version is 20.x.
 
 Version numbers from Nodesource: https://github.com/nodesource/distributions.
 
+Node.js 18 and 20 on Amazon Linux 2 are supported, using pre-built binaries from:
+https://code.europa.eu/ecgalaxy/amazonlinux2-nodejs
+
 Dependencies
 ------------
 
diff --git a/RELEASES.md b/RELEASES.md
index 8ce3caa..05ce80e 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,9 +1,15 @@
 # Releases
 
+## 2.0.0
+
+- Node.js 20.x set as default version.
+- RedHat 7 and Ubuntu 18.04 support removed.
+- Node.js 18.x and 20.x for Amazon Linux 2 support added.
+
 ## 1.0.0
 
 - Ubuntu 22.04 LTS support added.
-- Node.js 16.
+- Node.js 16.x
 
 ## 0.1.x
 
diff --git a/defaults/main.yml b/defaults/main.yml
index 7249bb4..9769c93 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -1,4 +1,4 @@
 ---
 # Set the version of Node.js to install ("12.x", "13.x", "14.x", "15.x", etc.).
 # Version numbers from Nodesource: https://github.com/nodesource/distributions
-nodejs_version: "16.x"
+nodejs_version: "20.x"
diff --git a/meta/main.yml b/meta/main.yml
index 3df502f..a21caa1 100644
--- a/meta/main.yml
+++ b/meta/main.yml
@@ -11,11 +11,9 @@ galaxy_info:
         - "2"
     - name: EL
       versions:
-        - "7"
         - "8"
     - name: Ubuntu
       versions:
-        - bionic
         - focal
         - jammy
   galaxy_tags:
diff --git a/molecule/custom/converge.yml b/molecule/custom/converge.yml
index dd236c2..e174c6f 100644
--- a/molecule/custom/converge.yml
+++ b/molecule/custom/converge.yml
@@ -9,9 +9,9 @@
       vars:
         nodejs_version: "{{ version }}"
       loop:
-        - "14.x"
-        - "16.x"
-        - "14.x"
+        - "18.x"
+        - "20.x"
+        - "18.x"
       loop_control:
         loop_var: version
   environment:
diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml
index 74b185c..207c4af 100644
--- a/molecule/default/molecule.yml
+++ b/molecule/default/molecule.yml
@@ -11,13 +11,6 @@ platforms:
       http_proxy: "${http_proxy}"
       https_proxy: "${https_proxy}"
       no_proxy: "${no_proxy}"
-  - name: centos7-${CI_JOB_ID:-0}
-    image: code.europa.eu:4567/ecgalaxy/centos7-ansible:latest
-    pre_build_image: true
-    environment:
-      http_proxy: "${http_proxy}"
-      https_proxy: "${https_proxy}"
-      no_proxy: "${no_proxy}"
   - name: rockylinux8-${CI_JOB_ID:-0}
     image: code.europa.eu:4567/ecgalaxy/rockylinux8-ansible:latest
     pre_build_image: true
@@ -25,13 +18,6 @@ platforms:
       http_proxy: "${http_proxy}"
       https_proxy: "${https_proxy}"
       no_proxy: "${no_proxy}"
-  - name: ubuntu1804-${CI_JOB_ID:-0}
-    image: code.europa.eu:4567/ecgalaxy/ubuntu1804-ansible:latest
-    pre_build_image: true
-    environment:
-      http_proxy: "${http_proxy}"
-      https_proxy: "${https_proxy}"
-      no_proxy: "${no_proxy}"
   - name: ubuntu2004-${CI_JOB_ID:-0}
     image: code.europa.eu:4567/ecgalaxy/ubuntu2004-ansible:latest
     pre_build_image: true
diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml
index ea9bc20..889ee81 100644
--- a/molecule/default/verify.yml
+++ b/molecule/default/verify.yml
@@ -6,14 +6,6 @@
       with_first_found:
         - "../../defaults/main.yml"
       ansible.builtin.include_vars: "{{ item }}"
-    - name: Check nodejs binary file
-      ansible.builtin.stat:
-        path: /usr/bin/node
-      register: bin
-    - name: Assert that node binary is installed
-      ansible.builtin.assert:
-        that:
-          - "bin.stat.exists"
     - name: Check node execution
       ansible.builtin.command: node --version
       register: output
@@ -21,14 +13,6 @@
       ansible.builtin.assert:
         that:
         - "'v{{ nodejs_version.split('.')[0] }}' in output.stdout"
-    - name: Check npm binary file
-      ansible.builtin.stat:
-        path: /usr/bin/npm
-      register: bin
-    - name: Assert that npm binary is installed
-      ansible.builtin.assert:
-        that:
-          - "bin.stat.exists"
     - name: Check npm execution
       ansible.builtin.command: npm --version
       register: output
diff --git a/tasks/main.yml b/tasks/main.yml
index 1561484..cbc3837 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -1,8 +1,20 @@
 ---
+- name: Compute nodejs_version_major
+  ansible.builtin.set_fact:
+    nodejs_version_major: "{{ nodejs_version | regex_replace('.x', '') }}"
+
+- name: Setup
+  ansible.builtin.include_tasks: setup-RedHat.yml
+  when: ansible_os_family == 'RedHat' and nodejs_version_major | int < 17
+
+- name: Setup
+  ansible.builtin.include_tasks: setup-RedHat.yml
+  when: ansible_os_family == 'RedHat' and ansible_distribution != 'Amazon' and nodejs_version_major | int > 16
+
 - name: Setup
-  ansible.builtin.import_tasks: setup-RedHat.yml
-  when: ansible_os_family == 'RedHat'
+  ansible.builtin.include_tasks: setup-Amazon.yml
+  when: ansible_distribution == 'Amazon' and nodejs_version_major | int > 16
 
 - name: Setup
-  ansible.builtin.import_tasks: setup-Debian.yml
+  ansible.builtin.include_tasks: setup-Debian.yml
   when: ansible_os_family == 'Debian'
diff --git a/tasks/setup-Amazon.yml b/tasks/setup-Amazon.yml
new file mode 100644
index 0000000..8c89473
--- /dev/null
+++ b/tasks/setup-Amazon.yml
@@ -0,0 +1,117 @@
+---
+- name: Set Node.js release
+  ansible.builtin.set_fact:
+    nodejs_release: "18.18.2"
+    nodejs_checksum: "sha256:2bcc02cbd144de11a21b8b1365b772b7a009e5a42689d1058cd89325ad5429ad"
+  when: nodejs_version_major | int == 18
+
+- name: Set artifact download URL
+  ansible.builtin.set_fact:
+    nodejs_release: "20.9.0"
+    nodejs_checksum: "sha256:b5b68bea977d9d4da1ec2656e72963ab61f9460f184144194c913a60bb54e0f8"
+  when: nodejs_version_major | int == 20
+
+- name: Set artifact download URL
+  ansible.builtin.set_fact:
+    nodejs_download_url: "https://code.europa.eu/api/v4/projects/569/packages/generic/amazonlinux2-nodejs/{{ nodejs_release }}/nodejs-v{{ nodejs_release }}.tar.gz"
+    nodejs_install_path: "/opt/nodejs/{{ nodejs_release }}"
+
+- name: Check if Node.js {{ nodejs_version_major }} is already installed # noqa: name[template]
+  ansible.builtin.stat:
+    path: "{{ nodejs_install_path }}"
+  register: nodejs_st
+
+- name: Install Node.js
+  when: nodejs_st.stat.isdir is not defined
+  block:
+  - name: Create directory
+    ansible.builtin.file:
+      state: directory
+      owner: root
+      group: root
+      mode: 'u=rwx,go=rx'
+      path: "{{ nodejs_install_path }}"
+    become: true
+
+  - name: Download Node.js artifact
+    ansible.builtin.get_url:
+      url: "{{ nodejs_download_url }}"
+      checksum: "{{ nodejs_checksum }}"
+      mode: 'u=rwx,go=rx'
+      dest: /tmp
+    register: downloaded_file
+
+  - name: Extract artifact
+    ansible.builtin.unarchive:
+      src: "{{ downloaded_file.dest }}"
+      dest: "{{ nodejs_install_path }}"
+      owner: "root"
+      group: "root"
+      mode: "u=rwx,go=rx"
+      remote_src: yes
+      extra_opts: [--strip-components=3]
+    become: true
+
+  - name: Create node symlink
+    ansible.builtin.file:
+      src: "{{ nodejs_install_path }}/bin/node"
+      dest: /usr/local/bin/node
+      owner: "root"
+      group: "root"
+      mode: 'u=rwx,go=rx'
+      state: link
+    become: true
+
+  - name: Create npm symlink
+    ansible.builtin.file:
+      src: "{{ nodejs_install_path }}/bin/npm"
+      dest: /usr/local/bin/npm
+      owner: "root"
+      group: "root"
+      mode: 'u=rwx,go=rx'
+      state: link
+    become: true
+
+  - name: Create npx symlink
+    ansible.builtin.file:
+      src: "{{ nodejs_install_path }}/bin/npx"
+      dest: /usr/local/bin/npx
+      owner: "root"
+      group: "root"
+      mode: 'u=rwx,go=rx'
+      state: link
+    become: true
+
+  - name: Create corepack symlink
+    ansible.builtin.file:
+      src: "{{ nodejs_install_path }}/bin/corepack"
+      dest: /usr/local/bin/corepack
+      owner: "root"
+      group: "root"
+      mode: 'u=rwx,go=rx'
+      state: link
+    become: true
+
+  - name: Clean up temporary files
+    ansible.builtin.file:
+      path: "{{ downloaded_file.dest }}"
+      state: absent
+
+- name: Install yarn
+  community.general.npm:
+    name: yarn
+    global: true
+    executable: /usr/local/bin/npm
+  environment:
+    PATH: /usr/local/bin:{{ ansible_env.PATH }}
+  become: true
+
+- name: Create yarn symlink
+  ansible.builtin.file:
+    src: "{{ nodejs_install_path }}/bin/yarn"
+    dest: /usr/local/bin/yarn
+    owner: "root"
+    group: "root"
+    mode: 'u=rwx,go=rx'
+    state: link
+  become: true
diff --git a/tasks/setup-RedHat.yml b/tasks/setup-RedHat.yml
index f0d540d..8a090b9 100644
--- a/tasks/setup-RedHat.yml
+++ b/tasks/setup-RedHat.yml
@@ -1,8 +1,4 @@
 ---
-- name: Set up the Nodesource RPM directory
-  ansible.builtin.set_fact:
-    rhel_distribution_major_version: 7
-
 - name: Set up the Nodesource RPM directory
   ansible.builtin.set_fact:
     rhel_distribution_major_version: "{{ ansible_distribution_major_version }}"
-- 
GitLab