<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Felix Vaucourt</title>
    <description>The latest articles on Forem by Felix Vaucourt (@felvct).</description>
    <link>https://forem.com/felvct</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%2F184651%2F04814e27-25cb-437e-977d-d5bfd8462b36.jpeg</url>
      <title>Forem: Felix Vaucourt</title>
      <link>https://forem.com/felvct</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/felvct"/>
    <language>en</language>
    <item>
      <title>Proxmox: Resize Your Local (pve) Disk</title>
      <dc:creator>Felix Vaucourt</dc:creator>
      <pubDate>Wed, 30 Oct 2024 14:45:24 +0000</pubDate>
      <link>https://forem.com/felvct/proxmox-resize-your-local-pve-disk-500a</link>
      <guid>https://forem.com/felvct/proxmox-resize-your-local-pve-disk-500a</guid>
      <description>&lt;p&gt;Ever wondered how to resize your local (pve) disk after a fresh install or when adding a new disk to your homelab setup?&lt;/p&gt;

&lt;p&gt;The storage section for this is located in &lt;code&gt;pve-root&lt;/code&gt;, and you can easily extend it using LVM. After that, you'll need to resize your filesystem as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lvresize /dev/pve/root &lt;span class="nt"&gt;-L&lt;/span&gt; +&amp;lt;size&amp;gt;G

&lt;span class="c"&gt;# if you are using an ext4 partition&lt;/span&gt;
resize2fs /dev/pve/root

&lt;span class="c"&gt;# if you are using a xfs partition&lt;/span&gt;
xfs_growfs /
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;lt;size&amp;gt;&lt;/code&gt; with your desired size (in GB)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This process is particularly useful if you have a two-disk setup and want to dedicate one disk solely for local storage, while using the other for all your containers/VMs.&lt;/p&gt;




&lt;p&gt;If you have any questions, feel free to hit me up on &lt;a href="https://twitter.com/felvct" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

</description>
      <category>proxmox</category>
      <category>devops</category>
      <category>beginners</category>
      <category>homelab</category>
    </item>
    <item>
      <title>Deploy Your Website with GitHub Actions to Uberspace (the rsync way)</title>
      <dc:creator>Felix Vaucourt</dc:creator>
      <pubDate>Tue, 29 Oct 2024 21:30:28 +0000</pubDate>
      <link>https://forem.com/felvct/deploy-your-website-with-github-actions-to-uberspace-the-rsync-way-1784</link>
      <guid>https://forem.com/felvct/deploy-your-website-with-github-actions-to-uberspace-the-rsync-way-1784</guid>
      <description>&lt;h2&gt;
  
  
  Deploy Your Website with GitHub Actions to Uberspace (the rsync Way)
&lt;/h2&gt;

&lt;p&gt;I am hosting my &lt;a href="https://felvct.com" rel="noopener noreferrer"&gt;website&lt;/a&gt; on a personal and sustainable webspace at &lt;a href="https://uberspace.de/en/" rel="noopener noreferrer"&gt;Uberspace&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As a side note, the content I upload is a static HTML website, which is what we will cover in this guide.&lt;/p&gt;

&lt;p&gt;In this tutorial, I’ll show you how to automatically build, deploy, and update my content whenever I push to the main branch of my GitHub repository.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclaimer: the tutorial is written for Unix systems&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I've been using Uberspace for quite some time now. One feature that initially attracted me was the "pay what you want" model, allowing users to pay any amount per month—even as low as 1€. While any amount is accepted, Uberspace recommends at least 5€/month, as it costs them approximately 10€ per month per user to cover expenses.&lt;/p&gt;

&lt;p&gt;In addition to flexible pricing, Uberspace provides daily and weekly backups, SSH and SFTP access, HTTPS for all domains, and most impressively, all their servers run on green energy.&lt;/p&gt;

&lt;p&gt;In a nutshell, this hosting provider offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a developer-friendly server with excellent documentation&lt;/li&gt;
&lt;li&gt;european-based servers, so I don’t have to rely on US-based providers&lt;/li&gt;
&lt;li&gt;full control over my personal webspace&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Warning: this GitHub Action will overwrite files on Uberspace that are not visible in your GitHub repository. Ensure you back up your data or set up a sub-folder on your webspace before proceeding.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create new SSH keys on your local machine&lt;/li&gt;
&lt;li&gt;Create the GitHub Action&lt;/li&gt;
&lt;li&gt;Configure GitHub Repository Secrets: user, host, and generated private key&lt;/li&gt;
&lt;li&gt;Upload your generated public key to Uberspace&lt;/li&gt;
&lt;li&gt;Test the setup&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 1: Create New SSH Keys on Your Local Machine
&lt;/h3&gt;

