├── .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 |

Logo WinGet Updater (GitHub Action)

2 | 3 | [![GitHub release (latest by date)](https://img.shields.io/github/v/release/michidk/winget-updater?logo=github)](https://github.com/michidk/winget-updater/releases) 4 | [![GitHub](https://img.shields.io/github/license/michidk/winget-updater)](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 Komac logo

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 | } --------------------------------------------------------------------------------