<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<title>Yaro&#x27;s blog</title>
	<link href="https://yaro.codes/atom.xml" rel="self" type="application/atom+xml"/>
	<link href="https://yaro.codes"/>
	<generator uri="https://www.getzola.org/">Zola</generator>
	<updated>2024-11-10T00:00:00+00:00</updated>
	<id>https://yaro.codes/atom.xml</id>
	<entry xml:lang="en">
        <title>Biking to Utah lake</title>
        <author><name>Yaroslav Berejnoi</name></author>
		<published>2024-11-10T00:00:00+00:00</published>
		<updated>2024-11-10T00:00:00+00:00</updated>
		<link href="https://yaro.codes/biking-utah-lake/" type="text/html"/>
		<id>https://yaro.codes/biking-utah-lake/</id>
		<content type="html">&lt;p&gt;It wasn&#x27;t long ago I found out that the &lt;a href=&quot;https:&#x2F;&#x2F;www.slc.gov&#x2F;parks&#x2F;parks-division&#x2F;jordan-river-parkway-trail&#x2F;&quot;&gt;Jordan River Parkway Trail&lt;&#x2F;a&gt; in Utah is the longest paved &lt;em&gt;urban&lt;&#x2F;em&gt; trail in the United States (the bold &amp;quot;urban&amp;quot; was not a mistake; there are longer trails in the US that aren&#x27;t urban 😂).&lt;&#x2F;p&gt;
&lt;p&gt;Some websites say it&#x27;s 45+ miles. Some say it 60+. I wonder what the discrepancy is there? Anyway, you can go from Utah Lake all the way to the Great Salt Lake in about in a 58 mile stretch of it. I would love to make that trek someday on my bike, but I decided I would first make an attempt to bike from my house in east Sandy to Utah Lake and back.&lt;&#x2F;p&gt;
&lt;p&gt;Part of the journey would just be heading straight west until I reached the JRT, about 6 miles, and the remainder 21 miles would be on the beautiful meandering trail that&#x27;s fully away from car traffic, aside from a few crossing on the way.&lt;&#x2F;p&gt;
&lt;p&gt;I had planned to take a bus or Frontrunner (our commuter rail system) part of the way back in case I didn&#x27;t feel like biking the entire length, but due to poor planning and the lack of service on Sunday, I missed both the last train and bus.&lt;&#x2F;p&gt;
&lt;p&gt;I want to say I was up for the challenge, but by the time I got to Utah lake, the sun was already setting and it started to get really cold, really fast, which I was also unprepared for.&lt;&#x2F;p&gt;
&lt;p&gt;I did have my bike lights with me, which helped illuminate the trail and made for a really awesome and different experience on the way back. But man, was I cold.&lt;&#x2F;p&gt;
&lt;p&gt;I did make it back home safely, covering just over 54 miles in 5 hours and 20 minutes. The journey on the way back was undoubtedly the slowest; partly due to trying to reduce the wind chill, and partly because JRT to my house is mostly just hill climb.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately, the cold caused a pretty bad flare of dermatitis all over my ears and scalp... but I still think that the trip was worth it! How else would I have been able to get this awesome picture?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;biking_utah_lake&#x2F;utah_lake.webp&quot; alt=&quot;Utah Lake with my bike&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
        <title>Why I love observability</title>
        <author><name>Yaroslav Berejnoi</name></author>
		<published>2024-08-10T00:00:00+00:00</published>
		<updated>2024-08-10T00:00:00+00:00</updated>
		<link href="https://yaro.codes/why-i-love-obervability/" type="text/html"/>
		<id>https://yaro.codes/why-i-love-obervability/</id>
		<content type="html">&lt;h2 id=&quot;why-i-love-observability&quot;&gt;Why I love observability&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;sub&gt;And why I think operational excellence is the most important pillar of the well architected framework&lt;&#x2F;sub&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-5-pillars-of-the-well-architected-framework&quot;&gt;The 5 pillars of the well architected framework&lt;&#x2F;h3&gt;
