Skip to content

ci(docs): activate docs-site analytics wiring + privacy facts#456

Merged
marcusrbrown merged 2 commits into
mainfrom
feat/launch-analytics
May 30, 2026
Merged

ci(docs): activate docs-site analytics wiring + privacy facts#456
marcusrbrown merged 2 commits into
mainfrom
feat/launch-analytics

Conversation

@marcusrbrown
Copy link
Copy Markdown
Owner

Summary

Wires up the final launch unit: makes the docs-site analytics actually activatable, and fills the privacy page with the real data-handling facts. This is the mechanism behind the public launch — it does not itself turn analytics on.

What's included

  • ci(docs): thread UMAMI_WEBSITE_ID into the docs build. astro.config.mjs only injects the Umami script when UMAMI_WEBSITE_ID is set at build time, but the "Build docs" step had no env: block — GitHub Actions doesn't auto-expose repo variables to run: steps, so the script never shipped even if the variable existed. Now the build passes vars.UMAMI_WEBSITE_ID through. Unset (dev, forks, or before the variable is configured) → no script at all.
  • docs: privacy page IP/identifier facts. Replaces the pre-launch placeholder with the live metrics.fro.bot posture: no raw IPs or personal identifiers stored, monthly-rotating one-way hash for visitor counting, approximate location derived locally with no third-party calls, Do-Not-Track visitors not recorded.

Verified

The env gating was tested both ways against a real build:

Build Umami script in homepage
UMAMI_WEBSITE_ID unset absent (0 tags)
UMAMI_WEBSITE_ID set present, with data-website-id

Workflow YAML parses clean. docs:build produces 112 pages in both modes.

Activation is a separate, manual step (not in this PR)

Merging this PR does not start collecting analytics. After merge, the launch is:

  1. Set the repo variable UMAMI_WEBSITE_ID (the website id is public — it ships in client HTML — so a variable, not a secret).
  2. Trigger the Docs workflow via workflow_dispatch to build + deploy with the variable set.
  3. Verify the live site loads the tracker and metrics.fro.bot receives a pageview.

Release impact

ci(docs) / docs — no published-package surface change, so no version bump. The docs site deploys on the next release or a manual dispatch.

astro.config.mjs injects the Umami script only when UMAMI_WEBSITE_ID is set at
build time, but the Build docs step had no env block — GitHub Actions does not
auto-expose repo variables to run steps, so analytics never activated. Pass the
public website id via vars.UMAMI_WEBSITE_ID. When the variable is unset (dev,
forks), the script is omitted entirely.
Replaces the pre-launch placeholder with the metrics.fro.bot data posture: no
raw IPs or personal identifiers stored, monthly-rotating one-way hash for
visitor counting, approximate location derived locally with no third-party
calls, Do-Not-Track visitors not recorded.
Copy link
Copy Markdown
Collaborator

@fro-bot fro-bot left a comment

Choose a reason for hiding this comment

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

Verdict: PASS

Tight, well-scoped launch-mechanism PR. The workflow fix correctly addresses a real GitHub Actions gotcha (repo vars.* are not auto-exposed to run: steps), and the gating in astro.config.mjs:109 means an unset variable is a true no-op — safe to merge before the variable is configured. Privacy copy aligns with documented Umami defaults plus the data-do-not-track="true" config already in astro.config.mjs.

Blocking issues

None.

Non-blocking concerns

  • Retention silently dropped from the privacy page. The previous heading was "Retention and IP handling" with a placeholder note that retention specifics would be added before launch. The new content (docs/src/content/docs/privacy.mdx:40-42) renames the section to "IP addresses and identifiers" and removes the retention promise entirely without stating a retention period. If the live metrics.fro.bot instance has a configured retention window (Umami defaults to indefinite unless data deletion is configured), a one-sentence statement — even "data is retained indefinitely in aggregate form" — would close the loop the prior copy opened. As written, a careful reader notices the topic was dropped rather than answered.
  • Workflow env scope. UMAMI_WEBSITE_ID is scoped to the single "Build docs" step (.github/workflows/docs.yaml:81-84), which is correct and minimal. No action needed; flagging for awareness if a future step also needs it (e.g., a preview-build matrix), it will need its own env: block.
  • No workflow_dispatch input fallback. The PR description's activation plan calls for a manual workflow_dispatch to deploy with the variable set. Since vars.UMAMI_WEBSITE_ID is repo-wide, that already works — but if you ever want to deploy a one-off build with a different/empty id (e.g., to verify the unset path on the live deploy pipeline without unsetting the repo var), consider a workflow_dispatch input that overrides. Not needed for this PR.

Missing tests

None required. The PR description documents a manual two-mode build verification (script present/absent depending on env), which is the right test for this surface — there's no unit-testable seam here, and adding a workflow-lint test for a four-line env: block would be overkill. The astro config already gates correctly at astro.config.mjs:109.

Risk assessment: LOW

  • Blast radius: docs site only. No plugin runtime, no published package, no config/tool/system.transform hook surface touched.
  • Regression likelihood: very low. The workflow change is additive (env: block on one step); when vars.UMAMI_WEBSITE_ID is unset, the value is empty string, process.env.UMAMI_WEBSITE_ID is falsy, and the script array stays empty — identical to today's behavior.
  • Security exposure: none. The website id is public by design (ships in client HTML); using vars rather than secrets is correct. No new injection surface — the value flows into a data-website-id attribute, not into shell or HTML body.
  • Privacy/compliance: the new privacy copy makes stronger affirmative claims ("No raw IP addresses or personal identifiers are stored", "one-way hash that rotates monthly"). These match Umami's documented behavior, but they are now load-bearing statements about the live metrics.fro.bot instance configuration. Worth a one-time confirmation that the instance is not configured to log raw IPs (e.g., via reverse-proxy access logs feeding into the same retention scope) before flipping the variable on.

Run Summary
Field Value
Event pull_request
Repository marcusrbrown/systematic
Run ID 26670020365
Cache hit
Session ses_1899a1992ffemiXq70W8BUW2ZP

@marcusrbrown marcusrbrown merged commit a958aeb into main May 30, 2026
11 checks passed
@marcusrbrown marcusrbrown deleted the feat/launch-analytics branch May 30, 2026 01:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants