Update PSGallery Stats #77
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Update PSGallery Stats | |
| # Runs daily at 06:00 IST (00:30 UTC) — away from the midnight deploy window. | |
| # Also triggerable manually from the Actions tab. | |
| # On commit, deploy.yml auto-triggers (push to main) → site rebuilds with fresh stats. | |
| on: | |
| schedule: | |
| - cron: "30 0 * * *" | |
| workflow_dispatch: | |
| jobs: | |
| update-stats: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout source | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Fetch PSGallery stats and update data/psgallery.yaml | |
| run: | | |
| python3 << 'PYEOF' | |
| import urllib.request | |
| import xml.etree.ElementTree as ET | |
| import datetime | |
| import textwrap | |
| MODULES = [ | |
| { | |
| "name": "VB.WorkstationReport", | |
| "description": "End-to-end workstation auditing — user profiles, printer mappings, folder redirections, OneDrive backup status, and network interfaces.", | |
| }, | |
| { | |
| "name": "VB.NextCloud", | |
| "description": "WebDAV utilities for Nextcloud from PowerShell — single-file upload, batch orchestration with auto folder creation, and directory listing.", | |
| }, | |
| { | |
| "name": "VB.ServerInventory", | |
| "description": "34 cmdlets across 10 categories for comprehensive Windows Server auditing — AD health, GPO, security, DHCP/DNS, RDS, and more.", | |
| }, | |
| { | |
| "name": "VB.AdminTools", | |
| "description": "See PSGallery for details.", | |
| }, | |
| ] | |
| ns = { | |
| "atom": "http://www.w3.org/2005/Atom", | |
| "d": "http://schemas.microsoft.com/ado/2007/08/dataservices", | |
| "m": "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata", | |
| } | |
| total_downloads = 0 | |
| module_lines = [] | |
| for mod in MODULES: | |
| name = mod["name"] | |
| desc = mod["description"] | |
| url = f"https://www.powershellgallery.com/packages/{name}" | |
| api_url = ( | |
| f"https://www.powershellgallery.com/api/v2/FindPackagesById()" | |
| f"?id='{name}'&$orderby=Version%20desc&$top=1&$select=Id,Version,DownloadCount" | |
| ) | |
| version = "" | |
| downloads = 0 | |
| try: | |
| req = urllib.request.Request(api_url, headers={"Accept": "application/atom+xml"}) | |
| with urllib.request.urlopen(req, timeout=30) as resp: | |
| xml_data = resp.read().decode("utf-8") | |
| root = ET.fromstring(xml_data) | |
| entry = root.find("atom:entry", ns) | |
| if entry is not None: | |
| props = entry.find("m:properties", ns) | |
| version = props.findtext("d:Version", default="", namespaces=ns).strip() | |
| dl_raw = props.findtext("d:DownloadCount", default="0", namespaces=ns).strip() | |
| downloads = int(dl_raw) if dl_raw.isdigit() else 0 | |
| print(f" {name}: v{version}, {downloads} downloads") | |
| except Exception as e: | |
| print(f" WARNING: Failed to fetch {name} — {e}") | |
| total_downloads += downloads | |
| module_lines.append(f"- name: {name}") | |
| module_lines.append(f" url: {url}") | |
| module_lines.append(f' description: "{desc}"') | |
| module_lines.append(f" downloads: {downloads}") | |
| module_lines.append(f' version: "{version}"') | |
| module_lines.append("") | |
| today = datetime.date.today().isoformat() | |
| modules_block = "\n".join(module_lines) | |
| yaml_content = ( | |
| "# PSGallery module stats — auto-updated daily by GitHub Actions" | |
| " (.github/workflows/psgallery-stats.yml)\n" | |
| "# Do not edit manually — changes will be overwritten on next scheduled run.\n" | |
| f"# Last updated: {today}\n" | |
| "\n" | |
| "modules:\n" | |
| f"{modules_block}\n" | |
| f"total_downloads: {total_downloads}\n" | |
| f"total_modules: {len(MODULES)}\n" | |
| f'last_updated: "{today}"\n' | |
| ) | |
| with open("data/psgallery.yaml", "w", encoding="utf-8") as f: | |
| f.write(yaml_content) | |
| print(f"Done — {len(MODULES)} modules, {total_downloads} total downloads.") | |
| PYEOF | |
| - name: Commit updated stats (triggers site rebuild via deploy.yml) | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add data/psgallery.yaml | |
| git diff --staged --quiet \ | |
| && echo "No changes — stats unchanged." \ | |
| || (git commit -m "chore: update PSGallery stats [$(date -u +%Y-%m-%d)]" && git push) |