&lt;p&gt;To transfer files to our webspace, we need a dedicated pair of SSH keys.&lt;/p&gt;

&lt;p&gt;You can create these on your local machine or directly on Uberspace. For simplicity, we’ll create them on our machine.&lt;/p&gt;

&lt;p&gt;First, create a new folder in your Documents directory to hold your keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/Documents
&lt;span class="nb"&gt;mkdir &lt;/span&gt;uberspace-ssh-keys
&lt;span class="nb"&gt;cd &lt;/span&gt;uberspace-ssh-keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, generate the key pair. You can rename &lt;code&gt;github-uberspace-keys&lt;/code&gt; to something you prefer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-f&lt;/span&gt; github-uberspace-keys &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-a&lt;/span&gt; 100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Leave the passphrase blank by simply pressing "enter"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Verify that the keys were generated correctly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;span class="nt"&gt;-rw-------&lt;/span&gt;  1 felvct  staff   399B May  5 23:08 github-uberspace-keys
&lt;span class="nt"&gt;-rw-r--r--&lt;/span&gt;  1 felvct  staff    93B May  5 23:08 github-uberspace-keys.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can move on to the exciting part: setting up our GitHub Action!&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Create the GitHub Action
&lt;/h3&gt;

&lt;p&gt;Open your GitHub repository in your favorite IDE or text editor and create a &lt;code&gt;deploy.yml&lt;/code&gt; in &lt;code&gt;.github/workflows&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# in the root of your repository&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; .github/workflows &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;touch&lt;/span&gt; .github/workflows/deploy.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we’ll be deploying files to a remote location via rsync over SSH, we’ll use the &lt;a href="https://github.com/Burnett01/rsync-deployments" rel="noopener noreferrer"&gt;burnett01/rsync-deployments&lt;/a&gt; GitHub Action:&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;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;main&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;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;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@v4&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;Rsync Deployments 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;Burnett01/rsync-deployments@7.0.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;switches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;-avzr --delete&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;static-site/*&lt;/span&gt;
          &lt;span class="na"&gt;remote_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/${{ secrets.UBERSPACE_USER }}/html/&lt;/span&gt;
          &lt;span class="na"&gt;remote_host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.UBERSPACE_HOST }}&lt;/span&gt;
          &lt;span class="na"&gt;remote_user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.UBERSPACE_USER }}&lt;/span&gt;
          &lt;span class="na"&gt;remote_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DEPLOY_KEY_PRIVATE }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: The &lt;code&gt;path&lt;/code&gt; is your local path in the repository, and the &lt;code&gt;remote_path&lt;/code&gt; is the path on Uberspace.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 3: Configure GitHub Repository Secrets: User, Host, Generated Private Key
&lt;/h3&gt;

