From 09079091aea0c0881991609340795039f798c61e Mon Sep 17 00:00:00 2001 From: Aric Camarata Date: Tue, 30 Jun 2026 15:56:57 -0400 Subject: [PATCH] add opt-in anonymous telemetry (#1) * 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 --- .forgejo/workflows/ci.yml | 138 ++++++++++++++++++++++++++++++++++++++ README.md | 4 ++ TELEMETRY.md | 8 +++ package.json | 1 + pnpm-lock.yaml | 9 +++ src/index.ts | 9 +++ 6 files changed, 169 insertions(+) create mode 100644 .forgejo/workflows/ci.yml create mode 100644 TELEMETRY.md diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml new file mode 100644 index 00000000..c5e3a1cf --- /dev/null +++ b/.forgejo/workflows/ci.yml @@ -0,0 +1,138 @@ +# 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: + name: Test (Node ${{ matrix.node }}) + runs-on: ubuntu-latest + strategy: + matrix: + node: [20, 22, 24] + steps: + - uses: actions/checkout@v4 + - name: Enable corepack + run: corepack enable + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm build + - run: node --test test.mjs + - run: node --test test-cjs.cjs + - name: Report failure to nSentry + if: failure() + run: | + # nself sentry ci enable 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 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: + name: Typecheck + 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 typecheck + - name: Report failure to nSentry + if: failure() + run: | + # nself sentry ci enable 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: + name: Pack check + 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 build + - name: Verify pack contents + run: | + PACK=$(npm pack --dry-run 2>&1) + echo "$PACK" + for f in dist/index.cjs dist/index.mjs dist/index.d.ts dist/index.d.mts README.md LICENSE CHANGELOG.md; do + echo "$PACK" | grep -q "$f" || (echo "Missing: $f" && exit 1) + done + echo "$PACK" | grep -q "src/" && (echo "ERROR: src/ should not be in pack" && exit 1) || true + echo "Pack check passed" + - name: Report failure to nSentry + if: failure() + run: | + # nself sentry ci enable 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: + name: 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 + - run: pnpm build + - 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 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 diff --git a/README.md b/README.md index 69a42cdf..68645a74 100644 --- a/README.md +++ b/README.md @@ -58,3 +58,7 @@ Images are in the public domain per NASA's [media usage guidelines](https://www. ## License MIT. See [LICENSE](LICENSE) for the full text. + +## 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. \ No newline at end of file diff --git a/TELEMETRY.md b/TELEMETRY.md new file mode 100644 index 00000000..99cfaa4e --- /dev/null +++ b/TELEMETRY.md @@ -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) diff --git a/package.json b/package.json index ef33ef86..6f729032 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,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": "^22.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 32bb0352..5a60f14e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -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': {} diff --git a/src/index.ts b/src/index.ts index 2e3c0e4e..a9340719 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,3 +11,12 @@ export { YEAR_ANCHOR, } from "./types.js"; export { imageFolder, cdnUrl } from "./helpers.js"; + +// ── 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: "moon-cycle", version: "2.0.0" })) + .catch(() => { + // telemetry not installed or disabled — that's fine + });