<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Pedro Lopez</title>
    <description>The latest articles on Forem by Pedro Lopez (@plopcas).</description>
    <link>https://forem.com/plopcas</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F306577%2F56158511-f755-461e-b281-acfac19093f3.png</url>
      <title>Forem: Pedro Lopez</title>
      <link>https://forem.com/plopcas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/plopcas"/>
    <language>en</language>
    <item>
      <title>Emoji Issue Classifier</title>
      <dc:creator>Pedro Lopez</dc:creator>
      <pubDate>Sat, 20 May 2023 15:28:24 +0000</pubDate>
      <link>https://forem.com/plopcas/emoji-issue-classifier-4b70</link>
      <guid>https://forem.com/plopcas/emoji-issue-classifier-4b70</guid>
      <description>&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;I built an Emoji Issue Classifier, a machine learning-based solution that automatically adds relevant labels to GitHub issues based on their content. The classifier analyses the text of an issue and predicts appropriate emoji labels, such as "🐛", "✨", "📈", and more, to help categorise and prioritise issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  Category Submission:
&lt;/h3&gt;

&lt;p&gt;Maintainer Must-Haves&lt;/p&gt;

&lt;h3&gt;
  
  
  App Link
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/marketplace/actions/emoji-issue-classifier"&gt;https://github.com/marketplace/actions/emoji-issue-classifier&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uc0yUZX5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dn0z37e6nyrptjtp9n53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uc0yUZX5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dn0z37e6nyrptjtp9n53.png" alt="Screenshot" width="744" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More examples here: &lt;a href="https://github.com/plopcas/gh-actions-test/issues"&gt;https://github.com/plopcas/gh-actions-test/issues&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Description
&lt;/h3&gt;

&lt;p&gt;The Emoji Issue Classifier is designed to improve the issue management process by automating the labeling of GitHub issues. It utilizes natural language processing and machine learning techniques to analyze the issue's title and description, perform sentiment analysis, and extract keywords. Based on this analysis, it adds appropriate emoji labels that represent the sentiment and topic of the issue.&lt;/p&gt;

&lt;p&gt;This solution saves time and effort for both issue submitters and project maintainers by accurately categorising and prioritising issues. It ensures that issues are properly labeled, enabling efficient issue tracking, organisation, and decision-making.&lt;/p&gt;

&lt;h3&gt;
  
  
  Link to Source Code
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/plopcas/emoji-issue-classifier"&gt;https://github.com/plopcas/emoji-issue-classifier&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Permissive License
&lt;/h3&gt;

&lt;p&gt;MIT license&lt;/p&gt;

&lt;h2&gt;
  
  
  Background (What made you decide to build this particular app? What inspired you?)
&lt;/h2&gt;

&lt;p&gt;The inspiration for this project came from my own experience with managing GitHub repositories and the challenges faced in efficiently processing and categorising a large number of issues. I wanted to automate the process of labelling issues, allowing project maintainers to focus more on issue resolution and providing a better experience for issue submitters. I also wanted to do this with a twist, hence the emojis.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I built it (How did you utilise GitHub Actions or GitHub Codespaces? Did you learn something new along the way? Pick up a new skill?)
&lt;/h3&gt;

&lt;p&gt;To build the Emoji Issue Classifier, I used GitHub Actions and GitHub Codespaces. GitHub Actions allowed me to automate the process of applying labels to issues based on the classifier's predictions. I integrated the classifier into a GitHub Action workflow, which runs whenever a new issue is opened or edited.&lt;/p&gt;

&lt;p&gt;GitHub Codespaces provided a convenient development environment. It allowed me to work on the project seamlessly in the browser without worrying about the setup or compatibility of development environments.&lt;/p&gt;

&lt;p&gt;Throughout the development process, I learned and applied various natural language processing techniques, including sentiment analysis, keyword extraction, and data augmentation. I trained a machine learning model using scikit-learn and employed the TextBlob library for sentiment analysis. I also used the NLTK library for data augmentation and synonym replacement to enhance the training data.&lt;/p&gt;

</description>
      <category>githubhack23</category>
    </item>
    <item>
      <title>Count triaged issues week on week</title>
      <dc:creator>Pedro Lopez</dc:creator>
      <pubDate>Sat, 13 May 2023 16:13:39 +0000</pubDate>
      <link>https://forem.com/plopcas/count-triaged-issues-week-on-week-1p68</link>
      <guid>https://forem.com/plopcas/count-triaged-issues-week-on-week-1p68</guid>
      <description>&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;A Jupyter Notebook that will allow you to count issues that have been applied a specific label week on week, for a number of weeks that you choose.&lt;/p&gt;

&lt;p&gt;This is particularly useful if you use a specific label to triage issues e.g. "triaged". You can then see how many issues were triaged week on week and by whom.&lt;/p&gt;

&lt;h3&gt;
  
  
  Category Submission:
&lt;/h3&gt;

&lt;p&gt;Maintainer Must-Haves&lt;/p&gt;

&lt;h3&gt;
  
  
  App Link
&lt;/h3&gt;

&lt;p&gt;You can try it directly in GitHub Codespaces.&lt;/p&gt;

&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fnA0pBGV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mr8c5qqo5sw1jqwot95w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fnA0pBGV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mr8c5qqo5sw1jqwot95w.png" alt="Input parameters" width="770" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pmK6zCgx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8v668lp5fc5gz0jepif2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pmK6zCgx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8v668lp5fc5gz0jepif2.png" alt="Output" width="800" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Description
&lt;/h3&gt;

&lt;p&gt;This Python script is used to count the number of issues in a specific GitHub repository that have been labeled with a specific label within a given number of weeks. The script uses the GitHub API to fetch and process the repository's issues.&lt;/p&gt;

&lt;p&gt;Here's a breakdown of what each function in the script does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;get_start_of_week()&lt;/code&gt;: returns the datetime object of the start of the current week (Monday at 00:00:00).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;get_total_issues(repo_owner, repo_name, access_token, label)&lt;/code&gt;: returns the total number of issues in the given repository with the given label. It does this by sending a GET request to the GitHub API's search endpoint.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;count_labelled_issues(repo_owner, repo_name, access_token, label, weeks)&lt;/code&gt;: main function of the script. It counts the number of issues in the given repository that have been labeled with the given label within the given number of weeks. It does this by sending a GET request to the GitHub API's issues endpoint, then iterating over the response data and counting the number of issues that meet the criteria. The function also prints a report for each week, listing the issues that were labeled during that week, their titles, their URLs, and the user who labeled them. I also included closed issues in the output.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The script uses the colorama library to print coloured text to the console (it doesn't show in the Jupyter Notebook version).&lt;/p&gt;

&lt;h3&gt;
  
  
  Link to Source Code
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/plopcas/labelled-issues-jupyter"&gt;https://github.com/plopcas/labelled-issues-jupyter&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Permissive License
&lt;/h3&gt;

&lt;p&gt;MIT license &lt;/p&gt;

&lt;h2&gt;
  
  
  Background (What made you decide to build this particular app? What inspired you?)
&lt;/h2&gt;

&lt;p&gt;Trying to gather metrics for triaging process. GitHub doesn't make it obvious to work with events like "labeled". This script allows me to generate metrics week on week.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I built it (How did you utilise GitHub Actions or GitHub Codespaces? Did you learn something new along the way? Pick up a new skill?)
&lt;/h3&gt;

&lt;p&gt;I used GitHub Codespaces with the &lt;a href="https://github.com/github/codespaces-jupyter"&gt;Jupyter Notebook template&lt;/a&gt; which allowed me to very quickly test the functionality as I was building it.&lt;/p&gt;

</description>
      <category>githubhack23</category>
    </item>
    <item>
      <title>What advice would you give to a younger version of yourself?</title>
      <dc:creator>Pedro Lopez</dc:creator>
      <pubDate>Tue, 06 Oct 2020 09:00:00 +0000</pubDate>
      <link>https://forem.com/plopcas/what-advice-would-you-give-to-a-younger-version-of-yourself-2ob0</link>
      <guid>https://forem.com/plopcas/what-advice-would-you-give-to-a-younger-version-of-yourself-2ob0</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7HUSIOSx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/te21wfgqi74duof3nfjv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7HUSIOSx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/te21wfgqi74duof3nfjv.jpg" alt="header"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few weeks ago, as part of my regular 121s with the team, I decided to ask them the question “What advice would you give to a younger version of yourself trying to get to where you are today in half the time?”. Now, this is typically a question that I would ask a mentor of mine, not that my mentor would ask me. However, I decided to try this question as a self-reflecting question for a change, and the results were pretty amazing as you will see.&lt;/p&gt;

&lt;p&gt;Ultimately, I think this exercise is not something most of us would normally do on our own. So I gave it a go for you, with my team 💙 I hope you like it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;These are not to be blindly followed, but rather, I hope most of these (if not all) will resonate with you, and you will take them as food for thought.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Ask, ask, ask and then ask a bit more
&lt;/h4&gt;

&lt;p&gt;Asking is the fastest way to learn new things. Especially when you find yourself in a new environment or working on a new domain. Having the conversation has the additional benefit of bringing people together. Human interaction is sometimes underestimated. Reading something on a wiki is efficient, having a chat is insightful, and opens the possibility of a deeper conversation about the subject.​&lt;/p&gt;

&lt;p&gt;In an environment with the right culture, I’ve never really heard something like “John asks too much”, so generally speaking, don’t be afraid to ask. But if you feel that you can’t ask freely, then ask yourself “is this the right environment for me”.​&lt;/p&gt;

&lt;p&gt;Sometimes it makes sense to try for yourself first, of course. But there is no need to bang your head against the wall for too long if you’re not making enough progress, particularly if a quick hint from someone else can go a long way.​&lt;/p&gt;

&lt;h4&gt;
  
  
  Get a mentor and become one
&lt;/h4&gt;

