Skip to content

Commit 09a7376

Browse files
committed
Add GitHub Actions CI/CD and WinGet submission workflows
- build.yml: PR validation and reusable build for x64/ARM64 - Matrix strategy with win-x64 and win-arm64 runtime identifiers - .NET 11 Preview SDK setup - Conditional publish and artifact upload when called with version input - Permissions scoped to contents: read - Concurrency group cancels stale PR builds - release.yml: Manual release orchestrator (workflow_dispatch) - Calls build.yml with version input - Creates git tag and GitHub Release with exe binaries - Chains to winget-release.yml for WinGet submission - winget-release.yml: Reusable WinGet package submission - Downloads release exe assets and computes SHA256 hashes - Generates version, locale, and installer manifests - Portable installer type for standalone exe distribution - wingetcreate pinned to v1.10.3.0 with SHA256 verification - Secrets passed explicitly (WINGET_PAT)
1 parent 4d56bbe commit 09a7376

File tree

4 files changed

+253
-1
lines changed

4 files changed

+253
-1
lines changed

.github/workflows/build.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Build
2+
3+
on:
4+
pull_request:
5+
branches: ["*"]
6+
workflow_call:
7+
inputs:
8+
version:
9+
description: "Version string (e.g. 0.1.0)"
10+
required: false
11+
type: string
12+
13+
permissions:
14+
contents: read
15+
16+
concurrency:
17+
group: build-${{ github.head_ref || github.run_id }}
18+
cancel-in-progress: true
19+
20+
jobs:
21+
build:
22+
runs-on: windows-latest
23+
strategy:
24+
matrix:
25+
platform: [x64, ARM64]
26+
include:
27+
- platform: x64
28+
rid: win-x64
29+
- platform: ARM64
30+
rid: win-arm64
31+
32+
steps:
33+
- uses: actions/checkout@v4
34+
35+
- name: Setup .NET 11 Preview
36+
uses: actions/setup-dotnet@v4
37+
with:
38+
dotnet-version: "11.0.x"
39+
dotnet-quality: "preview"
40+
41+
- name: Restore dependencies
42+
run: dotnet restore CopilotTaskbarApp/CopilotTaskbarApp.csproj -r ${{ matrix.rid }} -p:Platform=${{ matrix.platform }}
43+
44+
- name: Build
45+
run: dotnet build CopilotTaskbarApp/CopilotTaskbarApp.csproj -c Release -r ${{ matrix.rid }} -p:Platform=${{ matrix.platform }} --no-restore
46+
47+
- name: Publish
48+
if: inputs.version != ''
49+
run: dotnet publish CopilotTaskbarApp/CopilotTaskbarApp.csproj -c Release -r ${{ matrix.rid }} -p:Platform=${{ matrix.platform }} --no-restore -o publish/${{ matrix.rid }}
50+
51+
- name: Upload artifact
52+
if: inputs.version != ''
53+
uses: actions/upload-artifact@v4
54+
with:
55+
name: CopilotTaskbarApp-${{ inputs.version }}-${{ matrix.rid }}
56+
path: publish/${{ matrix.rid }}/CopilotTaskbarApp.exe

