<?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>DEV Community: Kamau Wanyee</title>
    <description>The latest articles on DEV Community by Kamau Wanyee (@steekam).</description>
    <link>https://dev.to/steekam</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%2F146534%2F1b634c3b-0894-4575-8a30-3caac13163d2.png</url>
      <title>DEV Community: Kamau Wanyee</title>
      <link>https://dev.to/steekam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/steekam"/>
    <language>en</language>
    <item>
      <title>TenancyForLaravel FileSystem Bootstrapper asset Gotcha</title>
      <dc:creator>Kamau Wanyee</dc:creator>
      <pubDate>Tue, 24 May 2022 20:09:14 +0000</pubDate>
      <link>https://dev.to/steekam/tenancyforlaravel-filesystem-bootstrapper-gotcha-2400</link>
      <guid>https://dev.to/steekam/tenancyforlaravel-filesystem-bootstrapper-gotcha-2400</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TLDR; If you are using the &lt;code&gt;FileSystemBootstrapper&lt;/code&gt; on the &lt;code&gt;archtechx/tenancy&lt;/code&gt; package and also the &lt;a href="https://laravel-vite.dev" rel="noopener noreferrer"&gt;Laravel-Vite&lt;/a&gt; package, update your tenancy config (&lt;code&gt;tenancy.filesystem.asset_helper_tenancy&lt;/code&gt;) to &lt;code&gt;false&lt;/code&gt;. Otherwise your generated script/style tags after building assets will be returning a tenant-scoped asset URL.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here is the context of the problem I was facing:&lt;/p&gt;

&lt;p&gt;I am building a multi-tenant SaaS application using this tenancy package from &lt;a href="https://tenancyforlaravel.com/" rel="noopener noreferrer"&gt;Tenacy for Laravel&lt;/a&gt;. It has a concept of tenancy bootstrappers that modifies relevant framework defaults to make the application tenant aware. The &lt;a href="https://tenancyforlaravel.com/docs/v3/tenancy-bootstrappers/" rel="noopener noreferrer"&gt;FileSystem Bootstrapper&lt;/a&gt; makes the Laravel &lt;code&gt;asset()&lt;/code&gt; helper method return tenant specific assets through a &lt;code&gt;TenantAssetController&lt;/code&gt;.&lt;br&gt;
I also replaced Laravel Mix with &lt;a href="https://vitejs.dev/" rel="noopener noreferrer"&gt;Vite&lt;/a&gt; and I'm using this &lt;a href="https://laravel-vite.dev/" rel="noopener noreferrer"&gt;Laravel Vite&lt;/a&gt; package to make the integration easier. The package provides &lt;code&gt;@vite&lt;/code&gt; directive to output all the necessary asset tags in your blade file. The underlying methods use the &lt;code&gt;asset()&lt;/code&gt; helper method from the framework. Therefore, any generated asset URL is tenant-scope if I am under a tenant aware route. I am using VueJS for templating so my page ends up not being rendered correctly.&lt;/p&gt;

&lt;p&gt;The solution is to update a tenancy config (&lt;code&gt;tenancy.filesystem.asset_tenancy_helper&lt;/code&gt;) to &lt;code&gt;false&lt;/code&gt;. The &lt;code&gt;asset()&lt;/code&gt; helper revert to default. The tenancy package still provides &lt;code&gt;tenant_asset()&lt;/code&gt; helper method for tenant specific assets.&lt;/p&gt;

&lt;p&gt;I hope this helps someone out there facing the same issue and save you time.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>todayisearched</category>
      <category>vite</category>
    </item>
    <item>
      <title>A reflection point in my career</title>
      <dc:creator>Kamau Wanyee</dc:creator>
      <pubDate>Wed, 18 May 2022 16:17:12 +0000</pubDate>
      <link>https://dev.to/steekam/a-reflection-point-in-my-career-4oba</link>
      <guid>https://dev.to/steekam/a-reflection-point-in-my-career-4oba</guid>
      <description>&lt;p&gt;This is the first time I’ve worked full-time for a whole year and I thought to make it a reflection point in my career. I always thought that I will land a job at a company with established best practices on their development processes. However, so far I have not had that luck but that means there is a lot I have learnt along the way.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Be the change that you want to see&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is no reason that the desired company culture shouldn’t start with you. Start writing the tests and setting up build tools on your assigned projects. Be visible and vocal about what you are doing and others will pick up on it. You get to sell your designed change by demonstrating the benefits first hand.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Change requires support from management&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As much as you get the buy-in from your colleagues, if management does not see and acknowledge the value in your proposal then your efforts will be moot. Something being best practice in the industry is not enough reason to adopt it. Especially when what you are proposing does not have a “direct” business value, you might get some resistance. You need to back up your proposal with research to get the sign-off.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Technical debt should be part of team deliverables&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;“We will fix it better when things cool down”&lt;/em&gt;&lt;strong&gt;.&lt;/strong&gt; One of the biggest lies we tell ourselves on projects. Then the codebase has some weird patch that can’t be touched without breaking the build and no one knows why. Take time to clean up that patchy code so that it does not becomes tomorrow’s problem.&lt;/p&gt;