&lt;p&gt;Getting a mentor early on in your career is hugely beneficial, yet most junior professionals wait for a few years before even considering formal mentorship as an option. In fact, having more than one mentor for different things is also an option. Think of a mentor dedicated to career growth, another one to soft skills and a third one for technical competencies. This can definitely boost your progress. Don’t be afraid of “wasting” people’s time. Mentoring is a two-way street, and mentors get as much from the relationship as you do.&lt;/p&gt;

&lt;p&gt;Which is also why you should consider becoming a mentor yourself as soon as you are (reasonably) comfortable with the idea.&lt;/p&gt;

&lt;h4&gt;
  
  
  Seek feedback like there’s no tomorrow
&lt;/h4&gt;

&lt;p&gt;Biases are real, and they are everywhere. Some examples are overconfidence bias, self-serving bias (good things are due to skill, bad things are due to environment), confirmation bias (seeking out information that confirms pre-existing ideas). A simple step towards overcoming biases is to increase awareness. And nothing like good old constructive feedback to open your eyes.​&lt;/p&gt;

&lt;p&gt;Asking for feedback regularly is one of the most common traits of high performing individuals, and it shows and invested interest in self-development. You want to understand how your actions and behaviours are perceived by others, so that you can improve.&lt;/p&gt;

&lt;h4&gt;
  
  
  Don’t get too comfortable
&lt;/h4&gt;

&lt;p&gt;This is the typical “get out of your comfort zone”. But what does that mean? If you know basically everything that there is to know about something, it’s time to start expanding your horizons. You can start by teaching others what you know for instance.&lt;/p&gt;

&lt;p&gt;Seek for opportunities that are aligned with your career goals. Ask for help finding opportunities if you get stuck.​&lt;/p&gt;

&lt;p&gt;A reasonable amount of discomfort with your tasks is good, because it keeps you on your toes, and it pushes you to think outside of the box.​&lt;/p&gt;

&lt;p&gt;There are probably opportunities around you at the reach of the hand, like joining a project that uses a technology you’ve never used before, assuming a different set of responsibilities within your team, or swap teams to get exposure to an unfamiliar area of your business.​&lt;/p&gt;

&lt;p&gt;Ultimately, if you feel too comfortable for too long, and there are no opportunities that catch you eye in your environment, it’s probably time to start considering changing jobs, and that is actually ok.&lt;/p&gt;

&lt;h4&gt;
  
  
  Be curious
&lt;/h4&gt;

&lt;p&gt;Learn beyond what’s in your hands at a given moment. Read what’s new in your industry. Expand your knowledge by proactively seeking opportunities, like hackathons, meetups or conferences. Don’t take anything for granted and always keep an eye on future trends.&lt;/p&gt;

&lt;h4&gt;
  
  
  But at the same time, Stay focused
&lt;/h4&gt;

&lt;p&gt;Looking outwards helps to find new opportunities, generate a (healthy) discomfort and expand our knowledge. However, it’s also crucial to stay in the moment, and balance out that explorer mindset we talked about earlier, with laser focus.&lt;/p&gt;

&lt;p&gt;Once you’ve identified an opportunity, or an area of interest, you’ll need to invest enough time to really get the grasp of it and understand it inside out, to the point that you could teach it to others maybe, that’s a good benchmark usually. Setting uninterrupted time aside, to get in the flow, working on something, is the best way to make the most of your efforts and really master that one thing before moving on to something else.&lt;/p&gt;

&lt;h4&gt;
  
  
  Changing careers slows you down but it may be worth it
&lt;/h4&gt;

&lt;p&gt;At some point, most of us face a dilemma. And that is whether we should stay in the track that we are in, or we should change. A classical example is IC vs management. But by no means it’s the only one, think back-end vs front-end, integration vs data, machine learning vs distributed systems, or even just changing sectors like healthcare vs travel (like in my case). The good news is that usually these decisions are reversible, and a career change will teach you loads regardless, so it won’t necessarily be wasted time if things don’t work out. However, be aware that every time you change paths significantly, it’ll take some time to go over the learning curve and master your new skillset. So you want to give it a serious thought before making a career move like this, and definitely consider your context and personal circumstances. But remember change is not bad per se, it’s just scary, and it may be worth it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pay attention to impact (at scale)
&lt;/h4&gt;

&lt;p&gt;A very common motivator between software engineers is to be able to work on things that make a somewhat big impact. It’s very rewarding knowing that your contributions made the life of others a bit better, or more interesting or simply more fun. Therefore, when choosing your opportunities, it’s generally a good idea to consider the impact and scale of the problem you are trying to solve. Please note this doesn’t mean you should disregard any work that is not high impact / high scale, it just means you should be mindful. On a daily basis, there are things you can do too, even if your feature or task has a relatively low impact at first glance. You can share learnings with a wider audience, you can think about what it would take to expand beyond the current scope and maybe make a proposal, you can tweak aspects of it so that it can scale virtually indefinitely if needs be. In any case, the definition of impact in the context of a career conversation is not always obvious. So that is also something to keep in mind.&lt;/p&gt;

&lt;h4&gt;
  
  
  Work towards your next job
&lt;/h4&gt;

&lt;p&gt;An interesting way to keep you on the right path is to think about your future on a regular basis and make investments on things that are aligned with your mid-term to long-term goals.&lt;/p&gt;

&lt;p&gt;For example, even though at Skyscanner this is more of hat that you wear, let’s say you are looking to become an architect one day, sign up for opportunities that will allow you to work on architectural designs, stay closer to senior architects within your organisation and learn from them, stay informed about the latest developments in the field and bring in those learnings so that they become part of your current job as much as possible.&lt;/p&gt;

&lt;h4&gt;
  
  
  Politics are part of the job
&lt;/h4&gt;

&lt;p&gt;Some places are more “political” than others but in all companies, it is possible to promote yourself and your cause without compromising your values or those of your organisation by playing the office politics correctly (and positively).&lt;/p&gt;

&lt;p&gt;This is not (or shouldn’t be) about backstabbing, it’s about understanding the organigram and the informal networks, building connections and developing “people” skills. By leveraging your circle of influence, you can increase your impact and promote win-win situations.&lt;/p&gt;

&lt;h4&gt;
  
  
  The bad, the good and the ugly, all of it is worth it
&lt;/h4&gt;

&lt;p&gt;It is important to learn from the bad things as much as the good things. Nothing tells as much about ourselves as how we reacted to adversity. Using misses as learning opportunities is also hugely beneficial because it gives us the opportunity to have somewhat awkward and difficult conversations that can push us forward when done correctly.&lt;/p&gt;

&lt;p&gt;There are also lessons to be learned from the tedious work (ugly) that we must do from time to time, even if it just how to automate it for next time it comes our way.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Hugo S3 Deployments</title>
      <dc:creator>Pedro Lopez</dc:creator>
      <pubDate>Sun, 23 Aug 2020 14:20:58 +0000</pubDate>
      <link>https://forem.com/plopcas/hugo-s3-deployments-34ni</link>
      <guid>https://forem.com/plopcas/hugo-s3-deployments-34ni</guid>
      <description>&lt;h3&gt;
  
  
  My Workflow
&lt;/h3&gt;

&lt;p&gt;I have created a new GitHub Action that deploys to S3 using a configured deployment target in Hugo. Additional information about Hugo deployments is available in the &lt;a href="https://gohugo.io/hosting-and-deployment/hugo-deploy/"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why?
&lt;/h4&gt;

&lt;p&gt;I use Hugo for my personal website, and every time I make a change or create new content I need to build the site locally and then deploy it. But not any more. Now, with every commit, GitHub will build the site, deploy it to S3 and invalidate my CloudFront distribution so that fresh new content is available immediately.&lt;/p&gt;

&lt;h4&gt;
  
  
  Are there similar actions out there?
&lt;/h4&gt;

&lt;p&gt;Yes and no. I explored the Marketplace and could find workarounds. For example, there are actions to build a Hugo site, and there are actions to deploy it manually by uploading the output folder (&lt;code&gt;public&lt;/code&gt; typically) to a remote destination, like S3. And there are actions to invalidate CloudFront distributions.&lt;/p&gt;

&lt;p&gt;However, Hugo already provides a mechanism to do all this for you, the &lt;code&gt;hugo deploy&lt;/code&gt; command. Yet, there was no GitHub action I could find to run your this command and execute your configured deployment.&lt;/p&gt;

&lt;p&gt;This action solves this.&lt;/p&gt;

&lt;h4&gt;
  
  
  Implementation details
&lt;/h4&gt;

&lt;p&gt;I have created a Docker Container action for this. Documentation available &lt;a href="https://docs.github.com/en/actions/creating-actions/creating-a-docker-container-action"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  Dockerfile
&lt;/h5&gt;

&lt;p&gt;To define my container I use a Dockerfile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM pahud/awscli-v2:node-lts

RUN yum update -y &amp;amp;&amp;amp; \
    yum install -y curl jq

COPY entrypoint.sh /

ENTRYPOINT ["/entrypoint.sh"]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I'm using a base image that contains AWS CLI already, so that I can perform the CloudFront invalidation. Reference at the bottom.&lt;/p&gt;

&lt;p&gt;Then I'm installing &lt;code&gt;curl&lt;/code&gt; and &lt;code&gt;jq&lt;/code&gt; which I'll use to install Hugo in the container later on.&lt;/p&gt;

&lt;p&gt;Finally, I specify the entrypoint.&lt;/p&gt;
&lt;h5&gt;
  
  
  entrypoint.sh
&lt;/h5&gt;

&lt;p&gt;Important to remember to make it executable as explained in the documentation.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod +x entrypoint.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The entrypoint is what contains the logic that will be executed when the action runs.&lt;/p&gt;

&lt;p&gt;First, fail the pipeline immediately if there are any errors.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;set -eo pipefail
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Check the different parameters that we pass as environment variables. E.g.:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if [ -z "$AWS_ACCESS_KEY_ID" ]; then
  echo "error: AWS_ACCESS_KEY_ID is not set"
  err=1
