Skip to content

Commit 59639a9

Browse files
committed
first commit
0 parents  commit 59639a9

28 files changed

Lines changed: 3957 additions & 0 deletions

.github/CODEOWNERS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# every change requires review by a codeowner.
2+
# enforced via branch protection: require pr + 1 review + codeowner review.
3+
4+
* @0-draft/maintainers
5+
.github/workflows/ @0-draft/security
6+
scripts/ @0-draft/security
7+
SECURITY.md @0-draft/security

.github/dependabot.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# dependabot scope is intentionally narrow:
2+
# only github-actions, because sha-pinned action references go stale and
3+
# stale pins quietly carry old cves into every fork.
4+
# npm dependabot is a per-fork choice, not a template choice.
5+
6+
version: 2
7+
updates:
8+
- package-ecosystem: github-actions
9+
directory: "/"
10+
schedule:
11+
interval: weekly
12+
day: monday
13+
open-pull-requests-limit: 10
14+
commit-message:
15+
prefix: "ci"
16+
include: scope

.github/pull_request_template.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
## summary
2+
3+
<!-- one or two lines on intent -->
4+
5+
## checklist
6+
7+
- [ ] commits are signed (`gitsign` or gpg)
8+
- [ ] no third-party action references a tag (run `npm run pin-actions` if you added any)
9+
- [ ] if this changes the release pipeline, attach a sample rekor entry url or in-toto bundle
10+
- [ ] `npm run check` passes locally

.github/workflows/ci.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# template note:
2+
# action references in this file ship as semver tags so the template builds on day one.
3+
# after `scripts/init.sh`, run `npm run pin-actions` (or it runs automatically) to rewrite
4+
# every `uses:` line to a full commit sha. dependabot bumps the sha; the trailing
5+
# `# v6.x` comment is preserved for human readability.
6+
7+
name: ci
8+
9+
on:
10+
pull_request:
11+
branches: [main]
12+
push:
13+
branches: [main]
14+
workflow_dispatch:
15+
16+
permissions:
17+
contents: read
18+
19+
concurrency:
20+
group: ci-${{ github.ref }}
21+
cancel-in-progress: true
22+
23+
jobs:
24+
ci:
25+
name: lint / typecheck / test / audit / build
26+
runs-on: ubuntu-latest
27+
steps:
28+
- name: harden runner
29+
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2
30+
with:
31+
egress-policy: audit
32+
33+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
34+
with:
35+
persist-credentials: false
36+
37+
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
38+
with:
39+
node-version: 24
40+
cache: npm
41+
42+
- name: install (locked, no scripts)
43+
run: npm ci --ignore-scripts
44+
45+
- name: lint
46+
run: npm run lint
47+
48+
- name: typecheck
49+
run: npm run typecheck
50+
51+
- name: test
52+
run: npm run test
53+
54+
- name: audit
55+
run: npm run audit
56+
57+
- name: build
58+
run: npm run build
59+
60+
pinned-actions:
61+
name: every action is sha-pinned
62+
runs-on: ubuntu-latest
63+
steps:
64+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
65+
with:
66+
persist-credentials: false
67+
68+
- name: assert no tag references in workflows
69+
run: bash scripts/check-pins.sh

