<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://islomar.es/feed.xml" rel="self" type="application/atom+xml" /><link href="https://islomar.es/" rel="alternate" type="text/html" /><updated>2026-02-15T18:55:58+01:00</updated><id>https://islomar.es/feed.xml</id><title type="html">Like tears in rain 🤖🚀</title><subtitle>Personal blog where I (have the intention to) write about product/software development, Psychology, Anthropology, Buddhism, Lean, eXtreme Programming (XP), DevOps or whatever I feel like 🙏</subtitle><author><name>Isidro López</name></author><entry xml:lang="en"><title type="html">Vertical Slicing Listicle</title><link href="https://islomar.es/vertical-slicing-listicle/" rel="alternate" type="text/html" title="Vertical Slicing Listicle" /><published>2025-06-08T19:41:41+02:00</published><updated>2026-02-15T17:21:41+01:00</updated><id>https://islomar.es/vertical-slicing-listicle</id><content type="html" xml:base="https://islomar.es/vertical-slicing-listicle/"><![CDATA[<p>Every time I arrive to a new company or team, one of the first things that I get myself doing is talking about <strong>vertical slicing</strong>: why it matters, techniques, workshops, etc. And then, I take a look for the n-th time to the resources I have saved in Notion, Drive, GitHub, or my hard-drive (distributed systems have their drawbacks 🤣), in order to share them (because… well, you know, sharing is caring 😄).</p>

<p>The goal of this post, which I will update whenever I discover more interesting resources, is to have in a single place the main resources that I have found valuable related with “vertical slicing”. Some people refer to it as <strong>story slicing</strong> or <strong>vertical story slicing</strong>: all sounds great to me. Personally, I prefer thinking of “story slicing” as the generic term, where we can find “tastes” like “vertical slicing” or “horizontal slicing”.</p>

<p>As usual: this post is for my future me, but I decided to share it in case it might be found useful for someone else 🙏</p>

<p>Although the goal of this post is not to explain what vertical slicing is and its benefits, I will do a quick and hypersimplified review of it:</p>

<h2 id="what-is-slicing">What is slicing?</h2>

<ul>
  <li>I love something I heard during a workshop with <a href="https://sessionize.com/kevin-meadows">Kevin Meadows</a> and <a href="https://chrispipito.com/">Chris Pipito</a>:
    <ul>
      <li><strong>“Getting to the smallest possible thing we can have a conversation about. ‘What can we do today, that can be used tomorrow?’ That can make tomorrow easier for customers, for users or for us.”</strong></li>
    </ul>
  </li>
  <li><strong>Horizontal slicing</strong> (PLEASE, AVOID IT 🙃):
    <ul>
      <li>“A horizontal slice tends to decompose problems into technical layers which may seem to match well with the technical skills of team members, i.e. they’re split amongst a database team, a UI team, and a server team each of which is responsible for their own tasks.
Even though we may call these horizontal slices user stories, and create them in form of user stories, they are in fact can’t deliver the value to the end customer without interaction or integration with other layers, components, or other building blocks of the software system. It is like slicing a cake horizontally, which does not allow for users to have the perfect bite.” (source: <a href="https://www.visual-paradigm.com/scrum/user-story-splitting-vertical-slice-vs-horizontal-slice/">User Story Splitting - Vertical Slice vs Horizontal Slice</a>)</li>
    </ul>
  </li>
  <li><strong>Vertical slicing</strong>:
    <ul>
      <li>Vertical slicing is a technique in agile product and software development where work is broken down into <strong>small</strong>, <strong>end-to-end</strong> increments that <strong>deliver value</strong> across <strong>all layers</strong> of the system—UI, backend, database, etc. Each “slice” represents a complete, functional piece of the product, allowing teams to build, test, and deliver working software <strong>iteratively</strong> and get <strong>early feedback</strong>.</li>
    </ul>
  </li>
</ul>

<div style="display: flex;
            align-items: stretch;
            justify-content: center;
            gap: 1em;
            margin: 2em 0;">
  <figure style="display: flex;
                 flex-direction: column;
                 justify-content: space-between;
                 margin: 0;
                 text-align: center;
                 width: 50%;">
    <img src="/assets/images/vertical_slicing_1.png" alt="Is this the alt??" style="max-width:100%; height:auto;" />
    <figcaption style="width: 100%; text-align: center; margin: 0;">
      <em>(from <a href="https://www.gianty.com/vertical-slice-game-development/" target="_blank" rel="noopener">
        Gianty
      </a>)</em>
    </figcaption>
  </figure>

  <figure style="display: flex;
                 flex-direction: column;
                 justify-content: space-between;
                 margin: 0;
                 text-align: center;
                 width: 30%;">
    <!-- here we add margin-top to push it down -->
    <img src="/assets/images/vertical_slicing_2.png" alt="A cake slice showing several horizontal slices with a cherry on top" style="max-width:100%; height:auto; margin-top:3em;" />
    <figcaption style="width: 100%; text-align: center; margin: 0;">
      <em>(from <a href="https://www.visual-paradigm.com/scrum/user-story-splitting-vertical-slice-vs-horizontal-slice/" target="_blank" rel="noopener">
        Visual Paradigm
      </a>)</em>
    </figcaption>
  </figure>
</div>

<h2 id="why-do-we-need-stories">Why do we “need” stories?</h2>

<ul>
  <li>Bridge <strong>business-technical communication</strong></li>
  <li>Focus on <strong>user value</strong> over tech specs</li>
  <li>Enable <strong>iterative and incremental delivery &amp; feedback</strong></li>
  <li>Support <strong>prioritization</strong> (and re-prioritization)</li>
  <li>Track progress</li>
</ul>

<p>My personal opinion: in order to enable and get its benefits, you need some principles and practices (e.g. from XP and Lean), e.g. parallel changes techniques, continuous delivery/deployment, deferring commitment, simplicity, a design that enables it (e.g. ports and adapters aka “hexagonal architecture” or some patterns from DDD), etc.</p>

<h2 id="some-techniques-and-heuristics">Some techniques and heuristics</h2>

<ul>
  <li><a href="https://www.humanizingwork.com/wp-content/uploads/2020/10/HW-Story-Splitting-Flowchart.pdf">How to split a user story (flowchart)</a>. For example:
    <ul>
      <li>Workflow steps</li>
      <li>Defer performance</li>
      <li>Simple/complex</li>
      <li>Operations</li>
      <li>Interface variations</li>
      <li>Business rule variations</li>
    </ul>
  </li>
  <li><a href="https://blogs.itemis.com/en/spidr-five-simple-techniques-for-a-perfectly-split-user-story">SPIDR – five simple techniques for a perfectly split user story</a> (6 min. read)
    <ul>
      <li>A technique by <a href="https://www.mountaingoatsoftware.com/company/about-mike-cohn">Mike Cohn</a></li>
    </ul>
  </li>
  <li><a href="https://www.agilelearninglabs.com/wp-content/uploads/2013/05/Splitting-User-Stories.pdf">Splitting User Stories</a>, from Agile Learning Labs
    <ul>
      <li><strong>Conjunctions</strong>: look for connector words, e.g. and, or, if, when, but, etc.</li>
      <li><strong>Generic words</strong>: look for generic words that could be replaced with more specific terms</li>
      <li><strong>Acceptance Criteria</strong></li>
      <li><strong>Timeline Analysis</strong></li>
    </ul>
  </li>
  <li><a href="https://gojko.net/2012/01/23/splitting-user-stories-the-hamburger-method/">Splitting user stories – the hamburger method</a> by <a href="https://gojko.net/">Gojko Adzic</a> (7 min. read)
    <ul>
      <li>I was lucky enough to attend in CraftConf 2016 his great “Specification by example” workshop (finally delivered by his partner)</li>
      <li><a href="https://ancaonuta.medium.com/hamburger-method-to-split-user-stories-from-dev-team-perspective-d17aba58be02">Hamburger technique to Split User Stories from Development team perspective</a></li>
    </ul>
  </li>
  <li><a href="https://www.slideshare.net/slideshow/effective-story-slicing/31078074">Effective story slicing</a> by <a href="https://www.neilkillick.com/">Neil Killick</a></li>
  <li><a href="https://somebetterways.substack.com/p/some-better-ways-for-user-story-slicing">Slice, slice, baby!</a>
    <ul>
      <li>By <a href="https://www.linkedin.com/in/rafael-sh">Rafael Sobrá</a>, based on a free workshop led by Chris Pipito and Kevin Meadows in December 2024, mentioned later</li>
    </ul>
  </li>
  <li><a href="https://www.goodreads.com/book/show/21411450-fifty-quick-ideas-to-improve-your-user-stories">50 quick ideas to improve your user stories</a> by <a href="https://gojko.net/">Gojko Adzic</a>
    <ul>
      <li>A highly recommended book with tones of great techniques and heuristics for getting better in vertical slicing.</li>
      <li>Some examples mentioned:
        <ul>
          <li>Narrow down your user segment</li>
          <li>Split by capacity</li>
          <li>Start with dummy, then move to dynamic</li>
          <li>Simplify outputs</li>
          <li>Split learning from earning</li>
          <li>Extract basic utility</li>
          <li>When all else fails, slice the hamburger
            <ul>
              <li>User story mapping</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
  <li><a href="https://xp123.com/slicing-functionality-alternate-paths/">Slicing Functionality: Alternate Paths</a></li>
</ul>

<h2 id="workshops">Workshops</h2>

<ul>
  <li><a href="https://alistaircockburn.com/Elephant-Carpaccio">Elephant Carpaccio (by Alistair Cockburn)</a>
    <ul>
      <li><a href="https://blog.crisp.se/2013/07/25/henrikkniberg/elephant-carpaccio-facilitation-guide">Facilitation guide (by Henrik Kniberg)</a></li>
    </ul>
  </li>
  <li><a href="https://www.eferro.net/p/small-safe-steps-3s-workshop.html">Small Safe Steps workshop (parallel changes)</a> by <a href="https://www.eferro.net/">Edu Ferro</a></li>
  <li><a href="https://www.linkedin.com/posts/jkmeadows_free-story-slicing-workshop-activity-7272369317571096576-uNyE/">User Story Slicing: deliver today what can be used tomorrow</a>
    <ul>
      <li>A 2-hour, online, hands-on workshop facilitated by <a href="https://teamingwithsasquatch.com/">Chris Pipito</a> &amp; <a href="https://www.linkedin.com/in/jkmeadows/">Kevin Meadows</a></li>
      <li>Amazing one, I was really lucky to be able to attend it some time ago. They offer it among their services, I wouldn’t doubt to purchase it (disclaimer: I get no benefits from it, besides spreading happiness 😅)
        <ul>
          <li><a href="https://www.tickettailor.com/events/chrispipito/1521015">https://www.tickettailor.com/events/chrispipito/1521015</a></li>
        </ul>
      </li>
      <li>Connector Types Reference:
        <ul>
          <li><strong>Coordinating Conjunctions</strong>: and, or, but, yet, nor, etc.</li>
          <li><strong>Action-Related Connectors</strong>: manage, handle, support, process, maintain, administer, etc.</li>
          <li><strong>Sequence Connectors</strong>: before, after, hen, while, during, when, etc.</li>
          <li><strong>Scope Indicators</strong>: including, as-well-as, along with, also, additionally, plus, with, etc.</li>
          <li><strong>Option Indicator</strong>: either/or, whether, alternatively, optionally, etc.</li>
          <li><strong>Exceptions Indicators</strong>: except, unless, however, although, despite, etc.</li>
        </ul>
      </li>
      <li><strong><em>“After slicing, can we pick one slice that is small enough to build today for use tomorrow?”</em></strong></li>
    </ul>
  </li>
</ul>

<h2 id="related-interesting-resources">Related interesting resources</h2>

<ul>
  <li><a href="https://github.com/abrahamvallez/bokata-slicer-cc">Intelligent vertical slicing and feature decomposition for Claude Code using the Hamburger Method and radical vertical slicing techniques</a></li>
  <li><a href="https://www.eferro.net/2025/01/developing-software-postponing.html">Developing Software: Postponing Decisions and Working in Small Steps</a> by Edu Ferro (17 min. read)</li>
  <li><a href="https://www.geepawhill.org/series/many-more-much-smaller-steps/">MMMSS: Many More Much Smaller Steps</a>, a great series of articles by Geepaw Hil</li>
  <li><a href="https://docs.google.com/document/d/1bXAGIueSCZiclhVD_uNph4BzO47EHpkw/edit">Think About How You Organize Your Work</a>, by Don Reinertsen (4 min. read)</li>
  <li><a href="https://www.eferro.net/2022/08/software-development-art-of-postponing.html">Lean Software development: The art of postponing decisions</a> by Edu Ferro (9 min. read)</li>
  <li><a href="https://jpattonassociates.com/5-story-mapping-mistakes/">Five common story mapping mistakes</a> by Jeff Patton (8 min. read)</li>
  <li><a href="https://leanpub.com/software-economics">Software economics</a> by Luis Artola (only in Spanish)</li>
  <li><a href="https://www.industriallogic.com/blog/return-of-the-horizontal-slice/">Return of the horizontal slice</a> by Joshua Kerievsky (4 min. read)</li>
  <li><a href="https://www.visual-paradigm.com/scrum/user-story-splitting-vertical-slice-vs-horizontal-slice/">User Story Splitting - Vertical Slice vs Horizontal Slice</a> (7 min. read)</li>
  <li><a href="https://www.youtube.com/watch?v=ajYN66GCpf8">Vertical Story Slicing</a> (video, 53 min.)</li>
  <li><a href="https://www.youtube.com/watch?v=R_JQGXmrkyY">Agile Delivery - Lean Coffee - Slicing (in Spanish)</a> (1 hour 35 min, video)</li>
</ul>

<h3 id="llms">LLMs</h3>

<ul>
  <li><a href="https://www.eferro.net/2025/06/built-custom-gpt-to-help-teams-ship.html">Lean GPT</a>
    <ul>
      <li>Edu Ferro built a Custom GPT to help teams ship smaller, safer, faster. It challenges assumptions, guides toward small safe steps, enables continuous learning and delivery.</li>
      <li>For developers, PMs, designers, architects—anyone building products.</li>
      <li><a href="https://chatgpt.com/g/g-693d314e7f888191ac8efcafafcb60ff-eferro-lean-discovery">Lean Discovery</a></li>
      <li><a href="https://chatgpt.com/g/g-693c4a50a404819184a8dc938be0cfbe-eferro-lean-delivery">Lean Delivery</a></li>
    </ul>
  </li>
  <li><a href="https://github.com/abrahamvallez/bokata-skills">Bokata: Vertical Slicing &amp; Task Decomposition Prompt Framework</a>, by Abraham Vállez
    <ul>
      <li>Bokata is a prompt engineering framework designed to guide Large Language Models (LLMs) in decomposing complex software requirements into incremental, high-value, and actionable development plans.</li>
      <li>Using techniques like Vertical Slicing and User Story Mapping, Bokata transforms vague ideas or large PRDs into a structured “Walking Skeleton” and a prioritized backlog of functional increments.</li>
    </ul>
  </li>
</ul>

<h2 id="further-interesting-topics-tools-and-techniques">Further interesting topics, tools, and techniques</h2>

<ul>
  <li><a href="https://gojko.net/2012/01/23/splitting-user-stories-the-hamburger-method/">Hamburger method</a></li>
  <li><a href="https://jpattonassociates.com/story-mapping/">User Story Mapping</a></li>
  <li><a href="https://en.wikipedia.org/wiki/INVEST_(mnemonic)">INVEST</a></li>
  <li><a href="https://www.impactmapping.org/">Impact mapping</a></li>
  <li><a href="https://en.wikipedia.org/wiki/Value-stream_mapping">Value stream mapping</a>
    <ul>
      <li><a href="https://www.goodreads.com/book/show/17718225-value-stream-mapping">Great book here</a></li>
    </ul>
  </li>
  <li><a href="https://www.nngroup.com/articles/user-journeys-vs-user-flows/">User journeys</a></li>
  <li><a href="http://www.domainstorytelling.org/">Domain storytelling</a></li>
  <li><a href="https://www.eventstorming.com/">Event storming</a></li>
  <li><a href="https://jobstobedone.org/">Jobs-to-be-Done framework (JTBD)</a></li>
  <li><a href="https://en.wikipedia.org/wiki/Opportunity_cost">Opportunity cost</a></li>
  <li><a href="https://blackswanfarming.com/cost-of-delay-divided-by-duration/">Cost of Delay and CD3</a></li>
  <li>Technical slicing
    <ul>
      <li><a href="https://martinfowler.com/bliki/ParallelChange.html">Parallel changes</a></li>
      <li><a href="https://iadb.notion.site/Story-slicing-Technical-0db4467761e842a883b4b80462b7c01d">Story slicing – Technical</a></li>
    </ul>
  </li>
  <li><a href="https://alistair.cockburn.us/hexagonal-architecture">Ports &amp; Adapters, aka “Hexagonal Architecture”</a></li>
</ul>

<p>Feel free to suggest other resources that you have found helpful, insightful, or illuminating!! 😊🙏</p>]]></content><author><name>Isidro López</name></author><category term="blog" /><category term="english" /><category term="agile" /><category term="product-management" /><category term="story-slicing" /><category term="vertical-slicing" /><summary type="html"><![CDATA[Every time I arrive to a new company or team, one of the first things that I get myself doing is talking about vertical slicing: why it matters, techniques, workshops, etc. And then, I take a look for the n-th time to the resources I have saved in Notion, Drive, GitHub, or my hard-drive (distributed systems have their drawbacks 🤣), in order to share them (because… well, you know, sharing is caring 😄).]]></summary></entry><entry xml:lang="en"><title type="html">Questions and answers from my talk at the BilboStack 2024 conference</title><link href="https://islomar.es/questions-and-answers-bilbostack-2024/" rel="alternate" type="text/html" title="Questions and answers from my talk at the BilboStack 2024 conference" /><published>2025-03-16T16:26:27+01:00</published><updated>2025-03-16T16:26:27+01:00</updated><id>https://islomar.es/questions-and-answers-bilbostack-2024</id><content type="html" xml:base="https://islomar.es/questions-and-answers-bilbostack-2024/"><![CDATA[<blockquote>
  <p>This is the <strong>English version</strong> for <a href="/preguntas-y-respuestas-bilbostack-2024">the post I wrote in March 2024</a> answering several highly interesting questions related to my talk at the BilboStack conference about <strong>Continuous Deployment</strong> (including a lot of product-mindset, eXtreme Programming, and Lean Product Development values, principles and practices).</p>
