Skip to content
SpecterShellPublic

About

Dump remote resources and lint outdated packages

Resources

Stars

59 stars

Watchers

4 watching

Forks

Repository files navigation

Dumplings

Dumplings monitors Windows package releases and submits updated manifests to microsoft/winget-pkgs. Its PowerShell runner manages thousands of package tasks, with static installer analysis, manifest validation, and notifications.

Features

  • Runs selected or all package tasks with explicit dependency ordering and configurable concurrency.
  • Compares releases with persisted task state and distinguishes new, changed, updated, and rollback states.
  • Detects and statically analyzes many Windows installer and bootstrapper formats.
  • Reads, updates, formats, and validates multi-file WinGet manifests without invoking winget validate.
  • Writes task state, sends queued Telegram or Matrix notifications, and submits guarded pull requests.
  • Publishes a task status dashboard to GitHub Pages after each Automation workflow run.
  • Keeps GPL installer implementations behind a JSON child-process boundary from the Apache-2.0 PackageModule.

Architecture

flowchart LR
    Core["Core runner"] --> Tasks["Tasks/*"]
    Core --> Package["PackageModule (Apache-2.0)"]
    Tasks --> Package
    Package -->|"JSON child process"| Parsers["InstallerParsers (GPL-2.0/GPL-3.0)"]
    Package --> Output["State, manifests, and messages"]
    Package --> Winget["winget-pkgs pull requests"]
Loading
Path Responsibility
Core Task discovery, dependency planning, worker coordination, hooks, timeouts, and synchronization.
Modules/PackageModule Package task model, release helpers, installer analysis, WinGet manifest processing, messaging, and submission.
Modules/InstallerParsers Process-isolated static parsers for formats whose implementations use GPL-compatible licenses.
Tasks One directory per automation task, containing Config.yaml, Script.ps1, and persisted state.
.agents/skills Workflow documentation for installer analysis and WinGet manifest authoring.
Utilities Repository maintenance and GitHub Actions support scripts.

Core, PackageModule, and InstallerParsers are Git submodules and are also usable as independently versioned projects.

PackageModule's supported standalone entry point is Modules/PackageModule/PackageModule.psd1. Core uses Modules/PackageModule/Index.ps1 to import that manifest and load task model classes.

Requirements

  • Windows
  • PowerShell 7.4 or later
  • Git with submodule support
  • Network access for release checks and installer downloads
  • GitHub credentials, and optionally a local winget-pkgs checkout, only when submission is enabled

The runner installs missing PowerShell modules declared in Preference.yaml. GitHub Actions caches the pinned versions in PowerShellModules.psd1. The optional browser helper restores the Apache-2.0 Patchright runtime pinned by PlaywrightRuntime.psd1. Its large, version-specific driver payload is cached outside Git.

Getting Started

Clone the repository and all submodules:

git clone --recurse-submodules https://github.com/SpecterShell/Dumplings.git
Set-Location .\Dumplings

If the repository was cloned without submodules:

git submodule update --init --recursive

Run one task without enabling state writes, messages, or submissions:

.\Core\Index.ps1 -Name Adobe.WorkfrontProof

Run several tasks with four workers:

.\Core\Index.ps1 -Name Adobe.WorkfrontProof, Mozilla.Firefox -ThrottleLimit 4

Run every task:

.\Core\Index.ps1

Arguments not owned by Core\Index.ps1 override values from Preference.yaml.

# Re-evaluate a task regardless of its persisted state.
.\Core\Index.ps1 -Name Vendor.Package -Force

# Persist State.yaml and a timestamped log after a detected change.
.\Core\Index.ps1 -Name Vendor.Package -EnableWrite

# Exercise manifest generation and submission logic without opening a PR.
.\Core\Index.ps1 -Name Vendor.Package -Force -EnableSubmit -Dry

# Preserve existing installer metadata while still downloading, hashing, validating, and submitting manifests.
.\Core\Index.ps1 -Name Vendor.Package -Force -EnableSubmit -Dry -SkipInstallerAnalysis

