<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Bruno Luiz da Silva on Medium]]></title>
        <description><![CDATA[Stories by Bruno Luiz da Silva on Medium]]></description>
        <link>https://medium.com/@brunoluiz?source=rss-20630242f3aa------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*1ZrSxn2m4KdGhNqUK2aqnA.jpeg</url>
            <title>Stories by Bruno Luiz da Silva on Medium</title>
            <link>https://medium.com/@brunoluiz?source=rss-20630242f3aa------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 14:00:12 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@brunoluiz/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[A Tale Of How To Not Deploy Two Months Old Features]]></title>
            <link>https://medium.com/@brunoluiz/a-tale-of-how-to-not-deploy-two-months-old-features-bbec2c9ba495?source=rss-20630242f3aa------2</link>
            <guid isPermaLink="false">https://medium.com/p/bbec2c9ba495</guid>
            <category><![CDATA[development]]></category>
            <category><![CDATA[agile]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[retail]]></category>
            <category><![CDATA[failure]]></category>
            <dc:creator><![CDATA[Bruno Luiz da Silva]]></dc:creator>
            <pubDate>Wed, 07 Mar 2018 16:38:11 GMT</pubDate>
            <atom:updated>2018-03-11T16:11:09.643Z</atom:updated>
            <content:encoded><![CDATA[<h3>A Tale of How To Not Deploy Two Month Old Features</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FB6fOzH3Fe3VP2NsHqULrg.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/P3pI6xzovu0?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Clark Street Mercantile</a> on <a href="https://unsplash.com/search/photos/retail?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><h3>The Most Special Retail Market Date</h3><p>There is one big and very special date on the e-commerce and retail market and it&#39;s called Black Friday. For many, it means &quot;discount prices&quot;, &quot;sale!&quot;, &quot;50% off&quot;, but for developers and IT people it is a challenging adventure.</p><p>To begin with, two weeks before, feature deployments are frozen and everything passes through load tests. On the week, machines are scaled up and, at the event&#39;s day, all eyes are on metrics and logs.</p><p>But there is a catch in this whole story: the feature development can&#39;t stop. This means features will begin to stack up soon after the feature deployment freeze and usually it continues a bit after the event, especially when your software is multi-tenant and each client has its own Black Friday agenda.</p><p>In the case which gave this article its title, the deploy was delayed until close Christmas and, as it was Christmas, the team preferred to not deploy until the next year.</p><p>January came by and, at some point, the delayed deploys would have to start. As four sprints have been passed since Black Friday, the usual process would be to deploy each sprint package atomically, monitoring its results in the production environment. But this, this is not an ideal world.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UhmIv0jwpiZJ6DbDajl31A.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/qtzzQjEmB54?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">rawpixel.com</a> on <a href="https://unsplash.com/search/photos/present?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><h3>Product Development Life Is Full Of Surprises</h3><p>When a product is just in its early days, the first clients are tech early adopters and the development team have to be close to them, as their inputs are valuable.</p><p>At some day in January, one of the major platform&#39;s clients informed they would launch more shops on the system. Besides the fact that, usually, some preparation is required, the biggest issue was that a specific feature was required. It had been developed at some point, but it was not well tested yet.</p><p>Even worse, this feature depended on others, implemented in late November and early December, which means &quot;Goodbye atomic deploys&quot;: the team will have to prepare a deploy package with all four sprint features. Dangerous, isn&#39;t it? Remember the <em>challenging adventure</em> part?</p><p>While finishing and polishing the required feature, the QA team had to work deliberately to test all features again to be sure that everything would be pretty smooth. Even those which were already tested as, since November, some hotfixes were made on the production environment and who knows if they could have affected one of the already tested features.</p><p>With the feature finished, the QA and management teams got together to test it. After a period of tests, they confirmed it was working as expected, with no bugs or business rules flaws. Even though this surprise feature made us work insanely, the deploy looked like it would be a walk in the park.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Lvz897QCIoq8ID_3MPn_cA.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/uj3hvdfQujI?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">SpaceX</a> on <a href="https://unsplash.com/search/photos/launch?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><h3>D(eploy)-Day</h3><p>It was 2 am when the whole deploy started. Low traffic and not that many orders flooding the system made it the perfect time to deploy the application. While deploying it, everything seemed fine, even though minor adjustments and migrations were needed. As soon as the clock hit 3h30 am, the team members were already wishing &quot;Good Night&quot; to each other.</p><p>For a package with a lot of features and one quite critical, it was quite smooth… and this is when things started to fall apart. At 4 pm, one of the clients started to complain about some orders not being registered due to HTTP 400 errors and some inventory not being updated for no reason. <em>&quot;WHAT THE F*CK IS GOING ON!&quot; </em>everybody said, in despair.</p><p>All developers stopped to investigate the problem and, of course, hidden in the middle of one of the sprint release packages, there were two bugs: one related to how the application dealt with the inventory queue producer and the other related to how addresses were validated. Ten lines of code worth of trouble.</p><p>After roughly one hour of stress, everything was calm again, but the results of this deploy changed the entire team.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XsmvUvDELQVWAl3zhTvvlQ.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/jLwVAUtLOAQ?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Dustin Lee</a> on <a href="https://unsplash.com/search/photos/notes?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><h3>THAT Post-Mortem And Its Results</h3><p>Soon after, a post-mortem had been written. Everybody collaborated: developers, managers, and QAs. The information contained in this single document would allow the team to learn, grow and know better how to deal with problems like this in the future.</p><p>At the other day, a morning meeting was scheduled to discuss the points written in the post-mortem. Besides the issues from the deploy itself, many other problems arose in the heat of the discussion. All members agreed on the pointed issues and suggested some actions to tackle them.</p><h4>Deploy age</h4><p>One could point to the code and say it was a bug, but it was not only that. Deploys that are too many weeks old are a problem, as it has features developed way too long ago, where devs and testers probably don&#39;t remember all specifics for these. This can lead to database issues (if a migration was forgotten), schema validation problems, business rules flaws, and so on.</p><p>The best way to tackle this is to deploy the feature package not too long after the sprint has been finished. Everything will be fresh for all team members and no git gimmicks will be required for this (rebase hell mostly).</p><h4>Rushed deploys</h4><p>Never do rush deploys, especially big ones. The team will get stressed, communication probably will not be the best, documents (such as the release notes) can have errors or miss information. In this deploy, one of the features was not specified on the JIRA Release Board, but it was on the GitHub release. A developer with more time would have noticed that some stuff was missing.</p><p>These release notes usually will not only be used by the clients, but by the QAs as well, as it will have which features will be deployed. As these have impacts on everybody, the best thing to do is to have a consensus on what can be fully delivered (developer side) and well tested (QA side). The idea is to avoid features which can have bugs or not well tested because they were made in a rush.</p><h4>Create Processes</h4><p>Usually, people love to complain about &quot;processes&quot;. Some people even say they love startups because of the lack of them. But they exist for a reason and, in this case, it would have helped if everything followed a well-defined process.</p><p>There was already a process, but it was not that specific. After the incident, the team got together and wrote a document describing each step of the product feature development, with a pipe of what should be done on each step of it: feature discussions and development, peer reviews metrics, deploy and release notes for tests environments, test processes and finally, the production deploy.</p><p>Is it more bureaucratic? For sure! But until now, there were no complains by the team members and, especially, the client.</p><h4>More Automated Tests</h4><p>Each sprint feature package is tested by QAs in a staging environment. The best scenario is to have a lot of different automated test scenarios, which would give 100% guarantee that nothing will break the APIs.</p><p>But, this isn&#39;t a perfect world. The usual is to have part of it automated and part of it is tested by humans. But, as this aging deploy was urgent and made in a rush, some features passed through without being well tested.</p><p>How to solve this problem? Well, one side of the problem is organization: a board tool would help with this but, as aging deploys such as this one have too many tasks, the best thing to do is organize THAT release note. The QA team will be able then to plan how to do its tests.</p><p>The other side, which is a bit more complicated, is to create more automated tests. Not only QAs but developers as well. Everybody knows someone who wants to skip the test development, but this can help to avoid countless problems (especially in the future). The other developers should not allow a feature to go on without automated tests for it. The same applies for QAs.</p><h4>Error Metrics Monitoring and Alerts</h4><p>Soon after the deploy, the team has checked some error metrics on <a href="https://www.graylog.org/">Graylog</a> and <a href="https://aws.amazon.com/cloudwatch/">CloudWatch</a>, but these error metrics were just for a part of the system, not its whole. If more metrics had been monitored, probably the problem would have been discovered way before and the impact would have been smaller.</p><p>The team should monitor at least some of these metrics manually, through dashboards or even the application log, but the best way to tackle this is through automated alerts. Nowadays, all major IaaS providers have a service for metrics and logs. With CloudWatch (AWS), the team can set alerts for when too many error HTTP responses are given by the applications on a certain determined period. It can send e-mails, SMS and even be integrated with mobile apps such as <a href="https://www.opsgenie.com/">OpsGenie</a>.</p><p>There are other tools besides these, such as <a href="https://newrelic.com/">NewRelic</a> and <a href="https://www.librato.com/">Librato</a>, but they are a bit more specific and the team should analyze if they are really required.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dC5MToDibPTP-pWsg7g3Ow.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/gsf4OfORp5c?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Kupono Kuwamura</a> on <a href="https://unsplash.com/search/photos/blue-sky?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><h3>End Of Problems?</h3><p>This will not be the last problem the team will have to struggle with. Stressful moments like these will appear but this is when the team will learn and grow, being able to rise and aim towards high stakes through time.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bbec2c9ba495" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Joi: validate input and define databases in JavaScript]]></title>
            <link>https://medium.com/@brunoluiz/joi-validate-input-and-define-databases-in-javascript-84adc6f1474b?source=rss-20630242f3aa------2</link>
            <guid isPermaLink="false">https://medium.com/p/84adc6f1474b</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[joi]]></category>
            <category><![CDATA[validation]]></category>
            <category><![CDATA[development]]></category>
            <dc:creator><![CDATA[Bruno Luiz da Silva]]></dc:creator>
            <pubDate>Wed, 30 Aug 2017 21:18:52 GMT</pubDate>
            <atom:updated>2018-01-04T00:49:48.765Z</atom:updated>
            <content:encoded><![CDATA[<h3>Joi: validate input and define database schemas in JavaScript</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ak94Xh5LGvl2TgtnXPQQhQ.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/6PF6DaiWz48?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Rayi Christian Wicaksono</a> on <a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>As the saying goes: <em>never trust user input</em>. People coming from PHP and Java have many validation libraries available. But what about JavaScript? There are some options, but none seems more interesting than Joi.</p><p><a href="https://github.com/hapijs/joi">Joi</a> is maintained by <a href="https://hapijs.com/">Hapi.js project</a>. Even though hapi.js is a web framework by itself, Joi is independent and can be used in any type of node project. This is great for people using express or restify, for example.</p><p>What makes it even more interesting is that, besides user validation, it can be used to define database schemas as well. This post will introduce a quick start guide, with some usage cases and general tweaks.</p><h3>How to use it?</h3><p>First things first: it has to be installed on the project. Considering an already initiated node project, the command to install it is: npm install joi. After being installed, a schema is required to use it, such as the file rating-schema.js below:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6be80f7851d8f406c6e104d6346b54ce/href">https://medium.com/media/6be80f7851d8f406c6e104d6346b54ce/href</a></iframe><p>This defines a model where an username, a rating (from 1 to 5) and an email (which is a required field) are expected. This is a simple example, but there are way more validation options, which can be found on the <a href="https://github.com/hapijs/joi/blob/v10.6.0/API.md">API reference</a>. To use the defined schema, consider a file called rating-test.js:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7a1548a1fe0c2068080fc4606a067e39/href">https://medium.com/media/7a1548a1fe0c2068080fc4606a067e39/href</a></iframe><p><a href="https://github.com/hapijs/joi/blob/v10.6.0/API.md#errors">More about Joi errors</a></p><h3>Real project usage</h3><h4>Validation middleware</h4><p>In a real project, Joi can be used on a middleware layer. On <a href="http://expressjs.com/">express</a>, for example, this can be done using:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c25e0ff780b02b819f99a08d6b92b2a3/href">https://medium.com/media/c25e0ff780b02b819f99a08d6b92b2a3/href</a></iframe><p>In this case, if the ratingsValidator returns an error due to validation, express will stop the request before even reaching the controller.</p><h4>Database schema (MongoDB and DynamoDB)</h4><p>Some tools can use it to define their database schema (keep in mind that Joi is not an ORM). For MongoDB, mongoose can be used together with <a href="https://github.com/yoitsro/joigoose">joigoose</a>, which easily converts a Joi schema. For example:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d8b457a81179375b7a9ca0ccee836d65/href">https://medium.com/media/d8b457a81179375b7a9ca0ccee836d65/href</a></iframe><p>Through <a href="https://github.com/ryanfitz/vogels">vogels</a>, the same can be done in projects using DynamoDB. By default, it accepts Joi as its schema definition. The following example is based on vogels documentation:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/218d417fa17bf3b61675970748de03da/href">https://medium.com/media/218d417fa17bf3b61675970748de03da/href</a></iframe><h4>Exchangeability for front-end validation</h4><p>Some developers prefer to define the schema once and then use everywhere, including on browsers. Today <a href="https://github.com/hapijs/joi/#browsers">Joi doesn&#39;t support browser usage</a>, but a package called <a href="https://github.com/jeffbski/joi-browser">joi-browser does this job</a>, enabling the usage of exactly the same schema on the front-end as well.</p><h3>Useful tweaks</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6JEKFpOmUl79tToa0BtmwQ.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/oEtQ0C6HS2I?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">chuttersnap</a> on <a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><h4>#1: Disable Joi number() convert</h4><p>By default, Joi allows users to pass numbers formatted as strings, in cases of number() fields. This is specially bad if the validate() result is only used to check if there was an error, but not for it&#39;s value field. To solve this, there are two possible solutions</p><ol><li>On schema.validate(value), an extra parameter can be passed to disable it, as: schema.validate(value, { convert: false })</li><li>Put a strict() at the end of the desired number field, as: Joi.number().strict()</li></ol><p>Both of them are quite annoying, because either all fields or all function calls require a specific config. One way to solve this is by extending Joi…</p><h4>#2: Extend Joi defaults</h4><p>In cases such as the above, or for new field types, or even when the behavior of a default field has to be changed, Joi.extend() can be an option.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/aecdd34188b3655caed6729ccf82f221/href">https://medium.com/media/aecdd34188b3655caed6729ccf82f221/href</a></iframe><p>When using Joi through this file, all number fields will be on the strict mode — which solves the issue of applying tweak #1 everywhere — and a zipcode() validator is created, based on a pre-defined regex.</p><p>More rules can be added and, actually, the Joi API enables <a href="https://github.com/hapijs/joi/blob/v10.6.0/API.md#extendextension">much more customisation</a> on Joi.extend.</p><h4>#3: Create default fields</h4><p>In some projects, a lot of models will have some default fields, such as an extensionAttributes, where custom vendor data will be put into (as Magento already does) or updatedAt. In these cases, the Joi.object can be extended to include default fields:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f836ec0088da872345e92119fd9000a5/href">https://medium.com/media/f836ec0088da872345e92119fd9000a5/href</a></iframe><h4>#4: Show all validation errors</h4><p>Usually Joi validation dies on the first error, returning on it&#39;s message which field failed. This is an issue when an input have many fields with problems. The user will have to do many requests to discover all problematic fields. To fix this issue, the following option can be added on the function call:</p><p>const result = schema.validate(value, { abortEarly: false })</p><p>With this config, if an error occurs, the result.error will return all validation failures.</p><h4>#5: Built-in Joi conditional validations</h4><p>If a field depends on values from another field, the conditional when() can be used.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ec556ecc74daeedd3ccea3112b1ca547/href">https://medium.com/media/ec556ecc74daeedd3ccea3112b1ca547/href</a></iframe><p>In this case, the field a accepts the value x, y, z. But, to accept y as a value, the field b have to be equals 5, otherwise only x and z will be accepted.</p><p>Of course, this is a simple and fictitious conditional validation, but it is quite useful in cases where some field requires a specific validator when some other had a specific input.</p><h3>Are you ready to use it?</h3><p>I hope this post convinced you to use some validation tool such as Joi, instead of validating everything by hand (or not validating at all). But, if you are using it already: do you know any other cool trick or tweak? Let me know in the comments section below.</p><h3>References</h3><ul><li>Joi repo: <a href="https://github.com/hapijs/joi">https://github.com/hapijs/joi</a></li><li>Joi API Reference: <a href="https://github.com/hapijs/joi/blob/v10.6.0/API.md">https://github.com/hapijs/joi/blob/v10.6.0/API.md</a></li><li>Joigoose repo: <a href="https://github.com/yoitsro/joigoose">https://github.com/yoitsro/joigoose</a></li><li>Joi-browser repo: <a href="https://github.com/jeffbski/joi-browser">https://github.com/jeffbski/joi-browser</a></li><li>Mongoose website: <a href="http://mongoosejs.com/">http://mongoosejs.com</a></li><li>Vogels repo: <a href="https://github.com/ryanfitz/vogels">https://github.com/ryanfitz/vogels</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=84adc6f1474b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Still using GitFlow? What about a simpler alternative?]]></title>
            <link>https://medium.com/@brunoluiz/still-using-gitflow-what-about-a-simpler-alternative-74aa9a46b9a3?source=rss-20630242f3aa------2</link>
            <guid isPermaLink="false">https://medium.com/p/74aa9a46b9a3</guid>
            <category><![CDATA[deployment]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[git]]></category>
            <dc:creator><![CDATA[Bruno Luiz da Silva]]></dc:creator>
            <pubDate>Tue, 18 Jul 2017 00:04:30 GMT</pubDate>
            <atom:updated>2017-09-04T10:39:35.219Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_Y-nzMWT_ifHttX8hI3FQA.jpeg" /><figcaption>Alternative on sight…</figcaption></figure><p>GitFlow is a branching model created by Vincent Driessen on 2010 (<a href="http://nvie.com/posts/a-successful-git-branching-model/">original article</a>). Since it was published, many companies had tested and implemented it, which allows us to have many reviews about how well (or not) it works. After some discussions within our team, we decided to not go with GitFlow, but use a simpler model instead, together with a tightly defined workflow. Some of the discussed reasons of why not go with GitFlow are the same written on <a href="http://endoflineblog.com/gitflow-considered-harmful">this blog post</a>.</p><h3>The Feature Branch Model</h3><p>Compared to GitFlow, it is easier to implement and does not require any plugins to be properly used. The step-by-step of this model would be:</p><ol><li>Create a branch from the master (feature-x), which is where the feature will be developed: git checkout -b feature-x</li><li>Push the branch to the remote: git push -u origin feature-x. With the branch in the remote repo, a pull request should be opened with it (<a href="https://help.github.com/articles/creating-a-pull-request/">How to open it in GitHub</a>). A pull request is where all modifications are available to other members and they will be able to review it</li><li>Fix the reviewed code and wait for approval. If a new release on the master generates a conflict, a best practice would be to rebase it (instead of merging)</li><li>(optional) If a rebase is needed: checkout to master git checkout master, pull the changes git pull, go back to the feature branch git checkout feature-x, do the rebase git rebase master and then sync the rebased branch git push --force-with-lease . <a href="https://www.atlassian.com/git/tutorials/merging-vs-rebasing">A good tutorial about merging x rebasing is available on this Atlassian article</a>.</li><li>If there are no conflicts and it was approved ⇒ <strong>squash + merge</strong></li></ol><p><a href="https://www.atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow">This Atlassian article have a more detailed view on the feature branch model</a></p><h4>Why Squash + Merge instead of just Merge?</h4><p>The squash and merge is made up of two processes: the squash, which compact all commits in one big commit/patch, and then the merge itself. After squashing + merging, you will have only one commit in the target branch (usually master) containing all your modifications. This enables two things:</p><ol><li>It is easier to move this feature, as the whole patch/feature will be on one commit hash</li><li>The target branch will be cleaner, less messy and more readable — without those 67 commits you have made to finish the feature.</li></ol><p>There are more information about <a href="https://softwareengineering.stackexchange.com/questions/263164/why-squash-git-commits-for-pull-requests">about why devs prefers squash and merge, instead of only merging, on this article</a>.</p><h3>Managing release versions with git tags</h3><p>In the feature branch model, a merge is considered a new version release. To track each release version, tags can be used. These will be used as reference to choose which version should be deployed at the servers.</p><p>To manage these tags/release, a good practice is the usage of <a href="http://semver.org/"><em>semantic versioning</em></a><em>:</em></p><blockquote>Given a version number <strong>MAJOR.MINOR.PATCH</strong>, increment the:</blockquote><blockquote>1. MAJOR version when you make incompatible API changes,</blockquote><blockquote>2. MINOR version when you add functionality in a backwards-compatible manner, and</blockquote><blockquote>3. PATCH version when you make backwards-compatible bug fixes.</blockquote><p>The process to create the releases can be automated using <a href="https://github.com/geddski/grunt-release">grunt-release</a> or <a href="https://github.com/lfender6445/gulp-release-tasks">gulp-release-tasks</a>. But, following the steps bellow, it can be easily done by hand:</p><ol><li>Checkout to the master branch: git checkout master</li><li>Pull changes from the remote git pull</li><li>Get the most recent tag using git describe --abbrev=0 (let&#39;s say it returns v0.1.0)</li><li>Create a tag using git tag -a &lt;version&gt;⇒git tag -a v0.2.0</li><li>Push the modifications and the tag: git push origin v0.2.0 --follow-tags</li><li>Done!</li></ol><h3>Deploying</h3><p>In many PaaS, such as AWS Beanstalk or Heroku, a remote repository is set-up where, when changes are pushed (eg. git push heroku master), a deploy is triggered using the latest commits on master. In these cases, a simple push force using the release tag will deploy the desired version: git push -f &lt;deploy/env-remote&gt; v0.2.0^<strong>{}</strong>:master. Easy, eh?</p><blockquote>NOTE: At Chaordic New Offers Team, a grunt script was developed where we publish which tag should be deployed: grunt deploy:&lt;version&gt;:&lt;env&gt;:all</blockquote><h3>What happens if a hot-fix is needed?</h3><p>At some point, an issue will be raised and the production version will need a hot-fix <em>ASAP</em>. A feature branch can&#39;t just be opened to develop a fix, as the master will probably be ahead of the production version. In this case, the fix needs to be done directly on the production version:</p><ol><li>Checkout to the production version tag git checkout v0.10.0</li><li>Create a new branch from this tag git checkout -b hotfix-v0.10.1-weirdbehavior</li><li>Create the fix and commit it</li><li>Create a tag for this new release git tag -a v0.10.1 (notice the SEMVER pattern)</li><li>Push the branch and tag to remote git push -u origin hotfix-v0.10.1-weirdbehavior --follow-tags</li><li>Deploy the tag v0.10.1 to the production environment</li><li>A push request should be opened, as the fix should be applied at the master afterwards</li></ol><p>If more patches are needed, this process can be repeated on the same version, incrementing only the patch version.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2F13sc1Erq6rAoQU%2Ftwitter%2Fiframe&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2F13sc1Erq6rAoQU%2Fgiphy.gif&amp;image=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2F13sc1Erq6rAoQU%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="452" frameborder="0" scrolling="no"><a href="https://medium.com/media/364660922d3d96660250608a21ca716a/href">https://medium.com/media/364660922d3d96660250608a21ca716a/href</a></iframe><h4>What about applying it to other environments?</h4><p>This patch probably should be applied to other environments as well, which can be done through <a href="http://think-like-a-git.net/sections/rebase-from-the-ground-up/cherry-picking-explained.html">git cherry-pick</a> &lt;commit-hash&gt; . It basically applies the chosen commit to the actual HEAD.</p><ol><li>Checkout to the environment version tag git checkout v0.13.0</li><li>Create a new branch for the patch git checkout -b hotfix-v0.13.1</li><li>Do a git cherry-pick v0.10.1 or a git cherry-pick &lt;commit-hash&gt; to apply the desired commit</li><li>git tag -a v0.13.1 and git push origin v0.13.1 (push just the tag)</li><li>Deploy it</li></ol><h4>What if I want to get a modification from master and sent to one of the environments?</h4><p>It is very similar to the above one: a git cherry-pick should be done using a commit hash from the master as, after <strong>squash + merge</strong> a push request, a new commit is generated with all changes (big patch of commits condensed in one).</p><h3>Just keep in mind…</h3><p>The gap between the environments versions should be as short as possible. Otherwise, some issues may appear:</p><ul><li>If the production is on v0.1.10, the latest release is v0.10, but the version v0.3 will be deployed: the team members will have to check if some of the production patches are still required and then apply them, one by one.</li><li>If some feature was only finished on v0.10.0, and it is required for the roll-out, but the v0.7.0 is still not well tested: the release should be hold until the v0.7.0 has been tested</li></ul><p>Usually, these version gaps occur when the producing capacity is higher than the testing capacity (developers x testers ratio).</p><h3>Conclusion</h3><p>The model is still being tested but, until now, it has been working well. The only faced drawbacks were the ones pointed on the session above.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=74aa9a46b9a3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Are you using git push force? Oh mate, you are doing it wrong!]]></title>
            <link>https://medium.com/@brunoluiz/are-you-using-git-push-force-oh-mate-you-are-doing-it-wrong-b00674140e9d?source=rss-20630242f3aa------2</link>
            <guid isPermaLink="false">https://medium.com/p/b00674140e9d</guid>
            <category><![CDATA[git]]></category>
            <category><![CDATA[software]]></category>
            <category><![CDATA[development]]></category>
            <dc:creator><![CDATA[Bruno Luiz da Silva]]></dc:creator>
            <pubDate>Sat, 03 Jun 2017 23:13:28 GMT</pubDate>
            <atom:updated>2017-06-03T23:13:28.495Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/389/1*NJF7lpGTkoxYYCPwuXGuOA@2x.png" /></figure><p>You are developing some feature together with your team. Most likely you have done the usual dance: checkout a branch from the master or development branch, done your commits, pushed this feature branch to the remote and opened a push request for peer review.</p><p>In ideal cases, you will be able to just squash and merge after some reviews and fixes. But, the world is not ideal (as you might know), and maybe one of your mates modified the same files and already merged it. So, surprise surprise, you got a merge conflict to resolve!</p><p>This usually means you will need to do a <em>git rebase</em> before merging. After doing it, this new rebased branch need to be pushed back to the remote. And here is one of the steps that people usually do wrong:</p><pre>git push —-force</pre><p>You might be thinking: what is the problem with this?</p><p>Well, <strong>push force</strong> ignore everything on the remote and override it with local changes. This is &quot;kinda&quot; what you want, but what if you did some mistake in the rebase but didn&#39;t notice? Or someone pushed more modifications while you were rebasing? Yes, you thought right: kaputt, gone. One safer way to do this is using:</p><pre>git push --force-with-lease</pre><p>This simple command will not push force your modifications until it checked if everything that is in the remote is also in your rebased version. It is the same as a <em>push force</em>, but safer.</p><p>If you want to know more about it, checkout <a href="https://developer.atlassian.com/blog/2015/04/force-with-lease/">this article</a>. But the basic idea is: <strong>start to use <em>force-with-lease</em> instead of <em>force</em></strong>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b00674140e9d" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>