</blockquote>

<blockquote>
  <p>There were questions related with code freezes, branching strategies, teams in distributed timezones, painful experiences with Git Hooks, async PRs, pairing, parallel changes techniques, technical debt, outside-in TDD, how to deal with deployment coupling between front-back, achieving ISO 27001/SOC2 certifications while practicing continuous deployment, etc.</p>
</blockquote>

<h1 id="questions-and-answers-from-my-talk-at-bilbostack-2024">Questions and Answers from My Talk at BilboStack 2024</h1>

<p>When at the wonderful <a href="https://bilbostack.com/" target="_blank" rel="noopener noreferrer">BilboStack</a> I finished <a href="/slides-and-resources-talk-bilbostack-2024">my talk on Continuous Deployment</a> (I’ll never get tired of repeating that it was just an excuse to talk about “what really matters”, which is the ability to deliver value in a continuous and sustainable way, while enjoying the journey), I was informed that there were no questions 😱<br />
In my experience, when that happens it means the level of boredom was astronomical and the message didn’t land at all 😅</p>

<p>Luckily, it seems the explanation was less dramatic: there was some problem with the application that collected the questions (was a test missing? 😜). The organizers were kind enough to send them to me afterwards, so I’ll try to answer them in this post.</p>

<p><strong>Important clarification</strong>: I lack a lot of context in almost every question; I would need to understand many things better before giving a “reasonable” answer. I’ll make this explicit in some responses and infer it in others 🙏</p>

<hr />

