GitHub
GitHub is the operational backbone of TABS — it hosts the code, enforces quality gates, deploys the site, scans for vulnerabilities, and orchestrates every external-API data pipeline.
Role Overview
Most projects treat GitHub as a place to store code and open pull requests. TABS uses it as a full DevOps platform. Every automated task — from daily analytics reports to weekly participant-data collection — runs inside GitHub Actions, is gated by environment secrets, and produces auditable step summaries.
CI/CD Pipeline
Continuous Integration
The core CI workflow (ci.yml) runs on every pull request, merge-queue entry, and push to main. It executes five stages sequentially, then fans out into four parallel shards for E2E testing:
| Stage | Command | What It Catches |
|---|---|---|
| Format check | npm run format:check | Inconsistent code formatting |
| Lint | npm run lint | ESLint errors, unused imports |
| Unit tests | npm test | Logic regressions, accessibility violations (jest-axe) |
| Build | npm run build | TypeScript errors, static export failures |
| E2E (4 shards) | npx playwright test --shard=n/4 | Visual regressions, broken navigation, missing images |
Concurrency control ensures that pushing a new commit to a PR cancels any in-progress CI run for the same ref, saving compute and avoiding stale results.
Deployment
When CI passes on main, the deployment workflow builds the static site with output: 'export' and publishes the out/ directory to the github-pages environment. The site is served at the custom domain technologyadoptionbarriers.org via a CNAME record managed in Cloudflare.
Performance Monitoring
A Lighthouse CI workflow runs after every deployment and on a weekly schedule. It dynamically discovers every HTML page in the build output and runs Lighthouse against each one, providing performance, accessibility, best-practices, and SEO scores.
All GitHub Actions Workflows
The repository contains 11 workflow files covering CI, deployment, security, performance, and three external API integrations:
| Workflow | Trigger | Purpose |
|---|---|---|
| ci.yml | PR, merge queue, push | Format, lint, test, build, E2E (4 shards) |
| deploy.yml | After CI on main | Build and deploy to GitHub Pages |
| codeql.yml | PR, push, weekly | Security scanning (JS/TS + Actions) |
| lighthouse.yml | After deploy, weekly | Performance audit of every page |
| ga-report.yml | Daily (00:00 UTC) | Fetch GA4 data, update impact.json, email report |
| qualtrics-metrics-update.yml | Daily (03:17 UTC) | Fetch Qualtrics survey metrics, update data file |
| prolific.yml | Weekly (Mon 09:00 UTC) | Collect participant data from Prolific API |
| qualtrics-api-smoke.yml | Manual | API connectivity and authentication check |
| qualtrics-prolific-verify.yml | Manual | Cross-platform survey setup verification |
| fetch-qualtrics-questions.yml | Manual | Download survey question definitions |
| qualtrics-dump-flow.yml | Manual | Export Survey Flow JSON for inspection |
Automated Code Review
GitHub Copilot Review
Every pull request is automatically reviewed by GitHub Copilot when marked as Ready for review. Copilot scans for common issues — accessibility problems, missing ARIA labels, type safety gaps, and unused code. Review comments appear inline on the PR diff and must be addressed before merging.
CODEOWNERS
A CODEOWNERS file maps file paths to responsible reviewers. This ensures that changes to security-sensitive files (workflows, environment configs, governance docs) always require review from the appropriate owner.
PR Template
A comprehensive pull request template guides contributors through a structured description with sections for change type, related issues, manual testing, automated testing, accessibility, and a final checklist. This standardizes the review process and ensures nothing is overlooked.
Security Scanning
CodeQL
CodeQL Advanced runs on every push and PR to main, plus on a weekly schedule. It analyses two language matrices:
- JavaScript / TypeScript — source code analysis for injection vulnerabilities, insecure data handling, and logic errors
- GitHub Actions — workflow security analysis for secret exposure, untrusted input usage, and privilege escalation
Dependabot
Dependabot monitors two ecosystems weekly (Monday 09:00 UTC):
- npm — groups production and development dependency updates (minor + patch) into separate PRs, with major versions handled individually for careful review. Limited to 10 open PRs.
- GitHub Actions — updates action versions. Limited to 5 open PRs.
GitHub Environments
External API credentials are stored in environment-scoped secrets, never in the repository. Each environment is locked to specific workflows:
| Environment | Integration | Workflows |
|---|---|---|
| github-pages | GitHub Pages | deploy.yml |
| qualtrics-prod | Qualtrics API v3 | 5 workflows |
| prolific-prod | Prolific API v1 | 2 workflows |
| google-prod | Google Analytics Data API | ga-report.yml |
Automated Data Pipelines
Several workflows act as data pipelines — they fetch data from external APIs, update JSON files in the repository, and create auto-merge PRs. This keeps the site’s displayed metrics current without manual intervention:
- GA daily report — fetches analytics from GA4, updates
impact.json, creates a PR viapeter-evans/create-pull-request, and auto-merges it - Qualtrics metrics update — fetches survey response counts and updates
qualtrics-metrics.json, also auto-merged - Prolific data collection — weekly export of participant submission data, uploaded as a CI artifact
All pipeline outputs appear as GitHub Actions Job Summaries, using utility functions from src/lib/github-utils.ts that write Markdown tables and status indicators to GITHUB_STEP_SUMMARY.
Release Management
A TypeScript release-notes generator (scripts/generate-release-notes.ts) uses the GitHub CLI to query merged PRs and closed issues between Git refs. It separates human contributors from bots, categorises changes into user-facing and internal improvements, and produces structured Markdown with sections for each external integration.
The release process follows Conventional Commits — every commit message and PR title starts with a type prefix (feat:, fix:, docs:, chore:), enforced by a commitlint hook.
Community Health Files
The repository includes a complete set of GitHub-recognised community health files that appear automatically in the GitHub navigation:
README.md
Project overview and quick start
LICENSE
Apache 2.0
CODE_OF_CONDUCT.md
Contributor Covenant 2.1
CONTRIBUTING.md
Contribution guidelines
SECURITY.md
Security policies and reporting
SUPPORT.md
Support resources
CITATION.cff
Academic citation info
CHANGELOG.md
Release notes
.github/FUNDING.yml
GitHub Sponsors button
.github/CODEOWNERS
Auto-assign reviewers
.github/PULL_REQUEST_TEMPLATE.md
PR template
Issue templates (4)
Bug, feature, docs, onboarding
Lessons Learned
- Environment secrets are essential. Storing API tokens in environment-scoped secrets (not repository-level) limits blast radius — a workflow only has access to the environment it declares.
- Sharded E2E pays off fast. Splitting Playwright across 4 shards cuts E2E wall time by ~75%. The overhead of spinning up extra runners is negligible compared to running 50+ test files sequentially.
- Auto-merge data PRs carefully. The GA and Qualtrics pipelines auto-merge their data-update PRs. This works because (a) the PRs only modify specific JSON files, (b) CI validates the build after the update, and (c) the commit history is transparent. Manual review would create a bottleneck for daily data updates.
- Job Summaries improve observability. Writing Markdown tables to
GITHUB_STEP_SUMMARYturns workflow runs into readable reports without scrolling through log output.
Related
- Cloudflare Integration — DNS, CDN, and security layer that sits in front of GitHub Pages
- Google Analytics Integration — the GA4 data pipeline that feeds impact.json
- Qualtrics Integration — the survey automation workflows
- All Technical Integrations
