Skip to content
Open
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
46 changes: 46 additions & 0 deletions .github/workflows/prepare-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Prepare Release

on:
workflow_dispatch:

permissions:
contents: write

jobs:
prepare:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout main
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
ref: main

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "24"

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Prepare exact-version release shebangs
run: bun scripts/shebangs.ts set --target release

- name: Verify release artifact
run: bun run verify:release

- name: Commit and tag release
run: |
VERSION="$(node -p "require('./package.json').version")"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
if ! git diff --quiet; then
git add README.md note.tsx examples
git commit -m "Prepare note@${VERSION} release"
fi
git tag "v${VERSION}"
git push origin main "v${VERSION}"
8 changes: 5 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ name: Release
on:
push:
tags: ["v*"]
workflow_dispatch:

Comment on lines 3 to 6
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Verify package version step still contains a branch that checks ${GITHUB_EVENT_NAME} == workflow_dispatch, but this workflow no longer has a workflow_dispatch trigger. That condition is now unreachable and can be removed to avoid confusion.

Copilot uses AI. Check for mistakes.
permissions: {}

Expand Down Expand Up @@ -42,8 +41,8 @@ jobs:
- name: Install dependencies
run: bun install --frozen-lockfile

- name: Check package
run: bun run check
- name: Verify release artifact
run: bun run verify:release

- name: Verify package version
run: |
Expand Down Expand Up @@ -79,3 +78,6 @@ jobs:
unset NPM_CONFIG_USERCONFIG
NPM_TAG="$(node -p "require('./package.json').version.includes('-') ? 'beta' : 'latest'")"
npm publish --provenance --access public --tag "$NPM_TAG"

- name: Verify published package
run: bun run verify:published
63 changes: 63 additions & 0 deletions .github/workflows/shebangs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Normalize Shebangs

on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
push:
branches: ["main"]

permissions:
contents: write

jobs:
normalize:
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout PR branch
if: github.event_name == 'pull_request'
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
ref: ${{ github.event.pull_request.head.ref }}

- name: Checkout main
if: github.event_name == 'push'
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "24"

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Set PR shebangs
if: github.event_name == 'pull_request'
run: bun scripts/shebangs.ts set --target branch --branch "${{ github.event.pull_request.head.ref }}"

- name: Set main shebangs
if: github.event_name == 'push'
run: bun scripts/shebangs.ts set --target main

- name: Commit shebang state locally
run: |
if git diff --quiet; then
echo "Shebangs already normalized"
else
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add README.md note.tsx examples
git commit -m "Normalize PAD shebangs"
fi

- name: Verify normalized artifact
run: bun run verify:artifact

- name: Push shebang state
run: |
git push
32 changes: 32 additions & 0 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Verify

on:
pull_request:
push:
branches: ["main"]

permissions: {}

jobs:
artifact:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
persist-credentials: false

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "24"

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Verify artifact
run: bun run verify:artifact
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ A PAD is a normal Markdown, HTML, or SVG file that you can preview as a document
Try this first. It runs the beta generator and creates a PAD file in the current directory. Preview the created file before you run the PAD itself.

```sh
bunx note@beta some random thing
bunx --bun -p https://github.com/effect-native/pad/archive/refs/heads/feature/release-verification-gates.tar.gz note some random thing
```

Creates:
Expand All @@ -23,19 +23,19 @@ YYYY-MM-DD-some-random-thing.pad.md
Create other previewable web-native forms:

```sh
bunx note@beta --html checklist
bunx note@beta --svg diagram
bunx --bun -p https://github.com/effect-native/pad/archive/refs/heads/feature/release-verification-gates.tar.gz note --html checklist
bunx --bun -p https://github.com/effect-native/pad/archive/refs/heads/feature/release-verification-gates.tar.gz note --svg diagram
```

## Run

PAD files can include a shebang:

```sh
#!/usr/bin/env -S bunx --bun note@beta --pad
#!/usr/bin/env -S bunx --bun -p https://github.com/effect-native/pad/archive/refs/heads/feature/release-verification-gates.tar.gz note --pad
```

When executed, the document path is passed to `note@beta --pad` and enters trusted program mode. Running a PAD crosses the boundary from "view this document" to "execute local code with Bun". Only run PADs you would trust as scripts.
When executed, the document path is passed to `bunx --bun -p https://github.com/effect-native/pad/archive/refs/heads/feature/release-verification-gates.tar.gz note --pad` and enters trusted program mode. Running a PAD crosses the boundary from "view this document" to "execute local code with Bun". Only run PADs you would trust as scripts.

## Trust Ladder

