<?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: Elio Struyf</title>
    <description>The latest articles on DEV Community by Elio Struyf (@estruyf).</description>
    <link>https://dev.to/estruyf</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%2F428343%2Faa464efa-b313-404b-8710-27403507cbbd.jpg</url>
      <title>DEV Community: Elio Struyf</title>
      <link>https://dev.to/estruyf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/estruyf"/>
    <language>en</language>
    <item>
      <title>Introduction to Demo Time – Use Visual Studio Code as your presentation tool</title>
      <dc:creator>Elio Struyf</dc:creator>
      <pubDate>Fri, 11 Apr 2025 11:07:47 +0000</pubDate>
      <link>https://dev.to/estruyf/introduction-to-demo-time-use-visual-studio-code-as-your-presentation-tool-m3m</link>
      <guid>https://dev.to/estruyf/introduction-to-demo-time-use-visual-studio-code-as-your-presentation-tool-m3m</guid>
      <description></description>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
      <category>vscode</category>
    </item>
    <item>
      <title>Demo Time v1.1.0 Released: Now with Animations and Mermaid Diagrams!</title>
      <dc:creator>Elio Struyf</dc:creator>
      <pubDate>Fri, 11 Apr 2025 10:30:39 +0000</pubDate>
      <link>https://dev.to/estruyf/demo-time-v110-released-now-with-animations-and-mermaid-diagrams-4ak7</link>
      <guid>https://dev.to/estruyf/demo-time-v110-released-now-with-animations-and-mermaid-diagrams-4ak7</guid>
      <description>&lt;p&gt;I'm excited to share that &lt;a href="https://demotime.elio.dev" rel="noopener noreferrer"&gt;&lt;strong&gt;Demo Time&lt;/strong&gt;&lt;/a&gt; just reached version &lt;strong&gt;1.1.0&lt;/strong&gt; — and it's packed with features to help you run &lt;strong&gt;smoother, more dynamic live presentations&lt;/strong&gt; directly from &lt;strong&gt;Visual Studio Code&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 What's Demo Time?
&lt;/h2&gt;

&lt;p&gt;Demo Time is a VS Code extension built to &lt;strong&gt;simplify live coding demos&lt;/strong&gt;, workshops, and technical presentations. It helps you control the pace, structure your flow, and keep everything running stress-free — all within your editor.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ What’s New in v1.1.0?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🎬 Slide Animations
&lt;/h3&gt;

&lt;p&gt;You can now animate slide content using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;fade-in&lt;/code&gt;: For a smooth entrance&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;text-typewriter&lt;/code&gt;: Type text one character at a time&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;text-highlight&lt;/code&gt;: Highlight important phrases with emphasis&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;These are great for storytelling, guiding your audience's attention, or adding that little extra polish.&lt;/p&gt;

&lt;h3&gt;
  
  
  📊 Mermaid Diagram Support
&lt;/h3&gt;

&lt;p&gt;We now support &lt;strong&gt;Mermaid.js&lt;/strong&gt; syntax directly in slides! That means you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sketch flowcharts&lt;/li&gt;
&lt;li&gt;Show sequence diagrams&lt;/li&gt;
&lt;li&gt;Visualize architecture&lt;/li&gt;
&lt;li&gt;And more...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All without leaving VS Code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw1hachy98z696qak5ra8.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw1hachy98z696qak5ra8.webp" alt="Mermaid support"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;graph TD;
  A--&amp;gt;B;
  A--&amp;gt;C;
  B--&amp;gt;D;
  C--&amp;gt;D;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will render directly on your slide during the demo!&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 How to Get It
&lt;/h2&gt;

&lt;p&gt;📥 Install or update from the &lt;a href="https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-demo-time" rel="noopener noreferrer"&gt;&lt;strong&gt;Visual Studio Code Marketplace&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📖 Full docs: &lt;a href="https://demotime.elio.dev" rel="noopener noreferrer"&gt;demotime.elio.dev&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📹 Bonus: See It In Action
&lt;/h2&gt;

&lt;p&gt;I created a short demo video showing the animations and Mermaid integration in action.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/0YlUdvnHd9s"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  🙌 Feedback Welcome!
&lt;/h2&gt;

&lt;p&gt;I’d love to hear what you think if you try it out!&lt;br&gt;&lt;br&gt;
Have ideas or run into bugs? Open an issue on GitHub or drop a comment here on DEV.&lt;/p&gt;