&lt;p&gt;You’ll need to save the private SSH key you created at the beginning (&lt;code&gt;github-uberspace-keys&lt;/code&gt;) in your GitHub repository as the &lt;code&gt;DEPLOY_KEY_PRIVATE&lt;/code&gt; secret. This key will act as the deploy key (&lt;code&gt;{{ secrets.DEPLOY_KEY_PRIVATE }}&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Print out the key to copy it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; ~/Documents/uberspace-ssh-keys/github-uberspace-keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add it as a secret named &lt;code&gt;DEPLOY_KEY_PRIVATE&lt;/code&gt; in your repository’s secrets.&lt;/p&gt;

&lt;p&gt;The next two secrets — your username and the hostname of your Uberspace server — can be found on your Uberspace Dashboard. Create the following:&lt;/p&gt;

&lt;p&gt;A secret named &lt;code&gt;UBERSPACE_HOST&lt;/code&gt;, which is your hostname.&lt;br&gt;
A secret named &lt;code&gt;UBERSPACE_USER&lt;/code&gt;, which is your Uberspace username.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 4: Upload Your Generated Public Key to Uberspace
&lt;/h3&gt;

&lt;p&gt;Finally, we need to upload the generated public key to Uberspace.&lt;/p&gt;

&lt;p&gt;Print and copy the public key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; ~/Documents/uberspace-ssh-keys/github-uberspace-keys.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the next step, SSH into your Uberspace account. If you haven’t set an SSH password yet, set one on the Uberspace Dashboard under the “Access” tab.&lt;/p&gt;

&lt;p&gt;Once SSH is configured, connect to your Uberspace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &amp;lt;YOUR_UBERSPACE_USERNAME&amp;gt;@&amp;lt;YOUR_UBERSPACE_HOSTNAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;lt;YOUR_UBERSPACE_USERNAME&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;YOUR_UBERSPACE_HOSTNAME&amp;gt;&lt;/code&gt; with your Uberspace credentials.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Navigate to the &lt;code&gt;.ssh&lt;/code&gt; directory and update the &lt;code&gt;authorized_keys&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/.ssh
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don’t see an &lt;code&gt;authorized_keys&lt;/code&gt; file, SSH may not be fully set up for your account. You can refer to the Uberspace documentation for guidance.&lt;/p&gt;

&lt;p&gt;Now, add your public key to &lt;code&gt;authorized_keys&lt;/code&gt; and restrict access so it’s only allowed to rsync to your html directory.&lt;/p&gt;

&lt;p&gt;Open the file with nano:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following line, replacing &lt;code&gt;&amp;lt;username&amp;gt;&lt;/code&gt; with your Uberspace username and &lt;code&gt;&amp;lt;CONTENT_OF_YOUR_PUBLIC_KEY&amp;gt;&lt;/code&gt; with your public key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# GitHub Actions key for &amp;lt;your_repository/project&amp;gt;&lt;/span&gt;
&amp;lt;CONTENT_OF_YOUR_PUBLIC_KEY&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the file by pressing &lt;code&gt;CTRL + O&lt;/code&gt;, confirm with "Enter," and exit nano with &lt;code&gt;CTRL + X&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Test the Setup
&lt;/h3&gt;

&lt;p&gt;Push a change to your main branch, and you should see your action automatically running in the “Actions” tab.&lt;/p&gt;

&lt;p&gt;If everything went smoothly, you should see a green checkmark next to your latest action, and your content should be live on your webspace.&lt;/p&gt;

&lt;p&gt;Once everything is running, it’s a good practice to delete the generated SSH keys from your local machine and store them securely in a password manager (like Bitwarden).&lt;/p&gt;




&lt;p&gt;If you have any questions, feel free to hit me up on &lt;a href="https://twitter.com/felvct" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or on &lt;a href="https://github.com/felvct" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>productivity</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>NPM CLI Tips &amp; Tricks</title>
      <dc:creator>Felix Vaucourt</dc:creator>
      <pubDate>Mon, 27 Dec 2021 15:44:24 +0000</pubDate>
      <link>https://forem.com/felvct/npm-cli-tips-tricks-5al</link>
      <guid>https://forem.com/felvct/npm-cli-tips-tricks-5al</guid>
      <description>&lt;p&gt;If you are reading this, I am going on a whim and I will assume that you are using &lt;strong&gt;npm&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Even though, this package manager comes with a fair amount &lt;a href="https://docs.npmjs.com/cli/v8/commands" rel="noopener noreferrer"&gt;CLI commands&lt;/a&gt;, the chances are pretty high that you are using the same couple of ones in your day-to-day job.&lt;/p&gt;

&lt;p&gt;You are most likely familiar with installing and deleting packages either on a global level (accessible from anywhere on your machine) or on a local level (think of the &lt;code&gt;package.json&lt;/code&gt; in your projects).&lt;/p&gt;

&lt;p&gt;But do you really know which and how many packages are globally installed on your workstation? To be quite honest, probably not.&lt;/p&gt;

&lt;p&gt;Let's dive into it by listing all your global packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# for npm v7+&lt;/span&gt;
npm list &lt;span class="nt"&gt;-g&lt;/span&gt;

&lt;span class="c"&gt;# for npm v6 and less&lt;/span&gt;
npm list &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nt"&gt;--depth&lt;/span&gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;hint: &lt;code&gt;-g&lt;/code&gt; is the shorthand for &lt;code&gt;--global&lt;/code&gt;. You can execute all of the commands below for your local packages by omitting the &lt;code&gt;-g&lt;/code&gt; flag. And instead of using &lt;code&gt;list&lt;/code&gt; you can use &lt;code&gt;ls&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;your_user&amp;gt;/.nvm/versions/node/v16.13.0/lib
├── corepack@0.10.0
└── npm@8.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The installation path of the displayed packages will always be printed out at the top of the list&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;code&gt;--depth 0&lt;/code&gt; flag hides the dependencies of each installed package. Since npm v7, this is the default behavior of the &lt;code&gt;npm list&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;If you wish to see all packages, including their dependencies, simply add the &lt;code&gt;--all&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm list &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nt"&gt;--all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Furthermore, the &lt;code&gt;depth&lt;/code&gt; flag isn't restricted to &lt;code&gt;0&lt;/code&gt;. In fact, the trailing number represents the level of nested dependencies that you want to see. If you are interested in the top-level dependencies of your global packages, you would use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm list &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nt"&gt;--depth&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On a side note, if you installed a package in a custom location, using the &lt;code&gt;--prefix&lt;/code&gt; flag, then you will need to add the same flag (including the path) when running the &lt;code&gt;npm list&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;If you are looking for a specific package, either locally or globally, to check its version for example, you can combine &lt;code&gt;npm list&lt;/code&gt; with &lt;code&gt;grep&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm list &lt;span class="nt"&gt;-g&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &amp;lt;package&amp;gt;

&lt;span class="c"&gt;# example&lt;/span&gt;
npm list &lt;span class="nt"&gt;-g&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;rimraf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we know how to list our packages, wouldn't it be great to see if they are all up-to-date? No worries, there is a command for that as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm outdated &lt;span class="nt"&gt;-g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Do not forget to add &lt;code&gt;--depth 0&lt;/code&gt; if you are using npm v6 or less&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This will output what packages are outdated, what their latest available versions are and where they are installed.&lt;/p&gt;

&lt;p&gt;Since we just talked about the &lt;code&gt;outdated&lt;/code&gt; function, let's jump right into &lt;code&gt;update&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Thankfully, npm is smart enough to update all the packages to their latest version, respecting any constraints of both the package and its dependencies.&lt;/p&gt;

&lt;p&gt;Firstly, let's see how we can update a single package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm update &lt;span class="nt"&gt;-g&lt;/span&gt; &amp;lt;package&amp;gt;

&lt;span class="c"&gt;# example&lt;/span&gt;
npm update &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By omitting the package name, all packages in the specified location (global or local) will be updated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm update &lt;span class="nt"&gt;-g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is it. This will update all your packages and install new dependencies if needed. Easy as pie.&lt;/p&gt;

&lt;p&gt;Let's take another scenario. Imagine that you are currently developing a project and you know that you need a specific package, let's say &lt;code&gt;express&lt;/code&gt;, and you want to see what remote versions are available to you, then you would do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm view &amp;lt;package_name&amp;gt; versions

&lt;span class="c"&gt;# example&lt;/span&gt;
npm view express versions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Be aware that &lt;em&gt;versions&lt;/em&gt; is plural. This will give you a full listing of available versions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On the other hand, if you are only interested in the latest remote version, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm view &amp;lt;package_name&amp;gt; version

&lt;span class="c"&gt;# example&lt;/span&gt;
npm view express version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: &lt;em&gt;version&lt;/em&gt; is singular here&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that we know what package and what version we need, we can install specifically that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;-E&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &amp;lt;package&amp;gt;@&amp;lt;version&amp;gt;

&lt;span class="c"&gt;# example for a specific version&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;-E&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; express@4.16.4

&lt;span class="c"&gt;# example for the latest version&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;-E&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; express@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The optional &lt;code&gt;-E&lt;/code&gt; flag (shorthand for &lt;code&gt;--save-exact&lt;/code&gt;) will install and save the specific version of a package rather than using npm's default range operator.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using fixed versions within your projects is generally a good idea. In the unfortunate case that a release of a package ships with breaking changes (spoiler alert, that happened to me once - only a new minor version was released but the API of the package completely changed), this will not affect your builds. Or as we saw in recent events, some npm packages are shipped with malware or other harmful software. Being on fixed version gives you a peace of mind regarding those kind of problems.&lt;/p&gt;

&lt;p&gt;Last but not least, if you are in need of doing a clean install of your dependencies (think of continuous integration, deployment, test platforms and so on), take usage of &lt;code&gt;npm ci&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This command is also significantly faster than &lt;code&gt;npm install&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I will not reinvent the wheel for this one, so the upcoming statement is straight from the official &lt;a href="https://docs.npmjs.com/cli/v8/commands/npm-ci#description" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;"In short, the main differences between using &lt;code&gt;npm install&lt;/code&gt; and &lt;code&gt;npm ci&lt;/code&gt; are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The project must have an existing &lt;code&gt;package-lock.json&lt;/code&gt; or &lt;code&gt;npm-shrinkwrap.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If dependencies in the &lt;code&gt;package-lock&lt;/code&gt; do not match those in &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;npm ci&lt;/code&gt; will exit with an error, instead of updating the &lt;code&gt;package-lock&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;npm ci&lt;/code&gt; can only install entire projects at a time: individual dependencies cannot be added with this command.&lt;/li&gt;
&lt;li&gt;If a &lt;code&gt;node_modules&lt;/code&gt; directory is already present, it will be automatically removed before &lt;code&gt;npm ci&lt;/code&gt; begins its install.&lt;/li&gt;
&lt;li&gt;It will never write to &lt;code&gt;package.json&lt;/code&gt; or any of the package-locks: installs are essentially frozen."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are quite a few more CLI commands for npm out there. So it doesn't matter if you are new to npm or if you are using it for long time, mastering a tool always comes with a steep learning curve. This is especially true with CLI commands, since it is not a given to know most of the flags and to know what they are telling the underlying tool to do.&lt;/p&gt;

&lt;p&gt;Nonetheless, I hope that with those tips &amp;amp; tricks, you will be able to get the most out of your npm experience. Try to keep track of your global packages and to get rid of anything that is no longer needed.&lt;/p&gt;

&lt;p&gt;Another good tip for npm users, is the usage of &lt;strong&gt;npx&lt;/strong&gt; but that is a topic for a standalone article.&lt;/p&gt;




&lt;p&gt;If you have any questions, feel free to hit me up on &lt;a href="https://twitter.com/felvct" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or on &lt;a href="https://github.com/felvct" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>productivity</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Get the most out of your (remote) pair programming sessions</title>
      <dc:creator>Felix Vaucourt</dc:creator>
      <pubDate>Tue, 14 Dec 2021 17:47:11 +0000</pubDate>
      <link>https://forem.com/felvct/get-the-most-out-of-your-remote-pair-programming-sessions-2l7g</link>
      <guid>https://forem.com/felvct/get-the-most-out-of-your-remote-pair-programming-sessions-2l7g</guid>
      <description>&lt;p&gt;Most of us have heard of it and most of us have used it: pair programming.&lt;/p&gt;

&lt;p&gt;In the good old pre-covid days, pair programming involved two developers working simultaneously on the same machine. Nowadays, we tend to make it work with two separate computers, in two separate locations with the help of screen sharing but the principle remains the same. One developer, &lt;em&gt;the driver&lt;/em&gt;, should write code while the second developer, &lt;em&gt;the navigator&lt;/em&gt;, reviews the typed code in real time. Those roles should be changed frequently in order to keep the dynamic of the pairing session up.&lt;/p&gt;

&lt;p&gt;The idea behind this approach is that a higher output is being generated since teammates will be working together to solve an issue rather than working in silos. Furthermore, the constant communication in the pair allows to find the best solution, share knowledge between both parties and therefore quickly move through faced challenges.&lt;br&gt;
 &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of pair programming
&lt;/h2&gt;

&lt;p&gt;Pairing up can be more than just working on a ticket. It gives team members the opportunity to catch up and talk about their lives outside of work. The social aspect of it shouldn't be neglected, especially now that companies are shifting more and more towards remote work and engineers are getting less and less contact with their teammates.&lt;/p&gt;

&lt;p&gt;You know the old saying, &lt;em&gt;two heads are better than one&lt;/em&gt;. You should be able to freely share and discuss your thoughts and ideas on how to solve a problem. This will allow you to see the problem more clearly and to pool the knowledge of both parties to get the best outcome possible.&lt;/p&gt;

&lt;p&gt;The knowledge sharing that takes place during those sessions is another important aspect of pair programming. It will allow you to either learn or teach coding practices and how to approach and handle problems from another perspective. This will not only increase the efficiency but also the innovation and the code base knowledge while decreasing the silo knowledge within the team.&lt;/p&gt;

&lt;p&gt;Last but not least, being on "the same skill level" is not a requirement for pair programming. Pairing up a junior developer with a senior developer will benefit either of them. The junior developer will gain a significant amount of industry knowledge while the senior developer will be rewarded with a teaching experience while sharpening his/her competence to critically think about solutions.&lt;br&gt;
 &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Drawbacks of pair programming
&lt;/h2&gt;

&lt;p&gt;Until now we only spoke about the advantages of pair programming, but overdoing it can lead to inefficiency. Constantly pairing up, even for the smallest tasks and the tiniest bug fixes will lead to the navigator being left out. The communication will be non-existent since the implementation will be straight forward.&lt;/p&gt;

&lt;p&gt;A higher output would be generated if both developers would work on different tasks at the same time and not in a pair.&lt;br&gt;
 &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Remote pair programming
&lt;/h2&gt;

&lt;p&gt;Unlike other methods of in-person collaboration, pair programming works really well in a remote context. You don't lose anything of the pairing experience, you may even find it more effective.&lt;/p&gt;

&lt;p&gt;Use the advantage of not physically sitting next to your colleague. Thanks to screen sharing you will have more control of what you are looking at instead of working on one persons's screen.&lt;br&gt;
 &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Tips for remote pairing sessions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Know when to pair
&lt;/h3&gt;

&lt;p&gt;Working in an isolated, remote environment is a great experience when one is "in the zone" but having no one to talk to when you really linger on an issue makes the whole experience more difficult and frustrating.&lt;/p&gt;

&lt;p&gt;When a task is giving you a hard time and you are not able to generate any output or to create some sort of progress on it, it is time to pair up. Do not be afraid to ask for help.&lt;/p&gt;

&lt;p&gt;Keep in mind that anyone can benefit from pairing up when being stuck on a problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agenda
&lt;/h3&gt;

&lt;p&gt;No one likes to waste their time, this is why every meeting should have an agenda and a scheduled pair programming session is no exception to the rule.&lt;/p&gt;

&lt;p&gt;Do not spend the first 15 minutes of the session deciding on what to work on or going through several tickets in order to understand the problem to tackle.&lt;/p&gt;

&lt;p&gt;Set goals or expectations (this can be as simple as "let's discuss our options and decide on what path to take"), both developers should be on the same page about what to do and about what to focus on during the session.&lt;/p&gt;

&lt;h3&gt;
  
  
  Communication
&lt;/h3&gt;

&lt;p&gt;Do not be afraid to freely and openly speak your mind. Even if you say something wrong it helps the process, you will tackle the problem more quickly. By being corrected, a new idea may be sparked by you or your partner which will ultimately lead to a solution.&lt;/p&gt;

&lt;p&gt;Bounce of each other ideas and pool your knowledge in order to get the best outcome.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use your tools
&lt;/h3&gt;

&lt;p&gt;Several IDEs and text editors have tools dedicated to remote pair programming. Do yourself a favor and use them. It will give you more interaction than through screen sharing alone and therefore making the whole experience more enjoyable.&lt;/p&gt;

&lt;p&gt;Here are some tools and plugins:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/learn/collaboration/live-share" rel="noopener noreferrer"&gt;VSCode Live Share&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://teletype.atom.io/" rel="noopener noreferrer"&gt;Teletype (Atom)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tuple.app/" rel="noopener noreferrer"&gt;Tuple (macOS only)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://teamremote.github.io/remote-sublime/" rel="noopener noreferrer"&gt;Remote Collab (SublimeText)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/" rel="noopener noreferrer"&gt;CodePen&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Retros after each pairing session
&lt;/h3&gt;

&lt;p&gt;Being a good pair is not easy, regardless of your skill level. Do yourself a favor and finish your pairing session with a short retro in order to understand what worked well, what did not work and how you could improve your future sessions.&lt;/p&gt;




&lt;p&gt;If you have any questions, feel free to hit me up on &lt;a href="https://twitter.com/felvct" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or on &lt;a href="https://github.com/felvct" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>codequality</category>
      <category>programming</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
