<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Jack of all trades]]></title><description><![CDATA[Jack of all trades]]></description><link>https://blog.pawan.win</link><generator>RSS for Node</generator><lastBuildDate>Thu, 16 Apr 2026 12:03:07 GMT</lastBuildDate><atom:link href="https://blog.pawan.win/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to Easily Install Kiro AI Editor Preview on Arch Linux]]></title><description><![CDATA[Get the Kiro debian package
You must have a debian package from the public review account you have created on Kiro.
Installing Necessary Dependencies
paru -S apparmor.d-git c libxcomposite libxdamage libxkbfile nspr nss

or if you’re still using the ...]]></description><link>https://blog.pawan.win/how-to-easily-install-kiro-ai-editor-preview-on-arch-linux</link><guid isPermaLink="true">https://blog.pawan.win/how-to-easily-install-kiro-ai-editor-preview-on-arch-linux</guid><category><![CDATA[Kiro]]></category><category><![CDATA[Amazon]]></category><category><![CDATA[AWS]]></category><category><![CDATA[AI]]></category><category><![CDATA[llm]]></category><category><![CDATA[cursor]]></category><category><![CDATA[cursor IDE]]></category><category><![CDATA[cursor ai]]></category><category><![CDATA[windsurf]]></category><category><![CDATA[trae]]></category><category><![CDATA[traeai]]></category><dc:creator><![CDATA[Pawan]]></dc:creator><pubDate>Sun, 20 Jul 2025 16:05:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1753023097908/cf4d0024-b785-4205-b64e-c8a6d5194092.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-get-the-kiro-debian-package">Get the Kiro debian package</h2>
<p>You must have a debian package from the public review account you have created on <a target="_blank" href="https://kiro.dev">Kiro</a>.</p>
<h2 id="heading-installing-necessary-dependencies">Installing Necessary Dependencies</h2>
<pre><code class="lang-bash">paru -S apparmor.d-git c libxcomposite libxdamage libxkbfile nspr nss
</code></pre>
<p>or if you’re still using the dinosaur yay,</p>
<pre><code class="lang-bash">yay -S apparmor.d-git c libxcomposite libxdamage libxkbfile nspr nss
</code></pre>
<h2 id="heading-repackage-deb-package-to-arch-linux-package">Repackage .deb package to Arch Linux package</h2>
<p>Once done installing the dependencies, you have to repack the deb package into an arch linux package, which can be done using debtap.</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/helixarch/debtap
<span class="hljs-built_in">cd</span> debtap
chmod +x ./debtap
./debtap -u
</code></pre>
<p>Next up, we’ll start the repackaging.</p>
<pre><code class="lang-bash">./debtap 202507152342-distro-linux-x64.deb
</code></pre>
<p>Then, just give the name Kiro for Packager name and license shall be left blank since the app is proprietary.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753024216499/1fc02fe3-e161-4597-8ab6-533f7831ed1f.png" alt class="image--center mx-auto" /></p>
<p>Once that is done than you’ll be prompted that the repackaging is complete and you’ll see a tar.zst file in the same directory you had the debian package.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753024389459/81d7f065-8534-4cfb-87a0-2c5e64786175.png" alt class="image--center mx-auto" /></p>
<p>Finally, install the kiro arch linux package using pacman,</p>
<pre><code class="lang-bash">sudo pacman -U kiro-0.1.6-1-x86_64.pkg.tar.zst
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>While the app is in preview, you must follow the same steps to install/update the app, which is until the team working on Kiro releases the app for commercial use.</p>
]]></content:encoded></item><item><title><![CDATA[Learn SDKMAN! for Effective Developer Tool Management in 2024]]></title><description><![CDATA[What is SDKMAN?
SDKMAN! (Software Development Kit Manager) is indeed a powerful command-line tool designed for Unix-based systems, offering a streamlined way to manage development tools and SDKs. It functions similarly to fnm or nvm but is tailored f...]]></description><link>https://blog.pawan.win/learn-sdkman-for-effective-developer-tool-management-in-2024</link><guid isPermaLink="true">https://blog.pawan.win/learn-sdkman-for-effective-developer-tool-management-in-2024</guid><category><![CDATA[java,sdkman,sdk,jdk]]></category><category><![CDATA[SDKMAN]]></category><category><![CDATA[Java]]></category><category><![CDATA[Springboot]]></category><dc:creator><![CDATA[Pawan]]></dc:creator><pubDate>Sun, 10 Nov 2024 07:24:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1731218887885/fe649546-5c3c-43fe-8045-e2eaee67a843.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-what-is-sdkman">What is SDKMAN?</h2>
<p>SDKMAN! (Software Development Kit Manager) is indeed a powerful command-line tool designed for Unix-based systems, offering a streamlined way to manage development tools and SDKs. It functions similarly to fnm or nvm but is tailored for the Java and Spring Boot ecosystem, among others. SDKMAN! simplifies the installation and management of various programming languages, frameworks, and build tools, acting as a personal DevOps assistant to enhance productivity and consistency across development environments.</p>
<h3 id="heading-why-choose-sdkman">Why Choose SDKMAN?</h3>
<ul>
<li><p><strong>Simplified Version Management</strong>: Install and switch between different versions of Java, Kotlin, Gradle, and more</p>
</li>
<li><p><strong>Time-Saving Automation</strong>: Eliminate manual downloads and environment setup</p>
</li>
<li><p><strong>Project Consistency</strong>: Ensure all team members use identical tool versions</p>
</li>
<li><p><strong>Cross-Platform Compatibility</strong>: Works seamlessly on Linux, macOS, and Unix-like systems</p>
</li>
</ul>
<h2 id="heading-key-features-and-benefits">Key Features and Benefits</h2>
<h3 id="heading-1-effortless-installation">1. Effortless Installation</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># One-line installation</span>
curl -s <span class="hljs-string">"https://get.sdkman.io"</span> | bash

