<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[SEVEN SENDERS Techblog - Medium]]></title>
        <description><![CDATA[Learn more about how we design, build and run products at SEVEN SENDERS - Medium]]></description>
        <link>https://medium.com/sevensenders-techblog?source=rss----d6a1324e5ab1---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>SEVEN SENDERS Techblog - Medium</title>
            <link>https://medium.com/sevensenders-techblog?source=rss----d6a1324e5ab1---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Tue, 19 May 2026 04:00:22 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/sevensenders-techblog" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[How to implement Trunk Based Development]]></title>
            <link>https://medium.com/sevensenders-techblog/how-to-implement-trunk-based-development-8cb81bd62bb1?source=rss----d6a1324e5ab1---4</link>
            <guid isPermaLink="false">https://medium.com/p/8cb81bd62bb1</guid>
            <category><![CDATA[tbd]]></category>
            <category><![CDATA[teamwork]]></category>
            <category><![CDATA[git]]></category>
            <category><![CDATA[development]]></category>
            <category><![CDATA[software]]></category>
            <dc:creator><![CDATA[Jesus Flores]]></dc:creator>
            <pubDate>Tue, 03 Aug 2021 07:59:08 GMT</pubDate>
            <atom:updated>2021-08-03T07:59:08.505Z</atom:updated>
            <content:encoded><![CDATA[<p>Moving your team to a full CI/CD workflow</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/726/0*5osuN_4TASYHXQ55.png" /><figcaption>Image from <a href="https://trunkbaseddevelopment.com">https://trunkbaseddevelopment.com</a></figcaption></figure><p><em>Trunk Based Development</em> is a way of working with a collection of techniques and processes aimed at organizations that want to speed up their software delivery cadence. This goes a bit beyond simple branching strategy, as we lean on some tools to help us reach its full potential.</p><p>If your team wants to reduce merge friction, have the full picture about each other work, and release faster, then keep reading!</p><h3>Why consider Trunk Based Development?</h3><p>This experience is based entirely on our own, a 3-person development team. We are an experienced team and that makes <em>Trunk Based Development</em> a bit easier to implement.</p><p><strong>We currently carry our work using feature branches, that are long-lived in our case</strong>. <strong>This makes it a problem when we want to have a release from our master branch because the probability of having conflicts increases. </strong>In our case, having many feature branches combined all together and then splitting this work apart in order to generate a release branch was creating some friction that we wanted to fix.</p><p>We want to be able to deliver our work to the production environment in a more streamlined way, and that is why we decided to give <em>Trunk Based Development</em> a go.</p><p>We will focus this article following the needs of our team like we said earlier. We have some good CI/CD practices in place already, but <em>Trunk Based Development</em> will enable us to achieve a truly continuous deployment layout, making the release process more streamlined.</p><p>It is a new workflow for us, different from the traditional feature-branch system, and it requires careful planning to implement correctly. The good news is that this planning is really easy and adapts perfectly well to any kind of team, no matter how big.</p><h3><strong>Trunk Based Development vs. GitFlow</strong></h3><p>There are other branching strategies out there with their own pros and cons. One has to consider what is best for the team and what is possible to achieve with the current resources. In our case, as we mentioned already, we are a small team with an easy flow of communication.</p><p>I personally recommend <a href="https://www.toptal.com/software/trunk-based-development-git-flow">this article</a> to a full in-depth overview of both pros and cons.</p><h3>Prerequisites</h3><p>Being successful at implementing <em>Trunk Based Development</em> on a team is a task that requires attention to detail and a methodical approach in order to achieve its maximum potential. Let’s get an overview of some prerequisites that are necessary to be successful when implementing a <em>TBD </em>workflow.</p><h4>Small batches</h4><p>Developers usually push their code to the main repository once the task is finished, or maybe once a day. They do this by using short-lived local branches from the trunk. When implementing <em>TBD</em> the development team is encouraged to push small batches of their own work as often as possible, to avoid any kind of merge problem.</p><h4>MVP mindset</h4><p>The most important part about the success of <em>Trunk Based Development</em> is the team’s mindset. There has to be a change in mindset towards an <em>MVP</em> (minimum viable product) workflow, to fail earlier and safely. Features should be built in iterations, bugs should be fixed ASAP.</p><h4>Feature flags</h4><p>Feature flags are one of the key technical tools that usually go hand-in-hand with <em>Trunk Based Development</em>. This helper system allows for the <strong>integration of flaky or otherwise potentially risky code</strong> under a condition that can be easily toggled.</p><p>An easy and flexible package for feature flagging is: <a href="https://github.com/bestit/flagception-bundle">https://github.com/bestit/flagception-bundle</a></p><p>This PHP package already contains all the necessary workflow operations for flag toggling and setting.</p><h3>Technical approach and advice</h3><h4>General conventions</h4><ul><li>Despite <em>Trunk Based Development</em> encourages to work directly in a <em>trunk</em> (production branch) and push changes there, we need to facilitate the process of <strong>code review</strong> via pull requests, so we advise you to keep working with <em>feature branches</em>.</li><li>Always create a <em>feature branch</em> from <em>trunk</em> — the branch that we are deploying on <strong>production</strong> environment. In legacy repositories usually named as <em>master</em>, or in new ones <em>main</em>, you could create yours — <em>trunk</em>.</li><li>Before pushing of <em>feature branch</em> to origin, always <strong>rebase</strong> on top of the <em>trunk</em>.</li><li>Merging of <em>feature branch</em> PR to the <em>trunk</em> should be done using <strong>squash</strong> strategy to keep the history linear and straightforward.</li></ul><h4>Workflow conventions</h4><ul><li>Divide local work into <em>small batches</em></li><li>Push <em>feature branches</em> to origin asap and create a pull request, so it could be reviewed and merged into <em>trunk</em> earlier minimizing potential conflicts, as the changes are small.</li><li>Flaky/untested code should be wrapped in a feature flag</li><li>Ramp up the test suite</li><li>Release from <em>trunk</em> using <em>tags</em></li></ul><h3>Implementation</h3><p>Shifting work from GitFlow and variants to <em>Trunk Based Development</em> can seem like a daunting task, but it is mostly a mindset change. Your team will soon benefit from an improved release cycle, doing much less manual work, and having powerful tests to back the releases.</p><h4>Proposed general steps for the implementation:</h4><ul><li>We need to create a <em>trunk</em> branch from <em>master</em> and make it protected. We will keep development branch in parallel to be able to switch to the legacy process easily. Developers are encouraged to use <em>trunk</em> and create any <em>feature branches</em>, push small batches, and code review as early as possible.</li><li>Focus on having unit tests covering new functionality. Manual QA should be a process that should go much faster now.</li><li>Implement a feature flag solution. This can be either a Symfony bundle or just some configuration files and if() conditions. Wrap flaky or untested code that is already present in the <em>trunk, so</em> it can be released without any major modification. See <a href="https://github.com/bestit/flagception-bundle">https://github.com/bestit/flagception-bundle</a></li><li>Verify that the flag solution configuration is good for your setup and your team.</li><li>When planning release, create <em>tags</em> from <em>trunk</em> for QA approval.</li></ul><h4>Step by step guide for developers:</h4><ul><li>Always keep local <em>trunk</em> up to date.</li><li>Suppose we have a task called feature-101, create a local branch task/feature-101 for it.</li><li>Implement work.</li><li>Send the branch for review in a PR as soon as a small piece of functionality is ready. Cover missing work with a feature flag. This flag is open for test and closed for production environments.</li><li>Merge into the <em>trunk</em>. Allow the code on test to be tested with the flag open.</li><li>Remember to update your local <em>trunk</em> often as code is sent there frequently.</li></ul><h4>Step-by-step orientation guide for QA</h4><ul><li>Test work should be done with the flag open. Access the configuration in the profiler to verify.</li><li>In case it is closed for the test environment check with the developer how to proceed.</li></ul><h3>Trade-offs</h3><p>As with any methodology, <em>Trunk Based Development</em> is not a perfect solution, there are a few trade-offs to consider.</p><ul><li>Keeping all developers in sync is important, and failing to do so can lead to unexpected merge conflicts.</li><li>There is a heavy reliance on unit tests and QA approval.</li><li>This system relies on the effectiveness of the automated CI/CD tools, so keeping them up to date is very important.</li></ul><h3>Useful links</h3><ul><li>Trunk based development methodology — <a href="https://trunkbaseddevelopment.com">https://trunkbaseddevelopment.com</a></li><li>TBD vs GitFlow — <a href="https://www.toptal.com/software/trunk-based-development-git-flow">https://www.toptal.com/software/trunk-based-development-git-flow</a></li><li>Feature flag library for PHP — <a href="https://github.com/bestit/flagception-bundle">https://github.com/bestit/flagception-bundle</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8cb81bd62bb1" width="1" height="1" alt=""><hr><p><a href="https://medium.com/sevensenders-techblog/how-to-implement-trunk-based-development-8cb81bd62bb1">How to implement Trunk Based Development</a> was originally published in <a href="https://medium.com/sevensenders-techblog">SEVEN SENDERS Techblog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Hackday #2 at SEVEN SENDERS]]></title>
            <link>https://medium.com/sevensenders-techblog/hackday-2-at-seven-senders-5898e4b0a761?source=rss----d6a1324e5ab1---4</link>
            <guid isPermaLink="false">https://medium.com/p/5898e4b0a761</guid>
            <category><![CDATA[hackday]]></category>
            <category><![CDATA[startups-in-berlin]]></category>
            <category><![CDATA[hackathons]]></category>
            <category><![CDATA[seven-senders]]></category>
            <category><![CDATA[logistics]]></category>
            <dc:creator><![CDATA[Boris Diebold]]></dc:creator>
            <pubDate>Wed, 04 Dec 2019 19:31:38 GMT</pubDate>
            <atom:updated>2019-12-04T19:31:40.823Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*l6ulAFeGCVaO5cetQpaiBw.png" /></figure><p>After the great success of our <a href="https://medium.com/sevensenders-techblog/1st-hackday-at-seven-senders-aa6f4ee10327">first hackday</a> at <a href="https://www.sevensenders.com">SEVEN SENDERS</a>, we decided to conduct a second hackday in 2019.</p><p>This time, 40 hackers mainly from product &amp; engineering collaborated for one day away from work.</p><p>The goal was again to explore interesting ideas that might be beneficial for us in form of a software prototype and demo them at the end of the day.</p><p><a href="https://www.youtube.com/watch?v=6WTq6dyfRaE">See our video here to get some great impressions from the day.</a></p><p>Again, our hacks ranged from feature prototypes to application of current technologies to internal tools for our teams.</p><p>It was great to see the quality and impact of the hacks improving quite a lot since half a year ago.</p><p>Our winning hack was put into production shortly afterwards and is now used by several team members to help them in tedious data analytics tasks.</p><p>Due to the great success, we have now planned to continue and further evolve our hackday setup in 2020.</p><h3>Want to be part of the our next hackday ?</h3><p><a href="https://www.sevensenders.com/career">Join us — we are always looking for great talent !</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5898e4b0a761" width="1" height="1" alt=""><hr><p><a href="https://medium.com/sevensenders-techblog/hackday-2-at-seven-senders-5898e4b0a761">Hackday #2 at SEVEN SENDERS</a> was originally published in <a href="https://medium.com/sevensenders-techblog">SEVEN SENDERS Techblog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to improve your tech-talk (or any other presentation)]]></title>
            <link>https://medium.com/sevensenders-techblog/how-to-improve-your-tech-talk-or-any-other-presentation-c2adbd3dc8b?source=rss----d6a1324e5ab1---4</link>
            <guid isPermaLink="false">https://medium.com/p/c2adbd3dc8b</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[presentations]]></category>
            <category><![CDATA[soft-skills]]></category>
            <category><![CDATA[communication]]></category>
            <category><![CDATA[talks]]></category>
            <dc:creator><![CDATA[Jose Maria Valera Reales]]></dc:creator>
            <pubDate>Mon, 18 Nov 2019 09:24:58 GMT</pubDate>
            <atom:updated>2020-06-10T04:29:23.407Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-e5ApjcxpdPFoNLVW7mnCg.png" /></figure><p>We cannot negate that we’ve found ourselves attending one meeting that felt like we were wasting our time with a “monologue” that is either hard to follow or doesn’t seem so interesting as it could.</p><p>Therefore, I was thinking about it and I tried to get some keys to improving their general quality. It applies to all presentations but also tech-talks and other tech presentations in which engineers are usually involved.</p><h3>Structure of the talk</h3><p>To explain how I think a good presentation should look like I will address three main topics that are relevant to structure and design your presentation.</p><ol><li>Content of the presentation: what <strong>message</strong> do you want to convey to whom and how?</li><li>Design and Layout: how you can design an easy-to-follow presentation that supports your talk instead of taking away the attention from what you are actually trying to say.</li><li>Lastly, I think also the <strong>audience</strong> is responsible for making a tech talk successful, so I will also add a reminder about the role and responsibilities of the listeners.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/937/1*WgVr_dQQE9Q8U4Hr-BLbog.png" /></figure><h4>Consider your audience</h4><p>When you prepare your presentation, ask yourself:</p><ul><li><strong>Who</strong> is attending the talk?</li><li>Which <strong>backgrounds</strong> do they have?</li><li>Which <strong>position</strong> do they have?</li><li>Which information is <strong>relevant</strong> to them?</li><li>Do they have to know all the <strong>keywords</strong> that you would like to use?</li></ul><h4>Introduce the topic</h4><p>Create some atmosphere. Try to answer these questions:</p><ul><li>Why should they <strong>listen</strong> to you?</li><li>Why should they <strong>spend their time</strong> in another meeting?</li><li>What will they <strong>have learned</strong> by the end of the talk?</li><li>What is your <strong>main message</strong>?</li></ul><p>Every meeting should have an output and an outcome. Keep it in mind.</p><h4>Create a Storyline</h4><ul><li>When preparing the main content of your talk, think about a <strong>storyline that connects your arguments. </strong>This makes it easier for the audience to follow.</li><li>Stick to the <strong>messages that are necessary</strong> to explain your idea or concept.</li><li>Leave out any unnecessary information that is not relevant to the core of your message.</li></ul><h4>Build a conclusion</h4><p>Summarize the <strong>main conclusion(s)</strong> in a concise way:</p><ul><li>What is the <strong>conclusion</strong> of this meeting?</li><li>What are the <strong>learnings</strong> from this meeting?</li><li>What are the <strong>open questions</strong> or <strong>next steps</strong>?</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4Ja65X6QefpuAiGdLdbAwQ.png" /></figure><h3>Design and Layout</h3><h4>Write less, talk more</h4><ul><li>A tech-talk is about learning new ideas and concepts.</li><li>A presentation should support your talk, not replace or replicate what you have said.</li><li>The more words on the slide, the fewer they will be remembered.</li><li>Use visuals/graphics that support your talk instead of additional text.</li></ul><h4>L<strong>arge fonts</strong></h4><p>If you have some code to present, consider:</p><ul><li>If it is a picture: use <strong>large fonts</strong> inside. <br>I recommend using <a href="https://carbon.now.sh/">https://carbon.now.sh/</a> for simple snippets. <br>Or just screenshots from your favorite IDE.</li><li>If you will code in live: prepare your editor in advance. <br>Use the <strong><em>Presentation Mode</em></strong> of your IDE.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sKNtvMxf64IvnRm2ADNdLA.png" /></figure><h3>Role of the Audience</h3><h4>Responsibilities of the attendee</h4><ul><li><strong>No unnecessary phone</strong> usage, like Twitter, Instagram, Facebook, WhatsApp, Telegram, etc.</li><li>Keep your questions for the questions time, unless the presenter mentions at the very beginning that you can ask at any moment. Usually, it’s better not to interrupt the topic, so we can ask the <strong>questions at the end</strong>.</li><li><strong>Show interest</strong> in the topic. The presenter should have spent some time preparing the slides for you.</li><li>Pair with the presenter the interest of the topic. This is also the responsibility of the presenter. You both should be eager to learn more about the topic.</li></ul><h4>Inner questions</h4><ul><li>Was it <strong>worth the time</strong> that we all spent in this room?</li><li>Do we <strong>regret the attendance</strong> of this meeting?</li></ul><p>At the end of the meeting, we should ask these questions in order to improve. Ask other people for their feedback, so we can grow further and together.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zRezg3WzwafvCUdLr8F0sg.jpeg" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c2adbd3dc8b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/sevensenders-techblog/how-to-improve-your-tech-talk-or-any-other-presentation-c2adbd3dc8b">How to improve your tech-talk (or any other presentation)</a> was originally published in <a href="https://medium.com/sevensenders-techblog">SEVEN SENDERS Techblog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Improving Code Quality with SonarCloud]]></title>
            <link>https://medium.com/sevensenders-techblog/improving-code-quality-with-sonarcloud-cc3e2faeb89?source=rss----d6a1324e5ab1---4</link>
            <guid isPermaLink="false">https://medium.com/p/cc3e2faeb89</guid>
            <category><![CDATA[git]]></category>
            <category><![CDATA[code-quality-tools]]></category>
            <category><![CDATA[sonarcloud]]></category>
            <category><![CDATA[code-quality]]></category>
            <category><![CDATA[bitbucket-pipelines]]></category>
            <dc:creator><![CDATA[Nicola Feltrin]]></dc:creator>
            <pubDate>Mon, 04 Nov 2019 09:01:34 GMT</pubDate>
            <atom:updated>2019-11-04T09:01:34.120Z</atom:updated>
            <content:encoded><![CDATA[<p>While we all strive to improve the quality of our code, assessing the results of that effort remains a challenge. SonarCloud provides a standardized way to measure code quality and the progress of your team.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4EpTl0hs6F0k13A8YlBhmA.png" /></figure><h3>The Tool: SonarCloud</h3><p><a href="https://sonarcloud.io">SonarCloud</a> is the hosted version of the Sonar tools suite, including <a href="https://www.sonarqube.org/">SonarQube</a> (self-hosted) and SonarScanner (different scanner agents e.g. <a href="https://docs.sonarqube.org/latest/analysis/scan/sonarscanner/">generic</a>, <a href="https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-maven/">maven</a>, <a href="https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-gradle/">gradle</a>…). SonarCloud allows you to analyze your code through an appropriate SonarScan agent and easily record the results in a centralized location. Your team can then access a quick and simple interface to evaluate their code and take informed decisions on how to proceed. Isn’t that exciting?</p><p>SonarCloud revolves around <em>projects</em>: these are essentially units of code that are built from a single code base. The code of each project gets parsed through an appropriate agent to identify issues; the results are then sent to SonarCloud to be grouped by branch. The general expectation is that <em>short-lived branches</em> will be merged into a specific <em>long-lived branch</em>; this allows the interface to assess a branch impact on the existing code and helps you decide whether a feature branch is mature enough to be merged.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CJFmOCrWwBgWehpQKNao4Q.png" /></figure><p>The distinction between <em>long-</em> and <em>short-lived branches</em> is also helpful in reducing noise: code quality graphs take only the former into consideration, visualizing improvements only where it matters. These can be customized to select specific measures and with the version naming of your choice.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Q-8yrvv497g8vplC5m1A8w.png" /></figure><p>Surely you have spent many hours writing appropriate tests for your code. SonarCloud can parse the test reports providing a good estimate on your code coverage. Depending on the different agents, the tests are either run automatically or you will have to provide the test output in an appropriate format.</p><h3>The Idea: Code Quality</h3><p>All of this is well and nice, but there is an unavoidable question: what is code quality? It is surely a matter of perspective and different use cases, how is it possible to have a one-size-fits-all solution?</p><p>SonarCloud provides two levels of abstraction to make it easier for you to customize its rules to your needs. <em>Quality profiles</em> are closest to the code: they group sets of rules to trigger certain warnings or evaluations; <em>quality gates</em>, instead, are more abstract: they group rules evaluating the number and severity of warnings, to return a uniform evaluation of code quality. In other words: <strong>quality profiles define what a violation is, quality gates define how many violations are considered acceptable</strong>. While quality profiles are necessarily language-specific, quality gates depend only on the results of quality profiles, and can be used as a common frame of reference to evaluate projects in different languages.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aUj_8xzqwIVkbn8cI8GvEQ.png" /><figcaption>Some rules from a PHP <em>quality profile</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*U6RerU9BtCV8c8YIjV8ANg.png" /><figcaption>Some rules from the a quality gate</figcaption></figure><p>Still, does it really work? Can a set of rules replace careful review and mindful analysis? That is obviously not the point: the tool works very well out of the box to highlight <em>possible</em> issues. The maintainers of the project then need to go through the flagged items and assess the actual severity of the issue. After that, SonarCloud allows the user to modify the initial evaluation (change the severity, mark it as not an issue, or an issue of a different kind, open a ticket…); such a change will be saved and tracked, so the issue will not resurface when the same code gets propagated across branches.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3MggTQ6n_B2GtrsmMv4Tag.png" /></figure><p>Overall, code quality is graded according to five core parameters:</p><ol><li><strong>Bugs</strong>: issues that can make your code unreliable</li><li><strong>Vulnerabilities</strong>: issues that can put your code at risk of attack</li><li><strong>Code smells</strong>: issues that make your code harder to read</li><li><strong>Coverage</strong>: how much of your code is covered by tests</li><li><strong>Duplications</strong>: how many times a bit of code is repeated across the code base</li></ol><p>Depending on your needs, you might want to weight some of them more than others.</p><h3>The Implementation: Pipeline integration</h3><p>To have proper results, the code scan needs to be run quite often. While integrating it into the pipeline seems like a great idea, it may come at the expenses of pipeline runtime. We found that running a scan for every commit in every branch was a little too much for us, so we opted for a model where the scans are run in two cases:</p><ol><li>for <strong>each branch that has an open pull request</strong>, because the result of the scan will be necessary to evaluate the final impact on the code base; and</li><li>for <strong>each commit in the master branch</strong>, because their count should be limited to branch merges and the results are important for historical evaluation</li></ol><p>Integrating the SonarScan generic agent into our Bitbucket pipelines was quite easy, as we simply needed to provide an additional step to be run from an custom docker image containing only the agent itself. This way we managed to support most of our projects without having to modify our CI images. Even where the generic agent was not supported (gradle) and we had to made a couple more changes to our build process, the installation was not particularly challenging. In this case the installation and configuration of the scanner was managed through the step definitions of the build tool itself.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MIg7PhrM_6m1lofJrPJxsw.png" /><figcaption>A Bitbucket pipeline running the generic agent</figcaption></figure><p>The biggest challenge we faced was integration with monorepos. The entire environment seems to be built around the paradigm “one repository, one project”; if your team is using one, some integrations will not be available (e.g. the Bitbucket widget) and some additional scripting will be necessary if you do not want to scan each project every time a scan is triggered.</p><h3>The evaluation</h3><p>Despite some minor downsides, our overall impression is that SonarCloud does provide useful insights on how well your team is progressing towards a more secure, more maintainable code base and, as such, is a very valuable addition to a developer’s toolbox.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cc3e2faeb89" width="1" height="1" alt=""><hr><p><a href="https://medium.com/sevensenders-techblog/improving-code-quality-with-sonarcloud-cc3e2faeb89">Improving Code Quality with SonarCloud</a> was originally published in <a href="https://medium.com/sevensenders-techblog">SEVEN SENDERS Techblog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Modern PHP: know the best PHP features up to PHP 7.4]]></title>
            <link>https://medium.com/sevensenders-techblog/modern-php-know-the-best-php-features-til-php-7-4-e3b2bf5916b2?source=rss----d6a1324e5ab1---4</link>
            <guid isPermaLink="false">https://medium.com/p/e3b2bf5916b2</guid>
            <category><![CDATA[software]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[php]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Jose Maria Valera Reales]]></dc:creator>
            <pubDate>Mon, 23 Sep 2019 07:44:05 GMT</pubDate>
            <atom:updated>2020-06-10T03:27:02.374Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UxWtaG6grsBNDRXrulh7NQ.png" /></figure><h3>Content</h3><h4>PHP 7.4</h4><ul><li>Typed properties</li><li>Arrow functions</li><li>Limited return type covariance and argument type contravariance</li><li>The null coalescing assignment operator (??=)</li><li>Unpacking inside arrays</li><li>Numeric literal separator</li><li>Weak references</li><li>Allow exceptions from __toString()</li><li>Multibyte String</li><li>OPcache</li><li>strip_tags() with array of tag names</li><li>Custom object serialization</li></ul><h4>PHP 7.3</h4><ul><li>FastCGI Process Manager</li><li>Multibyte String Functions</li></ul><h4>PHP 7.2</h4><ul><li>New object type</li><li>Abstract method overriding</li><li>Parameter type widening</li><li>Allow a trailing comma for grouped namespaces</li></ul><h4>PHP 7.1</h4><ul><li>Nullable types</li><li>Void functions</li><li>Symmetric array destructuring</li><li>Class constant visibility</li><li>iterable pseudo-type</li><li>Multi catch exception handling</li><li>Support for keys in list()</li><li>Support for negative string offsets</li></ul><h4>PHP 7.0</h4><ul><li>Added strict_type directive</li><li>Scalar type declarations</li><li>Return type declarations</li><li>Null coalescing operator (??)</li><li>Spaceship operator (&lt;=&gt;)</li><li>Constant arrays using define()</li><li>Anonymous classes</li><li>Unicode codepoint escape syntax</li><li>Closure::call()</li><li>Group use declarations</li><li>Generator Return Expressions</li><li>Generator delegation</li></ul><h3>PHP 7.4 most interesting features</h3><p>From 28 November 2019! <a href="https://wiki.php.net/todo/php74">PHP 7.4 Preparation Tasks</a>.</p><h4><a href="https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.typed-properties">Typed properties</a></h4><p>Class properties now support type declarations.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1f0c486ab3890e1f4113ab7b31f83af6/href">https://medium.com/media/1f0c486ab3890e1f4113ab7b31f83af6/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.arrow-functions">Arrow functions</a></h4><p>Arrow functions provide a shorthand syntax for defining functions with implicit by-value scope binding.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/98a63b922b825a40b9c36c15a128edef/href">https://medium.com/media/98a63b922b825a40b9c36c15a128edef/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.type-variance">Limited return type covariance and argument type contravariance</a></h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/296b5f60c8b25e20890a9e3cdfe7a947/href">https://medium.com/media/296b5f60c8b25e20890a9e3cdfe7a947/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.null-coalescing-assignment-operator">The null coalescing assignment operator</a> (??=)</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e2a01cebff3eb072edb46cb5006d8e1d/href">https://medium.com/media/e2a01cebff3eb072edb46cb5006d8e1d/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.unpack-inside-array">Unpacking inside arrays</a></h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/eb763c94d6870a72fb0e58c80a1bbffc/href">https://medium.com/media/eb763c94d6870a72fb0e58c80a1bbffc/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.numeric-literal-separator">Numeric literal separator</a></h4><p>Numeric literals can contain underscores between digits.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0c9f5dbde435e5334814c64916fe136a/href">https://medium.com/media/0c9f5dbde435e5334814c64916fe136a/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.weakreference">Weak references</a></h4><p>Weak references allow the programmer to retain a reference to an object that does not prevent the object from being destroyed.</p><h4><a href="https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.tostring-exceptions">Allow exceptions from __toString()</a></h4><p>Throwing exceptions from `<em>__toString()`</em> is now permitted. Previously this resulted in a fatal error.</p><h4><a href="https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.mbstring">Multibyte String</a></h4><p>Added the `<em>mb_str_split()`</em> function, which provides the same functionality as `<em>str_split()`</em>, but operating on code points rather than bytes.</p><h4><a href="https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.opcache">OPcache</a></h4><p>Support for preloading code has been added.</p><h4><a href="https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.standard.strip-tags">strip_tags() with array of tag names</a></h4><p><em>`strip_tags()`</em> now also accepts an array of allowed tags:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9c10c390a9f1663a83cab4422aad3330/href">https://medium.com/media/9c10c390a9f1663a83cab4422aad3330/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.standard.magic-serialize">Custom object serialization</a></h4><p>A new mechanism for custom object serialization has been added, which uses two new magic methods: <em>__serialize</em> and <em>__unserialize</em>.</p><p>The new serialization mechanism supersedes the <em>Serializable</em> interface, which will be deprecated in the future.</p><h4><a href="https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.standard.array-merge-no-args">Array merge functions without arguments</a></h4><p><em>array_merge()</em> and <em>array_merge_recursive()</em> may now be called without any arguments, in which case they will return an empty array. This is useful in conjunction with the spread operator, e.g. <em>array_merge(…$arrays)</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6Dbixr8MndHpCkgREJXLmQ.png" /></figure><h3>PHP 7.3 most interesting features</h3><h4><a href="https://www.php.net/manual/en/migration73.new-features.php#migration73.new-features.core">PHP Core</a></h4><ul><li>Array Destructuring supports Reference Assignments:</li></ul><blockquote><em>[&amp;$a, [$b, &amp;$c]] = $d;</em></blockquote><ul><li><em>`instanceof`</em> Operator accepts Literals.</li><li>CompileError Exception instead of some Compilation Errors.</li><li>Trailing Commas are allowed in Calls.</li></ul><h4><a href="https://www.php.net/manual/en/migration73.new-features.php#migration73.new-features.fpm">FastCGI Process Manager</a></h4><p>New options have been added to customize the FPM logging: <em>log_limit</em>, <em>log_buffering, </em>and <em>decorate_workers_output</em>.</p><h4><a href="https://www.php.net/manual/en/migration73.new-features.php#migration73.new-features.mbstring">Multibyte String Functions</a></h4><ul><li>Full Case-Mapping and Case-Folding Support.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f3e0b163650bcd2094b0e4575848e08d/href">https://medium.com/media/f3e0b163650bcd2094b0e4575848e08d/href</a></iframe><ul><li>Unicode 11 Support.</li><li>Long String Support: now correctly support strings larger than 2GB.</li><li>Performance Improvements.</li><li>Named Captures Support: the <em>mb_ereg_*</em> functions now support named captures.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fac41923c7e11852ed17177953aaf665/href">https://medium.com/media/fac41923c7e11852ed17177953aaf665/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zUw6491846kiX6L4OLE5nQ.png" /></figure><h3>PHP 7.2 new features</h3><h4><a href="https://www.php.net/manual/en/migration72.new-features.php#migration72.new-features.object-type">New object type</a></h4><p>A new type, object, has been introduced that can be used for (contravariant) parameter typing and (covariant) return typing of any objects.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ad7a3e906f55acecf9fcdf44bf4acb92/href">https://medium.com/media/ad7a3e906f55acecf9fcdf44bf4acb92/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration72.new-features.php#migration72.new-features.abstract-method-overriding">Abstract method overriding</a></h4><p>Abstract methods can now be overridden when an abstract class extends another abstract class.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5df1db0bb3174111718c88dfb4e02530/href">https://medium.com/media/5df1db0bb3174111718c88dfb4e02530/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration72.new-features.php#migration72.new-features.param-type-widening">Parameter type widening</a></h4><p>Parameter types from overridden methods and from interface implementations may now be omitted.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/384eec96764c51c12c28ac4e26013765/href">https://medium.com/media/384eec96764c51c12c28ac4e26013765/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration72.new-features.php#migration72.new-features.trailing-comma-in-grouped-namespaces">Allow a trailing comma for grouped namespaces</a></h4><p>A trailing comma can now be added to the group-use syntax introduced in PHP 7.0.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/627ab0ed31e77217369548303c598c08/href">https://medium.com/media/627ab0ed31e77217369548303c598c08/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/826/1*j_0KTOQiDKTdIvsQOB6uOg.png" /></figure><h3>PHP 7.1 new features</h3><h4><a href="https://www.php.net/manual/en/migration71.new-features.php#migration71.new-features.nullable-types">Nullable types</a></h4><p>Type declarations for parameters and return values can now be marked as nullable by prefixing the type name with a question mark.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3a3e7d02d284218fe718c3e048206152/href">https://medium.com/media/3a3e7d02d284218fe718c3e048206152/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration71.new-features.php#migration71.new-features.void-functions">Void functions</a></h4><p>A <em>void</em> return type has been introduced. Functions declared with void as their return type must either omit their return statement altogether or use an empty return statement. <em>NULL</em> is not a valid return value for a <em>void</em> function.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/13ae955bbd64c8c62543dfbbe667e5cc/href">https://medium.com/media/13ae955bbd64c8c62543dfbbe667e5cc/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration71.new-features.php#migration71.new-features.symmetric-array-destructuring">Symmetric array destructuring</a></h4><p>The shorthand array syntax (<em>[]</em>) may now be used to destructure arrays for assignments (including within `<em>foreach`</em>) as an alternative to the existing <em>list() </em>syntax, which is still supported.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/43452151187f27b198b49e348944d737/href">https://medium.com/media/43452151187f27b198b49e348944d737/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration71.new-features.php#migration71.new-features.class-constant-visibility">Class constant visibility</a></h4><p>Support for specifying the visibility of class constants has been added.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b60fd29443795759f1a8d61f84c825bf/href">https://medium.com/media/b60fd29443795759f1a8d61f84c825bf/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration71.new-features.php#migration71.new-features.iterable-pseudo-type">iterable pseudo-type</a></h4><p>A new pseudo-type (similar to callable) called iterable has been introduced. It may be used in parameter and return types, where it accepts either arrays or objects that implement the Traversable interface.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3ec4dbcdb26f8d47ca65232e530c70de/href">https://medium.com/media/3ec4dbcdb26f8d47ca65232e530c70de/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration71.new-features.php#migration71.new-features.mulit-catch-exception-handling">Multi catch exception handling</a></h4><p>Multiple exceptions per catch block may now be specified using the pipe character (<em>|</em>).</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1a08275f99a13a8fc20200e9f9d7304c/href">https://medium.com/media/1a08275f99a13a8fc20200e9f9d7304c/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration71.new-features.php#migration71.new-features.support-for-keys-in-list">Support for keys in list()</a></h4><p>You can now specify keys in <em>list()</em>, or its new shorthand <em>[]</em> syntax. This enables destructuring of arrays with non-integer or non-sequential keys.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/48e681b16dac44ba20edc31b609b9a21/href">https://medium.com/media/48e681b16dac44ba20edc31b609b9a21/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration71.new-features.php#migration71.new-features.support-for-negative-string-offsets">Support for negative string offsets</a></h4><p>Support for negative string offsets has been added to the string manipulation functions accepting offsets, as well as to string indexing with <em>[]</em> or <em>{}</em>. In such cases, a negative offset is interpreted as being an offset from the end of the string.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bd01ec0eebf854ddf3f6513cc5e633f9/href">https://medium.com/media/bd01ec0eebf854ddf3f6513cc5e633f9/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*orZ-oSnEA8bLZzxKrF0NZg.png" /></figure><h3>PHP 7.0 new features</h3><h4><a href="https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration.strict">Added <em>strict_type</em> directive</a></h4><p>By default, PHP will coerce the values of the wrong type into the expected scalar type if possible. For example, a function that is given an integer for a parameter that expects a string will get a variable of type string.</p><p>It is possible to enable strict mode on a per-file basis. In strict mode, only a variable of the exact type of the type declaration will be accepted, or a <em>TypeError</em> will be thrown.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fb2db57f205a26784a0519a55cfc782c/href">https://medium.com/media/fb2db57f205a26784a0519a55cfc782c/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.scalar-type-declarations">Scalar type declarations</a></h4><p>From now on we can enforce the parameter types in a function: string, int, float, and bool. From PHP 5 we could already use augment other types as class names, interfaces, array and callable.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c6156690f45ec0442dea1bd753597e7f/href">https://medium.com/media/c6156690f45ec0442dea1bd753597e7f/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.return-type-declarations">Return type declarations</a></h4><p>Similarly to argument type declarations, return type declarations specify the type of value that will be returned from a function. The same types are available for return type declarations as are available for argument type declarations.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a89d22d1cc875ca64fa44568de8cfa5b/href">https://medium.com/media/a89d22d1cc875ca64fa44568de8cfa5b/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.null-coalesce-op">Null coalescing operator</a> (??)</h4><p>The null coalescing operator (<em>??</em>) has been added as syntactic sugar for the common case of needing to use a ternary in conjunction with `<em>isset()</em>`. It returns its first operand if it exists and is not <em>NULL</em>; otherwise, it returns its second operand.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/296364b664a02f3edc95e53551000d50/href">https://medium.com/media/296364b664a02f3edc95e53551000d50/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.spaceship-op">Spaceship operator</a> (&lt;=&gt;)</h4><p>The spaceship operator is used for comparing two expressions. It returns <em>-1, 0</em> or <em>1</em> when <em>$a</em> is respectively less than, equal to, or greater than<em> $b</em>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e012965845ad0abd20b2732725252707/href">https://medium.com/media/e012965845ad0abd20b2732725252707/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.define-array">Constant arrays using define()</a></h4><p>Array constants can now be defined with <em>define()</em>. In PHP 5.6, they could only be defined with const.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/104dc45ff68a6429813e65fac985d370/href">https://medium.com/media/104dc45ff68a6429813e65fac985d370/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.anonymous-classes">Anonymous classes</a></h4><p>Support for anonymous classes has been added via the new class.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f1804597031b8db661021646bda49579/href">https://medium.com/media/f1804597031b8db661021646bda49579/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.unicode-codepoint-escape-syntax">Unicode codepoint escape syntax</a></h4><p>This takes a Unicode codepoint in hexadecimal form and outputs that codepoint in <em>UTF-8</em> to a double-quoted string or a heredoc.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e3cc2dc52f5f9754e3a934df4e22988c/href">https://medium.com/media/e3cc2dc52f5f9754e3a934df4e22988c/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.closure-call-method">Closure::call()</a></h4><p><em>Closure::call()</em> is a more performant, shorthand way of temporarily binding an object scope to a closure and invoking it.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2ac19e469ccf9757a1dc13548c1db866/href">https://medium.com/media/2ac19e469ccf9757a1dc13548c1db866/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.group-use-declarations">Group use declarations</a></h4><p>Classes, functions, and constants being imported from the same namespace can now be grouped together in a single-use statement.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/69e658a7e233cb9d8639650055c4e07f/href">https://medium.com/media/69e658a7e233cb9d8639650055c4e07f/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.generator-return-expressions">Generator Return Expressions</a></h4><p>It enables a return statement to be used within a generator to enable a final expression to be returned.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/944b9e6f88c3feed5cf14f553623730f/href">https://medium.com/media/944b9e6f88c3feed5cf14f553623730f/href</a></iframe><h4><a href="https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.generator-delegation">Generator delegation</a></h4><p>Generators can now delegate to another generator, Traversable object or array automatically, without needing to write boilerplate in the outermost generator by using the yield from construct.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5b44d5e4e50e1d8354f971561cf9fb46/href">https://medium.com/media/5b44d5e4e50e1d8354f971561cf9fb46/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CQ9S8EInmljyAfj-WOFnrQ.png" /></figure><p>PHP development rocks. I really like to see how the language is evolving providing a lot of flexibility in order to create a more robust language like the others in the market.</p><p>Not just these nice features but also its increasing performance and speed. Especially now with the Opcache inbuild coming in this PHP 7.4.</p><blockquote>Really looking forward to seeing the next <strong>PHP 8</strong>.</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e3b2bf5916b2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/sevensenders-techblog/modern-php-know-the-best-php-features-til-php-7-4-e3b2bf5916b2">Modern PHP: know the best PHP features up to PHP 7.4</a> was originally published in <a href="https://medium.com/sevensenders-techblog">SEVEN SENDERS Techblog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My internship as a working student in Paris]]></title>
            <link>https://medium.com/sevensenders-techblog/my-internship-as-a-working-student-in-paris-4a6b4446399e?source=rss----d6a1324e5ab1---4</link>
            <guid isPermaLink="false">https://medium.com/p/4a6b4446399e</guid>
            <category><![CDATA[qa]]></category>
            <category><![CDATA[working-students]]></category>
            <category><![CDATA[internships]]></category>
            <category><![CDATA[paris]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Jan Driescher]]></dc:creator>
            <pubDate>Mon, 09 Sep 2019 12:33:13 GMT</pubDate>
            <atom:updated>2019-09-09T12:30:20.551Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RPWXj6MqZgfBsE5gxnQIzQ.jpeg" /></figure><p>As I have finally returned home after a <strong>6 months internship in France</strong>, I think this is a good time to reflect on my experiences at the new Seven Senders office in Paris.</p><p>Let me share with you this short story about a boy from Berlin exploring the beautiful city of Paris.</p><h4><strong>Who is this guy?</strong></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PR5SglfKeb5isFTbnWwZwA.jpeg" /><figcaption>me looking very happy in front of Sacré-Cœur</figcaption></figure><p>Great question! My name is <a href="https://www.linkedin.com/in/jan-driescher-056649178/">Jan </a>and when I don’t watch movies I study International Computer &amp; Media Science at HTW Berlin (sometimes…).</p><p>I’ve also been working <strong>at Seven Senders since August 2018</strong> so I think it’s fair to say I’m one of the cool kids now. I joined 7S as a working student in Product &amp; Engineering mostly supporting the QA and Product team with various tasks but more than anything, learning from all the experienced and creative minds in the office.</p><h4><strong>Why did this guy leave?</strong></h4><p>As part of my university program all students in my major had to do a <strong>mandatory internship</strong> in a country other than Germany. Thinking about the endless possibilities I naturally consulted with my colleagues and was lucky enough to be offered a position at the new <strong>Seven Senders Paris office</strong> which just opened up in the beginning of 2019 under the supervision of our head of New Markets Thomas Garnesson. So I packed my stuff, got myself a tiny apartment (actually it was not that easy) in Paris and flew there to start my new adventure.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*QvD6mDN8YMoYsxnP" /></figure><p>The office is located in the 8th arrondissement of Paris that’s right in the city center adjacent to the famous Champs Elysées. During my time there I got to meet many new and interesting personalities (as Thomas was hiring to build a new team) and also worked on some very interesting projects in collaboration with the QA and Product teams in Berlin.</p><h4><strong>How is Paris?</strong></h4><p>Let’s keep this short! Paris is <strong>beautiful</strong>. Actually just calling it beautiful is an understatement. Every street, every shop, every corner looks like it’s straight out of a movie. Being born and raised in Berlin I am naturally opposed to any other city in the world but I have to admit that the city of Paris stole my heart a little bit.</p><p>Whether it’s just walking by the Seine, exploring the nightlife of the République area, drinking some good wine in one of the countless bars and brasseries or just strolling through any of the amazing museums and exhibitions — Paris has something for almost everyone. If you can look beyond the harsh prices and the sometimes rough attitude that some Parisians have towards non-French people, Paris is definitely a must visit! Oh yeah, and most importantly: <strong>They have a Disneyland.</strong> Enough said!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9YYfD9M0RyJXP79oBSHDKg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FWySw7TcAgVW5Mj1FdV0LQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ltDdjwG_TN9eeyftC3RATg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Zi5ACZWQWILMsiJXKAb4bg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WSttG05Jw7JHj0KDwPxH5Q.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0XCJxwfz3wcfAK2t4aswWQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e6sBFKhQUCbf1FIEcSGpCw.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PfC0-EWr14dhtVlL9gDdmQ.jpeg" /><figcaption>some impressions from my time in the city of love</figcaption></figure><h4><strong>Did he even learn anything?</strong></h4><p>Naturally, since this is a university internship it had to be somewhat educational. I was lucky enough to be fully integrated in my team at Seven Senders to a point where it felt like I was a full grown member of the team. Together with my awesome colleagues Haik and Surendra in Berlin I worked hard on <strong>automating testing processes</strong> in the team and also spent a significant amount of time on projects in other departments of the company like Customer Support or Product. Working in a full time job, experiencing the day to day business and actually being able to shape the outcome of projects in a meaningful way really helped me on my path as a student and now gives me the <strong>confidence to keep working and prepare myself for the projects to come.</strong></p><h4><strong>What will he do now?</strong></h4><p>After coming back from Paris, I was offered the opportunity to <strong>come back to the Seven Senders Berlin</strong> office and join their <strong>Core Services team</strong> as a backend developer. Being with the company for over a year now, I am really glad to have the opportunity to keep developing and learning here. Paris was a hugely instructive experience for me. Getting to know a different culture and a new environment and having to adjust accordingly is something that everyone should experience first hand.</p><p>Learning to deal with change and sometimes personal hardships might be one of the most important skills one can learn in life. So follow your dreams, don’t let yourself down, dare to adventure and <strong>stay awesome!</strong></p><p><strong>A big thank you </strong>goes out to everyone at Seven Senders for the opportunity and all the support on my journey and to all my friends that came to visit me!</p><p><em>Jan</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KeRDED-tcp13q7DCsdDVtA.jpeg" /><figcaption>the whole Seven Senders team (Berlin + Paris) at our summer party</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4a6b4446399e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/sevensenders-techblog/my-internship-as-a-working-student-in-paris-4a6b4446399e">My internship as a working student in Paris</a> was originally published in <a href="https://medium.com/sevensenders-techblog">SEVEN SENDERS Techblog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1st Hackday at SEVEN SENDERS]]></title>
            <link>https://medium.com/sevensenders-techblog/1st-hackday-at-seven-senders-aa6f4ee10327?source=rss----d6a1324e5ab1---4</link>
            <guid isPermaLink="false">https://medium.com/p/aa6f4ee10327</guid>
            <category><![CDATA[seven-senders]]></category>
            <category><![CDATA[hackathons]]></category>
            <category><![CDATA[logistics]]></category>
            <category><![CDATA[hackday]]></category>
            <dc:creator><![CDATA[Boris Diebold]]></dc:creator>
            <pubDate>Mon, 01 Apr 2019 05:46:01 GMT</pubDate>
            <atom:updated>2019-04-01T05:52:45.524Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EFmS8j4svRA11kcUcnTnDw.jpeg" /></figure><p>In march, we conducted our first hackday at <a href="http://www.sevensenders.com">SEVEN SENDERS</a>.</p><p>30 <em>hackers</em> from engineering, product management, product design, marketing, business intelligence collaborated in small teams for one day away from work.</p><p>The goal was to explore interesting ideas that might be beneficial for us in form of a software prototype and demo them at the end of the day.</p><p>And of course — have fun:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fuscqu_dS7to%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Duscqu_dS7to&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2Fuscqu_dS7to%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/8b03bd225e8df4d7bb7c6d214af16dd9/href">https://medium.com/media/8b03bd225e8df4d7bb7c6d214af16dd9/href</a></iframe><p>The hacks ranged from new feature prototypes, applications of current technologies like machine learning and chat bots to internal tools for our teams.</p><p>While some hacks have been immediately put to daily use, others have sparked new ideas and focus for exploration. Some have even found a place on the product roadmap.</p><p>Due to the great success, we are looking forward to run the next hackday later this year and will establish it as a recurring event.</p><h3>Want to be part of the next hackday ?</h3><p><a href="https://www.sevensenders.com/career">Join us — we are always looking for great talent !</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=aa6f4ee10327" width="1" height="1" alt=""><hr><p><a href="https://medium.com/sevensenders-techblog/1st-hackday-at-seven-senders-aa6f4ee10327">1st Hackday at SEVEN SENDERS</a> was originally published in <a href="https://medium.com/sevensenders-techblog">SEVEN SENDERS Techblog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Speaking Data with Snowflake and Looker]]></title>
            <link>https://medium.com/sevensenders-techblog/speaking-data-with-snowflake-and-looker-e4b219ed37aa?source=rss----d6a1324e5ab1---4</link>
            <guid isPermaLink="false">https://medium.com/p/e4b219ed37aa</guid>
            <category><![CDATA[looker]]></category>
            <category><![CDATA[business-intelligence]]></category>
            <category><![CDATA[snowflake]]></category>
            <category><![CDATA[logistics]]></category>
            <category><![CDATA[data-warehouse]]></category>
            <dc:creator><![CDATA[Martin Ebel]]></dc:creator>
            <pubDate>Thu, 28 Mar 2019 06:46:00 GMT</pubDate>
            <atom:updated>2019-03-28T06:46:00.819Z</atom:updated>
            <content:encoded><![CDATA[<p>There are probably hundreds of start-ups out there that claim to speak data and most likely each and every one of them takes a different view or approach on this topic depending on the area of business or company culture.</p><p>In this story I would like to share <a href="https://www.sevensenders.com/">our</a> approach on <em>“speaking data”</em> as delivery platform and how we use <a href="https://www.snowflake.com/">Snowflake </a>as data warehouse solution together with <a href="https://looker.com/">Looker </a>as a BI platform to achieve that.</p><p><strong><em>What Makes us Speaking Data</em></strong></p><p>Just claiming to speak data and emphasizing the importance of data driven decisions is -if at all- just half the battle. We as the BI team of Seven Senders strive for making the data available for everyone in the company without the need of contacting us. We serve the other departments by providing the infrastructure and knowledge for a decentralized business intelligence architecture and as a data governance instance to make sure that we all have the same understanding of the data provided.</p><p>We do so by using Looker as a BI tool on top of our Snowflake data warehouse. This setup allows us not only to model the data on the fly in an flexible ELT process but also to share the same results internally with other departments and externally with customers and partners.</p><p><strong><em>A Data Warehouse as Enabler for Speaking Data</em></strong></p><p>The core of our business model is to connect merchants with prime last mile carriers worldwide. In terms of data this means many different data sources, different types of data and different aggregations. Now imagine to have all those data of different types in various unconnected data silos rotting over time without adding any value to the whole supply chain. This would definitely not be a good starting point for speaking data and for making data driven decisions.</p><p>That is why we decided to implement a data warehouse. By bringing together all the data in one central place we had the data where we needed it to be in order to generate holistic data insights.</p><p><strong><em>Why Snowflake as Data Warehouse</em></strong></p><p>Our decision on using Snowflake end of 2017 was mainly due to the following three factors:</p><ol><li><em>Performance</em><br>As stated above we use Looker and thus also our data warehouse both internally and externally. For us it was very important to not make an any compromises in terms on performance towards our customers despite using an ELT approach. Snowflake and its adaptive architecture enable very fast query times needed in such a setup.</li><li><em>Flexible Scale<br></em>Different consumers of data have different needs in terms of computing and storage. With Snowflake we are able to adapt the power of our data warehouse depending on the user by using multiple virtual data warehouses with a different scale depending on the user. Aligning the different demands for compute and storage to different supplies of compute and storage also helps to generate saving potential.</li><li><em>Usability</em><br>Snowflake is a ready-to-use data warehouse allowing us as a BI team to instantly scale, create, modify warehouses in a user friendly web interface. There is no need for a DevOps even if you are completely without IT background (like myself). Simply login, select the desired warehouse and adjust the computing power by means of a click.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/638/1*OmcCetx-cOxRmcOObP-dyw.jpeg" /></figure><p>I will share some more detailed insights on our decision for Looker as BI platform on top of Snowflake in an upcoming post.</p><p><strong><em>The Result</em></strong></p><p>By implementing our tool stack with Snowflake and Looker we were instantly able to generate much more value out of our data silos. By bringing the different sources together in one place we expanded our data insights to make data driven decisions. From monthly reporting to daily cost controlling and monthly performance audits. What has not been done before or just irregular in extensive excel work is now possible with a click.</p><p>In addition we were able to decrease the time to market for new data insights for our customers in our <a href="https://software.sevensenders.com/">Sendwise Delivery Software</a>. With our ELT approach enabled by Snowflake we can model and share new data insights in hours to days rather than weeks to months. This of course also helps to widely expand our customer base and with the new setup we do not have to worry about scalability or performance issues.</p><p>Take a look at the following video by Snowflake where I summarized our journey (German only, sorry).</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FjhtNVODn9so%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DjhtNVODn9so&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FjhtNVODn9so%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/b7d36b663d673497850872d4375b62ee/href">https://medium.com/media/b7d36b663d673497850872d4375b62ee/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e4b219ed37aa" width="1" height="1" alt=""><hr><p><a href="https://medium.com/sevensenders-techblog/speaking-data-with-snowflake-and-looker-e4b219ed37aa">Speaking Data with Snowflake and Looker</a> was originally published in <a href="https://medium.com/sevensenders-techblog">SEVEN SENDERS Techblog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Statecharts in product development ?]]></title>
            <link>https://medium.com/sevensenders-techblog/state-machines-in-product-development-8e284e51a9d4?source=rss----d6a1324e5ab1---4</link>
            <guid isPermaLink="false">https://medium.com/p/8e284e51a9d4</guid>
            <category><![CDATA[product-management]]></category>
            <category><![CDATA[statecharts]]></category>
            <category><![CDATA[mvp]]></category>
            <category><![CDATA[state-machine]]></category>
            <category><![CDATA[lean-startup]]></category>
            <dc:creator><![CDATA[Jeremy Fourna]]></dc:creator>
            <pubDate>Tue, 03 Jul 2018 14:55:17 GMT</pubDate>
            <atom:updated>2018-07-04T11:43:38.176Z</atom:updated>
            <content:encoded><![CDATA[<p>At Seven Senders, this year the product management team rediscovered a computer science concept/theory under a new angle… State Machine!</p><p>The development teams at Seven Senders use state machines all the time in their projects. But when the Front End team started using State Machine inside the UI of our new application Sendwise, something clicked…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5dEAowU4JTPet1TiuhTa_A.jpeg" /><figcaption>PM listening to a tech talk about state machine and statecharts</figcaption></figure><p>We started to have the following conversation:</p><blockquote>PM 1: If you think about it, isn’t an application just a succession of states?</blockquote><blockquote>PM 2: Hum… Yes, you can see it like that for basics pages indeed like login, signup, on boarding etc… but for some other pages that we have it is way more complex!</blockquote><blockquote>PM 1: Let’s try to describe our product as a State Machine just to see if it hold!</blockquote><blockquote>PM 2: OK, but I can assure you it is going to be messy…</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iO5mG8o6GxaujjNC27vsWQ.png" /></figure><p>Indeed it is and the chart that you see on the left is still a work in progress, not all the pages and interactions have been represented!</p><p>We used <a href="https://statecharts.github.io/">statecharts</a> website to learn the concepts about Statecharts and State Machine.</p><p>The chart on the left was made via the super tool called <a href="https://sketch.systems/">Sketch.systems</a></p><p>We use it to represent all the states of our product, all new features ideas or improvements.</p><p>It really helps us PMs to manage the complexity of the UI System.</p><h3>What we learned</h3><ul><li>Our product is way more complex than we imagined</li><li>Some states do not have a specific UI linked to it (mostly all asynchronous state when we save content)</li><li>Statecharts are super easy to understand for PM and it really helps to translate business idea/requirements into functional specifications</li></ul><h3>How PMs use Statecharts at Seven Senders</h3><p>Imagine the following situation:</p><p>A stakeholder/customer/anyone brings a new idea/feature/improvement for your application/website/software. As PM, we look into our Statechart where this change will have an impact inside our system.<br>This helps us to quickly understand how much we will need to change the UI to implement this change.</p><p>With this knowledge we can better prioritise between different request when we need to develop them.</p><p>When the implementation/design of the idea/feature/improvement starts, the UI/UX designer can see quickly which states need to be designed or improved.</p><p>When the Front End team starts the work they already have their State Machine updated and all the screens/mocks for all the states.</p><p>This has helped us to drastically reduce development time for complex UI interactions.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8e284e51a9d4" width="1" height="1" alt=""><hr><p><a href="https://medium.com/sevensenders-techblog/state-machines-in-product-development-8e284e51a9d4">Statecharts in product development ?</a> was originally published in <a href="https://medium.com/sevensenders-techblog">SEVEN SENDERS Techblog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Startup Stories #2 - Seven Senders]]></title>
            <link>https://medium.com/sevensenders-techblog/startup-stories-2-seven-senders-d42000dcd3ae?source=rss----d6a1324e5ab1---4</link>
            <guid isPermaLink="false">https://medium.com/p/d42000dcd3ae</guid>
            <category><![CDATA[scaleup]]></category>
            <category><![CDATA[berlin]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[logistics]]></category>
            <category><![CDATA[startup]]></category>
            <dc:creator><![CDATA[Boris Diebold]]></dc:creator>
            <pubDate>Tue, 03 Jul 2018 14:36:03 GMT</pubDate>
            <atom:updated>2018-07-05T06:57:58.612Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eEbYG5xYK8-WwKtuM4RPJw.jpeg" /></figure><h3>Startup life, the next chapter — SEVEN SENDERS</h3><p>Beginning of this year, I started my second chapter of startup life in Berlin.</p><p><strong>What did I do before ?</strong></p><p>The previous four years have been awesome.</p><p>As part of the executive team at <a href="http://www.babbel.com">Babbel</a>, I helped scale the company to one of the most successful tech companies in Europe, growing to millions of paying subscribers and scaling up the from 100 to almost 500 in Berlin and New York.</p><p>It was a great journey, but somehow the most enjoying moments I had in the earlier days of scaling the company.</p><p>So — what next ?</p><p>For almost 20 years, I worked hard with 2 months off being the maximum that allowed myself a few times (and often a lot less).</p><p>I always dreamed of doing a longer sabbatical — which I now made reality: 6 months.</p><p><strong>Why SEVEN SENDERS ?</strong></p><p>I decided to join <a href="http://www.sevensenders.com">SEVEN SENDERS</a> since it ticked all my boxes on what I was looking for in my next professional challenge:</p><ul><li>CTO position in a promising startup/scaleup</li><li>possibility to shape product, tech as well as the company itself</li><li>an industry i like and interesting product &amp; tech challenges</li><li>current size between 50–100 people overall</li><li>a good existing tech team &gt;15 (I am not a coding CTO anymore)</li><li>significant business growth potential</li><li>solid financials and business model</li><li>enough runway (preferably recently closed Series A or similar)</li><li>strong no BS founder team (not just a bunch of kids with money playing)</li><li>experienced management team (or planning to hire)</li><li>good sense of humour and fun at work</li><li>nice office in Berlin</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5ATRNOs_b8mqlNLKo28-5Q.png" /><figcaption>Some pictures from Seven Senders office in Berlin, Prenzlauer Berg</figcaption></figure><p><strong>How did it turn out ?</strong></p><p>After 6 months, I can honestly say it has been an excellent decision.</p><p>We are ramping up business, product, tech, team and the overall company — while building a great culture and enjoying an awesome environment in the heart of Berlin (<a href="https://www.google.de/search?rlz=1C5CHFA_enDE783DE783&amp;biw=1920&amp;bih=903&amp;tbm=isch&amp;sa=1&amp;ei=g9SOWqW3N4TawAK6iqzoDw&amp;q=kastanienallee&amp;oq=kastanienallee&amp;gs_l=psy-ab.3..0l2j0i5i30k1l2j0i24k1l6.5754.7384.0.8178.14.14.0.0.0.0.135.1102.13j1.14.0....0...1c.1.64.psy-ab..0.14.1097...0i67k1j0i30k1.0.FVnKp4u8Hzw">see here for nice views </a>of the area where our office is located).</p><p>We are building a diverse team with people from all over the world that are excited about building the leading delivery platform.</p><p>As Berlin is <a href="https://blog.spiced-academy.com/brexit-berlin-startup-scene/">Europes #1 tech destination</a>, it is easy to convince promising candidates to relocate. Especially since <a href="https://www.numbeo.com/cost-of-living/in/Berlin">cost of living is still quite low compared to other major tech destinations</a>).</p><p>​As my journey continues, I will launch further posts…</p><p><strong>Interested to join us ? </strong><a href="https://www.sevensenders.com/careers/"><strong>Check out our team and open positions</strong></a><strong>.</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d42000dcd3ae" width="1" height="1" alt=""><hr><p><a href="https://medium.com/sevensenders-techblog/startup-stories-2-seven-senders-d42000dcd3ae">Startup Stories #2 - Seven Senders</a> was originally published in <a href="https://medium.com/sevensenders-techblog">SEVEN SENDERS Techblog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>