fi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Create an AWS profile for this action.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws configure --profile hugo-s3 &amp;lt;&amp;lt;-EOF &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
${AWS_ACCESS_KEY_ID}
${AWS_SECRET_ACCESS_KEY}
${AWS_REGION}
text
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Then install Hugo by fetching the latest version with curl (not adding the code here, but can be found in the repo).&lt;/p&gt;

&lt;p&gt;Build and deploy the site.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hugo
hugo deploy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And finally, we clean up the AWS profile (not really needed if the container is destroyed immediately afterwards but good practice to clean up after ourselves).&lt;/p&gt;
&lt;h5&gt;
  
  
  action.yml
&lt;/h5&gt;

&lt;p&gt;Contains the metadata for the action.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: 'Hugo S3'
description: 'Deploy Hugo with an S3 target'
author: 'Pedro Lopez'
branding:
  icon: 'book'
  color: 'purple'
runs:
  using: 'docker'
  image: 'Dockerfile'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Submission Category
&lt;/h3&gt;

&lt;p&gt;DIY Deployments&lt;/p&gt;
&lt;h3&gt;
  
  
  Yaml File or Link to Code
&lt;/h3&gt;

&lt;p&gt;This action is now available in the GitHub Marketplace &lt;br&gt;
&lt;a href="https://github.com/marketplace/actions/hugo-s3"&gt;https://github.com/marketplace/actions/hugo-s3&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/plopcas"&gt;
        plopcas
      &lt;/a&gt; / &lt;a href="https://github.com/plopcas/hugo-s3-action"&gt;
        hugo-s3-action
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      GitHub Action to use `hugo deploy` configured with an S3 target
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Hugo S3 Action&lt;/h1&gt;
&lt;p&gt;GitHub action to run &lt;code&gt;hugo deploy&lt;/code&gt; provided there is an S3 target configured in your Hugo repo.&lt;/p&gt;
&lt;h2&gt;
Usage&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;name: Hugo S3
on
  push
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:
    
    runs-on: ubuntu-latest

    steps:
      - name: Check out master
        uses: actions/checkout@master
          
      - name: Deploy site
        uses: plopcas/hugo-s3-action@v1.3.0
        env:
          AWS_REGION: 'eu-west-2'
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
Configuration&lt;/h2&gt;
&lt;p&gt;Set the following properties as secrets in your repository under &lt;code&gt;Settings / Secrets&lt;/code&gt;.&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Required&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AWS_REGION&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;AWS region&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS_ACCESS_KEY_ID&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Access key with permissions to execute your deployment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS_SECRET_ACCESS_KEY&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Secret key&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Information about how to configure a deployment to S3 in Hugo can be found here &lt;a href="https://gohugo.io/hosting-and-deployment/hugo-deploy/" rel="nofollow"&gt;https://gohugo.io/hosting-and-deployment/hugo-deploy/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can optionally include a CloudFront distribution ID in your &lt;code&gt;config.toml&lt;/code&gt; file. Make sure the key you use can grant permission to invalidate it as well as deploy to S3 in that case.&lt;/p&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/plopcas/hugo-s3-action"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;I've also configured it on my personal site &lt;a href="https://retrolog.io/"&gt;https://retrolog.io/&lt;/a&gt;, which is also publicly available on GitHub.&lt;/p&gt;

&lt;p&gt;An example of a successful run is available here &lt;br&gt;
&lt;a href="https://github.com/plopcas/retrolog/runs/1018289670"&gt;https://github.com/plopcas/retrolog/runs/1018289670&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Hugo S3

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
      - name: Check out master
        uses: actions/checkout@master

      - name: Deploy site
        uses: plopcas/hugo-s3-action@v1.3.0
        env:
          AWS_REGION: 'eu-west-2'
          AWS_ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.ACCESS_KEY_SECRET }}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;

&lt;p&gt;GitHub repository &lt;a href="https://github.com/plopcas/hugo-s3-action"&gt;https://github.com/plopcas/hugo-s3-action&lt;/a&gt;&lt;br&gt;
Personal site using the new action &lt;a href="https://retrolog.io/"&gt;https://retrolog.io/&lt;/a&gt;&lt;br&gt;
Personal site on GitHub &lt;a href="https://github.com/plopcas/retrolog"&gt;https://github.com/plopcas/retrolog&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  References
&lt;/h4&gt;

&lt;p&gt;GitHub actions documentation &lt;a href="https://docs.github.com/en/actions/creating-actions/creating-a-docker-container-action"&gt;https://docs.github.com/en/actions/creating-actions/creating-a-docker-container-action&lt;/a&gt;&lt;br&gt;
Hugo on GitHub &lt;a href="https://github.com/gohugoio/hugo"&gt;https://github.com/gohugoio/hugo&lt;/a&gt;&lt;br&gt;
AWS CLI Docker base image &lt;a href="https://hub.docker.com/r/pahud/awscli-v2"&gt;https://hub.docker.com/r/pahud/awscli-v2&lt;/a&gt;&lt;/p&gt;

</description>
      <category>actionshackathon</category>
    </item>
    <item>
      <title>A Pragmatic Approach to Roadmapping</title>
      <dc:creator>Pedro Lopez</dc:creator>
      <pubDate>Sun, 28 Jun 2020 17:30:00 +0000</pubDate>
      <link>https://forem.com/plopcas/a-pragmatic-approach-to-roadmapping-jbn</link>
      <guid>https://forem.com/plopcas/a-pragmatic-approach-to-roadmapping-jbn</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tt6jG_oM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/a-pragmatic-approach-to-roadmapping.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tt6jG_oM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/a-pragmatic-approach-to-roadmapping.jpg" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating a roadmap can be a challenging task. I can't really say I am an expert on the matter, but have done it a couple of times. The most recent one, I put together a workshop that got fairly positive feedback and so I'm sharing it for the benefit of anyone interested.&lt;/p&gt;

&lt;p&gt;This post describes a pragmatic approach to creating a roadmap for half a year, but can be extrapolated to cover whatever time period you need. Just be aware that the longest the period, the fuzziest it will be after the first 6 months, particularly in an agile environment with quarterly OKRs.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Plan out the session
&lt;/h4&gt;

&lt;p&gt;I used a Miro board as the canvas for the workshop. Having a tool that allows for realtime remote collaboration is essential.&lt;/p&gt;

&lt;p&gt;Lay out the different steps (which I cover below) and add a time estimate, so that everyone can check if each part is overrunning.&lt;/p&gt;

&lt;p&gt;You don't need to cover absolutely everything in one session. Do it if you can, but this can be quite challenging, as there is a lot to cover, and probably people will be tired after max two hours.&lt;/p&gt;

&lt;p&gt;A high level overview of the board we used looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pqSIVgxO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/a-pragmatic-approach-to-roadmapping-1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pqSIVgxO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/a-pragmatic-approach-to-roadmapping-1.jpg" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Ice-breaker
&lt;/h4&gt;

&lt;p&gt;It's usually a good idea to start with an ice-breaker that will get people in the right mood. During the workshop, everyone needs to be participative. Spending a few minutes at the beginning, having a laugh and chatting informally, will definitely be beneficial.&lt;/p&gt;

&lt;p&gt;You can use classic exercises from your retrospectives, like guessing everyone's favourite food or describing your current mood with an emoji. The sky is the limit.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Set out expectations
&lt;/h4&gt;

&lt;p&gt;It is worth spending 5-10 minutes clarifying the expectations for the workshop. What are we trying to achieve, what's in scope and what's not?&lt;/p&gt;

&lt;p&gt;As the facilitator, come prepared with a proposal. Read through it during the meeting and get agreement or make amendments.&lt;/p&gt;

&lt;p&gt;Some of the categories we covered last time were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What we should do if we had unlimited time&lt;/li&gt;
&lt;li&gt;What we are actually doing today&lt;/li&gt;
&lt;li&gt;What we are not doing today&lt;/li&gt;
&lt;li&gt;What we should follow up on&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are just examples, feel free to come up with your own version.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Build individual roadmaps
&lt;/h4&gt;

&lt;p&gt;Here you will start the actual roadmapping exercise. It has a few steps.&lt;/p&gt;

&lt;h5&gt;
  
  
  4.1. List all the projects you can think of
&lt;/h5&gt;

&lt;p&gt;In a column, list all the projects/epics in your area. Doesn't matter if they have been discussed previously or not, and you are encouraged to think out-of-the-box.&lt;/p&gt;

&lt;p&gt;As a facilitator, it is a good idea to pre-populate the list with the projects you know of already. This will save time and will serve as an example for others to contribute.&lt;/p&gt;

&lt;p&gt;Remember you are listing projects, not tasks nor programs.&lt;/p&gt;

&lt;p&gt;Give people time to add projects to the list. You can use different techniques for this e.g. round robin, silent brainstorming, 1-2-4-all, free for all.&lt;/p&gt;

&lt;p&gt;At the end of this stage, you will have an unestimated, unordered and unowned list of projects that contains everything everyone in the room knows about the work you need to do in your area.&lt;/p&gt;

&lt;h5&gt;
  
  
  4.2 Estimate using t-shirt sizes
&lt;/h5&gt;

&lt;p&gt;Estimates are context dependent. What is big for one team, might be medium for another. Here, use whatever makes more sense to your team/area. For example, if you always work on one single thing at a time vs you usually parallelise two or three things, your estimates might differ. These are just ballpark figures, so don't worry too much.&lt;/p&gt;

&lt;p&gt;The sizes we used were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Small = 1/3 of the quarter&lt;/li&gt;
&lt;li&gt;Medium = 2/3 of the quarter&lt;/li&gt;
&lt;li&gt;Large = 1 quater&lt;/li&gt;
&lt;li&gt;Extra large = more than 1 quarter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Miro, it is easy to resize rectangles (projects) to match the reference sizes at the top of the list (see the template).&lt;/p&gt;