<ol>
  <li><strong>Can you explain how to achieve ISO 27001/SOC2 while working in continuous delivery?</strong>
    <ul>
      <li><strong>Summary:</strong> Not really 🤣 But I can share a few tidbits that might help somewhat…</li>
      <li>One thing I mentioned the other day while talking with someone about this topic is that we tend to take too many things for granted. The very first thing we must always do is to <strong>UNDERSTAND</strong> in depth the needs to be met. I think there is a lot of “broken telephone” at play and we infer that many things are needed that are actually potential solutions (e.g. having a PR) rather than the underlying need to be solved (e.g. that more than one person has reviewed something).</li>
      <li>That said: I know that the auditor you get can influence things a lot.</li>
      <li>At a much higher level, Clarity published a post about this: <a href="https://medium.com/clarityai-engineering/iso27001-and-soc2-type-ii-from-greenfield-to-success-24ca99decb26">“ISO27001 and SOC2 Type II from Greenfield to Success”</a></li>
      <li>In my team we actually practiced “Continuous Deployment” and in our case it was enough to follow these requirements:
        <ul>
          <li>Each commit included the <strong>Jira issue</strong> that originated it – generating an unequivocal trace to the need that gave rise to that code.</li>
          <li>Since we worked in pairing or ensemble programming by default, every commit included all the people involved by using Git’s <strong><a href="https://docs.github.com/es/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors">“Co-authored-by” feature</a></strong>
            <ul>
              <li>To reduce friction, we all had a shared <strong><a href="https://gist.github.com/lisawolderiksen/a7b99d94c92c6671181611be1641c733">git message template</a></strong> with the rest of our team members, so we didn’t have to keep writing it.</li>
              <li>As far as I know, and simplifying a lot, one of the things required is <strong>evidence</strong> that someone other than the code’s author has reviewed it. This practice satisfied that need.</li>
            </ul>
          </li>
          <li>If the change to be made was “very trivial” (which is always abstract, but we had a document defining it), it was allowed that no reviewer existed (e.g. a change in documentation). In these cases, it was enough to include in the commit message a certain keyword (in our specific case, <code class="language-plaintext highlighter-rouge">[trivial-small-change]</code>).</li>
        </ul>
      </li>
      <li>For people working with branches and PRs/MRs, the person who validated the PR had to be different from the one who opened it.</li>
      <li>If you need more detail, perhaps <a href="https://www.eferro.net/">Edu Ferro</a> can tell you more things 🙏</li>
    </ul>
  </li>
  <li><strong>What do you think of code freezes? Do they make sense in certain cases? For example, a large company with teams distributed across different time zones.</strong>
    <ul>
      <li>Questions that come to mind:
        <ul>
          <li>Are we talking about distributed teams or distributed systems? Or both?</li>
          <li>When we talk about distributed teams, is it on an individual level or at the team level? Are all members of the same team in very different time zones? Or is the dispersion at the team level? (That is, members of the same team in a similar time zone, but each team in very different time zones)</li>
        </ul>
      </li>
      <li>Although I believe everything can make sense in some context, in general “code freezes” (especially if they occur relatively frequently) are a bad symptom. The mere fact of being a large company with teams distributed across different time zones does not imply that those code freezes should exist. Each team should have end-to-end ownership of a “value stream” (see the <a href="https://martinfowler.com/bliki/TeamTopologies.html">“stream-aligned teams” of Team Topologies</a>).</li>
      <li>Here Conway’s Law (and its reverse) comes into play, and one must be very careful with how teams, systems, and their responsibilities are designed.</li>
      <li>Something that can also help is the existence of <a href="https://medium.com/agile-outside-the-box/team-apis-af2dbc1805e7">“Team APIs”</a>.</li>
      <li>Depending on the degree of overlapping hours, “core” hours can be set for pairing/ensemble work.</li>
      <li>If we talk about distributed individuals: a branching strategy like <a href="https://martinfowler.com/articles/ship-show-ask.html">“Ship, Show, Ask”</a> might be interesting.</li>
      <li>If what we’re discussing is a distributed system and not only distributed teams (which is not the same), then it is essential to perform very good <a href="https://martinfowler.com/bliki/ContractTest.html">“Contract Testing”</a>: each system/service should be functionally testable in isolation without depending on the rest. This is independent of having additional end-to-end tests (which, in complex distributed systems, becomes quite complicated).</li>
    </ul>
  </li>
  <li><strong>Thanks for the talk! In your opinion, what would be a good branching strategy? Currently, having baby-commits and merging into the main branch, we opt for squash and merge, which creates a new commit and loses the trace of the old commits, leading to a commit hell when reviewing PRs. They usually ask us to try to make a single commit per feature and then merge (not fast-forward) and I manage that with git –amend.</strong>
    <ul>
      <li>My first answer: “it depends” 😜</li>
      <li>My second answer: the branching strategy that generally allows for fast feedback and a continuous, sustainable value contribution is “Trunk-Based Development”, better with a single default branch (accompanied, as I mentioned in the talk, by pair/ensemble programming, TDD, a secure, repeatable, and powerful pipeline, micro-commits, etc.).</li>
      <li>Personally, I prioritize the continuous flow and getting the commit to Production as soon as possible over having an “immaculate” commit history. What is always important is that the commits are descriptive and clearly state the “why” above all (“the what” is implicit in the commit).</li>
      <li>In line with what you mentioned, the good folks at <a href="https://codely.com/">Codely</a> recorded a video a couple of years ago with their opinions on the matter. I think it might interest you if you can’t work with a single branch. I highly recommend it (it’s in Spanish): <a href="https://www.youtube.com/watch?v=HlmZLXMOpEM">“Git Merge vs Rebase vs Squash: Which strategy should we choose?”</a></li>
    </ul>
  </li>
  <li><strong>What are the advantages and disadvantages of having tests in a Git hook?</strong>
    <ul>
      <li><strong>Clarification:</strong> Everything you put in Git hooks must be “fast.” What “fast” means depends on the sensitivity of each person or team, but in my experience any execution that exceeds 5 seconds starts to “hurt” (pushes can take a little longer because we run them less frequently, but not much longer). In any case, and in my opinion, it’s better to wait “a little” at the time of commit-push than to face too many “surprises” later (a context switch problem). Also, in my opinion, it is wise to balance what is included in the pre-commit and what in the pre-push (see <a href="./2024-01-29-slides-and-resources-talk-bilbostack-2024.md">examples in the diagrams with real cases from the talk</a>).</li>
      <li><em>Advantages:</em> You get much faster feedback if tests fail (you don’t have to wait for them to fail in the pipeline when you’ve already switched focus and are halfway through something else). Of course, I wouldn’t include the slower tests, but only the “fast” ones (in my opinion all unit tests should be fast, as well as some integration tests – what I consider “unit” or “integration” could be a post on its own).</li>
      <li><em>Disadvantages:</em> The problem arises if their execution is “too slow”; what will eventually happen is that we’ll skip them or accumulate too many changes. The solution is to have only the fastest tests or those that do not cause too much slowdown in the Git hooks. Parallelizing their execution as much as possible is important to reduce times.</li>
    </ul>
  </li>
  <li><strong>At first glance, very interesting. As a question: didn’t you notice that pre-commit and pre-push hooks could add friction and latency in the commit process, leading the team to make larger commits to avoid running linting, tests, etc. multiple times?</strong>
    <ul>
      <li>Very good question, and unfortunately it is not uncommon for that to happen. One must be very alert about it. I tried to address it in the previous question ☝️🙏</li>
    </ul>
  </li>
  <li><strong>Synchronous validations or asynchronous PR validations?</strong>
    <ul>
      <li>I’m not sure if I understand this question, sorry. What do you mean by “validations”? Are we talking about tests? Linters? Or code review?</li>
      <li>In line with what I mentioned in the talk: we must try to get feedback as fast and as frequently as possible for everything. As much as possible, I would prioritize synchronous code reviews; and even better: do as much pairing/ensemble work as possible.</li>
      <li>I would also recommend taking a look at the branching strategy <a href="https://martinfowler.com/articles/ship-show-ask.html">“Ship, Show, Ask”</a>, which might be interesting as a step toward reducing integration times.</li>
    </ul>
  </li>
  <li><strong>When the “vicious cycle” you showed at the beginning becomes so large, how do you get out of it?</strong>
    <ul>
      <li>Uuufffff, a difficult question (or rather, a difficult answer 😅). The first necessary step is to have a general awareness of the problem and its nature (I would say that this is the hardest part). Making it visible and explicit, with data, always helps (for example, measuring the time from the moment we make a commit until it reaches Production), putting it in black and white.</li>
      <li>The next important step is to really want to invest time in solving it, to clearly see the benefit that solving it can bring (which again is very difficult if it hasn’t been experienced before).</li>
      <li>If all of the above is met: take it slowly. First, identify any “quick wins” that may exist (low cost and high benefit). Improve automated testing. Gradually reduce branch/PR times as much as possible. Adopt branching strategies that decrease the time it takes to integrate into the main branch. Increase and improve collaboration (e.g., through pairing). Learn techniques for parallel changes and start using “feature flags.”</li>
    </ul>
  </li>
  <li><strong>How can you showcase the contribution of CI/CD and overcome developers’ fear of deploying things early?</strong>
    <ul>
      <li>In my experience, the best way I’ve seen is to <strong>lead by example</strong> (which requires experience doing so), while also providing a lot of education about the value it brings to everyone, both business and engineering. I don’t think there are shortcuts or magic formulas… 😕 Of course, that “deploying things early” must be accompanied by a robust safety net; otherwise, the remedy will be worse than the disease, and understandably people won’t want to do it.</li>
    </ul>
  </li>
  <li><strong>Do you use pairing strategies like ping-pong? In these cases, wouldn’t the use of Git hooks be annoying?</strong>
    <ul>
      <li>In the past, I have done pairing with TDD using ping-pong (I’d say I have done pairing in almost every possible mode 🤣).</li>
      <li>When I did ping-pong (Person A writes the test, Person B makes it pass, refactors, then Person B writes the next test, etc.) we did it by sharing the terminal (that is, both people really worked on the same machine, using <a href="https://tmate.io/">tmate</a>). This implies that we did not commit until the test was green (and therefore Git hooks were not a problem).</li>
      <li>One thing I would never do, regardless of Git hooks, is push code to the main branch without tests.</li>
      <li>There are people who use <a href="https://github.com/remotemobprogramming/mob">this tool</a> which might cover certain use cases (personally, I prefer not doing ping-pong and simply rotate by pomodoro, which is enough).</li>
      <li>On the topic of pairing, this post is really good: <a href="https://martinfowler.com/articles/on-pair-programming.html">On Pair Programming</a></li>
    </ul>
  </li>
  <li><strong>Can having too many micro-commits get the main branch “dirty”?</strong>
    <ul>
      <li>It depends on what is meant by “dirty”. What is always important is that commits have good messages, clearly describing the “why,” and of course no commit should break the tests.</li>
      <li>That said, I believe it is more important to take small steps and have continuous feedback and flow than to maintain a supposedly “ideal” commit history.</li>
    </ul>
  </li>
  <li><strong>Generally, it is required that a feature be complete before being pushed and they don’t want to see anything until it’s finished. Would trunk-based development be applicable?</strong>
    <ul>
      <li>Absolutely. To resolve the problem you describe, which is very common, there are multiple techniques for parallel changes (<a href="https://islomar.es/blog/talks/slides-and-resources-talk-bilbostack-2024/#parallel-changes">I included some information on this</a>) and, above all, the use of <a href="https://martinfowler.com/articles/feature-toggles.html">feature flags/toggles</a>.</li>
      <li>This is related to the decoupling I mentioned during the talk between “Deployment” (a technical decision) and “Release” (a business decision).</li>
    </ul>
  </li>
  <li><strong>For using CD with trunk-based development, when making commits and pushing them, did you have any configuration to prevent commits that don’t pass tests?</strong>
    <ul>
      <li>Yes, we had Git hooks configured for both pre-commit and pre-push. In the <a href="/slides-and-resources-talk-bilbostack-2024">diagrams from the slides of the talk</a> you can see what we included in each.</li>
    </ul>
  </li>
  <li><strong>To the question someone asked: “It’s to change the world, because to a greater or lesser extent when we push a change, it changes the lives of some people (for better or for worse) – our users or clients, because they have tools to do their work better.”</strong>
    <ul>
      <li>I understand this is the answer to the question I posed: “Why do we develop software professionally?” I find this perspective wonderful, truly—I feel very aligned with the idea underlying it.</li>
      <li>Regarding the nuance I mentioned in my answer that I wanted to highlight, I would say: what if you could change/improve the world more optimally/efficiently <strong>WITHOUT</strong> software—wouldn’t you do it? 😉</li>
    </ul>
  </li>
  <li><strong>Do you think it makes sense to run several CI processes in parallel? For example, unit tests, building the build, and e2e tests at the same time?</strong>
    <ul>
      <li>Yes, but it depends on which ones. Without a doubt, <strong>we must parallelize everything possible</strong>, starting with the tests themselves (almost all testing libraries allow parallel execution); additionally, it forces us to write “self-contained” tests whose input or output does not depend on other tests (which is by default what is most recommended). There should be no issue with unit and integration tests. With e2e/acceptance tests it might be different (it’s worth differentiating which ones can be parallelized and doing so).</li>
      <li>In the <a href="https://speakerdeck.com/islomar/valor-por-encima-de-codigo-el-poder-del-despliegue-continuo?slide=44">two real-life examples I included</a> you can see what we parallelized and what we didn’t; I’d say almost everything was done with great awareness (and always improvable) 😊</li>
      <li>For example, regarding the second pipeline, I can explain why we didn’t parallelize those three tasks in particular:
        <ul>
          <li>We did not want to invest time in building the Docker image (and subsequently pushing it to an ECR) if the tests didn’t pass first.</li>
          <li>Unit tests are the fastest and the most blocking: we don’t want to do anything else if they fail (another reason not to parallelize them with some other tasks). We can parallelize them with other equally fast tasks, such as linters and other static validations.</li>
          <li>As for e2e tests: in our testing taxonomy, these are tests we run against the new version of the system already deployed somewhere (staging or production), so we couldn’t parallelize them with the build or unit tests either.</li>
          <li>The tests we did parallelize as the first step in the pipeline were the <strong>unit tests</strong> (which follow the <a href="https://github.com/tekguard/Principles-of-Unit-Testing" target="_blank" rel="noopener noreferrer">FIRST principles</a>), <strong>integration tests</strong> (in our case tests for the secondary adapters of <a href="https://herbertograca.com/2017/09/14/ports-adapters-architecture/" target="_blank" rel="noopener noreferrer">our hexagonal architecture</a>), and acceptance tests (which are tests “from the outside” run against the system that includes the updates, brought up “locally” before being deployed).</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><strong>When doing TDD outside-in, you first write tests from the user’s perspective but then, do you continue with more internal tests?</strong>
    <ul>
      <li>Exactly, that’s the idea. It’s similar to <a href="https://www.agilealliance.org/glossary/atdd/">Acceptance TDD</a>, <a href="https://gojko.net/books/specification-by-example/" target="_blank" rel="noopener noreferrer">Specification by Example</a>, or <a href="https://dannorth.net/introducing-bdd/" target="_blank" rel="noopener noreferrer">Behaviour-Driven Development (BDD)</a> (there are nuances among the three, but in all cases we seek to test the system’s behavior from the perspective of its external user).</li>
      <li>I would say that perhaps it is not always possible (I don’t always manage it), but it should be the primary approach: when done that way, the development experience is fantastic (and of course so is the user experience) 😍</li>
    </ul>
  </li>
  <li><strong>Do you consider it indispensable that continuous delivery always goes all the way to production? Wouldn’t it be enough with a Test environment that is a replica of Production to avoid risks?</strong>
    <ul>
      <li>We must not confuse “Continuous Delivery” with “Continuous Deployment.” In the first part of my talk I tried to explain <a href="https://speakerdeck.com/islomar/valor-por-encima-de-codigo-el-poder-del-despliegue-continuo?slide=16" target="_blank" rel="noopener noreferrer">the differences</a>.</li>
      <li>With <strong>“Continuous Delivery”</strong>, indeed the pipeline does not deploy to Production. It may, for example, stop at a pre-production environment (e.g. Staging). The important thing is that once our code is integrated into the main branch and the build and automated tests have run, it remains in a “deployable state”: whenever we want, we could deploy it to Production (and that deployment should be simple and repeatable).</li>
      <li>With <strong>“Continuous Deployment”</strong>, on the other hand, the entire pipeline is completely automated, including the step of deploying to Production.</li>
      <li>In the first pipeline example I mentioned, we had Continuous Deployment but we still deployed first to a Staging environment: after deploying there, several e2e and smoke tests ran automatically and, if everything worked correctly, it was automatically deployed to Production.</li>
    </ul>
  </li>
  <li><strong>Understanding that a release is a business concept rather than a technological one, why is taking <em>product delivery lead time</em> as a metric important? Isn’t that something outside of technology’s control?</strong>
    <ul>
      <li>Good question. My answer: because it is fundamental to see it as a “whole.” From the perspective of engineering/technology, we must understand that technology is a means to an end.</li>
      <li>To me, it is one of the keys to evolving toward “product engineering”: understanding that ALL of us are part of the product and the business, and that what we do must meet user needs.</li>
      <li>In reality, from an engineering perspective we can and should influence the “product delivery lead time” much more than we think. I have often seen product managers’ vision change (for the better) when developers bring to the table simpler ways to start satisfying user needs.</li>
      <li>Obviously, the appropriate company culture is needed for this to occur so that we do not end up with isolated silos where “business” and “technology” are completely separated: we must move toward understanding that <strong>we are all the PRODUCT</strong> and need to collaborate continuously and intensively.</li>
    </ul>
  </li>
  <li><strong>When always working on the same branch, if you push to the server and something fails, as part of that rollback is a commit with a revert automatically generated? Or would the main branch be blocked?</strong>
    <ul>
      <li>First, let’s do what we can in each context, which is already a lot 😄</li>
      <li>In the <a href="https://speakerdeck.com/islomar/valor-por-encima-de-codigo-el-poder-del-despliegue-continuo?slide=45" target="_blank" rel="noopener noreferrer">second real-world example</a> that I shared in the talk, it was a very quick rollback of the deployment, so no commit was generated. To give more technical details, we did the <a href="https://helm.sh/docs/helm/helm_rollback/" target="_blank" rel="noopener noreferrer">rollback with helm</a> (which was also what we used for deployment).</li>
      <li>When that happened, we received a message in the team Slack channel for important issues (e.g. any pipeline failure).</li>
      <li>The automatic rollback in Production gave us the peace of mind of knowing that the system remained in a stable state, with the previous version still functioning.</li>
      <li>Once we finished the pomodoro that was in progress (we primarily work in <em>ensemble</em>), we immediately prioritized checking what had failed and resolving it. There was no “blockage” of the main branch because we worked in <em>ensemble</em>. But if that were not the case—as I mentioned in the talk—fixing a broken pipeline must be <strong>PRIORITY</strong>, meaning it isn’t that the branch stays blocked; it must be fixed immediately, and everyone on the team, regardless of who made the commit that broke it, works together (I believe that a change in mindset is important, and working in isolation and very individually doesn’t help).</li>
      <li>Working in a single branch with lead times of minutes, there was no need for the concept of a “hot fix”: after the automatic rollback, we fixed the issue as soon as possible (within a few minutes) and committed the fix (with an automated test included to avoid recurrence, if possible) and then moved on 😉</li>
      <li>Part of the philosophy here is that when there is an incident in Production, the first and most important thing is to get Production back up and running as soon as possible—whether by reverting to the previous version or by quickly committing a solution.</li>
      <li>Over two years, there have been very few occasions when such a rollback occurred (we had a very strong safety net in place). We must not get used to it happening all the time; that would be a symptom of needing to invest in improving the safety net.</li>
    </ul>
  </li>
  <li><strong>Thanks for the great talk, you rock! I love your point about discipline and especially about the bottleneck focused on knowledge! I have a question: This world has evolved with terms like CI/CD and others such as DevOps, DevSecOps. What do you think about this? Who should have this responsibility, an individual or a team? I’d love to know your perspective.</strong>
    <ul>
      <li>Thanks! Well, <a href="https://www.youtube.com/watch?v=GYtzu_G4A4M">in my opinion</a> with DevOps we have reached a situation of <a href="https://martinfowler.com/bliki/SemanticDiffusion.html">“semantic inversion”</a>: it ended up meaning exactly the opposite of what was intended. The goal was to improve collaboration and break down silos of knowledge, blockers, and hot potato handoffs, but in general it ended up with “DevOps teams” (essentially a renaming of the “systems team”) that continue to maintain silos, blocking dependencies, etc. <em>&lt;/rant&gt;</em></li>
      <li><a href="https://martinfowler.com/bliki/DevOpsCulture.html">DevOps</a> is a culture, not a team. This is not incompatible with having, for example, <a href="https://martinfowler.com/bliki/TeamTopologies.html">platform or enabler teams that make life easier for the “stream-aligned teams”</a> through various self-service tools and services. But teams—say, “external product teams”—should not have blocking dependencies on those teams.</li>
      <li>The same applies to DevSecOps: as much as possible it should be integrated into the deployment/delivery pipeline, probably supported by services/tools from other teams.</li>
    </ul>
  </li>
  <li><strong>Do you think the trunk/CI approach is valid for addressing technical debt or for sustaining tasks like upgrading versions of frameworks or libraries? Or is it something exclusive to product delivery?</strong>
    <ul>
      <li>Absolutely, I believe that TBD/CI can be applied in multiple contexts.</li>
      <li>In fact, I think the best way to address <strong><a href="https://martinfowler.com/bliki/TechnicalDebt.html" target="_blank" rel="noopener noreferrer">technical debt</a></strong> (which, by the way, we need to be sure we are talking about the same thing 😄) is gradually. Running “technical debt sprints” is usually a symptom of a lack of “slack” in the team (among other things).</li>
      <li>Regarding framework/library updates: here I’d say it depends.
        <ul>
          <li>For library updates, I’d say yes (in my team we used <a href="https://github.com/renovatebot/renovate" target="_blank" rel="noopener noreferrer">renovatebot</a> to automatically update all libraries on a daily basis, and the pipeline still deployed at the end). But again, I repeat: you need a very robust safety net, especially very good automated tests.</li>
          <li>As for framework updates: it depends on the implications of the change. Normally yes, but when they are <em>major</em> versions, it is not unlikely that the impact is significant enough to require doing it in a branch that lives for more than 24 hours so you can change and test everything calmly.</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><strong>Do you have any suggestions or techniques for running E2E tests in Production? For example, synthetic traffic, traffic mirroring, etc.?</strong>
    <ul>
      <li>Interesting question 😄 The answer is: “it depends on the context” (sorry, not sorry). To share a couple of very different cases I’ve encountered (among many others):
        <ul>
          <li><strong>At <a href="https://clarity.ai/" target="_blank" rel="noopener noreferrer">Clarity AI</a>:</strong>
            <ul>
              <li>See the <a href="https://speakerdeck.com/islomar/valor-por-encima-de-codigo-el-poder-del-despliegue-continuo?slide=45" target="_blank" rel="noopener noreferrer">second real-life pipeline example</a> that I shared.</li>
              <li>There we had several e2e tests (those that mimic a real user): some using <a href="https://www.cypress.io/" target="_blank" rel="noopener noreferrer">Cypress</a> (the main service was a <a href="https://api.slack.com/interactivity/slash-commands" target="_blank" rel="noopener noreferrer">Slack app (with a slash command)</a>, so these tests actually accessed Slack from a browser and executed various commands) and some in pure Python (making HTTP requests to some endpoints that we also published).</li>
              <li>The services/applications deployed there were all for internal use by Clarity employees (about 300 at the time), mainly in Engineering.</li>
              <li>For all the above, in our specific case scalability wasn’t an issue: we didn’t have hundreds, thousands, or millions of concurrent users. Therefore, we didn’t need load or stress tests, and the e2e tests we had didn’t require anything special.</li>
            </ul>
          </li>
          <li><strong>At <a href="https://form3.tech/" target="_blank" rel="noopener noreferrer">Form3</a>:</strong>
            <ul>
              <li>Here things change: for several months I was on the (micro) scalability team, whose main responsibility was detecting (and sometimes fixing) bottlenecks in the scalability of our (not simple) distributed system.</li>
              <li>To say that Form3’s product was (or is) an <a href="https://www.api-docs.form3.tech/" target="_blank" rel="noopener noreferrer">HTTP API</a> in fintech is an understatement. We handled a lot of money daily and it was quite critical (no one died, but it was no laughing matter 🤣).</li>
              <li>Something very interesting is that we worked hand in hand with the Sales team to generate simulated traffic based on the “real” forecast of new users (e.g., if X contracts had been signed for a certain date, implying N new clients/users).</li>
              <li>The load and stress e2e tests were run with <a href="https://k6.io/" target="_blank" rel="noopener noreferrer">k6.io</a> (in fact, Form3 eventually released an <a href="https://github.com/form3tech-oss/f1" target="_blank" rel="noopener noreferrer">open-source solution called ‘f1’</a> that simplified this based on the work we did on my team; it’s very interesting, I recommend checking it out). We created an hourly distribution of requests similar to what we usually had, with Gaussian distributions but with the estimated volumes.</li>
              <li>It’s something that, honestly, I had not seen done before, nor have I seen it done again 🤯</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
  <li><strong>How can you balance huge test suites that slow down pipelines with the speed required in trunk-based development?</strong>
    <ul>
      <li>To clarify, in Trunk-Based Development (TBD) or CI that “speed” isn’t as critical in my opinion – at least merging once a day into the main branch. I’d say the more frequent, the better: for example, every 2 hours is preferable to every 24 hours; and if you can work with a single branch by default and merge every few minutes, that’s icing on the cake (in my experience, the difference is enormous, but life is tough and we do what we can…).</li>
      <li>Those “huge test suites” you mention – what exactly makes them so huge? Is it a large non-modularized monolith? Or is it because there are “too many” slow tests?</li>
      <li>As I mentioned above: we must parallelize everything we can. Most of our tests (regardless of type, even integration and e2e) should be parallelizable (by default, with few exceptions, they should initialize what they need autonomously and then restore everything as it was).</li>
      <li>With proper modularization, perhaps only the tests that give us enough confidence for deployment could be run (only triggering the affected ones, using “contract testing,” only the most critical e2e/functional/acceptance tests, etc.).</li>
      <li>And finally: it is advisable to have many more fast tests than slow ones.</li>
    </ul>
  </li>
  <li><strong>I have mixed feelings about pre-push and pre-commit hooks, as I’ve seen that sometimes they lead developers to make larger commits than they should in order to avoid running linting, tests, etc. multiple times. I wanted to ask your opinion about that – if you have experienced it and, if so, how did you channel the situation.</strong> [Question received via Twitter, thanks Eneko 🙏]
    <ul>
      <li>First, I’d need to understand why linting, tests, etc. fail multiple times. Is it because there are flaky tests or some type of non-deterministic validation? Or is it simply because developers “make mistakes”?</li>
      <li>I haven’t encountered the situation you describe, perhaps because there are several aspects on which I always place high priority with Git hooks:
        <ul>
          <li>They must be <strong>VERY fast</strong>. Otherwise, one will be tempted to skip them or wait until you have many changes to run them.</li>
          <li>They must be deterministic: the result should not vary if the “input” (tests, linters, whatever) hasn’t changed.</li>
          <li>We normally practice TDD, so if a test fails, we usually find out sooner rather than later (<strong>shortening the feedback loop</strong>).</li>
          <li>We have linters and formatters configured in the IDE exactly as they are in the Git hooks. This usually provides even faster feedback and almost no surprises when Git hooks run.</li>
        </ul>
      </li>
      <li>And… basically that’s all I can think of 😅 As I said, I’d need to experience the situation in person to fully understand where the friction is 😊🙏</li>
    </ul>
  </li>
  <li><strong>Doesn’t the possibility of doing Continuous Deployment go hand in hand with the criticality of potential application errors? That is, it is not the same to introduce a bug in, for example, a music streaming platform as in a financial transactions app or one that handles very sensitive data.</strong>
    <ul>
      <li>In my opinion, no 😊 The main motivation for “Continuous X” (Integration/Delivery/Deployment), as I mentioned in the talk (sorry for the self-reference), is to <strong>LEARN quickly</strong> (so that we can adapt and reorient ourselves fast and deliver value quickly). We want feedback as soon as possible about both <strong>WHAT</strong> (user/client/business needs) and <strong>HOW</strong> (systems/technology/organization). And generally, we want that all the time; in fact, it seems to me that in the example you mention (and in my experience) it probably applies more in the music app than in the financial one.</li>
      <li>As I see it, the reasoning is actually the opposite: it is to enable that continuous learning, those rapid feedback loops, for which we need, among other things, a very strong safety net that will result in fewer application errors. Reducing bugs is not an end in itself; it is a means to other ends (improving user experience, delivering value, continuous learning, etc.).</li>
      <li>In other words: in the false dichotomy of “quality vs. speed,” only with good internal quality can we achieve speed.</li>
    </ul>
  </li>
  <li><strong>It seems we try to reinvent the wheel but always end up coming back to Eliyahu Goldratt’s concepts. In what cases do you think we should NOT apply all these principles? Or conversely, do you consider them universal for any problem space?</strong>
    <ul>
      <li>Uuffff… a difficult question. In summary: no, I don’t think they are universal for every problem space. For example, if you have a pure, hard CRUD where you “know” it will hardly evolve (something I’ve almost never encountered, but let’s imagine), then I wouldn’t apply them. There is no uncertainty (or so we believe), nothing significant to learn. But more importantly: in that context today <strong>I wouldn’t even develop software</strong>, as there are plenty of NoCode tools to resolve such cases (e.g., when business domain logic is minimal).</li>
      <li>If I were to act as a “coach” 😜, I’d talk about the <a href="https://en.wikipedia.org/wiki/Cynefin_framework">Cynefin framework</a> and that in the “clear” domain, everything is already sold.</li>
      <li>That said, I believe that statistically (at least based on my <a href="https://en.wikipedia.org/wiki/Anecdotal_evidence">anecdotal evidence</a>) this context is infinitesimal; it is not the usual context in which we operate and for which we are paid.</li>
    </ul>
  </li>
  <li><strong>When, due to the context of initiatives (e.g., very complex changes), you cannot merge daily, can it still be considered Continuous Integration?</strong>
    <ul>
      <li>First, I’d need to understand that context much better.</li>
      <li>Here I will “challenge” it: in most cases where someone or a team has indicated that their context was “special” or “too complex” and therefore they couldn’t do X or Y, when I’ve dug deeper, asked questions, and tried to understand, I (or we) found that the underlying problems were different and that it was actually possible to do it (or at least start moving in that direction). I’m not saying it’s your case, because I lack a lot of information, but I do say that almost always it is possible.</li>
      <li>In very sporadic cases, anything goes – we are human and that’s what happens (and indeed there are specific situations where there is no alternative). But if that is the everyday situation, if you really can’t merge daily into a main branch for your regular work, I find it hard to believe that it isn’t a matter of knowledge, principles, and practices (i.e., a self-generated problem). It is probably “accidental complexity” rather than “essential complexity” (see the famous <a href="http://www.cs.unc.edu/techreports/86-020.pdf">“No Silver Bullet” by Fred Brooks</a>).</li>
      <li>In any case: if you aren’t merging at least daily, I don’t think we can talk about “continuity” (and it’s not about linguistic purism, but about the value of the practice).</li>
    </ul>
  </li>
  <li><strong>How would the process be for deploying front-end features that depend on back-end changes using TBD?</strong>
    <ul>
      <li>To use a cliché: I’m glad you asked that question 🤣. In fact, during the networking session someone asked me the same case (perhaps it was the same person).</li>
      <li><em>Disclaimer</em>: It is highly recommended that an entire <strong><em>value stream</em></strong> be handled within the same team. There are always exceptions, but as a general rule both the Front and Back for an end-to-end feature should be <strong>the responsibility of the same team</strong>.</li>
      <li>On one hand, I must again mention the importance of using <a href="https://martinfowler.com/articles/feature-toggles.html">feature flags</a> to enable various changes in parallel. For example, for this specific case, we could have a <strong><em>feature flag</em></strong> both on the Front and the Back (with the same default for both), so that either part can be continuously deployed without impact for the users, while progress is made gradually or while waiting for the “other part.” The idea is to hide from the user what is not yet functioning correctly because it is still under development.</li>
      <li>At this point, I’d like to share a concrete experience that I find very relevant for this case: the project we worked on at <a href="https://www.codium.team/">Codium</a> for a client, from which I showed one of the <a href="https://speakerdeck.com/islomar/valor-por-encima-de-codigo-el-poder-del-despliegue-continuo?slide=44">Continuous Deployment pipelines</a> we had (specifically, the back-end one).
        <ul>
          <li><strong>Important context:</strong>
            <ul>
              <li>We formed a mixed team of 3 people from Codium and 3 from the client (one of them acting as “Product Manager”). We worked in <strong>pairing and ensemble programming by default</strong>. And although one person was more specialized in Front and another in Back, the rest rotated between both worlds: there were hardly any silos or isolated compartments—in the team almost everyone did almost everything (each with their own strengths, of course). We were also very autonomous in the Systems part.</li>
              <li>There was a Back-end (in PHP, with Symfony) and a Front-end (React with TypeScript). The Back published an HTTP API that the Front consumed.</li>
            </ul>
          </li>
          <li>Bottom line: we used <a href="https://www.openapis.org/">OpenAPI</a> to define the contract to be met between Front and Back. When a new behavior (or change) was required that implied changes on both sides, the first thing we did was to gather the entire team to write the “contract” together. In a YAML file, OpenAPI allows you to define that contract – e.g., the endpoint URI, input types, output types, HTTP status codes returned, etc.</li>
          <li>Once we had this contract written by everyone, we could, if we wanted, tackle the Front and Back separately. Depending on the type of change, sometimes not even a “feature flag” was needed.</li>
          <li>To ensure that neither side broke the contract, we had several validations in Git hooks and in the pipeline (as you can see in the diagram I shared):
            <ul>
              <li><strong>Back-end:</strong>
                <ul>
                  <li>We used <a href="https://schemathesis.readthedocs.io/en/stable/">schemathesis</a>. It is a tool that automates testing of HTTP APIs by dynamically generating test cases from the OpenAPI contract. It allows multiple configurations depending on the number of tests desired, parallelism, etc.</li>
                  <li>Basically, we used it to run dynamic tests based on the contract against the API published by the Back.</li>
                  <li>We ran it at two different moments:
                    <ul>
                      <li>In the pre-push Git hook, against a local environment (automatically brought up with Docker).</li>
                      <li>During the pipeline, for example against the Staging environment, once the Back was deployed there.</li>
                    </ul>
                  </li>
                </ul>
              </li>
              <li><strong>Front-end:</strong>
                <ul>
                  <li>We used <a href="https://github.com/jormaechea/open-api-mocker">jormaechea/open-api-mocker</a>, which is an API mocker based on OpenAPI 3.0.</li>
                  <li>It essentially spun up a mock server based on the OpenAPI contract, which received requests during certain types of Front-end tests.</li>
                </ul>
              </li>
              <li>The YAML file with the OpenAPI contract was present in both the Front and Back: this duplication wasn’t ideal, but it was very “cheap” at the time. In the pipeline, we had a validation to ensure that the contract was exactly the same on both sides (and, of course, we would immediately notice if it wasn’t).</li>
            </ul>
          </li>
          <li><strong>IMPORTANT:</strong> The choice of these tools was made several years ago; it is very likely that better solutions exist today 😊</li>
          <li>If the Back endpoints were consumed by <strong>many</strong> more consumers (excuse the redundancy), perhaps we could consider more advanced (and much more complex, better to wait until it’s REALLY needed) solutions like <a href="https://pact.io/">Pact</a>.</li>
        </ul>
      </li>
    </ul>
  </li>