Expand Down
6 changes: 3 additions & 3 deletions examples/checklist.pad.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#!/usr/bin/env -S bunx --bun note@beta --pad
#!/usr/bin/env -S bunx --bun -p https://github.com/effect-native/pad/archive/refs/heads/feature/release-verification-gates.tar.gz note --pad
<!-- PAD: the shebang is intentional; only run this document if you trust it as a Bun script. -->
<!doctype html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light dark">
<title>Checklist PAD</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/note@0.5.1-beta.0/pad.css">
<script type="module" src="https://cdn.jsdelivr.net/npm/note@0.5.1-beta.0/pad.mjs"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/effect-native/pad@feature/release-verification-gates/pad.css">
<script type="module" src="https://cdn.jsdelivr.net/gh/effect-native/pad@feature/release-verification-gates/pad.mjs"></script>
<main>
<h1>Checklist PAD</h1>
<p>Preview like a file. Open like a page. Run like an app.</p>
Expand Down
2 changes: 1 addition & 1 deletion examples/checklist.pad.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env -S bunx --bun note@beta --pad
#!/usr/bin/env -S bunx --bun -p https://github.com/effect-native/pad/archive/refs/heads/feature/release-verification-gates.tar.gz note --pad
<!-- PAD: the shebang is intentional; only run this document if you trust it as a Bun script. -->
# Checklist

Expand Down
2 changes: 1 addition & 1 deletion examples/demo2.pad.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 6 additions & 5 deletions note.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type PadSocket = ServerWebSocket<unknown>;
const HOST = "0.0.0.0";
const DEFAULT_IDLE_SHUTDOWN_MS = 2_000;
const DEFAULT_FIRST_CLIENT_TIMEOUT_MS = 5 * 60_000;
const PAD_ASSET_BASE = "https://cdn.jsdelivr.net/gh/effect-native/pad@feature/release-verification-gates";

function readVersion() {
const packageJsonPath = resolve(dirname(fileURLToPath(import.meta.url)), "package.json");
Expand Down Expand Up @@ -81,7 +82,7 @@ function packageRoot() {
}

function packageAssetUrl(asset: string) {
return `https://cdn.jsdelivr.net/npm/note@${VERSION}/${asset}`;
return `${PAD_ASSET_BASE}/${asset}`;
}

function contentTypeFor(pathname: string) {
Expand Down Expand Up @@ -167,7 +168,7 @@ function renderEditorHtml(config: {
}

function markdown(title: string) {
return `#!/usr/bin/env -S bunx --bun note@beta --pad
return `#!/usr/bin/env -S bunx --bun -p https://github.com/effect-native/pad/archive/refs/heads/feature/release-verification-gates.tar.gz note --pad
<!-- PAD: the shebang is intentional; only run this document if you trust it as a Bun script. -->
# ${title}

Expand All @@ -177,7 +178,7 @@ function markdown(title: string) {

function html(title: string) {
const safeTitle = escapeHtml(title);
return `#!/usr/bin/env -S bunx --bun note@beta --pad
return `#!/usr/bin/env -S bunx --bun -p https://github.com/effect-native/pad/archive/refs/heads/feature/release-verification-gates.tar.gz note --pad
<!-- PAD: the shebang is intentional; only run this document if you trust it as a Bun script. -->
<!doctype html>
<meta charset="utf-8">
Expand All @@ -200,7 +201,7 @@ function svg(title: string) {
<title>${safeTitle}</title>
<rect width="900" height="480" fill="#08111f"/>
<text x="60" y="150" fill="#f8ffe8" font-family="system-ui, sans-serif" font-size="64" font-weight="700">${safeTitle}</text>
<text x="60" y="230" fill="#d7ff9b" font-family="system-ui, sans-serif" font-size="28">Preview like a file. Open like a page. Run with: bunx note@beta --pad</text>
<text x="60" y="230" fill="#d7ff9b" font-family="system-ui, sans-serif" font-size="28">Preview like a file. Open like a page. Run with: bunx --bun -p https://github.com/effect-native/pad/archive/refs/heads/feature/release-verification-gates.tar.gz note --pad</text>
</svg>
`;
}
Expand Down Expand Up @@ -236,7 +237,7 @@ async function createPad(args: Array<string>) {

const title = titleParts.join(" ").trim() || "untitled";
if (!forcedTitle && looksLikePath(title)) {
die(`That looks like a file path.\n\nRun a PAD with:\n bunx note@beta --pad ${title}\n\nForce a literal title with:\n bunx note@beta --title ${JSON.stringify(title)}`);
die(`That looks like a file path.\n\nRun a PAD with:\n bunx --bun -p https://github.com/effect-native/pad/archive/refs/heads/feature/release-verification-gates.tar.gz note --pad ${title}\n\nForce a literal title with:\n bunx --bun -p https://github.com/effect-native/pad/archive/refs/heads/feature/release-verification-gates.tar.gz note --title ${JSON.stringify(title)}`);
}

const file = `${localDate()}-${slugify(title)}.pad.${format}`;
Expand Down
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@
"examples"
],
"scripts": {
"check": "bun -e \"const result=await Bun.build({entrypoints:['./note.tsx'],target:'bun',write:false});if(!result.success)process.exit(1)\" && node --check pad.mjs"
"check": "bun -e \"const result=await Bun.build({entrypoints:['./note.tsx'],target:'bun',write:false});if(!result.success)process.exit(1)\" && node --check pad.mjs",
"shebangs": "bun scripts/shebangs.ts",
"shebangs:check": "bun scripts/shebangs.ts check",
"shebangs:set": "bun scripts/shebangs.ts set",
"verify:artifact": "bun scripts/verify-artifact.ts",
"verify:release": "bun scripts/verify-release.ts",
"verify:published": "bun scripts/verify-published.ts"
},
"engines": {
"bun": ">=1.3.0"
Expand Down
Loading
Loading