.github/workflows/release.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
name: Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: "Release version (e.g. 0.1.0)"
8+
required: true
9+
type: string
10+
11+
permissions:
12+
contents: write
13+
14+
jobs:
15+
build:
16+
uses: ./.github/workflows/build.yml
17+
with:
18+
version: ${{ inputs.version }}
19+
20+
release:
21+
needs: build
22+
runs-on: ubuntu-latest
23+
steps:
24+
- uses: actions/checkout@v4
25+
with:
26+
fetch-depth: 0
27+
28+
- name: Download x64 artifact
29+
uses: actions/download-artifact@v4
30+
with:
31+
name: CopilotTaskbarApp-${{ inputs.version }}-win-x64
32+
path: artifacts/x64
33+
34+
- name: Download arm64 artifact
35+
uses: actions/download-artifact@v4
36+
with:
37+
name: CopilotTaskbarApp-${{ inputs.version }}-win-arm64
38+
path: artifacts/arm64
39+
40+
- name: Rename artifacts
41+
run: |
42+
mv artifacts/x64/CopilotTaskbarApp.exe artifacts/CopilotTaskbarApp-${{ inputs.version }}-win-x64.exe
43+
mv artifacts/arm64/CopilotTaskbarApp.exe artifacts/CopilotTaskbarApp-${{ inputs.version }}-win-arm64.exe
44+
45+
- name: Create tag
46+
run: |
47+
git config user.name "github-actions[bot]"
48+
git config user.email "github-actions[bot]@users.noreply.github.com"
49+
git tag -a "v${{ inputs.version }}" -m "Release v${{ inputs.version }}"
50+
git push origin "v${{ inputs.version }}"
51+
52+
- name: Create GitHub Release
53+
uses: softprops/action-gh-release@v2
54+
with:
55+
tag_name: v${{ inputs.version }}
56+
name: v${{ inputs.version }}
57+
generate_release_notes: true
58+
files: |
59+
artifacts/CopilotTaskbarApp-${{ inputs.version }}-win-x64.exe
60+
artifacts/CopilotTaskbarApp-${{ inputs.version }}-win-arm64.exe
61+
62+
winget:
63+
needs: release
64+
uses: ./.github/workflows/winget-release.yml
65+
with:
66+
tag: v${{ inputs.version }}
67+
version: ${{ inputs.version }}
68+
secrets:
69+
WINGET_PAT: ${{ secrets.WINGET_PAT }}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
name: Publish to WinGet
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
tag:
7+
description: "Release tag (e.g. v0.1.0)"
8+
required: true
9+
type: string
10+
version:
11+
description: "Version string without v prefix (e.g. 0.1.0)"
12+
required: true
13+
type: string
14+
secrets:
15+
WINGET_PAT:
16+
required: true
17+
18+
jobs:
19+
publish:
20+
runs-on: windows-latest
21+
steps:
22+
- name: Resolve version
23+
id: version
24+
shell: pwsh
25+
run: |
26+
"version=${{ inputs.version }}" >> $env:GITHUB_OUTPUT
27+
"tag=${{ inputs.tag }}" >> $env:GITHUB_OUTPUT
28+
29+
- name: Download release assets
30+
shell: pwsh
31+
run: |
32+
$tag = "${{ steps.version.outputs.tag }}"
33+
$version = "${{ steps.version.outputs.version }}"
34+
$baseUrl = "https://github.com/${{ github.repository }}/releases/download/$tag"
35+
Invoke-WebRequest "$baseUrl/CopilotTaskbarApp-$version-win-x64.exe" -OutFile x64.exe
36+
Invoke-WebRequest "$baseUrl/CopilotTaskbarApp-$version-win-arm64.exe" -OutFile arm64.exe
37+
38+
- name: Compute SHA256 hashes
39+
id: hash
40+
shell: pwsh
41+
run: |
42+
$x64Hash = (Get-FileHash x64.exe -Algorithm SHA256).Hash
43+
$arm64Hash = (Get-FileHash arm64.exe -Algorithm SHA256).Hash
44+
"x64=$x64Hash" >> $env:GITHUB_OUTPUT
45+
"arm64=$arm64Hash" >> $env:GITHUB_OUTPUT
46+
47+
- name: Create winget manifest
48+
shell: pwsh
49+
run: |
50+
$version = "${{ steps.version.outputs.version }}"
51+
$tag = "${{ steps.version.outputs.tag }}"
52+
$baseUrl = "https://github.com/${{ github.repository }}/releases/download/$tag"
53+
$dir = "manifests/s/sirredbeard/CopilotTaskbarApp/$version"
54+
New-Item -ItemType Directory -Path $dir -Force | Out-Null
55+
56+
# Version manifest
57+
@"
58+
# yaml-language-server: `$schema=https://aka.ms/winget-manifest.version.1.9.0.schema.json
59+
PackageIdentifier: sirredbeard.CopilotTaskbarApp
60+
PackageVersion: $version
61+
DefaultLocale: en-US
62+
ManifestType: version
63+
ManifestVersion: 1.9.0
64+
"@ -replace '(?m)^ ', '' | Set-Content "$dir/sirredbeard.CopilotTaskbarApp.yaml" -NoNewline
65+
66+
# Default locale manifest
67+
@"
68+
# yaml-language-server: `$schema=https://aka.ms/winget-manifest.defaultLocale.1.9.0.schema.json
69+
PackageIdentifier: sirredbeard.CopilotTaskbarApp
70+
PackageVersion: $version
71+
PackageLocale: en-US
72+
Publisher: sirredbeard
73+
PublisherUrl: https://github.com/sirredbeard
74+
PackageName: Copilot Taskbar
75+
PackageUrl: https://github.com/${{ github.repository }}
76+
License: MIT
77+
LicenseUrl: https://github.com/${{ github.repository }}/blob/main/LICENSE
78+
ShortDescription: System tray access to GitHub Copilot with automatic context awareness
79+
Tags:
80+
- copilot
81+
- github
82+
- ai
83+
- developer-tools
84+
ManifestType: defaultLocale
85+
ManifestVersion: 1.9.0
86+
"@ -replace '(?m)^ ', '' | Set-Content "$dir/sirredbeard.CopilotTaskbarApp.locale.en-US.yaml" -NoNewline
87+
88+
# Installer manifest
89+
@"
90+
# yaml-language-server: `$schema=https://aka.ms/winget-manifest.installer.1.9.0.schema.json
91+
PackageIdentifier: sirredbeard.CopilotTaskbarApp
92+
PackageVersion: $version
93+
MinimumOSVersion: 10.0.17763.0
94+
InstallerType: portable
95+
Commands:
96+
- copilot-taskbar
97+
Installers:
98+
- Architecture: x64
99+
InstallerUrl: $baseUrl/CopilotTaskbarApp-$version-win-x64.exe
100+
InstallerSha256: ${{ steps.hash.outputs.x64 }}
101+
- Architecture: arm64
102+
InstallerUrl: $baseUrl/CopilotTaskbarApp-$version-win-arm64.exe
103+
InstallerSha256: ${{ steps.hash.outputs.arm64 }}
104+
ManifestType: installer
105+
ManifestVersion: 1.9.0
106+
"@ -replace '(?m)^ ', '' | Set-Content "$dir/sirredbeard.CopilotTaskbarApp.installer.yaml" -NoNewline
107+
108+
- name: Download wingetcreate
109+
shell: pwsh
110+
run: |
111+
$url = "https://github.com/microsoft/winget-create/releases/download/v1.10.3.0/wingetcreate.exe"
112+
$expectedHash = "9F56BB326B852A699296E936C7B40DADFAF3CCFF01C8E84ECFF89871ECFF8E5C"
113+
Invoke-WebRequest $url -OutFile wingetcreate.exe
114+
$actualHash = (Get-FileHash wingetcreate.exe -Algorithm SHA256).Hash
115+
if ($actualHash -ne $expectedHash) {
116+
throw "wingetcreate.exe hash mismatch: expected $expectedHash, got $actualHash"
117+
}
118+
119+
- name: Submit manifest
120+
shell: pwsh
121+
run: |
122+
$version = "${{ steps.version.outputs.version }}"
123+
$dir = "manifests/s/sirredbeard/CopilotTaskbarApp/$version"
124+
125+
.\wingetcreate.exe submit --token "${{ secrets.WINGET_PAT }}" "$dir"

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# GitHub Copilot Taskbar GUI
22

3-
<img width="1374" height="794" alt="image" src="https://github.com/user-attachments/assets/ae15dfb5-3c29-4d7d-ae21-8143d491d170" />
3+
<img width="1002" height="657" alt="Screenshot 2026-02-03 010803" src="https://github.com/user-attachments/assets/01d43924-95e5-489b-a352-7bdc80855e2f" />
4+
5+
> **Work in Progress**: Experimental proof-of-concept for deep OS integration with GitHub Copilot. APIs and features subject to change.
46
57
.NET 11 Preview WinUI 3 desktop application providing system tray access to GitHub Copilot CLI with automatic context awareness. Detects active focus, open applications, file system state, and running services to augment prompts with relevant environment information.
68

0 commit comments

Comments
 (0)