Add Usage Statistics Tracker GitHub Action with configuration options, outputs, and README integration

This commit is contained in:
Luke Hagar
2025-07-29 14:19:22 -05:00
parent 7975dc0cbe
commit 1f24188c62
9 changed files with 937 additions and 131 deletions

52
.github/workflows/test-action.yml vendored Normal file
View File

@@ -0,0 +1,52 @@
name: Test GitHub Action
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:
jobs:
test-action:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Run tests
run: bun test
- name: Build action
run: bun run action:build
- name: Test action with preview mode
uses: ./
with:
preview-mode: 'true'
json-output-path: 'test-stats.json'
csv-output-path: 'test-stats.csv'
report-output-path: 'test-report.md'
update-readme: 'false'
- name: Check outputs
run: |
echo "Checking generated files..."
ls -la test-stats.* test-report.md || echo "No output files found (expected in preview mode)"
echo "Checking action outputs..."
echo "JSON output: ${{ steps.test-action.outputs.json-output }}"
echo "CSV output: ${{ steps.test-action.outputs.csv-output }}"
echo "Report output: ${{ steps.test-action.outputs.report-output }}"
echo "Total downloads: ${{ steps.test-action.outputs.total-downloads }}"
echo "Unique packages: ${{ steps.test-action.outputs.unique-packages }}"
echo "Platforms tracked: ${{ steps.test-action.outputs.platforms-tracked }}"

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Usage Statistics Tracker
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

258
PUBLISHING.md Normal file
View File

