add opt-in anonymous telemetry (#1)
Some checks failed
CI / test (20) (push) Failing after 27s
CI / test (22) (push) Failing after 31s
CI / test (24) (push) Failing after 40s
CI / typecheck (push) Failing after 32s
CI / Lint & Format (push) Failing after 33s
CI / pack-check (push) Failing after 42s
CI / coverage (push) Failing after 2s

* add Forgejo CI mirror and telemetry disclosure

Mirrors .github/workflows/ci.yml to .forgejo/workflows/ for self-hosted
runner on git.ariccamarata.com. Adds failure-reporting hook stub (server
registration via nself sentry ci enable is a server-side step). Adds
telemetry disclosure section to README.

* add opt-in telemetry via @acamarata/telemetry (off by default)

* chore: update lockfile for @acamarata/telemetry devDep

* chore: fix prettier formatting on telemetry import
This commit is contained in:
Aric Camarata 2026-06-30 15:56:57 -04:00 committed by GitHub
parent 35128dda86
commit 74b6f609f8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 196 additions and 0 deletions

165
.forgejo/workflows/ci.yml Normal file
View file

@ -0,0 +1,165 @@
# Forgejo CI mirror — git.ariccamarata.com
# Mirrors .github/workflows/ci.yml for the self-hosted Forgejo Actions runner.
# Keep in sync with the GitHub workflow; only addition is the nSentry failure step.
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
matrix:
node-version: [20, 22, 24]
steps:
- uses: actions/checkout@v4
- name: Enable corepack
run: corepack enable
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Build TypeScript
run: pnpm run build
- name: Run tests (ESM)
run: node --test test.mjs
- name: Run tests (CJS)
run: node --test test-cjs.cjs
- name: Report failure to nSentry
if: failure()
run: |
# nself sentry ci enable <repo> must be run on the CamClaw server first.
# Once registered, the runner's nself-sentry-sync hook delivers this report
# to ~/Sites/acamarata/.claude/inbox via root@sentry-errors.ariccamarata.com.
echo "CI_FAILURE repo=${{ github.repository }} job=${{ github.job }} run=${{ github.run_id }}" >&2
typecheck:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- name: Enable corepack
run: corepack enable
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm run typecheck
- name: Report failure to nSentry
if: failure()
run: |
# nself sentry ci enable <repo> must be run on the CamClaw server first.
# Once registered, the runner's nself-sentry-sync hook delivers this report
# to ~/Sites/acamarata/.claude/inbox via root@sentry-errors.ariccamarata.com.
echo "CI_FAILURE repo=${{ github.repository }} job=${{ github.job }} run=${{ github.run_id }}" >&2
lint:
name: Lint & Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Enable corepack
run: corepack enable
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm run lint
- run: pnpm run format:check
- name: Report failure to nSentry
if: failure()
run: |
# nself sentry ci enable <repo> must be run on the CamClaw server first.
# Once registered, the runner's nself-sentry-sync hook delivers this report
# to ~/Sites/acamarata/.claude/inbox via root@sentry-errors.ariccamarata.com.
echo "CI_FAILURE repo=${{ github.repository }} job=${{ github.job }} run=${{ github.run_id }}" >&2
pack-check:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- name: Enable corepack
run: corepack enable
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm run build
- name: Verify package contents
run: |
npm pack --dry-run 2>&1 | tee pack-output.txt
for f in dist/index.cjs dist/index.mjs dist/index.d.ts dist/index.d.mts lib/spa.js README.md CHANGELOG.md LICENSE; do
grep -qE "(^|[[:space:]])${f}([[:space:]]|$)" pack-output.txt || { echo "MISSING: $f"; exit 1; }
done
echo "All expected files present in package"
- name: Report failure to nSentry
if: failure()
run: |
# nself sentry ci enable <repo> must be run on the CamClaw server first.
# Once registered, the runner's nself-sentry-sync hook delivers this report
# to ~/Sites/acamarata/.claude/inbox via root@sentry-errors.ariccamarata.com.
echo "CI_FAILURE repo=${{ github.repository }} job=${{ github.job }} run=${{ github.run_id }}" >&2
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Enable corepack
run: corepack enable
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Build
run: pnpm run build
- name: Coverage
run: pnpm run coverage
- name: Upload to Codecov
uses: codecov/codecov-action@v4
with:
files: ./coverage/lcov.info
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false
- name: Report failure to nSentry
if: failure()
run: |
# nself sentry ci enable <repo> must be run on the CamClaw server first.
# Once registered, the runner's nself-sentry-sync hook delivers this report
# to ~/Sites/acamarata/.claude/inbox via root@sentry-errors.ariccamarata.com.
echo "CI_FAILURE repo=${{ github.repository }} job=${{ github.job }} run=${{ github.run_id }}" >&2

View file

@ -66,3 +66,7 @@ The core algorithm is a JavaScript port of the NREL SPA by Ibrahim Reda and Afsh
## License
MIT (TypeScript wrapper and build tooling). The core algorithm in `lib/spa.js` is a port of NREL's SPA C source, subject to its own terms. See [LICENSE](./LICENSE).
## Telemetry
This package supports optional, anonymous usage telemetry via [`@acamarata/telemetry`](https://github.com/acamarata/telemetry). It is **off by default**. See [TELEMETRY.md](https://github.com/acamarata/telemetry/blob/main/TELEMETRY.md) for what is collected and how to enable or disable it.

8
TELEMETRY.md Normal file
View file

@ -0,0 +1,8 @@
# Telemetry Disclosure
This package supports opt-in anonymous usage telemetry via [`@acamarata/telemetry`](https://github.com/acamarata/telemetry).
Telemetry is **off by default**. No data is sent unless you set `ACAMARATA_TELEMETRY=1`.
Full disclosure (what is sent, where it goes, how to disable):
[github.com/acamarata/telemetry/blob/main/TELEMETRY.md](https://github.com/acamarata/telemetry/blob/main/TELEMETRY.md)

View file

@ -71,6 +71,7 @@
"devDependencies": {
"@acamarata/eslint-config": "^0.1.0",
"@acamarata/prettier-config": "^0.1.0",
"@acamarata/telemetry": "^0.1.0",
"@acamarata/tsconfig": "^0.1.0",
"@eslint/js": "^10.0.1",
"@types/node": "^25.3.0",

View file

@ -14,6 +14,9 @@ importers:
'@acamarata/prettier-config':
specifier: ^0.1.0
version: 0.1.0(prettier@3.8.1)
'@acamarata/telemetry':
specifier: ^0.1.0
version: 0.1.0
'@acamarata/tsconfig':
specifier: ^0.1.0
version: 0.1.0
@ -81,6 +84,10 @@ packages:
peerDependencies:
prettier: '>=3.0.0'
'@acamarata/telemetry@0.1.0':
resolution: {integrity: sha512-iP09ZD0bHencHLbv6kQZDgwN9crLCWGKxmiMrfJjhBCoWTgv4koSgg0Li/LFKwCCFluua6orj9fVeQ8eqcJXSQ==}
engines: {node: '>=20'}
'@acamarata/tsconfig@0.1.0':
resolution: {integrity: sha512-bgzyBak43mE+0HhduZX3cvaPjKcggtGGZZMjr35qtYWolsIWgZ9nx7OOswbVYoU35qoUv6rZ0mTK6GbZ8QTYjw==}
engines: {node: '>=20'}
@ -1225,6 +1232,8 @@ snapshots:
dependencies:
prettier: 3.8.1
'@acamarata/telemetry@0.1.0': {}
'@acamarata/tsconfig@0.1.0': {}
'@bcoe/v8-coverage@1.0.2': {}

View file

@ -367,3 +367,12 @@ export function calcSpa(
sunset: formatTime(raw.sunset),
};
}
// ── Opt-in anonymous telemetry ────────────────────────────────────────────────
// Off by default. Enable: ACAMARATA_TELEMETRY=1
// What is sent + how to disable: https://github.com/acamarata/telemetry/blob/main/TELEMETRY.md
import("@acamarata/telemetry")
.then(({ track }) => track("load", { package: "nrel-spa", version: "2.0.2" }))
.catch(() => {
// telemetry not installed or disabled — that's fine
});