&lt;p&gt;Thanks for supporting Demo Time, and happy presenting!&lt;br&gt;&lt;br&gt;
🧑‍💻🎤✨&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://demotime.elio.dev" rel="noopener noreferrer"&gt;Get Demo Time for VS Code&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>devtools</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Check out this post to present your code demos without stress</title>
      <dc:creator>Elio Struyf</dc:creator>
      <pubDate>Mon, 06 Jan 2025 09:42:53 +0000</pubDate>
      <link>https://dev.to/estruyf/check-out-this-post-to-present-your-code-demos-without-stress-20h</link>
      <guid>https://dev.to/estruyf/check-out-this-post-to-present-your-code-demos-without-stress-20h</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/estruyf" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F428343%2Faa464efa-b313-404b-8710-27403507cbbd.jpg" alt="estruyf"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/estruyf/making-live-coding-demos-easier-with-demo-time-d8o" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Making Live Coding Demos Easier with Demo Time&lt;/h2&gt;
      &lt;h3&gt;Elio Struyf ・ Dec 28 '24&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#speaking&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#vscode&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>speaking</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Elio Struyf</dc:creator>
      <pubDate>Sat, 28 Dec 2024 18:05:07 +0000</pubDate>
      <link>https://dev.to/estruyf/-16k7</link>
      <guid>https://dev.to/estruyf/-16k7</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/estruyf" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F428343%2Faa464efa-b313-404b-8710-27403507cbbd.jpg" alt="estruyf"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/estruyf/making-live-coding-demos-easier-with-demo-time-d8o" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Making Live Coding Demos Easier with Demo Time&lt;/h2&gt;
      &lt;h3&gt;Elio Struyf ・ Dec 28 '24&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#speaking&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#vscode&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>speaking</category>
      <category>vscode</category>
      <category>productivity</category>
      <category>learning</category>
    </item>
    <item>
      <title>Making Live Coding Demos Easier with Demo Time</title>
      <dc:creator>Elio Struyf</dc:creator>
      <pubDate>Sat, 28 Dec 2024 17:02:19 +0000</pubDate>
      <link>https://dev.to/estruyf/making-live-coding-demos-easier-with-demo-time-d8o</link>
      <guid>https://dev.to/estruyf/making-live-coding-demos-easier-with-demo-time-d8o</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fazl7rx0rkeyqfo92sxxf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fazl7rx0rkeyqfo92sxxf.png" alt="Image description" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Live coding demos can be one of the most engaging ways to share knowledge, showcase skills, and teach others. However, they come with their fair share of challenges—technical hiccups, time constraints, or simply the fear of something going wrong in front of an audience. Enter Demo Time, a tool I created to make live coding demos easier and stress-free. From creating files, to inserting code, or highlighting certain code blocks, these actions are all possible with &lt;a href="https://demotime.elio.dev" rel="noopener noreferrer"&gt;Demo Time&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Demo Time?
&lt;/h2&gt;

&lt;p&gt;Demo Time is a Visual Studio Code extension to streamline your live coding presentations. It helps you focus on what truly matters—delivering value to your audience—by automating mundane tasks, organizing your scripts, and ensuring you’re always prepared.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step-by-step guidance&lt;/strong&gt;: Organize your demos into clear, manageable steps, so you never lose track of where you are.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation ready&lt;/strong&gt;: Run your demos with just a click, saving time and avoiding errors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visual indicators&lt;/strong&gt;: Highlight where you are in your demo flow to keep both you and your audience aligned.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable&lt;/strong&gt;: Tailor it to fit your demo style, project needs, and preferences.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visual Studio Code commands support&lt;/strong&gt;: Beside the Demo Time actions, you can also configure your demos to run Visual Studio Code commands.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Did I Create Demo Time?
&lt;/h2&gt;

&lt;p&gt;As someone who often presents live demos in sessions, I know the pressure of balancing technical accuracy with audience engagement. I wanted a tool that could act as my co-pilot, reducing the chance of errors while enabling me to deliver a polished presentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Get Started
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Visit the &lt;a href="https://demotime.elio.dev" rel="noopener noreferrer"&gt;Demo Time&lt;/a&gt; site and explore its features.&lt;/li&gt;
&lt;li&gt;Install the extension in your IDE.&lt;/li&gt;
&lt;li&gt;Create a demo script, define your steps, and customize the flow to your liking.&lt;/li&gt;
&lt;li&gt;Practice with Demo Time to ensure seamless execution during your presentation.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;On the website, you can find some &lt;a href="https://demotime.elio.dev/examples/" rel="noopener noreferrer"&gt;example projects&lt;/a&gt; and &lt;a href="https://demotime.elio.dev/examples/showcases/" rel="noopener noreferrer"&gt;showcases&lt;/a&gt; of where Demo Time is used.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conferences&lt;/strong&gt;: Simplify coding demonstrations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workshops&lt;/strong&gt;: Guide attendees through hands-on exercises.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Internal Training&lt;/strong&gt;: Make onboarding or knowledge-sharing sessions smoother.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Feedback and Collaboration
&lt;/h2&gt;