</ol>

<hr />

<p><strong>And that’s it!!</strong> With this, I finally scratch the itch of not having been able to answer any questions after my talk 😊</p>

<p>I truly had a lot of fun answering these—it was an interesting exercise, and I only hope I’ve provided something valuable to someone 🙏</p>]]></content><author><name>Isidro López</name></author><category term="blog" /><category term="talks" /><category term="talks" /><category term="bilbostack24" /><category term="english" /><summary type="html"><![CDATA[This is the English version for the post I wrote in March 2024 answering several highly interesting questions related to my talk at the BilboStack conference about Continuous Deployment (including a lot of product-mindset, eXtreme Programming, and Lean Product Development values, principles and practices).]]></summary></entry><entry xml:lang="en"><title type="html">My ethical stance</title><link href="https://islomar.es/my-ethical-stance/" rel="alternate" type="text/html" title="My ethical stance" /><published>2024-03-17T12:35:00+01:00</published><updated>2025-06-05T22:11:27+02:00</updated><id>https://islomar.es/my-ethical-stance</id><content type="html" xml:base="https://islomar.es/my-ethical-stance/"><![CDATA[<p><em><strong>IMPORTANT DISCLAIMER:</strong> I’m writing this post as a <strong>personal reminder</strong>, not to tell anyone what they should do, convince anybody of anything, impart moral lessons or grant any kind of “licenses”. Life is hard and I have enough on my plate with setting my own moral compass</em> 🙏</p>

<hr />

<p>I’m currently in a “relaxed” search of new professional challenges. By “relaxed” I mean that I have not openly published it and I’m not intensively searching: for the moment, I just knocked a couple of doors (from people/companies I feel a high level of alignment) and entered a few processes with people who directly approached me (I’m such a privileged person and I feel SO LUCKY 😍).</p>

<p>Still, this is a moment when I’m asking myself questions such as:</p>
<ul>
  <li>What kind of industries do I feel specially motivated to join?</li>
  <li>What kind of industries or business models or organizational behaviour I don’t want to join?</li>
  <li>What are my “ethical red lines”? How big is the “grey area” to me?</li>
</ul>

<p>This is not the first time that I pose myself this kind of questions. I remembered that Edu Ferro (a reference to me in so many ways) has his own <a href="https://www.eferro.net/p/to-be-happy-and-make-those-around-me.html">“ethical stance” published here</a>, so I thought it would be a perfect moment to write down mine. And I want to be so specific as possible; otherwise it would be useless for myself.</p>

<p>For different reasons (i.e. there are higher and lower levels of “criticality” in this list) and with no particular order and without this being an exhaustive list, <strong>I prefer not to work in</strong>:</p>

<ul>
  <li>Fast fashion (and anything directly related)</li>
  <li>Traditional banks (especially those with proven record of abuses and illegalities)</li>
  <li>“Buy now, pay later” or any kind of “fast credit” business models</li>
  <li>Porn industry</li>
  <li>Military industry</li>
  <li>Any company directly or indirectly connected with any genocidal state (e.g. Israel)</li>
  <li>Casinos, gambling and bets (“been there, done that”)</li>
  <li>Any green-washing, or generally speaking, “ethical-washing” activity</li>
  <li>Crypto businesses and alike</li>
  <li>Activities where people can quickly lose a lot of money</li>
  <li>Delivery riders business models that often exploit riders, typically misclassified as “independent contractors”</li>
  <li>Business models whose main goal is encouraging wild consumerism of any kind</li>
  <li>Highly polluting activities</li>
  <li>Anything where there is no full transparency about the business model and how they earn money</li>
  <li>Any activity without “full honesty”: lying, cheating, hiding relevant information or “tricking” their users, providers, employees, etc.</li>
</ul>

<p>And I write these words being fully conscious about my own incoherences: with the current complexity of the world and society, I don’t think that it’s possible to live on it being “fully coherent”. Sometimes I would even say that it isn’t “healthy”. Long life to the <a href="https://en.wikipedia.org/wiki/Cognitive_dissonance">cognitive dissonances</a>! 😆</p>

<p>Despite my efforts to minimize it, I’m acutely aware of being part of a global community that continuously exploits other regions and people. Shame on me. Shame on us.</p>

<p>Regarding some topics, my views have evolved in the past, and I hope they will continue to do so in the future. Still, I’m not always in peace with that, which I think is good 🙏</p>]]></content><author><name>Isidro López</name></author><category term="blog" /><category term="english" /><summary type="html"><![CDATA[IMPORTANT DISCLAIMER: I’m writing this post as a personal reminder, not to tell anyone what they should do, convince anybody of anything, impart moral lessons or grant any kind of “licenses”. Life is hard and I have enough on my plate with setting my own moral compass 🙏]]></summary></entry><entry xml:lang="es"><title type="html">Preguntas y respuestas de mi charla en la BilboStack 2024</title><link href="https://islomar.es/preguntas-y-respuestas-bilbostack-2024/" rel="alternate" type="text/html" title="Preguntas y respuestas de mi charla en la BilboStack 2024" /><published>2024-01-31T16:26:27+01:00</published><updated>2024-02-04T08:26:27+01:00</updated><id>https://islomar.es/preguntas-y-respuestas-bilbostack-2024</id><content type="html" xml:base="https://islomar.es/preguntas-y-respuestas-bilbostack-2024/"><![CDATA[<blockquote>
  <p>Here you can read the post <a href="/questions-and-answers-bilbostack-2024">in English</a></p>
</blockquote>

<p>Cuando en la pasada y maravillosa <a href="https://bilbostack.com/" target="_blank" rel="noopener noreferrer">BilboStack</a> finalicé <a href="/slides-and-resources-talk-bilbostack-2024">mi charla sobre Continuous Deployment</a> (no me cansaré de repetir que como excusa para hablar de “lo importante”), me hicieron saber que no había ninguna pregunta 😱
 En mi experiencia, cuando eso pasa, es que el nivel de turra ha sido astronómico y el mensaje no ha llegado de ninguna manera 😅</p>

<p>Por suerte, parece ser que la explicación era menos dramática: hubo algún problema con la aplicación que recogía las preguntas (¿faltaría algún test? 😜). La organización ha tenido el detallazo de enviármelas <em>a posteriori</em>, así que intentaré contestarlas en este post.</p>

<p><strong>Aclaración importante</strong>: me falta muchísimo contexto en casi todas las preguntas; necesitaría entender mejor muchísimas cosas antes de dar una respuesta “razonable”. Lo haré explícito en las respuestas de algunas pero lo inferiré en otras 🙏</p>

<hr />

<ol>
  <li><strong>¿Puedes explicar cómo conseguir la ISO 27001/SOC2 trabajando en continuos delivery?</strong>
    <ul>
      <li>Resumen: realmente no 🤣 Pero puedo compartir algunas cosillas que tal vez ayude en algo…</li>
      <li>Algo que comentaba el otro día hablando con otra persona sobre este tema es que tendemos a dar por hecho demasiadas cosas. Lo primero que siempre debemos hacer es ENTENDER en profundidad las necesidades a satisfacer. Creo que hay mucho “teléfono escacharrao” e inferimos que se necesitan muchas cosas que en realidad son una posible solución (e.g. que haya una PR) en lugar de la necesidad de base a resolver (e.g. que más de una persona haya revisado algo).</li>
      <li>Dicho esto: tengo claro que el auditor que te toque puede influir muchísimo.</li>
      <li>A mucho más alto nivel, Clarity publicó un post al respecto: <a href="https://medium.com/clarityai-engineering/iso27001-and-soc2-type-ii-from-greenfield-to-success-24ca99decb26">“ISO27001 and SOC2 Type II from Greenfield to Success”</a></li>
      <li>En mi equipo hacíamos de hecho “Continuous Deployment” y en nuestro caso era suficiente con seguir los siguientes requisitos:
        <ul>
          <li>Cada commit incluía el <strong>issue de Jira</strong> que lo originaba: se generaba una traza inequívoca con la necesidad de la que surgía ese código.</li>
          <li>Puesto que trabajábamos en pairing o ensemble por defecto, en cada commit incluíamos a todas las personas involucradas usando el <strong><a href="https://docs.github.com/es/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors">“Co-authored-by” de Git</a></strong>
            <ul>
              <li>Para reducir la fricción, todos teníamos un <strong>template del <a href="https://gist.github.com/lisawolderiksen/a7b99d94c92c6671181611be1641c733">git message</a></strong> compartido con el resto de compañeras del equipo, no teníamos que estar escribiéndolo conitnuamente.</li>
              <li>Hasta donde sé, y simplificando mucho, una de las cosas que se requiere es <strong>evidencia</strong> de que una persona diferente a quien escribió el código, lo ha revisado. Esta práctica satisfacía esa necesidad.</li>
            </ul>
          </li>
          <li>Si el cambio a realizar era “muy trivial” (lo cual siempre es abstracto, pero teníamos un documento definiéndolo), se permitía que no hubiera un revisor (e.g. cambio en documentación). En estos casos, era suficiente con incluir en el mensaje del commit cierta palabra clave (en nuestro caso concreto, <code class="language-plaintext highlighter-rouge">[trivial-small-change]</code>)</li>
        </ul>
      </li>
      <li>Para la gente que trabajaba con ramas y PRs, la persona que validaba la PR debía ser diferente a la persona que la había abierto.</li>
      <li>Si necesitas más detalle, probablemente <a href="https://www.eferro.net/">Edu Ferro</a> pueda contarte más cosas 🙏</li>
    </ul>
  </li>
  <li><strong>¿Qué opinas de los code freeze? ¿Tienen sentido en determinados casos? Por ejemplo, una empresa grande con equipos distribuidos en distintas zonas horarias</strong>
    <ul>
      <li>Preguntas que me surgen:
        <ul>
          <li>¿Hablamos de equipos distribuidos o de sistemas distribuidos? ¿O de ambas cosas?</li>
          <li>Cuando hablamos de equipos distribuidos, ¿a nivel individual o de equipo? ¿Están todos los miembros de un mismo equipo en zonas horarias muy diferentes? ¿O la dispersión era a nivel de equipo? (es decir, miembros de un mismo equipo en zona horaria similar, pero cada equipo en zonas horarias muy diferentes)</li>
        </ul>
      </li>
      <li>Si bien creo que todo puede tener sentido en algún contexto, en general los “code freeze” (sobre todo si ocurren con relativa frecuencia) son un mal síntoma. El mero hecho de ser una empresa grande con equipos distribuidos en distintas zonas horarias no implica que deban existir esos “code freeze”. Cada equipo debería tener el ownership e2e de un “value stream” (ver los <a href="https://martinfowler.com/bliki/TeamTopologies.html">“stream-aligned teams” de Team Topologies</a>).</li>
      <li>Aquí entra en juego y hay que tener mucho cuidado con la <a href="https://martinfowler.com/bliki/ConwaysLaw.html">ley de Conway</a> y <a href="https://www.agileanalytics.cloud/blog/team-topologies-the-reverse-conway-manoeuvre">su reverso</a>, cómo están diseñados los equipos, los sistemas y sus responsabilidades.</li>
      <li>Algo que también puede ayudar es la existencia de <a href="https://medium.com/agile-outside-the-box/team-apis-af2dbc1805e7">“Team APIs”</a>.</li>
      <li>Según el nivel de solapamiento horario, se pueden poner unas horas “core” para el pairing/ensemble.</li>
      <li>Si hablamos de personas distribuidas: una estrategia de branching tipo <a href="https://martinfowler.com/articles/ship-show-ask.html">“Ship, Show, Ask”</a> puede ser interesante.</li>
      <li>Si de lo que hablamos es de un sistema distribuido y no sólo equipos distribuidos (que no es lo mismo), entonces es fundamental hacer muy buen <a href="https://martinfowler.com/bliki/ContractTest.html">“Contract Testing”</a>: cada sistema/servicio debería poder ser testeado funcionalmente de forma “aislada” sin depender del resto de servicios. Esto es independiente de tener algún tipo de tests end-to-end adicionales (lo cual en sistemas complejos distribuidos se complica bastante).</li>
    </ul>
  </li>
  <li><strong>¡Gracias por la charla! ¿Cuál sería en tu opinion una buena estrategia de ramas? Actualmente al tener baby-commits y al mergear con la rama principal optamos por squash and merge, que crea un nuevo código de commit y se pierde el rastro de los antiguos commits entrando en un infierno de commits a la hora de revisar PRs. Nos suelen pedir intentar hacer un solo commit por desarrollo y luego mergeo (not fast foward) y yo consigo eso con git -ammend</strong>
    <ul>
      <li>Mi primera respuesta: “depende” 😜</li>
      <li>Mi segunda respuesta: la estrategia de ramas que, en general, mejor permite tener feedback rápido y un aporte de valor continuo y sostenible es “Trunk-Based Development” con una única rama por defecto (acompañado, como comentaba en la charla, de pair/ensemble programming, TDD, una pipeline segura, repetible y potente, micro-commits, etc.)</li>
      <li>Personalmente priorizo el flow continuo y llevar cuanto antes el commit a Producción, que un histórico “impoluto” de commits. Lo que sí es siempre importante es que los commits sean descriptivos y cuenten claramente “el porqué” ante todo (“el qué” está implícito en el commit).</li>
      <li>En la línea de lo que comentas, la buena gente de <a href="https://codely.com/">Codely</a> grabó hace un par de años un vídeo con sus opiniones al respecto, creo que te podría interesar en caso de que no puedas trabajar con una rama única, te lo recomiendo: <a href="https://www.youtube.com/watch?v=HlmZLXMOpEM">“Git Merge vs Rebase vs Squash ¿Qué estrategia debemos elegir?”</a></li>
    </ul>
  </li>
  <li><strong>¿Ventajas y desventajas de tener los test en un git hook?</strong>
    <ul>
      <li>Aclaración: todo lo que se meta en Git hooks debe ser “rápido”. Qué significa “rápido” depende de la sensibilidad de cada persona o equipo, pero en mi experiencia, toda ejecución que supere los 5 segundos empieza a “doler” (los “push” pueden tardar algo más porque los solemos ejecutar con menos frecuencia, pero no mucho más). En cualquier caso, y en mi opinión, es mejor tener que esperar “un poco” en el momento del commit-push que encontrarnos con demasiadas “sorpresas” más tarde (problema de “context switch”). Y por otra parte, es conveniente balancear qué se incluye en el pre-commit y qué en el pre-push (ver <a href="./2024-01-29-slides-and-resources-talk-bilbostack-2024.md">ejemplos en los diagramas con ejemplos reales de la charla</a>)</li>
      <li><em>Ventajas</em>: tener feedback mucho más rápido si fallan los tests (no tener que esperar a que fallen en la pipeline, cuando ya hemos cambiado el foco y estamos a medias de otra cosa). Por supuesto no incluiría los tests más “lentos”, pero sí los “rápidos” (en mi opinión todos los unitarios deberían serlo, así como algunos de integración - qué considero “unitario” o “integración” da para otro post).</li>
      <li><em>Inconvenientes</em>: el inconveniente surge si su ejecución es “demasiado lenta”; lo que acabará pasando es que los saltaremos o acumularemos demasiados cambios. La solución pasa por tener en los Git hooks únicamente los tests más rápidos o que no provoquen demasiada sensación de ralentización. Paralelizar todo lo posible su ejecución es importante para disminuir los tiempos.</li>
    </ul>
  </li>
  <li>
    <p><strong>De primeras, muy interesante. Como pregunta ¿no notaste que los hooks pre-commit y pre-push podian añadir friccion y latencia en el proceso de commit, llevando al equipo a hacer commits mas grandes para evitar hacer menos commits por pasar menos procesos?</strong><br />
Muy buena pregunta, y por desgracia no es difícil que ocurra, hay que estar muy pendiente de ello. Lo he intentado contestar en la pregunta anterior ☝️🙏</p>
  </li>
  <li><strong>¿Validaciones sincronas o PR en asincrono?</strong>
    <ul>
      <li>No sé si entiendo esta pregunta, lo siento. ¿Qué quieren decir “validaciones”? ¿Hablamos de los tests? ¿De linters? ¿O de la revisión de código?</li>
      <li>En la línea de lo que comenté en la charla: debemos intentar tener feedback los más rápido y frecuente posible de todo. En la medida de lo posible, priorizaría las revisiones de código síncronas; y aún mejor: hacer pairing/ensemble todo lo “posible”.</li>
      <li>También recomendaría echar un vistazo a la estrategia de branching <a href="https://martinfowler.com/articles/ship-show-ask.html">“Ship, Show, Ask”</a>,  puede ser interesante como avance hacia la reducción de tiempos de integración.</li>
    </ul>
  </li>
  <li><strong>Cuando el “circulo vicioso” que has enseñado al principio se ha hecho tan grande, ¿cómo sales de ahí?</strong>
    <ul>
      <li>Uuufffff, difícil pregunta (o mejor dicho, difícil respuesta 😅). Lo primero necesario es tener consciencia general del problema y de su naturaleza (yo diría que esto es lo más difícil). Hacerlo visible y explícito, con datos, siempre ayuda (e.g. tomar tiempos de todo lo que ocurre desde que hacemos un commit hasta que llega a Producción), ponerlo negro sobre blanco.</li>
      <li>Lo siguiente importante es querer realmente invertir tiempo para resolverlo, ver claramente el beneficio que eso puede reportar (lo cual de nuevo suele ser muy difícil si no se ha experimentado antes).</li>
      <li>Si se cumple todo lo anterior: ir poquito a poco. Identificar primero los “quick wins” que puedan existir (bajo coste y alto beneficio). Mejorar el testing automatizado. Ir disminuyendo todo lo posible los tiempos de nuestras ramas/PRs. Adoptar estrategias de branching que disminuya el tiempo que tardamos en integrar en la rama principal. Aumentar y mejorar la colaboración (e.g. a través del pairing). Aprender técnicas de cambios paralelos y empezar a usar “feature flags”.</li>
      <li>Y creo que el mejor consejo: buscad y contratad a alguien con experiencia en todo lo anterior, es extramadamente difícil si no (no digo que no sea posible, pero sí muy complicado).</li>
    </ul>
  </li>
  <li>
    <p><strong>¿Como se puede poner en valor el aporte de CI/CD y hacer perder el miedo a desarrolladorxs de desplegar pronto cosas?</strong><br />
