<?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: Kevin Ryan Khan</title>
    <description>The latest articles on DEV Community by Kevin Ryan Khan (@kevinryankhan).</description>
    <link>https://dev.to/kevinryankhan</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1342118%2F874b2dc8-e34e-46ce-8fc8-7461257f43af.jpeg</url>
      <title>DEV Community: Kevin Ryan Khan</title>
      <link>https://dev.to/kevinryankhan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kevinryankhan"/>
    <language>en</language>
    <item>
      <title>See what every pull request changes — and catch what it introduces</title>
      <dc:creator>Kevin Ryan Khan</dc:creator>
      <pubDate>Wed, 04 Nov 2026 14:39:14 +0000</pubDate>
      <link>https://dev.to/kevinryankhan/see-what-every-pull-request-changes-and-catch-what-it-introduces-3kb</link>
      <guid>https://dev.to/kevinryankhan/see-what-every-pull-request-changes-and-catch-what-it-introduces-3kb</guid>
      <description>&lt;p&gt;SDF Analyzer — PR Check is a free GitHub Action from Strikaris for teams who build on NetSuite's SuiteCloud Development Framework (SDF) — Oracle's system for holding a NetSuite account's customizations as files in a code repository. On every pull request, it posts one comment — updated in place on each new commit, never spammed — containing your script inventory, your dependency map, sanity checks on the project, and pattern checks on the files the pull request changed. It runs entirely on the GitHub runner inside your own repository: your code never leaves your GitHub account, and no Strikaris server is involved. It is MIT-licensed — free to use, and the code is public.&lt;/p&gt;

&lt;p&gt;The whole install — one workflow file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SDF Analyzer — PR Check&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pull_request&lt;/span&gt;
&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull-requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&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;pr-check&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&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;Strikaris-Tech/sdf-analyzer-pr-check@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;project-path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything below is the detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your SuiteCloud project is a black box at review time
&lt;/h2&gt;

&lt;p&gt;Every NetSuite team that works in SDF knows the feeling: you open a pull request and you cannot tell, from the diff, what actually changed in the project. A rename here, a script swapped there, a dependency added quietly in a file you were not watching — and the only way to be sure is to go and look.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many scripts does this project actually contain?&lt;/li&gt;
&lt;li&gt;Which built-in NetSuite modules (the &lt;code&gt;N/&lt;/code&gt; modules, such as &lt;code&gt;N/record&lt;/code&gt; and &lt;code&gt;N/search&lt;/code&gt;) do those scripts depend on?&lt;/li&gt;
&lt;li&gt;Did this change add a script, remove one, or quietly break the project file that ties everything together?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reviewers answer those questions by opening files one at a time, or they stop answering them at all. The Action answers them before the review starts.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the comment contains
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A script inventory.&lt;/strong&gt; Every SuiteScript in the project, with its type (read from the &lt;code&gt;@NScriptType&lt;/code&gt; annotation every SuiteScript carries: User Event, Restlet, Map/Reduce, and the rest), its API version, and how many modules it depends on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A dependency map.&lt;/strong&gt; The unique &lt;code&gt;N/&lt;/code&gt; modules used across the whole project, and how many scripts use each one — the fastest way to see what a change really touches.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sanity checks.&lt;/strong&gt; Plain warnings for the failures that otherwise surface late: a missing or unparseable &lt;code&gt;manifest.xml&lt;/code&gt; (the project definition file), a missing SuiteScripts directory, and scripts that fail to parse at all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pattern checks.&lt;/strong&gt; The files the pull request changed are checked for six patterns: a hardcoded credential written into the source, dynamic code execution (&lt;code&gt;eval&lt;/code&gt; and its equivalents), an empty catch block that swallows errors silently, a log call carrying a credential- or personal-data-shaped value, a call to a retired SuiteScript 1.0 API (&lt;code&gt;nlapi…&lt;/code&gt; / &lt;code&gt;nlobj…&lt;/code&gt;), and a synchronous web call in a client script. Each changed file is compared against its version on the base branch, and only findings the pull request &lt;em&gt;introduces&lt;/em&gt; are reported — pre-existing findings in the same files are not.&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/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff6j6ma5zw4vdn2q0gwf1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff6j6ma5zw4vdn2q0gwf1.gif" alt="SDF Analyzer — PR Check running on a pull request" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Used as a merge gate, it can also fail the run. Two options, independent of each other and both off by default: set &lt;code&gt;fail-on-issues&lt;/code&gt; and the run fails when any sanity warning is found; set &lt;code&gt;fail-on-findings&lt;/code&gt; and the run fails when the pattern checks report new findings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project mode.&lt;/strong&gt; If your repository holds an SDF project, you get the full behaviour above, in either of the layouts SDF accepts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loose-file mode.&lt;/strong&gt; If it does not — if you simply have SuiteScript files in a repository, as many teams do — the Action inventories those loose files instead, with their types and dependencies, says plainly that no project was found, and runs the same pattern checks on pull requests. And if a repository contains neither a project nor any SuiteScript, the comment says exactly that. It never reports a bare zero as if a check had passed.&lt;/p&gt;