&lt;p&gt;Go through the projects from the top and estimate all of them. On a second pass, try to break down the biggest ones into smaller chunks.&lt;/p&gt;

&lt;h5&gt;
  
  
  4.3 Order projects using a naive approach
&lt;/h5&gt;

&lt;p&gt;A simple bubble-sort will do. Starting from the top decide wether the next project should be done before or after the previous one. Very quickly we started moving things up or down, and ended up with a reasonably well sorted list. Doesn't have to be perfect, but it should help to group things that need to be done roughly at the same time, and identify things that can probably wait.&lt;/p&gt;

&lt;h5&gt;
  
  
  4.4 Roughly define which team should own each project
&lt;/h5&gt;

&lt;p&gt;If you are building a roadmap for more than one team, at this point is useful to colour-code the projects to highlight which team will be the official owner of the project. In practice, this means the team that will provide an Epic Owner for the project. If you are unfamiliar with the concept of Epic Owner, it's the person in charge of an epic acting like the project manager (plus other things, but that's a topic for a different time).&lt;/p&gt;

&lt;p&gt;Sometimes ownership is shared, and sometimes you just don't know. This is absolutely fine at this point, especially for things that will happen 2+ quarters away from now.&lt;/p&gt;

&lt;h5&gt;
  
  
  4.5 Build roadmaps individually
&lt;/h5&gt;

&lt;p&gt;Give people 10-15 minutes to build their own roadmaps with the projects on the list. The goal is to prioritise and parallelise things. Think about dependencies and respect the order as much as possible. But don't feel constrained by the order that came out of 4.3. It was ordered naively after all.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Build a straw-man roadmap together
&lt;/h4&gt;

&lt;p&gt;At this point, everyone should be pretty familiar with the items in the roadmap, the non-controversial topics, and the trickiest ones.&lt;/p&gt;

&lt;p&gt;As a group, try to put together a final version. Use arrows to explicitly flag dependencies between projects.&lt;/p&gt;

&lt;p&gt;It's very important to remember that this is just a straw-man roadmap, meaning it's an advanced draft. Not something to be publicly shared, as it needs more work still. But a helpful internal tool nonetheless.&lt;/p&gt;

&lt;p&gt;The output will be useful in deciding what to do next, and for OKR planning. But things can, and most certainly will, change.&lt;/p&gt;

&lt;h4&gt;
  
  
  6. Reconcile with OKRs
&lt;/h4&gt;

&lt;p&gt;Let's think for a minute about what we have. We have a list of things that we want to build as an area (area meaning the part of the business you are roadmapping for, made out of a subset of the total of teams in the organisation). We know how those different things relate to each other in terms of dependencies. And we roughly know who is best placed to own each of the work streams.&lt;/p&gt;

&lt;p&gt;The are two missing pieces still.&lt;/p&gt;

&lt;h5&gt;
  
  
  Strategy
&lt;/h5&gt;

&lt;p&gt;Ideally you should write your strategy briefs first. We had some drafts, but we made a conscious decision to invert the order. Our aim was to gain clarity about the future and prepare ourselves for the imminent OKR planning.&lt;/p&gt;

&lt;p&gt;If you have already written a formal strategy, for the most part, your projects will come directly from it.&lt;/p&gt;

&lt;h5&gt;
  
  
  OKRs
&lt;/h5&gt;

&lt;p&gt;Company-driven goals might clash somehow with your roadmap. You wouldn't know until close to the beginning of next quarter, when company OKRs are refreshed (this might be different in your case, depending on the cadence of your organisation).&lt;/p&gt;

&lt;p&gt;Even though adjustments might be necessary, company OKRs don't invalidate your roadmap, but you might want to reserve certain capacity to make sure you can accommodate unexpected needs. Typically this will be in the form of OKRs that require enabling others to deliver their goals, or to contribute to pushing metrics in reaction to a market change (like during COVID).&lt;/p&gt;

&lt;p&gt;Having a roadmap will prepare you better with the tools you need to accomplish company OKRs. It'll be much easier to find something in your roadmap that supports one of those company goals, than having to come up with an entirely new project on the spot. So you are increasing the chances of having something ready, that is aligned with both the company goals and your long term vision for your area.&lt;/p&gt;

&lt;h4&gt;
  
  
  7. Share with the teams and keep iterating
&lt;/h4&gt;

&lt;p&gt;It's important to get buy-in from the team that will actually work on the projects. You want to give everyone a chance to contribute and provide input if they have anything to add. Share your roadmap, ask for feedback, learn and iterate. Do that a few times and you will have a solid and always up-to-date roadmap, ready for any planning cycle.&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>technique</category>
      <category>workshop</category>
      <category>roadmap</category>
    </item>
    <item>
      <title>One Remote, All Remote</title>
      <dc:creator>Pedro Lopez</dc:creator>
      <pubDate>Thu, 14 May 2020 19:45:52 +0000</pubDate>
      <link>https://forem.com/plopcas/one-remote-all-remote-4ib7</link>
      <guid>https://forem.com/plopcas/one-remote-all-remote-4ib7</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6SAWGZ-M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/one-remote-all-remote.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6SAWGZ-M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/one-remote-all-remote.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This post was originally intended as a compilation of suggestions to promote a “one remote, all remote” approach to meetings. That is, instead of using room equipment that can make the experience less than ideal for remote attendees, if one person joins remotely, everyone does.&lt;/p&gt;

&lt;p&gt;During COVID-19 lockdown, I've confirmed with my team that all of these apply to a full remote setup as well.&lt;/p&gt;

&lt;p&gt;Also, as we start going back to “normality”, some people will return to the office from day one, while others will stay home for a bit longer. As a result, hybrid team configurations, like the one this post was originally intended to address, will be very common for a while. Now more than ever, these tips might be relevant to you too.&lt;/p&gt;

&lt;p&gt;NOTE: these tips mention Zoom specifically, just replace with you video conferencing software of choice.&lt;/p&gt;

&lt;p&gt;🎧 &lt;strong&gt;Use headphones&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Any type is fine, but noise cancelling ones work best because they provide with a higher level of sound isolation. If there is more than one attendee in the same room, because of the lag, you might want to set the volume high enough so that is not distracting to hear the other person speaking at the same time. But not too high, you'll still need your ears after the meeting, safety first.&lt;/p&gt;

&lt;p&gt;There is an exception. If you are in a phone booth, or you are the only person in the room, feel free to use your laptop internal microphone and speakers (or equivalent). Consider double checking that there is no undesired echo for everyone else in the call.&lt;/p&gt;

&lt;p&gt;🎥 &lt;strong&gt;Use a camera&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;General rules for remote meetings still apply, and it's generally better to see the person speaking. Please make sure you either have an external webcam or you keep your laptop lid open during the call so that you can use the laptop camera. Consider enabling your camera by default or turn it on right after joining the call. Feel free to disconnect video temporarily, though, if you are not speaking or if the signal is bad.&lt;/p&gt;

&lt;p&gt;🙊 &lt;strong&gt;If you are not speaking, mute yourself&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is paramount in a set up where multiple people is in the same room joining the same call, otherwise the audio experience will be bad due to unwanted echo. Depending on the configuration of the meeting, the host can also mute all participants if needed.&lt;/p&gt;

&lt;p&gt;Extra tip: Use the “Mute microphone when joining a meeting” setting that you can find in Preferences → Audio.&lt;/p&gt;

&lt;p&gt;✋ &lt;strong&gt;Consider using the raise hand functionality to indicate that you want to talk&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In a remote setup it's hard to see when someone has the intention to speak, particularly when the screen is shared. You might be hidden in the gallery if many people is in the call. One effective way to tackle this is to use the raise hand functionality in Zoom. If the number of people is small (typically less than 5) this might not be necessary.&lt;/p&gt;

&lt;p&gt;NOTE: with recent versions of Zoom, the host can enable Nonverbal feedback. Click on the participants tab and you'll see icons for things like “go faster”, “thumbs up” or “need a break” that will be seen by the meeting host.&lt;/p&gt;

&lt;p&gt;🙋 &lt;strong&gt;Every meeting needs a facilitator (and if you don't know who that is, it's probably you)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You need someone to tell others to mute themselves if they don't realise, and to coordinate who speaks when the conversation doesn't flow naturally. The facilitator in this particular case could just be the meeting host, but in large meetings it might make sense to get some help. As a rule of thumb, if there is no clearly designated facilitator, please jump in and help.&lt;/p&gt;

&lt;p&gt;🔍 &lt;strong&gt;Font size matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You might have your laptop connected to a high resolution monitor, but most attendees probably won't. Some might even be using a room monitor and looking at the screen from a distance. Also the image will not be as crisp because of video compression. Be mindful of this and zoom in a little 🙏&lt;/p&gt;

&lt;p&gt;This applies to every tool or tab that you switch to, not just the first one.&lt;/p&gt;

&lt;p&gt;➗ &lt;strong&gt;Divide and conquer using Zoom breakout rooms&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Useful for brainstorming topics that are too complex to discuss with a large audience. Break down the topic into questions, divide up people into groups to work on those questions, then re-group and share learnings.&lt;/p&gt;

&lt;p&gt;⏳ &lt;strong&gt;Be mindful of time and let others have a chance to speak&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A facilitator could help with this by intervening when someone is dominating the discussion and not leaving enough time for others to express their opinions. This is more difficult to do in a remote setting, as body language cues do not work as well here, so everyone just needs to be more aware and understanding of each other 🙂&lt;/p&gt;

&lt;p&gt;The raise hand feature could help (encourages people to pass the mic more), and other formats like silent brainstorming and zoom breakout rooms also ensure everyone can contribute, even if they are not vocal.&lt;/p&gt;