Yo como mejor lo he visto hacer es liderando con el ejemplo (lo cual requiere experiencia haciéndolo), haciendo al mismo tiempo mucha pedagogía al respecto (sobre el valor que aporta a todes, tanto negocio como ingeniería). No creo que haya atajos ni fórmulas mágicas… 😕 Por supuesto, ese “desplegar pronto cosas” debe ir acompañado de una red de seguridad potente, si no será peor el remedio que la enfermedad y la gente, con razón, no querrá hacerlo.</p>
  </li>
  <li><strong>¿Utilizas estrategias de pairing como el ping-pong? En estos casos, ¿no sería molesto el uso de Git Hooks?</strong>
    <ul>
      <li>En el pasado sí he hecho pairing con TDD en ping-pong (diría que he hecho pairing en todas o casi todas las modalidades posibles 🤣)</li>
      <li>Cuando he hecho ping-pong (la persona A escribe el test, B lo pasa, refactor, B escribe el siguiente test, etc.) lo hacía compartiendo el terminal (es decir, ambas personas trabajábamos realmente en la misma máquina, usando <a href="https://tmate.io/">tmate</a>). Eso implica que no hacíamos commit hasta que el test no estuviera en verde (y por tanto los Git hooks no eran un problema).</li>
      <li>Algo que no haría, independientemente de los Git Hooks, es subir código a la rama principal sin tests.</li>
      <li>Hay gente que usa <a href="https://github.com/remotemobprogramming/mob">esta herramienta</a>, podría cubrir según qué casos de uso (personalmente prefiero no hacer ping-pong y ya está, rotamos por pomodoro y ya es suficiente).</li>
      <li>Sobre pairing, este post es realmente bueno: <a href="https://martinfowler.com/articles/on-pair-programming.html">On Pair Programming</a></li>
    </ul>
  </li>
  <li><strong>¿Tener muchos micro commits no puede ensuciar la rama main?</strong>
    <ul>
      <li>Depende de lo que se entienda por “ensuciar”. Lo que siempre es importante es tener commits con buenos mensajes, describiendo muy bien “el porqué”; y por supuesto ningún commit debe romper los tests.</li>
      <li>Dicho esto, creo que es más importante dar pasitos pequeños y el feedback y flow muy continuos que una supuesta historia de commits “ideal”.</li>
    </ul>
  </li>
  <li><strong>Generalmente lo que se pide es que la feature este completa antes de subir y no quieren ver nada hasta que no esté, ¿Sería aplicable trunk-based?</strong>
    <ul>
      <li>Absolutamente. Para resolver el problema que describes, que efectivamente es muy habitual, existen múltiples técnicas de cambios paralelos (<a href="https://islomar.es/blog/talks/slides-and-resources-talk-bilbostack-2024/#parallel-changes">incluí información al respecto</a>) y sobre todo el uso de <a href="https://martinfowler.com/articles/feature-toggles.html">feature flags/toggles</a>.</li>
      <li>Esto está relacionado con el desacoplamiento que mencionaba durante la charla entre “Deployment” (decisión técnica) y “Release” (decisión de negocio).</li>
    </ul>
  </li>
  <li>
    <p><strong>Para usar CD con trunk-based development, a la hora de hacer commits y pushearlos, ¿teniais algun tipo de configuracion para prevenir commit que no pasasen los tests?</strong><br />
Sí, teníamos configurados Git hooks tanto de pre-commit como de pre-push. En los <a href="/slides-and-resources-talk-bilbostack-2024">diagramas de los slides de la charla</a> puedes ver qué incluíamos en cada uno de ellos. Por la forma en que funcionan los Git hooks, si el pre-commit no pasa (i.e. si estado de salida es distinto de cero), no se realiza el commit (idem para el pre-push).</p>
  </li>
  <li><strong>A la pregunta que ha hecho: “Es para cambiar el Mundo, porque en mayor o menos medida cuando subimos un cambio, estos cambian la vida de algunas personas (para bien o para mal) nuestros usuarios o cliebtes, porque tienen herramientas para hacer mejor su trabajo”</strong>
    <ul>
      <li>Entiendo que esto es la respuesta a la pregunta que lancé: “¿Para qué desarrollamos software profesionalmente?”. Me parece una perspectiva maravillosa, la verdad, me siento muy alineado con la idea que subyace a ella.</li>
      <li>En relación con el matiz que mencionaba en mi respuesta y que era lo que quería resaltar, te diría: ¿y si pudieras cambiar/mejorar el mundo de manera más óptima/eficiente <strong>SIN</strong> software, no lo harías? 😉</li>
    </ul>
  </li>
  <li><strong>¿Tendría sentido ejecutar varios procesos de CI en paralelo? Por ejemplo los unit tests, construir la build y los e2e tests a la vez</strong>
    <ul>
      <li>Sí, pero depende de cuales. Sin duda <strong>debemos paralelizar todo lo posible</strong>, comenzando por los propios tests (casi todas las librerías de testing permiten la ejecución en paralelo); además, así nos forzamos a escribir tests “autocontenidos”, cuya entrada o salida no dependa de otros tests ni los contamine (lo cual es por defecto lo más recomendable). Con los tests unitarios y de integración no debería haber problema. Con los tests e2e/acceptance tal vez sí (merece la pena diferenciar cuáles se puden paralelizar y hacerlo).</li>
      <li>En los <a href="https://speakerdeck.com/islomar/valor-por-encima-de-codigo-el-poder-del-despliegue-continuo?slide=44">dos ejemplos reales que incluí</a>, puedes ver qué paralelizamos y qué no, diría que casi todo con mucha consciencia (y siempre mejorable) 😊</li>
      <li>Si por ejemplo miramos la segunda pipeline, te puedo contar por qué no paralelizamos en concreto las tres tareas que comentas:
        <ul>
          <li>No queríamos invertir tiempo en el build de la imagen de Docker (y el posterior push a un ECR) si los tests no pasaban antes.</li>
          <li>Los tests unitarios son los más rápidos, por lo que son los más bloqueantes: no queremos hacer nada más si eso falla (otro motivo por el que no paralelizarlos con según qué). Sí los podemos paralelizar con otras tareas también rápidas, como linters y otras validaciones estáticas.</li>
          <li>En cuanto a los tests e2e: en nuestra taxonomía de testing, esos son tests que lanzamos contra la nueva versión del sistema ya desplegado en alguna parte (staging o production), por lo que no podríamos paralelizarlo tampoco con la build o tests unitarios.</li>
          <li>Los tests que sí paralelizamos como primer paso de la pipeline son los <strong>unitarios</strong> (cumplen <a href="https://github.com/tekguard/Principles-of-Unit-Testing" target="_blank" rel="noopener noreferrer">los principios FIRST</a>), <strong>integración</strong> (en nuestro caso son tests para los adaptadores secundarios de <a href="https://herbertograca.com/2017/09/14/ports-adapters-architecture/" target="_blank" rel="noopener noreferrer">nuestra arquitectura hexagonal</a>) y tests de aceptación (que son tests “desde fuera” y los lanzamos contra el sistema que incluye las actualizaciones, levantado “en local”, antes de ser deplegado).</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><strong>Cuando haces TDD outside-in haces primero los tests desde el punto de vista del usuario pero, ¿continuas con tests más internos?</strong>
    <ul>
      <li>Exactamente, ésa es la idea. Similar a <a href="https://www.agilealliance.org/glossary/atdd/">Acceptance TDD</a>, <a href="https://gojko.net/books/specification-by-example/" target="_blank" rel="noopener noreferrer">Specification by Example</a> o <a href="https://dannorth.net/introducing-bdd/" target="_blank" rel="noopener noreferrer">Behaviour-Driven Development (BDD)</a> (existen matices de diferencias entre los tres, pero en los tres casos buscamos testear el comportamiento del sistema desde el punto de vista de su usuario externo)</li>
      <li>Decir que tal vez no siempre sea posible (yo no siempre lo consigo), pero sí debería ser el primer enfoque: cuando se hace así, la experiencia de desarrollo es fantástica (y por supuesto también revierte en la de usuario) 😍</li>
    </ul>
  </li>
  <li><strong>¿Consideras indispensable que el continous delivery llegue siempre hasta producción? ¿No sería suficiente con un entorno de Test que sea una replica de Producción para evitar riesgos?</strong>
    <ul>
      <li>No debemos confundir “Continuous Delivery” y “Continuous Deployment”. En la primera parte de mi charla intenté explicar <a href="https://speakerdeck.com/islomar/valor-por-encima-de-codigo-el-poder-del-despliegue-continuo?slide=16" target="_blank" rel="noopener noreferrer">las diferencias</a>.</li>
      <li>Con <strong>“Continuous Delivery”</strong>, efectivamente la pipeline no llega a desplegar en Producción. Puede, por ejemplo, quedarse en un enterno previo (e.g. Staging). Lo importante es que una vez nuestro código se integra en la rama principal y se ejecuta la build y tests automatizados, queda en un “estado desplegable”: cuando lo deseemos, a voluntad, podríamos desplegarlo a Producción (ese despliegue debería ser sencillo y repetible).</li>
      <li>Con <strong>“Continuous Deployment”</strong>, ahí ya sí, toda la pipeline está completamente automatizada, incluido el paso de despliegue a Producción.</li>
      <li>En la primera pipeline de ejemplo que mencioné, teníamos Continuous Deployment pero sí se desplegaba previamente a un entorno de Staging: tras desplegar ahí, se ejecutaban automáticamente varios tests e2e y smoke (lo más crítico) y si todo funcionaba correctamente, automáticamente se desplegaba a Producción.</li>
    </ul>
  </li>
  <li><strong>Entendiendo que una release es un concepto de negocio y no tecnológico, ¿por qué tomar el <em>product delivery lead time</em> es importante como métrica? ¿No es algo fuera del control de tecnología?</strong>
    <ul>
      <li>Buena pregunta. Mi respuesta: porque es fundamental verlo como un “todo”. Desde “ingeniería/tecnología” tenemos que entender que la tecnología es un medio para un fin.</li>
      <li>Para mí es una de las claves de la evolución hacia “product engineering”: entender que TODOS somos producto y negocio, que lo que hacemos debe responder a necesidades de usuarios.</li>
      <li>En realidad desde “ingenería” podemos y debemos influir mucho más de lo que creemos en el “product delivery lead time”. Muy a menudo he visto cómo la visión de los <em>product managers</em> cambia (para bien) cuando los desarrolladores ponemos sobre la mesa formas más sencillas de empezar a satisfacer la necesidad del usuario.</li>
      <li>Evidentemente, es necesaria la cultura adecuada en la empresa para que lo anterior ocurra y no nos encontremos con reinos de taifas y compartimentos estancos donde diferenciemos por completo “negocio” y “tecnología”: debemos ir hacia entender que <strong>todos somos PRODUCTO</strong> y necesitamos colaborar de forma continua e intensa.</li>
      <li>Por último: como yo lo veo, un “product team” está compuesto de perfiles varios, todos con igual importancia. El “product manager/owner” debe ser un miembro más del equipo, con horizontalidad respecto a los demás.</li>
    </ul>
  </li>
  <li><strong>Al trabajar siempre en la misma rama, si se hace push al server y algo falla. Como parte de ese rollback ¿se auto generaría un commit con revert? ¿O tendríamos bloqueado la rama principal?</strong>
    <ul>
      <li>Lo primero: hagamos en cada contexto lo que mejor que podamos y sepamos, que ya es mucho 😄</li>
      <li>En el <a href="https://speakerdeck.com/islomar/valor-por-encima-de-codigo-el-poder-del-despliegue-continuo?slide=45" target="_blank" rel="noopener noreferrer">segundo ejemplo del mundo real</a> que incluí en la charla, era un rollback muy rápido del despliegue, por lo que no se generaba ningún commit. Por dar más detalles técnicos, hacíamos el <a href="https://helm.sh/docs/helm/helm_rollback/" target="_blank" rel="noopener noreferrer">rollback con helm</a> (que era lo que también usábamos para el despliegue).</li>
      <li>Cuando eso ocurría, recibíamos un mensaje en el canal de Slack de equipo que teníamos para cuestiones importantes (e.g. cualquier fallo en la pipeline).</li>
      <li>El rollback automático en Producción nos daba la tranquilidad de saber que se quedaba en un estado estable, que seguía funcionando lo anterior.</li>
      <li>En cuanto acabábamos el pomodoro que estaba en curso (trabajamos principalmente en <em>ensemble</em>), priorizábamos inmediatamente ver qué había fallado y lo resolvíamos. No había ningún “bloqueo” de la rama principal porque trabajábamos en <em>ensemble</em>. Pero si no fuera así, como comenté en la charla arreglar una pipeline rota debe ser <strong>PRIORITARIO</strong>, por lo que no es que se quede bloqueada, sino que hay que arreglarla <em>ipso facto</em>, y además todos a una en el equipo, da igual quién hizo el commit que lo rompió (creo que el cambio de mentalidad es importante, y el trabajar de forma aislada y muy individualista no ayuda).</li>
      <li>Trabajando en rama única con lead time de minutos, no teníamos necesidad del concepto de “hot fix”: tras el rollback automático, en cuanto podíamos lo arregláblamos (pocos minutos) y comiteábamos el arreglo que fuera (con un test automático incluído para evitar que se repitiera, de ser posible) y p’arriba 😉</li>
      <li>Parte de la filosofía aquí es que cuando hay un incidente en Producción, lo primero y más importante es que Producción deje de fallar cuanto antes: puede ser porque volvemos a la versión anterior o porque comiteamos muy rápidamente una solución.</li>
      <li>A lo largo de 2 años, son muy pocas las ocasiones en las que ese rollback nos ocurrió (teníamos una red de seguridad previa bastante potente). No debemos acostumbrarnos a que esté ocurriendo cada dos por tres, sería síntoma de que tenemos que invertir en mejorar la red de seguridad previa.</li>
    </ul>
  </li>
  <li><strong>¡Gracias por la charla crack! Me encanta tu punto sobre la disciplina y sobre todo el cuello de botella enfocado en el conocimiento! Tengo una duda, este mundo ha ido evolucionando con términos como CI/CD y otros como DevOps, DevSecOps. ¿Qué opinas sobre esto? ¿Quién debería tener esta responsabilidad, una persona, un equipo? Me encantaría saber tu punto de vista</strong>
    <ul>
      <li>¡Gracias! Pues <a href="https://www.youtube.com/watch?v=GYtzu_G4A4M">opino de que</a> con DevOps se ha llegado a una situación de <a href="https://martinfowler.com/bliki/SemanticDiffusion.html">“inversión semántica”</a>: ha acabado significando exactamente lo contrario de lo que se buscaba. Se buscaba mejorar la colaboración y derribar silos de conocimiento, bloqueos y pasos de patata caliente, pero en general ha acabado con “equipos DevOps” (en realidad un renombrado del “equipo de sistemas”) que siguen manteniendo el silo, las dependencias bloqueantes, etc. <em>&lt;/rant&gt;</em></li>
      <li><a href="https://martinfowler.com/bliki/DevOpsCulture.html">DevOps</a> es una cultura, no un equipo. Lo cual no es incompatible con tener, por ejemplo, <a href="https://martinfowler.com/bliki/TeamTopologies.html">equipo(s) de plataforma o enablers que faciliten la vida a los equipos “stream-aligned”</a> con diversas herramientas y servicios <em>self-service</em>. Pero los equipos, digamos “de producto externo”, no deben tener dependencias bloqueantes de esos equipos.</li>
      <li>Y lo mismo aplicaría a DevSecOps, todo lo posible debería estar integrado en la pipeline de despliegue/delivery, probablemente apoyándonos en servicios/herramientas de otros equipos.</li>
    </ul>
  </li>
  <li><strong>¿Crees que el approach trunk/CI es válido para resolución de deuda técnica o sustaining como incremento de versiones de frameworks o librerías? ¿O es algo exclusivo de delivery de producto?</strong>
    <ul>
      <li>Totalmente, creo que TBD/CI puede aplicarse a múltiples contextos.</li>
      <li>De hecho creo que la mejor manera de abordar la <strong><a href="https://martinfowler.com/bliki/TechnicalDebt.html" target="_blank" rel="noopener noreferrer">deuda técnica</a></strong> (que por cierto, tendríamos que estar seguros de que hablamos de lo mismo 😄) es poco a poco. Hacer “sprints de deuda técnica” suele ser síntoma de falta de “slack/holgura” en el equipo (entre otras cosas).</li>
      <li>En cuanto a la <strong>actualización de frameworks/librerías</strong>: aquí ya te diría que “depende”.
        <ul>
          <li>Para actualizaciones de librerías, te diría que sí (en mi equipo teníamos un <a href="https://github.com/renovatebot/renovate" target="_blank" rel="noopener noreferrer">renovatebot</a> actualizando automáticamente a diario todas las librerías y desplegando al final igualmente la pipeline). Pero de nuevo, lo que repito todo el tiempo: necesitas una red de seguridad potente, sobre todo muy buenos tests automatizados.</li>
          <li>En cuanto a actualizaciones de frameworks: depende de las implicaciones del cambio. Normalmente sí, pero cuando son versiones <em>major</em> no es improbable que el impacto sea suficientemente grande como para requerir hacerlo en una rama que viva más de 24 horas y poder cambiar y probar ahí todo tranquilamente.</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><strong>¿Tienes alguna sugerencia o técnica para ejecutar E2E tests en producción? ¿Tráfico sintético, mirroring de tráfico, etc.?</strong><br />
