Skip to content

Commit 8253b13

Browse files
committed
feat: Add WinGet publishing automation via Dagger
Signed-off-by: Snowiee <xenonoxidee@gmail.com>
1 parent 871f86c commit 8253b13

File tree

3 files changed

+187
-0
lines changed

3 files changed

+187
-0
lines changed

.dagger/README.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,73 @@ dagger call publish-image \
7070
--imageTags=v0.1.0,latest
7171
```
7272

73+
### `PublishToWinget(packageId, version, githubToken, installerUrls)`
74+
75+
Automates the submission of Harbor CLI updates to the Windows Package Manager (WinGet) repository. This function uses `wingetcreate` to update the package manifest and automatically submit a pull request to `microsoft/winget-pkgs`.
76+
77+
Before running the command, export your GitHub Personal Access Token (with `public_repo` scope):
78+
79+
```shell
80+
export GITHUB_TOKEN=ghp_yourTokenHere
81+
```
82+
83+
**Basic Usage** (auto-detects installer URLs from GitHub releases):
84+
85+
```bash
86+
dagger call publish-to-winget \
87+
--package-id="GoHarbor.Harbor" \
88+
--version="0.0.11" \
89+
--github-token=env:GITHUB_TOKEN
90+
```
91+
92+
**Advanced Usage** (specify custom installer URLs):
93+
94+
```bash
95+
dagger call publish-to-winget \
96+
--package-id="GoHarbor.Harbor" \
97+
--version="0.0.11" \
98+
--github-token=env:GITHUB_TOKEN \
99+
--installer-urls="https://github.com/goharbor/harbor-cli/releases/download/v0.0.11/harbor-cli_0.0.11_windows_amd64.zip" \
100+
--installer-urls="https://github.com/goharbor/harbor-cli/releases/download/v0.0.11/harbor-cli_0.0.11_windows_arm64.zip"
101+
```
102+
103+
This will:
104+
1. Download the latest `wingetcreate` tool
105+
2. Update the WinGet manifest with the new version and installer URLs
106+
3. Automatically submit a PR to the `microsoft/winget-pkgs` repository
107+
108+
**Requirements:**
109+
- GitHub Personal Access Token with `public_repo` scope
110+
- Valid installer URLs (must be publicly accessible)
111+
- Existing package in the WinGet repository
112+
- **Windows Docker host** or Windows container support (for CI/CD, use `runs-on: windows-latest` in GitHub Actions)
113+
114+
**Note:** This function requires Windows containers because `wingetcreate` is a Windows-only tool. On Linux/macOS hosts, this will fail. In GitHub Actions, ensure your workflow uses a Windows runner.
115+
116+
### `PublishToWingetDryRun(packageId, version, installerUrls)`
117+
118+
Test the WinGet publishing logic without requiring Windows containers. This shows exactly what command would be executed.
119+
120+
```bash
121+
dagger call publish-to-winget-dry-run \
122+
--package-id="GoHarbor.Harbor" \
123+
--version="0.0.11"
124+
```
125+
126+
Output example:
127+
```
128+
📦 WinGet Publishing Dry Run
129+
========================================
130+
Package ID: GoHarbor.Harbor
131+
Version: 0.0.11
132+
Installer URLs:
133+
https://github.com/goharbor/harbor-cli/releases/download/v0.0.11/harbor-cli_0.0.11_windows_amd64.zip
134+
https://github.com/goharbor/harbor-cli/releases/download/v0.0.11/harbor-cli_0.0.11_windows_arm64.zip
135+
136+
Command that would be executed:
137+
wingetcreate.exe update GoHarbor.Harbor --version 0.0.11 --urls "..." --submit --token $env:GITHUB_TOKEN
138+
```
139+
73140
---
74141

75142
## ⚙️ Configuration Constants

.dagger/main.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,3 +477,95 @@ func (m *HarborCli) Sign(ctx context.Context,
477477
"--timeout", "1m",
478478
}).Stdout(ctx)
479479
}
480+
481+
// PublishToWingetDryRun shows what commands would be executed for WinGet publishing
482+
// This is useful for testing and validation without requiring Windows containers
483+
func (m *HarborCli) PublishToWingetDryRun(
484+
ctx context.Context,
485+
packageId string,
486+
version string,
487+
// +optional
488+
// URL(s) to the installer(s) - multiple URLs can be provided for different architectures
489+
installerUrls []string,
490+
) string {
491+
// Construct installer URLs from GitHub release if not provided
492+
if len(installerUrls) == 0 {
493+
baseUrl := fmt.Sprintf("https://github.com/goharbor/harbor-cli/releases/download/v%s", version)
494+
installerUrls = []string{
495+
fmt.Sprintf("%s/harbor-cli_%s_windows_amd64.zip", baseUrl, version),
496+
fmt.Sprintf("%s/harbor-cli_%s_windows_arm64.zip", baseUrl, version),
497+
}
498+
}
499+
500+
urlsParam := strings.Join(installerUrls, " ")
501+
502+
output := fmt.Sprintf(` WinGet Publishing Dry Run
503+
========================================
504+
Package ID: %s
505+
Version: %s
506+
Installer URLs:
507+
%s
508+
509+
Command that would be executed:
510+
wingetcreate.exe update %s --version %s --urls "%s" --submit --token $env:GITHUB_TOKEN
511+
512+
Note: This is a dry run. To actually publish, use publish-to-winget on a Windows host.
513+
`, packageId, version, strings.Join(installerUrls, "\n"), packageId, version, urlsParam)
514+
515+
return output
516+
}
517+
518+
// PublishToWinget updates the WinGet package manifest and submits a PR to microsoft/winget-pkgs
519+
// This automates the process of keeping the Harbor CLI package up-to-date in the Windows Package Manager
520+
// NOTE: Requires Windows containers - must run on Windows host or GitHub Actions windows-latest runner
521+
func (m *HarborCli) PublishToWinget(
522+
ctx context.Context,
523+
packageId string,
524+
version string,
525+
githubToken *dagger.Secret,
526+
// +optional
527+
// URL(s) to the installer(s) - multiple URLs can be provided for different architectures
528+
// If not provided, will attempt to construct from GitHub release
529+
installerUrls []string,
530+
) (string, error) {
531+
fmt.Println(" Publishing to WinGet...")
532+
533+
// Construct installer URLs from GitHub release if not provided
534+
if len(installerUrls) == 0 {
535+
// Default to common Windows installer patterns
536+
baseUrl := fmt.Sprintf("https://github.com/goharbor/harbor-cli/releases/download/v%s", version)
537+
installerUrls = []string{
538+
fmt.Sprintf("%s/harbor-cli_%s_windows_amd64.zip", baseUrl, version),
539+
fmt.Sprintf("%s/harbor-cli_%s_windows_arm64.zip", baseUrl, version),
540+
}
541+
fmt.Printf("Using default installer URLs: %v\n", installerUrls)
542+
}
543+
544+
urlsParam := strings.Join(installerUrls, " ")
545+
546+
// Use a Windows container with PowerShell to run wingetcreate
547+
container := dag.Container().
548+
From("mcr.microsoft.com/windows/servercore:ltsc2022").
549+
WithSecretVariable("GITHUB_TOKEN", githubToken).
550+
WithExec([]string{
551+
"powershell", "-Command",
552+
"Invoke-WebRequest -Uri https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe",
553+
}).
554+
// Run wingetcreate update with submit flag
555+
WithExec([]string{
556+
"powershell", "-Command",
557+
fmt.Sprintf(
558+
"./wingetcreate.exe update %s --version %s --urls \"%s\" --submit --token $env:GITHUB_TOKEN",
559+
packageId, version, urlsParam,
560+
),
561+
})
562+
563+
output, err := container.Stdout(ctx)
564+
if err != nil {
565+
stderr, _ := container.Stderr(ctx)
566+
return "", fmt.Errorf("failed to publish to WinGet: %v\nStderr: %s", err, stderr)
567+
}
568+
569+
fmt.Printf("WinGet publication completed:\n%s\n", output)
570+
return output, nil
571+
}

.github/workflows/default.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,3 +253,31 @@ jobs:
253253
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
254254
REGISTRY_ADDRESS: ${{ vars.REGISTRY_ADDRESS }}
255255
REGISTRY_USERNAME: ${{ vars.REGISTRY_USERNAME }}
256+
257+
publish-to-winget:
258+
needs:
259+
- publish-release
260+
runs-on: windows-latest
261+
if: github.event_name == 'push' && (startsWith(github.ref, 'refs/tags/'))
262+
steps:
263+
- name: Checkout repo
264+
uses: actions/checkout@v4
265+
with:
266+
fetch-depth: 0
267+
268+
- name: Extract version from tag
269+
id: extract_version
270+
shell: bash
271+
run: |
272+
VERSION=${{ github.ref_name }}
273+
VERSION_WITHOUT_V=${VERSION#v}
274+
echo "version=${VERSION_WITHOUT_V}" >> $GITHUB_OUTPUT
275+
276+
- name: Publish to WinGet
277+
uses: dagger/dagger-for-github@v7
278+
env:
279+
GITHUB_TOKEN: ${{ secrets.WINGET_GITHUB_TOKEN }}
280+
with:
281+
version: "latest"
282+
verb: call
283+
args: "publish-to-winget --package-id=GoHarbor.Harbor --version=${{ steps.extract_version.outputs.version }} --github-token=env:GITHUB_TOKEN"

0 commit comments

Comments
 (0)