&lt;p&gt;Demo Time is a project close to my heart, and I’d love to hear your thoughts. Whether it’s ideas for new features or stories of how Demo Time helped your presentations, let’s connect and make this tool even better together.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Feel free to submit your feedback to the &lt;a href="https://github.com/estruyf/vscode-demo-time" rel="noopener noreferrer"&gt;Demo Time - GitHub repository&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Live demos don’t have to be nerve-wracking. With Demo Time, you can focus on sharing your expertise while letting the tool handle the logistics. Give it a try, and experience the difference in your next presentation!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/l2dTaHsvJ14"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>speaking</category>
      <category>webdev</category>
      <category>programming</category>
      <category>vscode</category>
    </item>
    <item>
      <title>Front Matter version 4 coming soon</title>
      <dc:creator>Elio Struyf</dc:creator>
      <pubDate>Mon, 20 Sep 2021 20:13:58 +0000</pubDate>
      <link>https://dev.to/estruyf/front-matter-version-4-coming-soon-1b8</link>
      <guid>https://dev.to/estruyf/front-matter-version-4-coming-soon-1b8</guid>
      <description>&lt;p&gt;Currently, I'm preparing the next major version of Front Matter - a full CMS running in Visual Studio Code. Front Matter allows you to customize it to your needs, like adding your own custom Node.js scripts to automate additional tasks.&lt;/p&gt;

&lt;p&gt;A big PRO about Front Matter is that you get a CMS that doesn't require any account or APIs to manage your content.&lt;/p&gt;

&lt;p&gt;In version 4 there will be a couple of big changes like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Content-Type support with new fields types: image, choice, date, ...&lt;/li&gt;
&lt;li&gt;Image selection support for your articles&lt;/li&gt;
&lt;li&gt;Team level settings: move your settings from the user workspace level to a higher level to share with the rest of your editors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmolkyoeprgt9s8rqshob.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmolkyoeprgt9s8rqshob.gif" alt="Alt Text" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It would be great if you would give Front Matter a try and a GitHub ⭐️ &lt;a href="https://github.com/estruyf/vscode-front-matter" rel="noopener noreferrer"&gt;the repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Check out the beta release notes: &lt;a href="https://beta.frontmatter.codes/updates/v4_0_0" rel="noopener noreferrer"&gt;v4.0.0 release notes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://frontmatter.codes" rel="noopener noreferrer"&gt;frontmatter.codes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>cms</category>
      <category>webdev</category>
      <category>staticsites</category>
    </item>
    <item>
      <title>Creating a VSCode extension for all other extensions</title>
      <dc:creator>Elio Struyf</dc:creator>
      <pubDate>Thu, 08 Jul 2021 12:32:11 +0000</pubDate>
      <link>https://dev.to/estruyf/creating-a-vscode-extension-for-all-other-extensions-3pgi</link>
      <guid>https://dev.to/estruyf/creating-a-vscode-extension-for-all-other-extensions-3pgi</guid>
      <description>&lt;p&gt;Earlier this week, I wanted to a couple of action buttons to the Visual Studio Code sidebar. To do this, you will need to register a button for the activity bar and create a view panel to show your sidebar actions.&lt;/p&gt;

&lt;p&gt;As this extension would only have two to three actions, it would be a bit overkill, but the use case was still there. A button makes it easier than searching the command in the command palette. This use case made me wonder, can I create an extension that another extension can use to share or enhance their experience.&lt;/p&gt;

&lt;p&gt;I wanted to make it easier for extensions to add their actions to a side panel without too much overhead. With this idea in mind, I started developing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The extension
&lt;/h2&gt;

&lt;p&gt;The extension I created is the &lt;a href="https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-extension-panel" rel="noopener noreferrer"&gt;Extension panel&lt;/a&gt;, and it offers a sidebar view panel which allows other extensions to link their actions to it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs39s9do9ti4y2juaxllr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs39s9do9ti4y2juaxllr.png" alt="Example of how it is used for the Writing Style Guide extension" width="602" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The communication flow
&lt;/h2&gt;

&lt;p&gt;As extensions run in their context, I needed to find a simple way to make it possible to share the configuration between them. &lt;/p&gt;

&lt;p&gt;The trick here is to use a VSCode command. The extension panel code, will try to execute the &lt;code&gt;&amp;lt;publisher&amp;gt;.&amp;lt;your-extension-name&amp;gt;.panel.registration&lt;/code&gt; command. To register your extension, all you need to do is specify this command with a configuration like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscriptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;vscode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commands&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;publisher&amp;gt;.&amp;lt;your-extension-name&amp;gt;.panel.registration&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;your-extension-name&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Extension actions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Actions for testing purposes only.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
                &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Action 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vscode-extension-panel.panel.test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;checkbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Action 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vscode-extension-panel.panel.test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Just extra text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;}]&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the extension panel's code executes the registration command, it will retrieve the specified configuration and show the defined actions.&lt;/p&gt;

&lt;p&gt;When there is no registration command present, it will fail internally and skip the extension.&lt;/p&gt;

&lt;p&gt;If you are an extension developer for Visual Studio Code, add your actions without writing a whole new sidebar panel. I recommend you to give the &lt;a href="https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-extension-panel" rel="noopener noreferrer"&gt;Extension Panel&lt;/a&gt; a try.&lt;/p&gt;

&lt;p&gt;PS: If you would use the extension, please submit a PR to add your extension to the README. &lt;/p&gt;