Interesante pregunta 😄 La respuesta: “depende del contexto” (sorry, not sorry). Por si te aporta, puedo contarte dos casuísticas muy diferentes que me he encontrado (entre otras muchas):
    <ul>
      <li><strong>En <a href="https://clarity.ai/" target="_blank" rel="noopener noreferrer">Clarity AI</a></strong>:
        <ul>
          <li>Ver la <a href="https://speakerdeck.com/islomar/valor-por-encima-de-codigo-el-poder-del-despliegue-continuo?slide=45" target="_blank" rel="noopener noreferrer">segunda pipeline de ejemplos de la vida real</a> que compartí.</li>
          <li>Ahí teníamos varios tests e2e (los que imitan a un usuario real): algunos en <a href="https://www.cypress.io/" target="_blank" rel="noopener noreferrer">Cypress</a> (el servicio principal era una <a href="https://api.slack.com/interactivity/slash-commands" target="_blank" rel="noopener noreferrer">app en Slack (con un <em>slashcommand</em>)</a>, así que estos tests accedían realmente a Slack desde un navegador y ejecutaban varios comandos) y algunos en Python puro y duro (peticiones a algunos endpoints HTTP que también publicábamos).</li>
          <li>Los servicios/aplicaciones ahí desplegadas eran todas para uso interno de trabajadoras en Clarity (300 empleados en su momento), principlamente Ingeniería.</li>
          <li>Por todo lo anterior, en nuestro caso específico la escalabilidad no era un problema: no teníamos cientos ni miles ni millones de usuarios concurrentes. Así que no necesitábamos tests de carga ni de estrés, y los tests e2e que teníamos no necesitaban nada especial.</li>
        </ul>
      </li>
      <li><strong>En <a href="https://form3.tech/" target="_blank" rel="noopener noreferrer">Form3</a></strong>:
        <ul>
          <li>Aquí ya la cosa cambia: durante varios meses estuve en el (micro)equipo de escalabilidad, cuya principal responsabilidad era detectar (y a veces corregir) cuellos de botella en la escalabilidad de nuestro (no simple) sistema distribuido.</li>
          <li>Decir que el producto de Form3 era (o es) un <a href="https://www.api-docs.form3.tech/" target="_blank" rel="noopener noreferrer">API HTTP</a> en fintech. Manejábamos muuuuucha pasta diaria y era bastante crítico (no moría gente, pero poca broma con la panoja 🤣)</li>
          <li>Algo muy interesante es que trabajábamos mano a mano con la gente de Ventas para generar tráfico simulado conforme a la predicción “real” de nuevos usuarios (e.g. si se había firmado X contratos para cierta fecha, que implicaría N clientes/usuarios nuevos).</li>
          <li>Los tests e2e de carga y de estrés los hacíamos con <a href="https://k6.io/" target="_blank" rel="noopener noreferrer">k6.io</a> (de hecho Form3 acabó sacando una <a href="https://github.com/form3tech-oss/f1" target="_blank" rel="noopener noreferrer">solución open-source llamada ‘f1’</a> que lo simplificaba a partir del trabajo que hicimos en mi equipo, es muy interesante, recomiendo echarle un vistazo). Creábamos una distribución de peticiones horaria diaria similar a la que solíamos tener, con distribuciones Gaussianas, pero con los volúmenes estimados.</li>
          <li>Es algo que, la verdad, no había visto hacer antes ni lo he vuelto a ver 🤯</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><strong>¿Cómo se puede balancear baterías de test enormes que hacen que las pipelines tarden, con la rapidez que se necesita en trunk based?</strong>
    <ul>
      <li>Por aclararlo, en Trunk-Based Development (TBD) o CI esa “rapidez” tampoco es tanta en mi opinión: al menos mergear una vez al día en la rama principal. Yo diría que cuanta mayor frecuencia, mejor: por ejemplo, cada 2 horas máximo, mejor que cada 24 horas; y si puedes trabajar con rama única por defecto y estar haciéndolo cada pocos minutos, miel sobre hojuelas (en mi experiencia, la diferencia es abismal, pero la vida es dura y hagamos lo que podamos…).</li>
      <li>Esas “baterías de test enormes” que mencionas, ¿de qué hablamos exactamente? ¿Por qué es tan enorme? ¿Es un gran monolito no modularizado? ¿Es porque se tienen “demasiados” tests lentos?</li>
      <li>Como menciono más arriba: debemos paralelizar todo lo que podamos. La mayoría de nuestros tests (sean del tipo que sean, incluso de integración y e2e) deberían ser paralelizables (por defecto, siempre con excepciones, deberían iniciar lo que necesiten de forma autónoma y dejarlo como estaba antes).</li>
      <li>Con una correcta modularización, tal vez se podrían lanzar los tests que nos den suficiente confianza para el despliegue (solo disparar los afectados, tirar de “contract testing”, sólo los e2e/funcionales/acceptance más críticos, etc.).</li>
      <li>Y por último: es recomendable tener muchos más tests rápidos que lentos.</li>
    </ul>
  </li>
  <li><strong>Tengo sentimientos encontrados con los hooks de prepush y precommit, ya que he visto que en ocasiones han llevado a  devs hacer commits mas grandes de lo que debian de ser por no pasar los procesos de linting, tests, etc. varias veces. Te queria preguntar tu opinión sobre eso. Si los has vivido o no, o si los has vivido, como habeis llegado a encauzar la situacion.</strong> [Pregunta recibida por Twitter, gracias Eneko 🙏]
    <ul>
      <li>Lo primero: me faltaría entender por qué no pasan los procesos de linting, tests, etc. varias veces. ¿Es porque hay tests flakies o algún tipo de validación no completamente determinista? ¿O es porque los desarrolladores “cometen errores”?</li>
      <li>No me he encontrado la situación que planteas, pero porque hay varias cuestiones a las que siempre marco mucha prioridad con los Git hooks:
        <ul>
          <li>Tienen que ser <strong>MUY rápidos</strong>. Si no, dará pereza ejecutarlos o esperarás a tener muchos cambios para hacerlo.</li>
          <li>Tienen que ser deterministas: no debe variar el resultado si no varía la “entrada” (tests, linters, lo que sea).</li>
          <li>Normalmente hacemos TDD, así que si algún test falla nos solemos enterar antes, no después (<strong>acortar el feedback loop</strong>).</li>
          <li>Tenemos linters y formatters configurados en el propio IDE, exactamente igual que en el Git hook. Eso nos permite tener normalmente feedback aún más rápido y apenas encontrarnos sorpresas cuando se ejecutan los Git hooks.
Y… básicamente eso es todo lo que se me ocurre 😅 Como te digo: tendría que vivir “in situ” la situación para entender bien dónde está exactamente la fricción 😊🙏</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><strong>La posibilidad de hacer Continuous Deployment ¿no va muy ligado a la criticidad de los posibles errores de la aplicación? Es decir, no es lo mismo introducir un bug en, por ejemplo, una plataforma para escuchar música que en una app de transacciones económicas o que maneje datos muy sensibles.</strong>
    <ul>
      <li>En mi opinión, no 😊 La motivación principal para “Continuous X” (Integration/Delivery/Deployment), como mencionaba en la charla (perdón por la autoreferencia) es <strong>APRENDER rápido</strong> (para poder adaptarnos y reorientarnos rápido y poder aportar valor rápido). Queremos tener feedback lo más rápido posible sobre el <strong>QUÉ</strong> (necesidades de usuario/cliente/negocio) y sobre el <strong>CÓMO</strong> (sistemas/tecnología/organización). Y eso, por normal general, lo queremos siempre, de hecho se me antoja que en el ejemplo que comentas (y en mi experiencia), probablemente más en la aplicación de música que en la financiera.</li>
      <li>Tal y como yo lo veo, el razonamiento es el inverso: es para habilitar ese aprendizaje continuo, esos <em>feedback loops</em> rápidos, por lo que necesitamos entre otras cosas una muy buena red de seguridad que conllevará menos errores de la aplicación. Reducir los bugs no es un fin en sí mismo, es un medio para otras cuestiones (mejorar la experiencia de usuario, el aporte de valor, el aprendizaje continuo, etc.)</li>
      <li>En otras palabras: en la falsa dicotomía de “calidad vs. velocidad”, en realidad sólo con buena calidad (interna) podremos conseguir la velocidad. Es un tema ya muy tratado e incluso “probado”, por ejemplo en el <a href="https://itrevolution.com/product/accelerate/">Accelerate</a>. Hay muchos posts interesantes al respecto, por ejemplo <a href="https://codescene.com/blog/code-quality-debunking-the-speed-vs-vs-quality-myth-with-empirical-data">este de Adam Tornhill</a> o <a href="https://nelis.boucke.be/post/trunk-based-development/">este otro</a>.</li>
    </ul>
  </li>
  <li><strong>Parece que intentamos reinventar la rueda pero siempre acabamos volviendo a los conceptos de Eliyahu Goldratt. ¿En qué casos consideras que NO deberíamos aplicar todos estos principios? O por el contrario, ¿los consideras universales para cualquier espacio de problema?</strong>
    <ul>
      <li>Uuffff… una pregunta difícil. Resumen: no, no creo que sea algo universal para cualquier espacio de problema. Por ejemplo: si tienes un CRUD puro y duro, donde además “sabes” que no se va a evolucionar apenas (algo que casi nunca me he encontrado, pero venga, imaginemos), entonces no lo aplicaría. No hay incertidumbre (o eso creemos), no hay gran cosa que aprender. Pero más importante aún: es que en ese contexto a día de hoy <strong>ni siquiera desarrollaría software</strong>, ya hay muchas herramientas NoCode para resolver ese tipo de casuísticas (e.g. con baja lógica dominio de negocio).</li>
      <li>Si me pusiera “coach” 😜, hablaría del <a href="https://en.wikipedia.org/wiki/Cynefin_framework">framework Cynefin</a> y que en el dominio “claro” está “tó el pescao vendío”.</li>
      <li>Dicho todo esto: creo que es un contexto que, estadísticamente (al menos en mi <a href="https://en.wikipedia.org/wiki/Anecdotal_evidence">evidencia anecdótica experimentada y observada</a>) es infinitesimal, no suele ser el contexto en el más frecuentemente solemos movernos y por el que nos pagan.</li>
    </ul>
  </li>
  <li><strong>Cuando por el contexto de las iniciativas, por ejemplo, cambios muy complejos, no se puede mergear diariamente, ¿no se puede considerar integración continua?</strong>
    <ul>
      <li>Lo primero: necesitaría entender mucho mejor ese contexto que mencionas.</li>
      <li>Aquí voy a hacer “challenge”: en la mayoría de los casos en los que una persona o equipo me ha indicado que su contexto era “especial” o “demasiado complejo” y por tanto no podía hacer X o Y, cuando he ido rascando, preguntando, entendiendo, he o hemos visto que los problemas de base eran otros y en realidad sí se podía hacer (o al menos empezar a andar el camino). No digo que sea tu caso, porque me falta mucha información, pero sí digo que casi siempre se puede.</li>
      <li>De forma muy esporádica todo vale, somos humanos y es lo que hay (y de hecho hay situaciones puntuales donde no queda otra). Pero si ésa es la situación del día a día, si realmente no podéis mergear diariamente a una rama principal para vuestro trabajo habitual, me cuesta pensar que no sea un problema de conocimiento, principios y prácticas (es decir, que no sea un problema autogenerado). Probablemente sea “complejidad accidental” y no “complejidad esencial” (ver el mítico <a href="http://www.cs.unc.edu/techreports/86-020.pdf">“No silver bullet”, de Fred Brooks</a>).</li>
      <li>En cualquier caso: si no vas a merger al menos diariamente, no creo que podamos hablar de “continuidad” (y no pasa nada, no es una cuestión de “purismo lingüístico”, sino del valor de la práctica).</li>
      <li>Aquí recomendaría trabajar con alguien con experiencia en <a href="https://islomar.es/blog/talks/slides-and-resources-talk-bilbostack-2024/#parallel-changes">técnicas de cambios paralelos</a>, <a href="https://martinfowler.com/articles/feature-toggles.html">feature flags</a>, <a href="https://martinfowler.com/bliki/ContractTest.html">contract testing</a>, aprender a dar pasos mucho más pequeños, etc.</li>
    </ul>
  </li>
  <li><strong>¿Como sería el proceso de desplegar funcionalidades del front que dependen de cambios del back con TBD?</strong>
    <ul>
      <li>Tirando de cliché: me alegro de que me hagas esta pregunta 🤣. De hecho hubo una persona durante el <em>networking</em> que me planteó el mismo caso (tal vez fuera la misma).</li>
      <li><em>Disclaimer</em>: es más que recomendable que todo un <strong><em>value stream</em></strong> se realice dentro de un mismo equipo. Siempre hay excepciones, pero como norma general tanto Front como Back de una funcionalidad e2e debería ser <strong>responsabilidad del mismo equipo</strong>.</li>
      <li>Por una parte, de nuevo tengo que mencionar la importancia del uso de <a href="https://martinfowler.com/articles/feature-toggles.html">feature flags</a> para habilitar diversos tipos de cambios en paralelo. Por ejemplo para este caso concreto, podríamos tener un <strong><em>feature flag</em></strong> tanto en Front como en Back (por defecto único para ambos), de manera que pudiéramos desplegar de manera continua cualquiera de las dos partes sin impacto para los usuarios, mientras se va avanzando poquito a poco o esperamos “a la otra parte”. La idea es ocultar al usuario aquello que aún no esté funcionando correctamente porque aún se está trabajando en ello.</li>
      <li>En este punto, me gustaría compartir una experiencia concreta que me parece muy relevante para este caso: el proyecto en el que trabajamos desde <a href="https://www.codium.team/">Codium</a> en un cliente y del que mostré una de las <a href="https://speakerdeck.com/islomar/valor-por-encima-de-codigo-el-poder-del-despliegue-continuo?slide=44">pipelines de Despliegue Continuo</a> que teníamos (en concreto la del backend)
        <ul>
          <li>Contexto <strong>importante</strong>:
            <ul>
              <li>Formamos un equipo mixto de 3 personas de Codium y otras 3 del cliente (una de ellas como “Product Manager”). Hacíamos <strong>pairing y ensemble programming por defecto</strong>. Y aunque había una persona más especializada en Front y otra en Back, el resto rotábamos entre ambos mundos: apenas había silos ni compartimentos estancos, en el equipo más o menos casi todos hacíamos de casi todo (cada uno con sus fortalezas, claro). También éramos muy autónomos para la parte de Sistemas.</li>
              <li>Había una parte de Back (en PHP, con Symphony) y otra de Front (React con TypeScript). Desde el Back publicábamos un API HTTP que el Front consumía.</li>
            </ul>
          </li>
          <li>Al turrón: usamos <a href="https://www.openapis.org/">OpenAPI</a> para definir el contrato a cumplir entre Front y Back. Cuando se requería algún nuevo comportamiento (o cambio) e implicaba cambios en ambos lados, lo primero que hacíamos era juntarnos todo el equipo para escribir juntos el “contrato”. En un fichero yaml, OpenAPI permite definir dicho contrato, e.g. la URI del endpoint, tipos de entrada, tipos de salida, códigos de estado HTTP devueltos, etc.</li>
          <li>Una vez teníamos este contrato escrito entre todos, ya podíamos si queríamos abordar por separado el Front y el Back. Dependiendo del tipo de cambio, en ocasiones no hacía falta ni “feature flag”.</li>
          <li>Para asegurarnos de que ninguna de las dos partes rompía el contrato, teníamos varias validaciones en Git hooks y la pipeline (en el diagrama que compartí se puede ver):
            <ul>
              <li><strong>Backend</strong>:
                <ul>
                  <li>Usamos <a href="https://schemathesis.readthedocs.io/en/stable/">schemathesis</a>. Es una herramienta que automatiza el testing de APIs HTTP, generando dinámicamente casos de tests a partir del contrato de OpenAPI. Permite múltiples configuraciones según el número de tests que se desean, paralelismo, etc.</li>
                  <li>Básicamente lo usábamos para lanzar tests dinámicos a partir del contrato contra el API publicado por el Back.</li>
                  <li>Lo ejecutábamos en dos momentos diferentes:
                    <ul>
                      <li>En el Git hook de pre-push, contra un entorno local (automáticamente levantado con Docker)</li>
                      <li>Durante la pipeline se ejecutaba por ejemplo contra el entorno de Staging, una vez desplegado ahí el Back.</li>
                    </ul>
                  </li>
                </ul>
              </li>
              <li><strong>Frontend</strong>:
                <ul>
                  <li>Usamos <a href="https://github.com/jormaechea/open-api-mocker">jormaechea/open-api-mocker</a>, que es un API mocker basado en OpenAPI 3.0</li>
                  <li>Básicamente levantaba un servidor mock a partir del contrato que teníamos de OpenAPI, y era quien recibía las peticiones durante ciertos tipos de tests del Frontend.</li>
                </ul>
              </li>
              <li>El fichero yaml con el contrato de OpenAPI estaba tanto en el Front como en el Back: esa duplicidad no era ideal, pero sí muy “barata” en su momento. En la pipeline teníamos una validación para asegurarnos de que el contrato era exactamente el mismo en ambos lados (y por supuesto nos enterábamos inmediatamente si eso ocurría).</li>
            </ul>
          </li>
        </ul>
      </li>
      <li><strong>IMPORTANTE</strong>: la elección de estas herramientas fue realizada hace varios años, es más que probable que hoy en día existan mejores soluciones 😊</li>
      <li>Si los endpoints del Back fueran consumidos por <strong>muchos</strong> más consumidores (valga la rebuznancia), tal vez podríamos plantearnos soluciones más avanzadas (y también mucho más complejas, mejor esperar a necesitarlo DE VERDAD), como <a href="https://pact.io/">Pact</a>.</li>
    </ul>
  </li>
</ol>

<hr />

<p>¡¡Y esto es todo!! Con esto me quito la espinita de no haber podido dar respuesta a ninguna pregunta tras mi charla 😊</p>

<p>La verdad es que me he divertido mucho respondiendo, ha sido un ejercicio interesante y ya sólo espero haberle aportado algo a alguien 🙏</p>]]></content><author><name>Isidro López</name></author><category term="blog" /><category term="talks" /><category term="talks" /><category term="bilbostack24" /><category term="spanish" /><summary type="html"><![CDATA[Here you can read the post in English]]></summary></entry><entry xml:lang="en"><title type="html">Slides and resources from my talk at BilboStack 2024</title><link href="https://islomar.es/slides-and-resources-talk-bilbostack-2024/" rel="alternate" type="text/html" title="Slides and resources from my talk at BilboStack 2024" /><published>2024-01-29T13:26:27+01:00</published><updated>2024-01-29T13:26:27+01:00</updated><id>https://islomar.es/slides-and-resources-talk-bilbostack-2024</id><content type="html" xml:base="https://islomar.es/slides-and-resources-talk-bilbostack-2024/"><![CDATA[<p>Some months ago, the organization of the amazing conference <a href="https://bilbostack.com/" target="_blank" rel="noopener noreferrer">BilboStack</a> made the mistake of inviting me to talk to the 2024 edition 😆</p>

