Skip to content

Automate Winget manifest submission on release#1263

Merged
spoorcc merged 5 commits into
mainfrom
claude/winget-pypi-publish-automation-j8fg79
Jun 14, 2026
Merged

Automate Winget manifest submission on release#1263
spoorcc merged 5 commits into
mainfrom
claude/winget-pypi-publish-automation-j8fg79

Conversation

@spoorcc

@spoorcc spoorcc commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Add winget-publish.yml workflow that triggers on release: published
(same event as PyPI publish) and uses vedantmgoyal9/winget-releaser
to submit an updated manifest PR to microsoft/winget-pkgs automatically.

The workflow skips the rolling 'latest' tag, uses harden-runner with
egress blocking, and pins all actions to commit SHAs following the
project's existing security pattern. Requires a WINGET_TOKEN secret
(GitHub PAT with public_repo scope) to be set in repository settings.

https://claude.ai/code/session_01Sf3iaNmGSZ7UAhFrXZRYzi

Summary by CodeRabbit

  • New Features

    • Added automated WinGet manifest update/submission to the Windows Package Manager Community Repository when a GitHub release is published (skipping the latest tag).
  • Documentation

    • Updated release/contributing instructions to include required WinGet token environment secret setup.
    • Expanded the supply-chain threat model to cover WinGet publishing and installation, including new threats and security controls.
  • Chores

    • Added an unreleased changelog entry for the WinGet manifest update behavior.

claude added 2 commits June 14, 2026 13:11
Add winget-publish.yml workflow that triggers on release: published
(same event as PyPI publish) and uses vedantmgoyal9/winget-releaser
to submit an updated manifest PR to microsoft/winget-pkgs automatically.

The workflow skips the rolling 'latest' tag, uses harden-runner with
egress blocking, and pins all actions to commit SHAs following the
project's existing security pattern. Requires a WINGET_TOKEN secret
(GitHub PAT with public_repo scope) to be set in repository settings.

https://claude.ai/code/session_01Sf3iaNmGSZ7UAhFrXZRYzi
Add Winget Community Repository (A-09) and WINGET_TOKEN PAT (A-10) as
new assets, with three new dataflows: DF-27 (CI manifest PR submission),
DF-28 (consumer winget install), and DF-29 (MSI download via winget).

