Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ input paths through the environment rather than interpolating them into shell so
default artifacts under the runner's temporary directory, and keeps the CLI's exit-code contract:

```yaml
- uses: softpeanut/csv-preflight@v0.5.0
- uses: softpeanut/csv-preflight-action@v1
with:
path: data/import.csv
normalized_path: ${{ runner.temp }}/import.normalized.csv
Expand Down
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<section id="drop" class="card drop"><input id="file" type="file" accept=".csv,text/csv"><label for="file"><strong>Drop a CSV here</strong><span>or choose a file</span></label><div class="or">OR PASTE</div><textarea id="input" placeholder="email,name&#10;ada@example.com,Ada"></textarea><div class="profile"><label for="profile">Validation profile</label><select id="profile"><option value="generic">Generic CSV structure</option><option value="shopify:create">Shopify — new products</option><option value="shopify:update">Shopify — update products</option></select><small>Shopify preset reviewed against the <a href="https://help.shopify.com/en/manual/products/import-export/using-csv" target="_blank" rel="noopener">official product CSV guide</a> on 2026-08-27. It checks a bounded set of documented rules and does not guarantee import success.</small></div><button id="check">Run preflight</button></section>
<section id="results" class="card" hidden><div class="summary"><div><small>ENCODING</small><strong id="encoding">Pasted text</strong></div><div><small>DELIMITER</small><strong id="delimiter">Comma</strong></div><div><small>ROWS</small><strong id="rows">0</strong></div><div><small>ISSUES</small><strong id="count">0</strong></div></div><h2>Preflight report</h2><ul id="issues"></ul><div class="actions"><button id="csvDownload">Download cleaned CSV</button><button id="reportDownload" class="secondary">Download error report</button></div></section>
<section class="pro"><div><span class="eyebrow">FREE NODE.JS 20+ CLI</span><h2>Check one CSV in a terminal.</h2><p>Run the same generic structural preflight locally with no package install. The CLI writes a normalized CSV and issues report, returns CI-friendly exit codes, and refuses to overwrite existing output. The free CLI is limited to one generic file per run; batch, Shopify profiles, ZIP, and JSON automation remain Pro features.</p><p><code>node cli.mjs input.csv --output normalized.csv --report issues.csv</code></p></div><a href="cli.mjs" download>Download free CLI ↗</a></section>
<section class="pro"><div><span class="eyebrow">FREE GITHUB ACTION · v0.5.0</span><h2>Fail CI before a broken CSV reaches an importer.</h2><p>The public composite Action runs the same one-file structural check inside GitHub Actions. It reads the path through an environment variable, keeps the file on the runner, writes normalized CSV and issue-report artifacts under the runner temporary directory by default, and fails the step when issues are found.</p><p><code>- uses: softpeanut/csv-preflight@v0.5.0</code></p><p class="fine-print">One generic UTF-8 CSV up to 10 MiB. Pin a full commit SHA when immutable third-party code is required. Batch, Shopify profiles, ZIP, and JSON output remain Pro features. <a href="validate-csv-github-actions.html">Read the complete workflow guide.</a></p></div><a href="https://github.com/softpeanut/csv-preflight/releases/tag/v0.5.0" target="_blank" rel="noopener">View Action release ↗</a></section>
<section class="pro"><div><span class="eyebrow">FREE GITHUB ACTION · v1.0.0</span><h2>Fail CI before a broken CSV reaches an importer.</h2><p>The standalone public composite Action runs the same one-file structural check inside GitHub Actions. It reads the path through an environment variable, keeps the file on the runner, writes normalized CSV and issue-report artifacts under the runner temporary directory by default, and fails the step when issues are found.</p><p><code>- uses: softpeanut/csv-preflight-action@v1</code></p><p class="fine-print">One generic UTF-8 CSV up to 10 MiB. Pin a full commit SHA when immutable third-party code is required. Batch, Shopify profiles, ZIP, and JSON output remain Pro features. <a href="validate-csv-github-actions.html">Read the complete workflow guide.</a></p></div><a href="https://github.com/softpeanut/csv-preflight-action/releases/tag/v1.0.0" target="_blank" rel="noopener">View Action release ↗</a></section>
<section class="pro"><div><span class="eyebrow">FIXED-SCOPE CSV CI SETUP · $99</span><h2>Get one repository wired correctly.</h2><p>One public repository or sanitized minimal reproduction, one generic UTF-8 CSV path, one GitHub-hosted Ubuntu workflow, diagnostic artifacts, a short usage note, and one revision. No private access, secrets, schema rules, import execution, or ongoing maintenance. Delivery within three business days after written scope and verified payment.</p><p><a href="ci-setup-terms.html">Read the complete scope, payment, cancellation, and refund terms.</a></p></div><a href="https://github.com/softpeanut/csv-preflight/issues/new?template=ci-setup.yml" target="_blank" rel="noopener">Check setup fit ↗</a></section>
<section class="pro product"><div><span class="eyebrow">OFFLINE BATCH + CI CLI · PERSONAL 15,000 / TEAM 100,000 SATS</span><h2>Process up to 20 files locally or in CI.</h2><p>The completed Pro edition creates comma-separated UTF-8 normalized files, per-file issue reports, and a manifest in one ZIP. It includes a browser interface and a Node.js 20+ CLI with JSON output, deterministic exit codes, and no-overwrite protection. Both keep every parsed data row and include generic, Shopify new-product, and Shopify update profiles.</p><p>Choose Personal for one user (15,000 sats) or Team for up to 10 named users in one legal organization (100,000 sats). Both tiers receive the same completed archive; only the license scope differs. No upload, account, subscription, schema mapping, sensitive data, or import guarantee. After availability is confirmed, the seller posts an issue-bound single-use Lightning invoice matching the selected tier and verifies its status directly. Delivery is through a buyer-only private GitHub repository.</p><p><a href="pro-terms.html">Review the license, delivery, and refund terms</a></p></div><a href="https://github.com/softpeanut/csv-preflight/issues/new?template=batch-license.yml" target="_blank" rel="noopener">Start Pro order ↗</a></section>
<section class="pro"><div><span class="eyebrow">FIXED-SCOPE SERVICE</span><h2>Need a difficult CSV cleaned?</h2><p><strong>$29 structural cleanup:</strong> one file up to 1 MB, a normalized CSV, and an issue report. No schema mapping or revision.</p><p><strong>$99 importer-fit cleanup:</strong> one file up to 10 MB, one target schema—including a bounded Shopify product import—plus a cleaned CSV, an issue report, and one revision.</p><p><strong>Payment available by Lightning:</strong> after scope and terms are agreed, the exact sats amount is quoted for <code>softpeanut@stacker.news</code>. Do not pay before receiving that written quote.</p><p class="fine-print">Fit, delivery, payment, and cancellation terms are confirmed before any work or payment. No sensitive or regulated data. Do not attach data, credentials, or private links to a public issue.</p></div><a href="https://github.com/softpeanut/csv-preflight/issues/new?template=csv-cleanup.yml" target="_blank" rel="noopener">Check project fit ↗</a></section>
Expand Down
6 changes: 3 additions & 3 deletions offer.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,15 @@ test("offers only the completed bounded offline batch product", () => {
});

test("publishes the tested free Action without blurring the Pro boundary", () => {
assert.match(page, /FREE GITHUB ACTION · v0\.5\.0/);
assert.match(page, /softpeanut\/csv-preflight@v0\.5\.0/);
assert.match(page, /FREE GITHUB ACTION · v1\.0\.0/);
assert.match(page, /softpeanut\/csv-preflight-action@v1/);
assert.match(page, /keeps the file on the runner/);
assert.match(page, /One generic UTF-8 CSV up to 10 MiB/);
assert.match(page, /Batch, Shopify profiles, ZIP, and JSON output remain Pro features/);
assert.match(action, /using: composite/);
assert.match(action, /CSV_PREFLIGHT_INPUT: \$\{\{ inputs\.path \}\}/);
assert.match(page, /validate-csv-github-actions\.html/);
assert.match(githubActionGuide, /softpeanut\/csv-preflight@340b31bb16a4c39463be3378270ea6c628aa5461/);
assert.match(githubActionGuide, /softpeanut\/csv-preflight-action@eb04c527a46ce3bc8bfc711fde8e93ca947597ae/);
assert.match(githubActionGuide, /if: always\(\)/);
assert.match(githubActionGuide, /contents: read/);
assert.match(githubActionGuide, /does not upload the CSV/);
Expand Down
8 changes: 4 additions & 4 deletions validate-csv-github-actions.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</head>
<body>
<main class="article">
<nav><a href="./">Try CSV Preflight</a> · <a href="https://github.com/softpeanut/csv-preflight/releases/tag/v0.5.0">Action release</a> · <a href="pro-terms.html">Pro terms</a></nav>
<nav><a href="./">Try CSV Preflight</a> · <a href="https://github.com/softpeanut/csv-preflight-action/releases/tag/v1.0.0">Action release</a> · <a href="pro-terms.html">Pro terms</a></nav>
<article>
<h1>Validate CSV Files in GitHub Actions</h1>
<p class="lede">Fail a workflow on broken structure, retain the diagnostic files, and keep the CSV on the runner.</p>
Expand Down Expand Up @@ -47,7 +47,7 @@ <h2>A complete workflow</h2>
- uses: actions/checkout@v4

- name: Check CSV structure
uses: softpeanut/csv-preflight@340b31bb16a4c39463be3378270ea6c628aa5461
uses: softpeanut/csv-preflight-action@eb04c527a46ce3bc8bfc711fde8e93ca947597ae
with:
path: data/import.csv
normalized_path: ${{ runner.temp }}/import.normalized.csv
Expand All @@ -63,7 +63,7 @@ <h2>A complete workflow</h2>
${{ runner.temp }}/import.issues.csv
if-no-files-found: warn</code></pre>

<p>The full commit SHA pins the checked v0.5.0 Action bytes. A shorter <code>@v0.5.0</code> reference is easier to read, but a full SHA prevents a tag move from changing third-party code without a workflow diff. Apply the same pinning policy to every external Action when your threat model requires immutable dependencies.</p>
<p>The full commit SHA pins the checked v1.0.0 Action bytes. A shorter <code>@v1</code> reference is easier to read, but a full SHA prevents a tag move from changing third-party code without a workflow diff. Apply the same pinning policy to every external Action when your threat model requires immutable dependencies.</p>

<h2>What the Action checks</h2>

Expand Down Expand Up @@ -113,7 +113,7 @@ <h2>Use schema checks separately</h2>

<p>Structural validation cannot decide whether a price is negative, a customer ID exists, or a date belongs to the required timezone. Add importer-specific schema and business-rule checks after structural parsing. Keep their reports separate so reviewers can distinguish malformed CSV from valid CSV containing invalid domain values.</p>

<p>Start with the <a href="./">browser checker</a>, inspect the <a href="https://github.com/softpeanut/csv-preflight">source and tests</a>, or use the public <a href="https://github.com/softpeanut/csv-preflight/releases/tag/v0.5.0">v0.5.0 Action release</a>. For offline batch and team use, the <a href="pro-terms.html">published Pro terms</a> describe the completed product. If you want this exact one-file workflow configured against a public or sanitized repository, the separate <a href="ci-setup-terms.html">$99 fixed-scope setup terms</a> define every deliverable and exclusion before payment.</p>
<p>Start with the <a href="./">browser checker</a>, inspect the <a href="https://github.com/softpeanut/csv-preflight-action">standalone Action source and tests</a>, or use the public <a href="https://github.com/softpeanut/csv-preflight-action/releases/tag/v1.0.0">v1.0.0 Action release</a>. For offline batch and team use, the <a href="pro-terms.html">published Pro terms</a> describe the completed product. If you want this exact one-file workflow configured against a public or sanitized repository, the separate <a href="ci-setup-terms.html">$99 fixed-scope setup terms</a> define every deliverable and exclusion before payment.</p>
</article>
</main>
</body>
Expand Down
Loading