@@ -0,0 +1,258 @@
# Publishing to GitHub Marketplace
This guide walks you through the process of publishing the Usage Statistics Tracker to the GitHub Marketplace.
## Prerequisites
1. **GitHub Account**: You need a GitHub account with a verified email
2. **Repository**: This repository should be public
3. **GitHub Actions**: Actions must be enabled on your repository
## Step 1: Prepare Your Repository
### 1.1 Build the Action
```bash
# Install dependencies
bun install
# Build the action for distribution
bun run action:build
# Verify the build
ls -la dist/
```
### 1.2 Commit the Built Files
```bash
# Add the built files
git add dist/
# Commit with a descriptive message
git commit -m "build: add action distribution files for v1.0.0"
# Push to main branch
git push origin main
```
### 1.3 Create a Release
```bash
# Create and push a tag
git tag v1.0.0
git push origin v1.0.0
# Or create a release via GitHub UI:
# 1. Go to your repository
# 2. Click "Releases" on the right
# 3. Click "Create a new release"
# 4. Choose the tag v1.0.0
# 5. Add release notes
# 6. Publish release
```
## Step 2: Publish to Marketplace
### 2.1 Access the Publishing Interface
1. Go to your repository on GitHub
2. Click on the **Actions** tab
3. Look for a banner that says "Publish this Action to the GitHub Marketplace"
4. Click **Publish this Action**
### 2.2 Fill in Action Details
#### Basic Information
- **Action name**: `usage-statistics-tracker`
- **Description**: `Track download statistics across multiple platforms (NPM, GitHub, PyPI, Homebrew, PowerShell, Postman, Go)`
- **Category**: Choose `Data` or `Utilities`
- **Icon**: Upload a relevant icon (512x512px PNG recommended)
- **Color**: Choose a brand color (e.g., `#0366d6` for blue)
#### Detailed Description
Use the content from the main README.md file, focusing on:
- Features and capabilities
- Usage examples
- Configuration options
- Supported platforms
#### Keywords
Add relevant keywords:
- `statistics`
- `analytics`
- `downloads`
- `npm`
- `github`
- `pypi`
- `homebrew`
- `powershell`
- `postman`
- `go`
- `tracking`
- `usage`
### 2.3 Marketplace Listing
#### Action Name
- **Marketplace name**: `Usage Statistics Tracker`
- **Description**: `Comprehensive GitHub Action for tracking download statistics across multiple platforms with configurable outputs and README integration`
#### Categories
- **Primary category**: `Data`
- **Secondary category**: `Utilities`
#### Pricing
- **Pricing model**: Free
- **License**: MIT
## Step 3: Version Management
### 3.1 Semantic Versioning
Follow semantic versioning for releases:
- **Major** (1.0.0): Breaking changes
- **Minor** (1.1.0): New features, backward compatible
- **Patch** (1.0.1): Bug fixes
### 3.2 Release Process
For each new version:
```bash
# 1. Update version in package.json
# 2. Update CHANGELOG.md
# 3. Build the action
bun run action:build
# 4. Commit changes
git add .
git commit -m "feat: release v1.1.0"
# 5. Create and push tag
git tag v1.1.0
git push origin v1.1.0
# 6. Create GitHub release
# Go to GitHub and create a release for the new tag
```
### 3.3 Changelog
Maintain a `CHANGELOG.md` file:
```markdown
# Changelog
## [1.1.0] - 2025-01-XX
### Added
- New platform support for X
- Enhanced error handling
- Additional configuration options
### Changed
- Improved performance for large datasets
- Updated dependencies
### Fixed
- Bug fix for Y platform
- Resolved issue with Z feature
## [1.0.0] - 2025-01-XX
### Added
- Initial release
- Support for NPM, GitHub, PyPI, Homebrew, PowerShell, Postman, Go
- Configurable outputs (JSON, CSV, human-readable)
- README integration
- Preview mode
```
## Step 4: Marketing and Documentation
### 4.1 README Optimization
Ensure your README includes:
- Clear installation instructions
- Multiple usage examples
- Configuration documentation
- Troubleshooting section
- Contributing guidelines
### 4.2 Examples Repository
Consider creating a separate repository with examples:
- Basic usage workflows
- Advanced configurations
- Custom integrations
- Troubleshooting guides
### 4.3 Social Media
Promote your action on:
- GitHub Discussions
- Reddit (r/github, r/devops)
- Twitter/X with relevant hashtags
- LinkedIn for professional audience
## Step 5: Maintenance
### 5.1 Monitoring
- Monitor GitHub Issues for user feedback
- Track download statistics
- Respond to questions and bug reports
- Update documentation as needed
### 5.2 Updates
Regular maintenance tasks:
- Update dependencies
- Fix security vulnerabilities
- Add new platform support
- Improve performance
- Enhance documentation
### 5.3 Community Engagement
- Respond to issues promptly
- Help users with configuration
- Accept and review pull requests
- Maintain a welcoming community
## Troubleshooting
### Common Issues
1. **Action not found**: Ensure the action is properly built and tagged
2. **Build failures**: Check that all dependencies are included
3. **Permission issues**: Verify GitHub token permissions
4. **Rate limiting**: Implement proper rate limiting in the action
### Support
- GitHub Issues: For bug reports and feature requests
- GitHub Discussions: For questions and community support
- Documentation: Comprehensive README and examples
## Success Metrics
Track these metrics to measure success:
- **Downloads**: Number of action downloads
- **Stars**: Repository stars
- **Forks**: Repository forks
- **Issues**: User engagement and feedback
- **Usage**: Number of repositories using the action
## Legal Considerations
- **License**: MIT License (included)
- **Privacy**: No personal data collection
- **Terms of Service**: Follow GitHub's terms
- **Attribution**: Credit original authors if applicable
## Resources
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
- [GitHub Marketplace Guidelines](https://docs.github.com/en/developers/github-marketplace)
- [Action Metadata Syntax](https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions)
- [Publishing Actions](https://docs.github.com/en/actions/creating-actions/publishing-actions-in-github-marketplace)

407
README.md
View File

@@ -1,184 +1,323 @@
# Usage Statistics
# Usage Statistics Tracker
A Bun TypeScript script project for analyzing usage statistics with a clean, modern architecture.
A comprehensive GitHub Action for tracking download statistics across multiple platforms (NPM, GitHub, PyPI, Homebrew, PowerShell, Postman, Go) with configurable outputs and README integration.
## Features
## 🚀 Features
- 🚀 **Fast Execution**: Built with Bun for lightning-fast TypeScript execution
- 📊 **Usage Analytics**: Track user actions and generate statistics
- 🧪 **Comprehensive Testing**: Full test suite with Bun's built-in test runner
- 📦 **Modern Tooling**: TypeScript, ES modules, and modern JavaScript features
- 🔧 **Developer Friendly**: Hot reloading, watch mode, and excellent DX
- 📊 **Multi-Platform Tracking**: NPM, GitHub, PyPI, Homebrew, PowerShell, Postman, Go
- 🎭 **Preview Mode**: Test with mock data without external API calls
- 📄 **Flexible Outputs**: JSON, CSV, and human-readable reports
- 📝 **README Integration**: Auto-update README with statistics
- ⚙️ **Configurable**: Custom configurations via JSON or preset modes
- 🔄 **GitHub Actions Ready**: Built for CI/CD workflows
- 🧪 **Comprehensive Testing**: Full test suite with Bun
## Prerequisites
## 📦 Installation
- [Bun](https://bun.sh/) (version 1.0.0 or higher)
### As a GitHub Action
## Installation
```yaml
- name: Usage Statistics Tracker
uses: your-username/usage-statistics@v1
with:
config: 'production'
json-output-path: 'stats.json'
csv-output-path: 'stats.csv'
report-output-path: 'report.md'
update-readme: 'true'
github-token: ${{ secrets.GITHUB_TOKEN }}
```
### Local Development
```bash
# Install dependencies
bun install
```
## Usage
### Running the Script
```bash
# Run the main script
# Run the tracker
bun start
# Preview the report with mock data (no external API calls)
# Preview mode (no external API calls)
bun preview
# Run in development mode with hot reloading
bun run dev
# Run directly with bun
bun run src/index.ts
# Run tests
bun test
```
### Preview Mode
## 🔧 Configuration
The preview mode allows you to see how the report will look without making any external API calls or writing files:
### Input Parameters
```bash
# Generate a preview report with mock data
bun preview
| Parameter | Description | Required | Default |
|-----------|-------------|----------|---------|
| `config` | Configuration mode or JSON | No | `production` |
| `json-output-path` | Path for JSON output | No | `stats.json` |
| `csv-output-path` | Path for CSV output | No | (empty) |
| `report-output-path` | Path for human-readable report | No | (empty) |
| `update-readme` | Whether to update README | No | `true` |
| `readme-path` | Path to README file | No | `README.md` |
| `github-token` | GitHub token for API access | No | `${{ github.token }}` |
| `postman-api-key` | Postman API key | No | (empty) |
| `commit-message` | Commit message for changes | No | `chore: update usage statistics [skip ci]` |
| `preview-mode` | Run with mock data | No | `false` |
# Or use the long flag
bun start --preview
### Configuration Modes
#### Production Mode
```yaml
- name: Usage Statistics Tracker
uses: your-username/usage-statistics@v1
with:
config: 'production'
```
This is useful for:
- Testing the report format
- Demonstrating the functionality
- Development and debugging
- CI/CD testing without external dependencies
### Building
```bash
# Build the project
bun run build
#### Development Mode
```yaml
- name: Usage Statistics Tracker
uses: your-username/usage-statistics@v1
with:
config: 'development'
```
### Testing
#### Custom JSON Configuration
```yaml
- name: Usage Statistics Tracker
uses: your-username/usage-statistics@v1
with:
config: '{"npmPackages": ["lodash", "axios"], "githubRepositories": ["microsoft/vscode"]}'
```
### Outputs
| Output | Description |
|--------|-------------|
| `json-output` | Path to the generated JSON file |
| `csv-output` | Path to the generated CSV file |
| `report-output` | Path to the generated report file |
| `total-downloads` | Total downloads across all platforms |
| `unique-packages` | Number of unique packages tracked |
| `platforms-tracked` | Comma-separated list of platforms tracked |
## 📋 Usage Examples
### Basic Usage
```yaml
name: Update Usage Statistics
on:
schedule:
- cron: '0 0 * * *' # Daily at midnight
workflow_dispatch:
jobs:
update-stats:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Usage Statistics Tracker
uses: your-username/usage-statistics@v1
with:
config: 'production'
json-output-path: 'stats.json'
update-readme: 'true'
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Commit and push changes
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add stats.json README.md
git commit -m "chore: update usage statistics [skip ci]" || echo "No changes to commit"
git push
```
### Advanced Usage with Multiple Outputs
```yaml
- name: Usage Statistics Tracker
uses: your-username/usage-statistics@v1
with:
config: 'production'
json-output-path: 'data/stats.json'
csv-output-path: 'data/stats.csv'
report-output-path: 'docs/usage-report.md'
update-readme: 'true'
readme-path: 'README.md'
github-token: ${{ secrets.GITHUB_TOKEN }}
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
commit-message: 'feat: update usage statistics with detailed report'
```
### Preview Mode for Testing
```yaml
- name: Test Usage Statistics
uses: your-username/usage-statistics@v1
with:
preview-mode: 'true'
json-output-path: 'test-stats.json'
csv-output-path: 'test-stats.csv'
report-output-path: 'test-report.md'
update-readme: 'false'
```
### Using Outputs in Subsequent Steps
```yaml
- name: Usage Statistics Tracker
id: stats
uses: your-username/usage-statistics@v1
with:
config: 'production'
json-output-path: 'stats.json'
- name: Use Statistics Data
run: |
echo "Total downloads: ${{ steps.stats.outputs.total-downloads }}"
echo "Unique packages: ${{ steps.stats.outputs.unique-packages }}"
echo "Platforms: ${{ steps.stats.outputs.platforms-tracked }}"
echo "JSON file: ${{ steps.stats.outputs.json-output }}"
```
## 📊 README Integration
To enable automatic README updates, add these markers to your README.md:
```markdown
<!-- USAGE_STATS_START -->
## 📊 Usage Statistics
Last updated: 2025-07-29T18:53:52.619Z
### Summary
- **Total Downloads**: 414,533
- **Unique Packages**: 8
- **Platforms Tracked**: npm, pypi, homebrew, go
### Top Packages
1. **node** (homebrew) - 226,882 downloads
2. **git** (homebrew) - 153,281 downloads
3. **axios** (npm) - 18,397 downloads
4. **lodash** (npm) - 15,914 downloads
5. **github.com/go-chi/chi** (go) - 33 downloads
### Recent Activity
- **node** (homebrew) - 226,882 downloads on 7/29/2025
- **git** (homebrew) - 153,281 downloads on 7/29/2025
- **axios** (npm) - 722 downloads on 7/29/2025
- **lodash** (npm) - 857 downloads on 7/29/2025
- **axios** (npm) - 936 downloads on 7/28/2025
<!-- USAGE_STATS_END -->
```
## 🔧 Development
### Prerequisites
- [Bun](https://bun.sh/) (version 1.0.0 or higher)
### Local Development
```bash
# Run all tests
# Install dependencies
bun install
# Run in development mode
bun dev
# Run tests
bun test
# Run tests in watch mode
bun test --watch
# Build the action
bun run action:build
# Test the action locally
bun run action:test
```
## Project Structure
### Project Structure
```
usage-statistics/
├── src/
│ ├── index.ts # Main entry point
│ ├── index.test.ts # Test suite
── test-setup.ts # Test configuration
│ ├── index.ts # Main library entry point
│ ├── action.ts # GitHub Action entry point
── config.ts # Configuration management
│ ├── aggregator.ts # Statistics aggregation
│ ├── types/ # TypeScript type definitions
│ ├── trackers/ # Platform-specific trackers
│ └── utils/ # Utility functions
├── .github/
│ └── workflows/ # GitHub Actions workflows
├── action.yml # Action metadata
├── package.json # Project configuration
├── tsconfig.json # TypeScript configuration
├── bunfig.toml # Bun configuration
├── .gitignore # Git ignore rules
└── README.md # This file
```
## API Reference
## 🚀 Publishing to GitHub Marketplace
### UsageStatistics Class
### 1. Prepare Your Repository
The main class for tracking and analyzing usage data.
#### Methods
- `addUsage(userId: string, action: string, metadata?: Record<string, any>)`: Add a new usage record
- `getAllData()`: Get all usage data
- `getUserData(userId: string)`: Get usage data for a specific user
- `getActionData(action: string)`: Get usage data for a specific action
- `getStatistics()`: Get comprehensive statistics summary
#### Example Usage
```typescript
import { UsageStatistics } from './src/index';
const stats = new UsageStatistics();
// Add usage data
stats.addUsage("user1", "login", { browser: "chrome" });
stats.addUsage("user2", "logout");
// Get statistics
const summary = stats.getStatistics();
console.log(`Total records: ${summary.totalRecords}`);
1. **Create a release tag**:
```bash
git tag v1.0.0
git push origin v1.0.0
```
## Development
2. **Build the action**:
```bash
bun run action:build
```
### Scripts
3. **Commit the built files**:
```bash
git add dist/
git commit -m "build: add action distribution files"
git push
```
- `bun start`: Run the main script
- `bun run dev`: Run in development mode with file watching
- `bun run build`: Build the project for production
- `bun test`: Run the test suite
### 2. Publish to Marketplace
### Adding Dependencies
1. Go to your repository on GitHub
2. Click on the **Actions** tab
3. Click **Publish this Action to the GitHub Marketplace**
4. Fill in the required information:
- **Action name**: `usage-statistics-tracker`
- **Description**: `Track download statistics across multiple platforms`
- **Category**: `Data` or `Utilities`
- **Icon**: Upload an appropriate icon
- **Color**: Choose a brand color
- **README**: Use the content from this README
### 3. Version Management
For each new version:
```bash
# Add a production dependency
bun add <package-name>
# Update version in package.json
# Build the action
bun run action:build
# Add a development dependency
bun add -d <package-name>
# Create and push a new tag
git tag v1.1.0
git push origin v1.1.0
```
## GitHub Actions Integration
## 📈 Supported Platforms
This project includes a GitHub Actions workflow that automatically updates usage statistics and commits the results to the repository.
- **NPM**: Package download statistics
- **GitHub**: Release download statistics
- **PyPI**: Python package downloads
- **Homebrew**: Formula installation statistics
- **PowerShell**: Module download statistics
- **Postman**: Collection fork/download statistics
- **Go**: Module proxy statistics
### Setup
1. **Enable the workflow**: The workflow file is located at `.github/workflows/update-stats.yml`
2. **Configure your packages**: Update `src/config.ts` with your actual package names
3. **Set up environment variables** (if needed):
- `GITHUB_TOKEN`: Automatically provided by GitHub Actions
- `POSTMAN_API_KEY`: If tracking Postman collections
### Workflow Features
- **Scheduled runs**: Updates stats daily at 2 AM UTC
- **Manual triggering**: Can be run manually via GitHub Actions UI
- **Rate limiting**: Built-in rate limiting to avoid API abuse
- **Auto-commit**: Automatically commits `stats.json` and updates README
- **Error handling**: Graceful handling of API failures
### Customization
Edit `src/config.ts` to track your specific packages:
```typescript
export const defaultConfig: TrackingConfig = {
npmPackages: ['your-package-name'],
githubRepos: ['your-org/your-repo'],
// ... other platforms
};
```
### Manual Execution
Run locally with GitHub Action mode:
```bash
GITHUB_TOKEN=your_token bun run src/index.ts --action
```
## Contributing
## 🤝 Contributing
1. Fork the repository
2. Create a feature branch
@@ -187,6 +326,12 @@ GITHUB_TOKEN=your_token bun run src/index.ts --action
5. Run the test suite
6. Submit a pull request
## License
## 📄 License
This project is open source and available under the [MIT License](LICENSE).
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## 🙏 Acknowledgments
- Built with [Bun](https://bun.sh/) for fast TypeScript execution
- Uses [Octokit](https://github.com/octokit/octokit.js) for GitHub API integration
- Inspired by the need for comprehensive usage analytics across multiple platforms

83
action.yml Normal file
View File

@@ -0,0 +1,83 @@
name: 'Usage Statistics Tracker'
description: 'Track download statistics across multiple platforms (NPM, GitHub, PyPI, Homebrew, PowerShell, Postman, Go)'
author: 'Your Name'
inputs:
# Configuration
config:
description: 'Configuration for tracking (development, production, test, or custom JSON)'
required: false
default: 'production'
# Output paths
json-output-path:
description: 'Path for JSON output file'
required: false
default: 'stats.json'
csv-output-path:
description: 'Path for CSV output file'
required: false
default: ''
report-output-path:
description: 'Path for human-readable report file'
required: false
default: ''
# README update
update-readme:
description: 'Whether to update README.md with statistics'
required: false
default: 'true'
readme-path:
description: 'Path to README file to update'
required: false
default: 'README.md'
# GitHub integration
github-token:
description: 'GitHub token for API access and commits'
required: false
default: '${{ github.token }}'
# Postman integration
postman-api-key:
description: 'Postman API key for collection statistics'
required: false
# Commit settings
commit-message:
description: 'Commit message for changes'
required: false
default: 'chore: update usage statistics [skip ci]'
# Preview mode
preview-mode:
description: 'Run in preview mode with mock data (no external API calls)'
required: false
default: 'false'
outputs:
json-output:
description: 'Path to the generated JSON file'
csv-output:
description: 'Path to the generated CSV file'
report-output:
description: 'Path to the generated report file'
total-downloads:
description: 'Total downloads across all platforms'
unique-packages:
description: 'Number of unique packages tracked'
platforms-tracked:
description: 'Comma-separated list of platforms tracked'
runs:
using: 'node20'
main: 'dist/index.js'

View File

@@ -4,6 +4,7 @@
"": {
"name": "usage-statistics",
"dependencies": {
"@actions/core": "1.11.1",
"@octokit/rest": "22.0.0",
},
"devDependencies": {
@@ -14,6 +15,16 @@
},
},
"packages": {
"@actions/core": ["@actions/core@1.11.1", "", { "dependencies": { "@actions/exec": "^1.1.1", "@actions/http-client": "^2.0.1" } }, "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A=="],
"@actions/exec": ["@actions/exec@1.1.1", "", { "dependencies": { "@actions/io": "^1.0.1" } }, "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w=="],
"@actions/http-client": ["@actions/http-client@2.2.3", "", { "dependencies": { "tunnel": "^0.0.6", "undici": "^5.25.4" } }, "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA=="],
"@actions/io": ["@actions/io@1.1.3", "", {}, "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q=="],
"@fastify/busboy": ["@fastify/busboy@2.1.1", "", {}, "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA=="],
"@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="],
"@octokit/core": ["@octokit/core@7.0.3", "", { "dependencies": { "@octokit/auth-token": "^6.0.0", "@octokit/graphql": "^9.0.1", "@octokit/request": "^10.0.2", "@octokit/request-error": "^7.0.0", "@octokit/types": "^14.0.0", "before-after-hook": "^4.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-oNXsh2ywth5aowwIa7RKtawnkdH6LgU1ztfP9AIUCQCvzysB+WeU8o2kyyosDPwBZutPpjZDKPQGIzzrfTWweQ=="],
@@ -50,8 +61,12 @@
"fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="],
"tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="],
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
"undici": ["undici@5.29.0", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg=="],
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
"universal-user-agent": ["universal-user-agent@7.0.3", "", {}, "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A=="],

33
examples/basic-usage.yml Normal file
View File

@@ -0,0 +1,33 @@
name: Update Usage Statistics
on:
schedule:
- cron: '0 0 * * *' # Daily at midnight
workflow_dispatch: # Allow manual triggering
jobs:
update-stats:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Usage Statistics Tracker
uses: your-username/usage-statistics@v1
with:
config: 'production'
json-output-path: 'stats.json'
csv-output-path: 'stats.csv'
report-output-path: 'docs/usage-report.md'
update-readme: 'true'
readme-path: 'README.md'
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Commit and push changes
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add stats.json stats.csv docs/usage-report.md README.md
git commit -m "chore: update usage statistics [skip ci]" || echo "No changes to commit"
git push

View File

@@ -8,7 +8,9 @@
"preview": "bun run src/index.ts --preview",
"dev": "bun --watch src/index.ts",
"build": "bun build src/index.ts --outdir dist",
"test": "bun test"
"test": "bun test",
"action:build": "bun build src/action.ts --outdir dist --target node --minify",
"action:test": "bun test && bun run action:build"
},
"devDependencies": {
"@types/node": "^20.0.0",
@@ -16,6 +18,7 @@
"typescript": "^5.0.0"
},
"dependencies": {
"@actions/core": "1.11.1",
"@octokit/rest": "22.0.0"
},
"engines": {

196
src/action.ts Normal file
View File

@@ -0,0 +1,196 @@
#!/usr/bin/env bun
import * as core from '@actions/core';
import * as fs from 'fs/promises';
import * as path from 'path';
import { UsageStatisticsManager } from './index';
import { getConfig, validateConfig } from './config';
async function run() {
try {
// Get inputs
const configInput = core.getInput('config');
const jsonOutputPath = core.getInput('json-output-path');
const csvOutputPath = core.getInput('csv-output-path');
const reportOutputPath = core.getInput('report-output-path');
const updateReadme = core.getInput('update-readme') === 'true';
const readmePath = core.getInput('readme-path');
const githubToken = core.getInput('github-token');
const postmanApiKey = core.getInput('postman-api-key');
const commitMessage = core.getInput('commit-message');
const previewMode = core.getInput('preview-mode') === 'true';
// Set environment variables
if (githubToken) {
process.env.GITHUB_TOKEN = githubToken;
}
if (postmanApiKey) {
process.env.POSTMAN_API_KEY = postmanApiKey;
}
// Get configuration
let trackingConfig;
if (configInput === 'development' || configInput === 'production' || configInput === 'test') {
trackingConfig = getConfig(configInput as 'development' | 'production' | 'test');
} else {
// Try to parse as JSON
try {
trackingConfig = JSON.parse(configInput);
} catch (error) {
core.setFailed(`Invalid config input: ${configInput}. Must be 'development', 'production', 'test', or valid JSON.`);
return;
}
}
// Validate configuration
try {
validateConfig(trackingConfig);
} catch (error) {
core.setFailed(`Configuration validation failed: ${error}`);
return;
}
// Create manager
const manager = new UsageStatisticsManager(trackingConfig);
// Generate report
let report;
if (previewMode) {
core.info('🎭 Running in preview mode with mock data...');
report = await manager.generatePreviewReport();
} else {
core.info('📊 Generating comprehensive usage statistics report...');
report = await manager.generateComprehensiveReport();
}
// Display report
await manager.displayReport(report);
// Write JSON output
if (jsonOutputPath) {
const jsonContent = JSON.stringify(report, null, 2);
await fs.writeFile(jsonOutputPath, jsonContent);
core.info(`📄 JSON report written to ${jsonOutputPath}`);
core.setOutput('json-output', jsonOutputPath);
}
// Write CSV output
if (csvOutputPath) {
const csvReport = await manager.exportReport('csv');
await fs.writeFile(csvOutputPath, csvReport);
core.info(`📊 CSV report written to ${csvOutputPath}`);
core.setOutput('csv-output', csvOutputPath);
}
// Write human-readable report
if (reportOutputPath) {
const reportContent = await generateHumanReadableReport(report);
await fs.writeFile(reportOutputPath, reportContent);
core.info(`📋 Human-readable report written to ${reportOutputPath}`);
core.setOutput('report-output', reportOutputPath);
}
// Update README if requested
if (updateReadme && readmePath) {
try {
await updateReadmeWithStats(report, readmePath);
core.info(`📝 README updated at ${readmePath}`);
} catch (error) {
core.warning(`Failed to update README: ${error}`);
}
}
// Set outputs
core.setOutput('total-downloads', report.totalDownloads.toString());
core.setOutput('unique-packages', report.uniquePackages.toString());
core.setOutput('platforms-tracked', report.platforms.join(','));
core.info('✅ Usage Statistics Tracker completed successfully!');
} catch (error) {
core.setFailed(`Action failed: ${error}`);
}
}
async function generateHumanReadableReport(report: any): Promise<string> {
let content = '# Usage Statistics Report\n\n';
content += `Generated on: ${new Date().toISOString()}\n\n`;
// Summary
content += '## Summary\n\n';
content += `- **Total Downloads**: ${report.totalDownloads.toLocaleString()}\n`;
content += `- **Unique Packages**: ${report.uniquePackages}\n`;
content += `- **Platforms Tracked**: ${report.platforms.join(', ')}\n\n`;
// Platform Breakdown
content += '## Platform Breakdown\n\n';
for (const [platform, data] of Object.entries(report.platformBreakdown)) {
content += `### ${platform.toUpperCase()}\n`;
content += `- Downloads: ${data.totalDownloads.toLocaleString()}\n`;
content += `- Packages: ${data.uniquePackages}\n`;
content += `- Package List: ${data.packages.join(', ')}\n\n`;
}
// Top Packages
content += '## Top Packages\n\n';
report.topPackages.slice(0, 10).forEach((pkg: any, index: number) => {
content += `${index + 1}. **${pkg.name}** (${pkg.platform}) - ${pkg.downloads.toLocaleString()} downloads\n`;
});
content += '\n';
// Recent Activity
content += '## Recent Activity\n\n';
report.recentActivity.slice(0, 5).forEach((activity: any) => {
content += `- **${activity.packageName}** (${activity.platform}) - ${activity.downloads.toLocaleString()} downloads on ${activity.timestamp.toLocaleDateString()}\n`;
});
return content;
}
async function updateReadmeWithStats(report: any, readmePath: string) {
const STATS_MARKER_START = '<!-- USAGE_STATS_START -->';
const STATS_MARKER_END = '<!-- USAGE_STATS_END -->';
try {
const readmeContent = await fs.readFile(readmePath, 'utf-8');
const statsSection = `
## 📊 Usage Statistics
Last updated: ${new Date().toISOString()}
### Summary
- **Total Downloads**: ${report.totalDownloads.toLocaleString()}
- **Unique Packages**: ${report.uniquePackages}
- **Platforms Tracked**: ${report.platforms.join(', ')}
### Top Packages
${report.topPackages.slice(0, 10).map((pkg: any, index: number) =>
`${index + 1}. **${pkg.name}** (${pkg.platform}) - ${pkg.downloads.toLocaleString()} downloads`
).join('\n')}
### Recent Activity
${report.recentActivity.slice(0, 5).map((activity: any) =>
`- **${activity.packageName}** (${activity.platform}) - ${activity.downloads.toLocaleString()} downloads on ${activity.timestamp.toLocaleDateString()}`
).join('\n')}
`;
const startMarker = readmeContent.indexOf(STATS_MARKER_START);
const endMarker = readmeContent.indexOf(STATS_MARKER_END);
if (startMarker !== -1 && endMarker !== -1) {
const beforeStats = readmeContent.substring(0, startMarker + STATS_MARKER_START.length);
const afterStats = readmeContent.substring(endMarker);
const updatedContent = beforeStats + statsSection + afterStats;
await fs.writeFile(readmePath, updatedContent);
} else {
core.warning(`Stats markers not found in README. Please add ${STATS_MARKER_START} and ${STATS_MARKER_END} markers.`);
}
} catch (error) {
throw new Error(`Failed to update README: ${error}`);
}
}
// Run the action
if (import.meta.main) {
run();
}