</description>
      <category>vscode</category>
      <category>extensions</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Deploy your Azure Functions as a package from GitHub Actions</title>
      <dc:creator>Elio Struyf</dc:creator>
      <pubDate>Mon, 03 May 2021 07:45:37 +0000</pubDate>
      <link>https://dev.to/estruyf/deploy-your-azure-functions-as-a-package-from-github-actions-1009</link>
      <guid>https://dev.to/estruyf/deploy-your-azure-functions-as-a-package-from-github-actions-1009</guid>
      <description>&lt;p&gt;For &lt;a href="https://squarl.com" rel="noopener noreferrer"&gt;Squarl&lt;/a&gt;, I started to implement a couple of improvements for the back-end running on Azure Functions. I created these functions with TypeScript. In the past, I used webpack and later Azure Funcpack to bundle my functions to one file per function. That way, the host does not have to do all those read actions for retrieving the dependencies.&lt;/p&gt;

&lt;p&gt;As I wanted to do the same thing, I read using Azure Funcpack is not supported/maintained anymore. Instead, you should use the &lt;strong&gt;run from package&lt;/strong&gt; functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the &lt;strong&gt;run from package&lt;/strong&gt; option?
&lt;/h2&gt;

&lt;p&gt;Instead of bundling, you install your dependencies, build your solution, and compress the directory as a ZIP file. &lt;/p&gt;

&lt;p&gt;No significant changes, but now comes the cool part. The ZIP package gets used by the Azure Functions to run the function's logic. Instead of pushing your files to the &lt;code&gt;wwwroot&lt;/code&gt; directory, the app service loads the ZIP package as a virtual directory.&lt;/p&gt;

&lt;p&gt;This option improves the load times, deployment times, and more.&lt;/p&gt;

&lt;p&gt;If you want to use this functionality, you will have to set the &lt;code&gt;WEBSITE_RUN_FROM_PACKAGE&lt;/code&gt; setting on your function app.&lt;/p&gt;

&lt;p&gt;The value for this can refer to where the function app can find the ZIP package, or it can just be &lt;code&gt;1&lt;/code&gt;. This option is the recommended approach when running apps on Windows. &lt;/p&gt;

&lt;p&gt;When using &lt;code&gt;1&lt;/code&gt; as the value, the function app will run the data from a local package. The ZIP package needs to be deployed to &lt;code&gt;d:\home\data\SitePackages&lt;/code&gt; as this improves the cold-start.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Info&lt;/strong&gt;: You can read more at: &lt;a href="https://docs.microsoft.com/en-gb/azure/azure-functions/run-functions-from-deployment-package#adding-the-website_run_from_package-setting" rel="noopener noreferrer"&gt;run your Azure Functions from a package file&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How do you use it on GitHub Actions?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: Make sure to first set the &lt;code&gt;WEBSITE_RUN_FROM_PACKAGE&lt;/code&gt; to &lt;code&gt;1&lt;/code&gt; in the function app configuration.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The steps which you need to perform to deploy your code to the functions app are the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check out your code&lt;/li&gt;
&lt;li&gt;Specify the Node.js version to use&lt;/li&gt;
&lt;li&gt;Install your dependencies&lt;/li&gt;
&lt;li&gt;Build your project&lt;/li&gt;
&lt;li&gt;Create the ZIP&lt;/li&gt;
&lt;li&gt;Perform the deployment with the &lt;code&gt;webapps-deploy&lt;/code&gt; action&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My GitHub Actions workflow looks as follows:&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;deploy_az&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;windows-latest&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;back-end"&lt;/span&gt;
  &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ !contains(github.event.head_commit.message, '#frontend') }}&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&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/setup-node@v1&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;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;12'&lt;/span&gt;
        &lt;span class="na"&gt;registry-url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://registry.npmjs.org/&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Install&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;build"&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;npm ci&lt;/span&gt;
        &lt;span class="s"&gt;npm run build&lt;/span&gt;
        &lt;span class="s"&gt;npm prune --production&lt;/span&gt;

    &lt;span class="c1"&gt;# You can also make use of a ZIP GitHub Action&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Create&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ZIP"&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;Get-ChildItem $pwd | Compress-Archive -Destination .\backend.zip&lt;/span&gt;
      &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pwsh&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="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ZIP&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;app'&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;azure/webapps-deploy@v2&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;app-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.AZURE_FUNCTIONAPP_NAME }}&lt;/span&gt;
        &lt;span class="na"&gt;publish-profile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE_DEV }}&lt;/span&gt;
        &lt;span class="na"&gt;package&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./backend.zip&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this workflow ran. Your function app will now run from the package you deployed. You can verify this if you take a look in the &lt;code&gt;wwwroot&lt;/code&gt; directory. This directory should now contain the files from the package. Be aware; this directory is now read-only.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faajg890kbsprec9ucc4a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faajg890kbsprec9ucc4a.png" alt="The packages pushed to your Azure Function" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Info&lt;/strong&gt;: The &lt;code&gt;packagename.txt&lt;/code&gt; file contains the name of the ZIP package which needs to be used.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>github</category>
      <category>githubactions</category>
      <category>azure</category>
      <category>azurefunctions</category>
    </item>
    <item>
      <title>Deploy your site to Vercel using GitHub Actions and Releases</title>
      <dc:creator>Elio Struyf</dc:creator>
      <pubDate>Tue, 27 Apr 2021 06:56:15 +0000</pubDate>
      <link>https://dev.to/estruyf/deploy-your-site-to-vercel-using-github-actions-and-releases-1l3l</link>
      <guid>https://dev.to/estruyf/deploy-your-site-to-vercel-using-github-actions-and-releases-1l3l</guid>
      <description>&lt;p&gt;One of my favorite hosting companies is &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt; as they can provide simplicity and flexibility at the same time. I wanted to control my site's deployment process on Vercel entirely for a new product I am building.&lt;/p&gt;

&lt;p&gt;Usually, when you use Vercel in combination with GitHub. It will automatically trigger new deployments when you push code. You can configure it to your needs, but the main issue is when you want to work with GitHub releases. Vercel cannot yet deploy on new releases. &lt;/p&gt;

&lt;p&gt;There are a couple of ways to overcome this. You can, for instance, start a build by calling Vercel with a &lt;strong&gt;deploy hook&lt;/strong&gt;. That way, you can call the hook from within your GitHub Actions workflow.&lt;/p&gt;

&lt;p&gt;Another approach is to make use of the Vercel CLI and the combination of GitHub Actions. This approach is the one I used, as this gave me all the flexibility I needed during my CI/CD process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you start, you need to know your &lt;strong&gt;project ID&lt;/strong&gt; and &lt;strong&gt;org ID&lt;/strong&gt; from Vercel. The simplest way to get this is to link your project to Vercel. You can do this by using &lt;code&gt;npx vercel link&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Info&lt;/strong&gt;: You read more about the CLI here: &lt;a href="https://vercel.com/docs/cli" rel="noopener noreferrer"&gt;Vercel CLI&lt;/a&gt;. When you have not used it yet, it will first ask you to sign in. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When you ran the command, it will create a &lt;code&gt;.vercel&lt;/code&gt; folder in your project with a &lt;code&gt;project.json&lt;/code&gt; file. In that file, you will find the &lt;code&gt;projectId&lt;/code&gt; and &lt;code&gt;orgId&lt;/code&gt;, which you can use later in your GitHub Actions workflow.&lt;/p&gt;

&lt;p&gt;Something else you need to configure is to disable GitHub for your project on Vercel. That way, you let Vercel know that you want to take over control, and it will not trigger when you push your code to GitHub. &lt;/p&gt;

&lt;p&gt;To disable GitHub, you create a &lt;code&gt;vercel.json&lt;/code&gt; file in the root of your project (if it does not yet exist), and add the following contents to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"github"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"silent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;One more thing&lt;/em&gt;, a &lt;code&gt;token&lt;/code&gt; is required to use the CLI on GitHub Actions. &lt;/p&gt;

&lt;p&gt;Go to &lt;a href="https://vercel.com/account/tokens" rel="noopener noreferrer"&gt;Vercel Tokens&lt;/a&gt;, and create a new token. Keep this token safe, as you will need it later.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Secrets to configure
&lt;/h2&gt;

&lt;p&gt;In your GitHub project, go to settings and add the following secrets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VERCEL_ORG_ID&lt;/strong&gt;: Value is the &lt;code&gt;orgId&lt;/code&gt; from the JSON file created with the &lt;code&gt;vercel link&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VERCEL_PROJECT_ID&lt;/strong&gt;: Value is the &lt;code&gt;projectId&lt;/code&gt; from the JSON file created with the &lt;code&gt;vercel link&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VERCEL_TOKEN&lt;/strong&gt;: Value is the token you created previously.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqcxvtzr66zke6cyjt9gt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqcxvtzr66zke6cyjt9gt.png" alt="GitHub Secrets" width="217" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;The last step is to add the job to your GitHub workflow. Here is an example of how you could do this:&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Deploy"&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;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;published&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;dev&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&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;vercel&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;front-end"&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&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/setup-node@v1&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;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;14'&lt;/span&gt;
          &lt;span class="na"&gt;registry-url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://registry.npmjs.org/&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Vercel"&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;prodRun=""&lt;/span&gt;
          &lt;span class="s"&gt;if [[ ${GITHUB_REF} == "refs/heads/main" ]]; then&lt;/span&gt;
            &lt;span class="s"&gt;prodRun="--prod"&lt;/span&gt;
          &lt;span class="s"&gt;fi&lt;/span&gt;

          &lt;span class="s"&gt;npx vercel --token ${VERCEL_TOKEN} $prodRun&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;VERCEL_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.VERCEL_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;VERCEL_PROJECT_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.VERCEL_PROJECT_ID }}&lt;/span&gt;
          &lt;span class="na"&gt;VERCEL_ORG_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.VERCEL_ORG_ID }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Info&lt;/strong&gt;: When the action runs for any other branch than my &lt;code&gt;main&lt;/code&gt; branch, it will not deploy to production.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As you can see from the above workflow, the GitHub Actions workflow only gets triggered when there is a release, push to &lt;code&gt;dev&lt;/code&gt;, or manual trigger on the workflow.&lt;/p&gt;