New threats:
- DFT-34: Long-lived stored PAT enables persistent publish rights after
  exfiltration (unlike OIDC's short-lived tokens used for PyPI)
- DFT-35: Compromised PAT enables malicious installer URL injection via
  manifest PR (Winget distributes references to binaries, not binaries
  directly, so an attacker can craft a valid-hash PR for a trojanised MSI)

New controls:
- C-041: Winget manifest PRs reviewed by microsoft/winget-pkgs maintainers
- C-042: WINGET_TOKEN scoped to dedicated 'winget' GitHub environment

Regenerated doc/explanation/threat_model_supply_chain.rst from source.

https://claude.ai/code/session_01Sf3iaNmGSZ7UAhFrXZRYzi
@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@spoorcc, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 49 minutes and 15 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 55e7398f-08ba-4db0-a114-a94448791f9e

📥 Commits

Reviewing files that changed from the base of the PR and between 3e6d1eb and 8285261.

📒 Files selected for processing (2)
  • doc/explanation/threat_model_supply_chain.rst
  • security/tm_supply_chain.py

Walkthrough

Adds a GitHub Actions workflow (winget-publish.yml) that automatically submits a WinGet manifest PR to the Windows Package Manager Community Repository on each published release. Extends the supply-chain threat model (Python code, JSON threat data, and RST documentation) to cover the new Winget distribution path, assets (A-09, A-10), dataflows (DF-27–29), threats (DFT-21, DFT-34, DFT-35), and controls (C-041, C-042).

Changes

Winget Publishing and Threat Model

Layer / File(s) Summary
WinGet publish workflow, changelog, and contributing docs
.github/workflows/winget-publish.yml, CHANGELOG.rst, doc/howto/contributing.rst
New workflow triggers on published GitHub releases (excluding latest), hardens the runner with egress restrictions, and invokes vedantmgoyal9/winget-releaser with WINGET_TOKEN to create the WinGet manifest PR. Changelog and contributing docs document the automatic submission and required WINGET_TOKEN secret configuration.
Supply-chain threat model Python code and threat data
security/tm_supply_chain.py, security/threats.json
Introduces _make_sc_winget_elements_and_flows() with a Winget boundary, repository entity, A-10: WINGET_TOKEN PAT datastore, and dataflows DF-27–29. Wires into _make_sc_elements_and_flows, adds controls C-041/C-042, extends _SUPPLY_CHAIN_ASSET_IDS with A-09/A-10, and appends threat responses DFT-34/DFT-35. In threats.json, inserts DFT-34 (stored credential risk) and DFT-35 (malicious installer URL injection via manifest).
Threat model RST documentation
doc/explanation/threat_model_supply_chain.rst
Updates rendered RST to include the Winget boundary in Boundaries table, Winget subgraph and DF-27–29 edges in UML diagrams, new assets A-09/A-10, DF-27–29 dataflow rows, DFT-21/DFT-35 threat rows, and C-041/C-042 control rows. Applies minor table formatting fixes around existing DF-12/DF-13/DF-15b entries.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • dfetch-org/dfetch#1182: Introduces the tm_supply_chain pytm model scaffolding that this PR extends with new Winget boundary, assets, dataflows, threats, and controls.

Suggested labels

github_actions, documentation

Suggested reviewers

  • ben-edna
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Automate Winget manifest submission on release' directly and clearly describes the main change: automating the submission of Winget manifests when releases are published.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/winget-pypi-publish-automation-j8fg79

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@spoorcc

spoorcc commented Jun 14, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/winget-publish.yml:
- Around line 10-16: The publish job in the winget-publish.yml workflow lacks a
concurrency setting, which allows overlapping executions (from re-runs or
concurrent release.published events) to create competing Winget manifest PR
submissions. Add a concurrency configuration to the publish job that uses a
unique identifier based on the release tag (such as
github.event.release.tag_name) to group concurrent executions and automatically
cancel in-progress runs when a new execution is triggered, ensuring only one
submission attempt proceeds at a time.

In `@CHANGELOG.rst`:
- Line 4: In the CHANGELOG.rst file, locate the entry about "Winget manifest is
now submitted automatically to the Windows Package Manager Community Repository"
and replace the `(`#TODO`)` placeholder with the actual GitHub issue or pull
request number reference (e.g., `#123`). This ensures the changelog contains a
valid reference for users to track the related change in your repository
history.

In `@doc/howto/contributing.rst`:
- Around line 380-381: The documentation at lines 380-381 incorrectly describes
WINGET_TOKEN as a repository secret, but it should be scoped as an environment
secret to the winget environment to limit exposure. Update the text to clarify
that WINGET_TOKEN must be configured as an environment secret in the winget
environment settings, not at the repository level, to properly restrict its
access to only the workflows that require it.

In `@security/tm_supply_chain.py`:
- Around line 196-203: The file has formatting drift detected by the black
formatter during pre-commit checks. Run the local code formatter (black) on the
file to resolve the formatting issues and bring the code into compliance with
the project's style guidelines. After running the formatter, commit the updated
file to unblock the merge.
- Around line 613-617: The DF-27 data flow definition currently has network flow
and access control enabled but lacks integrity verification, which
unintentionally satisfies DFT-21's threat condition (VCS-tag threat) and creates
a mismatched threat mapping. Add integrity control verification to the df27
object (specifically set isIntegrity to True or add appropriate integrity
validation) alongside the existing protocol, encryption, hardening, access
control, and network flow settings to prevent the unintended match with DFT-21's
conditions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 445d0ac9-617c-4cd3-9d5b-e25f32e3bc42

📥 Commits

Reviewing files that changed from the base of the PR and between 4800144 and 89e9283.

📒 Files selected for processing (6)
  • .github/workflows/winget-publish.yml
  • CHANGELOG.rst
  • doc/explanation/threat_model_supply_chain.rst
  • doc/howto/contributing.rst
  • security/threats.json
  • security/tm_supply_chain.py

Comment thread .github/workflows/winget-publish.yml
Comment thread CHANGELOG.rst Outdated
Comment thread doc/howto/contributing.rst Outdated
Comment thread security/tm_supply_chain.py
Comment thread security/tm_supply_chain.py
@spoorcc

spoorcc commented Jun 14, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
security/tm_supply_chain.py (1)

232-236: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Align A-10 secret storage scope with the actual workflow configuration.

Line 235 states WINGET_TOKEN is a repository secret, but the workflow and contributor docs scope it to the winget environment secret. This inconsistency weakens the threat model’s control traceability for C-042 and misstates blast radius.

Suggested patch
-            "stored as a GitHub Actions repository secret.  "
+            "stored as a GitHub Actions environment secret in the "
+            "``winget`` deployment environment.  "
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@security/tm_supply_chain.py` around lines 232 - 236, The A-10 secret
documentation for WINGET_TOKEN incorrectly describes the storage scope. The
description currently states the secret is stored as a "GitHub Actions
repository secret," but according to the actual workflow configuration and
contributor docs, it is stored as an environment secret in the winget
environment. Update the description parameter in the A-10 section to accurately
reflect that WINGET_TOKEN is scoped to the winget environment secret rather than
a repository secret, ensuring the threat model accurately documents the control
scope and blast radius for C-042.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@security/tm_supply_chain.py`:
- Around line 232-236: The A-10 secret documentation for WINGET_TOKEN
incorrectly describes the storage scope. The description currently states the
secret is stored as a "GitHub Actions repository secret," but according to the
actual workflow configuration and contributor docs, it is stored as an
environment secret in the winget environment. Update the description parameter
in the A-10 section to accurately reflect that WINGET_TOKEN is scoped to the
winget environment secret rather than a repository secret, ensuring the threat
model accurately documents the control scope and blast radius for C-042.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ccdc4724-b889-4c7b-922d-b80e65f2209f

📥 Commits

Reviewing files that changed from the base of the PR and between 89e9283 and 3e6d1eb.

📒 Files selected for processing (4)
  • .github/workflows/winget-publish.yml
  • CHANGELOG.rst
  • doc/howto/contributing.rst
  • security/tm_supply_chain.py

@spoorcc spoorcc merged commit c5e12fc into main Jun 14, 2026
36 checks passed
@spoorcc spoorcc deleted the claude/winget-pypi-publish-automation-j8fg79 branch June 14, 2026 15:27
@coderabbitai coderabbitai Bot mentioned this pull request Jun 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants