<?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: Geert-Jan Zwiers</title>
    <description>The latest articles on DEV Community by Geert-Jan Zwiers (@gjzwiers).</description>
    <link>https://dev.to/gjzwiers</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%2F740144%2F9d3c97e4-5746-4064-b803-749420d8b7ca.jpeg</url>
      <title>DEV Community: Geert-Jan Zwiers</title>
      <link>https://dev.to/gjzwiers</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gjzwiers"/>
    <language>en</language>
    <item>
      <title>Away with your Errors - A Short Tutorial on Running Sentry with Deno</title>
      <dc:creator>Geert-Jan Zwiers</dc:creator>
      <pubDate>Tue, 28 Jun 2022 13:03:10 +0000</pubDate>
      <link>https://dev.to/gjzwiers/away-with-your-errors-a-short-tutorial-on-running-sentry-with-deno-4nld</link>
      <guid>https://dev.to/gjzwiers/away-with-your-errors-a-short-tutorial-on-running-sentry-with-deno-4nld</guid>
      <description>&lt;p&gt;&lt;em&gt;Cover image credit: Arc'blroth; &lt;a href="https://deno.land/artwork"&gt;image link&lt;/a&gt;; CC-BY-SA-4.0&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Recently, I decided to see if one can run the Sentry SDK for JavaScript on Deno. If you have not heard of Sentry, it is a tool for tracking errors and can be especially useful when working in complex environments such as cloud-native apps with multiple containerized services. Sentry can be used to capture errors and warnings and send them to a centralized dashboard, providing an overview of what might be going awry at any given time.&lt;/p&gt;

&lt;p&gt;Although there seems to be no dedicated Sentry module for Deno just yet, Deno comes with the option to run a program in Node compatibility mode. This mode allows running 'hybrid' programs, meaning you can install certain Node packages like you normally would with npm, and then use them alongside code written for Deno. Quite an impressive amount of Node programs can work this way, though not everything. Mostly, it is meant to ease the transition to Deno for Node developers. In this tutorial, I will show how to use Deno's Node compatibility mode to run the Sentry SDK and send an application error to the Sentry dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Deno installed on your machine. You can get it from &lt;a href="https://deno.land/#installation"&gt;deno.land&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Node and npm installed on your machine. You can get them from &lt;a href="https://nodejs.org/en/"&gt;nodejs.org&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A Sentry account. They have a &lt;a href="https://sentry.io/pricing/"&gt;free plan&lt;/a&gt; available for developers which will do nicely for the purposes of this tutorial. They also have a trial for the more advanced plans in case you're interested in exploring that.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;p&gt;Start by making a new directory for the program. Because we want to use the Node compatibility mode with Deno, we do need to install the npm packages that we want to use, so in the new directory run &lt;code&gt;npm init -y&lt;/code&gt; for a default &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;npm install @sentry/node @sentry/tracing&lt;/code&gt; to install the Sentry SDK. You should now have a directory with a &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;package-lock.json&lt;/code&gt; and the &lt;code&gt;node_modules&lt;/code&gt; directory containing the node dependencies.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Code
&lt;/h3&gt;

&lt;p&gt;Create a new file &lt;code&gt;main.mjs&lt;/code&gt;. This will be a JavaScript module in which we will test that the Sentry integration works. First, we import Sentry from the npm package like we would in Node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Sentry&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@sentry/node&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sentry recommends running &lt;code&gt;Sentry.init&lt;/code&gt; as early on as possible in the program, so we will do that next. For this we need to login to Sentry, go to Projects and click Create Project. Choose Node.js  as the platform (Deno is not yet listed as an option here) and give a name to the project. On the next page Sentry will show a quickstart, copy the following lines into &lt;code&gt;main.mjs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Sentry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;dsn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;my-sentry-dsn&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;tracesSampleRate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.0&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;Replace &lt;code&gt;&amp;lt;my-sentry-dsn&amp;gt;&lt;/code&gt; with the actual Data Source Name (DSN) shown in the quickstart. This string is used by Sentry to figure out where to send events to.&lt;/p&gt;

&lt;p&gt;Now we can add some code to generate a test event and see if it is sent to Sentry successfully. Change the contents of &lt;code&gt;main.mjs&lt;/code&gt; to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Sentry&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@sentry/node&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://deno.land/std@0.145.0/log/mod.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;Sentry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;dsn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;my-sentry-dsn&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;tracesSampleRate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;testEvent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sending test event to Sentry.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Nope.&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="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Sentry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;captureException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;Sentry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flush&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;testEvent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the &lt;code&gt;log&lt;/code&gt; import from the Deno standard library (&lt;code&gt;std&lt;/code&gt;). &lt;br&gt;
To understand what is happening, it is important to know that Deno and Node use different systems to resolve JavaScript modules. Node relies heavily on the node_modules directory while Deno utilizes URLs. With Node compatibility mode it is possible to use both 'styles' together in a file.&lt;/p&gt;

&lt;p&gt;When you're ready, run the following command from a terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deno run --compat --allow-read --allow-env --allow-net --unstable main.mjs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important thing here is the &lt;code&gt;--compat&lt;/code&gt; option, which enables the Node compatibility mode. If you are interested in how this works behind the scenes, you can find more info on it &lt;a href="https://deno.land/manual/node/compatibility_mode#how-does-it-work"&gt;in the deno manual&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When you run the command, you will probably see a few warning messages in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Not implemented: process.on("uncaughtException")
Not implemented: process.on("unhandledRejection")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are Node methods of the &lt;code&gt;process&lt;/code&gt; global that are not available in Deno compatibility mode (yet). This does mean that certain parts of the Sentry SDK are not fully compatible with Deno at the moment, but luckily it does not matter for the example shown in this tutorial. After the program has run, go to the Sentry dashboard, refresh the page (or enable real-time updates) and you should see the error appear:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IKpRbNF3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5elm48sdpf08qkcgxgoq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IKpRbNF3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5elm48sdpf08qkcgxgoq.png" alt="sentry error" width="363" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This short tutorial covered how to use the Sentry SDK for JavaScript in a Deno program and run it in Node compatibility mode. This shows how many Node programs can be re-used in Deno, which is very beneficial to speeding up development until the Deno ecosystem has grown enough that it provides a module of its own.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A Deno-licious Workflow</title>
      <dc:creator>Geert-Jan Zwiers</dc:creator>
      <pubDate>Sun, 14 Nov 2021 12:37:28 +0000</pubDate>
      <link>https://dev.to/gjzwiers/a-deno-licious-workflow-30cm</link>
      <guid>https://dev.to/gjzwiers/a-deno-licious-workflow-30cm</guid>
      <description>&lt;p&gt;If there is one project that has increased my developer happiness, it is probably Deno. One of the best things is the ease at which one can set up a coding workflow and maintain a project with the combination of Deno, Git and the GitHub CLI.&lt;/p&gt;

&lt;p&gt;With this workflow, pull requests (PRs) can be made and merged from a terminal, release notes can be generated automatically and releases are made in the blink of an eye. Once you get used to this workflow, it feels about as fluent as coding gets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A GitHub Account&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;deno&lt;/code&gt; installed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gh&lt;/code&gt; (&lt;a href="https://cli.github.com/"&gt;GitHub CLI&lt;/a&gt;) installed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git&lt;/code&gt; installed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Recommended:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an autocompletion tool for your terminal, e.g. &lt;a href="https://ohmyz.sh/"&gt;oh-my-zsh&lt;/a&gt; for the &lt;code&gt;zsh&lt;/code&gt; shell or &lt;a href="https://github.com/dahlbyk/posh-git"&gt;posh-git&lt;/a&gt; for PowerShell&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up verified commits
&lt;/h2&gt;

&lt;p&gt;As Deno places more emphasis on security, let's begin by creating a key to sign our commits with. This way we can make verified commits that prove we are not some impostor trying to upload a million cat.jpg files or something. In a way, GPG keys are an implementation of 'Just be yourself'!&lt;/p&gt;

&lt;p&gt;Read how to generate a GPG key for GitHub &lt;a href="https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key"&gt;here&lt;/a&gt; and &lt;a href="https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-new-gpg-key-to-your-github-account"&gt;adding it&lt;/a&gt; to your account.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a module
&lt;/h2&gt;