&lt;h2&gt;
  
  
  We tried to break it before we shipped it
&lt;/h2&gt;

&lt;p&gt;Before the first release, we ran an adversarial pass against the Action: a deliberate attempt to make it report wrong numbers, miss findings, or claim a check had passed when it had not. Thirteen issues came out of that pass — an off-by-one in a page count, a file counted twice, a false pass on a repository that was not, in fact, an SDF project.&lt;/p&gt;

&lt;p&gt;We held the release until all thirteen were fixed, each with a permanent regression test — a test that stays in the suite and fails the build if the bug ever returns. That includes the uncomfortable cases: a mistyped project path now fails loudly instead of reporting an empty repository, and a file that merely &lt;em&gt;mentions&lt;/em&gt; the SuiteScript annotations in a string or a comment is no longer counted as a script. Version 1.0.0 shipped only when the count reached zero. The suite has grown since: the Action now carries 149 automated tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SDF Analyzer — PR Check&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pull_request&lt;/span&gt;
&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull-requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&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;pr-check&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&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;Strikaris-Tech/sdf-analyzer-pr-check@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;project-path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save that as a workflow file in your repository (for example, .github/workflows/pr-check.yml). There is no sign-up and no account — and if it is not for you, removing it is deleting the file. The Action is on GitHub Marketplace: &lt;a href="https://github.com/marketplace/actions/sdf-analyzer-pr-check" rel="noopener noreferrer"&gt;https://github.com/marketplace/actions/sdf-analyzer-pr-check&lt;/a&gt; — and the code is public, if you would rather read it first: &lt;a href="https://github.com/Strikaris-Tech/sdf-analyzer-pr-check" rel="noopener noreferrer"&gt;https://github.com/Strikaris-Tech/sdf-analyzer-pr-check&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it deliberately does not do
&lt;/h2&gt;

&lt;p&gt;The free tier is inventory, dependency map, sanity checks, and the six pattern checks — nothing more. The pattern checks examine only the files a pull request changed, for the six patterns above. They are not an audit: the rest of the project, data flow within and between files, deployments, roles, and configuration are not examined. The Action does not link scripts to their deployment records, does not evaluate governance or compliance rules, and does not produce diagrams or audit reports. For a deeper, human-reviewed audit of a NetSuite project — deployment linkage, findings with line-level evidence, and a remediation report — Strikaris offers the SDF Analyzer Audit service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;One pull request is enough to know whether it earns its place:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SDF Analyzer — PR Check&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pull_request&lt;/span&gt;
&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull-requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&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;pr-check&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&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;Strikaris-Tech/sdf-analyzer-pr-check@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;project-path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/marketplace/actions/sdf-analyzer-pr-check" rel="noopener noreferrer"&gt;https://github.com/marketplace/actions/sdf-analyzer-pr-check&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dedicated to Brandon Lee Zeek, co-founder of Strikaris — the other half of the work that led here.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>netsuite</category>
      <category>githubactions</category>
      <category>javascript</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
