All projects
ArchivedDevOpsApr 2025 — present

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

TypeScriptGitHub ActionsGitHub API

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

📝 Create GitHub 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

🔐 Configure 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

⚙️ Set Variables

STORAGE_MODE = 1

Storage Options:

  • 1 = GitHub Variables (48KB, fast, recommended — and the fallback the workflow uses when STORAGE_MODE is 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

📄 Setup 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

🧪 Run Test Workflow

  • Click "Run workflow"
  • Action: list
  • Password: your ADMIN_PASSWORD
  • Click "Run workflow" again

8. Access Your Dashboard

🌐 View Dashboard

Replace {YOUR_USERNAME} with your actual GitHub username in all URLs above.

🎯 Usage

Via GitHub Actions UI

  1. Actions tab → Handle Projects
  2. Choose action (increment, add, list, etc.)
  3. Enter project name and password
  4. 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_alias is 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 on github.event.inputs.action, which is empty for repository_dispatch. Manual workflow_dispatch runs are the path that works.

Available Actions

The Actions-tab form (workflow_dispatch) offers exactly these:

  • increment - Add 1 to project count
  • decrement - Subtract 1 from project count (floor 0)
  • add - Create new project
  • remove - Delete project
  • set - Change any field of a project, including its count and its name
  • get - View project details
  • list - 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

ModeSTORAGE_MODEWhere counts are storedState
GitHub Variables1 (fallback default)Actions repository variables PROJECTS_DATA and ANALYTICS_DATA, as base64-encoded JSON, bounded by GitHub's 48KB variable limitImplemented
Database2A PostgreSQL table, reached with psql from the runnerImplemented
Repository Commits3—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 the ADMIN_PASSWORD secret; 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

🛠️ 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

🤝 Get Help

🌟 Contributing

Quick Help:

  • "Invalid password" error: Check ADMIN_PASSWORD secret is set correctly
  • Analytics not showing: ANALYTICS_DATA is 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 from PROJECTS_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.

Local Storage Notice

This site uses local storage to cache GitHub data for better performance, and an anonymous visit counter. No personal data is stored or shared.