<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: jenoH</title>
    <description>The latest articles on Forem by jenoH (@jenoh).</description>
    <link>https://forem.com/jenoh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F163540%2F474b4734-137d-40b8-accc-8199293fdbe5.jpg</url>
      <title>Forem: jenoH</title>
      <link>https://forem.com/jenoh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jenoh"/>
    <language>en</language>
    <item>
      <title>Developer journey: From Working Code to Maintainable Code</title>
      <dc:creator>jenoH</dc:creator>
      <pubDate>Tue, 27 May 2025 11:31:00 +0000</pubDate>
      <link>https://forem.com/jenoh/from-working-code-to-maintainable-code-4bdm</link>
      <guid>https://forem.com/jenoh/from-working-code-to-maintainable-code-4bdm</guid>
      <description>&lt;p&gt;This post isn’t technical, it doesn’t cover specific design patterns or advanced techniques. It’s more about stepping back and thinking about how complexity shows up in everyday coding. I wrote it to reflect on the kinds of questions I try to ask myself when writing or reading code, to be more thoughtful about structure, clarity, and how things evolve over time.&lt;/p&gt;

&lt;p&gt;When I was learning to code, the goal was simple: make it work. In school projects or small personal projects, once the program ran and the output was correct, it felt like the job was done.&lt;/p&gt;

&lt;p&gt;But as I started working on larger systems, especially with multiple engineers involved, I began to notice something: even when the code worked, coming back to it later was confusing. Small changes would break things unexpectedly. Features that sounded simple ended up being surprisingly messy to implement. I started realizing that writing code that works isn’t the same as writing code that lasts.&lt;/p&gt;

&lt;p&gt;This is where the idea of &lt;strong&gt;complexity&lt;/strong&gt; enters the picture. As systems grow, complexity builds up, and it quietly becomes one of the biggest challenges in software development. It makes code harder to understand, slower to modify, and more fragile over time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Complexity is anything related to the structure of a software system that makes it hard to understand and modify the system.”&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
— &lt;em&gt;John Ousterhout, A Philosophy of Software Design&lt;/em&gt; (2018)  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This post is just me trying to reflect on what I’ve started to notice about complexity. I'm still figuring it out, but writing this down helps me make sense of the patterns I'm seeing and the habits I want to build going forward.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Cost of Ignoring Complexity
&lt;/h2&gt;

&lt;p&gt;At first, complexity doesn’t seem like a big deal. The code works, the tests pass, and features get shipped. But slowly, things start to drag. Small changes take longer. Bugs are harder to fix. New team members (or even future-you) need more time to understand how things work.&lt;/p&gt;

&lt;p&gt;These issues don’t show up overnight, they creep in. But if you pay attention, there are early signs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Change Amplification
&lt;/h3&gt;

&lt;p&gt;Sometimes, making a small change in one place means updating five other files, multiple tests, and maybe even other services. A small rename turns into a mini refactor.&lt;/p&gt;

&lt;p&gt;This is called &lt;strong&gt;change amplification&lt;/strong&gt;, and it usually means parts of the system are too tightly connected. It makes even safe changes feel risky, and slows everyone down.&lt;/p&gt;

&lt;h3&gt;
  
  
  High Cognitive Load
&lt;/h3&gt;

&lt;p&gt;When things are too coupled, full of edge cases, or just hard to follow, it takes a lot of mental effort to get going. That’s what people mean by &lt;strong&gt;high cognitive load&lt;/strong&gt;, you have to keep too much in your head at once.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unclear Change Points
&lt;/h3&gt;

&lt;p&gt;A bug shows up in one place, but the root cause is somewhere else. Or a new feature needs to touch several parts of the code, and I’m not sure which one should be updated, or if I should add something new.&lt;/p&gt;




&lt;h2&gt;
  
  
  Early Habits That (I Think) Help
&lt;/h2&gt;

&lt;p&gt;I'm still learning, but here are some habits that seem to help reduce complexity, or at least make it more manageable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Try to Keep Boundaries Clear
&lt;/h3&gt;

&lt;p&gt;Even in small projects, I’ve started paying more attention to what belongs where. A function should do one thing. A module should have a clear role. When boundaries get fuzzy, everything gets harder to change later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Read Code to Understand Design
&lt;/h3&gt;

&lt;p&gt;Whenever I’m working in an unfamiliar part of the codebase, I try to slow down a little and ask: &lt;em&gt;why is it written this way?&lt;/em&gt; Not just how it works, but what the intent might have been.&lt;/p&gt;