&lt;p&gt;Incremental upgrades are better than huge batch upgrades. Don’t wait until the tools you use are reaching their End of Life deadline to upgrade them. Using stable latest versions of a framework or libraries can also lead to better developer happiness which translates to better productivity. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Contextual internal documentation is important&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A lot of contextual information about a project/codebase can be lost if it’s only kept in the mind. Document the not-so-obvious and context specific content. This creates a reference point for future and also on-boarding new people. It’s also critical to document this stuff when it’s fresh in the mind otherwise it is lost when it becomes &lt;em&gt;obvious.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Documentation makes sense when it is visible and utilized&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sharing links to the documentation makes it visible and people are more likely to utilize the knowledge hub. People get to know where to go if it’s an already solved problem. This also applies to customer support interactions for your products. Sharing a link to the help section that solves their problem, let’s them know where to go when facing the same issue next time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Automation is critical for smaller teams&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fewer decisions you have to make the more energy you have for complex problems. Automating your tasks where you can clears up time and mental energy which can be utilized for other important things. Other people can utilize your automation or get inspiration for their workflows as well so it benefits the whole team to move efficiently.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Source diving is a treasure trove of knowledge&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Source diving frameworks and packages is a treasure trove of experience and learning. You get to learn to solve problems you did not know even existed. You get different perspectives on solving your current problems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Be visible and public about your contributions&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of the time the decision makers only care about the end result. Your work or contributions might not always be visible or immediately appreciated. Try as much as possible to publicly mention your contributions. Others get to appreciate the effort that went into getting the expected result. The decision makers also get to notice you. Don’t down play your achievements because they have become normal to you.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Learn how to say No&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are situations when you are swamped and another request would not be feasible. Or sometimes a client or management might come with an improbable or obscene feature request. Strategically saying no helps you stay sane and also manage expectations on project deadlines and deliverables. Saying yes to everything is a sure path to burn out. Down the line there is too much on your plate which affects your performance.&lt;/p&gt;

</description>
      <category>career</category>
      <category>beginners</category>
    </item>
    <item>
      <title>I tried pair programming</title>
      <dc:creator>Kamau Wanyee</dc:creator>
      <pubDate>Wed, 31 Mar 2021 15:18:26 +0000</pubDate>
      <link>https://dev.to/steekam/i-tried-pair-programming-pak</link>
      <guid>https://dev.to/steekam/i-tried-pair-programming-pak</guid>
      <description>&lt;p&gt;I recently completed my undergrad and had some free time on my hands as I applied for jobs. I was a little bit low on motivation to work on side projects or tinker with new technology. As a substitute, I got into watching Twitch coding streams and was intrigued by the concept of mob programming with the chat. I felt like that was something I would like to try one day, baby steps though. I reached out to my friends to see if anyone was interested in hopping on a call to pair program on a project they were working on. Luckily I found someone willing to experiment with me. They were working on a tourist destination Flutter project. The first session went well enough that we had another.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;My friend has a blog series on the process of building the "Places to Visit" Flutter application. If you are interested, you can check it out &lt;a href="https://cosmasnyairo.medium.com/making-a-places-to-visit-app-using-python-and-flutter-prerequisites-b1449c100ae8" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here are a few takeaways I got from my experience pair programming:&lt;/p&gt;

&lt;h2&gt;
  
  
  Concepts are transferrable among languages
&lt;/h2&gt;

&lt;p&gt;First of all, I know nothing about Dart, the programming language used in Flutter. However, that did not put me at a disadvantage to derail my friend's productivity. We did a quick overview of the project he was working on. I got a quick crash course on the structure of a Flutter application. After that, we were off to the races working on the next feature in the application.&lt;/p&gt;