<span class="hljs-comment"># Install latest Java</span>
sdk install java

<span class="hljs-comment"># List available versions</span>
sdk list java
</code></pre>
<h3 id="heading-2-version-management-made-simple">2. Version Management Made Simple</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># Switch Java versions instantly</span>
sdk use java 17.0.9-tem

<span class="hljs-comment"># Set default version</span>
sdk default java 17.0.9-tem
</code></pre>
<h3 id="heading-3-multi-tool-support">3. Multi-tool Support</h3>
<p>SDKMAN! manages essential development tools including:</p>
<ul>
<li><p>☕ Java (OpenJDK, Eclipse Temurin, GraalVM)</p>
</li>
<li><p>🛠️ Build Tools (Maven, Gradle)</p>
</li>
<li><p>🚀 Frameworks (Spring Boot, Micronaut)</p>
</li>
<li><p>📜 Languages (Groovy, Kotlin, Scala)</p>
</li>
</ul>
<h2 id="heading-installation-and-setup">Installation and Setup</h2>
<h3 id="heading-quick-start-guide">Quick Start Guide</h3>
<ol>
<li><strong>Install SDKMAN!</strong></li>
</ol>
<pre><code class="lang-bash">curl -s <span class="hljs-string">"https://get.sdkman.io"</span> | bash
<span class="hljs-built_in">source</span> <span class="hljs-string">"<span class="hljs-variable">$HOME</span>/.sdkman/bin/sdkman-init.sh"</span>
</code></pre>
<blockquote>
<p>📜 A note for fish shell users: While SDKMAN! is primarily designed for Bash/Zsh shells, you can make it work with Fish shell using a simple wrapper function, <a target="_blank" href="https://pawann.hashnode.dev/how-to-use-sdkman-with-fish-shell-a-detailed-guide">click here to know how.</a></p>
</blockquote>
<ol start="2">
<li><strong>Verify Installation</strong></li>
</ol>
<pre><code class="lang-bash">sdk version
</code></pre>
<ol start="3">
<li><strong>Install Your First Tool</strong></li>
</ol>
<pre><code class="lang-bash">sdk install java
</code></pre>
<h3 id="heading-project-configuration">Project Configuration</h3>
<p>Create a <code>.sdkmanrc</code> file for project-specific versions:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># .sdkmanrc</span>
java=17.0.9-tem
gradle=8.4
kotlin=1.9.20
</code></pre>
<h2 id="heading-common-use-cases">Common Use Cases</h2>
<h3 id="heading-for-core-java-developers">For Core Java Developers</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># Install specific Java version (Eclipse Temurin in this case)</span>
sdk install java 17.0.9-tem