.github/workflows/release.yml

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# release flow:
2+
# 1. tag v* on main triggers this workflow
3+
# 2. build job produces a tarball + slsa provenance via the slsa-github-generator
4+
# reusable workflow (which runs in an isolated builder, not in our repo's runner)
5+
# 3. publish job uses npm trusted publisher (oidc) to publish with --provenance
6+
# 4. sign job runs cosign sign-blob keylessly, identity = this workflow
7+
#
8+
# secrets used: none. there is no NPM_TOKEN. credentials are minted via oidc per run.
9+
10+
name: release
11+
12+
on:
13+
push:
14+
tags: ["v*"]
15+
workflow_dispatch:
16+
17+
permissions: {}
18+
19+
jobs:
20+
build:
21+
name: build tarball + slsa provenance
22+
runs-on: ubuntu-latest
23+
permissions:
24+
contents: read
25+
id-token: write
26+
outputs:
27+
tarball-name: ${{ steps.pack.outputs.tarball-name }}
28+
tarball-sha256: ${{ steps.pack.outputs.tarball-sha256 }}
29+
steps:
30+
- name: harden runner
31+
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2
32+
with:
33+
egress-policy: audit
34+
35+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
36+
with:
37+
persist-credentials: false
38+
39+
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
40+
with:
41+
node-version: 24
42+
cache: npm
43+
registry-url: https://registry.npmjs.org
44+
45+
- name: install (locked, no scripts)
46+
run: npm ci --ignore-scripts
47+
48+
- name: build
49+
run: npm run build
50+
51+
- name: pack
52+
id: pack
53+
run: |
54+
set -euo pipefail
55+
tarball=$(npm pack --silent | tail -n 1)
56+
sha=$(shasum -a 256 "$tarball" | awk '{print $1}')
57+
echo "tarball-name=$tarball" >>"$GITHUB_OUTPUT"
58+
echo "tarball-sha256=$sha" >>"$GITHUB_OUTPUT"
59+
60+
- name: upload tarball
61+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
62+
with:
63+
name: tarball
64+
path: ${{ steps.pack.outputs.tarball-name }}
65+
if-no-files-found: error
66+
retention-days: 7
67+
68+
provenance:
69+
name: slsa v1.0 provenance
70+
needs: [build]
71+
permissions:
72+
actions: read
73+
contents: read
74+
id-token: write
75+
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@f7dd8c54c2067bafc12ca7a55595d5ee9b75204a # v2.1.0
76+
with:
77+
base64-subjects: ${{ needs.build.outputs.tarball-sha256 }}
78+
provenance-name: ${{ needs.build.outputs.tarball-name }}.intoto.jsonl
79+
upload-assets: true
80+
81+
publish:
82+
name: npm trusted publisher (--provenance)
83+
needs: [build, provenance]
84+
runs-on: ubuntu-latest
85+
environment: release
86+
permissions:
87+
contents: read
88+
id-token: write
89+
steps:
90+
- name: harden runner
91+
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2
92+
with:
93+
egress-policy: audit
94+
95+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
96+
with:
97+
persist-credentials: false
98+
99+
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
100+
with:
101+
node-version: 24
102+
registry-url: https://registry.npmjs.org
103+
104+
- name: download tarball
105+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
106+
with:
107+
name: tarball
108+
109+
- name: publish
110+
run: npm publish "${{ needs.build.outputs.tarball-name }}" --provenance --access public
111+
112+
sign:
113+
name: cosign sign-blob (keyless)
114+
needs: [build, publish]
115+
runs-on: ubuntu-latest
116+
permissions:
117+
contents: write
118+
id-token: write
119+
steps:
120+
- uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1
121+
122+
- name: download tarball
123+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
124+
with:
125+
name: tarball
126+
127+
- name: sign
128+
run: |
129+
cosign sign-blob --yes \
130+
--output-signature "${{ needs.build.outputs.tarball-name }}.sig" \
131+
--output-certificate "${{ needs.build.outputs.tarball-name }}.crt" \
132+
"${{ needs.build.outputs.tarball-name }}"
133+
134+
- name: attach signature to release
135+
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3
136+
with:
137+
files: |
138+
${{ needs.build.outputs.tarball-name }}.sig
139+
${{ needs.build.outputs.tarball-name }}.crt

.github/workflows/scorecard.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: scorecard
2+
3+
on:
4+
branch_protection_rule:
5+
schedule:
6+
- cron: "31 6 * * 1"
7+
push:
8+
branches: [main]
9+
workflow_dispatch:
10+
11+
permissions: read-all
12+
13+
jobs:
14+
analysis:
15+
name: openssf scorecard
16+
runs-on: ubuntu-latest
17+
permissions:
18+
security-events: write
19+
id-token: write
20+
contents: read
21+
actions: read
22+
steps:
23+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
24+
with:
25+
persist-credentials: false
26+
27+
- name: run analysis
28+
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
29+
with:
30+
results_file: results.sarif
31+
results_format: sarif
32+
publish_results: true
33+
34+
- name: upload artifact
35+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
36+
with:
37+
name: scorecard-results
38+
path: results.sarif
39+
retention-days: 5
40+
41+
- name: upload to code-scanning
42+
uses: github/codeql-action/upload-sarif@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a # v3
43+
with:
44+
sarif_file: results.sarif

.gitignore

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
node_modules
2+
dist
3+
coverage
4+
5+
# release artifacts (built locally, never committed)
6+
*.tgz
7+
*.sig
8+
*.crt
9+
*.intoto.jsonl
10+
audit.json
11+
12+
# editor / os
13+
.DS_Store
14+
.vscode
15+
.idea
16+
*.swp
17+
*.swo
18+
19+
# logs
20+
*.log
21+
npm-debug.log*
22+
23+
# env (commit only .env.example)
24+
.env
25+
.env.*
26+
!.env.example

.markdownlint-cli2.jsonc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"config": {
3+
"default": true,
4+
"MD013": false,
5+
"MD024": false,
6+
"MD033": { "allowed_elements": ["div", "picture", "source", "img"] },
7+
"MD036": false,
8+
"MD041": false,
9+
"MD060": false
10+
},
11+
"ignores": [
12+
"node_modules",
13+
"dist",
14+
"coverage"
15+
]
16+
}

.npmrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# engine-strict makes npm refuse to install on a node version outside `engines`.
2+
# fund=false silences the donate prompt; everything else here is npm 11 default.
3+
engine-strict=true
4+
fund=false

CODE_OF_CONDUCT.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# code of conduct
2+
3+
this project adopts the [contributor covenant v2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).
4+
5+
## reporting
6+
7+
email <conduct@0-draft.dev> or use github private vulnerability reporting for sensitive cases.
8+
maintainers will respond within 72 hours and treat reports as confidential.
9+
10+
## enforcement
11+
12+
violations follow the contributor covenant enforcement ladder: correction → warning → temporary ban → permanent ban.
13+
maintainers decide and document each action in a private incident log.

0 commit comments

Comments
 (0)