尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证GitHub page for stharrold, "Data Science Demos", with source code (`src_*` branches).
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Source for Data Science Demos, a blog built with Pelican and deployed to GitHub Pages by GitHub Actions.
Requirements: uv (Python 3.12+). All dependencies are pinned in pyproject.toml and uv.lock.
uv sync # install Pelican, plugins, Pagefind, dev tools
uv run pre-commit install # once: ruff and file checks on commit
uv run pelican --settings pelicanconf.py # build the dev site into output/ (drafts included, no analytics)
uv run python -m pagefind --site output # build the search index (rerun after each build)
uv run pelican --listen # serve output/ at http://localhost:8000
uv run pytest # build the publish site in a temp dir and check it
uv run pelican --settings pelicanconf.py --autoreload --listen rebuilds on every change, but each rebuild deletes
output/pagefind/, so search only works after rerunning Pagefind. Stop it with Ctrl-C; killing only the parent
process leaves its file watcher running.
| Branch | Purpose |
|---|---|
src_master | Production source. Every push builds, tests, and deploys the site (.github/workflows/pages.yml). |
src_develop | Integration branch; pushes run the same checks without deploying. |
src_feature_* | Feature branches off src_develop (git-flow); merged with --no-ff. |
(tag) legacy-ghp-import-master | The former master branch, which held the built site (via ghp-import) until 2026-10-06. |
To release: merge src_feature_* into src_develop, then src_develop into src_master, and push. The workflow runs
ruff, pytest, pelican --settings publishconf.py --fatal warnings, and Pagefind, then deploys output/.
GitHub Pages must be set to Settings > Pages > Source: GitHub Actions. output/ is generated and not tracked.
To verify a deploy, wait for the run (gh run watch <id>; find it with
gh run list --workflow pages.yml --json databaseId,headSha), then check the live site with a cache-busting query,
e.g. curl -s "https://stharrold.github.io/?v=$(date +%s)". For visual changes, compare before/after screenshots of a
local dev build served with python3 -m http.server before merging to src_master.
Automation:
.github/workflows/links.yml logs internal and external link status every Monday (and on manual dispatch) against
a fresh build: a job summary plus a link-report JSON artifact kept 90 days. It is report-only (never fails, files
no issues); alerting belongs to whatever reads the log. Dead links in the frozen 2015-2016 posts are left as is.
GitHub disables scheduled workflows in public repos after 60 days without repository activity, so the log can
stop silently on a quiet blog; re-enable with gh workflow enable links.yml (see #67)..github/dependabot.yml) opens weekly grouped PRs for GitHub Actions and Python packages against
src_develop; security fixes target src_master, so review them as deploys. Actions are pinned to commit SHAs.themes/README.md.pelicanconf.py holds the site settings; publishconf.py extends it for production (absolute URLs, feeds, GA4,
no drafts).
Posts are Markdown files in content/ with a metadata header (Title, Date, Modified, Category, Tags,
Slug, Summary, optional Related_posts and Alias for old URLs). Pages go in content/pages/. Notebooks,
notebook HTML exports, and images go in content/static/<slug>/ and are linked with {static}/static/<slug>/....
Status: draft renders only in dev builds (output/drafts/). Static files are copied regardless of
status, so add a draft's static/<slug> folder to STATIC_EXCLUDES in publishconf.py, and remove it when the
post is published.$...$ inline and $$...$$ display (as its own paragraph); rendered by MathJax 4.
Prices such as $20 are left alone.OUTDATED_AFTER_YEARS).uv run pytest. Deploys stop on any Pelican warning (for example a broken
{filename}/{static} link) or failed test. The tests derive what to expect from content/, so new and newly
published posts need no test changes; publishing a draft that has a STATIC_EXCLUDES entry fails with a message
saying which entry to remove.themes/datasciencedemos/, Bootstrap 5 with Bootswatch Flatly, forked from pelican-bootstrap3;
see themes/README.md.output/ after Pelican; runs in the browser.data/archived-comments/<slug>.html.G-K4PX9089RZ, publish builds only, Google signals off), exported daily to
BigQuery project stharrold-github-io (dataset analytics_393124094). Universal Analytics history recovered from
the GA monthly snapshot emails (2017-11 to 2019-10) is in stharrold-github-io.ua_history.monthly_snapshots.scripts/analytics_archive.py copies every BigQuery table to Parquet in the private Google
Drive folder My_Drive/Data/stharrold.github.io/ (ga4/events_YYYYMMDD.parquet, ua_history/), reads each file
back, and records rows, BigQuery's last-modified time, a sha256 and the writing commit in manifest.json; each run
also writes a README.md there linking back to this repository at that commit. A day is archived once it is
3 days old (GA4 adds late events for 72 hours); a table that changes later is archived again with the old file
kept in superseded/; nothing is deleted. It warns if the newest export is over 7 days old, if an archived table
has left BigQuery, or if billing is off. A launchd job runs it at 09:00 and 21:00 from a copy outside ~/Documents:
install or update with bash scripts/install_analytics_launchd.sh (re-run after changing either script), start a
run with --run-now, log in ~/Library/Logs/stharrold-analytics.log. uv run --script scripts/analytics_archive.py --dry-run shows what is due. The read-back checks the write, not Drive's upload. The files include visitor
pseudonymous IDs, so they never go in git./analytics skill (.claude/skills/analytics/SKILL.md): checks the archive is healthy, reports readership with
uv run --script scripts/analytics_report.py --save (DuckDB over the archive plus the days still only in BigQuery;
totals saved to on Drive; pages ranked only once one has 30 engaged visitors), then proposes
the next post. Engaged visitors (GA4 or engagement time) screen out most crawlers. The owner's own
visits are kept out three ways: a GA4 internal-traffic rule for the home IP with the Internal Traffic filter active
(from 2026-10-29; re-enter the IP if it changes), the Google Analytics opt-out add-on in the owner's browsers, and
on Drive (browser IDs from the cookie, which the report drops from all past data).
How it was built: .Open work is tracked as GitHub issues grouped in milestones: one per post ("post about predicting income", "post about agentic development", ...) plus Site maintenance for build, theme, and tooling upkeep. Planned posts, in order: a pre-registered causal study on CMS Medicare Shared Savings Program data (#73, pinned), an evaluation harness for a retrieval-augmented QA agent (#74), and an interactive household-income demo built from ACS PUMS data (#68). Published 2015-2016 posts are frozen as written.
Code: MIT. Content: CC BY 4.0, except where indicated
otherwise. Vendored theme assets keep their own licenses (themes/datasciencedemos/licenses/).
reports/YYYY-MM-DD.mdsession_engagedexcluded_visitors.txt_gaanalysis/site-analytics/BUILD-NOTES.mdhttps://stharrold.github.io/ (URL prefix, verified through the GA4 tag, so removing
the tag unverifies it), linked to GA4 and bulk-exporting daily to BigQuery dataset searchconsole since 2026-10-29
(the export's service account has BigQuery Job User and Data Editor on the project). The archive copies its tables
one data_date partition per file (searchconsole/<table>/YYYYMMDD.parquet). Search Console keeps only 16 months
and the export does not backfill, so the earlier history is saved once with uv run --script scripts/analytics_archive.py searchconsole-backfill into searchconsole_backfill/<stamp>/; it needs a
webmasters.readonly login kept in its own gcloud configuration, so the default credentials stay untouched:
CLOUDSDK_CONFIG=$HOME/.config/gcloud-searchconsole gcloud auth application-default login --scopes=openid,https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/webmasters.readonly.assets/youtube/ (outside content/, so not published), made by uv run --no-sync python scripts/youtube_art.py
in the site's colours and Lato; its README records what was uploaded. Video files stay on Google Drive, not in git.
How it was set up: analysis/youtube-channel/BUILD-NOTES.md.content/pages/privacy.md lists every third-party service the site loads; update it when adding one.related_posts, tag_cloud, sitemap (from PyPI), and plugins/pelican_alias.py
(Python 3 port of pelican-alias) for Alias: redirects.