<span class="hljs-comment"># List installed versions</span>
sdk list java installed

<span class="hljs-comment"># Switch versions</span>
sdk use java 17.0.9-tem
</code></pre>
<h3 id="heading-for-java-full-stack-developers">For Java Full-Stack Developers</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># Install multiple tools</span>
sdk install gradle
<span class="hljs-comment"># or</span>
sdk install maven
sdk install springboot
</code></pre>
<p>and many other developers who use several other tooling and sdks for development can use sdkman, please refer to the official documentation for your sdk support</p>
<h2 id="heading-advanced-features">Advanced Features</h2>
<h3 id="heading-1-environment-management">1. Environment Management</h3>
<ul>
<li><p><strong>Auto-switching</strong> between tool versions</p>
</li>
<li><p><strong>Isolated environments</strong> per project</p>
</li>
<li><p><strong>Parallel version</strong> installation</p>
</li>
</ul>
<h3 id="heading-2-update-management">2. Update Management</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># Update SDKMAN!</span>
sdk update

<span class="hljs-comment"># Upgrade all tools</span>
sdk upgrade
</code></pre>
<h2 id="heading-troubleshooting-and-tips">Troubleshooting and Tips</h2>
<h3 id="heading-common-issues-and-solutions">Common Issues and Solutions</h3>
<ol>
<li><p><strong>Installation Fails</strong></p>
<ul>
<li><p>Check internet connection</p>
</li>
<li><p>Verify system requirements</p>
</li>
<li><p>Ensure bash is installed</p>
</li>
</ul>
</li>
<li><p><strong>Version Switching Issues</strong></p>
<ul>
<li><p>Restart terminal</p>
</li>
<li><p>Verify PATH settings</p>
</li>
<li><p>Check <code>.sdkmanrc</code> syntax</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-pro-tips">Pro Tips</h3>
<ol>
<li><p><strong>Speed Up Workflow</strong></p>
<pre><code class="lang-bash"> <span class="hljs-comment"># Create aliases</span>
 <span class="hljs-built_in">alias</span> sdki=<span class="hljs-string">'sdk install'</span>
 <span class="hljs-built_in">alias</span> sdku=<span class="hljs-string">'sdk use'</span>
</code></pre>
</li>
<li><p><strong>Project Management</strong></p>
<pre><code class="lang-bash"> <span class="hljs-comment"># Initialize project</span>
 sdk env init

 <span class="hljs-comment"># Load project config</span>
 sdk env
</code></pre>
</li>
</ol>
<h2 id="heading-frequently-asked-questions">Frequently Asked Questions</h2>
<p><strong>Q: Can I use SDKMAN! with Docker?</strong> A: Yes, SDKMAN! can be installed in Docker containers for consistent development environments.</p>
<p><strong>Q: Does it work on Windows?</strong> A: SDKMAN! works on Windows through WSL (Windows Subsystem for Linux) or Git Bash.</p>
<p><strong>Q: Can I install multiple Java distributions?</strong> A: Yes, SDKMAN! supports various Java distributions including OpenJDK, Eclipse Temurin, and GraalVM.</p>
<h2 id="heading-resources-and-further-reading">Resources and Further Reading</h2>
<ul>
<li><p><a target="_blank" href="https://sdkman.io/usage">Official SDKMAN! Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/sdkman">GitHub Repository</a></p>
</li>
<li><p><a target="_blank" href="https://discord.gg/y9mVJYVyu4">SDKMAN! Community Discord</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[How to Use SDKMAN! with Fish Shell: A Detailed Guide]]></title><description><![CDATA[TL;DR: While SDKMAN! is primarily designed for Bash/Zsh shells, you can make it work with Fish shell using a simple wrapper function that bridges the gap between Fish and Bash.
The Problem with SDKMAN! and Fish Shell
If you're a Fish shell user tryin...]]></description><link>https://blog.pawan.win/how-to-use-sdkman-with-fish-shell-a-detailed-guide</link><guid isPermaLink="true">https://blog.pawan.win/how-to-use-sdkman-with-fish-shell-a-detailed-guide</guid><category><![CDATA[fishshell]]></category><category><![CDATA[Java]]></category><category><![CDATA[SDKMAN]]></category><category><![CDATA[sdk]]></category><dc:creator><![CDATA[Pawan]]></dc:creator><pubDate>Sun, 10 Nov 2024 04:47:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/aZ9biTaCPJM/upload/111a2f1217cb99af20d774851bc94808.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>TL;DR</strong>: While SDKMAN! is primarily designed for Bash/Zsh shells, you can make it work with Fish shell using a simple wrapper function that bridges the gap between Fish and Bash.</p>
<h2 id="heading-the-problem-with-sdkman-and-fish-shell">The Problem with SDKMAN! and Fish Shell</h2>
<p>If you're a Fish shell user trying to use SDKMAN! (Software Development Kit Manager), you've probably encountered errors like:</p>
<pre><code class="lang-bash">~/.sdkman/etc/config (line 1): Unsupported use of <span class="hljs-string">'='</span>. In fish, please use <span class="hljs-string">'set sdkman_auto_answer false'</span>.
</code></pre>
<p>This happens because SDKMAN!'s scripts are written in Bash/Zsh syntax, which isn't compatible with Fish shell's unique syntax.</p>
<h2 id="heading-the-quick-solution-a-fish-shell-wrapper">The Quick Solution: A Fish Shell Wrapper</h2>
<p>Instead of converting all of SDKMAN!'s scripts to Fish (which would be time-consuming and break with updates), we can create a simple wrapper function that lets Fish and SDKMAN! work together seamlessly.</p>
<h3 id="heading-step-1-install-sdkman">Step 1: Install SDKMAN!</h3>
<p>First, make sure you have SDKMAN! installed:</p>
<pre><code class="lang-bash">curl -s <span class="hljs-string">"https://get.sdkman.io"</span> | bash
</code></pre>
<h3 id="heading-step-2-create-the-wrapper-function-initialization-script">Step 2: Create the Wrapper Function Initialization Script</h3>
<p>First, create a new file in your Fish config directory if it doesn't already exist:</p>
<pre><code class="lang-bash">mkdir -p ~/.config/fish/conf.d
</code></pre>
<p>Then, create a new file called <a target="_blank" href="http://sdkman.fish"><code>sdkman-init.fish</code></a> in the conf.d directory:</p>
<pre><code class="lang-bash">touch ~/.config/fish/conf.d/sdkman-init.fish
</code></pre>
<p>Finally, write the script in your favorite text editor, by following these steps:</p>
<ol>
<li><p>Open your terminal and type the command to open the file in your preferred text editor. For example, using <code>nvim</code>:</p>
<pre><code class="lang-bash"> nvim ~/.config/fish/conf.d/sdkman-init.fish
</code></pre>
</li>
<li><p>Copy and paste the following script into the file:</p>
<pre><code class="lang-bash"> <span class="hljs-keyword">function</span> sdk --description <span class="hljs-string">'SDKMAN! wrapper for Fish shell'</span>
     <span class="hljs-built_in">set</span> -q SDKMAN_DIR; or <span class="hljs-built_in">set</span> -gx SDKMAN_DIR <span class="hljs-string">"<span class="hljs-variable">$HOME</span>/.sdkman"</span>
     <span class="hljs-built_in">set</span> -q SDKMAN_CANDIDATES_API; or <span class="hljs-built_in">set</span> -gx SDKMAN_CANDIDATES_API <span class="hljs-string">"https://api.sdkman.io/2"</span>

     <span class="hljs-keyword">if</span> <span class="hljs-built_in">test</span> -f <span class="hljs-string">"<span class="hljs-variable">$SDKMAN_DIR</span>/var/platform"</span>
         <span class="hljs-built_in">set</span> -gx SDKMAN_PLATFORM (cat <span class="hljs-string">"<span class="hljs-variable">$SDKMAN_DIR</span>/var/platform"</span>)
     end
     <span class="hljs-built_in">command</span> bash -c <span class="hljs-string">"source <span class="hljs-variable">$SDKMAN_DIR</span>/bin/sdkman-init.sh &amp;&amp; sdk <span class="hljs-variable">$argv</span>"</span>

     <span class="hljs-keyword">if</span> contains -- <span class="hljs-string">"<span class="hljs-variable">$argv</span>[1]"</span> <span class="hljs-string">"install"</span> <span class="hljs-string">"uninstall"</span> <span class="hljs-string">"use"</span> <span class="hljs-string">"default"</span> <span class="hljs-string">"env"</span>
         <span class="hljs-built_in">set</span> -l candidates (cat <span class="hljs-string">"<span class="hljs-variable">$SDKMAN_DIR</span>/var/candidates"</span>)
         <span class="hljs-keyword">for</span> candidate <span class="hljs-keyword">in</span> (string split <span class="hljs-string">','</span> <span class="hljs-variable">$candidates</span>)
             <span class="hljs-built_in">set</span> -l candidate_dir <span class="hljs-string">"<span class="hljs-variable">$SDKMAN_DIR</span>/candidates/<span class="hljs-variable">$candidate</span>/current"</span>
             <span class="hljs-keyword">if</span> <span class="hljs-built_in">test</span> -L <span class="hljs-string">"<span class="hljs-variable">$candidate_dir</span>"</span>; or <span class="hljs-built_in">test</span> -d <span class="hljs-string">"<span class="hljs-variable">$candidate_dir</span>"</span>
                 <span class="hljs-keyword">if</span> not contains <span class="hljs-string">"<span class="hljs-variable">$candidate_dir</span>/bin"</span> <span class="hljs-variable">$PATH</span>
                     <span class="hljs-built_in">set</span> -gx PATH <span class="hljs-string">"<span class="hljs-variable">$candidate_dir</span>/bin"</span> <span class="hljs-variable">$PATH</span>
                 end
             end
         end
     end
 end

 complete -c sdk -f
 complete -c sdk -a <span class="hljs-string">"install uninstall list use current upgrade version default home env clear help offline selfupdate update flush"</span> -d <span class="hljs-string">"SDKMAN! command"</span>
 complete -c sdk -n <span class="hljs-string">"__fish_seen_subcommand_from install uninstall list use current upgrade version default home"</span> -a <span class="hljs-string">"(cat <span class="hljs-variable">$HOME</span>/.sdkman/var/candidates | string split ',')"</span> -d <span class="hljs-string">"SDK candidate"</span>
</code></pre>
</li>
<li><p>Save the file and exit the text editor.</p>
</li>
</ol>
<h3 id="heading-step-3-initialize-fish-shell-with-sdkman">Step 3: Initialize fish shell with sdkman</h3>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> ~/.config/fish/conf.d/sdkman.fish
</code></pre>
<p>Get the complete file as a gist on my <a target="_blank" href="https://gist.github.com/pawann-2000/9976d1eab61c0f10373115c160f5914d">github</a>.</p>
<h2 id="heading-how-it-works">How It Works</h2>
<p>The wrapper function:</p>
<ol>
<li><p>Sets up necessary SDKMAN! environment variables.</p>
</li>
<li><p>Uses Bash to execute SDKMAN! commands.</p>
</li>
<li><p>Updates Fish's PATH after installing or switching versions.</p>
</li>
<li><p>Provides command completion for common SDKMAN! operations.</p>
</li>
</ol>
<h2 id="heading-using-sdkman-in-fish">Using SDKMAN! in Fish</h2>
<p>Now you can use SDKMAN! commands just like in Bash:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># List available Java versions</span>
sdk list java

<span class="hljs-comment"># Install a specific Java version (Eclipse Temurin in this case)</span>
sdk install java 17.0.2-tem

<span class="hljs-comment"># Use a specific Java version</span>
sdk use java 17.0.2-tem
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This wrapper provides a practical solution for Fish shell users who want to use SDKMAN! without converting all its scripts or switching shells. It maintains compatibility with SDKMAN! updates while providing most of the functionality you need for day-to-day development.</p>
<h2 id="heading-faq">FAQ</h2>
<p><strong>Q: Will this break when SDKMAN! updates?</strong> A: No, since we're using Bash to execute SDKMAN! commands, it should continue working with updates.</p>
<p><strong>Q: Does this work on all operating systems?</strong> A: Yes, as long as you have both Fish and Bash installed.</p>
<p><strong>Q: Can I contribute to making SDKMAN! work natively in Fish?</strong> A: Yes! The SDKMAN! project is <a target="_blank" href="https://github.com/sdkman">open source</a> and welcomes contributions.</p>
]]></content:encoded></item><item><title><![CDATA[Tip for Recovering Disk Space from Docker Containers]]></title><description><![CDATA[If you use Docker a lot every day, you should clean up unwanted images, volumes, and containers to free up space on your disk.
To remove everything you don't need (make sure to stop unwanted containers first), run this command:
docker system prune --...]]></description><link>https://blog.pawan.win/tip-for-recovering-disk-space-from-docker-containers</link><guid isPermaLink="true">https://blog.pawan.win/tip-for-recovering-disk-space-from-docker-containers</guid><category><![CDATA[Docker]]></category><category><![CDATA[containers]]></category><dc:creator><![CDATA[Pawan]]></dc:creator><pubDate>Fri, 30 Aug 2024 21:28:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/jOqJbvo1P9g/upload/76220b111b01d28fe1915bcc6832fd7a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you use Docker a lot every day, you should clean up unwanted images, volumes, and containers to free up space on your disk.</p>
<p>To remove everything you don't need (make sure to stop unwanted containers first), run this command:</p>
<pre><code class="lang-bash">docker system prune --all
</code></pre>
<p>This command (note that it may take a while, especially in the last step) helps free up valuable disk space by removing not only the images, volumes, and containers mentioned above but also the build cache for the containers.</p>
<p>Moreover, if you want to just get rid of unwanted images, then run the following command,</p>
<pre><code class="lang-bash">docker image prune --all
</code></pre>
<p>if you want to just get rid of unwanted volumes, then run the following command,</p>
<pre><code class="lang-bash">docker volume prune --all
</code></pre>
<p>Moreover, if you want to just get rid of unwanted containers, then run the following command,</p>
<pre><code class="lang-bash">docker container prune --all
</code></pre>
<p>I reclaimed almost 74 GB of disk space. How much did you reclaim? Let me know in the comments below. hope this article helped you :)</p>
]]></content:encoded></item><item><title><![CDATA[Local Execution of GitHub Workflows: Easy Guide]]></title><description><![CDATA[Have you ever wondered about testing GitHub workflows before pushing them into the repository and hoping they don't fail? Then you've come to the right place.
Act Before You Push
I use act to test GitHub workflows all the time, and I can't count how ...]]></description><link>https://blog.pawan.win/local-execution-of-github-workflows-easy-guide</link><guid isPermaLink="true">https://blog.pawan.win/local-execution-of-github-workflows-easy-guide</guid><category><![CDATA[Devops]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[GitHub Actions]]></category><category><![CDATA[github-actions]]></category><category><![CDATA[software development]]></category><category><![CDATA[Devops articles]]></category><dc:creator><![CDATA[Pawan]]></dc:creator><pubDate>Thu, 22 Aug 2024 03:35:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/UT8LMo-wlyk/upload/726f69def96ba1544fb1e3c0870bb7e7.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Have you ever wondered about testing GitHub workflows before pushing them into the repository and hoping they don't fail? Then you've come to the right place.</p>
<h2 id="heading-act-before-you-push"><em>Act</em> Before You Push</h2>
<p>I use <a target="_blank" href="https://github.com/nektos/act">act</a> to test GitHub workflows all the time, and I can't count how many times it has saved me.</p>
<p>To get started, install act using brew,</p>
<pre><code class="lang-bash">brew install act
</code></pre>
<p>It helps you do many things, including:</p>
<ul>
<li><p>Running your GitHub workflow in a specific container allows you to simulate the exact environment your workflow will run in, ensuring consistency and reducing the chances of unexpected failures.</p>
<ul>
<li><pre><code class="lang-bash">    act -P ubuntu-latest=catthehacker/ubuntu:act-latest
</code></pre>
</li>
</ul>
</li>
<li><p>Run a specific workflow to test individual parts of your GitHub Actions, ensuring each component works as expected before integrating them into the main workflow.</p>
<ul>
<li><pre><code class="lang-bash">    act -P ubuntu-latest=catthehacker/ubuntu:act-latest push
</code></pre>
</li>
</ul>
</li>
<li><p>Pass secrets if required, ensuring that sensitive information is securely handled during the workflow execution.</p>
<ul>
<li><pre><code class="lang-bash">    act -P ubuntu-latest=catthehacker/ubuntu:act-latest -s GITHUB_TOKEN=f4bhuj2gb5trhigbihfgbti4h2 push
</code></pre>
</li>
</ul>
</li>
</ul>
<p>You can learn more about the act CLI from the repository below:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/nektos/act">https://github.com/nektos/act</a></div>
]]></content:encoded></item><item><title><![CDATA[How to Fix "User Not in Sudoers File" Error in Docker Containers]]></title><description><![CDATA[The Problem
Earlier today, I was exploring dev containers from Microsoft and trying to set up a Rust dev container using Distrobox on Docker. I got stuck at the 'user not in sudoers file' error. The typical solution is to add the user to the sudo gro...]]></description><link>https://blog.pawan.win/how-to-fix-user-not-in-sudoers-file-error-in-docker-containers</link><guid isPermaLink="true">https://blog.pawan.win/how-to-fix-user-not-in-sudoers-file-error-in-docker-containers</guid><category><![CDATA[Docker]]></category><category><![CDATA[Tutorial]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Pawan]]></dc:creator><pubDate>Wed, 31 Jul 2024 07:45:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/HSACbYjZsqQ/upload/69be3fcf926672ff29bfd3e6a5a68502.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-the-problem">The Problem</h2>
<p>Earlier today, I was exploring dev containers from Microsoft and trying to set up a <a target="_blank" href="https://mcr.microsoft.com/en-us/product/devcontainers/rust/tags">Rust</a> dev container using Distrobox on Docker. I got stuck at the 'user not in sudoers file' error. The typical solution is to add the user to the sudo group using:</p>
<pre><code class="lang-bash">usermod -aG sudo <span class="hljs-variable">$USER</span>
</code></pre>
<p>The problem with this command is that I had to be a member of the sudo group, but I wasn't. Later, I tried:</p>
<pre><code class="lang-bash">su
</code></pre>
<p>for which, again, I had to know the root password. This was still an unknown. At this point, I was thinking of other solutions until...</p>
<h2 id="heading-the-solution">The Solution</h2>
<p>I remembered that Docker has an exec command that allows executing commands as the root user on containers. Then I tried:</p>
<pre><code class="lang-bash">docker <span class="hljs-built_in">exec</span> -it &lt;container_name or container_id&gt; sudo usermod -aG sudo <span class="hljs-variable">$USER</span>
</code></pre>
<p>for example in my case it was the rustbox container,</p>
<pre><code class="lang-bash">docker <span class="hljs-built_in">exec</span> -it rustbox sudo usermod -aG sudo <span class="hljs-variable">$USER</span>
</code></pre>
<p>If this solution helped you, then leave a like or comment for anything I may be missing. Happy to help, happy coding! 🖥️</p>
]]></content:encoded></item><item><title><![CDATA[How distrobox changed my life]]></title><description><![CDATA[Hey! This is my first blog on Hashnode, but not my first blog ever. Previously, I used to write tech blogs on WordPress. Over time, I lost interest in writing there because there was too much happening in tech, and I couldn't keep up due to work. Any...]]></description><link>https://blog.pawan.win/how-distrobox-changed-my-life</link><guid isPermaLink="true">https://blog.pawan.win/how-distrobox-changed-my-life</guid><category><![CDATA[Developer Tools]]></category><dc:creator><![CDATA[Pawan]]></dc:creator><pubDate>Mon, 29 Jul 2024 05:23:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/8dvTZPVEJWk/upload/0f81d19e2141327b2f99499df071bc40.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey! This is my first blog on Hashnode, but not my first blog ever. Previously, I used to write tech blogs on <a target="_blank" href="https://techspeakr.wordpress.com/"><strong>WordPress</strong></a>. Over time, I lost interest in writing there because there was too much happening in tech, and I couldn't keep up due to work. Anyway, let's move past the boring part and get started with my first blog here. By the way, whether you like my content or not, please comment and make sure you leave a like 😉.</p>
<p>Let's get to the nitty gritty of the article.</p>
<h2 id="heading-the-inception">The inception</h2>
<p>I used to be like almost everyone, installing devtools and packages on my local machine back in the day, until I discovered Docker one day. Here's what I found during that time:</p>
<p>Docker can:</p>
<ul>
<li><p>Set up your development environment with a single file called the Dockerfile.</p>
</li>
<li><p>Let you use any Linux distro you want without having to install it on bare metal.</p>
</li>
<li><p>Make you focus only on the software you're building, not the environment.</p>
</li>
</ul>
<p>But one Sunday evening, I was bored and wanted to further simplify my development environment setup beyond a Dockerfile.</p>
<h2 id="heading-the-elaboration">The elaboration</h2>
<p>There I found <a target="_blank" href="https://distrobox.it">distrobox</a>, which fascinated me in every single way, I was jumping in joy because of the simplicity it offered, for context, thanks to <a target="_blank" href="https://docs.docker.com/language/nodejs/develop/">docker docs</a>, this was the compose file, which I used to setup a nodejs dev environment:</p>
<pre><code class="lang-dockerfile">services:
  server:
    build:
      context: .
      target: dev
    ports:
      - <span class="hljs-number">3000</span>:<span class="hljs-number">3000</span>
      - <span class="hljs-number">9229</span>:<span class="hljs-number">9229</span>
    environment:
      NODE_ENV: production
      POSTGRES_HOST: db
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD_FILE: /<span class="hljs-keyword">run</span><span class="bash">/secrets/db-password</span>
      POSTGRES_DB: example
    depends_on:
      db:
        condition: service_healthy
    secrets:
      - db-password
    volumes:
      - ./src:/usr/src/app/src
  db:
    image: postgres
    restart: always
    <span class="hljs-keyword">user</span>: postgres
    secrets:
      - db-password
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=example
      - POSTGRES_PASSWORD_FILE=/<span class="hljs-keyword">run</span><span class="bash">/secrets/db-password</span>
    <span class="hljs-keyword">expose</span>:
      - <span class="hljs-number">5432</span>
    <span class="hljs-keyword">healthcheck</span><span class="bash">:</span>
      test: [ <span class="hljs-string">"CMD"</span>, <span class="hljs-string">"pg_isready"</span> ]
      interval: <span class="hljs-number">10</span>s
      timeout: <span class="hljs-number">5</span>s
      retries: <span class="hljs-number">5</span>
volumes:
  db-data:
secrets:
  db-password:
    file: db/password.txt
</code></pre>
<p>By the way, if you want to use this, please change the POSTGRES_DB name and other example values provided. Moving on, this was the distrobox file after I switched to distrobox. Once again, thanks to <a target="_blank" href="https://mcr.microsoft.com/en-us/catalog?search=dev&amp;type=partial&amp;page=1">Microsoft devcontainers images</a> for making this beautiful machine learning box image. I use the same box for all my development activities, ranging from developing Java APIs to creating ML apps.</p>
<pre><code class="lang-dockerfile">[mlbox]
image=mcr.microsoft.com/devcontainers/anaconda:latest
additional_packages=<span class="hljs-string">"nano git btop"</span>
init_hooks=<span class="hljs-string">"pip3 install huggingface_hub tokenizers transformers accelerate datasets wandb peft bitsandbytes fastcore fastprogress watermark torchmetrics deepspeed"</span>
nvidia=true
pull=true
root=false
replace=false
home=/home/$<span class="hljs-keyword">USER</span>/mlbox-home
</code></pre>
<p>As you can see from the above file, I have all the necessary packages for machine learning. The rest of the packages are installed using brew. Even my code editor, Vscodium, is installed on the same box. This not only separates concerns but also contributes to the immutability of my base operating system, which is Arch Linux (I use Arch btw).</p>
<h2 id="heading-the-conclusion">The Conclusion</h2>
<p>Distrobox changed the way I looked at Docker containers and further simplified my life by isolating my development environment from my local packages.</p>
<p>I will publish more blogs detailing my complete dev environment setup in parts over the upcoming days. Until then, stay tuned and happy coding! 🖥️</p>
]]></content:encoded></item></channel></rss>