&lt;p&gt;Doing this regularly is helping me build a kind of intuition for what “clean” or “messy” really means in context.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understand Tradeoffs (Not Just Rules)
&lt;/h3&gt;

&lt;p&gt;I’ve come across a lot of advice like “keep functions short” or “don’t repeat yourself.” These are useful, but I’ve also seen how following rules blindly can sometimes make code worse.&lt;/p&gt;

&lt;p&gt;What I’m starting to realize is that most decisions are tradeoffs. It’s not about always doing the same thing, it’s about thinking through the consequences.&lt;/p&gt;

&lt;p&gt;One question I’ve started asking myself more often: &lt;em&gt;will this make the next change easier or harder?&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Complexity Feels Like a Design Problem
&lt;/h2&gt;

&lt;p&gt;One of the most valuable lessons I’m learning is that complexity isn’t usually caused by “bad code.” More often, it comes from design decisions that were made under pressure, with limited context, or simply as the best idea at the time.&lt;/p&gt;

&lt;p&gt;Code tends to grow around real-world constraints: deadlines, changing requirements, evolving teams. Sometimes the structure doesn’t keep up, and things start to feel messy or hard to change.&lt;/p&gt;

&lt;p&gt;What I’ve started to realize is that complexity is often a &lt;strong&gt;design problem&lt;/strong&gt;, not a personal one. It's about how pieces fit together, and how decisions made early on affect everything that comes later.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Complexity is part of the job. It can’t be avoided entirely, but I’ve learned that it can be managed. And the earlier you start noticing it, the more control you have over it.&lt;/p&gt;

</description>
      <category>design</category>
      <category>junior</category>
      <category>learning</category>
      <category>career</category>
    </item>
    <item>
      <title>Automate the deployment of a virtual machine on AWS using Terraform and Github Actions</title>
      <dc:creator>jenoH</dc:creator>
      <pubDate>Fri, 27 Jan 2023 14:09:06 +0000</pubDate>
      <link>https://forem.com/jenoh/how-to-automate-the-deployment-of-a-virtual-machine-on-aws-using-terraform-and-github-actions-24bn</link>
      <guid>https://forem.com/jenoh/how-to-automate-the-deployment-of-a-virtual-machine-on-aws-using-terraform-and-github-actions-24bn</guid>
      <description>&lt;p&gt;&lt;em&gt;First, I want to notify that I'm a software developer and not a devops engineer. That's why if you have any good practice tips, feel free to give me feedback, I will enjoy that!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The goal of this guide is to show you a way to automate the deployment of your virtual machine on AWS. We will need to use Terraform to describe our infrastructure as code and Github Action to trigger/automate the deployment. This combo is very powerful if you want a flexible infrastructure, so I will try to show you a clean overview of what you can do for your professional/side projects. &lt;/p&gt;

&lt;h2&gt;
  
  
  Terraform
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.hashicorp.com/terraform" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt; creates and manages resources on cloud platforms and other services through their application programming interfaces (APIs). Providers enable Terraform to work with virtually any platform or service with an accessible API.&lt;/p&gt;

&lt;h3&gt;
  
  
  The benefit of using Terraform
&lt;/h3&gt;

&lt;p&gt;Terraform will allow you to define your infrastructure as code. Combined with pipeline like Github Action you can automize the deployment of your entire infrastructure. You can &lt;code&gt;deploy&lt;/code&gt;, &lt;code&gt;destroy&lt;/code&gt; and &lt;code&gt;change&lt;/code&gt; your cloud infrastructure with one command line, thank's to the &lt;a href="https://developer.hashicorp.com/terraform/cli" rel="noopener noreferrer"&gt;Terraform CLI&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;First, you will need to install Terraform in your machine. I let you have a look at the documentation &lt;a href="https://developer.hashicorp.com/terraform/downloads" rel="noopener noreferrer"&gt;here&lt;/a&gt;. If you are using macOS and brew like me, type these two commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew tap hashicorp/tap
brew install hashicorp/tap/terraform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use your &lt;a href="https://aws.amazon.com/fr/iam/" rel="noopener noreferrer"&gt;IAM credentials&lt;/a&gt; to authenticate the Terraform AWS provider, set the &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; and the &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt; environment variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Files architecture
&lt;/h4&gt;

&lt;p&gt;I'll present you a way to arrange your Terraform files into a terraform folder (for readability reasons).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ec2.tf&lt;/td&gt;
&lt;td&gt;Configuration of our virtual machine (in our case an ec2 from aws).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;security_group.tf&lt;/td&gt;
&lt;td&gt;Rules of security for the machine.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;variables.tf&lt;/td&gt;
&lt;td&gt;Set variables from our environment.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vpc.tf&lt;/td&gt;
&lt;td&gt;Definition of our virtual private network.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Let's build our virtual machine !
&lt;/h3&gt;

