Skip to content

Commit 14e6919

Browse files
authored
ci: Add winget and Chocolatey packaging workflows
2 parents 921cbe0 + 353a370 commit 14e6919

File tree

9 files changed

+426
-0
lines changed

9 files changed

+426
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Publish to Chocolatey Community Repository
2+
#
3+
# PREREQUISITES:
4+
# 1. Create a Chocolatey account at https://community.chocolatey.org/account/Register
5+
# 2. Get your API key from https://community.chocolatey.org/account
6+
# 3. Add the API key as repository secret: CHOCOLATEY_API_KEY
7+
#
8+
# Reference: https://docs.chocolatey.org/en-us/create/create-packages-quick-start
9+
10+
name: Publish to Chocolatey
11+
12+
on:
13+
release:
14+
types: [released]
15+
workflow_dispatch:
16+
inputs:
17+
release_tag:
18+
description: 'Release tag to publish (e.g., v0.96.1)'
19+
required: true
20+
type: string
21+
22+
jobs:
23+
publish:
24+
runs-on: windows-latest
25+
steps:
26+
- name: Checkout repository
27+
uses: actions/checkout@v6
28+
29+
- name: Get version from tag
30+
id: version
31+
shell: bash
32+
run: |
33+
TAG="${{ github.event.inputs.release_tag || github.event.release.tag_name }}"
34+
# Strip 'v' prefix if present
35+
VERSION="${TAG#v}"
36+
echo "version=$VERSION" >> $GITHUB_OUTPUT
37+
echo "tag=$TAG" >> $GITHUB_OUTPUT
38+
39+
- name: Download MSI from release
40+
shell: pwsh
41+
run: |
42+
$version = "${{ steps.version.outputs.version }}"
43+
$tag = "${{ steps.version.outputs.tag }}"
44+
$msiUrl = "https://github.com/CCExtractor/ccextractor/releases/download/$tag/CCExtractor.$version.msi"
45+
46+
Write-Host "Downloading MSI from: $msiUrl"
47+
Invoke-WebRequest -Uri $msiUrl -OutFile "CCExtractor.msi"
48+
49+
# Calculate SHA256 checksum
50+
$hash = (Get-FileHash -Path "CCExtractor.msi" -Algorithm SHA256).Hash
51+
Write-Host "SHA256: $hash"
52+
echo "MSI_CHECKSUM=$hash" >> $env:GITHUB_ENV
53+
54+
- name: Update nuspec version
55+
shell: pwsh
56+
run: |
57+
$version = "${{ steps.version.outputs.version }}"
58+
$nuspecPath = "packaging/chocolatey/ccextractor.nuspec"
59+
60+
$content = Get-Content $nuspecPath -Raw
61+
$content = $content -replace '<version>.*</version>', "<version>$version</version>"
62+
Set-Content -Path $nuspecPath -Value $content
63+
64+
Write-Host "Updated nuspec to version $version"
65+
66+
- name: Update install script
67+
shell: pwsh
68+
run: |
69+
$version = "${{ steps.version.outputs.version }}"
70+
$tag = "${{ steps.version.outputs.tag }}"
71+
$checksum = $env:MSI_CHECKSUM
72+
$installScript = "packaging/chocolatey/tools/chocolateyInstall.ps1"
73+
74+
$content = Get-Content $installScript -Raw
75+
76+
# Update URL
77+
$newUrl = "https://github.com/CCExtractor/ccextractor/releases/download/$tag/CCExtractor.$version.msi"
78+
$content = $content -replace "url64bit\s*=\s*'[^']*'", "url64bit = '$newUrl'"
79+
80+
# Update checksum
81+
$content = $content -replace "checksum64\s*=\s*'[^']*'", "checksum64 = '$checksum'"
82+
83+
Set-Content -Path $installScript -Value $content
84+
85+
Write-Host "Updated install script with URL and checksum"
86+
87+
- name: Build Chocolatey package
88+
shell: pwsh
89+
run: |
90+
cd packaging/chocolatey
91+
choco pack ccextractor.nuspec
92+
93+
# List the generated package
94+
Get-ChildItem *.nupkg
95+
96+
- name: Test package locally
97+
shell: pwsh
98+
run: |
99+
cd packaging/chocolatey
100+
$nupkg = Get-ChildItem *.nupkg | Select-Object -First 1
101+
Write-Host "Testing package: $($nupkg.Name)"
102+
103+
# Install from local package
104+
choco install ccextractor --source="'.;https://community.chocolatey.org/api/v2/'" --yes --force
105+
106+
# Verify installation
107+
$ccx = Get-Command ccextractor -ErrorAction SilentlyContinue
108+
if ($ccx) {
109+
Write-Host "CCExtractor found at: $($ccx.Source)"
110+
& ccextractor --version
111+
} else {
112+
Write-Host "CCExtractor not found in PATH, checking Program Files..."
113+
$exePath = Join-Path $env:ProgramFiles "CCExtractor\ccextractor.exe"
114+
if (Test-Path $exePath) {
115+
& $exePath --version
116+
}
117+
}
118+
119+
- name: Push to Chocolatey
120+
shell: pwsh
121+
env:
122+
CHOCOLATEY_API_KEY: ${{ secrets.CHOCOLATEY_API_KEY }}
123+
run: |
124+
cd packaging/chocolatey
125+
$nupkg = Get-ChildItem *.nupkg | Select-Object -First 1
126+
127+
Write-Host "Pushing $($nupkg.Name) to Chocolatey..."
128+
choco push $nupkg.Name --source="https://push.chocolatey.org/" --api-key="$env:CHOCOLATEY_API_KEY"
129+
130+
Write-Host "Package submitted to Chocolatey! It may take some time to be moderated and published."
131+
132+
- name: Upload package artifact
133+
uses: actions/upload-artifact@v6
134+
with:
135+
name: chocolatey-package
136+
path: packaging/chocolatey/*.nupkg
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Publish to Windows Package Manager (winget)
2+
#
3+
# PREREQUISITES:
4+
# 1. CCExtractor must already have ONE version in winget-pkgs before this works
5+
# - Submit the initial manifest manually from packaging/winget/
6+
# - PR to: https://github.com/microsoft/winget-pkgs
7+
#
8+
# 2. Create a fork of microsoft/winget-pkgs under the CCExtractor organization
9+
# - https://github.com/CCExtractor/winget-pkgs (needs to be created)
10+
#
11+
# 3. Create a GitHub Personal Access Token (classic) with 'public_repo' scope
12+
# - Add as repository secret: WINGET_TOKEN
13+
#
14+
# Reference: https://github.com/vedantmgoyal9/winget-releaser
15+
16+
name: Publish to WinGet
17+
18+
on:
19+
release:
20+
types: [released]
21+
workflow_dispatch:
22+
inputs:
23+
release_tag:
24+
description: 'Release tag to publish (e.g., v0.96.1)'
25+
required: true
26+
type: string
27+
28+
jobs:
29+
publish:
30+
runs-on: windows-latest
31+
steps:
32+
- name: Publish to WinGet
33+
uses: vedantmgoyal9/winget-releaser@v2
34+
with:
35+
identifier: CCExtractor.CCExtractor
36+
installers-regex: '\.msi$' # Only use the MSI installer
37+
token: ${{ secrets.WINGET_TOKEN }}
38+
release-tag: ${{ github.event.inputs.release_tag || github.event.release.tag_name }}

packaging/README.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# CCExtractor Packaging
2+
3+
This directory contains packaging configurations for Windows package managers.
4+
5+
## Windows Package Manager (winget)
6+
7+
### Initial Setup (One-time)
8+
9+
1. **Calculate MSI hash** for the current release:
10+
```powershell
11+
certutil -hashfile CCExtractor.0.96.1.msi SHA256
12+
```
13+
14+
2. **Update the manifest files** in `winget/` with the SHA256 hash
15+
16+
3. **Fork microsoft/winget-pkgs** to the CCExtractor organization:
17+
- Go to https://github.com/microsoft/winget-pkgs
18+
- Fork to https://github.com/CCExtractor/winget-pkgs
19+
20+
4. **Submit initial manifest** via PR:
21+
- Clone your fork
22+
- Create directory: `manifests/c/CCExtractor/CCExtractor/0.96.1/`
23+
- Copy the three YAML files from `winget/`
24+
- Submit PR to microsoft/winget-pkgs
25+
26+
5. **Create GitHub token** for automation:
27+
- Go to GitHub Settings > Developer settings > Personal access tokens > Tokens (classic)
28+
- Create token with `public_repo` scope
29+
- Add as secret `WINGET_TOKEN` in CCExtractor/ccextractor repository
30+
31+
### Automated Updates
32+
33+
After the initial submission is merged, the `publish_winget.yml` workflow will automatically submit PRs for new releases.
34+
35+
## Chocolatey
36+
37+
### Initial Setup (One-time)
38+
39+
1. **Create Chocolatey account**:
40+
- Register at https://community.chocolatey.org/account/Register
41+
42+
2. **Get API key**:
43+
- Go to https://community.chocolatey.org/account
44+
- Copy your API key
45+
46+
3. **Add secret**:
47+
- Add `CHOCOLATEY_API_KEY` secret to CCExtractor/ccextractor repository
48+
49+
### Package Structure
50+
51+
```
52+
chocolatey/
53+
├── ccextractor.nuspec # Package metadata
54+
└── tools/
55+
├── chocolateyInstall.ps1 # Installation script
56+
└── chocolateyUninstall.ps1 # Uninstallation script
57+
```
58+
59+
### Manual Testing
60+
61+
```powershell
62+
cd packaging/chocolatey
63+
64+
# Update version and checksum in files first, then:
65+
choco pack ccextractor.nuspec
66+
67+
# Test locally
68+
choco install ccextractor --source="'.'" --yes --force
69+
70+
# Verify
71+
ccextractor --version
72+
```
73+
74+
### Automated Updates
75+
76+
The `publish_chocolatey.yml` workflow automatically:
77+
1. Downloads the MSI from the release
78+
2. Calculates the SHA256 checksum
79+
3. Updates the nuspec and install script
80+
4. Builds and tests the package
81+
5. Pushes to Chocolatey
82+
83+
Note: Chocolatey packages go through moderation before being publicly available.
84+
85+
## Workflow Triggers
86+
87+
Both workflows trigger on:
88+
- **Release published**: Automatic publishing when a new release is created
89+
- **Manual dispatch**: Can be triggered manually with a specific tag
90+
91+
## Secrets Required
92+
93+
| Secret | Purpose |
94+
|--------|---------|
95+
| `WINGET_TOKEN` | GitHub PAT with `public_repo` scope for winget PRs |
96+
| `CHOCOLATEY_API_KEY` | Chocolatey API key for package uploads |
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
3+
<metadata>
4+
<id>ccextractor</id>
5+
<version>0.96.2</version>
6+
<title>CCExtractor</title>
7+
<authors>CCExtractor Development Team</authors>
8+
<owners>CCExtractor</owners>
9+
<licenseUrl>https://github.com/CCExtractor/ccextractor/blob/master/LICENSE.txt</licenseUrl>
10+
<projectUrl>https://ccextractor.org</projectUrl>
11+
<iconUrl>https://raw.githubusercontent.com/CCExtractor/ccextractor/master/windows/CCX.ico</iconUrl>
12+
<requireLicenseAcceptance>false</requireLicenseAcceptance>
13+
<description>CCExtractor is a tool that analyzes video files and produces independent subtitle files from the closed captions data.
14+
15+
### Features
16+
- Extracts closed captions from various video formats (MPEG, H.264, MKV, MP4, etc.)
17+
- Supports multiple input sources including DVDs, DVRs, and live TV captures
18+
- Outputs to multiple formats (SRT, WebVTT, SAMI, transcript, etc.)
19+
- OCR support for bitmap-based subtitles (DVB, teletext)
20+
- Includes a graphical user interface
21+
22+
### Usage
23+
After installation, run `ccextractor` from the command line or use the GUI.
24+
25+
```
26+
ccextractor video.ts -o output.srt
27+
```
28+
29+
For more options: `ccextractor --help`
30+
</description>
31+
<summary>Extract closed captions and subtitles from video files</summary>
32+
<releaseNotes>https://github.com/CCExtractor/ccextractor/releases</releaseNotes>
33+
<copyright>Copyright (c) CCExtractor Development</copyright>
34+
<tags>subtitles closed-captions video extraction accessibility srt dvb teletext ocr media cli</tags>
35+
<projectSourceUrl>https://github.com/CCExtractor/ccextractor</projectSourceUrl>
36+
<packageSourceUrl>https://github.com/CCExtractor/ccextractor/tree/master/packaging/chocolatey</packageSourceUrl>
37+
<docsUrl>https://github.com/CCExtractor/ccextractor/wiki</docsUrl>
38+
<bugTrackerUrl>https://github.com/CCExtractor/ccextractor/issues</bugTrackerUrl>
39+
</metadata>
40+
<files>
41+
<file src="tools\**" target="tools" />
42+
</files>
43+
</package>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
$ErrorActionPreference = 'Stop'
2+
3+
$packageName = 'ccextractor'
4+
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
5+
6+
# Package parameters
7+
$packageArgs = @{
8+
packageName = $packageName
9+
fileType = 'MSI'
10+
url64bit = 'https://github.com/CCExtractor/ccextractor/releases/download/v0.96.2/CCExtractor.0.96.2.msi'
11+
checksum64 = 'FFCAB0D766180AFC2832277397CDEC885D15270DECE33A9A51947B790F1F095B'
12+
checksumType64 = 'sha256'
13+
silentArgs = '/quiet /norestart'
14+
validExitCodes = @(0, 3010, 1641)
15+
}
16+
17+
Install-ChocolateyPackage @packageArgs
18+
19+
# Add to PATH if not already there
20+
$installPath = Join-Path $env:ProgramFiles 'CCExtractor'
21+
if (Test-Path $installPath) {
22+
Install-ChocolateyPath -PathToInstall $installPath -PathType 'Machine'
23+
Write-Host "CCExtractor installed to: $installPath"
24+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
$ErrorActionPreference = 'Stop'
2+
3+
$packageName = 'ccextractor'
4+
5+
# Get the uninstall registry key
6+
$regKey = Get-UninstallRegistryKey -SoftwareName 'CCExtractor*'
7+
8+
if ($regKey) {
9+
$silentArgs = '/quiet /norestart'
10+
$file = $regKey.UninstallString -replace 'msiexec.exe','msiexec.exe ' -replace '/I','/X'
11+
12+
$packageArgs = @{
13+
packageName = $packageName
14+
fileType = 'MSI'
15+
silentArgs = "$($regKey.PSChildName) $silentArgs"
16+
file = ''
17+
validExitCodes = @(0, 3010, 1605, 1614, 1641)
18+
}
19+
20+
Uninstall-ChocolateyPackage @packageArgs
21+
} else {
22+
Write-Warning "CCExtractor was not found in the registry. It may have been uninstalled already."
23+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.9.0.schema.json
2+
PackageIdentifier: CCExtractor.CCExtractor
3+
PackageVersion: 0.96.2
4+
Platform:
5+
- Windows.Desktop
6+
MinimumOSVersion: 10.0.0.0
7+
InstallModes:
8+
- interactive
9+
- silent
10+
- silentWithProgress
11+
InstallerSwitches:
12+
Silent: /quiet
13+
SilentWithProgress: /passive
14+
UpgradeBehavior: install
15+
Installers:
16+
- Architecture: x64
17+
InstallerType: msi
18+
InstallerUrl: https://github.com/CCExtractor/ccextractor/releases/download/v0.96.2/CCExtractor.0.96.2.msi
19+
InstallerSha256: FFCAB0D766180AFC2832277397CDEC885D15270DECE33A9A51947B790F1F095B
20+
ManifestType: installer
21+
ManifestVersion: 1.9.0

0 commit comments

Comments
 (0)