<?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: AlessandroMinoccheri</title>
    <description>The latest articles on Forem by AlessandroMinoccheri (@minompi).</description>
    <link>https://forem.com/minompi</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%2F39763%2Ffd454b0e-1a70-40e0-a5de-41110443a609.jpg</url>
      <title>Forem: AlessandroMinoccheri</title>
      <link>https://forem.com/minompi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/minompi"/>
    <language>en</language>
    <item>
      <title>8 Code reviews tips and tricks</title>
      <dc:creator>AlessandroMinoccheri</dc:creator>
      <pubDate>Tue, 30 Aug 2022 06:31:42 +0000</pubDate>
      <link>https://forem.com/minompi/8-code-reviews-tips-and-tricks-1ed7</link>
      <guid>https://forem.com/minompi/8-code-reviews-tips-and-tricks-1ed7</guid>
      <description>&lt;p&gt;Code reviews are a largely accepted best practice for software development teams. There are a lot of benefits to using them and there is always something to learn as a reviewer. But adopting from zero code reviews isn’t so easy and immediate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RSSkNQMV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2026/1%2AfTjEhhV3IQH0vMEvrai71A.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RSSkNQMV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2026/1%2AfTjEhhV3IQH0vMEvrai71A.jpeg" alt="Image from iStock" width="880" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s important to share why they are so important for a team and what are their &lt;strong&gt;goals&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Quality control:&lt;/strong&gt; code reviews can increase the quality because we can find new solutions and improvements&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sharing knowledge:&lt;/strong&gt; It’s easy to end up in a situation where one developer deals with a certain part of the codebase because they’re most familiar with it. in short-period seems a win but it’s not for the future. When ownership is shared, teams become more motivated and autonomous.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Increasing developer's knowledge:&lt;/strong&gt; we can learn through code reviews, by asking questions about a piece of code that we don’t understand, or by sharing a different method to solve the problem&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So after sharing why code reviews are so important it’s time to understand what are some tips and tricks for using them correctly and take advantage of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  1 Keep Pull requests small
&lt;/h2&gt;

&lt;p&gt;Keeping the Pull requests &lt;strong&gt;smaller as possible&lt;/strong&gt; allows for the easiest review and, usually, more contribution and focus on it. &lt;br&gt;
If you create a bug pull request with 120 files changed, 12000 lines added and 3500 lines removed it’s very difficult to find problems or better solutions. It’s totally a waste of time reviewing such a big pull request and it takes too many hours for doing it. &lt;br&gt;
For that reason, it’s better to split the pull request into different pull requests with a specific code review.&lt;/p&gt;

&lt;p&gt;A &lt;a href="http://smartbear.com/resources/case-studies/cisco-systems-collaborator/"&gt;SmartBear study of a Cisco Systems programming team&lt;/a&gt; revealed that &lt;strong&gt;developers should review no more than 200 to 400 lines of code&lt;/strong&gt; (LOC) at a time because the brain can only effectively process so much information at a time; beyond 400 LOC, the ability to find bugs, defects diminishes.&lt;/p&gt;

&lt;p&gt;In practice, a review of 200–400 LOC over 60 to 90 minutes should yield 70–&lt;strong&gt;90% defect discovery.&lt;/strong&gt; So, if 10 defects existed in the code, a properly conducted review would find between 7 and 9 of them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xiy1IVK9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1316/1%2AhVvPK3s5lahatLY5DRUaiw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xiy1IVK9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1316/1%2AhVvPK3s5lahatLY5DRUaiw.jpeg" alt="" width="658" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2 Don’t review for more than 1 hour
&lt;/h2&gt;

&lt;p&gt;Usually, it’s not a best practice to review code too quickly, on the other side you shouldn’t review for too long because performance starts to decrease after about 1 hour. &lt;br&gt;
Our brain needs a break to refresh to have good performance and to review well the code. &lt;br&gt;
It’s important to keep the focus on the review to discover and understand every single part of the pull request. &lt;br&gt;
&lt;strong&gt;Doing a superficial review it’s not a good practice and decreases the credibility of the process for the whole team&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 Add a clear description
&lt;/h2&gt;

&lt;p&gt;To help reviewers to do their job it’s important to add a description to the pull request to share:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;which problem are you trying to solve&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;why did you choose that solution&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;doubts about something&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;question about the implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;…&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s also important to &lt;strong&gt;add a clear description&lt;/strong&gt; for the future, for example, after some months you would like to understand why that piece of code was added. There are a lot of benefits to adding a clear description!&lt;/p&gt;

&lt;h2&gt;
  
  
  4 Use Pull Request template
&lt;/h2&gt;

&lt;p&gt;Many tools, like &lt;strong&gt;GitHub&lt;/strong&gt;, provide a template to create Pull Requests, in this way you have a standard and it’s easier to create a new one and review it. If you want to add the template. &lt;br&gt;
GitHub you need to create a new file .github/pull_request_template.md&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Github Documentation&lt;/strong&gt;: &lt;a href="https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository"&gt;https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using a template allows the team to create a standard pull request to help each member of the team.&lt;/p&gt;

&lt;h2&gt;
  
  
  5 Number of reviewers
&lt;/h2&gt;

&lt;p&gt;What is the correct number of accepted reviews to merge a pull request? There isn’t a specific rule again but it’s important to decide it in the team and try to understand what is the correct number. &lt;br&gt;
Usually, you don’t need that every member of the team accepts the pull request, except for some critical features. &lt;br&gt;
Sometimes one or two accepted reviews are good enough to merge the pull request. &lt;br&gt;
Why not everyone? &lt;br&gt;
Because you can create a bottleneck and your deployment can be blocked by some reviewer that didn’t see it already for other reasons.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8GTxDtzW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A7m2DQhgndMyZPPbdS0Vu-w.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8GTxDtzW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A7m2DQhgndMyZPPbdS0Vu-w.jpeg" alt="" width="700" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6 Empathy
&lt;/h2&gt;

&lt;p&gt;Empathy is an important skill during the review. &lt;br&gt;
As a reviewer, you need to understand what the author is trying to solve, what was his thought, and why it’s implemented in this way. &lt;br&gt;
You need to &lt;strong&gt;be kind&lt;/strong&gt; when you comment on the pull request without being rude. &lt;br&gt;
Don’t try to give a new solution, instead ask questions about the implementation like: “Is this the only way to solve the problem?” “It seems a little bit coupled with this code, what do you think? Is there a better way?”&lt;/p&gt;

&lt;p&gt;If you liked a piece of code or you learn a new thing write a comment like: “this is perfect, I never thought about it” or “I didn’t know about this function! Amazing, it seems very useful!” &lt;br&gt;
Try to &lt;strong&gt;foster a positive code review culture!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7 Delegate static analysis
&lt;/h2&gt;

&lt;p&gt;Using a tool to automate static analysis checks it’s important because during reviews you need to focus on behaviors, business logic, and patterns you don’t have to focus on spaces, missing commas, or things that the static analysis tool can check. &lt;br&gt;
&lt;strong&gt;All the automatable static analysis checks should be delegated&lt;/strong&gt; to these tools during a CD/CI process. &lt;br&gt;
This delegation can save you a lot of time and allows the team to focus on the business logic and the high-level approach to the implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  8 Run a retrospective
&lt;/h2&gt;

&lt;p&gt;After a month or two of reviews it’s important to understand if the process is good or not and how can you improve it. &lt;br&gt;
To do it I can suggest running a retrospective to understand it. &lt;br&gt;
It’s important to find an external facilitator so all the team can discuss together what was good and what was not. &lt;br&gt;
There is a lot of different type of retrospectives and the facilitator can use one of them. &lt;br&gt;
Every month or two it’s important to run the retrospective, especially in the early stage of the adoption process, to improve it and create a feedback process for all the team.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BrYsWJkm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2800/1%2AU1VSpPxRPzb9OhukhR0FYQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BrYsWJkm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2800/1%2AU1VSpPxRPzb9OhukhR0FYQ.png" alt="" width="880" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Code reviews are a fantastic tool but you need to know how to manage them to get all the benefits.&lt;br&gt;
There is always something to learn and improve in this process to discover with your team and discuss it.&lt;br&gt;
I enjoy creating pull requests and reviewing the code of others, I always learn something and understand other points of view.&lt;br&gt;
Never stop learning.&lt;/p&gt;

</description>
      <category>collaboration</category>
      <category>codereview</category>
      <category>github</category>
      <category>team</category>
    </item>
    <item>
      <title>Add images to a React project with Typescript</title>
      <dc:creator>AlessandroMinoccheri</dc:creator>
      <pubDate>Fri, 22 Jul 2022 09:34:23 +0000</pubDate>
      <link>https://forem.com/minompi/add-images-to-a-react-project-with-typescript-4gbm</link>
      <guid>https://forem.com/minompi/add-images-to-a-react-project-with-typescript-4gbm</guid>
      <description>&lt;p&gt;In every single project, usually, you need to add an image to your React project to show something or to represent a graph and create a beautiful page for your audience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fz9ab8e7kv2jmhtecx2dg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fz9ab8e7kv2jmhtecx2dg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adding an image with React is very simple and fast, this is an example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import React from "react";
import imageToAdd from "./../assets/images/logo.png";
function YourComponent() {
   return &amp;lt;img src={imageToAdd} alt="Image" /&amp;gt;;
}
export default YourComponent;


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

&lt;/div&gt;

&lt;p&gt;This works like a charm in a React project built using &lt;a href="https://create-react-app.dev/" rel="noopener noreferrer"&gt;CRA&lt;/a&gt; or &lt;a href="https://vitejs.dev/" rel="noopener noreferrer"&gt;Vite&lt;/a&gt;.&lt;br&gt;
but if your project has a custom bundler, created using &lt;strong&gt;Typescript&lt;/strong&gt; + &lt;strong&gt;Webpack&lt;/strong&gt;, with the code above you will receive this error:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Cannot find module  './../assets/images/logo.png'


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

&lt;/div&gt;

&lt;p&gt;The first time I saw that error, I thought “It’s a bug!”, but after searching and understanding typescript well, I discovered that receiving an error is the correct behavior.&lt;/p&gt;

&lt;p&gt;By default in typescript, the &lt;a href="https://www.typescriptlang.org/docs/handbook/module-resolution.html" rel="noopener noreferrer"&gt;&lt;strong&gt;module resolution&lt;/strong&gt;&lt;/a&gt; resolves the import using only the files with extension: &lt;strong&gt;.ts&lt;/strong&gt; &lt;strong&gt;.tsx&lt;/strong&gt; or &lt;strong&gt;.d.ts&lt;/strong&gt; and this is the reason why in the previous case the module couldn't be found.&lt;/p&gt;

&lt;p&gt;So, how can we fix the problem?&lt;br&gt;
To solve the problem, usually, you have to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;add a directory called &lt;em&gt;types&lt;/em&gt; on your project's root&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create inside of that folder a file called &lt;em&gt;index.d.ts&lt;/em&gt; with the following content&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

declare module "*.jpg";
declare module "*.png";


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

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;N.B. the extension depends on the file type you are adding.&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;install the &lt;em&gt;file-loader&lt;/em&gt; dependence using &lt;strong&gt;npm&lt;/strong&gt;, &lt;strong&gt;yarn&lt;/strong&gt; or &lt;strong&gt;pnpm&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

npm install --save-dev file-loader


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

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;update your &lt;strong&gt;webpack&lt;/strong&gt; config file to use the file-loader module like this&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

...
{ test: /\\.(png|jp(e*)g|svg|gif)$/, use: ['file-loader'], }
...


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

&lt;/div&gt;

&lt;p&gt;Then, you can run your application, your build will succeed and your image will appear! 🎩&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F9z27na2nagv8knxs13ep.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F9z27na2nagv8knxs13ep.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>webpack</category>
    </item>
    <item>
      <title>Server-Sent events with PHP and Symfony</title>
      <dc:creator>AlessandroMinoccheri</dc:creator>
      <pubDate>Wed, 25 May 2022 10:05:37 +0000</pubDate>
      <link>https://forem.com/minompi/server-sent-events-with-php-and-symfony-4khj</link>
      <guid>https://forem.com/minompi/server-sent-events-with-php-and-symfony-4khj</guid>
      <description>&lt;p&gt;In the magic world of  &lt;strong&gt;PHP&lt;/strong&gt;, there is a library for many things that you don’t know, every day new libraries are born and it’s impossible to know each of them.&lt;br&gt;&lt;br&gt;
