ActionsCounter
Project analytics on GitHub Actions alone — superseded by CFlair-Counter / ViewFlare.
An event counter with no server: a single GitHub Actions workflow, run on demand from the Actions tab or by a repository_dispatch webhook, keeps per-project counts in the repository's own Actions variables as base64-encoded JSON, and a Vite dashboard published to GitHub Pages reads them back. A PostgreSQL storage mode is also implemented. This is the earlier approach to the problem; the current counter is CFlair-Counter (being renamed ViewFlare), which runs on Cloudflare Pages/Workers with D1 and serves counter.vkrishna04.me. ActionsCounter stays online as a working record of the Actions-based design.
Built with
Highlights
- ▸No infrastructure at all — the counter is one workflow file, and the state lives in GitHub Actions repository variables rather than in any database you have to run.
- ▸Counts change only when the workflow is dispatched; there is no schedule, so a quiet project costs nothing.
- ▸A second storage mode swaps the Actions variables for a PostgreSQL table when the 48KB variable limit gets close.
- ▸Manual runs are gated on an admin password held as a repository secret, and webhook runs on a per-project token compared as a SHA-256 hash.
- ▸Superseded by CFlair-Counter / ViewFlare on Cloudflare Pages/Workers with D1 — kept as a record of the GitHub-Actions-only approach.
From the README
🚀 ActionsCounter
Secure GitHub Actions-powered project analytics.
Superseded. ActionsCounter is the earlier, GitHub-Actions-based counter; the current one is CFlair-Counter (being renamed ViewFlare), which runs on Cloudflare Pages/Workers with D1 and serves
counter.vkrishna04.me. This repository stays up as a working record of the Actions-based approach.
Track project usage, downloads, API calls, or any events.
How it actually works: counts change only when the Handle Projects workflow runs, and that workflow runs only on demand — manually from the Actions tab (workflow_dispatch) or from a repository_dispatch webhook. There is no schedule and no cron; nothing updates on its own, and no push to this repository changes a count.
Where the data lives: in the repository's own GitHub Actions variables — PROJECTS_DATA (base64-encoded JSON) and ANALYTICS_DATA — not in a file in this repository. Two other storage modes exist; see Storage Modes.
⚡ Quick Start (5 Minutes)
1. Fork & Clone
# Fork this repository on GitHub, then:
git clone https://github.com/YOUR_USERNAME/ActionsCounter.git
cd ActionsCounter
2. Generate Personal Access Token
Required scopes:
- ✅
repo- Full repository access - ✅
workflow- Update workflows and trigger actions - ✅
admin:repo_hook- Repository webhook access - ✅
read:org- Read organization data
3. Set Repository Secrets
Replace {YOUR_USERNAME} with your GitHub username, then add:
ADMIN_PASSWORD = your_secure_password
PAT_TOKEN = your_personal_access_token_from_step_2
4. Choose Storage Mode
STORAGE_MODE = 1
Storage Options:
1= GitHub Variables (48KB, fast, recommended — and the fallback the workflow uses whenSTORAGE_MODEis unset)2= Database (unlimited, requires PostgreSQL setup)3= Repository Commits — not implemented. The workflow step is a stub that prints a warning and stores nothing.
5. Frontend Configuration
Nothing to edit. deploy-pages.yml substitutes the owner and repository name into frontend/src/main.ts and frontend/index.html at build time.
6. Enable GitHub Pages
Set source to: GitHub Actions. The dashboard is built and published by deploy-pages.yml, which runs on every push to main and on manual dispatch.
7. Test Your Setup
- Click "Run workflow"
- Action:
list - Password: your
ADMIN_PASSWORD - Click "Run workflow" again
8. Access Your Dashboard
Replace {YOUR_USERNAME} with your actual GitHub username in all URLs above.
🎯 Usage
Via GitHub Actions UI
- Actions tab → Handle Projects
- Choose action (
increment,add,list, etc.) - Enter project name and password
- Run workflow
Via Webhook (repository_dispatch)
curl -X POST \
-H "Authorization: token YOUR_PAT_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-H "Content-Type: application/json" \
https://api.github.com/repos/YOUR_USERNAME/ActionsCounter/dispatches \
-d '{
"event_type": "increment",
"client_payload": {
"project_alias": "proj_abc123",
"auth_token": "the-projects-own-auth-token"
}
}'
✅ Secure: no admin password in the request. The workflow SHA-256-hashes auth_token and compares it against the project's stored auth_hash; the admin password is read from repository secrets.
Known limitation. As committed, this webhook path does not complete.
project_aliasis read from the payload but never written to the step's outputs, so authentication always fails with "Project alias or auth token missing for webhook"; and the GitHub Variables operation step branches ongithub.event.inputs.action, which is empty forrepository_dispatch. Manualworkflow_dispatchruns are the path that works.
Available Actions
The Actions-tab form (workflow_dispatch) offers exactly these:
increment- Add 1 to project countdecrement- Subtract 1 from project count (floor 0)add- Create new projectremove- Delete projectset- Change any field of a project, including its count and its nameget- View project detailslist- Show all projects
repository_dispatch also declares a ping event type, but no storage mode implements a ping branch. There is no stats action.
📊 Storage Modes
| Mode | STORAGE_MODE | Where counts are stored | State |
|---|---|---|---|
| GitHub Variables | 1 (fallback default) | Actions repository variables PROJECTS_DATA and ANALYTICS_DATA, as base64-encoded JSON, bounded by GitHub's 48KB variable limit | Implemented |
| Database | 2 | A PostgreSQL table, reached with psql from the runner | Implemented |
| Repository Commits | 3 | — | Stub. The step prints "Repository commits mode operations need to be implemented" and stores nothing |
data/projects.json in this repository is an empty seed file. No workflow reads or writes it — the live counts are in the PROJECTS_DATA Actions variable, so they live outside the git history entirely.
Recommended: GitHub Variables (mode 1) — the default, and the only path that is routinely exercised.
🔒 Security Features
- Password Protection: manual (
workflow_dispatch) runs require theADMIN_PASSWORDsecret; webhook (repository_dispatch) runs authenticate against a per-project token instead, compared as a SHA-256 hash - Repository Secrets: Sensitive data stored securely in GitHub
- Token Validation: GitHub token authentication
- No Browser Storage: Zero sensitive data in localStorage
📚 Documentation
- 📖 Complete Documentation - Comprehensive guides and references
- 🎯 Usage Examples - Detailed usage examples and patterns
- 🔑 GitHub Token Scopes - Required Token permissions
- ⚡ Quick Setup - Detailed setup walkthrough
- 🔗 API Reference - All actions and webhook examples
- 🗃️ Storage Modes - Choose the right storage mode
🛠️ Database Setup (Mode 2 Only)
For Database mode, add these secrets:
DB_HOST = your_postgres_host
DB_NAME = your_database_name
DB_PORT = 5432
DB_USER = your_username
DB_PASS = your_password
DB_SCHEMA = myschema
Free PostgreSQL Providers:
🌟 Example Use Cases
- Download Tracking: Monitor software/file downloads
- API Analytics: Track API endpoint usage
- Website Metrics: Count page views and interactions
- Project Usage: Monitor tool/library adoption
- Event Tracking: Log application events
🔧 Support & Community
📚 Documentation
- 📖 Complete Setup Guide - Comprehensive documentation
- ❓ FAQ - Quick answers to common questions
- 🛠️ Troubleshooting - Step-by-step problem solving
🤝 Get Help
- 💬 GitHub Discussions - Ask questions, share ideas
- 🐛 Report Bug - Found an issue? Let us know
- ✨ Request Feature - Suggest new features
- 🆘 Support Guide - Comprehensive support information
🌟 Contributing
- 🤝 Contributing Guide - How to contribute to the project
- 👥 Contributors - Meet our amazing contributors
Quick Help:
- "Invalid password" error: Check
ADMIN_PASSWORDsecret is set correctly - Analytics not showing:
ANALYTICS_DATAis seeded with zeros on first run, but the step that recomputes it is gated to the unimplemented repository-commits mode, so in GitHub Variables mode it never refreshes. Per-project counts still come fromPROJECTS_DATA. - Need immediate help? Check our FAQ first!
📄 License
Apache 2.0 License - see LICENSE.md
🚀 Ready to start tracking? For a new setup, prefer CFlair-Counter / ViewFlare. To run this Actions-based version anyway, fork the repo and follow the Quick Start guide above.