&lt;p&gt;One convention in Deno is to have a file &lt;code&gt;mod.ts&lt;/code&gt; as entrypoint and two files &lt;code&gt;deps.ts&lt;/code&gt; and &lt;code&gt;dev_deps.ts&lt;/code&gt; as places to import other modules for use throughout yours. Note that the filenames have no special meaning in Deno, they are merely a convention. We'd probably like a &lt;code&gt;.gitignore&lt;/code&gt; file as well, but I know what you're thinking: Do I really have to make four whole files by hand? No way! Okay, hang on, because there is a solution. Just run &lt;code&gt;mod&lt;/code&gt; which is a deno CLI program that scaffolds a basic module for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deno install --allow-read --allow-run=git --allow-write --name mod https://deno.land/x/mod/mod.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mod -n my_deno_project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes a directory &lt;code&gt;my_deno_project&lt;/code&gt; in the current working directory with the files we just mentioned and runs &lt;code&gt;git init&lt;/code&gt; for us. Of course, you can name the directory whatever you like. &lt;/p&gt;

&lt;h2&gt;
  
  
  Uploading to GitHub
&lt;/h2&gt;

&lt;p&gt;Let's add the code to a remote repository by making a verified commit using our new GPG key. Configure git to require signing commits by running the following command in &lt;code&gt;my_deno_project&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config commit.gpgsign true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, add your files to the working tree and make the first commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add .
git commit -m "initial commit"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point you should be prompted to enter your GPG key's password to sign the commit with. Now we can send this code to a remote repository on GitHub with the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh repo create 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will let you make a new remote repository interactively, but if you already know what you want you can use something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh repo create my_deno_project --confirm --public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check that the remote repo was created successfully, then push the local files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push -u origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Protecting the main branch
&lt;/h2&gt;

&lt;p&gt;Now that the initial code is on GitHub it's time to setup branch protection that ensures we can only merge changes to the main branch via pull requests. The major benefit of doing this is that all changes can be checked and reviewed before being included in any sort of release.&lt;/p&gt;

&lt;p&gt;Go to the project on GitHub and go to the Settings tab, then go to Branches. Add a rule with the branch name pattern &lt;code&gt;main&lt;/code&gt; and enable the setting "Require a pull request before merging" and also turn on "Include administrators". There is another setting that we want to enable: "Require status checks to pass before merging", but we probably want to have actual checks before enabling it.&lt;/p&gt;

&lt;p&gt;We'll add some code and a pipeline soon, but let's do all of that in a new branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout -b first_feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding Continuous Integration
&lt;/h2&gt;

&lt;p&gt;When developing modules for Deno there are three steps that can be achieved quite easily using built-in &lt;code&gt;deno&lt;/code&gt; subcommands. These are formatting code with &lt;code&gt;deno fmt&lt;/code&gt;, linting code with &lt;code&gt;deno lint&lt;/code&gt; and running unit and/or integration tests with &lt;code&gt;deno test&lt;/code&gt;. Using GitHub Actions we can also include these steps in a Continuous Integration (CI) pipeline that will run anytime we push changes to the remote.&lt;/p&gt;

&lt;p&gt;Wait a minute, do we have to add a whole pipeline manually now? Nope! We can use &lt;code&gt;mod&lt;/code&gt; to create a basic pipeline for us! In the current working directory (&lt;code&gt;my_deno_project&lt;/code&gt;) run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mod --ci
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now have a &lt;code&gt;.github&lt;/code&gt; directory with a &lt;code&gt;workflows&lt;/code&gt; subdirectory and a &lt;code&gt;build.yaml&lt;/code&gt; file. Note that &lt;code&gt;mod&lt;/code&gt; doesn't overwrite existing files (you should see some warnings about that), so we could use it to add these additional files do the project.&lt;/p&gt;

&lt;p&gt;If you go into &lt;code&gt;build.yaml&lt;/code&gt;, you can see it has a basic pipeline structure for Deno that includes the aforementioned steps. It will format, lint and test the code. Only problem with that is we don't have any code yet! Let's fix that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test-Driven Development
&lt;/h2&gt;

