diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..6f2007c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,46 @@ +name: Bug report +description: Report a bug in rustkit +labels: [bug] +body: + - type: markdown + attributes: + value: | + Thanks for reporting a bug. A panic inside an `extern "C"` boundary aborts the + process — please include enough detail to reproduce exactly. + - type: input + id: version + attributes: + label: rustkit version + description: Version from `package.json` (or commit hash if unreleased) + placeholder: 0.1.0 + validations: + required: true + - type: input + id: environment + attributes: + label: Environment + description: Bun version, OS, and architecture (e.g. `bun --version` and `uname -m`) + placeholder: Bun 1.4.0, macOS 15 arm64 + validations: + required: true + - type: textarea + id: description + attributes: + label: Description + description: What happened vs. what you expected + validations: + required: true + - type: textarea + id: repro + attributes: + label: Reproduction + description: Minimal code that triggers the issue + render: typescript + validations: + required: true + - type: textarea + id: logs + attributes: + label: Logs / output + description: Error messages, stack traces, or crash output + render: shell \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..27ad3b1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Security + url: https://github.com/Shiv-SB/Rustkit/security/advisories/new + about: Please report security vulnerabilities privately — do not open a public issue. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..3519e1c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,31 @@ +name: Feature request +description: Suggest a new operation or improvement for rustkit +labels: [enhancement] +body: + - type: textarea + id: problem + attributes: + label: Problem + description: What gap does this fill? What are you trying to do? + validations: + required: true + - type: textarea + id: proposal + attributes: + label: Proposed API + description: Sketch the function signature(s) you have in mind + render: typescript + validations: + required: true + - type: textarea + id: alternatives + attributes: + label: Alternatives + description: What workarounds exist today? + - type: checkboxes + id: scope + attributes: + label: Scope + options: + - label: I'd be willing to implement this + - label: This is a niche use case (added to a "backlog" section) \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..81bfbef --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,19 @@ +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 \ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..186a425 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,16 @@ +## Summary + + + +## Changes + +- + +## Testing + + + +- [ ] `bun run compile:rs && bun test && bun run typecheck` passes +- [ ] (Rust changes only) `cargo test --workspace` passes +- [ ] CHANGELOG.md updated if user-facing +- [ ] README.md updated if user-facing \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d533ec0 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,56 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + name: Test (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + # macOS arm64 (macos-14) + Linux x64 (ubuntu-latest) cover two of the + # six shipped platform binaries; the full six are built in the publish workflow. + os: [ubuntu-latest, macos-14] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Rust + uses: dtolnay/rust-toolchain@stable + + - name: Cache cargo + uses: Swatinem/rust-cache@v2 + + - name: Set up Bun + uses: oven-sh/setup-bun@v2 + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Build native library + run: bun run compile:rs + + - name: Rust tests + run: cargo test --workspace + + - name: TS tests + run: bun test + + - name: Typecheck + run: bun run typecheck + + - name: Build dist + run: bun run build \ No newline at end of file diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml new file mode 100644 index 0000000..1a5f9e7 --- /dev/null +++ b/.github/workflows/npm-publish.yml @@ -0,0 +1,88 @@ +name: Publish to npm + +on: + push: + tags: + - "v*.*.*" + workflow_dispatch: + +permissions: + id-token: write # Required for OIDC (npm provenance + trusted publishing) + contents: write # Required to create the GitHub release for the tag + +jobs: + publish: + # build-platforms.ts requires a darwin-arm64 host: macos-14 is the arm64 runner. + # Do not switch to an x64 or Linux runner without loosening that check. + runs-on: macos-14 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Node.js and npm + uses: actions/setup-node@v5 + + - name: Upgrade npm + run: sudo npm install -g npm@latest + + - name: Show npm version + run: npm --version + + - name: Set up Bun + uses: oven-sh/setup-bun@v2 + + - name: Set up Rust + uses: dtolnay/rust-toolchain@stable + + - name: Install cargo-zigbuild + # Cross-compiles the four Linux targets (glibc + musl, x64 + arm64) from macOS. + run: brew install cargo-zigbuild + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Validate package.json version matches tag + if: startsWith(github.ref, 'refs/tags/') + run: | + bun run sync:version + PACKAGE_VERSION=$(bun pm pkg get version | tr -d '"') + TAG_VERSION=${GITHUB_REF#refs/tags/v} + echo "Package version: $PACKAGE_VERSION" + echo "Tag version: $TAG_VERSION" + if [ "$PACKAGE_VERSION" != "$TAG_VERSION" ]; then + echo "Version mismatch: package.json has $PACKAGE_VERSION but tag is $TAG_VERSION." + echo "Bump crates/rustkit-ffi/Cargo.toml, run 'bun run sync:version', and tag v$PACKAGE_VERSION." + exit 1 + fi + echo "Version matches: $PACKAGE_VERSION" + + - name: Audit vulnerabilities + run: bun audit + + - name: Typecheck + run: bun run typecheck + + - name: Build native library + run: bun run compile:rs + + - name: Build all 6 platform binaries + run: bun run build:platforms + + - name: Verify platform binaries + run: bun run verify:platforms + + - name: Run tests + run: bun test + + - name: Build dist + run: bun run build + + - name: Smoke test packed tarball + run: bun run smoke + + # Publishes via OIDC (no NPM_TOKEN required) and attaches npm provenance. + # Prerequisite: register this repo as a Trusted Publisher for the "rustkit" + # package on npmjs.com (Package > Access > Trusted Publishers > GitHub Actions). + - name: Publish to npm + run: npm publish --provenance --access public diff --git a/CHANGELOG.md b/CHANGELOG.md index f6f857f..568c425 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + +- GitHub Actions: CI workflow (Linux x64 + macOS arm64 matrix, Rust + TS tests), CodeQL analysis, and an OIDC-based npm publish workflow (`v*.*.*` tags), Dependabot config, issue/PR templates, and a security policy + ## [0.1.0] - 2026-09-03 ### Added diff --git a/README.md b/README.md index 01e038e..711fc1b 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,15 @@ A numeric library for [Bun](https://bun.com), implemented in Rust and exposed th Hot reductions (dot, sum, l1, squared-diff-sum, max-abs) use explicit SIMD — NEON on AArch64 (Apple Silicon and Linux arm64), AVX2/SSE2 on x86_64 chosen at runtime via CPU feature detection — with auto-vectorized scalar fallbacks on other targets. +