<p>I decided to talk about <strong>Continuous Deployment</strong>… as a Trojan horse in order to talk about many other topics related with software and product development (probably too many indeed! 😅)</p>

<p>Last Saturday, 27th January 2024, I finally gave it: <a href="https://2024.bilbostack.com/isidro-lopez" target="_blank" rel="noopener noreferrer">“Valor por encima de código: el poder del Despliegue Continuo”</a>, which might be translated to English as “Value over Code: the power of Continuous Deployment”.</p>

<p>Here I would like to share the slides and some of the people and resources included in the talk (and if you spot any link not working properly, please tell me 🙏).</p>

<p>Also, I have answered in another post all the questions sent during the talk; here you have it <a href="/questions-and-answers-bilbostack-2024">in English</a> and here <a href="/preguntas-y-respuestas-bilbostack-2024">in Spanish</a>.</p>

<p>Oh, and one last thing: I have included 3 extra slides that didn’t appear during the talk… if you attended, you can try to spot them! 😜</p>

<p>[Spanish] Si quienes asististeis a la charla me pudierais dar feedback (de mejora y positivo, cuanto más concreto mejor), os agradecería ENORMEMENTE si pudierais invertir 2 minutos (de reloj) en rellenar <a href="https://forms.gle/4omyq7PWoVbkWEJr5">este formulario</a> ¡¡GRACIAS!! 🙏🙏🙏</p>

<h2 id="slides">Slides</h2>
<ul>
  <li><a href="https://speakerdeck.com/islomar/valor-por-encima-de-codigo-el-poder-del-despliegue-continuo" target="_blank" rel="noopener noreferrer">In Speaker Deck</a></li>
  <li><a href="https://docs.google.com/presentation/d/e/2PACX-1vQjRyNPunwWLBRP-gEEVnMMVLq0373KDyT1IpqJXwato2jtTRtdjqecHNtQrJBiVzZ4j-WAc6J5py6c/pub?start=false&amp;loop=false&amp;delayms=3000" target="_blank" rel="noopener noreferrer">In Google Slides</a></li>
</ul>

<style>
.responsive-wrap iframe{ max-width: 100%;}
</style>

<div class="responsive-wrap">
<!-- this is the embed code provided by Google -->
    <iframe src="https://docs.google.com/presentation/d/e/2PACX-1vQjRyNPunwWLBRP-gEEVnMMVLq0373KDyT1IpqJXwato2jtTRtdjqecHNtQrJBiVzZ4j-WAc6J5py6c/embed?start=false&amp;loop=false&amp;delayms=3000" frameborder="0" width="1440" height="839" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
<!-- Google embed ends -->
</div>

<h2 id="recommended-books">Recommended books</h2>
<ul>
  <li><a href="https://thisislean.com/" target="_blank" rel="noopener noreferrer">“This is Lean”</a>, by Niklas Modig &amp; Pär Åhlström</li>
  <li><a href="https://fiftyquickideas.com/fifty-quick-ideas-to-improve-your-user-stories/" target="_blank" rel="noopener noreferrer">“Fifty quick ideas to improve your User Stories”</a>, by Gojko Adzic &amp; David Evans</li>
  <li><a href="https://continuousdelivery.com/" target="_blank" rel="noopener noreferrer">“Continuous Delivery”</a>, by Jez Humble and David Farley</li>
  <li><a href="https://www.goodreads.com/book/show/67833.Extreme_Programming_Explained" target="_blank" rel="noopener noreferrer">“Extreme Programming Explained”</a>, by Kent Beck</li>
  <li><a href="https://www.oreilly.com/library/view/building-evolutionary-architectures/9781491986356/" target="_blank" rel="noopener noreferrer">“Building evolutionary architectures”</a>, by Neal Ford, Rebecca Parsons &amp; Patrick Kua</li>
  <li><a href="https://leanpub.com/cd-pipelines" target="_blank" rel="noopener noreferrer">“Continuous Delivery Pipelines: how to build better software faster”</a>, by Dave Farley</li>
  <li><a href="https://pragprog.com/titles/mnee2/release-it-second-edition/" target="_blank" rel="noopener noreferrer">“Release it! - Design and deploy production-ready software”</a>, by Michael T. Nygard</li>
  <li><a href="https://itrevolution.com/product/accelerate/" target="_blank" rel="noopener noreferrer">“Accelerate - The Science of Lean Software and DevOps: Building and Scaling High Performing Technology Organizations”</a>, by Nicole Forsgreen, Jez Humble &amp; Gene Kim</li>
  <li><a href="https://donellameadows.org/systems-thinking-book-sale/" target="_blank" rel="noopener noreferrer">“Thinking in systems: a primer”</a>, by Donella H. Meadows</li>
  <li><a href="https://shop.leankanban.com/products/stop-starting-start-finishing-arne-roock-english-kindle-mobi-ebook-digital-edition" target="_blank" rel="noopener noreferrer">“Stop starting, start finishing!”</a>, by Arne Roock</li>
  <li><a href="https://www.goodreads.com/book/show/123715.Slack" target="_blank" rel="noopener noreferrer">“Slack: getting past burnout, busywork, and the myth of total efficiency”</a>, by Tom DeMarco</li>
  <li><a href="https://sammancoaching.org/" target="_blank" rel="noopener noreferrer">“Technical Agile Coaching with the Samman method”</a>, by Emily Bache</li>
  <li><a href="https://leanpub.com/agiletechnicalpracticesdistilled" target="_blank" rel="noopener noreferrer">“Agile Technical practices distilled”</a>, by Pedro M. Santos, Marco Consolaro &amp; Alessandro Di Gioia</li>
</ul>

<h2 id="real-life-examples-of-continuous-deployment-pipelines">Real life examples of Continuous Deployment pipelines</h2>
<p>I’ve been “lucky” enough to experience several teams and companies where we grew Continuous Delivery and Continuous Deployment pipelines. Here I would like to share two specific examples:</p>

<p align="center">
    <img src="/assets/images/Continuous_Deployment_pipeline_with_Codium.png" alt="Diagram with a Continuous Deployment pipeline" title="Continuous Deployment pipeline with Codium" />
</p>

<p align="center">
    <img src="/assets/images/Continuous_Deployment_pipeline_within_Clarity_AI.png" alt="Diagram with a Continuous Deployment pipeline" title="Continuous Deployment pipeline within Clarity AI" />
</p>

<h2 id="some-recommended-people">Some recommended people</h2>
<ul>
  <li>Eduardo Ferro
    <ul>
      <li><a href="https://bsky.app/profile/eferro.net" target="_blank" rel="noopener noreferrer">https://bsky.app/profile/eferro.net</a></li>
      <li><a href="https://www.eferro.net/" target="_blank" rel="noopener noreferrer">https://www.eferro.net/</a></li>
    </ul>
  </li>
  <li>Jessica Kerr
    <ul>
      <li><a href="https://bsky.app/profile/jessitron.bsky.social" target="_blank" rel="noopener noreferrer">https://bsky.app/profile/jessitron.bsky.social</a></li>
      <li><a href="https://jessitron.com/" target="_blank" rel="noopener noreferrer">https://jessitron.com/</a></li>
    </ul>
  </li>
  <li>Dave Farley
    <ul>
      <li><a href="https://bsky.app/profile/davefarley77.bsky.social" target="_blank" rel="noopener noreferrer">https://bsky.app/profile/davefarley77.bsky.social</a></li>
      <li><a href="https://www.youtube.com/c/ContinuousDelivery" target="_blank" rel="noopener noreferrer">https://www.youtube.com/c/ContinuousDelivery</a></li>
    </ul>
  </li>
  <li>Charity Majors
    <ul>
      <li><a href="https://bsky.app/profile/charity.wtf" target="_blank" rel="noopener noreferrer">https://bsky.app/profile/charity.wtf</a></li>
      <li><a href="https://charity.wtf/" target="_blank" rel="noopener noreferrer">https://charity.wtf/</a></li>
    </ul>
  </li>
  <li>Jez Humble
    <ul>
      <li><a href="https://bsky.app/profile/jezhumble.net" target="_blank" rel="noopener noreferrer">https://bsky.app/profile/jezhumble.net</a></li>
      <li><a href="https://continuousdelivery.com/" target="_blank" rel="noopener noreferrer">https://continuousdelivery.com/</a></li>
    </ul>
  </li>
  <li>Geepaw Hill
    <ul>
      <li><a href="https://mastodon.social/@GeePawHill" target="_blank" rel="noopener noreferrer">https://mastodon.social/@GeePawHill</a></li>
      <li><a href="https://www.geepawhill.org/" target="_blank" rel="noopener noreferrer">https://www.geepawhill.org/</a></li>
    </ul>
  </li>
  <li>Clare Sudbery
    <ul>
      <li><a href="https://bsky.app/profile/claresudbery.bsky.social" target="_blank" rel="noopener noreferrer">https://bsky.app/profile/claresudbery.bsky.social</a></li>
      <li><a href="https://insimpleterms.blog/" target="_blank" rel="noopener noreferrer">https://insimpleterms.blog/</a></li>
    </ul>
  </li>
  <li>Kent Beck
    <ul>
      <li><a href="https://bsky.app/profile/kentbeck.com" target="_blank" rel="noopener noreferrer">https://bsky.app/profile/kentbeck.com</a></li>
      <li><a href="https://www.kentbeck.com/" target="_blank" rel="noopener noreferrer">https://www.kentbeck.com/</a></li>
    </ul>
  </li>
  <li>Emily Bache
    <ul>
      <li><a href="https://bsky.app/profile/emilybache.com" target="_blank" rel="noopener noreferrer">https://bsky.app/profile/emilybache.com</a></li>
      <li><a href="https://www.youtube.com/@EmilyBache-tech-coach" target="_blank" rel="noopener noreferrer">https://www.youtube.com/@EmilyBache-tech-coach</a></li>
    </ul>
  </li>
  <li>Martin Fowler
    <ul>
      <li><a href="https://bsky.app/profile/martinfowler.com" target="_blank" rel="noopener noreferrer">https://bsky.app/profile/martinfowler.com</a></li>
      <li><a href="https://martinfowler.com/" target="_blank" rel="noopener noreferrer">https://martinfowler.com/</a></li>
    </ul>
  </li>
</ul>

<h2 id="other-resources">Other resources</h2>
<h3 id="general">General</h3>
<ul>
  <li><a href="https://wiki.c2.com/?SoftwareAsLiability">https://wiki.c2.com/?SoftwareAsLiability</a></li>
  <li><a href="https://www.youtube.com/watch?v=ESOaDiv3lXA">What is Value? by Jez Humble</a> (video)</li>
  <li><a href="https://medium.com/coding-stones/estimar-es-timar-example-mapping-e9dbad471ced">Estimar es timar: Example Mapping</a></li>
  <li><a href="https://martinfowler.com/articles/evodb.html">Evolutionary Database Design</a></li>
  <li><a href="https://twitter.com/tottinge/status/1748277312200540523">https://twitter.com/tottinge/status/1748277312200540523</a></li>
</ul>

<h3 id="continuous-integration-delivery-and-deployment">Continuous Integration, Delivery and Deployment</h3>
<ul>
  <li><a href="https://martinfowler.com/articles/continuousIntegration.html">A major revision of Continuous Integration</a> (by Martin Fowler)</li>
  <li><a href="https://www.youtube.com/watch?v=97qyNQz7fxY">Continuous Integration: That’s Not What They Meant • Clare Sudbery • YOW! 2023</a> (video)</li>
  <li><a href="https://minimumcd.org">Minimum Viable Continuous Delivery</a></li>
  <li><a href="https://resources.github.com/ci-cd/">CI/CD: the what, why and how</a></li>
  <li><a href="https://www.youtube.com/watch?v=7SNbDWob6cI">Continuous Delivery vs Continuous Deployment</a> (video by Dave Farley)</li>
  <li><a href="https://martinfowler.com/articles/continuousIntegration.html">https://martinfowler.com/articles/continuousIntegration.html</a></li>
  <li><a href="https://www.infoq.com/articles/continuous-delivery-teamplay/">https://www.infoq.com/articles/continuous-delivery-teamplay/</a></li>
  <li><a href="https://martinfowler.com/bliki/ContinuousDelivery.html">https://martinfowler.com/bliki/ContinuousDelivery.html</a></li>
  <li><a href="https://www.eficode.com/blog/pipeline-card-game">Card game to design Continuous Delivery pipelines</a> (by Emily Bache)</li>
  <li><a href="https://www.atlassian.com/continuous-delivery/principles/continuous-integration-vs-delivery-vs-deployment">Continuous integration vs. delivery vs. deployment</a></li>
  <li><a href="https://charity.wtf/2021/08/27/software-deploys-and-cognitive-biases">https://charity.wtf/2021/08/27/software-deploys-and-cognitive-biases</a></li>
  <li><a href="https://martinfowler.com/bliki/FrequencyReducesDifficulty.html">https://martinfowler.com/bliki/FrequencyReducesDifficulty.html</a></li>
</ul>

<h3 id="lean-and-flow">Lean and Flow</h3>
<ul>
  <li><a href="https://abrahamvallez.medium.com/one-piece-flow-7d5ade46d203">https://abrahamvallez.medium.com/one-piece-flow-7d5ade46d203</a></li>
  <li><a href="https://jessitron.com/2021/01/18/when-costs-are-nonlinear-keep-it-small">https://jessitron.com/2021/01/18/when-costs-are-nonlinear-keep-it-small</a></li>
  <li><a href="https://www.geepawhill.org/2021/05/18/big-batch-releases">https://www.geepawhill.org/2021/05/18/big-batch-releases</a></li>
  <li><a href="https://www.eferro.net/2021/01/small-batches-for-win-continuous.html">https://www.eferro.net/2021/01/small-batches-for-win-continuous.html</a></li>
  <li><a href="https://refactoring.fm/p/how-shipping-fast-changes-your-life">https://refactoring.fm/p/how-shipping-fast-changes-your-life</a></li>
  <li><a href="https://innolution.com/blog/limiting-work-in-process-wip-and-having-small-batches-is-antifragile">https://innolution.com/blog/limiting-work-in-process-wip-and-having-small-batches-is-antifragile</a></li>
  <li><a href="https://www.youtube.com/watch?v=Yqi9Gwt-OEA">Henrik Kniberg : Multiple WIP vs One Piece Flow Example</a> (video)</li>
</ul>

<h3 id="parallel-changes">Parallel changes</h3>

<ul>
  <li><a href="https://martinfowler.com/bliki/ParallelChange.html">https://martinfowler.com/bliki/ParallelChange.html</a></li>
  <li><a href="https://martinfowler.com/articles/feature-toggles.html">Feature toggles (aka “feature flags”)</a></li>
  <li><a href="https://martinfowler.com/bliki/BranchByAbstraction.html">Branch by abstraction</a></li>
  <li><a href="https://paulhammant.com/2013/07/14/legacy-application-strangulation-case-studies/">Strangler Fig pattern</a>
    <ul>
      <li><a href="https://martinfowler.com/bliki/StranglerFigApplication.html">Strangler Fig Application</a></li>
      <li><a href="https://shopify.engineering/refactoring-legacy-code-strangler-fig-pattern">Refactoring Legacy Code with the Strangler Fig Pattern</a></li>
    </ul>
  </li>
  <li><a href="https://docs.microsoft.com/en-us/azure/architecture/patterns/anti-corruption-layer">Anti-Corruption Layer</a></li>
  <li><a href="https://www.infoq.com/presentations/The-Limited-Red-Society/">The Limited Red Society</a></li>
</ul>

<h3 id="workshops-about-parallel-changes">Workshops about parallel changes</h3>
<ul>
  <li><a href="https://www.eferro.net/p/small-safe-steps-3s-workshop.html">Small Safe Steps 3s workshop - Agile (slides)</a>, by Eduardo Ferro</li>
  <li><a href="https://paucls.wordpress.com/2020/02/26/ci-cd-non-breaking-changes-exercise">https://paucls.wordpress.com/2020/02/26/ci-cd-non-breaking-changes-exercise</a></li>
</ul>

<h3 id="canary-releases-and-blue-green-deployment">Canary releases and Blue-green deployment</h3>
<ul>
  <li><a href="https://martinfowler.com/bliki/CanaryRelease.html">https://martinfowler.com/bliki/CanaryRelease.html</a></li>
  <li><a href="https://martinfowler.com/bliki/BlueGreenDeployment.html">https://martinfowler.com/bliki/BlueGreenDeployment.html</a></li>
  <li><a href="https://www.redhat.com/en/topics/devops/what-is-blue-green-deployment">https://www.redhat.com/en/topics/devops/what-is-blue-green-deployment</a></li>
  <li><a href="https://learn.hashicorp.com/tutorials/terraform/blue-green-canary-tests-deployments">https://learn.hashicorp.com/tutorials/terraform/blue-green-canary-tests-deployments</a></li>
  <li><a href="https://aws.amazon.com/es/blogs/compute/bluegreen-deployments-with-amazon-ecs">https://aws.amazon.com/es/blogs/compute/bluegreen-deployments-with-amazon-ecs</a></li>
</ul>

<h3 id="trunk-based-development">Trunk-Based Development</h3>
<ul>
  <li><a href="https://youtu.be/MXDJba472jE?t=1522">Lightning talk: “Pusheando a master, que es gerundio”</a> (video, in Spanish)</li>
  <li><a href="https://trishagee.com/2023/05/29/why-i-prefer-trunk-based-development/">Why I prefer trunk-based development</a> (Trisha Gee)</li>
  <li><a href="https://www.davefarley.net/?p=269">Perceived Barriers to Trunk-Based Development</a> (Dave Farley)</li>
  <li><a href="https://www.youtube.com/watch?v=aNgWjSAjjtg">Neil Crawdford - Trunk based development, continuous deployment and why you should adopt them</a> (video)</li>
  <li><a href="https://www.youtube.com/watch?v=qJhmqIv6SJk">Of Death and Dying: A Journey to Trunk Based Development</a> (video)</li>
  <li><a href="https://learning.oreilly.com/library/view/what-is-trunk-based/9781098146658/">What is Trunk-Based Development?</a> (Clare Sudbery)</li>
  <li><a href="https://nelis.boucke.be/post/trunk-based-development">https://nelis.boucke.be/post/trunk-based-development</a></li>