&lt;p&gt;Due to syntax similarities with other languages, I was able to infer what the majority of the code was responsible for based on the context and usage. I am comfortable with using higher-order functions when dealing with array manipulations. A quick search if there are &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt; functions in Dart and we were able to refactor code for better readability. I was happy to have some input even though I was in a foreign space. It should not be a surprise because languages are just tools we used to solve problems. Several principles guide the problem-solving techniques, the languages simply offer a representation of those techniques.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's a win-win situation
&lt;/h2&gt;

&lt;p&gt;Pair programming is a collaborative exercise, so you get to learn a lot from each other. People think and approach problems quite differently. Both parties need to be open to providing feedback along the way. The extra pair of eyes is really helpful when they catch things you miss along the way. This definitely reduced the debugging time when things went wrong. You also realize someone's thought process informs the way they code. Understanding how they think helps you phrase things in a way they will understand faster. This makes communication way easier. You learn a lot from each other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your code is not your identity
&lt;/h2&gt;

&lt;p&gt;The collaborative nature of pair programming means there will be a lot of back and forth feedback. Essentially your code may be under scrutiny. You have to remember to not get attached to your code and be defensive about it. Acknowledge good suggestions and have an open mind about the criticism. You can provide the reasoning behind your decisions to validate your method. You have to remember that it is not an argument on who is right or wrong. You are not your code, feedback is not attacking you as a person.&lt;/p&gt;

&lt;h2&gt;
  
  
  Readable code makes collaboration easier
&lt;/h2&gt;

&lt;p&gt;What is considered readable code is sometimes nuanced but there are definitely objective pointers on what is considered readable. The less the mental overhead for me to read and understand the code, the better. So definitely bespoke long one-liners are not good for readability. They may be good for codewars katas to flex your skills but not in a codebase meant to be consumed by others. &lt;/p&gt;

&lt;p&gt;I know naming things is one of the hardest things in programming, but try and make your functions and variables informative on what they are responsible for. It makes things a whole lot easier for others to understand the codebase. Future you will also benefit largely from naming things contextually.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Tools have come a long way that it has made remote pair programming quite effortless. It can be easy as hopping on a video call and sharing your screen. Tools like VsCode, like their share extension, have extra features that make code collaboration better.  I highly encourage people to try out pairing more often. For teams, it can help form bonds and synergy that helps with collaboration and productivity. Remember to have fun while at it. Share stories and crack jokes, it helps break the monotony of writing code.&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>writing</category>
    </item>
    <item>
      <title>Deploying Laravel applications to a shared server using GitHub Actions</title>
      <dc:creator>Kamau Wanyee</dc:creator>
      <pubDate>Wed, 23 Sep 2020 05:02:50 +0000</pubDate>
      <link>https://dev.to/steekam/pushing-your-laravel-application-to-a-shared-server-using-git-ftp-and-github-actions-5d6l</link>
      <guid>https://dev.to/steekam/pushing-your-laravel-application-to-a-shared-server-using-git-ftp-and-github-actions-5d6l</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I recently worked on a project where the staging server was on a shared hosting plan with users having very limited privileges. At the time I would push updates using &lt;a href="https://github.com/git-ftp/git-ftp" rel="noopener noreferrer"&gt;git-FTP&lt;/a&gt;, a tool that uses git to upload only changes to the FTP server. Without automation, the git-FTP initial push process would take me several hours. I decided to try out GitHub Actions to offload the workload from my machine.&lt;/p&gt;

&lt;p&gt;This post covers my workflow file which uses a combination of SSH and git-FTP for the staging deployment job. I am assuming that you have some knowledge of &lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before we get to the workflow
&lt;/h2&gt;

&lt;p&gt;The workflow connects to the server through SSH to run commands and files are transferred through FTP. On your GitHub account, you need to have saved secrets for these credentials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FTP user credentials.&lt;/li&gt;
&lt;li&gt;SSH private key.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There were some issues with installing composer on the staging server and I did not want to track the dependencies on git, so before deployment, I download the dependencies and create an archive.&lt;/p&gt;

&lt;p&gt;Also note that this post covers the deploy job after the initial setup of git-FTP that creates a log file on the staging server.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Staging Workflow
&lt;/h2&gt;