+ CI + CodeQL + npm version + npm downloads + GitHub + License +

+ ## Install ```bash @@ -322,7 +331,7 @@ The npm package is published from this repo with a single command. The version i ### Prerequisites -- npm auth: `npm login` (or a valid token in `~/.npmrc`). Verify with `npm whoami`. +- npm auth for local publishes: `npm login` (or a valid token in `~/.npmrc`). Verify with `npm whoami`. CI publishes use OIDC instead — no token needed (see below). - `cargo-zigbuild` for the Linux targets: `brew install cargo-zigbuild` (or `cargo install cargo-zigbuild`). Without it, the 4 Linux binaries are skipped and `--publish` will fail the platform check. - The `rustkit` name is already reserved on npm (`0.0.0` placeholder) — publishing a real version publishes over it. @@ -345,6 +354,17 @@ The pipeline runs, in order: Always run the dry-run first and inspect the output before shipping. The smoke step verifies the actual tarball, not the working tree. +### Automatic releases (GitHub Actions) + +Pushing a `v*.*.*` tag triggers `.github/workflows/npm-publish.yml`: + +1. Syncs the version from `crates/rustkit-ffi/Cargo.toml` into `package.json` and fails if it doesn't match the tag. +2. Builds all 6 platform binaries on a macOS arm64 runner (via `cargo-zigbuild`), runs the audit/typecheck/test/build/smoke pipeline, then publishes to npm. +3. Publishing uses **OIDC** (`id-token: write`) with npm provenance — no `NPM_TOKEN` secret required. One-time setup: register this repo as a Trusted Publisher for the `rustkit` package on npmjs.com (Package → Access → Trusted Publishers → GitHub Actions). +4. A GitHub release with auto-generated notes is created from the tag. + +CI (`.github/workflows/ci.yml`) runs the Rust + TypeScript test suites on Linux x64 and macOS arm64 for every push and pull request; CodeQL (`.github/workflows/codeql.yml`) analyzes the TypeScript layer. Local publishing (`bun run release --publish`) still works as before and uses your npm login. + ## License MIT \ No newline at end of file diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..48a73d0 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,26 @@ +# Security Policy + +## Reporting a vulnerability + +Please report security vulnerabilities through GitHub's Private Vulnerability Reporting: + +**[Report a vulnerability](https://github.com/Shiv-SB/Rustkit/security/advisories/new)** + +Do **not** open a public issue for security problems. + +Include, if possible: + +- Affected version(s) +- Steps to reproduce (a failing test case is ideal) +- Impact / what an attacker could gain + +You will receive an acknowledgment within 48 hours and updates as the issue is triaged and fixed. Once a fix is published, the advisory is disclosed following the [GitHub Security Advisory](https://docs.github.com/en/code-security/security-advisories) process. + +## Supported versions + +Only the latest published npm version receives security fixes. This is a `0.x` package — API changes may land in minor releases. + +## Scope + +- **In scope**: the Rust crates (`crates/`), the FFI layer, the TypeScript wrappers (`src/`), and the packaged native binaries. +- **Out of scope**: memory-safety issues in the non-`unsafe` Rust code paths (Rust's guarantees apply), and theoretical side channels in the non-cryptographic hash functions (`crypto` module) — they are explicitly not for security use. \ No newline at end of file