From b96f407840928c55798f7adaff8c9e83ed9cb178 Mon Sep 17 00:00:00 2001 From: twibster Date: Wed, 15 Apr 2026 23:00:24 +0200 Subject: [PATCH 1/3] Add winget auto-submission workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New workflow fires on release:released (plus a workflow_dispatch retry lane) and uses vedantmgoyal9/winget-releaser@v2 to submit each release to microsoft/winget-pkgs as twibster.ScreenSound. installers-regex filters to the Inno Setup exe so the portable zip isn't submitted as an installer (which would fail validation). Requires a classic PAT with public_repo scope as WINGET_TOKEN — the default GITHUB_TOKEN can't push to the personal fork of winget-pkgs or open a PR upstream. Setup prerequisites (fork winget-pkgs, create PAT, add secret) are documented in the workflow header and the PR body. First auto-submission fires on whatever release cuts after this lands on main. Past releases aren't backfilled automatically; the dispatch input can target any prior tag if that changes. --- .github/workflows/winget.yml | 69 ++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 .github/workflows/winget.yml diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml new file mode 100644 index 0000000..3d56e75 --- /dev/null +++ b/.github/workflows/winget.yml @@ -0,0 +1,69 @@ +name: Publish to Winget + +# Submits each new ScreenSound release to the Windows Package Manager +# Community Repository (microsoft/winget-pkgs) as `twibster.ScreenSound`. +# Once the first submission is merged upstream by Microsoft's reviewers, +# users can install with: +# +# winget install twibster.ScreenSound +# +# Trigger: `release: released` fires once, when release.yml publishes a +# non-draft, non-prerelease GitHub Release. softprops/action-gh-release +# in release.yml sets both flags to false, so every cut release kicks +# this flow. Workflow_dispatch is additionally provided as an operational +# retry lane — if the upstream PR needs to be re-opened (e.g. after the +# PAT rotates or reviewers request changes), a maintainer can rerun +# against any past tag without re-cutting the release. +# +# Required one-time setup (see README of the feat/winget-release PR): +# 1. Fork microsoft/winget-pkgs to the twibster account. +# 2. Create a classic PAT with `public_repo` scope. +# 3. Add the PAT as repo secret `WINGET_TOKEN`. +# +# Why a classic PAT instead of GITHUB_TOKEN: GITHUB_TOKEN is scoped to +# this repo, so it can't push manifest commits to twibster/winget-pkgs +# (our fork) nor open a PR targeting microsoft/winget-pkgs. The action +# needs a token tied to a user account with write access to both. A +# fine-grained PAT works too but requires explicitly granting access to +# the fork and to contents/pull-requests scopes; classic with public_repo +# is the documented, low-friction path. + +on: + release: + types: [released] + workflow_dispatch: + inputs: + tag: + description: 'Release tag to submit (e.g. v2.1.0). Leave blank to submit the latest release.' + required: false + default: '' + +permissions: + contents: read + +jobs: + publish: + name: Submit to winget-pkgs + runs-on: ubuntu-latest + steps: + - name: Submit manifests to winget-pkgs + uses: vedantmgoyal9/winget-releaser@v2 + with: + # PackageIdentifier follows the . convention. + # Must match the casing winget expects — it's case-sensitive in the + # repo's folder structure (manifests/t/twibster/ScreenSound/…). + identifier: twibster.ScreenSound + + # Installer-only filter: our releases include both a setup .exe and + # a portable .zip; winget only installs the Inno Setup executable, + # and submitting the zip as an installer would fail validation. + installers-regex: '^ScreenSound-Setup-.*\.exe$' + + # Empty string = "use the release that triggered this workflow" + # (the action's default). On workflow_dispatch runs, the input is + # passed through so the maintainer can target any past tag. + release-tag: ${{ inputs.tag }} + + # Token must be a PAT with `public_repo` scope (not GITHUB_TOKEN). + # See the file header for the why and the one-time setup steps. + token: ${{ secrets.WINGET_TOKEN }} From a5d278e2153cb97b87d63ef7496528e8a907f54f Mon Sep 17 00:00:00 2001 From: twibster Date: Wed, 15 Apr 2026 23:19:24 +0200 Subject: [PATCH 2/3] Pin winget-releaser action to commit SHA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The upstream @v2 major tag tracks the main branch and moves on every merge into it (v2 release published 2025-01-27, last moved to 4ffc788 on 2026-03-15). Referencing the mutable tag means upstream changes silently land in our pipeline whenever this workflow runs — a supply-chain integrity gap flagged in CodeRabbit review on #11. Pinning to the current SHA freezes that. Upgrade path and the exact commands to re-resolve the SHA are documented inline; a follow-up Dependabot config (github-actions ecosystem) would make this arrive as reviewable PRs instead of manual bumps. --- .github/workflows/winget.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml index 3d56e75..b007471 100644 --- a/.github/workflows/winget.yml +++ b/.github/workflows/winget.yml @@ -47,7 +47,18 @@ jobs: runs-on: ubuntu-latest steps: - name: Submit manifests to winget-pkgs - uses: vedantmgoyal9/winget-releaser@v2 + # Pinned to a commit SHA rather than the @v2 major tag for supply-chain + # hardening — the upstream v2 tag tracks main and moves on every merge, + # so referencing @v2 would silently pull in whatever's latest whenever + # this workflow runs. The pinned SHA is v2 as of 2026-04-15 (release + # "v2", published 2025-01-27, last moved to this commit 2026-03-15). + # + # To bump: check https://github.com/vedantmgoyal9/winget-releaser/releases, + # review the changelog since this SHA, then run: + # gh api repos/vedantmgoyal9/winget-releaser/git/refs/tags/v2 --jq '.object.sha' + # and replace the SHA below. Consider adding .github/dependabot.yml with + # the `github-actions` ecosystem so these bumps arrive as PRs instead. + uses: vedantmgoyal9/winget-releaser@4ffc7888bffd451b357355dc214d43bb9f23917e with: # PackageIdentifier follows the . convention. # Must match the casing winget expects — it's case-sensitive in the From 220262cf579030787fa32bc3051d751bc28f5988 Mon Sep 17 00:00:00 2001 From: twibster Date: Wed, 15 Apr 2026 23:24:06 +0200 Subject: [PATCH 3/3] Add Dependabot config for github-actions ecosystem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pairs with the SHA-pinned third-party action in winget.yml — without a bump mechanism, pinned SHAs go stale and every security patch requires manual re-resolution of the upstream tag. Weekly cadence (not daily to avoid noise, not monthly to avoid drift). Each auto-bump PR gets the `release:skip` label so the auto-release workflow doesn't cut a version for a CI-only change. Scope is intentionally just github-actions for now; nuget for the csproj package refs is a natural next step on the same pattern. --- .github/dependabot.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..1abc30e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,24 @@ +# Dependabot configuration. +# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file +# +# Pairs with the SHA-pinned third-party actions in .github/workflows/ — we pin +# third-party actions to exact commits for supply-chain integrity, and Dependabot +# surfaces new upstream releases as reviewable PRs so the SHAs stay current +# without manual re-resolution. +# +# Every auto-bump PR carries the `release:skip` label so the auto-release +# workflow (.github/workflows/auto-release.yml) doesn't attempt to cut a +# version for a CI-only change. Mirror the same label convention on any +# future ecosystems added here (e.g. nuget for the .csproj package refs). + +version: 2 +updates: + - package-ecosystem: "github-actions" + # Root "/" tells Dependabot to scan .github/workflows/ automatically — it's + # the only path convention GitHub Actions supports, so no per-workflow + # config is needed. + directory: "/" + schedule: + interval: "weekly" + labels: + - "release:skip"