├── .github
├── images
│ ├── github-actions-logo.png
│ ├── komac-logo.svg
│ └── pull-app-logo.svg
├── release.yml
└── workflows
│ ├── pr-stale.yml
│ ├── pr-title.yml
│ └── versioning.yml
├── .vscode
├── extensions.json
└── settings.json
├── LICENSE
├── README.md
├── action.yml
└── renovate.json
/.github/images/github-actions-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michidk/winget-updater/538b7f3ed26142a6220f657e19f17e7ef5f283e6/.github/images/github-actions-logo.png
--------------------------------------------------------------------------------
/.github/images/komac-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
159 |
--------------------------------------------------------------------------------
/.github/images/pull-app-logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/release.yml:
--------------------------------------------------------------------------------
1 | changelog:
2 | exclude:
3 | labels:
4 | - no-release-note
5 | categories:
6 | - title: Enhancements
7 | labels:
8 | - enhancement
9 | - title: Bugfixes
10 | labels:
11 | - bug
12 | - title: Dependency updates
13 | labels:
14 | - "dependencies"
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.github/workflows/pr-stale.yml:
--------------------------------------------------------------------------------
1 | name: Mark stale issues and pull requests
2 |
3 | on:
4 | schedule:
5 | - cron: '0 0 * * *'
6 |
7 | permissions:
8 | pull-requests: write
9 |
10 | jobs:
11 | stale:
12 | runs-on: ubuntu-24.04
13 | permissions:
14 | contents: write
15 | issues: write
16 | pull-requests: write
17 | steps:
18 | - uses: actions/stale@v9
19 | with:
20 | repo-token: ${{ secrets.GITHUB_TOKEN }}
21 | days-before-stale: 30
22 | days-before-close: 14
23 | stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.'
24 | exempt-issue-labels: 'in-progress, no-stale'
25 | exempt-pr-labels: 'in-progress, no-stale'
26 | remove-issue-stale-when-updated: true
27 | remove-stale-when-updated: true
--------------------------------------------------------------------------------
/.github/workflows/pr-title.yml:
--------------------------------------------------------------------------------
1 | name: Check PR title
2 |
3 | on:
4 | pull_request_target:
5 | types:
6 | - opened
7 | - reopened
8 | - edited
9 | - synchronize
10 |
11 | jobs:
12 | lint:
13 | runs-on: ubuntu-24.04
14 | permissions:
15 | statuses: write
16 | steps:
17 | - uses: aslafy-z/conventional-pr-title-action@v3
18 | env:
19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
20 |
--------------------------------------------------------------------------------
/.github/workflows/versioning.yml:
--------------------------------------------------------------------------------
1 | name: Keep the versions up-to-date
2 |
3 | on:
4 | release:
5 | types: [published, edited]
6 |
7 | jobs:
8 | actions-tagger:
9 | runs-on: windows-latest
10 | steps:
11 | - uses: Actions-R-Us/actions-tagger@latest
12 | with:
13 | publish_latest_tag: true
14 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "github.vscode-github-actions",
4 | "streetsidesoftware.code-spell-checker"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "cSpell.words": [
3 | "Komac",
4 | "vedantmgoyal",
5 | "vscli",
6 | "winget",
7 | "pkgs"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Michael Lohr
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
WinGet Updater (GitHub Action)
2 |
3 | [](https://github.com/michidk/winget-updater/releases)
4 | [](https://github.com/michidk/winget-updater?tab=MIT-1-ov-file#readme)
5 |
6 | A GitHub action which automatically updates WinGet packages, based on Komac.
7 |
8 | This project is heavily inspired by [vedantmgoyal2009/winget-releaser](https://github.com/vedantmgoyal2009/winget-releaser).
9 | The main differences are:
10 |
11 | - This action will update your package to the latest release available on GitHub automatically. It does not need to react to an `on: release` event in GitHub actions.
12 | - It is a composite action, which consists of other GitHub actions, which makes it very simple (no big Typescript project).
13 |
14 | ## Getting Started 🚀
15 |
16 | 1. At least **one** version of your package should already be present in the [Windows Package Manager Community Repository](https://github.com/microsoft/winget-pkgs). The action will use that version as a base to create manifests for new versions of the package.
17 |
18 | 2. You will need to create a _classic_ Personal Access Token (PAT) with `public_repo` scope. _New_ fine-grained PATs aren't supported by the action. Review [this issue](https://github.com/vedantmgoyal2009/winget-releaser/issues/172) for information.
19 |
20 | 3. Fork the [winget-pkgs](https://github.com/microsoft/winget-pkgs) repository under the same account/organization as your repository on which you want to use this action. Ensure that the fork is up-to-date with the upstream repository (see [this issue](https://github.com/vedantmgoyal2009/winget-releaser/issues/32) for why this is important). You can do this using one of the following methods:
21 | https://github.com/vedantmgoyal2009/winget-releaser
22 | - Give `workflow` permission to the token you created in Step 1. This will allow the action to automatically update your
23 | fork with the upstream repository.
24 | - You can use **[Pull App](https://github.com/wei/pull)** which keeps your fork up-to-date with the upstream repository via automated pull requests.
25 |
26 | 4. Add the action to your workflow file (e.g. `.github/workflows/.yml`).
27 |
28 | > [!IMPORTANT]
29 | > The action will only work when the release is **published** (not a draft), because the release assets (binaries) aren't available publicly until the release is published.
30 |
31 | > [!NOTE]
32 | > In case you're pinning the action to a commit hash, you'll need to update the hash frequently to get the latest features & bug fixes. Therefore, it is **highly** recommended to setup dependabot auto-updates for your repository. Check out [keeping your actions up to date with Dependabot](https://docs.github.com/en/actions/security-guides/encrypted-secrets#using-encrypted-secrets-in-a-workflow) for guidance on how to do this. (Yes, it also supports updating actions pinned to a commit hash!)
33 |
34 |
35 | ## 📖 Example Usage
36 |
37 | Minimal example:
38 |
39 | ```yaml
40 | name: Update WinGet Packages
41 |
42 | on: workflow_dispatch
43 |
44 | jobs:
45 | update:
46 | name: Update Package
47 | runs-on: ubuntu-latest
48 | steps:
49 | - name: Update Packages
50 | uses: michidk/winget-updater@v1
51 | with:
52 | komac-token: ${{ secrets.KOMAC_TOKEN }}
53 | identifier: "michidk.vscli"
54 | repo: "michidk.vscli"
55 | URL: "https://github.com/michidk/vscli/releases/download/v{VERSION}/vscli-x86_64-pc-windows-msvc.zip"
56 | ```
57 |
58 | Use a matrix to update multiple packages at once. Can also be combined with [Run Komac](https://github.com/michidk/run-komac) to automatically clean up branches after a PR has been merged:
59 |
60 | ```yaml
61 | name: Update WinGet Packages
62 |
63 | on:
64 | workflow_dispatch:
65 | schedule:
66 | - cron: '0 3 * * *' # Scheduled to run daily at 03:00
67 |
68 | jobs:
69 | update:
70 | name: Update package ${{ matrix.id }}
71 | runs-on: ubuntu-22.04
72 |
73 | strategy:
74 | matrix:
75 | include:
76 | - id: "Casey.Just"
77 | repo: "casey/just"
78 | url: "https://github.com/casey/just/releases/download/{VERSION}/just-{VERSION}-x86_64-pc-windows-msvc.zip"
79 | - id: "michidk.vscli"
80 | repo: "michidk/vscli"
81 | url: "https://github.com/michidk/vscli/releases/download/v{VERSION}/vscli-x86_64-pc-windows-msvc.zip"
82 | # Multi URL package entry
83 | - id: "michidk.vscli"
84 | repo: "michidk/vscli"
85 | url: '"https://github.com/michidk/vscli/releases/download/v{VERSION}/vscli-x86_64-pc-windows-msvc.zip https://github.com/michidk/vscli/releases/download/v{VERSION}/vscli-i686-pc-windows-msvc.zip"'
86 |
87 | steps:
88 | - name: Update Packages
89 | uses: michidk/winget-updater@latest
90 | with:
91 | komac-token: ${{ secrets.KOMAC_TOKEN }}
92 | identifier: ${{ matrix.id }}
93 | repo: ${{ matrix.repo }}
94 | url: ${{ matrix.url }}
95 |
96 | cleanup:
97 | name: Cleanup branches
98 | needs: update # Not necessarily needed as PRs don't get closed that quick but still nice to have it in order
99 | runs-on: ubuntu-22.04
100 |
101 | steps:
102 | - name: Run Komac
103 | uses: michidk/run-komac@latest
104 | with:
105 | args: 'cleanup --only-merged --token=${{ secrets.KOMAC_TOKEN }}'
106 | ```
107 |
108 | For a real-world example, have a look at my WinGet package updater repository: [michidk/winget](https://github.com/michidk/winget)
109 |
110 | ## ⚒️ Configuration Options
111 |
112 | - `komac-version`: Specifies which version of Komac to use.
113 | - **Required**: ❌
114 | - **Default**: `2.6.0`
115 | - `komac-token`: The GitHub token to use for authentication. The token should have the `public_repo` scope.
116 | - **Required**: ✅
117 | - ⚠ **WARNING**: Do **not** directly put the token in the action. Instead, create a repository secret containing the token and use that in the workflow. Refer to [using encrypted secrets in a workflow](https://docs.github.com/en/actions/security-guides/encrypted-secrets#using-encrypted-secrets-in-a-workflow) for more information.
118 | - `identifier`: The package identifier of the package to be updated in the [WinGet Community Repository](https://github.com/microsoft/winget-pkgs).
119 | - **Required**: ✅
120 | - **Example**: `michidk.vscli`
121 | - `repo`: The GitHub repository to check for the latest release.
122 | - **Required**: ✅
123 | - **Example**: `michidk/vscli`
124 | - `url`: The URL(s) to the latest release. Use the placeholder `{VERSION}` to specify where the version should be inserted. The placeholder contains the version without `v`, e.g. `1.2.3`. Multiple URLs may be specified by wrapping a space-separated string in single and double quotes as in the second example below.
125 | - **Required**: ✅
126 | - **Example 1**: `https://github.com/michidk/vscli/releases/download/v{VERSION}/vscli-x86_64-pc-windows-msvc.zip`
127 | - **Example 2**: `url: '"https://github.com/michidk/vscli/releases/download/v{VERSION}/vscli-x86_64-pc-windows-msvc.zip https://github.com/michidk/vscli/releases/download/v{VERSION}/vscli-i686-pc-windows-msvc.zip"'`
128 | - `custom-fork-owner`: The owner of the `winget-pkgs` repo fork to use. If not specified, the owner of the repository where the action is used will be used.
129 | - **Required**: ❌
130 | - **Example**: `michidk`
131 |
132 |
🚀 Integrating with
133 |
134 | This GitHub action leverages [Komac](https://github.com/russellbanks/komac) to generate and submit manifests to the [Windows Package Manager Community Repository](https://github.com/microsoft/winget-pkgs). Kudos to [Russell Banks](https://github.com/russellbanks) for developing Komac which powers this action.
135 | Also huge thanks to [vedantmgoyal2009](https://github.com/vedantmgoyal2009) for creating an awesome GitHub action, which this one is heavily inspired from.
136 |
--------------------------------------------------------------------------------
/action.yml:
--------------------------------------------------------------------------------
1 | name: 'WinGet Updater'
2 | description: 'Publish updates of your application to Windows Package Manager automatically.'
3 |
4 | branding:
5 | color: blue
6 | icon: upload-cloud
7 |
8 | inputs:
9 | komac-version:
10 | description: 'Which Komac version to use.'
11 | required: false
12 | default: '2.6.0'
13 | komac-token:
14 | description: 'The GitHub token to use for authentication.'
15 | required: true
16 | identifier:
17 | description: 'The PackageIdentifier of the package (case-sensitive).'
18 | required: true
19 | repo:
20 | description: 'The GitHub repository to check for the latest release.'
21 | required: true
22 | url:
23 | description: 'The URL(s) to the latest release.'
24 | required: true
25 | custom-fork-owner:
26 | description: 'Custom winget-pkgs fork owner'
27 | required: false
28 |
29 | runs:
30 | using: "composite"
31 | steps:
32 | - name: Check if Package Exists in winget-pkgs Repository
33 | uses: actions/github-script@v7
34 | with:
35 | script: |
36 | const pkgid = "${{ inputs.identifier }}";
37 | const url = `https://github.com/microsoft/winget-pkgs/tree/master/manifests/${pkgid.charAt(0).toLowerCase()}/${pkgid.replaceAll('.', '/')}`;
38 | const headers = { method: 'HEAD' };
39 |
40 | const res = await fetch(url, headers);
41 |
42 | if (!res.ok) {
43 | core.setFailed(`Package ${pkgid} does not exist in the winget-pkgs repository. Please add at least one version of the package before using this action.`);
44 | process.exit(1);
45 | }
46 |
47 | - name: Detect Latest Release
48 | id: latest_release
49 | uses: actions/github-script@v7
50 | with:
51 | script: |
52 | const [owner, repo] = '${{ inputs.repo }}'.split('/');
53 | try {
54 | const { data } = await github.rest.repos.getLatestRelease({ owner, repo });
55 | const tagName = data.tag_name.startsWith('v') ? data.tag_name.substring(1) : data.tag_name;
56 | return tagName;
57 | } catch (error) {
58 | core.setFailed(`Failed to get latest release for repo: ${owner}/${repo}`);
59 | process.exit(1);
60 | }
61 |
62 | - name: Compose URL
63 | shell: bash
64 | run: |
65 | VERSION=${{ steps.latest_release.outputs.result }}
66 | URL=${{ inputs.url }}
67 | FINAL_URL=$(echo $URL | sed "s/{VERSION}/$VERSION/g")
68 | echo "FINAL_URL=$FINAL_URL" >> $GITHUB_ENV
69 | echo "Detected latest Version: ${{ steps.latest_release.outputs.result }}"
70 | echo "Final URL: $FINAL_URL"
71 |
72 | - name: Run Komac
73 | uses: michidk/run-komac@v2
74 | continue-on-error: true
75 | with:
76 | komac-version: ${{ inputs.komac-version }}
77 | custom-fork-owner: ${{ inputs.custom-fork-owner }}
78 | custom-tool: WinGet Updater
79 | custom-tool-url: "https://github.com/michidk/winget-updater"
80 | args: update ${{ inputs.identifier }} --version ${{ steps.latest_release.outputs.result }} --urls $FINAL_URL --submit --token ${{ inputs.komac-token }}
81 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:recommended"
5 | ],
6 | "labels": [
7 | "no-stale"
8 | ]
9 | }
--------------------------------------------------------------------------------