&lt;p&gt;💚 &lt;strong&gt;Zoom virtual backgrounds&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As we recently learned, they are super cool! And for those that are working from home are worried about accidental photobombs by their housemates/partners/kids in the background, this offers a layer of privacy.&lt;/p&gt;

&lt;p&gt;🔁 &lt;strong&gt;Ask for feedback&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can't see people as clearly when everyone is joining remotely and crammed in a small gallery of thumbnails, so there's less visual feedback. Pause during presentations to ask if anyone has questions. As participants, a big thumbs up/down or a verbal “yes/no” is much more noticeable than a nod/head-shake.&lt;/p&gt;

&lt;p&gt;👔 &lt;strong&gt;VPN etiquette still applies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have a corporate VPN, disconnect from it when joining a remote meeting. Otherwise you will be using precious bandwidth and likely affecting others that need it.&lt;/p&gt;

&lt;p&gt;Kudos to my teammates Grace, Leandro and Stuart, who helped to put this together. Thanks!&lt;/p&gt;

</description>
      <category>wfh</category>
      <category>covid19</category>
      <category>remote</category>
      <category>teams</category>
    </item>
    <item>
      <title>Continuous Performance Assessment</title>
      <dc:creator>Pedro Lopez</dc:creator>
      <pubDate>Sun, 10 May 2020 17:30:50 +0000</pubDate>
      <link>https://forem.com/plopcas/continuous-performance-assessment-4g25</link>
      <guid>https://forem.com/plopcas/continuous-performance-assessment-4g25</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KBWbz1zD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/continuous-performance-assessment.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KBWbz1zD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/continuous-performance-assessment.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have you ever struggled evaluating the performance of your direct reports? Or have you been surprised in your performance evaluation meeting with your manager? In this post I'll explain a different approach and will give you some tips and guidelines to implement it yourself.&lt;/p&gt;

&lt;h4&gt;
  
  
  Is this 1-pager worth your time?
&lt;/h4&gt;

&lt;p&gt;As managers, it is important to provide support and guidance in regards to performance so that people continue to improve and grow. And this should be happening regardless of the performance assessment cycle.&lt;/p&gt;

&lt;p&gt;Let me start by trying to show you why I think this technique is for you, and also why Continuous Performance Assessment matters regardless of whether you are manager or a managee. This is for everyone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long do you spend on average preparing your performance notes?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Something between too long, and “please don’t ask me about that painful time of my life” → keep reading&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How often do you discuss performance with your direct reports / manager?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not often enough → keep reading&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you track wins and misses?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I don't do it → keep reading&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you know everyone in your team has the same understanding of the competency framework?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I don't know it, and just mentioning competency frameworks makes me feel goosebumps and a cold sweat on the back of my neck → keep reading&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How confident are you that there will be no surprises when discussing the results of the performance evaluation with your direct report / manager?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Anything less than 100% → keep reading&lt;/p&gt;

&lt;p&gt;I practice Continuous Performance Assessment with my team, and have been doing it for some time now. In this post I'll explain the benefits of this approach and will give you some tips and guidelines to implement it yourself.&lt;/p&gt;

&lt;h4&gt;
  
  
  Avoiding the big rush at the end
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mqDRd_wD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/continuous-performance-assessment-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mqDRd_wD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/continuous-performance-assessment-2.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Being consistent at writing notes about performance is hard.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It requires a lot of discipline.&lt;/li&gt;
&lt;li&gt;You need to know enough detail about the items you are capturing.&lt;/li&gt;
&lt;li&gt;It doesn't scale - In fact, it becomes exponentially harder as the number of direct reports grow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Managers (me included) know this, and build mental barriers to avoid a process that is unpleasant to their eyes. As a result, it is often left to the very last minute, when there is no other choice but to sit down and write.&lt;/p&gt;

&lt;p&gt;But what if this was part of your regular 121 conversations? You already have time booked for this.&lt;/p&gt;

&lt;p&gt;Remind yourself of the benefits. At the end of the cycle you will have notes covering the whole period. This will help you remember details that you would have forgotten otherwise, so your notes will be much more thorough. And fairer. Recency bias will be less relevant, because you will have been capturing information more evenly.&lt;/p&gt;

&lt;h4&gt;
  
  
  Choosing a frequency
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MmJbAEmH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/continuous-performance-assessment-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MmJbAEmH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/continuous-performance-assessment-3.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Should you update your notes every week? once a month? once a quarter? Only you know what works for you and your team.&lt;/p&gt;

&lt;p&gt;Personally, every two weeks is the cadence I find more useful, which also maps to the frequency of my 121s. So if you can afford doing this every single 121, do it. If not, do it as frequently as you can. Seriously, this is important. Having a chat about performance should be as easy and comfortable as talking about the weather or asking about the weekend.&lt;/p&gt;

&lt;p&gt;There are pre-requisites, of course. You'll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trust&lt;/li&gt;
&lt;li&gt;Transparency about the process&lt;/li&gt;
&lt;li&gt;Engagement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's a self-reinforcing cycle, you need transparency to generate trust, when you have trust and people see the benefit of having an open discussion about performance, there comes engagement. With engagement, there comes more feedback and proactivity, and more data. And with more data, there are even more reasons to be transparent and give clarity about how that data will be used.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating structure
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I9-ZNheU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/continuous-performance-assessment-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I9-ZNheU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/continuous-performance-assessment-4.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Keep it simple. Use a table (or a nested list but I prefer a table). Define categories that are relevant to your environment, typically areas of your competency framework. Bias in favour of outcomes and impact, instead of actions. And use the same structure with everyone.&lt;/p&gt;

&lt;p&gt;If you have an official structure for your performance assessment notes, you are half way there, use the same one. You don't want to reinvent the wheel and then have to spend time mapping between different formats. Equally, from the manager's perspective, you want to have meaningful discussion with other managers about the performance of your reports and their reports, and having a common framework makes it easier and more efficient.&lt;/p&gt;

&lt;p&gt;Make sure competencies are fully understood by everyone in your team. Spend 121 time going through each competency and share examples of bad/good/great behaviours in each one. Consider having a refresher session every 6 months or when competencies get an update.&lt;/p&gt;

&lt;p&gt;Don't forget to include misses. Discuss impact, foreseeability and response. It is paramount for your reports to understand what they should've done instead of what they did, and this will help them grow much faster. Also, it will give them the chance to turn the tables and come out stronger if you have these conversations early.&lt;/p&gt;

&lt;h4&gt;
  
  
  Avoiding surprises
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K1h0aitU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/continuous-performance-assessment-5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K1h0aitU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/continuous-performance-assessment-5.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the absolute key. If you are the manager, after you prepared the table, explained the competency framework, got alignment and common understanding, and started the process with some notes of your own, there is one last thing for you to do.&lt;/p&gt;

&lt;p&gt;Let go.&lt;/p&gt;

&lt;p&gt;That document is no longer yours. It's your report's. From this point on, most of the updates in the performance assessment will have to be done by them. It's no longer your performance assessment, it's a self-assessment now, with your input.&lt;/p&gt;

&lt;p&gt;As a result, you will have frequent conversations about wins and misses. Performance will not be something to be evaluated at the end of the cycle, it will be a way to assess how I'm doing against my own career path in real time. And equally as important, It will become a framework to have meaningful discussions about what's next and how to get there.&lt;/p&gt;

&lt;h4&gt;
  
  
  Takeaways
&lt;/h4&gt;

&lt;p&gt;If you want to try Continuous Performance Assessment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoid the big rush at the end by capturing performance on a regular basis.&lt;/li&gt;
&lt;li&gt;Choose a frequency that works for you and your team, but the more frequent the better.&lt;/li&gt;
&lt;li&gt;Use a structure that is compatible with your official performance evaluation notes.&lt;/li&gt;
&lt;li&gt;Avoid surprises at the end by making it a collaborative effort, and letting go.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>management</category>
      <category>technique</category>
      <category>career</category>
    </item>
    <item>
      <title>COVID-19 Peak Detector</title>
      <dc:creator>Pedro Lopez</dc:creator>
      <pubDate>Sat, 18 Apr 2020 17:39:50 +0000</pubDate>
      <link>https://forem.com/plopcas/covid-19-peak-detector-3okd</link>
      <guid>https://forem.com/plopcas/covid-19-peak-detector-3okd</guid>
      <description>&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;COVID-19 Peak Detector is a Java Spring Boot application with a DynamoDB store that displays graph information with stats about COVID-19. You can select the country you are interested in and you can create an alert by entering your phone number.&lt;/p&gt;

&lt;p&gt;A scheduled process will check the data periodically and will send the alert when a peak is detected.&lt;/p&gt;

&lt;p&gt;For simplicity and to avoid unnecessary spam, after sending the alert the process removes it from the database.&lt;/p&gt;

&lt;p&gt;In addition to that, there is an anonymous chat available, in which COVID-19 news are posted every 5 minutes. People can comment on the news or just talk about the weather.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk5cvyabiwgbilfeerf1u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk5cvyabiwgbilfeerf1u.png" alt="screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo Link
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://covid19.plopcas.com" rel="noopener noreferrer"&gt;http://covid19.plopcas.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Link to Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/plopcas/covid19-peak-detector" rel="noopener noreferrer"&gt;https://github.com/plopcas/covid19-peak-detector&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I built it (what's the stack? did I run into issues or discover something new along the way?)
&lt;/h2&gt;