&lt;p&gt;The 3 jobs on the workflow file:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;setup&lt;/strong&gt; — cleans up the vendor directory on the server.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Remove vendor directory&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fifsky/ssh-action@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;cd www/site_directory/&lt;/span&gt;
            &lt;span class="s"&gt;[ -d ./vendor ] &amp;amp;&amp;amp; rm -rf ./vendor&lt;/span&gt;
          &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://staging-server.com&lt;/span&gt;
          &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;system_user&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_PRIVATE_KEY }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;deploy&lt;/strong&gt; — Download dependencies and deploy the site.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to the staging server&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;setup&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2.1.0&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Composer Dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;composer install --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create zipped vendor directory&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;montudor/action-zip@v0.1.0&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;zip -qq -r ./vendor.zip ./vendor&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;FTP-Deploy-Action&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SamKirkland/FTP-Deploy-Action@3.1.1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;ftp-server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ftp://ADDRESS_HERE&lt;/span&gt;
          &lt;span class="na"&gt;ftp-username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;FTP_USER&lt;/span&gt;
          &lt;span class="na"&gt;ftp-password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FTP_PASSWORD }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Since &lt;code&gt;[vendor.zip](http://vendor.zip)&lt;/code&gt; isn't tracked using git, it is added to the &lt;code&gt;.git-ftp-include&lt;/code&gt; file to be always pushed. Creating an archive lets the transfer to be a single file. This actually reduced my workflow run from minutes to a few seconds, which I thought was a pretty cool trick.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;post-deploy&lt;/strong&gt; — Clean up &lt;code&gt;[vendor.zip](http://vendor.zip)&lt;/code&gt; and run several artisan commands.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;post-deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run migrations and seeders, clear cache for views, config and routes&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fifsky/ssh-action@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;cd www/site_dir/&lt;/span&gt;
            &lt;span class="s"&gt;unzip -qq ./vendor.zip&lt;/span&gt;
            &lt;span class="s"&gt;rm -f vendor.zip&lt;/span&gt;
            &lt;span class="s"&gt;php artisan migrate:fresh --seed&lt;/span&gt;
            &lt;span class="s"&gt;php artisan config:clear&lt;/span&gt;
            &lt;span class="s"&gt;php artisan view:clear&lt;/span&gt;
            &lt;span class="s"&gt;php artisan route:cache&lt;/span&gt;
          &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://SERVER_ADDRESS&lt;/span&gt;
          &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;USER&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.USER_PRIVATE_KEY }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Running the Workflow
&lt;/h2&gt;

&lt;p&gt;In the project I set the workflow to run on push to a staging branch which is only gets updates from master pull requests. Here is the whole workflow file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pushing to the staging server&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;staging&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Remove vendor directory&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fifsky/ssh-action@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;cd www/site_dir/&lt;/span&gt;
            &lt;span class="s"&gt;[ -d ./vendor ] &amp;amp;&amp;amp; rm -rf ./vendor&lt;/span&gt;
          &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://ADDRESS_HERE&lt;/span&gt;
          &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;USER&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.USER_PRIVATE_KEY }}&lt;/span&gt;

  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;setup&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2.1.0&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Composer Dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;composer install --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create zipped vendor directory&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;montudor/action-zip@v0.1.0&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;zip -qq -r ./vendor.zip ./vendor&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;FTP-Deploy-Action&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SamKirkland/FTP-Deploy-Action@3.1.1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;ftp-server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ftp://ADDRESS_HERE/&lt;/span&gt;
          &lt;span class="na"&gt;ftp-username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;FTP_USER&lt;/span&gt;
          &lt;span class="na"&gt;ftp-password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FTP_PASSWORD }}&lt;/span&gt;

  &lt;span class="na"&gt;post-deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run migrations and seeders, clear cache for views, config and routes&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fifsky/ssh-action@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;cd www/site_dir/&lt;/span&gt;
            &lt;span class="s"&gt;unzip -qq ./vendor.zip&lt;/span&gt;
            &lt;span class="s"&gt;rm -f vendor.zip&lt;/span&gt;
            &lt;span class="s"&gt;php artisan migrate:fresh --seed&lt;/span&gt;
            &lt;span class="s"&gt;php artisan config:clear&lt;/span&gt;
            &lt;span class="s"&gt;php artisan view:clear&lt;/span&gt;
            &lt;span class="s"&gt;php artisan route:cache&lt;/span&gt;
          &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://SERVER_ADDRESS&lt;/span&gt;
          &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;USER&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.USER_PRIVATE_KEY }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I would not recommend using this workflow in its current state for deployments to a production server since users might get unintended interruptions when you delete the vendor directory in the setup job. In the scenario where you have composer installed on your server, you would get rid of the setup job and the dependency installation step in the deployment job. It is also a good idea to set the application in maintenance mode when you are updating the composer dependencies or making a deployment update.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>github</category>
      <category>codenewbie</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