&lt;p&gt;Here are 4 of the pillars:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Make sure it&#x27;s performant.&lt;&#x2F;li&gt;
&lt;li&gt;Build it with cost optimization in mind.&lt;&#x2F;li&gt;
&lt;li&gt;Make sure it&#x27;s reliable.&lt;&#x2F;li&gt;
&lt;li&gt;Make it secure.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The foundation for all the other pillars of the Well Architected Framework is observability, which is part of the 5th operational excellence pillar. You can&#x27;t quantify your success in any of these other categories without having some baseline; some starting point to show &lt;em&gt;how much&lt;&#x2F;em&gt; you&#x27;ve improved.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s revisit the other pillars:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Make sure it&#x27;s performant. How performant?&lt;&#x2F;li&gt;
&lt;li&gt;Build it with cost optimization in mind. Where can we save costs?&lt;&#x2F;li&gt;
&lt;li&gt;Make sure it&#x27;s reliable. What&#x27;s our current uptime?&lt;&#x2F;li&gt;
&lt;li&gt;Make it secure. How do we know when and if there is an attack?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;collect-metrics-from-the-very-beginning&quot;&gt;Collect metrics from the very beginning&lt;&#x2F;h3&gt;
&lt;p&gt;We all need to build software that solves real business problems and we needed it yesterday. I get it. The last thing anyone wants to do is spend time writing code just collect metrics about the &lt;em&gt;real&lt;&#x2F;em&gt; code that&#x27;s solving &lt;em&gt;real&lt;&#x2F;em&gt; problems. And let me tell you, metrics are a real business problem, and it&#x27;s up to you to convince stakeholders that this effort is not for naught.&lt;&#x2F;p&gt;
&lt;p&gt;The wonderful thing is that it&#x27;s a lot easier to add telemetry collecting capabilities to your project than you probably think. Through the widely adopted and supported OpenTelemetry framework, there is likely a package out there for your language of choice that adds auto-instrumentation capabilities to many of the dependencies that you&#x27;re using.&lt;&#x2F;p&gt;
&lt;p&gt;The only initial startup cost might be to figure out where you are going to be dumping all the telemetry data. Lucky for us, many telemetry collectors are adopting the OpenTelemetry specification (OTel).&lt;&#x2F;p&gt;
&lt;p&gt;While working at my last job, our cloud provider of choice was Azure. All we had to do was install OpenTelemetry instrumentation libraries, which would hook into and collected various signals from logging, http client, Azure SDK, and other libraries, and the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Azure&#x2F;azure-sdk-for-python&#x2F;tree&#x2F;azure-monitor-opentelemetry_1.6.1&#x2F;sdk&#x2F;monitor&#x2F;azure-monitor-opentelemetry-exporter#microsoft-opentelemetry-exporter-for-azure-monitor&quot;&gt;Azure Monitor Open Telemetry exporter&lt;&#x2F;a&gt; to get it in Application Insights&#x2F;Diagnostics logs for querying and visualization.&lt;&#x2F;p&gt;
&lt;p&gt;Not in the cloud? Well you can dump OpenTelemetry data into Grafana, or a number of other destinations as well.&lt;&#x2F;p&gt;
&lt;p&gt;Is every scenario this easy? Well no. You might find that you want to instrument some code you wrote, or some 3rd party library yourself. Or even some code that runs in a unique environment (we did it for instrumenting Databricks python workflows!). For that, there is the Open Telemetry SDK. But more than likely, you can get started instrumenting libraries that are already supported and reap huge benefits.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;correlate-your-data&quot;&gt;Correlate your data&lt;&#x2F;h3&gt;
&lt;p&gt;Collecting metrics from various pieces in your architecture is useful on it&#x27;s own. But chances are those pieces are talking to each other and you want to see how they all tie together in the bigger picture. Maybe you have a complex workflow that start a service A and ends at service Z. Did a failure happen somewhere in the middle and you have no idea where it is? You need &lt;a href=&quot;https:&#x2F;&#x2F;opentelemetry.io&#x2F;docs&#x2F;concepts&#x2F;context-propagation&#x2F;&quot;&gt;Context Propagation&lt;&#x2F;a&gt;, which will start the tracing context at one end, and capture everything in between to the end, so long as the same Trace Parent (trace id and parent span id) is passed along between each service boundary.&lt;&#x2F;p&gt;
&lt;p&gt;In the end, you should be able to query all the signals that were collected, using a single trace id.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;an-analog-for-your-architecture&quot;&gt;An analog for your architecture&lt;&#x2F;h3&gt;
&lt;p&gt;Once we had all of infrastructure instrumented and the data was landing in a centralized location, we were able to visualize all the components, and how they were connected in Azure Monitor.&lt;&#x2F;p&gt;
&lt;p&gt;All of our logs, metrics, etc. became the &lt;em&gt;analog&lt;&#x2F;em&gt; for our infrastructure. We could start pinpointing where bottlenecks were happening, where exceptions were being thrown, and drill down to the exact lines of code with all the context that came before it.&lt;&#x2F;p&gt;
&lt;p&gt;At the point, building alerts on top of these signals is easy. And you can start monitoring the performance, cost, reliability, and security of your system over time, and focus your engineering teams to tackle &lt;em&gt;known&lt;&#x2F;em&gt; problems backed by &lt;em&gt;real&lt;&#x2F;em&gt; data.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-to-get-started&quot;&gt;How to get started&lt;&#x2F;h3&gt;
&lt;p&gt;With the &lt;a href=&quot;https:&#x2F;&#x2F;opentelemetry.io&#x2F;docs&#x2F;concepts&#x2F;observability-primer&#x2F;&quot;&gt;observability primer&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
        <title>What is a hydrometer and how do we build one?</title>
        <author><name>Yaroslav Berejnoi</name></author>
		<published>2022-10-02T00:00:00+00:00</published>
		<updated>2022-10-02T00:00:00+00:00</updated>
		<link href="https://yaro.codes/building-a-hydrometer-2/" type="text/html"/>
		<id>https://yaro.codes/building-a-hydrometer-2/</id>
		<content type="html">&lt;h2 id=&quot;what-is-a-hydrometer&quot;&gt;What is a hydrometer?&lt;&#x2F;h2&gt;