&lt;p&gt;Once you put this workflow in place, you are in control over all deployments to Vercel.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Article first published on &lt;a href="https://www.eliostruyf.com/deploy-site-vercel-github-actions-releases/" rel="noopener noreferrer"&gt;eliostruyf.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>vercel</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>New VSCode extension that takes automation to the next level</title>
      <dc:creator>Elio Struyf</dc:creator>
      <pubDate>Thu, 22 Apr 2021 08:14:32 +0000</pubDate>
      <link>https://dev.to/estruyf/new-vscode-extension-that-take-automation-to-the-next-level-3mcd</link>
      <guid>https://dev.to/estruyf/new-vscode-extension-that-take-automation-to-the-next-level-3mcd</guid>
      <description>&lt;p&gt;Recently I switched from using Alfred over to &lt;a href="https://raycast.com/" rel="noopener noreferrer"&gt;Raycast&lt;/a&gt;. What convinced me of Raycast is the simplicity the tool provides, plus the ability to simply create your custom commands/scripts.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Info&lt;/strong&gt;: I already wrote about it: &lt;a href="https://dev.to/estruyf/devhack-using-raycast-to-speed-up-my-productivity-1h4k"&gt;Using Raycast to speed up my productivity&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The more I use Raycast, the more I want to automate. A script I created was to start up my daily development tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open my VSCode editor with the right project loaded&lt;/li&gt;
&lt;li&gt;Open my terminal to the right folder&lt;/li&gt;
&lt;li&gt;Open &lt;code&gt;Microsoft Edge&lt;/code&gt; to the Azure Portal&lt;/li&gt;
&lt;li&gt;Open &lt;code&gt;Google Chrome&lt;/code&gt; with my application URL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tasks typically do not take a lot of time, but automating this by one command is so easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Taking it to the next level
&lt;/h2&gt;

&lt;p&gt;To take it to the next level, I wanted to start my commands in VSCode as well. For my project I use two terminals:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;code&gt;ngrok&lt;/code&gt; as my application needs to be accessible remotely.&lt;/li&gt;
&lt;li&gt;Start the local development server (Next.js in my case).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Unfortunately, you can only trigger certain actions in VSCode by shortcuts. That is why I thought to create a new VSCode &lt;code&gt;Remote Control&lt;/code&gt; extension which allows you to send commands from anywhere on your device to the running VSCode instance. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Info&lt;/strong&gt;: Check out the extension here: &lt;a href="https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-remote-control" rel="noopener noreferrer"&gt;VSCode Remote Control&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The extension spins up a &lt;code&gt;WebSocket&lt;/code&gt; server. By default, it will start it on port: &lt;code&gt;3710&lt;/code&gt;, but is configurable from the settings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Show me what it can do
&lt;/h2&gt;

&lt;p&gt;To speed up my process, I wanted to open two terminal instances in VSCode and run my commands in each of them.&lt;/p&gt;

&lt;p&gt;In my Raycast script, all I had to do is add the following code:&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;echo&lt;/span&gt; &lt;span class="s2"&gt;"{ &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;command&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;workbench.action.terminal.newWithCwd&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; }"&lt;/span&gt; | websocat ws://localhost:3710
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"{ &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;command&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;workbench.action.terminal.sendSequence&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;args&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: { &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;npm run ngrok&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; } }"&lt;/span&gt; | websocat ws://localhost:3710
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"{ &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;command&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;workbench.action.terminal.split&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; }"&lt;/span&gt; | websocat ws://localhost:3710
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"{ &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;command&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;workbench.action.terminal.focusAtIndex2&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; }"&lt;/span&gt; | websocat ws://localhost:3710
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"{ &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;command&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;workbench.action.terminal.sendSequence&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;args&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: { &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;cd solutions/msteams/webapp &amp;amp;&amp;amp; npm run dev&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; } }"&lt;/span&gt; | websocat ws://localhost:3710
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: this is not only created for Raycast. Once installed, you can run commands from anywhere on your device.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here the result of this script:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkh8wmqiqqyic2fdkpjy8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkh8wmqiqqyic2fdkpjy8.gif" alt="The result of the script" width="600" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check out the VSCode extension here: &lt;a href="https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-remote-control" rel="noopener noreferrer"&gt;VSCode Remote Control&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>vscode</category>
      <category>bash</category>
      <category>tooling</category>
    </item>
    <item>
      <title>#DevHack: Using Raycast to speed up my productivity</title>
      <dc:creator>Elio Struyf</dc:creator>
      <pubDate>Mon, 12 Apr 2021 08:04:24 +0000</pubDate>
      <link>https://dev.to/estruyf/devhack-using-raycast-to-speed-up-my-productivity-1h4k</link>
      <guid>https://dev.to/estruyf/devhack-using-raycast-to-speed-up-my-productivity-1h4k</guid>
      <description>&lt;p&gt;It does not happen often I write an article about a tool, but this time, I felt this tool deserved some extra attention.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://raycast.com/" rel="noopener noreferrer"&gt;Raycast&lt;/a&gt; is a tool that you can compare to Spotlight from macOS and &lt;a href="https://www.alfredapp.com/" rel="noopener noreferrer"&gt;Alfred&lt;/a&gt;, and yes, it is macOS only. &lt;/p&gt;