&lt;p&gt;To make a high-quality module means having well-tested code, amongst other things. Add the following line to &lt;code&gt;dev_deps.ts&lt;/code&gt;:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;assertEquals&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://deno.land/std@0.114.0/testing/asserts.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idea of Test-Driven Development is to write a test that initially fails, and then writing the minimal amount of code required to make the test pass. For the example project, we'll just be adding a &lt;code&gt;sum&lt;/code&gt; function, so create a new file &lt;code&gt;mod.test.ts&lt;/code&gt; and add the following code:&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;assertEquals&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./dev_deps.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./mod.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;Deno&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sum&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;3&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;Also add an empty &lt;code&gt;sum&lt;/code&gt; function in &lt;code&gt;mod.ts&lt;/code&gt;:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sum&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;If you run &lt;code&gt;deno test&lt;/code&gt; you can see the test won't pass. We'll implement a basic sum function here and class it up a bit by allowing it to sum any number of numbers using spread syntax and &lt;code&gt;Array.reduce&lt;/code&gt;:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;curr&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="nx"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;curr&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;If you run the test again you should see it pass. Now, try to run the commands &lt;code&gt;deno fmt&lt;/code&gt; and &lt;code&gt;deno lint&lt;/code&gt; as well. You can also run &lt;code&gt;deno test --coverage=cov&lt;/code&gt; to create a code coverage output directory and then &lt;code&gt;deno coverage cov&lt;/code&gt; to view a coverage report on the console (which should be 100% in this case!).&lt;/p&gt;

&lt;h2&gt;
  
  
  Merging to main
&lt;/h2&gt;

&lt;p&gt;This code looks ready for release, as all checks are passing. We want to include these as requirements for any pull requests. First, create another commit using conventional commit syntax. This style makes it easier to see what type of changes have been made and what sort of version increment would be best. You can read more about the specifications &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add .
git commit -m "feat: add sum function"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, instead of pushing the code to &lt;code&gt;main&lt;/code&gt;, which is protected, let's use the GitHub CLI to make a PR. We can use &lt;code&gt;--fill&lt;/code&gt; to autofill the title and body of the PR with the commit info.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr create --fill
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you don't need to leave the terminal at all with the GitHub CLI. You could keep working on something else, and use &lt;code&gt;gh pr status&lt;/code&gt; to check the PR.&lt;/p&gt;

&lt;p&gt;When the pipeline has run, edit the branch protection rule on GitHub and tick the "Require status checks to pass before merging" and search for the &lt;code&gt;build&lt;/code&gt; job that the pipeline runs, which includes formatting, linting and testing.&lt;/p&gt;

&lt;p&gt;If all the checks pass you can merge the changes into main with a (single) squash commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr merge --squash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is really the core of this workflow. You make changes, create a PR with &lt;code&gt;gh pr create --fill&lt;/code&gt;, then check in later and merge with &lt;code&gt;gh pr merge --squash&lt;/code&gt;. It takes care of using a consistent format in the code and ensures that good practices are applied by running the linter. It's a very fluent and programmatic way of developing and maintaining a codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Auto-generating release notes.
&lt;/h2&gt;

&lt;p&gt;The great thing about using conventional commits together with GitHub is that you can create release notes and autofill them with your commits. This gives a very nice, concise overview of what sort of fixes and features were made per release. The only downside right now is that it has to be done from GitHub and not the CLI.&lt;/p&gt;

&lt;p&gt;To create a release, go to Create a new release on GitHub (right below Releases on the right hand side). As long as your project is unstable, meaning breaking changes can happen at any release and not just major version increments, choose a &lt;code&gt;v0.x.x&lt;/code&gt; format for your tag, for example &lt;code&gt;v0.1.0&lt;/code&gt;. Click the button "auto-generate release notes" on the top-right of where you can write the release description, and there you go!&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;This tutorial showcased a module development workflow for Deno using GitHub. We configured a project to require signing commits with a GPG key. We used the &lt;code&gt;mod&lt;/code&gt; CLI to quickly scaffold a module for Deno with a GitHub Actions CI pipeline. Finally, we used the GitHub CLI to create a remote repository, to make pull requests and merge them into a protected branch. This workflow is highly programmatic, with only a few manual steps required on GitHub in the browser, and it greatly reduces the amount of context switching needed while developing.&lt;/p&gt;

&lt;p&gt;I hope this tutorial showed you how using Deno and GitHub greatly simplifies the creation of high-quality code, adhering to many good practices and standards (branch protection, commit signing, conventional commits, test-driven development). I recognize that this workflow takes some time to get used to before it starts to become fast and fluent, but it's absolutely worth making the effort as it will take your code quality to the next level.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