-EnableMessage and non-dry -EnableSubmit perform external side effects. Enable them only after configuring their credentials and reviewing the selected tasks. -SkipInstallerAnalysis is a global preference override. A task can opt out with SkipInstallerAnalysis: true in its Config.yaml. Both settings skip static analysis while retaining installer hashing and manifest validation.

Configuration

Preference.yaml contains non-secret runner and module defaults. Command-line overrides have higher priority.

Secrets are loaded in this order:

  1. YAML from the DUMPLINGS_SECRET environment variable.
  2. Values from the ignored local Secret.yaml file, which override matching environment values.

The runner also reads an ignored .env file without replacing environment variables that already exist. Never commit .env, Secret.yaml, tokens, cookies, or installer credentials.

Common environment variables include:

Variable Purpose
GH_DUMPLINGS_TOKEN, GITHUB_TOKEN GitHub API, repository, and submission authentication.
TG_BOT_TOKEN, TG_CHAT_ID Optional Telegram notifications.
MT_BOT_TOKEN, MT_ROOM_ID Optional Matrix notifications.
DUMPLINGS_SECRET Additional task-specific secrets encoded as YAML.

Task Layout

A task directory is selected only when it contains Config.yaml. A typical package task starts with:

Type: PackageTask
WinGetIdentifier: Vendor.Package
Skip: false

Script.ps1 populates $this.CurrentState, calls $this.Check(), and conditionally uses $this.Print(), $this.Write(), $this.Message(), and $this.Submit(). State.yaml points to the most recent timestamped state log and is read on the next run.

Dependencies must be explicit:

DependsOn:
- '#Vendor'

Tasks whose names begin with # commonly populate $Global:DumplingsStorage for dependent package tasks. Core validates declared dependencies, orders them deterministically, and blocks dependents whose providers fail.

Use tasks from the same publisher as references and verify their current behavior.

Authoring Documentation

  • analyze-winget-installer covers static installer detection, parser routing, Apps & Features evidence, and isolated VM validation.
  • author-winget-manifest covers official source discovery, manifest fields, localization, automation, validation, and submission.
  • author-dumplings-task covers task creation, state comparison, source/feed patterns, manifest-update projection, shared providers, and dry-run validation.
  • use-dumplings-functions covers shared networking, temporary-file, archive, content, feed, browser, HTML, and YAML helper APIs.

Testing

Run the component suites from the repository root:

Invoke-Pester .\Core\Tests
Invoke-Pester .\Modules\PackageModule\Tests
Invoke-Pester .\Modules\InstallerParsers\Tests

Run ScriptAnalyzer on a changed module when available:

Invoke-ScriptAnalyzer .\Modules\PackageModule\Libraries\Example.psm1

Downloaded fixtures are cached under ../Dumplings-TestFixtures/Installers/<Family>/<PackageIdentifier>/<Version>. Curated builder media and source trees live under Builders and Sources. Keep synthetic fixtures and extraction output in Pester's $TestDrive. Tests must not execute installers.

Offline and Performance Checks

The offline regression workflow tests Core, PackageModule, and InstallerParsers in separate jobs with pinned module caches. It does not run package tasks, submit manifests, send messages, or download installer fixtures. Run it locally with ./Utilities/Testing/Invoke-Regression.ps1 -Component PackageModule -Offline, selecting other components by name as needed.

Use Core's -MeasurePerformance switch for sanitized per-run stage measurements. The isolated benchmark and AST task-inventory tools are documented in Utilities/Testing, including measured startup costs and the ready scheduler's dependency-heavy results. These switches do not enable state writes or submission.

License

The root project remains licensed under the MIT License. Core and PackageModule use the Apache License 2.0 and Apache License 2.0, respectively. PackageModule contains documented file-level MIT and third-party exceptions. InstallerParsers has file-specific GPL licensing described in its README.

About

Dump remote resources and lint outdated packages

Resources

Stars

59 stars

Watchers

4 watching

Forks

Used by

Contributors

Languages