For this reason, I try always to follow on  &lt;strong&gt;Twitter&lt;/strong&gt;,  &lt;strong&gt;LinkedIn&lt;/strong&gt;, and  &lt;strong&gt;GitHub&lt;/strong&gt;  good developers that are sharing new approaches and libraries.&lt;br&gt;&lt;br&gt;
For one of our customers, we needed an application where the server can send data to all clients.&lt;br&gt;&lt;br&gt;
So we need to build the software with a  &lt;strong&gt;Server-Sent events approach&lt;/strong&gt;  in a short time to release the product as soon as possible to validate the customer idea.&lt;/p&gt;

&lt;p&gt;If you would like more about Server-Sent events, what it means, advantages and limits, you can read my previous article  &lt;a href="https://dev.to/minompi/websocket-vs-server-sent-events-2b77"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To realize a Server-Sent Events in PHP we found a Symfony library  &lt;a href="https://github.com/symfony/mercure" rel="noopener noreferrer"&gt;symfony/mercure&lt;/a&gt;, I saw this library in some article on LinkedIn and it’s the proof that following the right people can be very important.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2AE7Sz8Szuj-KJTpo08C_ErQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2AE7Sz8Szuj-KJTpo08C_ErQ.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  How to install it
&lt;/h1&gt;