&lt;p&gt;A hydrometer is a device that measures the &lt;strong&gt;relative density&lt;&#x2F;strong&gt; of liquids. In beer brewing, a brewer takes a reading &lt;em&gt;before&lt;&#x2F;em&gt; fermentation to find out how much sugar was extracted from the malt into water, and then another reading &lt;em&gt;after&lt;&#x2F;em&gt; fermentation when the yeast has converted much of the sugar into alcohol and CO2. The difference between these two measurements gives you a fairly accurate alcohol content reading for the beer.&lt;&#x2F;p&gt;
&lt;p&gt;Because relative density is defined as the &lt;strong&gt;ratio&lt;&#x2F;strong&gt; of the densities of two different liquids, non-fermented beer, or &lt;em&gt;wort&lt;&#x2F;em&gt;, and water in our case, water is taken to be 1.000. When a hydrometer reads 1.050, this means the density of the wort is 1.050 times that of water.&lt;&#x2F;p&gt;
&lt;p&gt;A hydrometer can look like many things, but a very common one would look like this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;building_a_hydrometer&#x2F;twaddels_hydrometer.webp&quot; alt=&quot;Twaddel Hydrometer&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Isaac Hopkins (Q106121459), Public domain, via Wikimedia Commons&lt;&#x2F;p&gt;
&lt;p&gt;This one is a glass tube, with a ballast at the bottom to give it upward stability when placed in water. Inside the glass tube is a paper scale that reads the relative density of the liquid when aligned with the surface of the liquid. The scale usually indicates at what temperature the scale was calibrated to. It is recommended that measurements are also taken at that same temperature but there various calculators out there that can adjust for temperature differences.&lt;&#x2F;p&gt;
&lt;p&gt;Questions thus far:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Does atmospheric pressure affect relative density readings?&lt;&#x2F;li&gt;
&lt;li&gt;What is the relationship of density and temperature, and how do we account for that in our readings?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A hydrometer can also have many names, such as an Alcoholometer, Lactometer, Saccharometer etc. They all have varying scales and units depending on what industry they&#x27;re applicable to, but all operate on the same principle: &lt;strong&gt;Archimedes&#x27; Principle&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;A body at rest in a fluid is acted upon by a force pushing upward called the buoyant force, which is equal to the weight of the fluid that the body displaces. If the body is completely submerged, the volume of fluid displaced is equal to the volume of the body. If the body is only partially submerged, the volume of the fluid displaced is equal to the volume of the part of the body that is submerged. &lt;a href=&quot;https:&#x2F;&#x2F;www.britannica.com&#x2F;science&#x2F;Archimedes-principle&quot;&gt;Britannica&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;how-do-we-build-an-iot-enabled-hydrometer&quot;&gt;How do we build an IOT enabled hydrometer?&lt;&#x2F;h2&gt;
&lt;p&gt;While the hydrometer pictured above operates on vertical displacement and manual eye-seeing measurement, a tool I already own works by taking the &lt;strong&gt;tilt&lt;&#x2F;strong&gt; or &lt;strong&gt;incline&lt;&#x2F;strong&gt; of the device suspended in the liquid &lt;a href=&quot;https:&#x2F;&#x2F;tilthydrometer.com&#x2F;products&#x2F;copy-of-tilt-floating-wireless-hydrometer-and-thermometer-for-brewing&quot;&gt;Tilt Hydrometer&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The goal of this project is to build a similar device.&lt;&#x2F;p&gt;
&lt;p&gt;The benefits of this device include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;We can drop it into the fermenter and leave it in there. This enables us to monitor the health of our fermentation at any interval we choose, and know when fermentation is done.&lt;&#x2F;li&gt;
&lt;li&gt;We limit the exposure of oxygen and unwanted microbes to our beer compared to taking manual samples.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;how-can-we-get-relative-gravity-using-inclination&quot;&gt;How can we get relative gravity using inclination?&lt;&#x2F;h3&gt;
&lt;p&gt;Applying Archimedes&#x27; principle, we know that if we drop an object with known mass&#x2F;density in water (assuming it doesn&#x27;t completely submerge), it will sink &lt;em&gt;less&lt;&#x2F;em&gt; in liquid that has higher density. I.e. the volume of the submerged portion of the object will be less.&lt;&#x2F;p&gt;
&lt;p&gt;From observation of dropping things into water, we&#x27;ve seen that some objects do not float completely vertically, or horizontally. An object might float with some inclination. Likely because the object is top-heavy.&lt;&#x2F;p&gt;
&lt;p&gt;The assumption, or hypothesis, is that for this &lt;em&gt;non-uniform&lt;&#x2F;em&gt; object, it&#x27;s inclination will be &lt;em&gt;greater&lt;&#x2F;em&gt; in denser liquids as less of it&#x27;s volume is submerged under the liquid, and it&#x27;s center of mass acts to tip it over.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-device-can-we-use-to-measure-inclination&quot;&gt;What device can we use to measure inclination?&lt;&#x2F;h3&gt;
&lt;p&gt;Accelerometers are cheap and very useful sensors for measuring inclination. Here is a resource I found that seems very well written: &lt;a href=&quot;https:&#x2F;&#x2F;www.analog.com&#x2F;en&#x2F;app-notes&#x2F;an-1057.html&quot;&gt;Analog, Accelerometer application&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;required-math-and-physics-concepts&quot;&gt;Required math and physics concepts&lt;&#x2F;h3&gt;
&lt;p&gt;From some quick online searching, the study of &lt;strong&gt;hydrostatics&lt;&#x2F;strong&gt; seems applicable:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Branch of physics that deals with the characteristics of fluids at rest, particularly with the pressure in a fluid or exerted by a fluid (gas or liquid) on an immersed body. &lt;a href=&quot;https:&#x2F;&#x2F;www.britannica.com&#x2F;science&#x2F;hydrostatics&quot;&gt;Britannica&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Glossing over some of the concepts from various searches, all of these seem to apply:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Center of mass&lt;&#x2F;li&gt;
&lt;li&gt;Moments of inertia&lt;&#x2F;li&gt;
&lt;li&gt;Buoyancy&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It&#x27;s been a while since I&#x27;ve seen these concepts, but I found some textbook sources that should help out (All on libretext.org!):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;phys.libretexts.org&#x2F;Bookshelves&#x2F;Classical_Mechanics&#x2F;Classical_Mechanics_(Tatum)&quot;&gt;Classical Mechanics, Tatum&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Particularly chapters 1 (Centers of Mass), 2 (Moments of Inertia), and 16 (Hydrostatics).&lt;&#x2F;li&gt;
&lt;li&gt;Chapter 16 even has an example problem explaining the tendency for logs to fill up with water, and start to right themselves vertically as their density approaches that of water. Sounds very similar to the problem we&#x27;re trying to solve!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Here is a chapter from a calculus book that covers density, mass, and center of mass: &lt;a href=&quot;https:&#x2F;&#x2F;math.libretexts.org&#x2F;Under_Construction&#x2F;Purgatory&#x2F;Book%3A_Active_Calculus_(Boelkins_et_al.)&#x2F;06%3A_Using_Definite_Integrals&#x2F;6.03%3A_Density_Mass_and_Center_of_Mass&quot;&gt;Active Calculus, using definite integrals for density, mass, and center of mass&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;And another book to cross-study calculus: &lt;a href=&quot;https:&#x2F;&#x2F;math.libretexts.org&#x2F;Bookshelves&#x2F;Calculus&#x2F;Book%3A_Calculus_(OpenStax)&quot;&gt;Calculus, Gilbert Strang &amp;amp; Edwin  Herman&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;There is quite a bit to learn in what was just outlined here. If you&#x27;re not comfortable with all the concepts like me, take some time to learn from the materials or find some alternatives! My next post(s) will be summarizing some of the learnings, determining if the assumptions made were correct, and answering the questions above. Later posts will dive into some code, microcontrollers, and the sensors that will be used for the project.&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
        <title>Bridging the gap: Building an IOT Hydrometer</title>
        <author><name>Yaroslav Berejnoi</name></author>
		<published>2022-09-27T00:00:00+00:00</published>
		<updated>2022-09-27T00:00:00+00:00</updated>
		<link href="https://yaro.codes/building-a-hydrometer-1/" type="text/html"/>
		<id>https://yaro.codes/building-a-hydrometer-1/</id>
		<content type="html">&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;building_a_hydrometer&#x2F;project.webp&quot; alt=&quot;esp8266 with mpu6050&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;building_a_hydrometer&#x2F;hydrometer.webp&quot; alt=&quot;reading a hydrometer&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bridging-the-gap-between-tutorial-following-and-making-fully-featured-projects&quot;&gt;Bridging the gap between tutorial following and making fully featured projects&lt;&#x2F;h2&gt;