&lt;p&gt;Many people use Alfred, and I have been using Alfred since I had my first Macbook. The biggest advantage of these applications is that you can quickly search your apps or execute tasks. What differentiates Raycast is that it is free, and it is straightforward to add custom scripts. You can write these scripts in &lt;code&gt;bash&lt;/code&gt;, &lt;code&gt;python&lt;/code&gt;, &lt;code&gt;nodejs&lt;/code&gt;, and more.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: They listen to feedback. I submitted feedback about the font size. In my opinion, it was a bit too small. In less than a week, the Raycast team released an update with this functionality implemented. Not only that, the team even sent an email thanking me for the feedback. ❤️&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How I got interested
&lt;/h2&gt;

&lt;p&gt;It all started with an order on &lt;a href="https://pimpyourowndevice.com" rel="noopener noreferrer"&gt;Pimp Your Own Device&lt;/a&gt;. There was a bug in the search React I wrote for the site. Luckily, the person who wanted to place an order was so nice to send us a message. &lt;/p&gt;

&lt;p&gt;We talked a bit, and I saw she was working at Raycast, so I asked what it was. That is how it got me interested in testing out the product. I removed Alfred and installed Raycast instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can it help you
&lt;/h2&gt;

&lt;p&gt;Apart from searching your applications, the most significant productivity boost it will give you is the custom scripts you can add. For sure, you will have many manual tasks you have to do daily to start your work.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Info&lt;/strong&gt;: Follow the steps in the following repository to get started with custom script creation for Raycast: &lt;a href="https://github.com/raycast/script-commands" rel="noopener noreferrer"&gt;Raycast Script Commands&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For instance, what I do frequently is open the Azure Portal. As I have various accounts, I always need to open the correct browser with the right profile.&lt;/p&gt;

&lt;p&gt;My first improvement would be to create a script to open the portal in the right browser and profile.&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;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Required parameters:&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.schemaVersion 1&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.title Open Azure Portal (personal)&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.mode silent&lt;/span&gt;

&lt;span class="c"&gt;# Optional parameters:&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.icon 🚀&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.packageName estruyf.azure.portal&lt;/span&gt;

&lt;span class="c"&gt;# Documentation:&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.author Elio Struyf&lt;/span&gt;

&lt;span class="nv"&gt;hs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;hostname&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$hs&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"ninja.local"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;
&lt;span class="k"&gt;then
  &lt;/span&gt;open &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="s2"&gt;"Google Chrome"&lt;/span&gt; &lt;span class="s1"&gt;'https://portal.azure.com'&lt;/span&gt; &lt;span class="nt"&gt;--args&lt;/span&gt; &lt;span class="nt"&gt;--profile-directory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Default
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Implementation for second machine"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Info&lt;/strong&gt;: The script is simple. In my case, I check my hostname to know where I am running the script as I work on two machines.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzlhmpdckeqsxzd8a9n3r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzlhmpdckeqsxzd8a9n3r.png" alt="Run the open Azure Portal script" width="789" height="171"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;That is not it. Another improvement that makes things even quicker is to get my development flow started just by running the script. Why? In my case, when I am developing for a Microsoft Teams project, I need to open:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Browser with the right profile for Microsoft Teams&lt;/li&gt;
&lt;li&gt;Browser with the right profile for the Azure Profile (another account)&lt;/li&gt;
&lt;li&gt;Visual Studio Code with the project&lt;/li&gt;
&lt;li&gt;Terminal opened in the project folder&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The script for this looks 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;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Required parameters:&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.schemaVersion 1&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.title Open Squarl project&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.mode silent&lt;/span&gt;

&lt;span class="c"&gt;# Optional parameters:&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.icon 🚀&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.packageName estruyf.code.squarl&lt;/span&gt;

&lt;span class="c"&gt;# Documentation:&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.author Elio Struyf&lt;/span&gt;

&lt;span class="nv"&gt;hs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;hostname&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$hs&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"ninja.local"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;
&lt;span class="k"&gt;then
  &lt;/span&gt;code ~/&amp;lt;path-to-project&amp;gt;
  hyper ~/&amp;lt;path-to-project&amp;gt;
  open &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="s2"&gt;"Google Chrome Canary"&lt;/span&gt; &lt;span class="s1"&gt;'https://teams.microsoft.com/'&lt;/span&gt; &lt;span class="nt"&gt;--args&lt;/span&gt; &lt;span class="nt"&gt;--profile-directory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Profile 9"&lt;/span&gt;
  open &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="s2"&gt;"Google Chrome"&lt;/span&gt; &lt;span class="s1"&gt;'https://portal.azure.com'&lt;/span&gt; &lt;span class="nt"&gt;--args&lt;/span&gt; &lt;span class="nt"&gt;--profile-directory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Default
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Implementation for second machine"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I can just run my command, and it will automatically open all these instances.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr36s7ehe4d0dpvtj9obz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr36s7ehe4d0dpvtj9obz.png" alt="Run the get started with developing your project" width="792" height="171"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;One more, for my blog, I place all the images in a &lt;code&gt;year/month&lt;/code&gt; folder. This structure is still leftover from the WordPress days. I just kept the format. Each time I write an article like this one and want to add an image, I have to open that particular folder. With a custom script, I can now quickly open that folder, and if it does not exist, it will be created. Great for when we started a new month.&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;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Required parameters:&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.schemaVersion 1&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.title Open blog screenshots&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.mode silent&lt;/span&gt;