&lt;p&gt;In a nutshell, this application uses the following techonologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spring Boot as the web framework&lt;/li&gt;
&lt;li&gt;DynamoDB as the database&lt;/li&gt;
&lt;li&gt;Thymeleaf for templating&lt;/li&gt;
&lt;li&gt;Chart.js for graphs&lt;/li&gt;
&lt;li&gt;Twilio SMS for alerts&lt;/li&gt;
&lt;li&gt;Twilio Chat for in-app messaging&lt;/li&gt;
&lt;li&gt;Twilio Sync for news&lt;/li&gt;
&lt;li&gt;Gradle as the build tool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the COVID-19 data and the news, I'm using free APIs that are available via the Postman website here &lt;a href="https://covid-19-apis.postman.com/" rel="noopener noreferrer"&gt;https://covid-19-apis.postman.com/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The demo application was deployed in AWS using Elastic Beanstalk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Resources/Info
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/plopcas/twilio-hackathon-covid-19-peak-detector-5hfk"&gt;https://dev.to/plopcas/twilio-hackathon-covid-19-peak-detector-5hfk&lt;/a&gt;&lt;/p&gt;

</description>
      <category>twiliohackathon</category>
    </item>
    <item>
      <title>Twilio Hackathon - COVID-19 Peak Detector</title>
      <dc:creator>Pedro Lopez</dc:creator>
      <pubDate>Sat, 18 Apr 2020 16:00:00 +0000</pubDate>
      <link>https://forem.com/plopcas/twilio-hackathon-covid-19-peak-detector-5hfk</link>
      <guid>https://forem.com/plopcas/twilio-hackathon-covid-19-peak-detector-5hfk</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretrolog.io%2Fimages%2Ftwilio-hackathon-covid-19-peak-detector.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretrolog.io%2Fimages%2Ftwilio-hackathon-covid-19-peak-detector.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm taking part in the Twilio x DEV.to Hackathon and this is my project. I'll show here how I built it and how it works. Keep reading if you want to know more.&lt;/p&gt;

&lt;h4&gt;
  
  
  The application
&lt;/h4&gt;

&lt;p&gt;COVID-19 Peak Detector is a Java Spring Boot application with a DynamoDB store that displays graph information with stats about COVID-19. You can select the country you are interested in and you can create an alert by entering your phone number.&lt;/p&gt;

&lt;p&gt;A scheduled process will check the data periodically and will send the alert when a peak is detected.&lt;/p&gt;

&lt;p&gt;For simplicity and to avoid unnecessary spam, after sending the alert the process removes it from the database.&lt;/p&gt;

&lt;p&gt;In addition to that, there is an anonymous chat available, in which COVID-19 news are posted every 5 minutes. People can comment on the news or just talk about the weather.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretrolog.io%2Fimages%2Ftwilio-hackathon-covid-19-peak-detector-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretrolog.io%2Fimages%2Ftwilio-hackathon-covid-19-peak-detector-2.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  How I built it
&lt;/h4&gt;

&lt;p&gt;In a nutshell, this application uses the following techonologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spring Boot as the web framework&lt;/li&gt;
&lt;li&gt;DynamoDB as the database&lt;/li&gt;
&lt;li&gt;Thymeleaf for templating&lt;/li&gt;
&lt;li&gt;Chart.js for graphs&lt;/li&gt;
&lt;li&gt;Twilio SMS for alerts&lt;/li&gt;
&lt;li&gt;Twilio Chat for in-app messaging&lt;/li&gt;
&lt;li&gt;Twilio Sync for news&lt;/li&gt;
&lt;li&gt;Gradle as the build tool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the COVID-19 data and the news, I'm using free APIs that are available via the Postman website here &lt;a href="https://covid-19-apis.postman.com/" rel="noopener noreferrer"&gt;https://covid-19-apis.postman.com/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The demo application was deployed in AWS using Elastic Beanstalk.&lt;/p&gt;

&lt;p&gt;I'll explain some of the most interesting pieces.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Welcome controller
&lt;/h4&gt;

&lt;p&gt;This is where everything starts. The controller is in charge of calling the different services to fetch the necessary data to populate the view.&lt;/p&gt;

&lt;p&gt;From here, we call the DataService to fetch the historical data, and we use Faker, a Java library to generate random data sets, to assign a random username to the user landing the page. This username will be important for the chat widget.&lt;/p&gt;

&lt;p&gt;Fun fact, all the usernames are characters from Game of Thrones 🤓&lt;/p&gt;

&lt;p&gt;It is important to mention that the data about COVID-19 doesn't change very frequently. Therefore, I'm caching the data in memory for 12 hourse before calling the third-party API again.&lt;/p&gt;

&lt;p&gt;This is a small optimisation, because those APIs are not very flexible, and they force you to fetch all the historical data in every call. This way, we minimise the amount of data transfered over the wire in exchange for a bit of up-to-dateness.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Data API
&lt;/h4&gt;

&lt;p&gt;We expose our data in an endpoint available at &lt;code&gt;/countries/{countryAndProvince}&lt;/code&gt;. This endpoint is called using AJAX from the browser everytime the user selects a different country from the dropdown.&lt;/p&gt;

&lt;p&gt;When called, it will pass the request to the data service so that we can load the data for the selected country and craft a response for the caller.&lt;/p&gt;

&lt;p&gt;We then read the information form Javascript and update the graph using Chart.js.&lt;/p&gt;

&lt;p&gt;This is a monolithic application, so typically we render the views on the server-side using Thymeleaf. However, it is useful to also call the back-end from Javascript and render changes without refreshing the page. This provides a better user experience.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating an alert
&lt;/h4&gt;

&lt;p&gt;Another thing we can do here is to create an SMS alert for a given country. When the user signs up, a confirmation SMS will be sent. When a peak is detected, a second SMS will be sent and the phone number will be deleted from the DynamoDB.&lt;/p&gt;

&lt;p&gt;But before that, we need to insert the data in Dynamo. For that, we use &lt;code&gt;spring-data-dynamodb&lt;/code&gt;. This library allows us to set up our repositories like normal JPA repositories. It's very convenient, and it makes it very easy to read and write from your tables.&lt;/p&gt;

&lt;p&gt;The key components here are the DyanmoDBConfiguration class, the model and the repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Configuration
@EnableDynamoDBRepositories(basePackages = "com.plopcas.twiliohackathon.cpd.repository")
public class DynamoDBConfiguration {
    @Value("${amazon.dynamodb.endpoint}")
    private String amazonDynamoDBEndpoint;

    @Value("${amazon.aws.accesskey}")
    private String amazonAWSAccessKey;

    @Value("${amazon.aws.secretkey}")
    private String amazonAWSSecretKey;

    @Bean
    public AmazonDynamoDB amazonDynamoDB() {
        AmazonDynamoDB dynamoDB = new AmazonDynamoDBClient(amazonAWSCredentials());

        if (!StringUtils.isEmpty(amazonDynamoDBEndpoint)) {
            dynamoDB.setEndpoint(amazonDynamoDBEndpoint);
        }

        // check table and create if it does not exist
        DynamoDBMapper mapper = new DynamoDBMapper(dynamoDB);
        CreateTableRequest request = mapper.generateCreateTableRequest(Alert.class);
        request.setProvisionedThroughput(new ProvisionedThroughput(1L, 1L));
        TableUtils.createTableIfNotExists(dynamoDB, request);

        return dynamoDB;
    }

    @Bean
    public AWSCredentials amazonAWSCredentials() {
        return new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey);
    }
}


@DynamoDBTable(tableName = "Alert")
public class Alert {
    private String id;
    private String country;
    private String phone;

    @DynamoDBHashKey
    @DynamoDBAutoGeneratedKey
    public String getId() {
        return id;
    }

    @DynamoDBAttribute
    public String getCountry() {
        return country;
    }

    @DynamoDBAttribute
    public String getPhone() {
        return phone;
    }

    // setters and constructors

}


public interface AlertRepository extends CrudRepository&amp;lt;Alert, String&amp;gt; {
    @EnableScan
    public List&amp;lt;Alert&amp;gt; findAll();
}

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

&lt;/div&gt;



&lt;p&gt;I am creating the table upfront, on app startup, if it doesn't exist already.&lt;/p&gt;

&lt;p&gt;Of course, all the sensitive information is externalised as environment variables.&lt;/p&gt;

&lt;p&gt;Like usual with Spring JPA repositories, all the CRUD operations are automagically available. I'm explicitely declaring the &lt;code&gt;findAll&lt;/code&gt; one so that I can annotate it with &lt;code&gt;@EnableScan&lt;/code&gt;. All methods of the repository are implemented as queries by default. However, if there is no index to query, these will fail. So you need to explicitly enable the scan operations with the annotation.&lt;/p&gt;

&lt;p&gt;More information can be found &lt;a href="https://www.baeldung.com/spring-data-dynamodb" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once these pieces are reading, we can call the &lt;code&gt;save&lt;/code&gt; method in the repository (it's not there, it's magic), to insert new alerts. This is done in the AlertService as expected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Alert alert = new Alert(country, phone);
alertRepository.save(alert);

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  The scheduled peak detector
&lt;/h4&gt;

&lt;p&gt;In order to detect peaks we use a very naive approach. It's a hack project, please bear with me. We check if the number of cases today, is lower than yesterday and lower than the day before yesterday.&lt;/p&gt;

&lt;p&gt;If that is the case, we consider a peak detected, and we send an alert to all the phone numbers that subscribed to that country.&lt;/p&gt;

&lt;p&gt;In order to run the process periodically, we use the &lt;code&gt;@Scheduled&lt;/code&gt; annotation with a fixedRate of 12 hours.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Scheduled(fixedRate = 12 * 60 * 60 * 1000)

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  The SMS service
&lt;/h4&gt;

&lt;p&gt;Twilio makes it very easy to send SMS messages. Once you have your account set up, it's as easy as using their SDK, get an access token and start sending messages. Note that you need to get a phone number first, that will be the number from which the messages will be sent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Service
public class SmsService {
    private String fromPhone;

    public SmsService(@Value("${twilio.accountSid}") String accountSid,
                      @Value("${twilio.authToken}") String authToken,
                      @Value("${twilio.fromPhone}") String fromPhone) {
        this.fromPhone = fromPhone;
        Twilio.init(accountSid, authToken);
    }

    public void sendConfirmationSms(String toPhone) {
        Message message = Message.creator(
                new com.twilio.type.PhoneNumber(toPhone),
                new com.twilio.type.PhoneNumber(fromPhone),
                "COVID-19 Peak Detector - Your alert has been created, thanks!")
                .create();
    }

    public void sendAlertSms(String toPhone, String country) {
        Message message = Message.creator(
                new com.twilio.type.PhoneNumber(toPhone),
                new com.twilio.type.PhoneNumber(fromPhone),
                "COVID-19 Peak Detector - A peak has been reached in "
                        + country + "! Thanks for using our service :)")
                .create();
    }
}

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

&lt;/div&gt;



&lt;p&gt;To get the tokens, I created a dedicated TokenService that uses the API key and API secret to generate tokens with the necessary grants depending on the service. In my case I need two types of tokens, one for the Chat service and one for the Sync service.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Chat
&lt;/h4&gt;

&lt;p&gt;The idea behind the chat is to have a forum for people to talk about the situation, ramble and share. I created a very simple UI, and using the Twilio Javascript SDK, I create a channel, and sychronise all the messages between all the users.&lt;/p&gt;

&lt;p&gt;In addition to this, to spice things up, I use the Sync service to store a shared state that contains COVID-19 news. Every 5 minutes, a process posts one headline for people to chat about. Using Sync, I can post the same headline to every browser at the same time.&lt;/p&gt;

&lt;p&gt;Keeping state in a distributed environment is not easy, and Twilio makes it very straightforward. Again, this requires some configuration in you Twilio console, but it's fairly simple and it's all explained in their documentation.&lt;/p&gt;

&lt;h4&gt;
  
  
  That's it!
&lt;/h4&gt;

&lt;p&gt;I hope you enjoyed this post. All the code is publicly available in GitHub here&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/plopcas/covid19-peak-detector" rel="noopener noreferrer"&gt;https://github.com/plopcas/covid19-peak-detector&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and the demo application (at least for a few days) is available here&lt;/p&gt;

&lt;p&gt;&lt;a href="http://covid19.plopcas.com" rel="noopener noreferrer"&gt;http://covid19.plopcas.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stay safe, stay strong, stay home 👋&lt;/p&gt;

</description>
      <category>twiliohackathon</category>
    </item>
    <item>
      <title>The COVID-19 Retrospective</title>
      <dc:creator>Pedro Lopez</dc:creator>
      <pubDate>Sat, 28 Mar 2020 17:26:26 +0000</pubDate>
      <link>https://forem.com/plopcas/the-covid-19-retrospective-20lj</link>
      <guid>https://forem.com/plopcas/the-covid-19-retrospective-20lj</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tJYwRvFJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/the-covid-19-retrospective.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tJYwRvFJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/the-covid-19-retrospective.jpg" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In an attempt to lighten the mood a bit during this difficult time, I put together a new retrospective technique inspired by the latest developments on COVID-19 and what we know about how to fight it. Keep reading if you want to know more.&lt;/p&gt;

&lt;p&gt;Like in previous posts, I use &lt;a href="https://miro.com"&gt;miro&lt;/a&gt; as a virtual whiteboard. This is now more important than ever given the lockdown restrictions in most countries around the world, so chances are that your team is working fully remotely at the minute.&lt;/p&gt;

&lt;h4&gt;
  
  
  Set the stage
&lt;/h4&gt;

&lt;p&gt;Divide the board in 6 sections like in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dMjTI1Kr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/the-covid-19-retrospective-2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dMjTI1Kr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/the-covid-19-retrospective-2.jpg" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consider adding an ice-breaker as well to warm things up.&lt;/p&gt;

&lt;h4&gt;
  
  
  Gather data (10 min)
&lt;/h4&gt;

&lt;p&gt;Give participants 7 minutes to write down their thoughts on virtual post-it notes in the five sections allocated for it. The 6th one is just for the facilitator to take notes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What are our biggest challenges?&lt;/strong&gt; Like with Coronavirus, teams face difficult challenges that need to be explicitely called out and discussed to ensure alignment and enable continuous improvement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What are our main pain points?&lt;/strong&gt; Like staying at home for a few weeks to fight a virus that spreads easily, teams suffer from technical debt, processes that require more than they should or organisational issues that get in the way. Use this section to write down all those things that are keeping you awake at night. Note that this section differs from the one above in that challenges are things we need to achieve in order to move forward, whereas pain points are typically a consequence of past decisions or contextual circumstances, but based on things that have happened already.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What quick wins will make us succeed?&lt;/strong&gt; Small things like washing your hands can have a huge impact if done right. Think of all the short term things you can do now that will take you closer to your long term goals further down the line. Focus on low hanging fruits here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What will make us succeed in the long run?&lt;/strong&gt; For what we know, even at record breaking speed, a vaccine for Coronavirus is not likely to be available for at least another 18 months. Yet, we need to start working on it now because it's the right thing to do and it will had the biggest long term impact. Similarly, what things does your team need to start working on now that will pay off in a few months.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What should we avoid?&lt;/strong&gt; At the moment, you should only travel if your journey is absolutely essential. Anything else will mean you are increasing the risk of spreading the virus and affecting key workers like healthcare professionals, that are trying to get to their workplaces. Similarly, what things does your team need to avoid as you move forward? These are not pain points from the past, and not necessarily challenges that you know you'll have to overcome, but rather things that you know already will get in the way if they materialise. Include here risks that you are aware of.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Generate insights (30 min)
&lt;/h4&gt;

&lt;p&gt;It's time to brainstorm and generate lots of ideas, but in the interest of time, filter first so that you can focus on the most relevant ones.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go through the notes and cluster similar topics.&lt;/li&gt;
&lt;li&gt;Give participants 5 votes each and set a 3 minute timer.&lt;/li&gt;
&lt;li&gt;Start discussing from the most voted idea.&lt;/li&gt;
&lt;li&gt;Ask questions to trigger conversations if they don't flow naturally e.g. why did you vote this note? what did you mean by X when you wrote it down? Is this related to a particular event that happened recently? How have you seen this apply in previous experiences? If you had unlimited resources, how would you tackle it?&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Decide what to do (10 min)
&lt;/h4&gt;

&lt;p&gt;For each discussion, make sure that you identify potential actions for the team to work on in the next iteration. &lt;strong&gt;Each action must have an owner&lt;/strong&gt;. You can do this as you generate insights in the previous step, no need to wait.&lt;/p&gt;

&lt;p&gt;Use some time at the end to ask people to sign up for the unassigned actions, and wrap things up by summarising the main points that were discussed as well as the final set of outcomes.&lt;/p&gt;




&lt;p&gt;I hope this is helpful. Take care, stay safe and until next time 👋&lt;/p&gt;

</description>
      <category>agile</category>
      <category>retrospective</category>
      <category>covid19</category>
      <category>coronavirus</category>
    </item>
    <item>
      <title>A Saint Patrick's Day Inspired Retrospective</title>
      <dc:creator>Pedro Lopez</dc:creator>
      <pubDate>Tue, 10 Mar 2020 08:00:00 +0000</pubDate>
      <link>https://forem.com/plopcas/a-saint-patrick-s-inspired-retrospective-3o73</link>
      <guid>https://forem.com/plopcas/a-saint-patrick-s-inspired-retrospective-3o73</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yud3fQWo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/a-saint-patricks-themed-retrospective.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yud3fQWo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/a-saint-patricks-themed-retrospective.jpg" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Saint Patrick's Day is around the corner. The 17th of March is celebrated in green and gold all around the world. I thought it might be fun to design a retrospective based on this festivity.&lt;/p&gt;

&lt;p&gt;I use &lt;a href="https://miro.com"&gt;miro&lt;/a&gt; as a virtual whiteboard. It's a visual collaboration tool that makes it very easy for remote teams to share and organise ideas. Perfect for retrospectives!&lt;/p&gt;

&lt;p&gt;If this is not your first retrospective, take 5 minutes to review actions for previous ones.&lt;/p&gt;

&lt;h4&gt;
  
  
  The layout
&lt;/h4&gt;

&lt;p&gt;Divide the board in three sections like in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--En-BTCax--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/a-saint-patricks-themed-retrospective-2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--En-BTCax--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/a-saint-patricks-themed-retrospective-2.jpg" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Trinity and the Shamrock&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first legend of Saint Patrick says he used a shamrock to explain the Holy Trinity to the Irish back in the 5th century.&lt;/p&gt;

&lt;p&gt;Let's use that analogy to discuss three fundamental areas that need to be considered by high performing teams, Technology, Processes and People.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Technology: which technologies are we using at the moment that help us achieve our goals? which tools and patterns?&lt;/li&gt;
&lt;li&gt;Process: which processes help us be efficient and keep us on our toes?&lt;/li&gt;
&lt;li&gt;People: take a moment to shout out any remarkable things your team mates did during the last iteration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Give participants 5 minutes to write down as many notes as they can in each of the categories.&lt;/em&gt;&lt;em&gt;Review notes and cluster similar topics to simplify the discussion later.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Banishing all the Snakes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The second legend of Saint Patrick says he banished all the snakes from the island, chasing them into the sea.&lt;/p&gt;

&lt;p&gt;In this section participants should focus on all the things that are affecting team performance and should be “bannished into the sea”. Feel free to focus on similar areas than the ones above i.e. Technology, Process and People, but do not limit the list to those. For example, you might want to include incidents or events that happened in the last iteration.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Give participants 5 minutes to write down as many notes as they can in each of the categories.&lt;/em&gt;&lt;em&gt;Review notes and cluster similar topics to simplify the discussion later.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Walking Stick grows into a Tree&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The third legend of Saint Patrick says he thrust his walking stick into the ground wherever he was evangelising, and at the place now known as Aspatria (ash of Patrick), the message of the dogma took so long to get through to the people there that the stick had taken root by the time he was ready to move on.&lt;/p&gt;