&lt;p&gt;Now, I'll explain how to define a simple EC2 virtual machine. First, we need to create an SSH key pair to allow access remote on the machine. If you don't know how to do, take a look at the &lt;a href="https://www.openssh.com/manual.html" rel="noopener noreferrer"&gt;Github documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now that you have your SSH key pair, you should set the &lt;code&gt;TF_VAR_SSH_PUB_KEY&lt;/code&gt; of your public key.&lt;br&gt;&lt;br&gt;
&lt;em&gt;Notice: All your environment variables used for Terraform will need the TF_VAR prefix.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# variables.tf

variable "SSH_PUB_KEY" {
    type = string
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal of the &lt;code&gt;provider.tf&lt;/code&gt; file, is to define the provider we are going to use, here we will specify AWS with the region (for french people, you can use &lt;code&gt;eu-west-3&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# provider.tf

provider "aws" {
    region = "eu-west-3"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we can write our &lt;code&gt;ec2.tf&lt;/code&gt; file, which is the heart of the configuration :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ec2.tf

resource "aws_key_pair" "admin" {
    key_name = "admin"
    public_key = var.SSH_PUB_KEY
}

resource "aws_instance" "SRV-Front-ESP" {
    ami = "ami-002ff2c881c910aa8"
    instance_type = "t2.nano"
    key_name = "admin"

    tags = {
        Name = "SRV-Front-ESP"
        "Application" = "Web-ESP"
        "Environment" = "PRD"
        "OS" = "Debian"
        "Role" = "Frontend"
    }
}

resource "aws_eip_association" "eip_assoc" {
    instance_id = aws_instance.SRV-Front-ESP.id 
    allocation_id = var.EIP_ASSOC_FRONTEND
}

terraform {
    backend "s3" {
    bucket = "kom-front-bucket-ml"
    key = "terraform.tfstate"
    region = "eu-west-3"
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each &lt;code&gt;resource&lt;/code&gt; block define a feature of our ec2. The &lt;code&gt;aws_key_pair&lt;/code&gt; resource will store into the virtual machine the public key. We should specify a name, to be able to manage multiples key pair. Here, I named my key &lt;code&gt;admin&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The next resource &lt;code&gt;aws_instance&lt;/code&gt; is very important, it may change with your needs. First, we will need to define an &lt;code&gt;ami&lt;/code&gt;. An &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html" rel="noopener noreferrer"&gt;ami&lt;/a&gt; (Amazon Machine Images) as its name indicates, is the image for your virtual machine, In my case I choose a Debian image. You can also create your own ami, if you have specific needs.&lt;br&gt;
Next, I defined &lt;code&gt;t2.nano&lt;/code&gt; as instance_type. The &lt;code&gt;t2.nano&lt;/code&gt; is a virtual machine with 1 vcpu ans 0.5 GiB of ram, it's the smallest offer. If you need more power, you can choose another offer &lt;a href="https://aws.amazon.com/fr/ec2/instance-types/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
The &lt;code&gt;key_name&lt;/code&gt; is used to provide the good SSH key for your virtual machine. And finally, the block &lt;code&gt;tags&lt;/code&gt; is here to provide informations, you can fill it as you want. &lt;/p&gt;

&lt;p&gt;Now, let me introduce you the &lt;code&gt;state&lt;/code&gt; in Terraform. The notion of &lt;code&gt;state&lt;/code&gt; is very important to understand how Terraform works. This &lt;code&gt;state&lt;/code&gt; is used by Terraform to map real world resources to your configuration. It's stored by default in a local file named "terraform.tfstate", but it can also be stored remotely, which works better in a team environment.&lt;br&gt;&lt;br&gt;
That's why I use a bucket from &lt;a href="https://aws.amazon.com/fr/s3/" rel="noopener noreferrer"&gt;Amason S3&lt;/a&gt; to store the &lt;code&gt;terraform.tfstate&lt;/code&gt;. Now, your file in your bucket will be up to date compared to the actual state of your server. &lt;/p&gt;

&lt;p&gt;That's all, now you can run &lt;code&gt;terraform init&lt;/code&gt;, this command performs several different initialization steps in order to prepare the current working directory for use with Terraform. After initialization, you can run &lt;code&gt;terraform plan&lt;/code&gt; to see what will make your terraform configuration. If you are ok with the result of the plan, you can finally run &lt;code&gt;terraform apply&lt;/code&gt; and see your virtual machine alive ! &lt;/p&gt;

&lt;p&gt;Now that we can deploy our virtual machine, we will need to setup &lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;Github Actions&lt;/a&gt; to automate the deployment.&lt;/p&gt;
&lt;h2&gt;
  
  
  Github Actions
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;Actions&lt;/a&gt; is a continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline. &lt;br&gt;
The global idea is to have in your Github repository of your project, a Terraform folder with your Terraform config and a .github folder with your jobs workflow. &lt;/p&gt;
&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;To run Terraform in your workflow, you will need to setup our secrets in the settings of your github's repository or your github organization (to share your secrets between repositories).  &lt;/p&gt;

&lt;p&gt;AWS credentials: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9dy91h03kytm2xib4so.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9dy91h03kytm2xib4so.png" alt="Image description" width="800" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Terraform environment variables: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6wovq76ee2yu247l6x05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6wovq76ee2yu247l6x05.png" alt="Image description" width="800" height="106"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Let's build our workflow !
&lt;/h3&gt;

&lt;p&gt;A workflow run is made up of one or more &lt;code&gt;jobs&lt;/code&gt;, which run in parallel by default. In our case, we need just one job. This job should setup and run Terraform.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .github/workflows/deploy.yml

name: DEPLOY

on:
  pull_request:
    branches:
      - main
    types: [closed]

jobs: 
  deploy-vm:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1

      - name: Install terraform
        run: sudo apt-get install -y software-properties-common gnupg2 curl

      - name: Install dependencies
        run: |
          curl https://apt.releases.hashicorp.com/gpg | gpg --dearmor &amp;gt; hashicorp.gpg
          sudo install -o root -g root -m 644 hashicorp.gpg /etc/apt/trusted.gpg.d/
          sudo apt-add-repository "deb [arch=$(dpkg --print-architecture)] https://apt.releases.hashicorp.com focal main"
          sudo apt update
          sudo apt install terraform

      - name: Terraform init
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          TF_VAR_EIP_ASSOC_FRONTEND: ${{ secrets.TF_VAR_EIP_ASSOC_FRONTEND }}
          TF_VAR_SSH_PUB_KEY: ${{ secrets.TF_VAR_SSH_PUB_KEY }}
        run: |
          pwd
          ls -la 
          cd terraform
          terraform init

      - name: Terraform apply
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          TF_VAR_EIP_ASSOC_FRONTEND: ${{ secrets.TF_VAR_EIP_ASSOC_FRONTEND }}
          TF_VAR_SSH_PUB_KEY: ${{ secrets.TF_VAR_SSH_PUB_KEY }}
        run: |
          cd terraform
          terraform apply -auto-approve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we define when we want to trigger the pipeline with the &lt;code&gt;on&lt;/code&gt; block. Here, I have decided to deploy/apply changes on my virtual machine for each closed merge request on the main branch, but you can change for scheduled task, push on develop, etc..&lt;/p&gt;

&lt;p&gt;Finally, you can define one step to install dependencies. Here I have defined &lt;code&gt;ubuntu-latest&lt;/code&gt; as image for the pipeline, so I should install dependencies with the package manager &lt;code&gt;apt-get&lt;/code&gt;. And now, you can write two steps, for &lt;code&gt;terraform init&lt;/code&gt; and &lt;code&gt;terraform apply&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And voila ! You can see your workflows in the Actions tab of your repository !&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fccsr2vhp3yawx7tveycc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fccsr2vhp3yawx7tveycc.png" alt="Image description" width="800" height="49"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all ! I hope I have helped you to see it more clearly !&lt;br&gt;&lt;br&gt;
As said at the beginning, I'm a software developer, I just love learning new things, but I understand that I can tell some mistakes, feel free to give me feedback ! I will fix it.&lt;/p&gt;

&lt;p&gt;Théo "jenoH". &lt;a href="https://twitter.com/jen0h_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;a href="https://github.com/jenoh" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>terraform</category>
      <category>github</category>
      <category>actions</category>
    </item>
    <item>
      <title>How I have created my own technological survey with node.js and Gitlab CI/CD.</title>
      <dc:creator>jenoH</dc:creator>
      <pubDate>Thu, 11 Jun 2020 09:34:54 +0000</pubDate>
      <link>https://forem.com/jenoh/how-i-have-created-my-own-technological-survey-with-node-js-and-gitlab-ci-cd-1dkm</link>
      <guid>https://forem.com/jenoh/how-i-have-created-my-own-technological-survey-with-node-js-and-gitlab-ci-cd-1dkm</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclaimer: It's my first article, and I'm not yet proud of my English level. Nice read at all !&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hello guys, how are you ? Do you subscribes to newsletters for your daily technological survey and don't read any articles ?&lt;/p&gt;

&lt;p&gt;I realized that some time ago. So I have decided to create my own "private" flux of news/articles.&lt;/p&gt;

&lt;h1&gt;
  
  
  In theory.
&lt;/h1&gt;

&lt;p&gt;The theory is really simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We need to &lt;strong&gt;find&lt;/strong&gt; some &lt;strong&gt;rss flux&lt;/strong&gt; of what you want to read. &lt;/li&gt;
&lt;li&gt;After this search, we need to make a script who &lt;strong&gt;send an email every morning&lt;/strong&gt; at your favorite email address.&lt;/li&gt;
&lt;li&gt;And at the end, you can &lt;strong&gt;run this script&lt;/strong&gt; on a server &lt;strong&gt;as a cron&lt;/strong&gt; or you can also use Gitlab CI/CD.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Notice that I have make the minimum at the moment. We can add more rss flux, and clear articles/news before send an email to improve your technological survey.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Let's code !
&lt;/h1&gt;

&lt;p&gt;I want to improve my javascript level so I have pick this technology, but you can do the &lt;strong&gt;same thing with another techno&lt;/strong&gt;..&lt;/p&gt;

&lt;p&gt;I will not explain a lot my code because you can do what you want, and you will probably understand my code easily !&lt;/p&gt;

&lt;p&gt;My gitlab &lt;a href="https://gitlab.com/theomemin/tech_survey/edit#js-general-settings" rel="noopener noreferrer"&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For my example I have take a Reddit rss like this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let feed = await parser.parseURL('https://www.reddit.com/r/softwaredevelopment/.rss');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sending email with nodemailer and handlebars.
&lt;/h2&gt;

&lt;p&gt;Sending email with node.js is really simple with nodemailer !&lt;br&gt;
First, we need to &lt;strong&gt;define the transport for nodemailer&lt;/strong&gt;, in my case I have use gmail, but you can take mailgun, or whatever, but gmail is easy to set up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var transporter = nodemailer.createTransport({
  service: 'gmail',
  auth: {
    user: 'cronjenoh@gmail.com',
    pass: process.env.MAIL_PASS
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we have to feed our HTML with our news previously collected on the rss flux.&lt;/p&gt;

&lt;p&gt;For that, I have used &lt;a href="https://handlebarsjs.com/" rel="noopener noreferrer"&gt;Handlebars&lt;/a&gt;. Handlebars is a simple templating language. It uses a template and an input object to generate HTML or other text formats.&lt;/p&gt;

&lt;p&gt;It's working like this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; readHTMLFile(__dirname + '/email.html', function (err, html) {
    var template = handlebars.compile(html);
    var replacements = {
      posts: posts
    };
    var htmlToSend = template(replacements);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;htmlToSend&lt;/code&gt; variable we have the template with our news. (My repository have an example of an email template).&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the srcipt as a cron
&lt;/h2&gt;

&lt;p&gt;In my case, I have choose GitLab CI/CD.&lt;br&gt;
GitLab CI/CD is a tool built into GitLab for software development through the continuous methodologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Continuous Integration (CI)&lt;/li&gt;
&lt;li&gt;Continuous Delivery (CD)&lt;/li&gt;
&lt;li&gt;Continuous Deployment (CD) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's perfect when you need to run a scrips as a cron, it's easy to use.&lt;br&gt;
So, first step, we need to add a &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; file in our repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;default:
  image: node:latest

stages:
  - run

cron run:
  stage: run
  script:
    - npm i
    - node cron.js

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first line is facultive, in fact if we remove this, Gitlab will take the default image for your docker container, but I have decided to take a &lt;strong&gt;node image&lt;/strong&gt; (more coherent with my project).&lt;/p&gt;

&lt;p&gt;Second step, we should whrite a &lt;strong&gt;stage&lt;/strong&gt; and a &lt;strong&gt;job&lt;/strong&gt;. In the job we should set the &lt;strong&gt;list of actions&lt;/strong&gt; to setup the project. For a node project, we need to install packages with &lt;code&gt;npm i&lt;/code&gt; and run the cron &lt;code&gt;node cron.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After that, if you push you will see in CI/CD settings of your project that &lt;strong&gt;a pipeline as been created&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Final step, go to your schedules settings in CI/CD and set up your cron, with the target branch, timezone, recurrence ..&lt;/p&gt;

&lt;p&gt;And it's done !&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I hope you have enjoyed my article, I did it with pleasure ❤️.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>project</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