&lt;span class="c"&gt;# Optional parameters:&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.icon 🏙&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.packageName estruyf.code.squarl&lt;/span&gt;

&lt;span class="c"&gt;# Documentation:&lt;/span&gt;
&lt;span class="c"&gt;# @raycast.author Elio Struyf&lt;/span&gt;

&lt;span class="nv"&gt;crntYear&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +&lt;span class="s1"&gt;'%Y'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;crntMonth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +&lt;span class="s1"&gt;'%m'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;monthDir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/blog/web-eliostruyf-hugo/static/uploads/&lt;span class="nv"&gt;$crntYear&lt;/span&gt;/&lt;span class="nv"&gt;$crntMonth&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$monthDir&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$monthDir&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
open &lt;span class="nv"&gt;$monthDir&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjy10vguc4t5f5dnu1jfz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjy10vguc4t5f5dnu1jfz.png" alt="Quickly open the blog images folder" width="790" height="170"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: For the icon, you can add a base64 encoded image. That way, you do not have to link it to a local or online file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;I hope Raycast will improve your flow as well. Article first published on &lt;a href="https://www.eliostruyf.com/devhack-raycast-speed-productivity/" rel="noopener noreferrer"&gt;eliostruyf.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>bash</category>
      <category>tooling</category>
    </item>
    <item>
      <title>#DevHack: Caching data for your VSCode extension</title>
      <dc:creator>Elio Struyf</dc:creator>
      <pubDate>Wed, 24 Mar 2021 13:55:26 +0000</pubDate>
      <link>https://dev.to/estruyf/devhack-caching-data-for-your-vscode-extension-11gb</link>
      <guid>https://dev.to/estruyf/devhack-caching-data-for-your-vscode-extension-11gb</guid>
      <description>&lt;p&gt;For my &lt;a href="https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-msgraph-autocomplete" rel="noopener noreferrer"&gt;Visual Studio Code extension&lt;/a&gt; to autocomplete the Microsoft Graph APIs, I wanted to improve the speed of the suggestions by implementing a cache. That way, you would not have to do the same API calls each time.&lt;/p&gt;

&lt;h2&gt;
  
  
  In-memory cache has its limits
&lt;/h2&gt;

&lt;p&gt;Initially, I started with just an in-memory cache. An in-memory cache is easy to establish, but whenever you close your VSCode session. The cache will be gone. Next time, the cache has to be created all from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the options?
&lt;/h2&gt;

&lt;p&gt;Luckily VSCode provides you a couple of options to cache data for your extension. There are two places where you can cache data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;workspaceState&lt;/code&gt;: When you want to cache data for the current workspace/project.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;globalState&lt;/code&gt;: When you want to cache data independent of your current project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both of these states are a &lt;code&gt;Memento&lt;/code&gt; object, which allows you to &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt; a value.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Info&lt;/strong&gt;: There is also a &lt;code&gt;SecretStorage&lt;/code&gt; which can be used to set/retrieve/delete secrets.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Using the VSCode state
&lt;/h2&gt;

&lt;p&gt;For my extension, I choose to use the &lt;code&gt;globalState&lt;/code&gt;, as I want to cache the Microsoft Graph data independently from the current project. Using the &lt;code&gt;workspaceState&lt;/code&gt; is similar to the &lt;code&gt;globalState&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Start by creating the cache as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;activate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;vscode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ExtensionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;defaultData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CacheObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="na"&gt;beta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cacheName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;EXTENSION_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_cache`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;globalState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CacheObject&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defaultData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once created, you can put data into the cache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Add API response to the right API version of the cache&lt;/span&gt;
&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;apiData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;globalState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you added the data. You can start retrieving it as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;globalState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CacheObject&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Currently, you can only get and update data, you cannot clear/delete the cache. If you can override the cache with a default value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;globalState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Info&lt;/strong&gt;: You can find a complete example of using the VSCode state here: &lt;a href="https://github.com/estruyf/vscode-msgraph-autocomplete/blob/main/src/providers/CacheProvider.ts" rel="noopener noreferrer"&gt;CacheProvider.ts&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Article first publish on &lt;a href="https://www.eliostruyf.com/devhack-caching-data-vscode-extension/" rel="noopener noreferrer"&gt;eliostruyf.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>extensions</category>
      <category>vscode</category>
      <category>caching</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