&lt;p&gt;We can use Flex to install it so, you can write into your CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require mercure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, you can configure Mercure environment variables into the file: config/packages/mercure.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mercure:  
  hubs:  
    default:  
      url: [https://mercure-hub.example.com/.well-known/mercure](https://mercure-hub.example.com/.well-known/mercure)  
      jwt:  
        secret: '!ChangeMe!'  
        publish: ['foo', '[https://example.com/foo](https://example.com/foo')']  
        subscribe: ['bar', '[https://example.com/bar](https://example.com/bar')']  
        algorithm: 'hmac.sha256'  
        provider: 'My\Provider'  
        factory: 'My\Factory'  
        value: 'my.jwt'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me explain what are the values to set into the configuration file:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;secret&lt;/strong&gt;: the key to use to sign the JWT (all other options, besides algorithm, subscribe, and publish will be ignored)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;publish&lt;/strong&gt;: a list of topics to allow publishing when generating the JWT (only usable when secret or factory are provided)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;subscribe&lt;/strong&gt;: a list of topics to allow subscribing to when generating the JWT (only usable when secret, or factory are provided)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;algorithm&lt;/strong&gt;: The algorithm to use to sign the JWT (only usable when the secret is provided)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;provider&lt;/strong&gt;: The ID of service to call to provide the JWT (all other options will be ignored)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;factory&lt;/strong&gt;: The ID of service to call to create the JWT (all other options, besides subscribe, and publish will be ignored)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;value&lt;/strong&gt;: the raw JWT to use (all other options will be ignored)&lt;/p&gt;

&lt;p&gt;Automatically inside your .env will be updated with environment variables.&lt;/p&gt;

&lt;p&gt;If you are using a Symfony version less than 6, the YAML file doesn’t exist and you need only to configure your environment variables into the .env file 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;MERCURE_URL=[http://localhost:9090/.well-known/mercure](http://localhost:9090/.well-known/mercure)  
MERCURE_PUBLIC_URL=[http://localhost:9090/.well-known/mercure](http://localhost:9090/.well-known/mercure)  
MERCURE_JWT_SECRET=”JWT-AuctionEngine”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Using a specific Docker container
&lt;/h1&gt;

&lt;p&gt;You can use an official docker for your local environment, with a simple configuration 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;version: "3.5"
services:  
  mercure:  
    container_name: mercure_sse_poc  
    image: dunglas/mercure  
    environment:  
      SERVER_NAME: ':80'  
      MERCURE_PUBLISHER_JWT_KEY: 'JWT-AuctionEngine'  
      MERCURE_SUBSCRIBER_JWT_KEY: 'JWT-AuctionEngine'  
      MERCURE_CORS_ALLOWED_ORIGINS: '*'  
      MERCURE_EXTRA_DIRECTIVES: |-  
      cors_origins "*"  
      anonymous 1  
    ports:  
      — "9090:80"  
      — "4433:443"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;JWT_KEY&lt;/strong&gt;  must be the same as your environment variables, in this little example, I declare that it’s not necessary to be authenticated and you can use Mercure from all domains.&lt;br&gt;&lt;br&gt;
&lt;em&gt;In production, I recommend restricting those parameters to avoid undesired problems.&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  How to use Symfony/Mercure
&lt;/h1&gt;

&lt;p&gt;To send data to your client you need to instantiate a Mercure object called  &lt;strong&gt;Update&lt;/strong&gt;  with 2 arguments: the topic name where you want to send your data, and the data encoded.&lt;br&gt;&lt;br&gt;
After that, you can publish your event using an object that implements HubInterface (for this example).&lt;br&gt;&lt;br&gt;
But symfony/mercure has already its implementation so you can use it without writing your implementation.&lt;br&gt;&lt;br&gt;
Here is a little example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function send(Request $request, HubInterface $hub): void  
{  
    $update = new Update(  
       'channelname',  
       json_encode([  
           'foo' =&amp;gt; 'bar'  
       ], JSON_THROW_ON_ERROR)  
    );  
    $hub-&amp;gt;publish($update);  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The object Update has different arguments (directly from  &lt;a href="https://mercure.rocks/spec" rel="noopener noreferrer"&gt;https://mercure.rocks/spec&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;topic&lt;/strong&gt;: The identifiers of the updated topic. It is RECOMMENDED to use an IRI as an identifier. If this name is present several times, the first occurrence is considered to be the canonical IRI of the topic, and other ones are considered to be alternate IRIs. The hub MUST dispatch this update to subscribers that are subscribed to both canonical or alternate IRIs.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;data (optional)&lt;/strong&gt;: the content of the new version of this topic.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;private (optional):&lt;/strong&gt;  if this name is set, the update MUST NOT be dispatched to subscribers not authorized to receive it. See authorization. It is recommended to set the value to on but it CAN contain any value including an empty string.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;id (optional):&lt;/strong&gt;  the topic’s revision identifier: it will be used as the SSE’s id property. The provided id MUST NOT start with the # character. The provided id SHOULD be a valid IRI. If omitted, the hub MUST generate a valid IRI (RFC3987). A UUID (RFC4122) or a DID MAY be used. Alternatively, the hub MAY generate a relative URI composed of a fragment (starting with #). This is convenient to return an offset or a sequence that is unique for this hub. Even if provided, the hub MAY ignore the id provided by the client and generate its id.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;type (optional):&lt;/strong&gt; the SSE’s event property (a specific event type).&lt;br&gt;&lt;br&gt;
&lt;strong&gt;retry (optional):&lt;/strong&gt;  the SSE’s retry property (the reconnection time).&lt;/p&gt;
&lt;h1&gt;
  
  
  Frontend
&lt;/h1&gt;

&lt;p&gt;The frontend client needs to subscribe to the topic, the following example is a piece of a React component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const url = '[http://127.0.0.1:9090/.well-known/mercure?topic=auctions-1](http://127.0.0.1:9090/.well-known/mercure?topic=auctions-1`)';  
const eventSource = new EventSource(url);eventSource.onmessage = event =&amp;gt; {  
  const results = JSON.parse(event.data);  
  console.log(results);  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use this code for example in a  &lt;strong&gt;UseEffect&lt;/strong&gt;  function of  &lt;strong&gt;React&lt;/strong&gt;  and you are telling that you want to subscribe to the topic auctions-1 and every event sent to that channel you will print it into the console to see what you have received and you can use those data for whatever you want.&lt;/p&gt;

&lt;h1&gt;
  
  
  What happens?
&lt;/h1&gt;

&lt;p&gt;I have written a little example here to understand well what happens:  &lt;a href="https://github.com/AlessandroMinoccheri/sse-poc" rel="noopener noreferrer"&gt;https://github.com/AlessandroMinoccheri/sse-poc&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Now if you clone the repository and follow the instructions to install the backend and frontend you can visit the page:  &lt;a href="http://localhost:8080/" rel="noopener noreferrer"&gt;http://localhost:8080/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
You can see a simple form to submit a bid offer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1042%2F1%2AEjhRNwVbA7xURsQv3eSy-A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1042%2F1%2AEjhRNwVbA7xURsQv3eSy-A.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, if you open the browser network, select Fetch/XHR (for Chrome), and reload the page you can see a subscription request to a specific topic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2ASCr03xPU8M1P9sr8KLSq5A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2ASCr03xPU8M1P9sr8KLSq5A.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, if you insert a number into the text field and click the button to make a bid, you can see in the network tab a new POST request for the bid, but inside the previous request in the tab Events, you can see a new event sent by the server with new information!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1134%2F1%2A9IQWIX9vqnOutq_aoDuncw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1134%2F1%2A9IQWIX9vqnOutq_aoDuncw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So in the same subscription request, we can receive events for the server, for this reason, the Server-Sent events approach is considered a monodirectional communication because is the server that sends data to the client, and the client decides only to subscribe to topics.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2Au4A0xUxn7RXwKUqRtqTLIw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2Au4A0xUxn7RXwKUqRtqTLIw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you make other bids you can see in the tab events all data sent from the server in the same HTPP connection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1190%2F1%2AAfTT8Nc0niKjR5FEE5tehw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1190%2F1%2AAfTT8Nc0niKjR5FEE5tehw.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Subscribe to multiple topics
&lt;/h1&gt;

&lt;p&gt;Is it possible for the client to subscribe to multiple topics? Yes, absolutely, but how?&lt;br&gt;&lt;br&gt;
Well, you can easily do this thing into your frontend app (in this example using React):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const url = '[http://127.0.0.1:9090/.well-known/mercure?topic=auctions-1](http://127.0.0.1:9090/.well-known/mercure?topic=auctions-1`)';  
const eventSource = new EventSource(url);eventSource.onmessage = event =&amp;gt; {  
  const results = JSON.parse(event.data);  
  console.log(results);  
}const anotherUrl = '[http://127.0.0.1:9090/.well-known/mercure?topic=anotherTopic](http://127.0.0.1:9090/.well-known/mercure?topic=anotherTopic`)';  
const anotherEventSource = new EventSource(anotherUrl);anotherEventSource.onmessage = event =&amp;gt; {  
  const results = JSON.parse(event.data);  
  console.log(results);  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can subscribe to many topics in this way because the server will send data to a specific topic.&lt;br&gt;&lt;br&gt;
You can use this approach to create a private topic for a single user, or group of users to send events only to them.&lt;/p&gt;
&lt;h1&gt;
  
  
  Asynchronous dispatching
&lt;/h1&gt;

&lt;p&gt;You can write your implementation to dispatch asynchronous events, but this is not recommended because  &lt;strong&gt;Mercure&lt;/strong&gt;  already sends them asynchronously.&lt;br&gt;&lt;br&gt;
But if you want, you can use  &lt;strong&gt;Symfony Messenger&lt;/strong&gt;  to dispatch it by yourself.&lt;br&gt;&lt;br&gt;
Let’s see how the previous example could be with your own implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function send(Request $request, MessageBusInterface $customBus): void  
{  
   $update = new Update(  
      'channelname',  
      json_encode([  
          'foo' =&amp;gt; 'bar'  
      ], JSON_THROW_ON_ERROR)  
   );  
   $customBus-&amp;gt;publish($update);  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see the code doesn’t change, you can use a different implementation.&lt;br&gt;&lt;br&gt;
But remember that  &lt;strong&gt;Mercure already sends events asynchronously&lt;/strong&gt;  so it depends on you if you want to maintain by yourself the dispatching system.&lt;/p&gt;

&lt;h1&gt;
  
  
  Use Case Examples
&lt;/h1&gt;

&lt;p&gt;There are many examples of using the Server-Sent events approach.&lt;br&gt;&lt;br&gt;
Imagine that you need to build a stock option client, the frontend application can subscribe to topics to receive data from the server only when a stock quote changes its value.&lt;br&gt;&lt;br&gt;
Or if you need to build a Twitter feed update, the server will send data when to every user (with a custom topic each) with new tweets.&lt;br&gt;&lt;br&gt;
Recently I built a push notification system where clients receive information and updates from the server like the common push notifications app on your phone.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusions
&lt;/h1&gt;

&lt;p&gt;There are a lot of useful resources and examples, in my opinion using symfony/mercure library has simplified my life because in some minutes you can create a system ready to send events to the client without a lot of configurations and code to do.&lt;br&gt;&lt;br&gt;
Using the right tool can be important to the success of the project, but to know it you don’t have to start from the implementation.&lt;/p&gt;

&lt;p&gt;Start understanding what is the real problem to solve, I usually do an  &lt;strong&gt;EventStorming&lt;/strong&gt; before coding because we need to know the domain and business logic.&lt;/p&gt;

&lt;p&gt;After that, you can understand better if Server-Sent Events is the right approach or not.&lt;/p&gt;

</description>
      <category>sse</category>
      <category>php</category>
      <category>symfony</category>
      <category>mercure</category>
    </item>
    <item>
      <title>WebSocket vs Server-Sent events</title>
      <dc:creator>AlessandroMinoccheri</dc:creator>
      <pubDate>Fri, 29 Apr 2022 08:25:37 +0000</pubDate>
      <link>https://forem.com/minompi/websocket-vs-server-sent-events-2b77</link>
      <guid>https://forem.com/minompi/websocket-vs-server-sent-events-2b77</guid>
      <description>&lt;p&gt;Usually, I have heard more times the term WebSocket than server-sent events.&lt;/p&gt;

&lt;p&gt;The reason could be that &lt;strong&gt;WebSocket is used more&lt;/strong&gt;, but not always is the ideal approach.&lt;br&gt;
Sometimes Server-sent events approach is better to solve problems and create good applications.&lt;/p&gt;

&lt;p&gt;It’s very important to understand differences, limits, and ideal cases for both to solve your problem with the right solution.&lt;br&gt;
Sometimes we have a cognitive bias that doesn’t allow us to take the right decision.&lt;br&gt;
&lt;strong&gt;Cognitive bias&lt;/strong&gt; is a systematic error in thinking that occurs when people are processing and interpreting information in the world around them and affects the decisions and judgments that they make.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F1%2AAgap4Upvp4UoSb6ODSU9Og.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F1%2AAgap4Upvp4UoSb6ODSU9Og.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Image from &lt;a href="https://uxdesign.cc/how-to-improve-experience-design-by-managing-cognitive-biases-d7b360d35b0a" rel="noopener noreferrer"&gt;https://uxdesign.cc/how-to-improve-experience-design-by-managing-cognitive-biases-d7b360d35b0a&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So, for example, if we have solved a problem using WebSocket, next time with a similar problem we could think that, again, it’s the right approach without considering the big picture, all information about the problem to solve.&lt;br&gt;
For that reason, understanding deeply bot approaches can help us to reduce the cognitive bias and make the best decision.&lt;/p&gt;

&lt;p&gt;Let’s try to explain both approaches and their characteristics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Websocket
&lt;/h2&gt;

&lt;p&gt;It’s a computer communications protocol, that provides full-duplex communication channels over a single TCP connection (Wikipedia). The protocol was standardized in 2011.&lt;/p&gt;

&lt;p&gt;The WebSocket approach is used in many contexts and projects because has many benefits and pros in its favor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bidirectional communication
&lt;/h3&gt;

&lt;p&gt;The client and server can both send data to the other part.&lt;br&gt;
The client creates a TCP connection to the server and keeps it open as long as needed. &lt;br&gt;
Both server and client can close the connection easily whenever they want.&lt;br&gt;
To exchange data there is a &lt;strong&gt;handshake process&lt;/strong&gt; that verifies the communication, and if it’s all ok, they can exchange data using the custom WebSocket protocol.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Ad_oB1Vst-wjJ6snOrUvuaQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Ad_oB1Vst-wjJ6snOrUvuaQ.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Image from: &lt;a href="https://www.onlyfullstack.com/polling-vs-server-sent-events-vs-websocket/" rel="noopener noreferrer"&gt;https://www.onlyfullstack.com/polling-vs-server-sent-events-vs-websocket/&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Bidirectional communication in real-time, connections can both send and receive data from the browser(example: chat).&lt;/li&gt;
&lt;li&gt;Generally don’t use XmlHttpRequest and headers are not sent every time, so it reduces the expensive data loads being sent to the server.&lt;/li&gt;
&lt;li&gt;Can transmit both binary data and UTF-8 format.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Limits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;When connections are terminated, WebSocket doesn’t automatically recover them, you need to implement a reconnection system by yourself.&lt;/li&gt;
&lt;li&gt;Browsers older than 2011 don’t support WebSocket connections.&lt;/li&gt;
&lt;li&gt;Some enterprise firewalls with packet inspection have trouble dealing with WebSocket.&lt;/li&gt;
&lt;li&gt;It cannot be placed behind container-based authentication methods with header-based security, it has to be query parameters (or hopefully, a token-based authentication where the token is established outside the WebSocket path).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ideal cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Chat: both client and server exchange data to send and receive messages&lt;/li&gt;
&lt;li&gt;Multiplayer games&lt;/li&gt;
&lt;li&gt;Collaborative editing/coding&lt;/li&gt;
&lt;li&gt;Social feeds&lt;/li&gt;
&lt;li&gt;Sport updates&lt;/li&gt;
&lt;li&gt;… a lot more …&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Server-Sent Events
&lt;/h2&gt;

&lt;p&gt;It’s a server push technology enabling a client to receive automatic updates from a server via an HTTP connection. &lt;br&gt;
It was born on September 1, 2006, so it’s been a while since it’s available.&lt;br&gt;
It provides a memory-efficient implementation of XHR streaming. &lt;br&gt;
Unlike a raw XHR connection, which buffers the full received response until the connection is dropped, an SSE connection can discard processed messages without accumulating all of them in memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monodirectional communication
&lt;/h3&gt;

&lt;p&gt;The client sends a request to subscribe to a specific channel and the server will send event/data into that request, so only the server can send data and the client receive automatically those events in the same HTTP connection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AUg-BosrJefTOOEBmtA2H4Q.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AUg-BosrJefTOOEBmtA2H4Q.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Image from: &lt;a href="https://www.onlyfullstack.com/polling-vs-server-sent-events-vs-websocket/" rel="noopener noreferrer"&gt;https://www.onlyfullstack.com/polling-vs-server-sent-events-vs-websocket/&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Transported over simple HTTP instead of a custom protocol&lt;/li&gt;
&lt;li&gt;Simpler protocol&lt;/li&gt;
&lt;li&gt;Built-in support for re-connection and event-id&lt;/li&gt;
&lt;li&gt;No troubles with corporate firewalls doing packet inspection&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Limits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It’s limited to UTF-8 and does not support binary data.&lt;/li&gt;
&lt;li&gt;When not used over HTTP/2, Server-Sent events approach is subject to limitations with regard to the maximum number of open connections. This can be especially painful when opening various tabs as the limit is per browser and set to a very low number (6).&lt;/li&gt;
&lt;li&gt;It’s mono-directional&lt;/li&gt;
&lt;li&gt;It doesn’t have native browser support. However, there are available workaround with poly-fill (replicate an API) in Javascript that simulates the SSE functionality to solve this issue. All modern browsers support server-sent events: Firefox 6+, Google Chrome 6+, Opera 11.5+, Safari 5+, Microsoft Edge 79+.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ideal cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Stock client updates: the client receives updates from the server when a stock changes its value&lt;/li&gt;
&lt;li&gt;Twitter feed updates: the client receives a new tweet every time one is sent&lt;/li&gt;
&lt;li&gt;push notifications&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, &lt;strong&gt;both approaches are valid&lt;/strong&gt; and can be used to build specific software.&lt;br&gt;
Websocket is more used and can be used also to develop an application that can use Server-sent events.&lt;br&gt;
Server-sent Events have fewer ideal cases but for them, it’s very useful with less configuration and less time to create the updating system.&lt;/p&gt;

&lt;p&gt;I have used both of them and no one is better than another, it depends on the specific context and what you need at that moment.&lt;/p&gt;

&lt;p&gt;Knowing WebSocket and Server-sent events can help you in deciding which approach is better for every application.&lt;/p&gt;

</description>
      <category>bias</category>
      <category>websocket</category>
      <category>sse</category>
      <category>decision</category>
    </item>
    <item>
      <title>How to test Github Actions locally</title>
      <dc:creator>AlessandroMinoccheri</dc:creator>
      <pubDate>Mon, 07 Mar 2022 13:34:47 +0000</pubDate>
      <link>https://forem.com/minompi/how-to-test-github-actions-locally-3ipk</link>
      <guid>https://forem.com/minompi/how-to-test-github-actions-locally-3ipk</guid>
      <description>&lt;p&gt;One of the first things that I do in a project is to create a CD/CI process using Github Actions usually.&lt;br&gt;
Why?&lt;br&gt;
Because I would like to deploy as soon as possible with a process that launches tests for me automatically to understand if I can merge the feature and deploy it.&lt;br&gt;
Nowadays Github Actions has a lot of integrations, tools, and containers to run your application.&lt;/p&gt;

&lt;p&gt;But every time you create a Github Actions you need to test it and usually, you try to commit something to trigger it, you are testing manually your CD/CI.&lt;br&gt;
For me it’s like testing my application manually, clicking buttons instead of automatic tests.&lt;/p&gt;

&lt;p&gt;For this reason for me, it’s important to test my Github Actions without committing something because it’s not necessary.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A7Z5NDciyXIzGK791LriXrQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A7Z5NDciyXIzGK791LriXrQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://www.giuseppemaccario.com/it/continuous-deployment-con-github-actions-su-server-condiviso/" rel="noopener noreferrer"&gt;https://www.giuseppemaccario.com/it/wp-content/uploads/2021/10/Continuous-Deployment-con-GitHub-Actions.png&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I found this library perfect for testing Github Actions: &lt;a href="https://github.com/nektos/act" rel="noopener noreferrer"&gt;act&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This library is very useful and easy to use, you can run locally your Github Actions and you have fast feedback on your workflows.&lt;/p&gt;
&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;Act simulates the actions we would like to perform in the container of our Github Actions.&lt;br&gt;
It creates a container capable of performing all the steps by properly simulating all the steps.&lt;br&gt;
So we can see all the steps of the Github Actions and their results through simple instruction.&lt;/p&gt;
&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;If you are using Homebrew (Linux, macOS) you can launch this command from your CLI:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;If you are not using Homebrew I recommend checking the Installation section inside the README file of the project because there are many ways and options to add it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it
&lt;/h2&gt;

&lt;p&gt;To run the tool you need to write into your CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;act
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command runs the default (&lt;code&gt;push&lt;/code&gt;) event.&lt;br&gt;
When you run for the first time act, it will ask you to choose an image to be used as default and it will save that information inside the file ~/.actrc that contains configuration flags.&lt;/p&gt;

&lt;p&gt;If you want to run a specific event you can launch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;act pull_request
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the specific event, I mean Github Events: &lt;a href="https://docs.github.com/en/developers/webhooks-and-events/events/github-event-types" rel="noopener noreferrer"&gt;https://docs.github.com/en/developers/webhooks-and-events/events/github-event-types&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To run a specific job you can launch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;act -j your_job
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also launch command in dry mode 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;act -n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Environment variables and Secret variables
&lt;/h2&gt;

&lt;p&gt;Secrets and environment variables saved in GitHub can’t be used by act, but you can pass them and define them locally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secrets
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;act -s KEY=VALUE — To pass secret from CLI
act — secret-file my.secrets — load secrets values from local.secrets file.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Environment variables
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;act -n KEY=VALUE — To pass environment variable from CLI
act — env-file my.env — load environment variables from local.env file.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use Case
&lt;/h2&gt;

&lt;p&gt;I have used act many times in these months because I created many Github actions for my projects.&lt;br&gt;
Every time that I change something I tried the action with &lt;strong&gt;act&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So, for me, it’s better to test it locally to save a lot of time.&lt;br&gt;
The process could be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create your first Github Actions&lt;/li&gt;
&lt;li&gt;launch act to test changes&lt;/li&gt;
&lt;li&gt;improve or fix your Github Actions&lt;/li&gt;
&lt;li&gt;launch act to test changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And then you can iterate until you are satisfied with your Githu Action.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;I have created a simple example to test act and you can find it following this link: &lt;a href="https://github.com/AlessandroMinoccheri/act-example" rel="noopener noreferrer"&gt;https://github.com/AlessandroMinoccheri/act-example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s a simple example to test act and it took me 2 minutes to install and launch &lt;strong&gt;act&lt;/strong&gt;.&lt;br&gt;
It’s very useful to see the output of your GitHub Actions to understand if it’s all ok or not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limit
&lt;/h2&gt;

&lt;p&gt;There are a few limitations by using act (&lt;a href="https://github.com/nektos/act#known-issues" rel="noopener noreferrer"&gt;https://github.com/nektos/act#known-issues&lt;/a&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Non-Linux Runners: act can works for Linux runners, not for the others, but it’s a Docker limitation on your workstation.
You can work around this by setting &lt;strong&gt;DOCKER_HOST&lt;/strong&gt; before running act, with e.g:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export DOCKER_HOST=$(docker context inspect — format ‘{{.Endpoints.docker.Host}}’)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Default images do not contain intentionally all the tools that GitHub Actions offers by default in their runners.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In my opinion, &lt;strong&gt;act can save you a lot of time to test your Github Actions without launching them every time&lt;/strong&gt;.&lt;br&gt;
It’s very easy and fast to use. &lt;br&gt;
Usually, when you are running act and all it’s fine your Github Actions will not have problems.&lt;/p&gt;

</description>
      <category>tests</category>
      <category>improvements</category>
      <category>github</category>
    </item>
    <item>
      <title>2021 Recap and 2022 Goals</title>
      <dc:creator>AlessandroMinoccheri</dc:creator>
      <pubDate>Thu, 27 Jan 2022 07:37:19 +0000</pubDate>
      <link>https://forem.com/minompi/2021-recap-and-2022-goals-74h</link>
      <guid>https://forem.com/minompi/2021-recap-and-2022-goals-74h</guid>
      <description>&lt;p&gt;At the end of every year usually, I check my goals for the current year and I set them for the next year.&lt;br&gt;
This is an activity that helps me to improve my skill build step by step career.&lt;/p&gt;

&lt;p&gt;Building a &lt;strong&gt;career&lt;/strong&gt; it’s difficult sometimes because you don’t know what you want next or what you want to achieve. &lt;br&gt;
For this reason, I take some days to understand it and try to design the next steps for my career.&lt;br&gt;
Sometimes I need to change a lot of things but it’s important to follow our dream.&lt;/p&gt;

&lt;p&gt;Remember that a career is more than a job and every company (or most of them) is hiring developers.&lt;/p&gt;

&lt;p&gt;So my goals for 2021 were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;read more than 30 books&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;learn React&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;5 meetup as a speaker&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;write at least 5 articles&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;release phparkitect&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D9vXueMl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/9856/1%2AUwElkoF1DiRkOHXeB2_pSg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D9vXueMl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/9856/1%2AUwElkoF1DiRkOHXeB2_pSg.jpeg" alt="" width="880" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Read more than 30 books
&lt;/h2&gt;

&lt;p&gt;I have read a lot of articles about: &lt;br&gt;
“You need to read at least 20 books, 30 books 50 books..”&lt;/p&gt;

&lt;p&gt;I have taken this advice and I set the goal of 30 books for 2021.&lt;br&gt;
In the first three months, I read about 8 books and I was really happy about it.&lt;br&gt;
But I decided to think about this behavior and what I’m trying to achieve in 2021.&lt;/p&gt;

&lt;p&gt;My goal is not to read 30 books, my goal is to improve my skill, get a new point of view. So my goal is to learn not to read books only to check from my list this goal.&lt;/p&gt;

&lt;p&gt;I decided to stop for a moment and change this behavior. &lt;br&gt;
After that, I take my books and I continue to reading them more slowly, getting notes and thinking about what they try to share.&lt;br&gt;
I have created a template in &lt;strong&gt;&lt;a href="https://www.notion.so/"&gt;Notion&lt;/a&gt;&lt;/strong&gt; to track my books and notes inside.&lt;br&gt;
I started to create a visual mapping with &lt;strong&gt;&lt;a href="https://miro.com/"&gt;Miro&lt;/a&gt;&lt;/strong&gt; and at the end of the year I don’t achieve my goal of 30 books, I read 18 books but I am really satisfied with what I have learned in a year.&lt;/p&gt;

&lt;p&gt;So it’s time to share the 3 best books that I have read this year:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Antifragile_(book)"&gt;Antifragile&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://startup-scaleup-screwup.com/"&gt;Startup, Scaleup, Screwup&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/The_Goal_(novel)"&gt;The goal&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Learn React
&lt;/h2&gt;

&lt;p&gt;Another goal for my 2021 was to learn &lt;strong&gt;React&lt;/strong&gt;, and to learn React I meant to write a single page application with components and test obviously.&lt;br&gt;
I have reached the goal before June following some articles and tutorials.&lt;br&gt;
I did an application useful to manage my bank account.&lt;/p&gt;

&lt;p&gt;I started watching some tutorials and create my first react &lt;strong&gt;Kata project&lt;/strong&gt;.&lt;br&gt;
A Kata is a project to learn something new without thinking about the idea. You can try new approaches, frameworks, and languages.&lt;/p&gt;

&lt;p&gt;My first kata project with React was a simple to-do list where I had to create a list, edit it and view it.&lt;br&gt;
After this, I have complicated the to-do list project with some features to understand well hooks and best practices.&lt;/p&gt;

&lt;h2&gt;
  
  
  5 meetup as a speaker
&lt;/h2&gt;

&lt;p&gt;In 2021 I did exactly 5 talks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=jAmRsz1GpTQ"&gt;PugRomagna&lt;/a&gt; 2 talks about hexagonal architecture in &lt;strong&gt;Symfony&lt;/strong&gt; and another one about smart working&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.jugmilano.it/"&gt;JUG Milano&lt;/a&gt; about hexagonal architecture in &lt;strong&gt;Kotlin&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.meetup.com/it-IT/Ticino-Software-Craft/"&gt;Ticino Software Craft &lt;/a&gt;about hexagonal architecture in &lt;strong&gt;Kotlin&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://roma.grusp.org/"&gt;PugRoma&lt;/a&gt; about hexagonal architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Speaking activities are moments where you share something with other people but you are learning at the same time because you need to study concepts deeply to explain them to others.&lt;br&gt;
It’s important to open your mind to questions and different points of view.&lt;br&gt;
Every time that I did a talk I learned something and I met a lot of clever developers, I recommend to all the developers to try to share their knowledge with others because it’s a moment to network and learn together every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write at least 5 articles
&lt;/h2&gt;

&lt;p&gt;In 2021 I wrote&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://dev.to/minompi/why-you-should-deploy-on-friday-without-fear-3c2p"&gt;Why you should deploy on Friday without fear&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://dev.to/minompi/how-dotfiles-can-save-you-a-lot-of-time-55oe"&gt;How dotfiles can save you a lot of time&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://dev.to/minompi/push-and-publish-docker-images-with-github-actions-8a3"&gt;Push and publish Docker images with GitHub Actions&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://dev.to/minompi/learning-a-new-programming-language-1d2j"&gt;Learning a new programming language&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://dev.to/minompi/phparkitect-put-your-architectural-rules-under-test-1c99"&gt;PHPArkitect: Put your architectural rules under test!&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It was very interesting to write these articles because explaining to others in a fluent and clear article sometimes could be difficult. &lt;br&gt;
I tried to write small articles and answer all their questions.&lt;br&gt;
Sometimes people contact me in private asking for advice or doubts about the article and their projects, and I am very happy to answer them and ask for a different point of view if it’s possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Release PHParkitect
&lt;/h2&gt;

&lt;p&gt;The last goal was to release &lt;strong&gt;&lt;a href="https://github.com/phparkitect/arkitect"&gt;PHPArkitect&lt;/a&gt;&lt;/strong&gt; in 2021.&lt;br&gt;
It’s a library that helps you to keep your &lt;strong&gt;PHP&lt;/strong&gt; codebase coherent and solid, by permitting you to add some architectural constraint check to your workflow.&lt;br&gt;
The team is made up of a couple of people and I am one of them.&lt;br&gt;
We developed the tool all year and we released it to all the world in May.&lt;br&gt;
Nowadays we are working to improve the library day by day and at the moment we are using it in some projects.&lt;br&gt;
I think that there are a lot of features to be done to improve the library.&lt;/p&gt;

&lt;p&gt;Feel free to try it and give me feedback, please!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d0gmcV1l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AHmezHW5GToSSYUl3pl17UA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d0gmcV1l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AHmezHW5GToSSYUl3pl17UA.jpeg" alt="" width="666" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Goals 2022
&lt;/h2&gt;

&lt;p&gt;For 2022 I take some hours and I walk alone to understand what I would like to achieve next year.&lt;br&gt;
Learning sometimes could be easy but focusing on the right things it’s difficult.&lt;/p&gt;

&lt;p&gt;I thought about my career path and what I can do in the next years and I understand that this year I would like to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;learn typescript because I think that it could be a good solution for many projects&lt;/li&gt;
&lt;li&gt;read books that can help me to improve my hard skill and soft skill. I wrote a list of books that can help me, and these are the first two books that I will read: &lt;strong&gt;&lt;a href="https://www.amazon.com/Clean-Craftsmanship-Disciplines-Standards-Ethics/dp/013691571X"&gt;Clean Craftsmanship&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href="https://www.amazon.com/Learning-Domain-Driven-Design-Aligning-Architecture/dp/1098100131/ref=sr_1_1?crid=3ATPWKPGJ322M&amp;amp;keywords=Learning+Domain-Driven+Design&amp;amp;qid=1643268343&amp;amp;s=books&amp;amp;sprefix=learning+domain-driven+design%2Cstripbooks-intl-ship%2C152&amp;amp;sr=1-1"&gt;Learning Domain-Driven Design&lt;/a&gt;&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;do at least 3 talks to continue my career as a speaker &lt;/li&gt;
&lt;li&gt;write at least 10 articles to share my knowledge and to understand deeply some concepts to share&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the moment these are my goals for 2022, I have scheduled some moments to check every point, and write down a path to achieve them during the year.&lt;br&gt;
It’s important not only to understand your goal but it’s important to measure them and create a path to understand how to achieve them.&lt;/p&gt;

&lt;p&gt;To do it you need to ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What is the definition of done to understand if this goal is achieved or not?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How can I achieve this goal?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Answering these questions you can understand well your next steps to improve yourself and your career.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating your career&lt;/strong&gt; it’s one of the most difficult things to do because it depends on you usually.&lt;br&gt;
You need to understand where do you want to go and what are next steps to achieve your goals.&lt;/p&gt;

&lt;p&gt;It’s a never-ending path but could be amazing, it depends on you!&lt;/p&gt;

</description>
      <category>career</category>
      <category>improvements</category>
      <category>goals</category>
    </item>
    <item>
      <title>PHPArkitect: Put your architectural rules under test!</title>
      <dc:creator>AlessandroMinoccheri</dc:creator>
      <pubDate>Mon, 03 Jan 2022 10:50:55 +0000</pubDate>
      <link>https://forem.com/minompi/phparkitect-put-your-architectural-rules-under-test-1c99</link>
      <guid>https://forem.com/minompi/phparkitect-put-your-architectural-rules-under-test-1c99</guid>
      <description>&lt;p&gt;In every project there is at least an architectural rule usually like: every class inside Controller directory should be called with suffix Controller.&lt;/p&gt;

&lt;p&gt;I have seen a lot of projects in my career with many different types of rules.&lt;br&gt;
Other examples could be when a team tries to apply the hexagonal architecture and inside the domain, you shouldn’t call external libraries or framework classes (there are exceptions but this is out of scope).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F12000%2F1%2AXKzTR8rLmh8ZCRC6xD9ACg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F12000%2F1%2AXKzTR8rLmh8ZCRC6xD9ACg.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Usually, a team shares those rules during retrospective or dedicated moments to improve the software and to establish rules to follow.&lt;br&gt;
But after some months usually, those rules could be violated by new members of the team or someone that doesn’t remember them.&lt;br&gt;
So the next step is to write down into a README file or in a file all the rules but again they can be violated.&lt;/p&gt;

&lt;p&gt;Another good solution is to write &lt;strong&gt;ADR&lt;/strong&gt;: &lt;a href="https://adr.github.io/" rel="noopener noreferrer"&gt;Architectural Decision Records&lt;/a&gt; that explain the choice and the reason, but still, they can guarantee that will not be violated.&lt;/p&gt;

&lt;p&gt;You need a tool to validate your architectural rules.&lt;br&gt;
&lt;a href="https://github.com/phparkitect/arkitect" rel="noopener noreferrer"&gt;PHPArkitect&lt;/a&gt; can do it for you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PHPArkitect&lt;/strong&gt; is a tool that helps you to keep your PHP codebase coherent and solid, by permitting you to add some architectural constraint check to your workflow.&lt;br&gt;
It was born in 2020 to satisfy the need to respect architectural rules in various projects.&lt;br&gt;
In Java there is a similar tool from which we took inspiration: &lt;a href="https://www.archunit.org/" rel="noopener noreferrer"&gt;archunit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now PHPArkitect is public and you can find it &lt;a href="https://github.com/phparkitect/arkitect" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Which problem is trying to solve PHPArkitect?
&lt;/h2&gt;

&lt;p&gt;As I explained before, PHPArkitect was born to help teams to define architectural rules in a project.&lt;br&gt;
With this tool, you can add a new step with it into your continuous integration and you have all your architectural rules in a file, so new developers can understand easily the constraints of the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to install it?
&lt;/h2&gt;

&lt;p&gt;To install PHPArkitect you can use composer launching this command into your CLI:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require — dev phparkitect/phparkitect
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can also use a &lt;strong&gt;.phar&lt;/strong&gt; file because you can have some conflicts with one or more of Phparkitect’s dependencies.&lt;br&gt;
The Phar can be downloaded from GitHub:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wget [https://github.com/phparkitect/arkitect/releases/latest/download/phparkitect.phar](https://github.com/phparkitect/arkitect/releases/latest/download/phparkitect.phar)
chmod +x phparkitect.phar
./phparkitect.phar check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  How can you use it?
&lt;/h2&gt;

&lt;p&gt;To use PHPArkitect it’s necessary to create a file inside your root called phparkitect.php with your rules written inside it like this:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

declare(strict_types=1);

use Arkitect\ClassSet;
use Arkitect\CLI\Config;
use Arkitect\Expression\ForClasses\HaveNameMatching;
use Arkitect\Expression\ForClasses\ResideInOneOfTheseNamespaces;
use Arkitect\Rules\Rule;

return static function (Config $config): void {
 $classSet = ClassSet::fromDir(__DIR__ . ‘/src’);
 $r1 = Rule::allClasses()
 -&amp;gt;that(new ResideInOneOfTheseNamespaces(‘App\Order\Infrastructure\Controller’))
 -&amp;gt;should(new HaveNameMatching(‘*Controller’))
 -&amp;gt;because(“we want uniform naming”);

$config-&amp;gt;add($classSet, $r1);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And now you can launch from your CLI the command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./vendor/bin/phparkitect check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you want to use a different name for your file you can specify it when you launch the command like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./vendor/bin/phparkitect check — config=/project/yourConfigFile.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  What can you do with PHPArkitect?
&lt;/h2&gt;

&lt;p&gt;With this tool, you can write your own rules for your project.&lt;br&gt;
At the moment you can check if a class:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;depends on a namespace&lt;/li&gt;
&lt;li&gt;extends another class&lt;/li&gt;
&lt;li&gt;not extend another class&lt;/li&gt;
&lt;li&gt;have a name matching a pattern&lt;/li&gt;
&lt;li&gt;not have a name matching a pattern&lt;/li&gt;
&lt;li&gt;implements an interface&lt;/li&gt;
&lt;li&gt;not implement an interface&lt;/li&gt;
&lt;li&gt;depends on a namespace&lt;/li&gt;
&lt;li&gt;don’t have dependency outside a namespace&lt;/li&gt;
&lt;li&gt;reside in a namespace&lt;/li&gt;
&lt;li&gt;not reside in a namespace&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s make some examples:&lt;/p&gt;

&lt;p&gt;Assume that if you want those classes inside a namespace that doesn’t depend on classes outside that namespace you can write this rule:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$rule = Rule::allClasses()
 -&amp;gt;that(new ResideInOneOfTheseNamespaces(‘App\Catalog\Domain’))
 -&amp;gt;should(new NotHaveDependencyOutsideNamespace(‘App\Catalog\Domain’))
 -&amp;gt;because(‘domain should not have external dependencies’);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you want to be sure that classes inside a namespace are following certain naming rules you write a rule like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$rule = Rule::allClasses()
 -&amp;gt;that(new ResideInOneOfTheseNamespaces(‘App\Order\Infrastructure\Controller’))
 -&amp;gt;should(new HaveNameMatching(‘*Controller’))
 -&amp;gt;because(“we want uniform naming”);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you want to be sure that all classes that extend a class are following certain naming rules you write a rule like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$rule = Rule::allClasses()
 -&amp;gt;that(new Extend(AbstractType::class))
 -&amp;gt;should(new HaveNameMatching(‘*Type’))
 -&amp;gt;because(‘we want uniform form type naming’);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can also exclude some classes from the rules for example:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$rule = Rule::allClasses()&lt;br&gt;
 -&amp;gt;exclude([‘App\Order\Application\Service\Foo’])&lt;br&gt;
 -&amp;gt;that(new ResideInOneOfTheseNamespaces(‘App\Order\Application\Service’))&lt;br&gt;
 -&amp;gt;should(new HaveNameMatching(‘*Service’))&lt;br&gt;
 -&amp;gt;because(“we want uniform naming”);&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  How to contribute&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;PHPArkitect it’s young at the moment and a lot of things could be developed.&lt;br&gt;
If you are interested you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;try the tool&lt;/li&gt;
&lt;li&gt;improve the documentation&lt;/li&gt;
&lt;li&gt;try to write your own rule&lt;/li&gt;
&lt;li&gt;open pull requests to fix bugs or to discuss new features with a draft&lt;/li&gt;
&lt;li&gt;open issues to ask something or to reveal a bug&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can help with a little effort to improve this project and help other developers.&lt;/p&gt;

</description>
      <category>rules</category>
      <category>php</category>
      <category>standards</category>
    </item>
    <item>
      <title>Learning a new programming language</title>
      <dc:creator>AlessandroMinoccheri</dc:creator>
      <pubDate>Fri, 05 Nov 2021 08:03:40 +0000</pubDate>
      <link>https://forem.com/minompi/learning-a-new-programming-language-1d2j</link>
      <guid>https://forem.com/minompi/learning-a-new-programming-language-1d2j</guid>
      <description>&lt;p&gt;In this period every day, a new programming language could be released and can become one of the most interesting in a few months.&lt;br&gt;
So it’s difficult for a developer to learn every day a new different programming language because you need the time to explore it.&lt;br&gt;
Many times other developers ask me: &lt;br&gt;
“How can I learn a new programming language?”&lt;/p&gt;

&lt;p&gt;Well in my opinion there isn’t the perfect recipe to learn a new programming language because it depends principally on how the developer can learn new things.&lt;br&gt;
Some people need to learn from books or others that prefer coding directly etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  SHU HA RI
&lt;/h2&gt;

&lt;p&gt;Before going deep into the argument, I would like to share the concept of SHU-HA-RI, because I think that it’s important to know when you start to learn something:&lt;/p&gt;

&lt;p&gt;Shu-ha-ri is a concept of Japanese martial arts and describes the stages from learning to mastery, therefore a path that involves the presence of a teacher accompanying a student.&lt;br&gt;
This concept was taken into Toyota to indicate the skills development model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AdtkMwR4AvquKXVUYpQcijw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AdtkMwR4AvquKXVUYpQcijw.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(image from:&lt;a href="https://leadagilesolutions.com.au/a-mental-model-for-the-phases-of-mastery/" rel="noopener noreferrer"&gt; https://leadagilesolutions.com.au/a-mental-model-for-the-phases-of-mastery/&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Shu-Ha-Ri is a way of thinking about how you learn a technique and can be divided into three steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step one: &lt;strong&gt;Shu&lt;/strong&gt;. The Sensei (the coach) protects the student by showing how to do it, without leaving room for errors and distortions. The practice must be performed as per the manual.&lt;/li&gt;
&lt;li&gt;Step Two: &lt;strong&gt;Ha&lt;/strong&gt;. The student, independently, applies the practices respecting the standard. Here the student will be wrong, but he will understand even more.&lt;/li&gt;
&lt;li&gt;Step Three: &lt;strong&gt;Ri&lt;/strong&gt;. The student applies the practice in complete autonomy, with strong creativity. He has understood the spirit and no longer feels “bound” by the rules. He might even revise the rules themselves.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach can be used in many different scopes: music, martial art, coding…&lt;/p&gt;

&lt;p&gt;Usually, when I would like to learn a new programming language I try to follow the Shu-ha-ri approach trying to divide my learning time into &lt;strong&gt;different steps&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read the documentation&lt;/li&gt;
&lt;li&gt;Watch videos &lt;/li&gt;
&lt;li&gt;Follow people on Twitter that shares context about that language&lt;/li&gt;
&lt;li&gt;Find a mentor&lt;/li&gt;
&lt;li&gt;Learning by Doing (kata)&lt;/li&gt;
&lt;li&gt;Contributing to open-source projects&lt;/li&gt;
&lt;li&gt;Teach What You Learn&lt;/li&gt;
&lt;li&gt;Be Curious&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Read the documentation
&lt;/h2&gt;

&lt;p&gt;Sometimes it’s very annoying to read the documentation of something but don’t under evaluate this step because reading the documentation is the first approach to a new language, to understand how it works, how you can start, what you need in terms of software, tools, libraries.&lt;br&gt;
Reading the “Get started” chapter, usually, helps you to enter into a new world and for me, it’s fantastic to see new things and how their work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You don’t have to read all the documentation&lt;/strong&gt;, my advice it’s to read the first parts, to understand how can you start to write something and step by step learn new things.&lt;br&gt;
Sometimes the documentation is not updated or is superficial, feel free to open a pull request or contact the support to improve that part.&lt;br&gt;
This is another good step to participate in something and learn new things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Watch videos
&lt;/h2&gt;

&lt;p&gt;Nowadays there are a lot of videos about all things.&lt;br&gt;
So it’s very common to find developers that share videos about the language that you would like to learn.&lt;br&gt;
I usually search for many videos or playlists and watch the first minutes to understand if the level of the video is correct or not for me at that moment.&lt;br&gt;
For example, six months ago I studied for a new language and I found an amazing video by an advocate of that language and I stopped that after 3 minutes because the level was too high for me at that moment.&lt;br&gt;
I marked the video as “&lt;strong&gt;Watch later&lt;/strong&gt;” and after two months I saw all the videos understanding all the things.&lt;br&gt;
It depends on your level and skills to find the best videos for that moment for you but believe me, you have a lot of options on the web nowadays to find the best video for you!&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow people on Twitter that shares context about that language
&lt;/h2&gt;

&lt;p&gt;Twitter is a social network where you can find a lot of developers that share powerful context about everything.&lt;br&gt;
My advice is to search for some developers that frequently share interesting content, and follow them.&lt;br&gt;
The next step is to interact with them to ask something to clarify your doubts.&lt;br&gt;
I have found a lot of kind developers that help me a lot and vice versa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find a mentor
&lt;/h2&gt;

&lt;p&gt;Finding a mentor sometimes seems difficult and impossible, but I can guarantee that it could be very easy.&lt;br&gt;
When I have to find a mentor, usually I am thinking of my colleagues or ex-colleagues first because I know already their skills.&lt;br&gt;
If no one has the required skills I am searching on Twitter for example or LinkedIn or participating in community meetings.&lt;br&gt;
When you will find your mentor it’s important to share with him your goals to set up your expectations.&lt;br&gt;
With him, you can establish a study plan to archive your goals.&lt;br&gt;
Once you have specified those things you need to schedule a meeting every one or two weeks with your mentor to check your progress.&lt;br&gt;
Don’t forget to ask a lot of things and thoughts in your mind to understand well what you are doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning by Doing
&lt;/h2&gt;

&lt;p&gt;Learning by doing it’s one of my favorite steps because I love to touch directly the code and find problems, things not clear and interesting points of view about this new language.&lt;br&gt;
It’s very important to practice a lot to become more confident with the new language.&lt;br&gt;
I usually create &lt;strong&gt;Kata projects&lt;/strong&gt; to make a lot of practice. &lt;br&gt;
Kata means “way of doing” and they are projects that you create yourself to learn something: new coding language, different approaches, architectures, etc.&lt;br&gt;
You can create a new little project and experiment with what you would like to explore.&lt;br&gt;
There are a lot of Kata projects and you can create your own, this is a list of possible kata:&lt;br&gt;
&lt;a href="https://project-awesome.org/gamontal/awesome-katas" rel="noopener noreferrer"&gt;https://project-awesome.org/gamontal/awesome-katas&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example. I did twenty times the Tic-tac-toe game because every time I tried new things and a new way of doing it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AwHIXPRtYgRXowiDj5CMZTg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AwHIXPRtYgRXowiDj5CMZTg.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Contributing to open-source projects
&lt;/h2&gt;

&lt;p&gt;Contributing to open-source projects could be another good solution to learn something about what you are studying, you can always ask questions creating issues or pull requests and you can try to create your first pull request starting from fixing some part of the documentation for example.&lt;br&gt;
Open source projects can generate a lot of value and a new strategy to implement something.&lt;br&gt;
You can write to contributors and maintainers to learn new things every day.&lt;br&gt;
Don’t be scared to try something, open source can open to you a lot of doors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Teach What You Learn
&lt;/h2&gt;

&lt;p&gt;After studying something it’s important to &lt;strong&gt;share your knowledge&lt;/strong&gt; with other developers. Try to teach what you have learned through a little talk with a few people or you can find a local meetup to try your new skills.&lt;br&gt;
When you try to explain something to others you can realize if you know the argument or not, you can realize what you can study and see things from another point of view by answering questions during your talk.&lt;br&gt;
Every time that I did a talk, after that, there were a lot of questions and we discussed those, understanding new approaches.&lt;/p&gt;

&lt;h2&gt;
  
  
  Be Curious
&lt;/h2&gt;

&lt;p&gt;Every day you can learn something new, there are a lot of resources nowadays.&lt;br&gt;
Now it’s up to you what you want to learn from today.&lt;br&gt;
Be curious about new approaches, technologies, and all the things about your work.&lt;br&gt;
Curiosity helps a developer with learning in two ways. First, it keeps you motivated during learning so you don’t get bored. Second, it highlights new learning opportunities that you would overlook.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Curiosity is what makes great engineers stand out from regular ones.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>learn</category>
      <category>learning</category>
      <category>agile</category>
    </item>
    <item>
      <title>Push and publish Docker images with GitHub Actions</title>
      <dc:creator>AlessandroMinoccheri</dc:creator>
      <pubDate>Sun, 02 May 2021 18:56:06 +0000</pubDate>
      <link>https://forem.com/minompi/push-and-publish-docker-images-with-github-actions-8a3</link>
      <guid>https://forem.com/minompi/push-and-publish-docker-images-with-github-actions-8a3</guid>
      <description>&lt;p&gt;In many articles, I mentioned many times about using &lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Actions&lt;/strong&gt;&lt;/a&gt; because they are a good choice for a lot of reasons.&lt;/p&gt;

&lt;p&gt;Nowadays I can admit that there is another choice that I have explored and used a lot these days.&lt;br&gt;
What I mean is the functionality of &lt;strong&gt;pushing your docker image through your GitHub Actions during your CI process.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Usually, when I want to publish my docker images to DockerHub, I need to do it manually by the command line, like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building the image&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker image build -t organization/project:0.1.0 .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Publishing to DockerHub&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker push organization/project:0.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s not a lot of work, but every time you fix or add a new feature you need to remember to build a new image and publish it.&lt;br&gt;
Usually, &lt;strong&gt;I try to avoid manual operations&lt;/strong&gt; because human error is possible, and automating what is repetitive for me is a best practice everywhere.&lt;/p&gt;

&lt;p&gt;So for this reason, in one open-source project &lt;a href="https://github.com/phparkitect/arkitect" rel="noopener noreferrer"&gt;Arkitect&lt;/a&gt; where I’m contributing nowadays, we have a Dockerfile that needs to be published every time there is a push on master, or a new release comes out.&lt;/p&gt;

&lt;p&gt;I can build and publish the Docker image manually every time, but I prefer to avoid this and I have tried exploring GitHub Actions to automate this process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2A_4Ex1uUhL93a3bHyC-TgPg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2A_4Ex1uUhL93a3bHyC-TgPg.png" alt="Github Actions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Exploring GitHub’s actions to automate the process of publishing a docker image to &lt;strong&gt;DockerHub&lt;/strong&gt; was interesting because I found a lot of other interesting GitHub actions and many projects that do the automation that I like.&lt;/p&gt;

&lt;p&gt;First of all, I have inserted inside my GitHub project into &lt;strong&gt;Settings-&amp;gt;Secrets&lt;/strong&gt;, two important repository secrets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DOCKERHUB_USERNAME&lt;/strong&gt;: this is your username on Dockerhub or the name of your organization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DOCKERHUB_TOKEN&lt;/strong&gt;: this is the token and you can get it going on DockerHub in &lt;strong&gt;Account Settings-&amp;gt;Security&lt;/strong&gt;. Here you can generate a new Access Token. You can take the value and put it on GitHub.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next step, I have created a file for the workflow inside GitHub and named it docker-publish.yml&lt;/p&gt;

&lt;p&gt;The file is something 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;name: Arkitect
on:
  push:
    branches:
      — '*'
    tags:
      — '*'
 pull_request:
jobs:
  publish_docker_images:
    runs-on: ubuntu-latest
    steps:
    — name: Checkout
      uses: actions/checkout@v2
    — name: Docker meta
      id: meta
      uses: crazy-max/ghaction-docker-meta@v2
      with:
        images: phparkitect/phparkitect
        tags: |
          type=raw,value=latest,enable=${{ endsWith(GitHub.ref, 'master') }}
          type=ref,event=tag
        flavor: |
          latest=false
     — name: Login to DockerHub
       if: GitHub.event_name != 'pull_request'
       uses: docker/login-action@v1
       with:
         username: ${{ secrets.DOCKERHUB_USERNAME }}
         password: ${{ secrets.DOCKERHUB_TOKEN }}
     — name: Build and push
       uses: docker/build-push-action@v2
       with:
         context: .
         push: ${{ GitHub.event_name != 'pull_request' }}
         tags: ${{ steps.meta.outputs.tags }}
         labels: ${{ steps.meta.outputs.labels }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But it’s not enough because this build will only start if the tests pass, so I have moved the content of this file inside my CI process to another workflow called: build.yml. This is the test suite.&lt;/p&gt;

&lt;p&gt;So we need to create a new job that depends on the test job, thanks to the keyword &lt;strong&gt;“needs”&lt;/strong&gt;, 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;name: Arkitect
on:
  push:
    branches:
      — '*'
    tags:
      — '*'
    pull_request:
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    — uses: actions/checkout@v2
    - name: Install PHP
      run : //stuff to install PHP
    - name: Test
      run: ./bin/phpunit
  publish_docker_images:
    needs: build
    runs-on: ubuntu-latest
    if: GitHub.ref == 'refs/heads/master' || GitHub.event_name == 'release'
    steps:
    — name: Checkout
      uses: actions/checkout@v2
    — name: Docker meta
      id: meta
      uses: crazy-max/ghaction-docker-meta@v2
      with:
        images: phparkitect/phparkitect
        tags: |
          type=raw,value=latest,enable=${{ endsWith(GitHub.ref, ‘master’) }}
          type=ref,event=tag
        flavor: |
          latest=false
    — name: Login to DockerHub
      if: GitHub.event_name != 'pull_request'
      uses: docker/login-action@v1
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}
    — name: Build and push
     uses: docker/build-push-action@v2
     with:
       context: .
       push: ${{ GitHub.event_name != 'pull_request' }}
       tags: ${{ steps.meta.outputs.tags }}
       labels: ${{ steps.meta.outputs.labels }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, as I said before, I have created a new job that depends on the job named &lt;strong&gt;“build”&lt;/strong&gt;.&lt;br&gt;
In this way, if the job named “build” fails, I don’t create a new docker image, because I want to create it only if the tests pass.&lt;/p&gt;

&lt;p&gt;I have used these GitHub Actions:&lt;br&gt;
&lt;a href="https://github.com/crazy-max/ghaction-docker-meta" rel="noopener noreferrer"&gt;crazy-max/ghaction-docker-meta@v2&lt;/a&gt;: it extracts metadata (tags, labels) for Docker.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/docker/build-push-action" rel="noopener noreferrer"&gt;docker/build-push-action@v2&lt;/a&gt;: it builds and pushes Docker images with &lt;a href="https://github.com/docker/buildx" rel="noopener noreferrer"&gt;Buildx&lt;/a&gt; with the full support of the features provided by &lt;a href="https://github.com/moby/buildkit" rel="noopener noreferrer"&gt;Moby BuildKit&lt;/a&gt; builder toolkit.&lt;/p&gt;

&lt;p&gt;A condition that I have added to my docker push job is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if: GitHub.ref == 'refs/heads/master' || GitHub.event_name == 'release'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because I want to execute this job only:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;when there is a push on master&lt;/li&gt;
&lt;li&gt;when a new tag is created&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is necessary for me because I don’t want to create a new docker image every time a pull request is created.&lt;/p&gt;

&lt;p&gt;When there is a push on master the workflow, create a new docker image with the tag “latest”.&lt;br&gt;
When a new tag is released, the workflow creates a new docker image, with the tag equal to the tag of the project and the tag “latest” is recreated.&lt;br&gt;
In this way, I am sure to publish the last version of the docker image every time with new features or bugs fixed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2AJzKdcgMYHRJJG97hN-0FnQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2AJzKdcgMYHRJJG97hN-0FnQ.png" alt="Github Actions build"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, using &lt;strong&gt;GitHub Actions saves me a lot of time&lt;/strong&gt; and repetitive work every time I need to publish my docker image for my project.&lt;br&gt;
There are a lot of other processes that can be automated that I would like to explore and try in my projects, so as soon as possible I will publish other articles about this argument.&lt;/p&gt;

</description>
      <category>build</category>
      <category>docker</category>
      <category>github</category>
      <category>automation</category>
    </item>
    <item>
      <title>How dotfiles can save you a lot of time</title>
      <dc:creator>AlessandroMinoccheri</dc:creator>
      <pubDate>Mon, 01 Mar 2021 15:29:13 +0000</pubDate>
      <link>https://forem.com/minompi/how-dotfiles-can-save-you-a-lot-of-time-55oe</link>
      <guid>https://forem.com/minompi/how-dotfiles-can-save-you-a-lot-of-time-55oe</guid>
      <description>&lt;p&gt;As a developer, I try to automate and optimize all of my processes and workflow.&lt;/p&gt;

&lt;p&gt;Sometimes it’s difficult to understand how you can optimize your work daily life, but for me, one of the best things that can help me a lot is sharing and discussing my ideas, my thoughts, my approaches, and my code with other developers.&lt;br&gt;
Sharing and discussing your leaks with other developers can open your mind to new approaches and fixes.&lt;/p&gt;

&lt;p&gt;Every time I try to talk to other developers about a problem, or a doubt, usually, in the end, I feel more conscious about the problem with a new idea in mind to develop.&lt;br&gt;
The discussion can be done &lt;strong&gt;asynchronously&lt;/strong&gt; or &lt;strong&gt;synchronously&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xXnb5V1A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A0chpI9TjnW2dMPm0FfIXFw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xXnb5V1A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A0chpI9TjnW2dMPm0FfIXFw.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, a discussion could be synchronous when you are doing pair programming with someone or when you are in a meeting.&lt;br&gt;
For asynchronous discussion, I mean for example: writing your problem in a chat and waiting for an answer from another developer.&lt;/p&gt;

&lt;p&gt;Another discussion method could be using &lt;strong&gt;pull requests&lt;/strong&gt; and waiting for other developers that review your code or open a new discussion about it.&lt;/p&gt;

&lt;p&gt;All those practices are fine; it depends on the problem and on the team.&lt;br&gt;
But trying to receive feedback about a solution or another point of view about a problem is one of the most important things to do to become better every day.&lt;/p&gt;

&lt;p&gt;As a developer usually I work on many projects and sometimes with different machines with different configurations.&lt;br&gt;
I try to understand an efficient way to &lt;strong&gt;optimize&lt;/strong&gt; my work using my configurations wherever I want.&lt;/p&gt;

&lt;p&gt;A couple of years ago, while discussing with other developers, I found that many people were sharing their configurations on &lt;strong&gt;GitHub&lt;/strong&gt;.&lt;br&gt;
Inside those repositories, there were configurations, discussions about optimizations, problems solved with &lt;strong&gt;bash scripts&lt;/strong&gt;, and many other useful things.&lt;/p&gt;

&lt;p&gt;For this reason, I have created my personal dotfiles repositories, and you can see it here: &lt;a href="https://github.com/AlessandroMinoccheri/dotfiles"&gt;https://github.com/AlessandroMinoccheri/dotfiles&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a dotfiles repository?
&lt;/h2&gt;

&lt;p&gt;A dotfiles repository is a set of configurations that can be used, usually, on every Linux or OSX system.&lt;br&gt;
You can change it on your personal computer, or inside a new server and you can always get that repository with your configurations in a few seconds.&lt;br&gt;
My dotfiles repository is evolving day after day because sometimes I fix an issue, I insert a new shortcut, or I install a new useful plugin.&lt;br&gt;
So it’s always in evolution, it depends on what you are using and what is useful for you.&lt;/p&gt;

&lt;p&gt;But, pay attention, there are things that you don’t have to commit inside a dotfiles repository like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;passwords&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ssh key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;…&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So &lt;strong&gt;don’t commit personal information or secret passwords&lt;/strong&gt;.&lt;br&gt;
You must commit only things that everyone can see without problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  My personal dotfiles repository
&lt;/h2&gt;

&lt;p&gt;In my repository I have created some scripts:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./copy_dotfiles.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This script is used when you change something inside your shared configuration and you want to commit it into your dotfiles repository.&lt;br&gt;
For example, I copy bash_profile and zsh configurations inside a folder with the same name:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;printf “\nCopying profile configuration”
cp ~/.bash_profile bash_profile
printf “\nCopying personal zsh configuration”
cp -rf ~/.zsh/ zsh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After launching the copy script I make a commit with a significant message about the last changes.&lt;br&gt;
Another essential script is:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./install_dotfiles.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The script is used when you want to import your configurations inside your actual system.&lt;br&gt;
Example of code inside the script:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;printf “\nInstalling profile configuration”
cp -f bash_profile ~/.bash_profile
printf “\nCopying personal zsh configuration”
cp -rf zsh/ ~/.zsh/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this case, I take directories from my repository and copy those inside the correct path for my system.&lt;/p&gt;

&lt;p&gt;Now you can copy and install your configurations whenever and wherever you want.&lt;br&gt;
In my dotfiles repository I have put configurations for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;bash_profile&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;zsh&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;nvim&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;git&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;oh-my-zsh&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As I wrote earlier in this article, &lt;strong&gt;sharing and discussing with other people can open your mind to new solutions&lt;/strong&gt;.&lt;br&gt;
In my case, I optimized a lot of my configurations by reading other dotfiles repositories and asking questions about some things that I couldn’t understand.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e5zeCknX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2956/1%2A8s6_M-tUuSvB_z45fQgitg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e5zeCknX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2956/1%2A8s6_M-tUuSvB_z45fQgitg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, it’s a good practice to open issues inside other dotfiles repositories for asking questions, fixing a problem, or asking for clarification.&lt;br&gt;
It’s up to you now, you can create your dotfiles repository and try to share and discuss your configurations with other developers&lt;/p&gt;

&lt;p&gt;Please write to me if you have any questions and follow me on &lt;a href="https://twitter.com/minompi"&gt;Twitter&lt;/a&gt; to stay updated with new articles or tips.&lt;/p&gt;

</description>
      <category>github</category>
      <category>automation</category>
      <category>dotfiles</category>
      <category>bash</category>
    </item>
    <item>
      <title>Why you should deploy on Friday without fear</title>
      <dc:creator>AlessandroMinoccheri</dc:creator>
      <pubDate>Mon, 25 Jan 2021 10:58:15 +0000</pubDate>
      <link>https://forem.com/minompi/why-you-should-deploy-on-friday-without-fear-3c2p</link>
      <guid>https://forem.com/minompi/why-you-should-deploy-on-friday-without-fear-3c2p</guid>
      <description>&lt;p&gt;I have heard a lot of times: “Don’t deploy on Friday!”&lt;/p&gt;

&lt;p&gt;Well, I understand why, but I disagree with 99% of the cases.&lt;br&gt;
To understand my point of view, I would like to share some concepts about software.&lt;/p&gt;

&lt;p&gt;I am always trying to create &lt;strong&gt;quality code&lt;/strong&gt; and when I start to work on a legacy project or a starting project, usually I ask the team:&lt;br&gt;
How often do you deploy the software?&lt;/p&gt;

&lt;p&gt;Many times when you talk about deploy with developers you can see fear on their faces because sometimes deploying an application can be complicated or very delicate.&lt;/p&gt;

&lt;p&gt;I have seen many different types of problems with deployment, and now I can share some stories.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7ubeF278--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A5CeM-PBDvVIjk69_VOWB8A.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7ubeF278--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A5CeM-PBDvVIjk69_VOWB8A.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a story about a legacy project that takes a lot of data from renewable energy systems every minute and generates a monthly report.&lt;br&gt;
This software is used to understand how much energy is generated and how much clients have to pay.&lt;/p&gt;

&lt;p&gt;After the introduction, I was starting to ask something about deploy to the team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt;: “Well, tell me, How often do you deploy the software?”&lt;br&gt;
&lt;strong&gt;Developer&lt;/strong&gt;: “Uhm, usually once a week but not on Friday! You know, don’t deploy on Friday :)”&lt;br&gt;
&lt;strong&gt;Me&lt;/strong&gt;: “Ok, the frequency could be fine, and how do you deploy your software?”&lt;br&gt;
&lt;strong&gt;Developer&lt;/strong&gt;: “Well, we open our FTPClient and we transfer updated and new files into that, and all it’s done!”&lt;/p&gt;

&lt;p&gt;In this example, the deployment frequency could be fine if you don’t make a lot of features or fixes, but in my opinion, the method to deploy manually is wrong because you have to know which files you need to upload or enter into the server to restart a process, for example.&lt;/p&gt;

&lt;p&gt;You can make an error because you forget to upload a file or the internet connection goes down when you are uploading files (it happens).&lt;br&gt;
So remove manual processes if it’s possible. It’s ideal to remove all manual processes, if possible.&lt;/p&gt;

&lt;p&gt;Now we can explore another story, this story is about a financial project where a team of 5 developers created a lot of features.&lt;br&gt;
Those features are deployed into a test server together, and after the customer approves them, they can deploy all the features to production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt;: “Well, tell me, how often do you deploy the software?”&lt;br&gt;
&lt;strong&gt;Developer&lt;/strong&gt;: “We deploy our features usually once a month because we need approval from the customer”&lt;br&gt;
&lt;strong&gt;Me&lt;/strong&gt;: “Why does the approval only come once a month?”&lt;br&gt;
&lt;strong&gt;Developer&lt;/strong&gt;: “because the customer can review only twice a month and we develop a lot of features and it takes a long time, and sometimes there are some bugs that need to be solved”&lt;/p&gt;

&lt;p&gt;In this example, there is a problem with the quantity of work developed, the approval time, and the frequency of deployment.&lt;/p&gt;

&lt;p&gt;To solve this problem I can advise customers to check features every week at least and approve only those features.&lt;br&gt;
When there is approval the team can deploy those features and restart the process.&lt;/p&gt;

&lt;p&gt;Try to avoid a long time for the approval to limit errors, deployment frequency, and possible errors in production because if you need to check a lot of features the error % increase because you don’t pay the right attention to each feature.&lt;/p&gt;

&lt;p&gt;Remember: &lt;strong&gt;small and frequent deployment can reduce errors and wasting time.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are a lot of other examples but with these two we can now understand some deployment problems.&lt;/p&gt;

&lt;p&gt;To avoid these problems we can try to deploy more frequently with continuous integration and continuous delivery.&lt;/p&gt;
&lt;h3&gt;
  
  
  Continuous integration (CI)
&lt;/h3&gt;

&lt;p&gt;Continuous Integration is a development practice where developers merge code into a repository whenever possible, for example, many times a day.&lt;br&gt;
Every merge is verified by an automated build that can try to understand if there is some problem.&lt;/p&gt;

&lt;p&gt;Another advantage of the CI is that you have a solid build process where you trust it to understand if your code can be deployed or not in production. You can reduce or remove the time to check manually your features and reduce integration problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to do it:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;every team developer has the source code inside their local machine&lt;/li&gt;
&lt;li&gt;when the developer completes a task or an important piece of feature, he commits to a specific branch for the feature&lt;/li&gt;
&lt;li&gt;CI whenever a push event is emitted, it runs tests, it runs code analysis&lt;/li&gt;
&lt;li&gt;if there is something wrong CI sends a failure message or an email, and the team fixes the problem&lt;/li&gt;
&lt;li&gt;if all is okay the code is ready to be deployed&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Continuous delivery (CD)
&lt;/h3&gt;

&lt;p&gt;Continuous Delivery is very close to Continuous Integration and usually, it refers to the practice of releasing every time there is a successful build.&lt;br&gt;
When all automated tests are passed, and every check is okay, it’s time to deploy your application automatically.&lt;/p&gt;

&lt;p&gt;It’s a set of capabilities that enables us to integrate features, bug fixes, and configuration changes into production in a safe and quick way.&lt;br&gt;
It’s important to understand that it is a culture and all people inside the project are responsible.&lt;/p&gt;

&lt;p&gt;We need to work in small batches to reduce errors and become more efficient in delivering value.&lt;br&gt;
Implementing CD means creating different feedback loops for high-quality software to be delivered to users frequently.&lt;/p&gt;

&lt;p&gt;Applying continuous integration and continuous delivery to your process can reduce risks and find bugs more quickly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1BJDUMYG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AIYE_nciF0DnT_jBbY8OKuQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1BJDUMYG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AIYE_nciF0DnT_jBbY8OKuQ.jpeg" alt="[https://www.slideshare.net/IzzetMustafaiev/fabric8-cicd](https://www.slideshare.net/IzzetMustafaiev/fabric8-cicd)"&gt;&lt;/a&gt;&lt;em&gt;&lt;a href="https://www.slideshare.net/IzzetMustafaiev/fabric8-cicd"&gt;https://www.slideshare.net/IzzetMustafaiev/fabric8-cicd&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Creating a &lt;strong&gt;CD / CI culture&lt;/strong&gt; and process means improving the quality of your software and the health of your teams.&lt;/p&gt;

&lt;p&gt;To release your software more frequently, I have seen that limiting the “Work in progress” (WIP) improves your lead time.&lt;/p&gt;

&lt;p&gt;By lead time, I mean the time from the moment that you start a feature, to the moment when that feature is released.&lt;/p&gt;
&lt;h3&gt;
  
  
  Tools
&lt;/h3&gt;

&lt;p&gt;Usually when we have to create a CD/CI build we try to use external services that can be integrated into our process.&lt;br&gt;
In my opinion, it’s important that every team can use its preferred tools for processes because every project is different, so they can need a different process.&lt;/p&gt;

&lt;p&gt;The team can choose which software, check, and steps need to be used and implemented for a specific application because it depends on many things.&lt;br&gt;
It’s not important to find the best choice immediately because after each deploy you can ask your team how to improve the process or if there is something wrong.&lt;/p&gt;

&lt;p&gt;Sometimes we create little experiments to try new tools, processes, or other things.&lt;br&gt;
Those experiments are small and in time-boxing to understand whether that improvement can be integrated into our process or not.&lt;br&gt;
This enables teams to explore new solutions and improve the quality of the software.&lt;/p&gt;

&lt;p&gt;Don’t be afraid of failure because you are trying to improve something in a little experiment without big consequences.&lt;/p&gt;
&lt;h3&gt;
  
  
  Example of a common CD/CI process in our project
&lt;/h3&gt;

&lt;p&gt;Usually, we create a repository in GitHub.&lt;br&gt;
Each developer has cloned the repository into his local machine and has coded new features into separate branches.&lt;/p&gt;

&lt;p&gt;Every time a developer pushes inside a branch we have configured &lt;strong&gt;GitHub actions&lt;/strong&gt; to run several processes like launch tests, run static code analysis&lt;/p&gt;

&lt;p&gt;Example of Github actions configuration:&lt;/p&gt;

&lt;p&gt;.github/ci.yml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: ProjectName

on:
  push:
    branches:
      - '*'

  pull_request:
    branches: [ master ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - name: Validate composer.json and composer.lock
      run: composer validate

    - name: Cache Composer packages
      id: composer-cache
      uses: actions/cache@v2
      with:
        path: vendor
        key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
        restore-keys: |
          ${{ runner.os }}-php-
    - name: Install dependencies
      #if: steps.composer-cache.outputs.cache-hit != 'true'
      run: composer install --prefer-dist --no-progress

    - name: Coding Standard Checks
      run: ./bin/php-cs-fixer fix --dry-run -v

    - name: Static Analysis
      run: ./bin/psalm

    - name: Test
      run: ./bin/phpunit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this configuration file, every time a developer pushes on a branch it creates an environment with the latest ubuntu, checkouts the project, launches composer install to install dependencies, and after that, launches tools like php-cs-fixer (for coding standard), psalm (for static analysis) and phpunit (for tests).&lt;/p&gt;

&lt;p&gt;If all is okay the branch could be merged into the main branch of the project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xt6_FHeu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2400/1%2A3PTrJei3zFAylve2qnUglg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xt6_FHeu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2400/1%2A3PTrJei3zFAylve2qnUglg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When a branch is merged into the main branch we have created another process to automatically deploy the software with &lt;strong&gt;AWS&lt;/strong&gt; in this project.&lt;/p&gt;

&lt;p&gt;With AWS there are many systems to deploy your application and we have chosen for our project: &lt;strong&gt;CodeDeploy&lt;/strong&gt; and &lt;strong&gt;CodePipeline&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To create an automatic deployment with these tools, you need to configure them on your AWS account and creates two files. For example:&lt;/p&gt;

&lt;p&gt;File: &lt;strong&gt;appspec.yml&lt;/strong&gt; is used to manage each deployment as a series of lifecycle event hooks, which are defined in the file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: 1.0
os: linux
files:
  - source: /
    destination: /var/www/yourProject/
permissions:
  - object: /var/www/yourProject/var/
    owner: data
    group: data
    mode: 755
    type:
      - directory
hooks:
  BeforeInstall:
    - location: scripts/deploy/before-install-production.sh
      timeout: 180
  AfterInstall:
    - location: scripts/deploy/after-install-production.sh
      timeout: 180
  ValidateService:
    - location: scripts/deploy/validate-service.bat    
      timeout: 900 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;File: &lt;strong&gt;buildspec.yml&lt;/strong&gt; is a collection of build commands and related settings, in YAML format, that &lt;strong&gt;CodeBuild&lt;/strong&gt; uses to run a build&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: 0.2
phases:
 install:
 pre_build:
   commands:
     - apt-get update -y
     - apt-get install -y software-properties-common
     - add-apt-repository ppa:git-core/ppa -y
     - apt-get update -y
     - apt-get install -y build-essential python-pip git
 build:
   commands:
     - make backend_test_ci
     - make frontend_test_ci
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don’t want to go deep inside AWS processes, I think that I will write another article about that.&lt;br&gt;
I have only shown you some examples to make it explicit that it’s not so difficult to create a CD/CI system with those tools.&lt;/p&gt;

&lt;p&gt;Another way to deploy software is to use &lt;strong&gt;Kubernetes&lt;/strong&gt; and deploy the docker images into production, we have used this solution for some projects with success.&lt;/p&gt;

&lt;p&gt;All these processes and tools can help you create a solid automated build for your software that you can trust and improve your projects because it enables you to launch tests, static analyses, and other checks asynchronously.&lt;br&gt;
You can improve your project step-by-step and code to create quality software day after day until you can feel comfortable to deploy on Friday without fear because you trust in your build and in your code.&lt;/p&gt;

&lt;h3&gt;
  
  
  But if you deploy something with an error?
&lt;/h3&gt;

&lt;p&gt;Well, with these tools you can rollback to the previous version in a few moments and try to understand the problem locally if you want.&lt;br&gt;
When you find a build problem (it happens) you should fix it and improve again your build by adding, for example, more checks or other processes and steps to avoid problems.&lt;/p&gt;

&lt;p&gt;It’s better to add a check inside a build than to see bugs that appear in many parts of the software.&lt;br&gt;
When you feel confident to deploy every time you want and on Friday also, you can feel less stressed and proud of your build and code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rpD9UFBD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2Alg-8SHzFgRN0Lz2Ep8WeYA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rpD9UFBD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2Alg-8SHzFgRN0Lz2Ep8WeYA.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The deploy frequency is one of the most important things that I try to understand when I analyze a new or legacy projects because it’s a powerful metric that can show you immediately the quality of the software.&lt;br&gt;
In my opinion the deployment process is a mindset and culture that must be embraced and shared by the team.&lt;/p&gt;

&lt;p&gt;For these reasons I believe that you should deploy on Friday without fear because if you trust in your code and your build process, it’s very easy to deploy and be calm when new code is going to production.&lt;/p&gt;

&lt;p&gt;I can recommend a very interesting book that treats all these and more concepts: &lt;strong&gt;Accelerate: The Science of Lean Software and DevOps: Building and Scaling High Performing Technology Organizations&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PTOJd5nq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AdDyuV7WnOQunGjizDsyqlA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PTOJd5nq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AdDyuV7WnOQunGjizDsyqlA.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you need more help or try to improve or create an automated deploy feel free to contact me or the company where I actually work: &lt;a href="https://flowing.it"&gt;Flowing&lt;/a&gt;&lt;/p&gt;

</description>
      <category>deployment</category>
      <category>aws</category>
      <category>ci</category>
      <category>automation</category>
    </item>
    <item>
      <title>Deploy a Symfony application with AWS Lambda, a quick guide</title>
      <dc:creator>AlessandroMinoccheri</dc:creator>
      <pubDate>Thu, 24 Dec 2020 09:19:42 +0000</pubDate>
      <link>https://forem.com/minompi/deploy-a-symfony-application-with-aws-lambda-a-quick-guide-2lhl</link>
      <guid>https://forem.com/minompi/deploy-a-symfony-application-with-aws-lambda-a-quick-guide-2lhl</guid>
      <description>&lt;p&gt;When I first heard the word Serverless I thought I would soon lose my job. No more servers, no more code, no more work to do, it's simple, isn't it?&lt;/p&gt;

&lt;p&gt;What happened instead is that, like all other back-end developers, I have a new tool to do my job better.&lt;/p&gt;

&lt;p&gt;In this article, I will briefly explain what Serverless is and what advantages it brings us. We will see the Bref library and how to deploy a Symfony application on AWS Lambda.&lt;/p&gt;

&lt;p&gt;In the next article I will go into the details of the deployment, analyzing the various components involved and proposing solutions and use cases for this architecture.&lt;/p&gt;

&lt;p&gt;Let's begin!&lt;/p&gt;

&lt;h2&gt;
  
  
  What does it mean really serverless?
&lt;/h2&gt;

&lt;p&gt;Serverless is a word that very often may misguide one into thinking that there is no server where the application is running.&lt;/p&gt;

&lt;p&gt;Serverless just means that developers don't have to maintain the infrastructure anymore because AWS will take care of it: developers can focus only on the code.&lt;/p&gt;

&lt;p&gt;AWS provides a serverless service called Lambda where you can run code without provisioning or managing servers. Lambda is based on two main concepts: functions and events. A function is a piece of code (which can be written using various languages) that performs some sort of operation. An event is something that happened in your infrastructure, for instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A file is uploaded on an S3 bucket&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A record is inserted in an Amazon DynamoDB table&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When an event happens it will trigger the Lambda function and our code will run.&lt;/p&gt;

&lt;p&gt;A big advantage of AWS Lambda service is a “pay-per-use” model: you are charged only for the actual compute time used — there is no charge when your code is not running. Let's compare it to a “traditional” EC2 scenario. In the graph below, you can see costs (green areas) are constant during the time: you pay the same amount of money, regardless of the actual use of your servers (blue area).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hs_yT79F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2ArvNWVNo4Lt3kqMnA" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hs_yT79F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2ArvNWVNo4Lt3kqMnA" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n0L4izeD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2An8GriTcAhTSiMNJt" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n0L4izeD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2An8GriTcAhTSiMNJt" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a serverless scenario, costs are always tied to the actual use of your infrastructure.&lt;/p&gt;

&lt;p&gt;Lambda is a very cheap service: 0,0000002 USD per request (a function run) with the first million requests per month free. This will increase if you need more memory or some other configurations.&lt;/p&gt;

&lt;p&gt;When Lambda was released it supported very few languages and PHP wasn't one of them. In December 2018 AWS announced:&lt;/p&gt;

&lt;p&gt;“Native PHP support on Lambda wasn't one of those features, but the new AWS Lambda runtime API and layers capabilities give us the ability to build a clean, supportable implementation of PHP on Lambda of our own.”&lt;/p&gt;

&lt;p&gt;This means that you can import PHP binaries file into Lambda layer, thus being able to run any PHP code, even your Symfony Application.&lt;/p&gt;

&lt;p&gt;PHP binaries need to be created following certain rules. Creating and maintaining those files is a very expensive and time-consuming activity but, lucky for us, Matthieu Napoli has created an open-source library called Bref that helps developers to deploy PHP applications on Lambda.&lt;/p&gt;

&lt;p&gt;It provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;PHP runtimes for AWS Lambda&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A library to interface PHP code with Lambda API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rich documentation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deployment tools&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x6mIjmjY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2A-majnhjUyXsknhSf" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x6mIjmjY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2A-majnhjUyXsknhSf" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image from &lt;a href="https://blog.theodo.com/2019/05/serverless-symfony-on-aws-lambda-with-bref/"&gt;https://blog.theodo.com/2019/05/serverless-symfony-on-aws-lambda-with-bref/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;To deploy a Symfony Application into a Lambda with Bref you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;AWS account with Access Key ID, Secret Access Key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install and configure the serverless framework&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install and initialize Bref library&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first step is to configure AWS with your command line interface with this command&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws configure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The terminal will ask you to enter the Access Key ID, the Secret Access Key, the default region name and default output format.&lt;/p&gt;

&lt;p&gt;Now you need to install the serverless framework, a tool to develop, deploy, test, secure, and monitor your Serverless applications&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g serverless
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To use this tool you need to associate your credentials with it by the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;serverless config credentials — provider aws — key &amp;lt;key&amp;gt; — secret &amp;lt;secret&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now your terminal is configured so we can start to work into our Symfony application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bref
&lt;/h2&gt;

&lt;p&gt;After you have created and configured your Symfony Application you can install Bref&lt;/p&gt;

&lt;p&gt;To install it you need to launch into your command line interface:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require bref/bref
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now you need to initialize the project by running&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vendor/bin/bref init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;When you initialize bref, it creates automatically two files into the project root:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;index.php that contains the function code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;serverless.yml that contains the configuration for deploying on AWS&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example of standard configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    service: symfony-bref
        provider:
            name: aws
            region: eu-central-1
            runtime: provided
            environment:
                APP_ENV: prod
        plugins:
            - ./vendor/bref/bref
        functions:
            api:
            handler: public/index.php
            description: ''
            timeout: 30 # in seconds (API Gateway has a timeout of 30 seconds)
            layers:
            - ${bref:layer.php-73-fpm}
            events:
            - http: 'ANY /'
            - http: 'ANY /{proxy+}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usually, you have to add the environment with APP_ENV and change the region name.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure serverless to deploy your Symfony application
&lt;/h2&gt;

&lt;p&gt;Before doing it, it's important to understand why the serverless framework can help us.&lt;/p&gt;

&lt;p&gt;Some months ago bref make the deploy with AWS SAM an open-source framework that you can use to build serverless applications on AWS, it's a tool for CloudFormation with a not simple configuration.&lt;/p&gt;

&lt;p&gt;AWS SAM has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Template specification&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Command-line interface&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a standard SAM configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    AWSTemplateFormatVersion: '2010–09–09'
    Transform: AWS::Serverless-2016–10–31
    Description: 'Symfony test'
    Resources:
        MyFunction:
        Type: AWS::Serverless::Function
        Properties:
        FunctionName: 'symfony-test'
        Description: ''
        CodeUri: .
        Handler: public/index.php
        Timeout: 30 # in seconds (API Gateway has a timeout of 30 seconds)
        MemorySize: 1024 # The memory size is related to the pricing and CPU power
        Runtime1sw: provided
        Layers:
            - 'arn:aws:lambda:eu-central-1:209497400698:layer:php-73-fpm:7'
        Events:
            # The function will match all HTTP URLs
            HttpRoot:
            Type: Api
            Properties:
            Path: /
            Method: ANY
            HttpSubPaths:
            Type: Api
            Properties:
            Path: /{proxy+}
            Method: ANY
        Environment:
            Variables:
            MY_CUSTOM_ENV_VARIABLES: 'this is my custom env variables'
            AWS_ENV_VARIABLES: '{{resolve:ssm:/env-aws-variable:1}}'
    # Outputs show up in the CloudFormation dashboard
        Outputs:
            DemoHttpApi:
            Description: 'URL of our function in the *Prod* environment'
            Value: !Sub 'https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The configuration is more complex and longer than serverless framework configuration.&lt;/p&gt;

&lt;p&gt;In serverless framework you can add SAM configuration for complex configuration and another advantage of serverless framework is the multi-provider: you can use it for AWS or Azure or other providers without changing the configuration. AWS SAM is only for AWS.&lt;/p&gt;

&lt;p&gt;For these reasons, Bref community decided to switch from AWS SAM to serverless framework.&lt;/p&gt;

&lt;p&gt;To start your deploy you need to install Composer dependencies optimized for production launching this command into your CLI:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer install --optimize-autoloader --no-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now launching this command you will deploy your application:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;serverless deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now some subroutines start and in the end, you can see a link, if you click on it you can see your application works!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y3_-SDX6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AscvorxyuaSwg02ld" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y3_-SDX6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AscvorxyuaSwg02ld" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What really happened?
&lt;/h2&gt;

&lt;p&gt;When you deploy into a Lambda service you will do it through a CloudFormation stack.&lt;/p&gt;

&lt;p&gt;A stack is simply a group of service that composes an application, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Databases&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;S3 Buckets&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The serverless framework translates configuration from serverless.yaml file and creates an AWS CloudFormation template from it.&lt;/p&gt;

&lt;p&gt;Based on that template, a stack is created (if needed), with no resources except for an S3 Bucket used to store your code as a zip file.&lt;/p&gt;

&lt;p&gt;Lambda will get the new code, unzip it and replace the older code.&lt;/p&gt;

&lt;p&gt;Serverless framework optimizes these operations by comparing hashes of the files and performing a new deploy only if needed.&lt;/p&gt;

&lt;p&gt;That's it, simple as promised, a Symfony application deployed on Lambda.&lt;br&gt;
In the next article, I'll tackle some issues like Symfony tweaks, use of environment variable and trigger upon events.&lt;/p&gt;

</description>
      <category>php</category>
      <category>serverless</category>
      <category>aws</category>
      <category>lambda</category>
    </item>
  </channel>
</rss>