</ul>

<h3 id="branching-pull-requests-and-blocking-code-reviews">Branching, Pull requests and blocking code reviews</h3>
<ul>
  <li><a href="https://elimydlarz.com/2021/08/09/how-to-stop-branching/">How to stop branching</a></li>
  <li><a href="https://thinkinglabs.io/articles/2022/05/30/on-the-evilness-of-feature-branching-the-problems.html">https://thinkinglabs.io/articles/2022/05/30/on-the-evilness-of-feature-branching-the-problems.html</a></li>
  <li><a href="https://www.youtube.com/watch?v=LVr-SMLrfgg">Async Code Reviews Are Killing Your Company’s Throughput</a> (video)</li>
  <li><a href="https://martinfowler.com/articles/branching-patterns.html">https://martinfowler.com/articles/branching-patterns.html</a></li>
  <li>Other experiences:
    <ul>
      <li><a href="https://twitter.com/jlangr/status/1487135760012627973">https://twitter.com/jlangr/status/1487135760012627973</a></li>
      <li><a href="https://twitter.com/aahoogendoorn/status/1531709454701453312">https://twitter.com/aahoogendoorn/status/1531709454701453312</a></li>
    </ul>
  </li>
</ul>

<h3 id="vertical-slicing">(Vertical) Slicing</h3>
<ul>
  <li><a href="https://www.youtube.com/watch?v=R_JQGXmrkyY">Agile Delivery - Lean Coffee - Slicing</a> (video, in Spanish)</li>
  <li><a href="https://gojko.net/2012/01/23/splitting-user-stories-the-hamburger-method">https://gojko.net/2012/01/23/splitting-user-stories-the-hamburger-method</a></li>
  <li><a href="https://xp123.com/articles/slicing-functionality-alternate-paths">https://xp123.com/articles/slicing-functionality-alternate-paths</a></li>
  <li><a href="https://www.humanizingwork.com/wp-content/uploads/2020/10/HW-Story-Splitting-Flowchart.pdf">How to split a user story?</a> (PDF flowchart)</li>
  <li><a href="https://docs.google.com/document/d/1TCuuu-8Mm14oxsOnlk8DqfZAA1cvtYu9WGv67Yj_sSk/pub">Elephant Carpaccio facilitation guide</a></li>
</ul>]]></content><author><name>Isidro López</name></author><category term="blog" /><category term="talks" /><category term="talks" /><category term="bilbostack24" /><category term="lean" /><category term="english" /><category term="continuous-integration" /><category term="continuous-deployment" /><category term="systems-thinking" /><summary type="html"><![CDATA[Some months ago, the organization of the amazing conference BilboStack made the mistake of inviting me to talk to the 2024 edition 😆]]></summary></entry><entry xml:lang="en"><title type="html">Some interview questions as an interviewee</title><link href="https://islomar.es/some-interview-questions-as-interviewee/" rel="alternate" type="text/html" title="Some interview questions as an interviewee" /><published>2021-11-10T13:05:34+01:00</published><updated>2025-09-23T11:01:31+02:00</updated><id>https://islomar.es/some-interview-questions-as-interviewee</id><content type="html" xml:base="https://islomar.es/some-interview-questions-as-interviewee/"><![CDATA[<p>This post is the extraction of a section at my page <a href="../../my-professional-services">My professional services</a>.
Some people enjoyed this part especially, so I thought it might be a good idea to extract it as an independent post that I might update from time to time.</p>

<p>The goal of these questions is to help clarifying my <strong>expectations</strong> and to generate the clearest and broadest possible idea about the company, the business, the culture, the role, the day-to-day work, etc. To better grab the “lights” and the “darkness”. Another outcome is to <strong>reduce the probability of a misalignment and big surprises</strong> during the first weeks of work 😊</p>

<p>And always remember that <strong>an interview is (or should be) a 2-ways conversation</strong>, a 2-ways discovering process.</p>

<p>Besides having many general questions, some of them depend on each specific role and company. Here some things that I do to get so much information as possible for getting some specific questions:</p>

<ul>
  <li>Carefully reading the job advertisement.</li>
  <li>Carefully reading their engineering blog or publications (in case they have them).</li>
  <li>Reading the “Careers” or “About us” from their website, any page with information about their culture, etc.</li>
  <li>Reading their information in LinkedIn.</li>
  <li>Look for news related with the company.</li>
  <li>Look for them in <a href="https://www.crunchbase.com/">Crunchbase</a></li>
  <li>Look for them in <a href="https://www.glassdoor.com/index.htm">Glassdoor</a></li>
  <li>Contact through LinkedIn with any acquittance you might have there, in the present or past, in order to ask them about their opinion (always with respect and maximum sensibility).</li>
</ul>

<p>So… here I share some of the questions that I have asked in the past or I will ask in the future to my interviewers; I would recommend you to select only a few and prioritize them according to the time that you have available, and taking into account the different stages during the recruitment process.</p>

<ul>
  <li>What is your <strong>mission</strong> and short-term goals as an organisation? What is your <strong>vision</strong> and long-term goals?</li>
  <li>What is the <strong>business model</strong> of the company? Who are your customers, users, providers?</li>
  <li>What <strong>differentiates</strong> you from any other company and from your competitors?</li>
  <li><strong>How do you earn money</strong>, what are your <strong>revenue streams</strong>? Did you surpass the break-even?</li>
  <li>How do you <strong>improve</strong> as a company or team? How do you <strong>learn</strong>?</li>
  <li>How are you <strong>organised</strong>? (company-wide and engineering)</li>
  <li>How do you take <strong>decision</strong>s? Who takes which ones and when? What decisions are taken at each “level”?</li>
  <li>How do you <strong>communicate</strong>? How do you get <strong>feedback</strong> in all the needed directions?</li>
  <li>How do you keep the whole organisation <strong>aligned</strong>?</li>
  <li>Do you consider the company a <strong>remote-first</strong> one? E.g. is there any company or team event which does not happen online? Can I enjoy my own local bank holidays? Will you pay for any expense related with an on-site gathering?</li>
  <li>Are there explicit actions in place to take care about <strong>Diversity, Equity and Inclusion (DE&amp;I)</strong>? E.g. do you have numbers about gender diversity? About age diversity? What about diversity in leadership and management positions (C-level included)?</li>
  <li>What opportunities exist for <strong>mentorship</strong>?</li>
  <li>What do you <strong>enjoy</strong> the most from working there?</li>
  <li>Tell me something that you don’t like here. What room for <strong>improvement</strong> exists? What would you like to be different, why and how?</li>
  <li>What are the current main <strong>challenges</strong> for the company? (product and technical challenges)</li>
  <li>What are the main <strong>challenges in the team</strong> that I would join? What are the current main pains?</li>
  <li>Why would you <strong>fire me</strong>?</li>
  <li><strong>Why are you hiring</strong> for this specific position? Is it a new team? Is it a backfill? In case it is a backfill, why, what happened?</li>
  <li><strong>Psychological safety</strong> is extremely important to me, so please be honest with me: are there verbally aggressive people, especially in positions with power?</li>
  <li>Is there <strong>micromanagement</strong> from any position with power (e.g CTO/VP/Head/Managers)? How do they intervene in team’s decisions if they don’t agree?</li>
  <li>What would be my <strong>boundaries</strong>? What wouldn’t I be allowed to do or to step into?</li>
  <li>What do you <strong>expect</strong> from me?</li>
  <li>Why don’t you cover this position with a current internal employee?</li>
  <li>Do you have a structured <strong>onboarding</strong> plan for me?</li>
  <li>Who would be <strong>my manager</strong>? I would like to talk to them and understand their vision and expectations about me.</li>
  <li>Why did the last 2 people of Engineering left? How did you handle it?</li>
  <li>Why did the last 2 people of Engineering were fired (or made redundant 😉)? How did you handle it?</li>
  <li>How do you take <strong>care</strong> of people?</li>
  <li>Can I talk to any <strong>potential peer</strong>, specially someone already doing the same work? Can I talk with a team?</li>
  <li>What does a <strong>team</strong> look like there?</li>
  <li>How would you describe your <strong>ideal colleague</strong>? And your ideal team?</li>
  <li>Who decides how a team works? (“rituals”, principles, practices, roles, etc.)</li>
  <li>What does <strong>“technical/engineering excellence”</strong> mean to you?</li>
  <li>Tell me about your <strong>infrastructure and platform</strong>. What is automated? Can the “external product teams” deploy on their own?</li>
  <li>Tell me about your <strong>observability</strong> practices. How do you find out that there is a problem? How do you dig deeper to solve it?</li>
  <li>What happens when an incident in Production is detected?</li>
  <li>Tell me about your main <strong>technical principles and practices</strong>.</li>
  <li>Is it needed to do <strong>on-call</strong> outside of working hours? (from my timezone perspective)
    <ul>
      <li>How often?</li>
      <li>How many production incidents do you have while on-call per week?</li>
      <li>Is it paid extra?</li>
    </ul>
  </li>
  <li>What is approximately your <strong>lead time</strong> (time from a commit to Production), <strong>throughput</strong> (frequency of deployments/releases to Production) and <strong>error rate</strong>?</li>
  <li>Could you tell me which is the whole lifecycle of a <strong>user need</strong>? Could you describe for me any of your main <strong>value streams</strong>? From the discovery of the user need until its satisfaction.</li>
  <li>How and when is the <strong>priorization</strong> done? Who does it? Based on what?</li>
  <li>How do you optimize the <strong>business and technical alignment of the teams</strong>?</li>
  <li>How do you handle <strong>disagreements</strong> on technical approaches?</li>
  <li>What happens from the moment a developer starts working on something until it is deployed? Could you please describe to me your <strong>delivery pipeline</strong>? What’s the full <strong>journey of a commit</strong>?</li>
  <li>How many teams does a team depend on to get a small change into production?</li>
  <li>What is the entire process for a <strong>one line change</strong> in code to make it to production? (by <a href="https://twitter.com/jeremykahne/status/1469416655168196620">Jeremy Kahne</a>)</li>
  <li>Do you decouple <strong>“Release”</strong> from “Deployment”?</li>
  <li>What is a <strong>typical day</strong> of a team? (from the very start to the very end)</li>
  <li>Do you support <strong>open source</strong> in any way?</li>
  <li>How does the whole <strong>recruitment process</strong> work? Which will be the next steps?</li>
  <li>What is the <strong>salary range</strong>? Social benefits?</li>
  <li>Is there any <strong>budget</strong> for training or any other concept?</li>
  <li>Would there be the possibility to work <strong>30-32 hours per week</strong> (6 hours per day or 4 days per week)?</li>
</ul>

<h2 id="more-questions-from-other-people">More questions from other people</h2>

<ul>
  <li><a href="https://charity.wtf/2022/01/29/how-can-you-tell-if-the-company-youre-interviewing-with-is-rotten-on-the-inside/">Charity Majors: How can you tell if the company you’re interviewing with is rotten on the inside?</a></li>
  <li><a href="https://blog.pragmaticengineer.com/pragmatic-engineer-test/">The Pragmatic Engineer Test: 12 Questions on Engineering Culture</a></li>
  <li><a href="https://flopezluis.medium.com/list-of-questions-to-identify-a-toxic-culture-during-the-interview-ba751cd0bf13">List of questions to identify a toxic culture during the interview</a>
    <ul>
      <li>A <a href="https://twitter.com/flopezluis/status/1463482536185716738">Twitter thread</a> with some great questions you can ask to identify a toxic culture in an interview, from <a href="https://es.linkedin.com/in/flopezluis">Félix López</a>.</li>
    </ul>
  </li>
  <li><a href="https://continuous-delivery.co.uk/downloads/How%20To%20-%20Get%20Your%20Next%20Job%2008-01-2025.pdf">How To - Get Your Next Job 01-08-2025</a> by Dave Farley</li>
  <li><a href="https://youtu.be/2Afk9KVEgpE">20 questions to ask your next employer</a>, video 18 min by Dave Farley</li>
  <li><strong>Six questions to determine whether a company is product-led</strong> (from the book <a href="https://www.oreilly.com/library/view/escaping-the-build/9781491973783/">“Escaping the build trap”</a> by Melissa Perri)
    <ul>
      <li>Who came up with the last feature or product idea you built?</li>
      <li>What was the last product you decided to kill?</li>
      <li>When’s the last time you talked with your customers?</li>
      <li>What is your goal?</li>
      <li>What are you currently working on?</li>
      <li>What are your product managers like?</li>
    </ul>
  </li>
  <li><a href="https://dev.to/epilot/the-product-engineer-checklist-469d">The Product Engineer Checklist (by epilot)</a></li>
  <li><a href="https://www.getmanfred.com/blog/que-preguntas-debes-hacer-en-una-entrevista">“Qué preguntas debes hacer en una entrevista” (Manfred)</a></li>
</ul>]]></content><author><name>Isidro López</name></author><category term="blog" /><category term="english" /><category term="interviews" /><summary type="html"><![CDATA[This post is the extraction of a section at my page My professional services. Some people enjoyed this part especially, so I thought it might be a good idea to extract it as an independent post that I might update from time to time.]]></summary></entry><entry xml:lang="en"><title type="html">YAHWP (Yet Another Hello World Post)</title><link href="https://islomar.es/yet-another-hello-world-post/" rel="alternate" type="text/html" title="YAHWP (Yet Another Hello World Post)" /><published>2020-06-29T21:22:00+02:00</published><updated>2020-06-29T21:22:00+02:00</updated><id>https://islomar.es/yet-another-hello-world-post</id><content type="html" xml:base="https://islomar.es/yet-another-hello-world-post/"><![CDATA[<p>Reintento número 459347 de escribir un blog de manera sostenida en el tiempo: ¡¡aaaaaacción!!</p>

<p>Pues nada, <a href="https://play.cadenaser.com/programa/jazztamos_aqui/">jazztamos aquí</a>. Ocho años después de mi último intento de arrancar y mantener un blog (“El reposo del guerrero” por aquel entonces, tres <em>posts</em> duré, que la tierra le sea leve), voy a intentarlo de nuevo.</p>

<h2 id="el-porqué-de-las-cosas"><a href="https://www.goodreads.com/book/show/23126.El_porqu_de_las_cosas">El porqué de las cosas</a></h2>
<p>¿Y por qué escribir? ¿Y para qué escribir? ¿Y para quién escribir? Bueno, me vienen varias respuestas a la mente:</p>
<ul>
  <li>Escribiré <strong>principalmente para mí</strong>:
    <ul>
      <li>En ocasiones como <strong>recordatorios</strong> para mi yo futuro, tanto de cuestiones técnicas como sobre mi pensamiento en un determinado momento sobre el tema X.</li>
      <li>En otras ocasiones para “obligarme” a estructurar mejor lo que pienso sobre algo. No hay nada como tener que expresar o explicar algo, para ayudarte a <strong>interiorizarlo mejor</strong>.</li>
      <li>Y como refrito de lo anterior: para <strong>aprender</strong>. Tanto por el proceso de escritura como de las posibles <strong>conversaciones</strong> que surjan después con quien lo lea.</li>
    </ul>
  </li>
  <li>Aunque no solo para mí (para eso no haría falta publicarlo): por muy obvio que nos parezca algo, siempre habrá a quien lo que una sabe/cree/piensa le aporte algún valor (lo que sea: algo técnico, político, espiritual, etc.). Ojalá algo, en algún momento, desde la humildad, <strong>le sea de utilidad a alguien</strong>.</li>
</ul>

<h2 id="y-cómo-lo-haré">¿Y cómo lo haré?</h2>
<p>No me es fácil, pero intentaré no sucumbir al <a href="https://cajadeletras.es/sindrome-del-folio-en-blanco/">síndrome del folio en blanco</a>, al típico bloqueo por querer escribir algo “interesante”.</p>

<p>En 2010 descubrí a <a href="https://www.sethgodin.com/">Seth Godin</a>. Un clásico: fue haciendo un <em>Executive MBA</em> (ya solo eso da para un post), donde era uno de los referentes para todo lo relacionado con <em>marketing</em> (por supuesto devoré <a href="https://www.goodreads.com/book/show/24789184-la-vaca-p-rpura">“La vaca púrpura”</a>).</p>

<p>A lo que voy: Seth Godin <a href="https://seths.blog/">escribe un blog</a> desde hace mil años, el cual sigo y recomendaría seguir a todo el mundo. Pero lo que siempre me ha fascinado de su blog, más allá del contenido, es que <strong>escribe absolutamente TODOS los días</strong> (al menos que yo sepa). Lo que me flipó cuando le conocí, es que a veces publica un <em>post</em> con una sola frase o línea. Una. Ya. En ocasiones se extiende más, en ocasiones menos, pero nunca “demasiado”…</p>

<p>Así que ahora mismo mi intención es probar ese formato (no escribir a diario, sino escribir aunque solo sea una frase si me apetece) y alternar artículos de diversa extensión (aunque estoy seguro de que en alguno me extenderé “demasiado”). Veremos qué sale.</p>

<h2 id="y-sobre-qué-tontás-vas-a-escribir-muchacho">¿Y sobre qué tontás vas a escribir, muchacho?</h2>
<p>En la sección <a href="/about/">“Sobre mí”</a> he intentado escribir un poco más… sobre mí (sorpresa) y también sobre aquello que me interesa y de lo que probablemente escriba en algún momento. Nada cerrado, así que imagino que eso repelerá a algunas personas y atraerá a otras. Me gusta ver los sistemas en su conjunto y eso me incluye a mí mismo.</p>

<p>También decir que durante las primeras semanas probablemente iré cambiando bastante la estructura del blog o su <em>look &amp; feel</em>; probaré diferentes <em>layouts</em>, secciones, configuraciones, etc. De aquí a un mes espero que esté ya estabilizado.</p>

<p>Y aunque empezaré en español, no descarto alternar con el inglés en algún momento.</p>

<h2 id="algo-más">¿Algo más?</h2>
<p>Que se aceptan opiniones y consejos. No para seguirlos necesariamente, pero nunca se sabe de dónde puede venir una idea interesante de mejora 😊</p>

<p>Y ahora sí, nada más por ahora: <a href="https://www.youtube.com/watch?v=Qyacurxs2qw">buenos días, buenas tardes y buenas noches</a> 😉</p>]]></content><author><name>Isidro López</name></author><category term="blog" /><category term="spanish" /><summary type="html"><![CDATA[Reintento número 459347 de escribir un blog de manera sostenida en el tiempo: ¡¡aaaaaacción!!]]></summary></entry></feed>