&lt;p&gt;You will use this last section to capture actions that will help the team take root and grow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Voting and discussion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run a poll to identify the most relevant clusters. Discuss focusing on two aspects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Situation: what's the reason behind the notes? what is the context?&lt;/li&gt;
&lt;li&gt;Action: what can we do to leverage a strength even more or mitigate a recurring issue? How can we improve our tools and processes?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;End the meeting by making sure each action has an owner. And if it's the end of the day, maybe go to the pub and grab a traditional Irish beverage. Cheers! 🍻&lt;/p&gt;

</description>
      <category>tools</category>
      <category>techniques</category>
      <category>retrospectives</category>
      <category>agile</category>
    </item>
    <item>
      <title>Mastering Pair Programming in 5 Minutes</title>
      <dc:creator>Pedro Lopez</dc:creator>
      <pubDate>Sun, 08 Mar 2020 16:41:21 +0000</pubDate>
      <link>https://forem.com/plopcas/mastering-pair-programming-in-5-minutes-2da</link>
      <guid>https://forem.com/plopcas/mastering-pair-programming-in-5-minutes-2da</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6zM-42r6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/mastering-pair-programming-in-5-minutes.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6zM-42r6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://retrolog.io/images/mastering-pair-programming-in-5-minutes.jpg" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This post is heavily based on &lt;a href="https://martinfowler.com/articles/on-pair-programming.html"&gt;https://martinfowler.com/articles/on-pair-programming.html&lt;/a&gt; (38 min read). That is, however, a very long (yet very good) article. For those of us that can't or don't want to afford spending that long, I collated its main points and added a few twists of my own. I hope it's useful.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why bother?
&lt;/h4&gt;

&lt;p&gt;According to some studies e.g. &lt;a href="https://collaboration.csc.ncsu.edu/laurie/Papers/XPSardinia.PDF,"&gt;https://collaboration.csc.ncsu.edu/laurie/Papers/XPSardinia.PDF,&lt;/a&gt; some of the most significant benefits of pair programming are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Many mistakes get caught as they are being typed in rather than in QA test or in the field (continuous code reviews)&lt;/li&gt;
&lt;li&gt;The end defect content is statistically lower (continuous code reviews)&lt;/li&gt;
&lt;li&gt;The designs are better and code length shorter (ongoing brainstorming and pair relaying)&lt;/li&gt;
&lt;li&gt;The team solves problems faster (pair relaying)&lt;/li&gt;
&lt;li&gt;People learn significantly more, about the system and about software development (line-of-sight learning)&lt;/li&gt;
&lt;li&gt;The project ends up with multiple people understanding each piece of the system&lt;/li&gt;
&lt;li&gt;People learn to work together and talk more often together, giving better information flow and team dynamics&lt;/li&gt;
&lt;li&gt;People enjoy their work more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The development cost for these benefits is not the 100% that might be expected, but approximately 15%. This is repaid in shorter and less expensive testing, quality assurance, and field support.&lt;/p&gt;

&lt;h4&gt;
  
  
  How to pair
&lt;/h4&gt;

&lt;p&gt;When the task involves coding, three options:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Driver and Navigator&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Driver is the person with the keyboard focused on completing the immediate goal at hand, temporarily ignoring larger issues. Should talk through what they are doing while doing it.&lt;/li&gt;
&lt;li&gt;Navigator is the observer while the driver types, reviews the code on-the-go, gives directions and shares thoughts. Keeps an eye on the larger issues, potential bugs and makes notes for next steps and obstacles.&lt;/li&gt;
&lt;li&gt;Driver thinks &lt;strong&gt;tactically&lt;/strong&gt; and is detail-oriented while the Navigator thinks &lt;strong&gt;strategically&lt;/strong&gt; and has the bigger picture in mind.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with a reasonably well-defined task&lt;/li&gt;
&lt;li&gt;Agree on one tiny goal at a time e.g. defined by a unit test or a commit message&lt;/li&gt;
&lt;li&gt;Switch roles regularly&lt;/li&gt;
&lt;li&gt;As Navigator, avoid tactical thinking, you'll be tempted! Make notes on potential obstacles and ideas and discuss after the tiny goal is done, so the Driver can stay in the flow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ping Pong&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TDD&lt;/strong&gt; oriented&lt;/li&gt;
&lt;li&gt;Ping - Person A writes a failing test&lt;/li&gt;
&lt;li&gt;Pong - Person B writes the implementation to make the test pass&lt;/li&gt;
&lt;li&gt;Ping - Person B writes a failing test&lt;/li&gt;
&lt;li&gt;Pong - Person A writes the implementation to make the test pass&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with a clearly defined task&lt;/li&gt;
&lt;li&gt;Each Pong can be followed by a code refactoring step done together by both (Red - Green - Refactor)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Strong-Style&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For an idea to go from your head into the computer, it MUST go through someone else's hands&lt;/li&gt;
&lt;li&gt;Particularly useful for &lt;strong&gt;knowledge transfer&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Driver is a novice&lt;/li&gt;
&lt;li&gt;Navigator is much more experienced with the task at hand&lt;/li&gt;
&lt;li&gt;Participants &lt;strong&gt;do not switch positions&lt;/strong&gt; throughout the session&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Driver totally trusts the Navigator and should be comfortable with incomplete understanding&lt;/li&gt;
&lt;li&gt;“Why” questions and challenging the solution should be discussed after the implementation session&lt;/li&gt;
&lt;li&gt;Don't overuse this technique&lt;/li&gt;
&lt;li&gt;Great for initial knowledge transfer but the goal is to transition to the other styles after a while&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the task does not involve coding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Planning&lt;/strong&gt; - what's our goal?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;E.g. pairing on Epic Ownership or aspects that overlap multiple epics&lt;/li&gt;
&lt;li&gt;Understand the problem, read through the story and play back to each other how you understand it to make sure there is alignment&lt;/li&gt;
&lt;li&gt;Clear up any questions or potential misunderstandings with the Produc Owner / Engineering Manager / Epic Owner&lt;/li&gt;
&lt;li&gt;Double check your Definition of Ready to make sure you have everything to get started&lt;/li&gt;
&lt;li&gt;Brainstorm a potential solution, together or individually and then present ideas to each other. If one is more familiar with the domain or technology, take some time to share context.&lt;/li&gt;
&lt;li&gt;Plan your approach, list out the steps to get to the solution you chose and how you will test it. Write them down! so that we can track progress (e.g. in JIRA as subtasks)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Spikes&lt;/strong&gt; - research and explore&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define a list of questions that you need to answer&lt;/li&gt;
&lt;li&gt;Split up, divide and conquer. Alternatively, try to find answers for the same questions separately.&lt;/li&gt;
&lt;li&gt;Search your company's intranet and messaging system, and any other resources you can find&lt;/li&gt;
&lt;li&gt;Read up on concepts that are new to both of you&lt;/li&gt;
&lt;li&gt;Get back together after a previously agreed upon time-box, share and discuss&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Documentation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reflect together if any documentation is necessary for what you've done&lt;/li&gt;
&lt;li&gt;Create a document together. Alternatively, one person creates it, then the other reviews it and “wordsmiths”.&lt;/li&gt;
&lt;li&gt;Pairing reduces the chance of skipping documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For time management you can use the pomodoro technique, small breaks after 25min and longer breaks after 2h.&lt;/p&gt;

&lt;p&gt;Pair rotations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don't stay in the same pair for more than 2-3 days&lt;/li&gt;
&lt;li&gt;This avoids silos, increase collective code ownership, and favours more code review on-the-go&lt;/li&gt;
&lt;li&gt;It also keeps things fresh, particularly when you are working on something tedious and energy-draining&lt;/li&gt;
&lt;li&gt;The person who stays is called the Anchor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plan the day:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pairing requires a certain level of scheduling and calendar coordination&lt;/li&gt;
&lt;li&gt;Start the day by agreeing on how many hours you are going to pair, and whether you need to plan around meetings or other commitments&lt;/li&gt;
&lt;li&gt;If someone is off-sick or on leave, rotate the pair&lt;/li&gt;
&lt;li&gt;Consider leaving some time at the beginning/end of the day for other activities e.g. checking your email or self-studying&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Physical setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make sure both have enough space, chairs included, clear up the desk if necessary&lt;/li&gt;
&lt;li&gt;Decide if you want to use one keyboard or two, same for the mouse. No hard rule, whatever works. Some other factors into play are hygiene and how much space is actually available.&lt;/li&gt;
&lt;li&gt;Consider using screen share on Zoom so that each one can use their own laptop&lt;/li&gt;
&lt;li&gt;Agree on a default the first time, so that you don't have to discuss this every time&lt;/li&gt;
&lt;li&gt;Remote pairing is ok as long as the internet connection is good enough, there is no background noise (use mute otherwise), and both of you agree to it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Celebrate when you have accomplished a task together, you earned it!&lt;/p&gt;

&lt;p&gt;Things to avoid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Drifting apart during the pairing session e.g. reading emails or using your phone. These can come across as disrespectful and distracts you from the task at hand. If you really need to check something, make it transparent, say what you are doing and why&lt;/li&gt;
&lt;li&gt;Micro-managing e.g. “Now type this…", “Now we need to create a class called…", “Press Cmd + Shift O…”&lt;/li&gt;
&lt;li&gt;Impatience, apply the 5-seconds-rule instead (when the Navigator sees something “wrong” and wants to comment, wait at least 5 seconds in case the driver already has it in mind, so that you don't interrupt their flow unnecessarily)&lt;/li&gt;
&lt;li&gt;Keyboard hogging, are you controlling the keyboard all the time? Sharing is caring ❤&lt;/li&gt;
&lt;li&gt;Pairing 8 hours per day, it's not sustainable, it's too exhausting and in practice there are other things you need to do other than coding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is not “THE” right way, try different approaches and find what works for you and your team.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