&lt;p&gt;The most frustrating thing about programming, and engineering in general, is that there is a load of resources on the two far ends of this spectrum: basic tutorials and amazing projects that others have built.&lt;&#x2F;p&gt;
&lt;p&gt;The bridge in the middle is no doubt the hardest, and most time consuming part of the process: knowledge and problem solving.&lt;&#x2F;p&gt;
&lt;p&gt;What motivated this guide are three things:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Bridging the gap for myself in the microcontroller, low-level programming, and applied mathematics space, and&lt;&#x2F;li&gt;
&lt;li&gt;Helping others bridge the gap (like a coding tutorial that you&#x27;re used to, but with a heavy emphasis on a tutorial to &lt;em&gt;learning&lt;&#x2F;em&gt; and &lt;em&gt;applying those learnings&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;I like to brew beer, and devices like the &lt;a href=&quot;https:&#x2F;&#x2F;tilthydrometer.com&#x2F;&quot;&gt;Tilt Hydrometer&lt;&#x2F;a&gt; really inspired me&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Since I started thinking about this project a week ago, I&#x27;ve tried &lt;em&gt;really&lt;&#x2F;em&gt; hard to keep myself from searching &amp;quot;diy iot hydrometer&amp;quot;, or &amp;quot;building a hydrometer using an accelerometer&amp;quot;. I think that discipline is important; remember we are trying to arrive at the solution ourselves, no matter the struggle. The goal is to build the intuition and skills required for bridging the gap.&lt;&#x2F;p&gt;
&lt;p&gt;I encourage you to do the same, and read from the start to the end of this series without peeking. Try solving the problems yourself, try messing with the code, math, etc.&lt;&#x2F;p&gt;
&lt;p&gt;I only have a vague idea of how to solve this problem. It&#x27;s a multifaceted problem and one that motivates me. 
This might not be the same for you, but hopefully my approach can lead you to solve a problem you might be interested in.&lt;&#x2F;p&gt;
&lt;p&gt;I am not a beginner in the software space, but my background is mostly in .net APIs, Angular front-end development, Azure stack of cloud development and deployments, and some Powershell scripting thrown in there.&lt;&#x2F;p&gt;
&lt;p&gt;Where I lack and what I intend it learn is:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;C&#x2F;C++ and low-level programming in general&lt;&#x2F;li&gt;
&lt;li&gt;Arduino, microcontrollers and interfacing with the wide variety of sensors out there and their protocols&lt;&#x2F;li&gt;
&lt;li&gt;A deep understanding of mathematics, and the application of (i.e &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Applied_mathematics&quot;&gt;Applied Mathematics&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So hopefully this guide is one that comes from experience, but more importantly &lt;em&gt;inexperience&lt;&#x2F;em&gt; so that you may feel like we are in the same shoes trying to bridge the gap. There are many concepts I don&#x27;t know, so you will see many explanations and all the resources from which they were derived. I intend to use all open source, or freely and easily accessible resources.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s begin.&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
        <title>Cargo workspace dependency woes</title>
        <author><name>Yaroslav Berejnoi</name></author>
		<published>2021-12-31T00:00:00+00:00</published>
		<updated>2021-12-31T00:00:00+00:00</updated>
		<link href="https://yaro.codes/cargo-workspace-woes/" type="text/html"/>
		<id>https://yaro.codes/cargo-workspace-woes/</id>
		<content type="html">&lt;p&gt;They said learning rust would feel like a constant battle with the compiler. They were right. Most of the time it&#x27;s because of user error with a nice little message telling you how to fix the error. Nice. Easy.
When it&#x27;s cargo yelling at you, it&#x27;s because of some dependency conflict that is the fault of one of the many libraries in your dependency tree. Fun...&lt;&#x2F;p&gt;
&lt;p&gt;In this case I was working on adding the second GUI to my &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YaroBear&#x2F;minesweeper-rs&quot;&gt;minesweeper-rs project&lt;&#x2F;a&gt;, this time with the implementation using the Bevy game engine. I structured my project using &lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;book&#x2F;ch14-03-cargo-workspaces.html&quot;&gt;cargo workspaces&lt;&#x2F;a&gt; so I wouldn&#x27;t have to recompile the shared minesweeper-logic library for every GUI that I would build, and possibly other libraries that would be shared between Nannou, Bevy etc.&lt;&#x2F;p&gt;
&lt;p&gt;This is the error I ran into right as I added the minesweeper-bevy binary project to the workspace:
&lt;img src=&quot;&#x2F;images&#x2F;cargo_workspace_woes&#x2F;nannou_bevy_error.png&quot; alt=&quot;nannou and bevy dependency error&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Nannou depends on &lt;strong&gt;wgpu 0.11.0&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Which has &amp;quot;loose&amp;quot; dependency on &lt;strong&gt;wasm-bindgen ^0.2.76&lt;&#x2F;strong&gt; (&amp;gt;= 0.2.76 and &amp;lt; 0.3.0)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Bevy depends on &lt;strong&gt;wgpu 0.7.0&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Which has a &amp;quot;strict&amp;quot; dependency on &lt;strong&gt;wasm-bindgen =0.2.69&lt;&#x2F;strong&gt; (has to be 0.2.69)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Cargo will attempt to pick a package that solves both of the requirements for &lt;strong&gt;wasm-bindgen&lt;&#x2F;strong&gt;, but &lt;em&gt;not&lt;&#x2F;em&gt; if they are constrained in the same compatibility range. In other words, cargo will pick &lt;em&gt;only one&lt;&#x2F;em&gt; version &lt;strong&gt;0.2.&lt;&#x2F;strong&gt;* that will satisfy the minor SemVer for both. But since &lt;strong&gt;wgpu 0.7.0&lt;&#x2F;strong&gt; has a strict dependency on a specific patch version, it goes with that one. This leaves &lt;strong&gt;wgpu 0.11.0&lt;&#x2F;strong&gt; requirements unsatisfied.&lt;&#x2F;p&gt;
&lt;p&gt;For more, see &lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;cargo&#x2F;reference&#x2F;resolver.html#semver-compatibility&quot;&gt;semver compatibility&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Theoretically, &lt;strong&gt;wgpu 0.7.0&lt;&#x2F;strong&gt; shouldn&#x27;t have such strict dependency on a patched version, as patches usually only include bug fixes and the like, and shouldn&#x27;t break existing features with future patches. That&#x27;s the definition of SemVer. O&#x27;well 🤷‍♂️.&lt;&#x2F;p&gt;
&lt;p&gt;To get around this, I think i&#x27;ll just get rid of the cargo workspace.&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
        <title>Rust&#x27;s Drop trait and drop function</title>
        <author><name>Yaroslav Berejnoi</name></author>
		<published>2021-07-25T00:00:00+00:00</published>
		<updated>2021-07-25T00:00:00+00:00</updated>
		<link href="https://yaro.codes/rust-drop-trait-and-function/" type="text/html"/>
		<id>https://yaro.codes/rust-drop-trait-and-function/</id>
		<content type="html">&lt;p&gt;Rust has been on my mind for the last couple of weeks and I wanted to get back into it (after wanting to get into it over a year ago). This blog has also been on my mind lately (and also left on the back burner over a year ago)... So let&#x27;s get to it. This is just a simple note for myself that I can refer to later and solidify the concept.&lt;&#x2F;p&gt;
&lt;p&gt;The purpose of the &lt;strong&gt;Drop&lt;&#x2F;strong&gt; trait is to relinquish memory on the heap that the implementor instance owns. For example, if your object references any file, network, or database connection. The trait only has one method, drop, and is called automatically when the object goes out of scope.&lt;&#x2F;p&gt;
&lt;p&gt;Similarly, there is a &lt;strong&gt;drop&lt;&#x2F;strong&gt; function in the &lt;strong&gt;std::mem&lt;&#x2F;strong&gt; crate which has a super simple implementation:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rs&quot; style=&quot;background-color:#282c34;color:#abb2bf;&quot; class=&quot;language-rs &quot;&gt;&lt;code class=&quot;language-rs&quot; data-lang=&quot;rs&quot;&gt;&lt;span style=&quot;font-style:italic;color:#5c6370;&quot;&gt;&#x2F;&#x2F; std::mem::drop
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c678dd;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61afef;&quot;&gt;drop&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;T&amp;gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;_x&lt;&#x2F;span&gt;&lt;span&gt;: T) { }
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;An empty function body, that&#x27;s literally it. Since the variable is &lt;strong&gt;moved&lt;&#x2F;strong&gt; into the drop function into a new scope &lt;strong&gt;{ }&lt;&#x2F;strong&gt;, the variable is deallocated immediately after the function is called.&lt;&#x2F;p&gt;
&lt;p&gt;This function can be used to deallocate memory on the heap manually rather than automatically when it goes out of scope.&lt;&#x2F;p&gt;
&lt;p&gt;Here is a quick scope example&#x2F;reminder from &amp;quot;Rust by Example&amp;quot;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rs&quot; style=&quot;background-color:#282c34;color:#abb2bf;&quot; class=&quot;language-rs &quot;&gt;&lt;code class=&quot;language-rs&quot; data-lang=&quot;rs&quot;&gt;&lt;span style=&quot;font-style:italic;color:#5c6370;&quot;&gt;&#x2F;&#x2F; raii.rs
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c678dd;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61afef;&quot;&gt;create_box&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6370;&quot;&gt;&#x2F;&#x2F; Allocate an integer on the heap
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c678dd;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; _box1 = Box::new(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d19a66;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c678dd;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6370;&quot;&gt;&#x2F;&#x2F; `_box1` is destroyed here, and memory gets freed
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c678dd;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61afef;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6370;&quot;&gt;&#x2F;&#x2F; Allocate an integer on the heap
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c678dd;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; _box2 = Box::new(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d19a66;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c678dd;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6370;&quot;&gt;&#x2F;&#x2F; A nested scope:
&lt;&#x2F;span&gt;&lt;span&gt;    {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6370;&quot;&gt;&#x2F;&#x2F; Allocate an integer on the heap
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c678dd;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; _box3 = Box::new(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d19a66;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c678dd;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6370;&quot;&gt;&#x2F;&#x2F; `_box3` is destroyed here, and memory gets freed
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6370;&quot;&gt;&#x2F;&#x2F; Creating lots of boxes just for fun
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6370;&quot;&gt;&#x2F;&#x2F; There&amp;#39;s no need to manually free memory!
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c678dd;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;_ in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d19a66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c678dd;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d19a66;&quot;&gt;1_000 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#56b6c2;&quot;&gt;create_box&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6370;&quot;&gt;&#x2F;&#x2F; `_box2` is destroyed here, and memory gets freed
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice how we boxed the integer instead of creating an integer on the stack. The &lt;strong&gt;Drop&lt;&#x2F;strong&gt; trait only applies to memory allocated on the heap, and cannot be implemented by anything that implements the &lt;strong&gt;Copy&lt;&#x2F;strong&gt; trait (integers and other scalar types).&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
        <title>Setting up a simple team project workflow on github</title>
        <author><name>Yaroslav Berejnoi</name></author>
		<published>2020-07-19T00:00:00+00:00</published>
		<updated>2020-07-19T00:00:00+00:00</updated>
		<link href="https://yaro.codes/setting-up-a-simple-team-project-workflow-on-github/" type="text/html"/>
		<id>https://yaro.codes/setting-up-a-simple-team-project-workflow-on-github/</id>
		<content type="html">&lt;p&gt;Before I started working as developer full-time there were many things that were not obvious to me.
One of those things is how to structure a workflow for a project. Sure, simple projects where I was the only person touching the code may seem overkill for some of the things listed in this blog post. But I promise it will be worth your time upfront and save time for your future self. These guidelines will be even more important for &lt;strong&gt;team projects&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;at-the-very-minimum&quot;&gt;At the very minimum&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;1-branch-policies&quot;&gt;1. Branch policies&lt;&#x2F;h3&gt;
&lt;p&gt;If you&#x27;re working on a team project, can you commit changes and push directly to &lt;strong&gt;master&#x2F;main&lt;&#x2F;strong&gt;? If the answer is yes, this is a huge problem and should be the first thing to fix.
Generally, any changes to code should be made by branching off of the &lt;strong&gt;master&#x2F;main&lt;&#x2F;strong&gt; or feature branch, and then creating a pull request to merge those changes back into the target branch. This ensures that someone other than yourself reviewed the code before changes were merged in. Humans make mistakes all the time. At the very least your fellow team members should be able to read the new code being checked in and understand what it does. Team members should take this opportunity to point out any mistakes or ways to improve the code before it is merged in.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;setting_up_a_simple_team_project_workflow_on_github&#x2F;add_rule.png&quot; alt=&quot;add branch protection rule&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Check &amp;quot;Require pull request reviews before merging&amp;quot;&lt;&#x2F;p&gt;
&lt;p&gt;We will also be checking &amp;quot;Require status checks to pass before merging&amp;quot; in &lt;a href=&quot;https:&#x2F;&#x2F;yaro.codes&#x2F;setting-up-a-simple-team-project-workflow-on-github&#x2F;#2-build-checks&quot;&gt;2. Build Checks&lt;&#x2F;a&gt; below.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;setting_up_a_simple_team_project_workflow_on_github&#x2F;branch_settings_checked.png&quot; alt=&quot;branch settings&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-build-checks&quot;&gt;2. Build checks&lt;&#x2F;h3&gt;
&lt;p&gt;You should always be checking in working code. Can&#x27;t tell you how many times I&#x27;ve seen compilation errors in a project after pulling down the latest changes. This slows down other teams members either by 1. you have to go and fix it, or 2. you have to remind someone to go and fix it. Don&#x27;t @ me bro.&lt;&#x2F;p&gt;
&lt;p&gt;Luckily we have a simple solution: build the code when a pull request is created, and setup a policy where pull requests can only succeed if the build succeeds.&lt;&#x2F;p&gt;
&lt;p&gt;For this we will use &lt;a href=&quot;https:&#x2F;&#x2F;docs.github.com&#x2F;en&#x2F;actions&#x2F;configuring-and-managing-workflows&#x2F;configuring-a-workflow&quot;&gt;Github workflows&#x2F;actions&lt;&#x2F;a&gt;. Setting up a basic workflow to build the project is fairly straightforward with the plentiful example workflows. At this point you should already have some code in your master&#x2F;main branch, so the only thing left to do is click &lt;strong&gt;Actions&lt;&#x2F;strong&gt; on your repo&#x27;s main page. Github is smart and will make a recommendation on what example workflow to setup based on the primary language used for the project. Go ahead and select the recommendation or start from scratch.&lt;&#x2F;p&gt;
&lt;p&gt;I won&#x27;t go into the heavy details of how actions work here; just know that most of what you probably need is already on the marketplace, workflows are written in yaml, and every action on the marketplace should have good example to get you started. Below I will outline a workflow that could apply to almost any project. The only thing that will differ will probably be the action and it&#x27;s configuration (build a C# project version build a node project).&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yaml&quot; style=&quot;background-color:#282c34;color:#abb2bf;&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span style=&quot;color:#d19a66;&quot;&gt;on&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;pull_request&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;jobs&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;build&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;runs-on&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;ubuntu-latest
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;steps&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;&amp;#39;Checkout&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;uses&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;actions&#x2F;checkout@master
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;&amp;quot;Setup node&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;uses&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;actions&#x2F;setup-node@v1
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;with&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;node-version&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;&amp;#39;12&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;npm install
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;npm build
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This should read &lt;em&gt;almost&lt;&#x2F;em&gt; like plain english: On a pull request, run the &lt;strong&gt;build&lt;&#x2F;strong&gt; job with these steps: use the &lt;strong&gt;checkout&lt;&#x2F;strong&gt; action to checkout our code, use the &lt;strong&gt;setup-node&lt;&#x2F;strong&gt; action to setup node.js, run &lt;strong&gt;npm install&lt;&#x2F;strong&gt; and then &lt;strong&gt;npm build&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;After setting up the build.yml (or whatever you choose to name it), you can go set the &amp;quot;Require status checks to pass before merging&amp;quot; under branch protection rules from above, and select the name of the build to be used (build.yml in this case).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-test-checks&quot;&gt;3. Test checks&lt;&#x2F;h3&gt;
&lt;p&gt;You should probably have some unit tests for your code. If you don&#x27;t, I would highly recommended adding them as they serve us as our guardian angels 👼. Luckily adding test checks is only one line of code! Simply append &lt;strong&gt;- run: npm test&lt;&#x2F;strong&gt; under &lt;strong&gt;- run: npm build&lt;&#x2F;strong&gt; and you are good to go. Not only are we checking if the code compiles now, but we are also making sure that our merged changes don&#x27;t break any existing tests 🤜🤛.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bonus-points&quot;&gt;Bonus points:&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;deploy-your-code&quot;&gt;Deploy your code&lt;&#x2F;h3&gt;
&lt;p&gt;We went through the effort to build our code and test it. Once the pull request completes and everything is merged into &lt;strong&gt;master&#x2F;main&lt;&#x2F;strong&gt;, why not deploy our built code automatically so the rest of our team can see the changes without having to pull and run changes locally? This is super easy for frontend web apps, as Github has the capability to host it for you via &lt;a href=&quot;https:&#x2F;&#x2F;pages.github.com&#x2F;&quot;&gt;Github pages&lt;&#x2F;a&gt;. Here is the action to do just that: &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;marketplace&#x2F;actions&#x2F;deploy-to-github-pages&quot;&gt;deploy-to-github-pages&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Do you have a more complex app with a private server you would like to deploy to? There are many options for that as well:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Deploy as an &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;marketplace&#x2F;actions&#x2F;azure-webapp&quot;&gt;Azure WebApp&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Deploy to &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;marketplace&#x2F;actions&#x2F;github-action-for-firebase&quot;&gt;Firebase&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Deploy to &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;marketplace&#x2F;actions&#x2F;deploy-to-heroku&quot;&gt;Heroku&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We can even just copy our build files to a target server using SCP&#x2F;SSH like I did for this blog: &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;YaroBear&#x2F;blog&#x2F;blob&#x2F;master&#x2F;.github&#x2F;workflows&#x2F;build.yml&quot;&gt;build.yml&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From the &lt;strong&gt;build_and_deploy&lt;&#x2F;strong&gt; job:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yaml&quot; style=&quot;background-color:#282c34;color:#abb2bf;&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;build_and_deploy&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;runs-on&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;ubuntu-latest
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;github.ref == &amp;#39;refs&#x2F;heads&#x2F;master&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;steps&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;&amp;#39;Checkout&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;uses&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;actions&#x2F;checkout@master
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;&amp;quot;Setup node&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;uses&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;actions&#x2F;setup-node@v1
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;with&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;node-version&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;&amp;#39;12&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;npm install
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;&amp;#39;Build with zola&amp;#39; 
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;uses&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;shalzz&#x2F;zola-deploy-action@master
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;env&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;BUILD_DIR&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d19a66;&quot;&gt;.
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;TOKEN&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;${{ secrets.TOKEN }}
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;BUILD_ONLY&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d19a66;&quot;&gt;true
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;copy files to target server via ssh
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;uses&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;appleboy&#x2F;scp-action@master
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;with&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;host&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;${{ secrets.HOST }}
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;username&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;${{ secrets.USERNAME }}
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;port&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;${{ secrets.PORT }}
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;${{ secrets.KEY }}
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;source&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;&amp;quot;.&#x2F;public&#x2F;*&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;target&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#98c379;&quot;&gt;&amp;quot;&#x2F;var&#x2F;www&#x2F;blog&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#e06c75;&quot;&gt;overwrite&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d19a66;&quot;&gt;true
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;strong&gt;secrets&lt;&#x2F;strong&gt; pipeline variables can be easily configured by going to your project&#x27;s settings and clicking the Secrets tab.&lt;&#x2F;p&gt;
&lt;p&gt;Some action require setting up a &lt;a href=&quot;https:&#x2F;&#x2F;docs.github.com&#x2F;en&#x2F;github&#x2F;authenticating-to-github&#x2F;creating-a-personal-access-token&quot;&gt;personal access token&lt;&#x2F;a&gt; with github. The action&#x27;s documentation should tell you what minimal scopes&#x2F;permissions it needs to run.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;That about covers the most basic scenario. The sky is the limit from here, but setting up a basic workflow to build code and validate our pull requests will save a lot of time and headaches for your team. Also, it&#x27;s pretty dang fun watching the logs as our build pipelines progress 🤓.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;setting_up_a_simple_team_project_workflow_on_github&#x2F;build_and_deploy.gif&quot; alt=&quot;build and deploy workflow&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
        <title>Welcome to my blog</title>
        <author><name>Yaroslav Berejnoi</name></author>
		<published>2020-07-07T00:00:00+00:00</published>
		<updated>2020-07-07T00:00:00+00:00</updated>
		<link href="https://yaro.codes/first/" type="text/html"/>
		<id>https://yaro.codes/first/</id>
		<content type="html">&lt;h1 id=&quot;welcome&quot;&gt;Welcome&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;strong&gt;Hello world&lt;&#x2F;strong&gt; and thanks for stopping by. This blog is dedicated as a self-reference for the things I learn and don&#x27;t want to forget (and if I do, easy to lookup 🕵️‍♀️).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-few-things-to-expect-from-this-blog&quot;&gt;A few things to expect from this blog:&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;&quot;&gt;Rust&lt;&#x2F;a&gt; learnings&lt;&#x2F;li&gt;
&lt;li&gt;Some C#&#x2F;Asp.net core, Angular&lt;&#x2F;li&gt;
&lt;li&gt;Linux&lt;&#x2F;li&gt;
&lt;li&gt;Vim&lt;&#x2F;li&gt;
&lt;li&gt;Design patterns&lt;&#x2F;li&gt;
&lt;li&gt;Cool things I find&lt;&#x2F;li&gt;
&lt;li&gt;Ramblings&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;also&quot;&gt;Also:&lt;&#x2F;h2&gt;
&lt;p&gt;There is an &lt;a href=&quot;..&#x2F;..&#x2F;atom.xml&quot;&gt;RSS&lt;&#x2F;a&gt; feed!&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Paper is to write things down that we need to remember. Our brains are used to think.” - Albert Einstein&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
	</entry>
</feed>
